diff --git a/htlcswitch/link_test.go b/htlcswitch/link_test.go index c26f68451..fc9655ebb 100644 --- a/htlcswitch/link_test.go +++ b/htlcswitch/link_test.go @@ -14,6 +14,7 @@ import ( "math" "github.com/davecgh/go-spew/spew" + "github.com/go-errors/errors" "github.com/lightningnetwork/lnd/chainntnfs" "github.com/lightningnetwork/lnd/lnwallet" "github.com/lightningnetwork/lnd/lnwire" @@ -189,7 +190,8 @@ func TestChannelLinkSingleHopPayment(t *testing.T) { // * alice<->bob commitment state to be updated. // * user notification to be sent. invoice, err := n.makePayment(n.aliceServer, n.bobServer, - n.bobServer.PubKey(), hops, amount, htlcAmt, totalTimelock) + n.bobServer.PubKey(), hops, amount, htlcAmt, + totalTimelock).Wait(10 * time.Second) if err != nil { t.Fatalf("unable to make the payment: %v", err) } @@ -275,7 +277,7 @@ func TestChannelLinkBidirectionalOneHopPayments(t *testing.T) { _, r.err = n.makePayment(n.aliceServer, n.bobServer, n.bobServer.PubKey(), hopsForwards, amt, htlcAmt, - totalTimelock) + totalTimelock).Wait(30 * time.Second) resultChan <- r }(i) } @@ -290,7 +292,7 @@ func TestChannelLinkBidirectionalOneHopPayments(t *testing.T) { _, r.err = n.makePayment(n.bobServer, n.aliceServer, n.aliceServer.PubKey(), hopsBackwards, amt, htlcAmt, - totalTimelock) + totalTimelock).Wait(30 * time.Second) resultChan <- r }(i) } @@ -398,7 +400,7 @@ func TestChannelLinkMultiHopPayment(t *testing.T) { // * user notification to be sent. invoice, err := n.makePayment(n.aliceServer, n.carolServer, n.bobServer.PubKey(), hops, amount, htlcAmt, - totalTimelock) + totalTimelock).Wait(10 * time.Second) if err != nil { t.Fatalf("unable to send payment: %v", err) } @@ -467,7 +469,8 @@ func TestExitNodeTimelockPayloadMismatch(t *testing.T) { hops[0].OutgoingCTLV = 500 _, err := n.makePayment(n.aliceServer, n.bobServer, - n.bobServer.PubKey(), hops, amount, htlcAmt, htlcExpiry) + n.bobServer.PubKey(), hops, amount, htlcAmt, + htlcExpiry).Wait(10 * time.Second) if err == nil { t.Fatalf("payment should have failed but didn't") } @@ -515,7 +518,8 @@ func TestExitNodeAmountPayloadMismatch(t *testing.T) { hops[0].AmountToForward = 1 _, err := n.makePayment(n.aliceServer, n.bobServer, - n.bobServer.PubKey(), hops, amount, htlcAmt, htlcExpiry) + n.bobServer.PubKey(), hops, amount, htlcAmt, + htlcExpiry).Wait(10 * time.Second) if err == nil { t.Fatalf("payment should have failed but didn't") } else if err.Error() != lnwire.CodeIncorrectPaymentAmount.String() { @@ -557,8 +561,8 @@ func TestLinkForwardTimelockPolicyMismatch(t *testing.T) { // Next, we'll make the payment which'll send an HTLC with our // specified parameters to the first hop in the route. _, err := n.makePayment(n.aliceServer, n.carolServer, - n.bobServer.PubKey(), hops, amount, htlcAmt, htlcExpiry) - + n.bobServer.PubKey(), hops, amount, htlcAmt, + htlcExpiry).Wait(10 * time.Second) // We should get an error, and that error should indicate that the HTLC // should be rejected due to a policy violation. if err == nil { @@ -610,7 +614,7 @@ func TestLinkForwardFeePolicyMismatch(t *testing.T) { // specified parameters to the first hop in the route. _, err := n.makePayment(n.aliceServer, n.bobServer, n.bobServer.PubKey(), hops, amountNoFee, amountNoFee, - htlcExpiry) + htlcExpiry).Wait(10 * time.Second) // We should get an error, and that error should indicate that the HTLC // should be rejected due to a policy violation. @@ -663,7 +667,7 @@ func TestLinkForwardMinHTLCPolicyMismatch(t *testing.T) { // specified parameters to the first hop in the route. _, err := n.makePayment(n.aliceServer, n.bobServer, n.bobServer.PubKey(), hops, amountNoFee, htlcAmt, - htlcExpiry) + htlcExpiry).Wait(10 * time.Second) // We should get an error, and that error should indicate that the HTLC // should be rejected due to a policy violation (below min HTLC). @@ -717,7 +721,7 @@ func TestUpdateForwardingPolicy(t *testing.T) { // should succeed, and all balances should be updated accordingly. invoice, err := n.makePayment(n.aliceServer, n.carolServer, n.bobServer.PubKey(), hops, amountNoFee, htlcAmt, - htlcExpiry) + htlcExpiry).Wait(10 * time.Second) if err != nil { t.Fatalf("unable to send payment: %v", err) } @@ -813,8 +817,9 @@ func TestChannelLinkMultiHopInsufficientPayment(t *testing.T) { // * Bob trying to add HTLC add request in Bob<->Carol channel. // * Cancel HTLC request to be sent back from Bob to Alice. // * user notification to be sent. - invoice, err := n.makePayment(n.aliceServer, n.bobServer, - n.bobServer.PubKey(), hops, amount, htlcAmt, totalTimelock) + invoice, err := n.makePayment(n.aliceServer, n.carolServer, + n.bobServer.PubKey(), hops, amount, htlcAmt, + totalTimelock).Wait(10 * time.Second) if err == nil { t.Fatal("error haven't been received") } else if !strings.Contains(err.Error(), "insufficient capacity") { @@ -966,8 +971,9 @@ func TestChannelLinkMultiHopUnknownNextHop(t *testing.T) { n.firstBobChannelLink, n.carolChannelLink) davePub := newMockServer("save", serverErr).PubKey() + invoice, err := n.makePayment(n.aliceServer, n.bobServer, davePub, hops, - amount, htlcAmt, totalTimelock) + amount, htlcAmt, totalTimelock).Wait(10 * time.Second) if err == nil { t.Fatal("error haven't been received") } else if err.Error() != lnwire.CodeUnknownNextPeer.String() { @@ -1039,7 +1045,8 @@ func TestChannelLinkMultiHopDecodeError(t *testing.T) { n.firstBobChannelLink, n.carolChannelLink) invoice, err := n.makePayment(n.aliceServer, n.carolServer, - n.bobServer.PubKey(), hops, amount, htlcAmt, totalTimelock) + n.bobServer.PubKey(), hops, amount, htlcAmt, + totalTimelock).Wait(10 * time.Second) if err == nil { t.Fatal("error haven't been received") } @@ -1245,12 +1252,14 @@ func TestChannelLinkSingleHopMessageOrdering(t *testing.T) { n.firstBobChannelLink) // Wait for: - // * htlc add htlc request to be sent to alice - // * alice<->bob commitment state to be updated - // * settle request to be sent back from alice to bob - // * alice<->bob commitment state to be updated - _, err := n.makePayment(n.aliceServer, n.bobServer, - n.bobServer.PubKey(), hops, amount, htlcAmt, totalTimelock) + // * HTLC add request to be sent to bob. + // * alice<->bob commitment state to be updated. + // * settle request to be sent back from bob to alice. + // * alice<->bob commitment state to be updated. + // * user notification to be sent. + _, err = n.makePayment(n.aliceServer, n.bobServer, + n.bobServer.PubKey(), hops, amount, htlcAmt, + totalTimelock).Wait(10 * time.Second) if err != nil { t.Fatalf("unable to make the payment: %v", err) } diff --git a/htlcswitch/test_utils.go b/htlcswitch/test_utils.go index 6a65875e1..be1f56fd9 100644 --- a/htlcswitch/test_utils.go +++ b/htlcswitch/test_utils.go @@ -402,6 +402,21 @@ func generateHops(payAmt lnwire.MilliSatoshi, startingHeight uint32, return runningAmt, totalTimelock, hops } +type paymentResponse struct { + invoice *channeldb.Invoice + err chan error +} + +func (r *paymentResponse) Wait(d time.Duration) (*channeldb.Invoice, error) { + select { + case err := <-r.err: + close(r.err) + return r.invoice, err + case <-time.After(d): + return r.invoice, errors.New("htlc was no settled in time") + } +} + // makePayment takes the destination node and amount as input, sends the // payment and returns the error channel to wait for error to be received and // invoice in order to check its status after the payment finished. @@ -413,7 +428,9 @@ func generateHops(payAmt lnwire.MilliSatoshi, startingHeight uint32, func (n *threeHopNetwork) makePayment(sendingPeer, receivingPeer Peer, firstHopPub [33]byte, hops []ForwardingInfo, invoiceAmt, htlcAmt lnwire.MilliSatoshi, - timelock uint32) (*channeldb.Invoice, error) { + timelock uint32) *paymentResponse { + + paymentErr := make(chan error, 1) sender := sendingPeer.(*mockServer) receiver := receivingPeer.(*mockServer) @@ -422,19 +439,31 @@ func (n *threeHopNetwork) makePayment(sendingPeer, receivingPeer Peer, // htlc add request. blob, err := generateRoute(hops...) if err != nil { - return nil, err + paymentErr <- err + return &paymentResponse{ + invoice: nil, + err: paymentErr, + } } // Generate payment: invoice and htlc. invoice, htlc, err := generatePayment(invoiceAmt, htlcAmt, timelock, blob) if err != nil { - return nil, err + paymentErr <- err + return &paymentResponse{ + invoice: nil, + err: paymentErr, + } } // Check who is last in the route and add invoice to server registry. if err := receiver.registry.AddInvoice(invoice); err != nil { - return nil, err + paymentErr <- err + return &paymentResponse{ + invoice: invoice, + err: paymentErr, + } } // Send payment and expose err channel. @@ -445,11 +474,9 @@ func (n *threeHopNetwork) makePayment(sendingPeer, receivingPeer Peer, errChan <- err }() - select { - case err := <-errChan: - return invoice, err - case <-time.After(5 * time.Minute): - return invoice, errors.New("htlc was not settled in time") + return &paymentResponse{ + invoice: invoice, + err: errChan, } }