mirror of
https://github.com/lightningnetwork/lnd.git
synced 2025-05-14 05:40:12 +02:00
itest: put mpp tests in one file
This commit is contained in:
parent
fee6b70519
commit
8f3100c984
@ -1,6 +1,7 @@
|
|||||||
package itest
|
package itest
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"encoding/hex"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/btcsuite/btcd/btcutil"
|
"github.com/btcsuite/btcd/btcutil"
|
||||||
@ -14,6 +15,110 @@ import (
|
|||||||
"github.com/stretchr/testify/require"
|
"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 := &lnrpc.RoutingPolicy{
|
||||||
|
FeeBaseMsat: 500_000,
|
||||||
|
FeeRateMilliMsat: int64(0.001 * 1_000_000),
|
||||||
|
TimeLockDelta: 40,
|
||||||
|
MinHtlc: 1000, // default value
|
||||||
|
MaxHtlcMsat: 133_650_000,
|
||||||
|
}
|
||||||
|
mts.dave.UpdateGlobalPolicy(expectedPolicy)
|
||||||
|
|
||||||
|
// 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()
|
||||||
|
}
|
||||||
|
|
||||||
// testSendToRouteMultiPath tests that we are able to successfully route a
|
// testSendToRouteMultiPath tests that we are able to successfully route a
|
||||||
// payment using multiple shards across different paths, by using SendToRoute.
|
// payment using multiple shards across different paths, by using SendToRoute.
|
||||||
func testSendToRouteMultiPath(ht *lntest.HarnessTest) {
|
func testSendToRouteMultiPath(ht *lntest.HarnessTest) {
|
||||||
|
@ -1,115 +0,0 @@
|
|||||||
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 := &lnrpc.RoutingPolicy{
|
|
||||||
FeeBaseMsat: 500_000,
|
|
||||||
FeeRateMilliMsat: int64(0.001 * 1_000_000),
|
|
||||||
TimeLockDelta: 40,
|
|
||||||
MinHtlc: 1000, // default value
|
|
||||||
MaxHtlcMsat: 133_650_000,
|
|
||||||
}
|
|
||||||
mts.dave.UpdateGlobalPolicy(expectedPolicy)
|
|
||||||
|
|
||||||
// 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()
|
|
||||||
}
|
|
Loading…
x
Reference in New Issue
Block a user