mirror of
https://github.com/lightningnetwork/lnd.git
synced 2025-07-28 13:52:55 +02:00
htlcswitch: add new TestUpdateFailMalformedHTLCErrorConversion test
In this commit, we add a new test to ensure that we're able to properly convert malformed HTLC errors that are sourced from multiple hops away, or our direct channel peers. In order to test this effectively, we force the onion decryptors of various peers to always fail which will trigger the malformed HTLC logic.
This commit is contained in:
@@ -2033,3 +2033,76 @@ func TestMultiHopPaymentForwardingEvents(t *testing.T) {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// TestUpdateFailMalformedHTLCErrorConversion tests that we're able to properly
|
||||
// convert malformed HTLC errors that originate at the direct link, as well as
|
||||
// during multi-hop HTLC forwarding.
|
||||
func TestUpdateFailMalformedHTLCErrorConversion(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
// First, we'll create our traditional three hop network.
|
||||
channels, cleanUp, _, err := createClusterChannels(
|
||||
btcutil.SatoshiPerBitcoin*3, btcutil.SatoshiPerBitcoin*5,
|
||||
)
|
||||
if err != nil {
|
||||
t.Fatalf("unable to create channel: %v", err)
|
||||
}
|
||||
defer cleanUp()
|
||||
|
||||
n := newThreeHopNetwork(
|
||||
t, channels.aliceToBob, channels.bobToAlice,
|
||||
channels.bobToCarol, channels.carolToBob, testStartingHeight,
|
||||
)
|
||||
if err := n.start(); err != nil {
|
||||
t.Fatalf("unable to start three hop network: %v", err)
|
||||
}
|
||||
|
||||
assertPaymentFailure := func(t *testing.T) {
|
||||
// With the decoder modified, we'll now attempt to send a
|
||||
// payment from Alice to carol.
|
||||
finalAmt := lnwire.NewMSatFromSatoshis(100000)
|
||||
htlcAmt, totalTimelock, hops := generateHops(
|
||||
finalAmt, testStartingHeight, n.firstBobChannelLink,
|
||||
n.carolChannelLink,
|
||||
)
|
||||
firstHop := n.firstBobChannelLink.ShortChanID()
|
||||
_, err = makePayment(
|
||||
n.aliceServer, n.carolServer, firstHop, hops, finalAmt,
|
||||
htlcAmt, totalTimelock,
|
||||
).Wait(30 * time.Second)
|
||||
|
||||
// The payment should fail as Carol is unable to decode the
|
||||
// onion blob sent to her.
|
||||
if err == nil {
|
||||
t.Fatalf("unable to send payment: %v", err)
|
||||
}
|
||||
|
||||
fwdingErr := err.(*ForwardingError)
|
||||
failureMsg := fwdingErr.FailureMessage
|
||||
if _, ok := failureMsg.(*lnwire.FailTemporaryChannelFailure); !ok {
|
||||
t.Fatalf("expected temp chan failure instead got: %v",
|
||||
fwdingErr.FailureMessage)
|
||||
}
|
||||
}
|
||||
|
||||
t.Run("multi-hop error conversion", func(t *testing.T) {
|
||||
// Now that we have our network up, we'll modify the hop
|
||||
// iterator for the Bob <-> Carol channel to fail to decode in
|
||||
// order to simulate either a replay attack or an issue
|
||||
// decoding the onion.
|
||||
n.carolOnionDecoder.decodeFail = true
|
||||
|
||||
assertPaymentFailure(t)
|
||||
})
|
||||
|
||||
t.Run("direct channel error conversion", func(t *testing.T) {
|
||||
// Similar to the above test case, we'll now make the Alice <->
|
||||
// Bob link always fail to decode an onion. This differs from
|
||||
// the above test case in that there's no encryption on the
|
||||
// error at all since Alice will directly receive a
|
||||
// UpdateFailMalformedHTLC message.
|
||||
n.bobOnionDecoder.decodeFail = true
|
||||
|
||||
assertPaymentFailure(t)
|
||||
})
|
||||
}
|
||||
|
Reference in New Issue
Block a user