diff --git a/lntemp/rpc/router.go b/lntemp/rpc/router.go index b5bd321a1..a136d74b3 100644 --- a/lntemp/rpc/router.go +++ b/lntemp/rpc/router.go @@ -177,3 +177,15 @@ func (h *HarnessRPC) HtlcInterceptor() (InterceptorClient, context.CancelFunc) { return resp, cancel } + +type TrackPaymentsClient routerrpc.Router_TrackPaymentsClient + +// TrackPayments makes a RPC call to the node's RouterClient and asserts. +func (h *HarnessRPC) TrackPayments( + req *routerrpc.TrackPaymentsRequest) TrackPaymentsClient { + + resp, err := h.Router.TrackPayments(h.runCtx, req) + h.NoError(err, "TrackPayments") + + return resp +} diff --git a/lntest/itest/list_on_test.go b/lntest/itest/list_on_test.go index 49a5d2571..71b2cc703 100644 --- a/lntest/itest/list_on_test.go +++ b/lntest/itest/list_on_test.go @@ -489,4 +489,8 @@ var allTestCasesTemp = []*lntemp.TestCase{ Name: "taproot coop close", TestFunc: testTaprootCoopClose, }, + { + Name: "trackpayments", + TestFunc: testTrackPayments, + }, } diff --git a/lntest/itest/lnd_test_list_on_test.go b/lntest/itest/lnd_test_list_on_test.go index 4b1e83d19..38489f510 100644 --- a/lntest/itest/lnd_test_list_on_test.go +++ b/lntest/itest/lnd_test_list_on_test.go @@ -8,10 +8,6 @@ var allTestCases = []*testCase{ name: "async bidirectional payments", test: testBidirectionalAsyncPayments, }, - { - name: "trackpayments", - test: testTrackPayments, - }, { name: "open channel fee policy", test: testOpenChannelUpdateFeePolicy, diff --git a/lntest/itest/lnd_trackpayments_test.go b/lntest/itest/lnd_trackpayments_test.go index 8819b95cc..2554471ef 100644 --- a/lntest/itest/lnd_trackpayments_test.go +++ b/lntest/itest/lnd_trackpayments_test.go @@ -1,102 +1,89 @@ package itest import ( - "context" "encoding/hex" + "time" "github.com/btcsuite/btcd/btcutil" "github.com/lightningnetwork/lnd/lnrpc" "github.com/lightningnetwork/lnd/lnrpc/routerrpc" - "github.com/lightningnetwork/lnd/lntest" + "github.com/lightningnetwork/lnd/lntemp" "github.com/stretchr/testify/require" ) // testTrackPayments tests whether a client that calls the TrackPayments api // receives payment updates. -func testTrackPayments(net *lntest.NetworkHarness, t *harnessTest) { +func testTrackPayments(ht *lntemp.HarnessTest) { // Open a channel between alice and bob. - net.EnsureConnected(t.t, net.Alice, net.Bob) - channel := openChannelAndAssert( - t, net, net.Alice, net.Bob, - lntest.OpenChannelParams{ + alice, bob := ht.Alice, ht.Bob + channel := ht.OpenChannel( + alice, bob, lntemp.OpenChannelParams{ Amt: btcutil.Amount(300000), }, ) - defer closeChannelAndAssert(t, net, net.Alice, channel, true) - - err := net.Alice.WaitForNetworkChannelOpen(channel) - require.NoError(t.t, err, "unable to wait for channel to open") - - ctxb := context.Background() - ctxt, cancelTracker := context.WithCancel(ctxb) - defer cancelTracker() // Call the TrackPayments api to listen for payment updates. - tracker, err := net.Alice.RouterClient.TrackPayments( - ctxt, - &routerrpc.TrackPaymentsRequest{ - NoInflightUpdates: false, - }, - ) - require.NoError(t.t, err, "failed to call TrackPayments successfully.") + req := &routerrpc.TrackPaymentsRequest{ + NoInflightUpdates: false, + } + tracker := alice.RPC.TrackPayments(req) // Create an invoice from bob. var amountMsat int64 = 1000 - invoiceResp, err := net.Bob.AddInvoice( - ctxb, + invoiceResp := bob.RPC.AddInvoice( &lnrpc.Invoice{ ValueMsat: amountMsat, }, ) - require.NoError(t.t, err, "unable to add invoice.") - - invoice, err := net.Bob.LookupInvoice( - ctxb, - &lnrpc.PaymentHash{ - RHashStr: hex.EncodeToString(invoiceResp.RHash), - }, - ) - require.NoError(t.t, err, "unable to find invoice.") + invoice := bob.RPC.LookupInvoice(invoiceResp.RHash) // Send payment from alice to bob. - paymentClient, err := net.Alice.RouterClient.SendPaymentV2( - ctxb, + paymentClient := alice.RPC.SendPayment( &routerrpc.SendPaymentRequest{ PaymentRequest: invoice.PaymentRequest, TimeoutSeconds: 60, }, ) - require.NoError(t.t, err, "unable to send payment.") // Make sure the payment doesn't error due to invalid parameters or so. - _, err = paymentClient.Recv() - require.NoError(t.t, err, "unable to get payment update.") + _, err := paymentClient.Recv() + require.NoError(ht, err, "unable to get payment update.") // Assert the first payment update is an inflight update. update1, err := tracker.Recv() - require.NoError(t.t, err, "unable to receive payment update 1.") + require.NoError(ht, err, "unable to receive payment update 1.") require.Equal( - t.t, lnrpc.PaymentFailureReason_FAILURE_REASON_NONE, + ht, lnrpc.PaymentFailureReason_FAILURE_REASON_NONE, update1.FailureReason, ) - require.Equal(t.t, lnrpc.Payment_IN_FLIGHT, update1.Status) - require.Equal(t.t, invoice.PaymentRequest, update1.PaymentRequest) - require.Equal(t.t, amountMsat, update1.ValueMsat) + require.Equal(ht, lnrpc.Payment_IN_FLIGHT, update1.Status) + require.Equal(ht, invoice.PaymentRequest, update1.PaymentRequest) + require.Equal(ht, amountMsat, update1.ValueMsat) // Assert the second payment update is a payment success update. update2, err := tracker.Recv() - require.NoError(t.t, err, "unable to receive payment update 2.") + require.NoError(ht, err, "unable to receive payment update 2.") require.Equal( - t.t, lnrpc.PaymentFailureReason_FAILURE_REASON_NONE, + ht, lnrpc.PaymentFailureReason_FAILURE_REASON_NONE, update2.FailureReason, ) - require.Equal(t.t, lnrpc.Payment_SUCCEEDED, update2.Status) - require.Equal(t.t, invoice.PaymentRequest, update2.PaymentRequest) - require.Equal(t.t, amountMsat, update2.ValueMsat) + require.Equal(ht, lnrpc.Payment_SUCCEEDED, update2.Status) + require.Equal(ht, invoice.PaymentRequest, update2.PaymentRequest) + require.Equal(ht, amountMsat, update2.ValueMsat) require.Equal( - t.t, hex.EncodeToString(invoice.RPreimage), + ht, hex.EncodeToString(invoice.RPreimage), update2.PaymentPreimage, ) + + // TODO(yy): remove the sleep once the following bug is fixed. + // When the invoice is reported settled, the commitment dance is not + // yet finished, which can cause an error when closing the channel, + // saying there's active HTLCs. We need to investigate this issue and + // reverse the order to, first finish the commitment dance, then report + // the invoice as settled. + time.Sleep(2 * time.Second) + + ht.CloseChannel(alice, channel) }