mirror of
https://github.com/lightningnetwork/lnd.git
synced 2025-01-19 05:45:21 +01:00
itest: refactor testSendMultiPathPayment
This commit is contained in:
parent
1f1123523e
commit
4292c05e04
@ -389,4 +389,8 @@ var allTestCasesTemp = []*lntemp.TestCase{
|
|||||||
Name: "sendtoroute multi path payment",
|
Name: "sendtoroute multi path payment",
|
||||||
TestFunc: testSendToRouteMultiPath,
|
TestFunc: testSendToRouteMultiPath,
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
Name: "send multi path payment",
|
||||||
|
TestFunc: testSendMultiPathPayment,
|
||||||
|
},
|
||||||
}
|
}
|
||||||
|
@ -439,6 +439,15 @@ func (m *mppTestScenario) closeChannels() {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TODO(yy): remove the sleep once the following bug is fixed. When the
|
||||||
|
// payment is reported as settled by Alice, it's expected the
|
||||||
|
// commitment dance is finished and all subsequent states have been
|
||||||
|
// updated. Yet we'd receive the error `cannot co-op close channel with
|
||||||
|
// active htlcs` or `link failed to shutdown` if we close the channel.
|
||||||
|
// We need to investigate the order of settling the payments and
|
||||||
|
// updating commitments to understand and fix .
|
||||||
|
time.Sleep(2 * time.Second)
|
||||||
|
|
||||||
// Close all channels without mining the closing transactions.
|
// Close all channels without mining the closing transactions.
|
||||||
m.ht.CloseChannelAssertPending(m.alice, m.channelPoints[0], false)
|
m.ht.CloseChannelAssertPending(m.alice, m.channelPoints[0], false)
|
||||||
m.ht.CloseChannelAssertPending(m.alice, m.channelPoints[1], false)
|
m.ht.CloseChannelAssertPending(m.alice, m.channelPoints[1], false)
|
||||||
|
@ -1,22 +1,19 @@
|
|||||||
package itest
|
package itest
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
|
||||||
"encoding/hex"
|
"encoding/hex"
|
||||||
|
|
||||||
"github.com/btcsuite/btcd/btcutil"
|
"github.com/btcsuite/btcd/btcutil"
|
||||||
"github.com/lightningnetwork/lnd/lnrpc"
|
"github.com/lightningnetwork/lnd/lnrpc"
|
||||||
"github.com/lightningnetwork/lnd/lnrpc/routerrpc"
|
"github.com/lightningnetwork/lnd/lnrpc/routerrpc"
|
||||||
"github.com/lightningnetwork/lnd/lntest"
|
"github.com/lightningnetwork/lnd/lntemp"
|
||||||
|
"github.com/stretchr/testify/require"
|
||||||
)
|
)
|
||||||
|
|
||||||
// testSendMultiPathPayment tests that we are able to successfully route a
|
// testSendMultiPathPayment tests that we are able to successfully route a
|
||||||
// payment using multiple shards across different paths.
|
// payment using multiple shards across different paths.
|
||||||
func testSendMultiPathPayment(net *lntest.NetworkHarness, t *harnessTest) {
|
func testSendMultiPathPayment(ht *lntemp.HarnessTest) {
|
||||||
ctxb := context.Background()
|
mts := newMppTestScenario(ht)
|
||||||
|
|
||||||
ctx := newMppTestContext(t, net)
|
|
||||||
defer ctx.shutdownNodes()
|
|
||||||
|
|
||||||
const paymentAmt = btcutil.Amount(300000)
|
const paymentAmt = btcutil.Amount(300000)
|
||||||
|
|
||||||
@ -30,57 +27,45 @@ func testSendMultiPathPayment(net *lntest.NetworkHarness, t *harnessTest) {
|
|||||||
// \ /
|
// \ /
|
||||||
// \__ Dave ____/
|
// \__ Dave ____/
|
||||||
//
|
//
|
||||||
ctx.openChannel(ctx.carol, ctx.bob, 135000)
|
req := &mppOpenChannelRequest{
|
||||||
ctx.openChannel(ctx.alice, ctx.carol, 235000)
|
amtAliceCarol: 235000,
|
||||||
ctx.openChannel(ctx.dave, ctx.bob, 135000)
|
amtAliceDave: 135000,
|
||||||
ctx.openChannel(ctx.alice, ctx.dave, 135000)
|
amtCarolBob: 135000,
|
||||||
ctx.openChannel(ctx.eve, ctx.bob, 135000)
|
amtCarolEve: 135000,
|
||||||
ctx.openChannel(ctx.carol, ctx.eve, 135000)
|
amtDaveBob: 135000,
|
||||||
|
amtEveBob: 135000,
|
||||||
defer ctx.closeChannels()
|
}
|
||||||
|
mts.openChannels(req)
|
||||||
ctx.waitForChannels()
|
chanPointAliceDave := mts.channelPoints[1]
|
||||||
|
|
||||||
// Increase Dave's fee to make the test deterministic. Otherwise it
|
// Increase Dave's fee to make the test deterministic. Otherwise it
|
||||||
// would be unpredictable whether pathfinding would go through Charlie
|
// would be unpredictable whether pathfinding would go through Charlie
|
||||||
// or Dave for the first shard.
|
// or Dave for the first shard.
|
||||||
_, err := ctx.dave.UpdateChannelPolicy(
|
expectedPolicy := mts.updateDaveGlobalPolicy()
|
||||||
context.Background(),
|
|
||||||
&lnrpc.PolicyUpdateRequest{
|
// Make sure Alice has heard it.
|
||||||
Scope: &lnrpc.PolicyUpdateRequest_Global{Global: true},
|
ht.AssertChannelPolicyUpdate(
|
||||||
BaseFeeMsat: 500000,
|
mts.alice, mts.dave, expectedPolicy, chanPointAliceDave, false,
|
||||||
FeeRate: 0.001,
|
|
||||||
TimeLockDelta: 40,
|
|
||||||
},
|
|
||||||
)
|
)
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("dave policy update: %v", err)
|
|
||||||
}
|
|
||||||
// Our first test will be Alice paying Bob using a SendPayment call.
|
// Our first test will be Alice paying Bob using a SendPayment call.
|
||||||
// Let Bob create an invoice for Alice to pay.
|
// Let Bob create an invoice for Alice to pay.
|
||||||
payReqs, rHashes, invoices, err := createPayReqs(
|
payReqs, rHashes, invoices := ht.CreatePayReqs(mts.bob, paymentAmt, 1)
|
||||||
ctx.bob, paymentAmt, 1,
|
|
||||||
)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("unable to create pay reqs: %v", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
rHash := rHashes[0]
|
rHash := rHashes[0]
|
||||||
payReq := payReqs[0]
|
payReq := payReqs[0]
|
||||||
|
|
||||||
payment := sendAndAssertSuccess(
|
sendReq := &routerrpc.SendPaymentRequest{
|
||||||
t, ctx.alice, &routerrpc.SendPaymentRequest{
|
PaymentRequest: payReq,
|
||||||
PaymentRequest: payReq,
|
MaxParts: 10,
|
||||||
MaxParts: 10,
|
TimeoutSeconds: 60,
|
||||||
TimeoutSeconds: 60,
|
FeeLimitMsat: noFeeLimitMsat,
|
||||||
FeeLimitMsat: noFeeLimitMsat,
|
}
|
||||||
},
|
payment := ht.SendPaymentAssertSettled(mts.alice, sendReq)
|
||||||
)
|
|
||||||
|
|
||||||
// Make sure we got the preimage.
|
// Make sure we got the preimage.
|
||||||
if payment.PaymentPreimage != hex.EncodeToString(invoices[0].RPreimage) {
|
require.Equal(ht, hex.EncodeToString(invoices[0].RPreimage),
|
||||||
t.Fatalf("preimage doesn't match")
|
payment.PaymentPreimage, "preimage doesn't match")
|
||||||
}
|
|
||||||
|
|
||||||
// Check that Alice split the payment in at least three shards. Because
|
// Check that Alice split the payment in at least three shards. Because
|
||||||
// the hand-off of the htlc to the link is asynchronous (via a mailbox),
|
// the hand-off of the htlc to the link is asynchronous (via a mailbox),
|
||||||
@ -97,32 +82,17 @@ func testSendMultiPathPayment(net *lntest.NetworkHarness, t *harnessTest) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const minExpectedShards = 3
|
const minExpectedShards = 3
|
||||||
if succeeded < minExpectedShards {
|
require.GreaterOrEqual(ht, succeeded, minExpectedShards,
|
||||||
t.Fatalf("expected at least %v shards, but got %v",
|
"expected shards not reached")
|
||||||
minExpectedShards, succeeded)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Make sure Bob show the invoice as settled for the full
|
// Make sure Bob show the invoice as settled for the full amount.
|
||||||
// amount.
|
inv := mts.bob.RPC.LookupInvoice(rHash)
|
||||||
ctxt, _ := context.WithTimeout(ctxb, defaultTimeout)
|
|
||||||
inv, err := ctx.bob.LookupInvoice(
|
|
||||||
ctxt, &lnrpc.PaymentHash{
|
|
||||||
RHash: rHash,
|
|
||||||
},
|
|
||||||
)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("error when obtaining invoice: %v", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
if inv.AmtPaidSat != int64(paymentAmt) {
|
require.EqualValues(ht, paymentAmt, inv.AmtPaidSat,
|
||||||
t.Fatalf("incorrect payment amt for invoice"+
|
"incorrect payment amt")
|
||||||
"want: %d, got %d",
|
|
||||||
paymentAmt, inv.AmtPaidSat)
|
|
||||||
}
|
|
||||||
|
|
||||||
if inv.State != lnrpc.Invoice_SETTLED {
|
require.Equal(ht, lnrpc.Invoice_SETTLED, inv.State,
|
||||||
t.Fatalf("Invoice not settled: %v", inv.State)
|
"Invoice not settled")
|
||||||
}
|
|
||||||
|
|
||||||
settled := 0
|
settled := 0
|
||||||
for _, htlc := range inv.Htlcs {
|
for _, htlc := range inv.Htlcs {
|
||||||
@ -130,8 +100,9 @@ func testSendMultiPathPayment(net *lntest.NetworkHarness, t *harnessTest) {
|
|||||||
settled++
|
settled++
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if settled != succeeded {
|
require.Equal(ht, succeeded, settled,
|
||||||
t.Fatalf("expected invoice to be settled "+
|
"num of HTLCs wrong")
|
||||||
"with %v HTLCs, had %v", succeeded, settled)
|
|
||||||
}
|
// Finally, close all channels.
|
||||||
|
mts.closeChannels()
|
||||||
}
|
}
|
||||||
|
@ -56,10 +56,6 @@ var allTestCases = []*testCase{
|
|||||||
name: "sendpayment amp invoice repeat",
|
name: "sendpayment amp invoice repeat",
|
||||||
test: testSendPaymentAMPInvoiceRepeat,
|
test: testSendPaymentAMPInvoiceRepeat,
|
||||||
},
|
},
|
||||||
{
|
|
||||||
name: "send multi path payment",
|
|
||||||
test: testSendMultiPathPayment,
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
name: "forward interceptor",
|
name: "forward interceptor",
|
||||||
test: testForwardInterceptorBasic,
|
test: testForwardInterceptorBasic,
|
||||||
|
Loading…
Reference in New Issue
Block a user