diff --git a/lntest/itest/list_on_test.go b/lntest/itest/list_on_test.go index feb1441e2..772b0a656 100644 --- a/lntest/itest/list_on_test.go +++ b/lntest/itest/list_on_test.go @@ -329,4 +329,8 @@ var allTestCasesTemp = []*lntemp.TestCase{ Name: "invoice routing hints", TestFunc: testInvoiceRoutingHints, }, + { + Name: "multi-hop payments over private channels", + TestFunc: testMultiHopOverPrivateChannels, + }, } diff --git a/lntest/itest/lnd_routing_test.go b/lntest/itest/lnd_routing_test.go index 2932cb2b9..c325849ee 100644 --- a/lntest/itest/lnd_routing_test.go +++ b/lntest/itest/lnd_routing_test.go @@ -746,9 +746,7 @@ func testInvoiceRoutingHints(ht *lntemp.HarnessTest) { // testMultiHopOverPrivateChannels tests that private channels can be used as // intermediate hops in a route for payments. -func testMultiHopOverPrivateChannels(net *lntest.NetworkHarness, t *harnessTest) { - ctxb := context.Background() - +func testMultiHopOverPrivateChannels(ht *lntemp.HarnessTest) { // We'll test that multi-hop payments over private channels work as // intended. To do so, we'll create the following topology: // private public private @@ -757,115 +755,42 @@ func testMultiHopOverPrivateChannels(net *lntest.NetworkHarness, t *harnessTest) // First, we'll open a private channel between Alice and Bob with Alice // being the funder. - chanPointAlice := openChannelAndAssert( - t, net, net.Alice, net.Bob, - lntest.OpenChannelParams{ + alice, bob := ht.Alice, ht.Bob + chanPointAlice := ht.OpenChannel( + alice, bob, lntemp.OpenChannelParams{ Amt: chanAmt, Private: true, }, ) - err := net.Alice.WaitForNetworkChannelOpen(chanPointAlice) - if err != nil { - t.Fatalf("alice didn't see the channel alice <-> bob before "+ - "timeout: %v", err) - } - err = net.Bob.WaitForNetworkChannelOpen(chanPointAlice) - if err != nil { - t.Fatalf("bob didn't see the channel alice <-> bob before "+ - "timeout: %v", err) - } - - // Retrieve Alice's funding outpoint. - aliceChanTXID, err := lnrpc.GetChanPointFundingTxid(chanPointAlice) - if err != nil { - t.Fatalf("unable to get txid: %v", err) - } - aliceFundPoint := wire.OutPoint{ - Hash: *aliceChanTXID, - Index: chanPointAlice.OutputIndex, - } - // Next, we'll create Carol's node and open a public channel between // her and Bob with Bob being the funder. - carol := net.NewNode(t.t, "Carol", nil) - defer shutdownAndAssert(net, t, carol) - - net.ConnectNodes(t.t, net.Bob, carol) - chanPointBob := openChannelAndAssert( - t, net, net.Bob, carol, - lntest.OpenChannelParams{ + carol := ht.NewNode("Carol", nil) + ht.ConnectNodes(bob, carol) + chanPointBob := ht.OpenChannel( + bob, carol, lntemp.OpenChannelParams{ Amt: chanAmt, }, ) - err = net.Bob.WaitForNetworkChannelOpen(chanPointBob) - if err != nil { - t.Fatalf("bob didn't see the channel bob <-> carol before "+ - "timeout: %v", err) - } - err = carol.WaitForNetworkChannelOpen(chanPointBob) - if err != nil { - t.Fatalf("carol didn't see the channel bob <-> carol before "+ - "timeout: %v", err) - } - err = net.Alice.WaitForNetworkChannelOpen(chanPointBob) - if err != nil { - t.Fatalf("alice didn't see the channel bob <-> carol before "+ - "timeout: %v", err) - } + // Alice should know the new channel from Bob. + ht.AssertTopologyChannelOpen(alice, chanPointBob) - // Retrieve Bob's funding outpoint. - bobChanTXID, err := lnrpc.GetChanPointFundingTxid(chanPointBob) - if err != nil { - t.Fatalf("unable to get txid: %v", err) - } - bobFundPoint := wire.OutPoint{ - Hash: *bobChanTXID, - Index: chanPointBob.OutputIndex, - } + // Next, we'll create Dave's node and open a private channel between + // him and Carol with Carol being the funder. + dave := ht.NewNode("Dave", nil) + ht.ConnectNodes(carol, dave) + ht.FundCoins(btcutil.SatoshiPerBitcoin, carol) - // Next, we'll create Dave's node and open a private channel between him - // and Carol with Carol being the funder. - dave := net.NewNode(t.t, "Dave", nil) - defer shutdownAndAssert(net, t, dave) - - net.ConnectNodes(t.t, carol, dave) - net.SendCoins(t.t, btcutil.SatoshiPerBitcoin, carol) - - chanPointCarol := openChannelAndAssert( - t, net, carol, dave, - lntest.OpenChannelParams{ + chanPointCarol := ht.OpenChannel( + carol, dave, lntemp.OpenChannelParams{ Amt: chanAmt, Private: true, }, ) - err = carol.WaitForNetworkChannelOpen(chanPointCarol) - if err != nil { - t.Fatalf("carol didn't see the channel carol <-> dave before "+ - "timeout: %v", err) - } - err = dave.WaitForNetworkChannelOpen(chanPointCarol) - if err != nil { - t.Fatalf("dave didn't see the channel carol <-> dave before "+ - "timeout: %v", err) - } - err = dave.WaitForNetworkChannelOpen(chanPointBob) - if err != nil { - t.Fatalf("dave didn't see the channel bob <-> carol before "+ - "timeout: %v", err) - } - - // Retrieve Carol's funding point. - carolChanTXID, err := lnrpc.GetChanPointFundingTxid(chanPointCarol) - if err != nil { - t.Fatalf("unable to get txid: %v", err) - } - carolFundPoint := wire.OutPoint{ - Hash: *carolChanTXID, - Index: chanPointCarol.OutputIndex, - } + // Dave should know the channel[Bob<->Carol] from Carol. + ht.AssertTopologyChannelOpen(dave, chanPointBob) // Now that all the channels are set up according to the topology from // above, we can proceed to test payments. We'll create an invoice for @@ -880,21 +805,11 @@ func testMultiHopOverPrivateChannels(net *lntest.NetworkHarness, t *harnessTest) Value: paymentAmt, Private: true, } - - ctxt, _ := context.WithTimeout(ctxb, defaultTimeout) - resp, err := dave.AddInvoice(ctxt, invoice) - if err != nil { - t.Fatalf("unable to add invoice for dave: %v", err) - } + resp := dave.RPC.AddInvoice(invoice) // Let Alice pay the invoice. payReqs := []string{resp.PaymentRequest} - err = completePaymentRequests( - net.Alice, net.Alice.RouterClient, payReqs, true, - ) - if err != nil { - t.Fatalf("unable to send payments from alice to dave: %v", err) - } + ht.CompletePaymentRequests(alice, payReqs) // When asserting the amount of satoshis moved, we'll factor in the // default base fee, as we didn't modify the fee structure when opening @@ -902,39 +817,34 @@ func testMultiHopOverPrivateChannels(net *lntest.NetworkHarness, t *harnessTest) const baseFee = 1 // Dave should have received 20k satoshis from Carol. - assertAmountPaid(t, "Carol(local) [private=>] Dave(remote)", - dave, carolFundPoint, 0, paymentAmt) + ht.AssertAmountPaid("Carol(local) [private=>] Dave(remote)", + dave, chanPointCarol, 0, paymentAmt) // Carol should have sent 20k satoshis to Dave. - assertAmountPaid(t, "Carol(local) [private=>] Dave(remote)", - carol, carolFundPoint, paymentAmt, 0) + ht.AssertAmountPaid("Carol(local) [private=>] Dave(remote)", + carol, chanPointCarol, paymentAmt, 0) // Carol should have received 20k satoshis + fee for one hop from Bob. - assertAmountPaid(t, "Bob(local) => Carol(remote)", - carol, bobFundPoint, 0, paymentAmt+baseFee) + ht.AssertAmountPaid("Bob(local) => Carol(remote)", + carol, chanPointBob, 0, paymentAmt+baseFee) // Bob should have sent 20k satoshis + fee for one hop to Carol. - assertAmountPaid(t, "Bob(local) => Carol(remote)", - net.Bob, bobFundPoint, paymentAmt+baseFee, 0) + ht.AssertAmountPaid("Bob(local) => Carol(remote)", + bob, chanPointBob, paymentAmt+baseFee, 0) // Bob should have received 20k satoshis + fee for two hops from Alice. - assertAmountPaid(t, "Alice(local) [private=>] Bob(remote)", net.Bob, - aliceFundPoint, 0, paymentAmt+baseFee*2) + ht.AssertAmountPaid("Alice(local) [private=>] Bob(remote)", bob, + chanPointAlice, 0, paymentAmt+baseFee*2) // Alice should have sent 20k satoshis + fee for two hops to Bob. - assertAmountPaid(t, "Alice(local) [private=>] Bob(remote)", net.Alice, - aliceFundPoint, paymentAmt+baseFee*2, 0) + ht.AssertAmountPaid("Alice(local) [private=>] Bob(remote)", alice, + chanPointAlice, paymentAmt+baseFee*2, 0) // At this point, the payment was successful. We can now close all the // channels and shutdown the nodes created throughout this test. - closeChannelAndAssert(t, net, net.Alice, chanPointAlice, false) - closeChannelAndAssert(t, net, net.Bob, chanPointBob, false) - closeChannelAndAssert(t, net, carol, chanPointCarol, false) -} - -// computeFee calculates the payment fee as specified in BOLT07. -func computeFee(baseFee, feeRate, amt lnwire.MilliSatoshi) lnwire.MilliSatoshi { - return baseFee + amt*feeRate/1000000 + ht.CloseChannel(alice, chanPointAlice) + ht.CloseChannel(bob, chanPointBob) + ht.CloseChannel(carol, chanPointCarol) } // testQueryRoutes checks the response of queryroutes. @@ -1460,3 +1370,8 @@ func testRouteFeeCutoff(net *lntest.NetworkHarness, t *harnessTest) { closeChannelAndAssert(t, net, net.Bob, chanPointBobDave, false) closeChannelAndAssert(t, net, carol, chanPointCarolDave, false) } + +// computeFee calculates the payment fee as specified in BOLT07. +func computeFee(baseFee, feeRate, amt lnwire.MilliSatoshi) lnwire.MilliSatoshi { + return baseFee + amt*feeRate/1000000 +} diff --git a/lntest/itest/lnd_test_list_on_test.go b/lntest/itest/lnd_test_list_on_test.go index 26c668727..7b444e26d 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: "single hop invoice", test: testSingleHopInvoice, }, - { - name: "multi-hop payments over private channels", - test: testMultiHopOverPrivateChannels, - }, { name: "multiple channel creation and update subscription", test: testBasicChannelCreationAndUpdates,