lnd/itest/lnd_send_multi_path_payment_test.go
ziggie a1678fa9b7
itest: multi part payments test fix.
Because we need to account for an addtional fee buffer we need to
increase channel capacities for the multi payment tests.
2024-01-08 16:47:47 +01:00

109 lines
3.2 KiB
Go

package itest
import (
"encoding/hex"
"github.com/btcsuite/btcd/btcutil"
"github.com/lightningnetwork/lnd/lnrpc"
"github.com/lightningnetwork/lnd/lnrpc/routerrpc"
"github.com/lightningnetwork/lnd/lntest"
"github.com/stretchr/testify/require"
)
// testSendMultiPathPayment tests that we are able to successfully route a
// payment using multiple shards across different paths.
func testSendMultiPathPayment(ht *lntest.HarnessTest) {
mts := newMppTestScenario(ht)
const paymentAmt = btcutil.Amount(300000)
// Set up a network with three different paths Alice <-> Bob. Channel
// capacities are set such that the payment can only succeed if (at
// least) three paths are used.
//
// _ Eve _
// / \
// Alice -- Carol ---- Bob
// \ /
// \__ Dave ____/
//
req := &mppOpenChannelRequest{
amtAliceCarol: 285000,
amtAliceDave: 155000,
amtCarolBob: 200000,
amtCarolEve: 155000,
amtDaveBob: 155000,
amtEveBob: 155000,
}
mts.openChannels(req)
chanPointAliceDave := mts.channelPoints[1]
// Increase Dave's fee to make the test deterministic. Otherwise it
// would be unpredictable whether pathfinding would go through Charlie
// or Dave for the first shard.
expectedPolicy := mts.updateDaveGlobalPolicy()
// Make sure Alice has heard it.
ht.AssertChannelPolicyUpdate(
mts.alice, mts.dave, expectedPolicy, chanPointAliceDave, false,
)
// Our first test will be Alice paying Bob using a SendPayment call.
// Let Bob create an invoice for Alice to pay.
payReqs, rHashes, invoices := ht.CreatePayReqs(mts.bob, paymentAmt, 1)
rHash := rHashes[0]
payReq := payReqs[0]
sendReq := &routerrpc.SendPaymentRequest{
PaymentRequest: payReq,
MaxParts: 10,
TimeoutSeconds: 60,
FeeLimitMsat: noFeeLimitMsat,
}
payment := ht.SendPaymentAssertSettled(mts.alice, sendReq)
// Make sure we got the preimage.
require.Equal(ht, hex.EncodeToString(invoices[0].RPreimage),
payment.PaymentPreimage, "preimage doesn't match")
// 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),
// there is some non-determinism in the process. Depending on whether
// the new pathfinding round is started before or after the htlc is
// locked into the channel, different sharding may occur. Therefore we
// can only check if the number of shards isn't below the theoretical
// minimum.
succeeded := 0
for _, htlc := range payment.Htlcs {
if htlc.Status == lnrpc.HTLCAttempt_SUCCEEDED {
succeeded++
}
}
const minExpectedShards = 3
require.GreaterOrEqual(ht, succeeded, minExpectedShards,
"expected shards not reached")
// Make sure Bob show the invoice as settled for the full amount.
inv := mts.bob.RPC.LookupInvoice(rHash)
require.EqualValues(ht, paymentAmt, inv.AmtPaidSat,
"incorrect payment amt")
require.Equal(ht, lnrpc.Invoice_SETTLED, inv.State,
"Invoice not settled")
settled := 0
for _, htlc := range inv.Htlcs {
if htlc.State == lnrpc.InvoiceHTLCState_SETTLED {
settled++
}
}
require.Equal(ht, succeeded, settled,
"num of HTLCs wrong")
// Finally, close all channels.
mts.closeChannels()
}