mirror of
https://github.com/lightningnetwork/lnd.git
synced 2024-11-19 18:10:34 +01:00
a1678fa9b7
Because we need to account for an addtional fee buffer we need to increase channel capacities for the multi payment tests.
109 lines
3.2 KiB
Go
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()
|
|
}
|