From 3a186a02a9963b5c579c5bf617a8e9c2051cbbb2 Mon Sep 17 00:00:00 2001 From: Conner Fromknecht Date: Tue, 16 Jan 2018 00:37:15 -0800 Subject: [PATCH] htlcswitch/link_test: generate random preimages --- htlcswitch/link_test.go | 299 +++++++++++++++++++++++++++++----------- 1 file changed, 215 insertions(+), 84 deletions(-) diff --git a/htlcswitch/link_test.go b/htlcswitch/link_test.go index 7411ca55..0a688845 100644 --- a/htlcswitch/link_test.go +++ b/htlcswitch/link_test.go @@ -2,7 +2,10 @@ package htlcswitch import ( "bytes" + "crypto/rand" + "encoding/binary" "fmt" + "io" "runtime" "strings" "sync" @@ -837,7 +840,7 @@ func TestUpdateForwardingPolicy(t *testing.T) { ferr, ok := err.(*ForwardingError) if !ok { - t.Fatalf("expected a ForwardingError, instead got: %T", err) + t.Fatalf("expected a ForwardingError, instead got (%T): %v", err, err) } switch ferr.FailureMessage.(type) { case *lnwire.FailFeeInsufficient: @@ -1050,7 +1053,11 @@ func TestChannelLinkMultiHopUnknownNextHop(t *testing.T) { htlcAmt, totalTimelock, hops := generateHops(amount, testStartingHeight, n.firstBobChannelLink, n.carolChannelLink) - davePub := newMockServer(t, "dave").PubKey() + daveServer, err := newMockServer(t, "dave", nil) + if err != nil { + t.Fatalf("unable to init dave's server: %v", err) + } + davePub := daveServer.PubKey() receiver := n.bobServer rhash, err := n.makePayment(n.aliceServer, n.bobServer, davePub, hops, amount, htlcAmt, totalTimelock).Wait(30 * time.Second) @@ -1412,7 +1419,14 @@ func newSingleLinkTestHarness(chanAmt, chanReserve btcutil.Amount) ( }, } - chanID := lnwire.NewShortChanIDFromInt(4) + var chanIDBytes [8]byte + if _, err := io.ReadFull(rand.Reader, chanIDBytes[:]); err != nil { + return nil, nil, nil, nil, err + } + + chanID := lnwire.NewShortChanIDFromInt( + binary.BigEndian.Uint64(chanIDBytes[:])) + aliceChannel, bobChannel, fCleanUp, _, err := createTestChannel( alicePrivKey, bobPrivKey, chanAmt, chanAmt, chanReserve, chanReserve, chanID, @@ -1423,8 +1437,8 @@ func newSingleLinkTestHarness(chanAmt, chanReserve btcutil.Amount) ( var ( invoiceRegistry = newMockRegistry() - decoder = &mockIteratorDecoder{} - obfuscator = newMockObfuscator() + decoder = newMockIteratorDecoder() + obfuscator = NewMockObfuscator() alicePeer = &mockPeer{ sentMsgs: make(chan lnwire.Message, 2000), quit: make(chan struct{}), @@ -1442,14 +1456,25 @@ func newSingleLinkTestHarness(chanAmt, chanReserve btcutil.Amount) ( preimageMap: make(map[[32]byte][]byte), } + aliceDb := aliceChannel.State().Db + + aliceSwitch, err := New(Config{DB: aliceDb}) + if err != nil { + return nil, nil, nil, nil, err + } + t := make(chan time.Time) ticker := &mockTicker{t} aliceCfg := ChannelLinkConfig{ - FwrdingPolicy: globalPolicy, - Peer: alicePeer, - Switch: New(Config{}), - DecodeHopIterator: decoder.DecodeHopIterator, - DecodeOnionObfuscator: func(*sphinx.OnionPacket) (ErrorEncrypter, lnwire.FailCode) { + FwrdingPolicy: globalPolicy, + Peer: alicePeer, + Switch: aliceSwitch, + Circuits: aliceSwitch.CircuitModifier(), + ForwardPackets: aliceSwitch.ForwardPackets, + DecodeHopIterator: decoder.DecodeHopIterator, + DecodeHopIterators: decoder.DecodeHopIterators, + DecodeOnionObfuscator: func(*sphinx.OnionPacket) ( + ErrorEncrypter, lnwire.FailCode) { return obfuscator, lnwire.CodeNone }, GetLastChannelUpdate: mockGetChanUpdateMessage, @@ -1457,10 +1482,11 @@ func newSingleLinkTestHarness(chanAmt, chanReserve btcutil.Amount) ( UpdateContractSignals: func(*contractcourt.ContractSignals) error { return nil }, - Registry: invoiceRegistry, - ChainEvents: &contractcourt.ChainEventSubscription{}, - BlockEpochs: globalEpoch, - BatchTicker: ticker, + Registry: invoiceRegistry, + ChainEvents: &contractcourt.ChainEventSubscription{}, + BlockEpochs: globalEpoch, + BatchTicker: ticker, + FwdPkgGCTicker: NewBatchTicker(time.NewTicker(5 * time.Second)), // Make the BatchSize large enough to not // trigger commit update automatically during tests. BatchSize: 10000, @@ -1468,6 +1494,9 @@ func newSingleLinkTestHarness(chanAmt, chanReserve btcutil.Amount) ( const startingHeight = 100 aliceLink := NewChannelLink(aliceCfg, aliceChannel, startingHeight) + mailbox := newMemoryMailBox() + mailbox.Start() + aliceLink.AttachMailBox(mailbox) if err := aliceLink.Start(); err != nil { return nil, nil, nil, nil, err } @@ -1659,25 +1688,27 @@ func TestChannelLinkBandwidthConsistency(t *testing.T) { // We'll start the test by creating a single instance of const chanAmt = btcutil.SatoshiPerBitcoin * 5 - link, bobChannel, tmr, cleanUp, err := newSingleLinkTestHarness(chanAmt, 0) + + aliceLink, bobChannel, tmr, cleanUp, err := newSingleLinkTestHarness(chanAmt, 0) if err != nil { t.Fatalf("unable to create link: %v", err) } defer cleanUp() var ( + carolChanID = lnwire.NewShortChanIDFromInt(3) mockBlob [lnwire.OnionPacketSize]byte - aliceLink = link.(*channelLink) - aliceChannel = aliceLink.channel - defaultCommitFee = aliceChannel.StateSnapshot().CommitFee + coreChan = aliceLink.(*channelLink).channel + coreLink = aliceLink.(*channelLink) + defaultCommitFee = coreChan.StateSnapshot().CommitFee aliceStartingBandwidth = aliceLink.Bandwidth() - aliceMsgs = aliceLink.cfg.Peer.(*mockPeer).sentMsgs + aliceMsgs = coreLink.cfg.Peer.(*mockPeer).sentMsgs ) // We put Alice into HodlHTLC mode, such that she won't settle // incoming HTLCs automatically. - aliceLink.cfg.HodlHTLC = true - aliceLink.cfg.DebugHTLC = true + coreLink.cfg.HodlHTLC = true + coreLink.cfg.DebugHTLC = true estimator := &lnwallet.StaticFeeEstimator{ FeeRate: 24, @@ -1705,9 +1736,22 @@ func TestChannelLinkBandwidthConsistency(t *testing.T) { t.Fatalf("unable to create payment: %v", err) } addPkt := htlcPacket{ - htlc: htlc, + htlc: htlc, + incomingChanID: sourceHop, + incomingHTLCID: 0, + obfuscator: NewMockObfuscator(), + } + + circuit := makePaymentCircuit(&htlc.PaymentHash, &addPkt) + _, err = coreLink.cfg.Switch.commitCircuits(&circuit) + if err != nil { + t.Fatalf("unable to commit circuit: %v", err) + } + + addPkt.circuit = &circuit + if err := aliceLink.HandleSwitchPacket(&addPkt); err != nil { + t.Fatalf("unable to handle switch packet: %v", err) } - aliceLink.HandleSwitchPacket(&addPkt) time.Sleep(time.Millisecond * 500) // The resulting bandwidth should reflect that Alice is paying the @@ -1733,10 +1777,9 @@ func TestChannelLinkBandwidthConsistency(t *testing.T) { } // Lock in the HTLC. - if err := updateState(tmr, aliceLink, bobChannel, true); err != nil { + if err := updateState(tmr, coreLink, bobChannel, true); err != nil { t.Fatalf("unable to update state: %v", err) } - // Locking in the HTLC should not change Alice's bandwidth. assertLinkBandwidth(t, aliceLink, aliceStartingBandwidth-htlcAmt-htlcFee) @@ -1748,7 +1791,7 @@ func TestChannelLinkBandwidthConsistency(t *testing.T) { t.Fatalf("unable to settle htlc: %v", err) } htlcSettle := &lnwire.UpdateFulfillHTLC{ - ID: bobIndex, + ID: 0, PaymentPreimage: invoice.Terms.PaymentPreimage, } aliceLink.HandleChannelUpdate(htlcSettle) @@ -1759,7 +1802,7 @@ func TestChannelLinkBandwidthConsistency(t *testing.T) { assertLinkBandwidth(t, aliceLink, aliceStartingBandwidth-htlcAmt-htlcFee) // Lock in the settle. - if err := updateState(tmr, aliceLink, bobChannel, false); err != nil { + if err := updateState(tmr, coreLink, bobChannel, false); err != nil { t.Fatalf("unable to update state: %v", err) } @@ -1773,9 +1816,22 @@ func TestChannelLinkBandwidthConsistency(t *testing.T) { t.Fatalf("unable to create payment: %v", err) } addPkt = htlcPacket{ - htlc: htlc, + htlc: htlc, + incomingChanID: sourceHop, + incomingHTLCID: 1, + obfuscator: NewMockObfuscator(), + } + + circuit = makePaymentCircuit(&htlc.PaymentHash, &addPkt) + _, err = coreLink.cfg.Switch.commitCircuits(&circuit) + if err != nil { + t.Fatalf("unable to commit circuit: %v", err) + } + + addPkt.circuit = &circuit + if err := aliceLink.HandleSwitchPacket(&addPkt); err != nil { + t.Fatalf("unable to handle switch packet: %v", err) } - aliceLink.HandleSwitchPacket(&addPkt) time.Sleep(time.Millisecond * 500) // Again, Alice's bandwidth decreases by htlcAmt+htlcFee. @@ -1787,6 +1843,7 @@ func TestChannelLinkBandwidthConsistency(t *testing.T) { case <-time.After(2 * time.Second): t.Fatalf("did not receive message") } + addHtlc, ok = msg.(*lnwire.UpdateAddHTLC) if !ok { t.Fatalf("expected UpdateAddHTLC, got %T", msg) @@ -1798,7 +1855,7 @@ func TestChannelLinkBandwidthConsistency(t *testing.T) { } // Lock in the HTLC, which should not affect the bandwidth. - if err := updateState(tmr, aliceLink, bobChannel, true); err != nil { + if err := updateState(tmr, coreLink, bobChannel, true); err != nil { t.Fatalf("unable to update state: %v", err) } @@ -1812,9 +1869,10 @@ func TestChannelLinkBandwidthConsistency(t *testing.T) { t.Fatalf("unable to fail htlc: %v", err) } failMsg := &lnwire.UpdateFailHTLC{ - ID: bobIndex, + ID: 1, Reason: lnwire.OpaqueReason([]byte("nop")), } + aliceLink.HandleChannelUpdate(failMsg) time.Sleep(time.Millisecond * 500) @@ -1822,7 +1880,7 @@ func TestChannelLinkBandwidthConsistency(t *testing.T) { assertLinkBandwidth(t, aliceLink, aliceStartingBandwidth-htlcAmt*2-htlcFee) // Lock in the Fail. - if err := updateState(tmr, aliceLink, bobChannel, false); err != nil { + if err := updateState(tmr, coreLink, bobChannel, false); err != nil { t.Fatalf("unable to update state: %v", err) } @@ -1834,7 +1892,7 @@ func TestChannelLinkBandwidthConsistency(t *testing.T) { // remain unchanged (but Alice will need to pay the fee for the extra // HTLC). htlcAmt, totalTimelock, hops := generateHops(htlcAmt, testStartingHeight, - aliceLink) + coreLink) blob, err := generateRoute(hops...) if err != nil { t.Fatalf("unable to gen route: %v", err) @@ -1847,11 +1905,12 @@ func TestChannelLinkBandwidthConsistency(t *testing.T) { // We must add the invoice to the registry, such that Alice expects // this payment. - err = aliceLink.cfg.Registry.(*mockInvoiceRegistry).AddInvoice(*invoice) + err = coreLink.cfg.Registry.(*mockInvoiceRegistry).AddInvoice(*invoice) if err != nil { t.Fatalf("unable to add invoice to registry: %v", err) } + htlc.ID = 0 bobIndex, err = bobChannel.AddHTLC(htlc, nil) if err != nil { t.Fatalf("unable to add htlc: %v", err) @@ -1862,58 +1921,84 @@ func TestChannelLinkBandwidthConsistency(t *testing.T) { assertLinkBandwidth(t, aliceLink, aliceStartingBandwidth-htlcAmt) // Lock in the HTLC. - if err := updateState(tmr, aliceLink, bobChannel, false); err != nil { + if err := updateState(tmr, coreLink, bobChannel, false); err != nil { t.Fatalf("unable to update state: %v", err) } // Since Bob is adding this HTLC, Alice only needs to pay the fee. assertLinkBandwidth(t, aliceLink, aliceStartingBandwidth-htlcAmt-htlcFee) + time.Sleep(time.Millisecond * 500) + + addPkt = htlcPacket{ + htlc: htlc, + incomingChanID: aliceLink.ShortChanID(), + incomingHTLCID: 0, + obfuscator: NewMockObfuscator(), + } + + circuit = makePaymentCircuit(&htlc.PaymentHash, &addPkt) + _, err = coreLink.cfg.Switch.commitCircuits(&circuit) + if err != nil { + t.Fatalf("unable to commit circuit: %v", err) + } + + addPkt.outgoingChanID = carolChanID + addPkt.outgoingHTLCID = 0 + + err = coreLink.cfg.Switch.openCircuits(addPkt.keystone()) + if err != nil { + t.Fatalf("unable to set keystone: %v", err) + } // Next, we'll settle the HTLC with our knowledge of the pre-image that // we eventually learn (simulating a multi-hop payment). The bandwidth // of the channel should now be re-balanced to the starting point. settlePkt := htlcPacket{ + incomingChanID: aliceLink.ShortChanID(), + incomingHTLCID: 0, + circuit: &circuit, + outgoingChanID: addPkt.outgoingChanID, + outgoingHTLCID: addPkt.outgoingHTLCID, htlc: &lnwire.UpdateFulfillHTLC{ - ID: bobIndex, + ID: 0, PaymentPreimage: invoice.Terms.PaymentPreimage, }, + obfuscator: NewMockObfuscator(), } - aliceLink.HandleSwitchPacket(&settlePkt) + if err := aliceLink.HandleSwitchPacket(&settlePkt); err != nil { + t.Fatalf("unable to handle switch packet: %v", err) + } time.Sleep(time.Millisecond * 500) // Settling this HTLC gives Alice all her original bandwidth back. assertLinkBandwidth(t, aliceLink, aliceStartingBandwidth) - // Alice wil send the Settle to Bob. select { case msg = <-aliceMsgs: case <-time.After(2 * time.Second): t.Fatalf("did not receive message") } - settleHtlc, ok := msg.(*lnwire.UpdateFulfillHTLC) + settleMsg, ok := msg.(*lnwire.UpdateFulfillHTLC) if !ok { t.Fatalf("expected UpdateFulfillHTLC, got %T", msg) } - pre := settleHtlc.PaymentPreimage - idx := settleHtlc.ID - err = bobChannel.ReceiveHTLCSettle(pre, idx) + err = bobChannel.ReceiveHTLCSettle(settleMsg.PaymentPreimage, settleMsg.ID) if err != nil { - t.Fatalf("unable to receive settle: %v", err) + t.Fatalf("failed receiving fail htlc: %v", err) } - // After a settle the link should do a state transition automatically, - // so we don't have to trigger it. - if err := handleStateUpdate(aliceLink, bobChannel); err != nil { + // After failing an HTLC, the link will automatically trigger + // a state update. + if err := handleStateUpdate(coreLink, bobChannel); err != nil { t.Fatalf("unable to update state: %v", err) } - assertLinkBandwidth(t, aliceLink, aliceStartingBandwidth) - // Finally, we'll test the scenario of failing an HTLC received from the + // Finally, we'll test the scenario of failing an HTLC received by the // remote node. This should result in no perceived bandwidth changes. htlcAmt, totalTimelock, hops = generateHops(htlcAmt, testStartingHeight, - aliceLink) + coreLink) blob, err = generateRoute(hops...) if err != nil { t.Fatalf("unable to gen route: %v", err) @@ -1922,7 +2007,8 @@ func TestChannelLinkBandwidthConsistency(t *testing.T) { if err != nil { t.Fatalf("unable to create payment: %v", err) } - if err := aliceLink.cfg.Registry.(*mockInvoiceRegistry).AddInvoice(*invoice); err != nil { + err = coreLink.cfg.Registry.(*mockInvoiceRegistry).AddInvoice(*invoice) + if err != nil { t.Fatalf("unable to add invoice to registry: %v", err) } @@ -1940,21 +2026,49 @@ func TestChannelLinkBandwidthConsistency(t *testing.T) { // No changes before the HTLC is locked in. assertLinkBandwidth(t, aliceLink, aliceStartingBandwidth) - if err := updateState(tmr, aliceLink, bobChannel, false); err != nil { + if err := updateState(tmr, coreLink, bobChannel, false); err != nil { t.Fatalf("unable to update state: %v", err) } // After lock-in, Alice will have to pay the htlc fee. assertLinkBandwidth(t, aliceLink, aliceStartingBandwidth-htlcFee) - // Now fail this HTLC. - failPkt := htlcPacket{ - incomingHTLCID: bobIndex, - htlc: &lnwire.UpdateFailHTLC{ - ID: bobIndex, - }, + addPkt = htlcPacket{ + htlc: htlc, + incomingChanID: aliceLink.ShortChanID(), + incomingHTLCID: 1, + obfuscator: NewMockObfuscator(), + } + + circuit = makePaymentCircuit(&htlc.PaymentHash, &addPkt) + _, err = coreLink.cfg.Switch.commitCircuits(&circuit) + if err != nil { + t.Fatalf("unable to commit circuit: %v", err) + } + + addPkt.outgoingChanID = carolChanID + addPkt.outgoingHTLCID = 1 + + err = coreLink.cfg.Switch.openCircuits(addPkt.keystone()) + if err != nil { + t.Fatalf("unable to set keystone: %v", err) + } + + failPkt := htlcPacket{ + incomingChanID: aliceLink.ShortChanID(), + incomingHTLCID: 1, + circuit: &circuit, + outgoingChanID: addPkt.outgoingChanID, + outgoingHTLCID: addPkt.outgoingHTLCID, + htlc: &lnwire.UpdateFailHTLC{ + ID: 1, + }, + obfuscator: NewMockObfuscator(), + } + + if err := aliceLink.HandleSwitchPacket(&failPkt); err != nil { + t.Fatalf("unable to handle switch packet: %v", err) } - aliceLink.HandleSwitchPacket(&failPkt) time.Sleep(time.Millisecond * 500) // Alice should get all her bandwidth back. @@ -1977,7 +2091,7 @@ func TestChannelLinkBandwidthConsistency(t *testing.T) { // After failing an HTLC, the link will automatically trigger // a state update. - if err := handleStateUpdate(aliceLink, bobChannel); err != nil { + if err := handleStateUpdate(coreLink, bobChannel); err != nil { t.Fatalf("unable to update state: %v", err) } assertLinkBandwidth(t, aliceLink, aliceStartingBandwidth) @@ -2015,20 +2129,27 @@ func TestChannelLinkBandwidthConsistencyOverflow(t *testing.T) { } feePerKw := feeRate.FeePerKWeight() - // The starting bandwidth of the channel should be exactly the amount - // that we created the channel between her and Bob. - expectedBandwidth := lnwire.NewMSatFromSatoshis(chanAmt - defaultCommitFee) - assertLinkBandwidth(t, aliceLink, expectedBandwidth) - - addLinkHTLC := func(amt lnwire.MilliSatoshi) [32]byte { + var htlcID uint64 + addLinkHTLC := func(id uint64, amt lnwire.MilliSatoshi) [32]byte { invoice, htlc, err := generatePayment(amt, amt, 5, mockBlob) if err != nil { t.Fatalf("unable to create payment: %v", err) } - aliceLink.HandleSwitchPacket(&htlcPacket{ - htlc: htlc, - amount: amt, - }) + + addPkt := &htlcPacket{ + htlc: htlc, + incomingHTLCID: id, + amount: amt, + obfuscator: NewMockObfuscator(), + } + circuit := makePaymentCircuit(&htlc.PaymentHash, addPkt) + _, err = coreLink.cfg.Switch.commitCircuits(&circuit) + if err != nil { + t.Fatalf("unable to commit circuit: %v", err) + } + + addPkt.circuit = &circuit + aliceLink.HandleSwitchPacket(addPkt) return invoice.Terms.PaymentPreimage } @@ -2040,10 +2161,11 @@ func TestChannelLinkBandwidthConsistencyOverflow(t *testing.T) { const numHTLCs = lnwallet.MaxHTLCNumber / 2 var preImages [][32]byte for i := 0; i < numHTLCs; i++ { - preImage := addLinkHTLC(htlcAmt) + preImage := addLinkHTLC(htlcID, htlcAmt) preImages = append(preImages, preImage) totalHtlcAmt += htlcAmt + htlcID++ } // The HTLCs should all be sent to the remote. @@ -2051,8 +2173,8 @@ func TestChannelLinkBandwidthConsistencyOverflow(t *testing.T) { for i := 0; i < numHTLCs; i++ { select { case msg = <-aliceMsgs: - case <-time.After(2 * time.Second): - t.Fatalf("did not receive message") + case <-time.After(5 * time.Second): + t.Fatalf("did not receive message %d", i) } addHtlc, ok := msg.(*lnwire.UpdateAddHTLC) @@ -2078,7 +2200,7 @@ func TestChannelLinkBandwidthConsistencyOverflow(t *testing.T) { htlcFee := lnwire.NewMSatFromSatoshis( feePerKw.FeeForWeight(commitWeight), ) - expectedBandwidth = aliceStartingBandwidth - totalHtlcAmt - htlcFee + expectedBandwidth := aliceStartingBandwidth - totalHtlcAmt - htlcFee expectedBandwidth += lnwire.NewMSatFromSatoshis(defaultCommitFee) assertLinkBandwidth(t, aliceLink, expectedBandwidth) @@ -2094,10 +2216,11 @@ func TestChannelLinkBandwidthConsistencyOverflow(t *testing.T) { // bandwidth accounting is done properly. const numOverFlowHTLCs = 20 for i := 0; i < numOverFlowHTLCs; i++ { - preImage := addLinkHTLC(htlcAmt) + preImage := addLinkHTLC(htlcID, htlcAmt) preImages = append(preImages, preImage) totalHtlcAmt += htlcAmt + htlcID++ } // No messages should be sent to the remote at this point. @@ -2245,10 +2368,18 @@ func TestChannelLinkBandwidthChanReserve(t *testing.T) { if err != nil { t.Fatalf("unable to create payment: %v", err) } - addPkt := htlcPacket{ - htlc: htlc, + + addPkt := &htlcPacket{ + htlc: htlc, + obfuscator: NewMockObfuscator(), } - aliceLink.HandleSwitchPacket(&addPkt) + circuit := makePaymentCircuit(&htlc.PaymentHash, addPkt) + _, err = coreLink.cfg.Switch.commitCircuits(&circuit) + if err != nil { + t.Fatalf("unable to commit circuit: %v", err) + } + + aliceLink.HandleSwitchPacket(addPkt) time.Sleep(time.Millisecond * 100) assertLinkBandwidth(t, aliceLink, aliceStartingBandwidth-htlcAmt-htlcFee) @@ -2834,11 +2965,11 @@ func TestChannelLinkUpdateCommitFee(t *testing.T) { } } -// TestChannelLinkRejectDuplicatePayment tests that if a link receives an -// incoming HTLC for a payment we have already settled, then it rejects the -// HTLC. We do this as we want to enforce the fact that invoices are only to be -// used _once. -func TestChannelLinkRejectDuplicatePayment(t *testing.T) { +// TestChannelLinkAcceptDuplicatePayment tests that if a link receives an +// incoming HTLC for a payment we have already settled, then it accepts the +// HTLC. We do this to simplify the processing of settles after restarts or +// failures, reducing ambiguity when a batch is only partially processed. +func TestChannelLinkAcceptDuplicatePayment(t *testing.T) { t.Parallel() // First, we'll create our traditional three hop network. We'll only be @@ -2891,8 +3022,8 @@ func TestChannelLinkRejectDuplicatePayment(t *testing.T) { // as it's a duplicate request. _, err = n.aliceServer.htlcSwitch.SendHTLC(n.bobServer.PubKey(), htlc, newMockDeobfuscator()) - if err.Error() != lnwire.CodeUnknownPaymentHash.String() { - t.Fatal("error haven't been received") + if err != nil { + t.Fatalf("error shouldn't have been received got: %v", err) } }