itest: refactor testSendPaymentAMP
This commit is contained in:
4 files changed
+65
-65
No files matched your search
@@ -241,6 +241,14 @@ func (s *State) updatePaymentStats() {
|
|||||||
}
|
}
|
||||||
resp := s.rpc.ListPayments(req)
|
resp := s.rpc.ListPayments(req)
|
||||||
|
|
||||||
|
// Exit early when the there's no payment.
|
||||||
|
//
|
||||||
|
// NOTE: we need to exit early here because when there's no invoice the
|
||||||
|
// `LastOffsetIndex` will be zero.
|
||||||
|
if len(resp.Payments) == 0 {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
s.Payment.LastIndexOffset = resp.LastIndexOffset
|
s.Payment.LastIndexOffset = resp.LastIndexOffset
|
||||||
for _, payment := range resp.Payments {
|
for _, payment := range resp.Payments {
|
||||||
if payment.Status == lnrpc.Payment_FAILED ||
|
if payment.Status == lnrpc.Payment_FAILED ||
|
||||||
@@ -261,6 +269,14 @@ func (s *State) updateInvoiceStats() {
|
|||||||
}
|
}
|
||||||
resp := s.rpc.ListInvoices(req)
|
resp := s.rpc.ListInvoices(req)
|
||||||
|
|
||||||
|
// Exit early when the there's no invoice.
|
||||||
|
//
|
||||||
|
// NOTE: we need to exit early here because when there's no invoice the
|
||||||
|
// `LastOffsetIndex` will be zero.
|
||||||
|
if len(resp.Invoices) == 0 {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
s.Invoice.LastIndexOffset = resp.LastIndexOffset
|
s.Invoice.LastIndexOffset = resp.LastIndexOffset
|
||||||
for _, invoice := range resp.Invoices {
|
for _, invoice := range resp.Invoices {
|
||||||
if invoice.State == lnrpc.Invoice_SETTLED ||
|
if invoice.State == lnrpc.Invoice_SETTLED ||
|
||||||
|
|||||||
@@ -401,4 +401,8 @@ var allTestCasesTemp = []*lntemp.TestCase{
|
|||||||
Name: "sendpayment amp invoice repeat",
|
Name: "sendpayment amp invoice repeat",
|
||||||
TestFunc: testSendPaymentAMPInvoiceRepeat,
|
TestFunc: testSendPaymentAMPInvoiceRepeat,
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
Name: "send payment amp",
|
||||||
|
TestFunc: testSendPaymentAMP,
|
||||||
|
},
|
||||||
}
|
}
|
||||||
@@ -356,12 +356,8 @@ func testSendPaymentAMPInvoiceRepeat(ht *lntemp.HarnessTest) {
|
|||||||
|
|
||||||
// testSendPaymentAMP tests that we can send an AMP payment to a specified
|
// testSendPaymentAMP tests that we can send an AMP payment to a specified
|
||||||
// destination using SendPaymentV2.
|
// destination using SendPaymentV2.
|
||||||
func testSendPaymentAMP(net *lntest.NetworkHarness, t *harnessTest) {
|
func testSendPaymentAMP(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)
|
||||||
|
|
||||||
// Set up a network with three different paths Alice <-> Bob. Channel
|
// Set up a network with three different paths Alice <-> Bob. Channel
|
||||||
@@ -374,44 +370,37 @@ func testSendPaymentAMP(net *lntest.NetworkHarness, t *harnessTest) {
|
|||||||
// \ /
|
// \ /
|
||||||
// \__ Dave ____/
|
// \__ Dave ____/
|
||||||
//
|
//
|
||||||
ctx.openChannel(ctx.carol, ctx.bob, 135000)
|
mppReq := &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(mppReq)
|
||||||
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{
|
|
||||||
Scope: &lnrpc.PolicyUpdateRequest_Global{Global: true},
|
|
||||||
BaseFeeMsat: 500000,
|
|
||||||
FeeRate: 0.001,
|
|
||||||
TimeLockDelta: 40,
|
|
||||||
},
|
|
||||||
)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("dave policy update: %v", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
payment := sendAndAssertSuccess(
|
// Make sure Alice has heard it.
|
||||||
t, ctx.alice, &routerrpc.SendPaymentRequest{
|
ht.AssertChannelPolicyUpdate(
|
||||||
Dest: ctx.bob.PubKey[:],
|
mts.alice, mts.dave, expectedPolicy, chanPointAliceDave, false,
|
||||||
Amt: int64(paymentAmt),
|
|
||||||
FinalCltvDelta: chainreg.DefaultBitcoinTimeLockDelta,
|
|
||||||
TimeoutSeconds: 60,
|
|
||||||
FeeLimitMsat: noFeeLimitMsat,
|
|
||||||
Amp: true,
|
|
||||||
},
|
|
||||||
)
|
)
|
||||||
|
|
||||||
|
sendReq := &routerrpc.SendPaymentRequest{
|
||||||
|
Dest: mts.bob.PubKey[:],
|
||||||
|
Amt: int64(paymentAmt),
|
||||||
|
FinalCltvDelta: chainreg.DefaultBitcoinTimeLockDelta,
|
||||||
|
TimeoutSeconds: 60,
|
||||||
|
FeeLimitMsat: noFeeLimitMsat,
|
||||||
|
Amp: true,
|
||||||
|
}
|
||||||
|
payment := ht.SendPaymentAssertSettled(mts.alice, sendReq)
|
||||||
|
|
||||||
// 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),
|
||||||
// there is some non-determinism in the process. Depending on whether
|
// there is some non-determinism in the process. Depending on whether
|
||||||
@@ -427,56 +416,51 @@ func testSendPaymentAMP(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 num of shards not reached")
|
||||||
minExpectedShards, succeeded)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Fetch Bob's invoices.
|
// Fetch Bob's invoices. There should only be one invoice.
|
||||||
invoiceResp, err := ctx.bob.ListInvoices(
|
invoices := ht.AssertNumInvoices(mts.bob, 1)
|
||||||
ctxb, &lnrpc.ListInvoiceRequest{},
|
rpcInvoice := invoices[0]
|
||||||
)
|
|
||||||
require.NoError(t.t, err)
|
|
||||||
|
|
||||||
// There should only be one invoice.
|
|
||||||
require.Equal(t.t, 1, len(invoiceResp.Invoices))
|
|
||||||
rpcInvoice := invoiceResp.Invoices[0]
|
|
||||||
|
|
||||||
// Assert that the invoice is settled for the total payment amount and
|
// Assert that the invoice is settled for the total payment amount and
|
||||||
// has the correct payment address.
|
// has the correct payment address.
|
||||||
require.True(t.t, rpcInvoice.Settled) // nolint:staticcheck
|
require.True(ht, rpcInvoice.Settled) // nolint:staticcheck
|
||||||
require.Equal(t.t, lnrpc.Invoice_SETTLED, rpcInvoice.State)
|
require.Equal(ht, lnrpc.Invoice_SETTLED, rpcInvoice.State)
|
||||||
require.Equal(t.t, int64(paymentAmt), rpcInvoice.AmtPaidSat)
|
require.Equal(ht, int64(paymentAmt), rpcInvoice.AmtPaidSat)
|
||||||
require.Equal(t.t, int64(paymentAmt*1000), rpcInvoice.AmtPaidMsat)
|
require.Equal(ht, int64(paymentAmt*1000), rpcInvoice.AmtPaidMsat)
|
||||||
|
|
||||||
// Finally, assert that the same set id is recorded for each htlc, and
|
// Finally, assert that the same set id is recorded for each htlc, and
|
||||||
// that the preimage hash pair is valid.
|
// that the preimage hash pair is valid.
|
||||||
var setID []byte
|
var setID []byte
|
||||||
require.Equal(t.t, succeeded, len(rpcInvoice.Htlcs))
|
require.Equal(ht, succeeded, len(rpcInvoice.Htlcs))
|
||||||
for _, htlc := range rpcInvoice.Htlcs {
|
for _, htlc := range rpcInvoice.Htlcs {
|
||||||
require.NotNil(t.t, htlc.Amp)
|
require.NotNil(ht, htlc.Amp)
|
||||||
if setID == nil {
|
if setID == nil {
|
||||||
setID = make([]byte, 32)
|
setID = make([]byte, 32)
|
||||||
copy(setID, htlc.Amp.SetId)
|
copy(setID, htlc.Amp.SetId)
|
||||||
}
|
}
|
||||||
require.Equal(t.t, setID, htlc.Amp.SetId)
|
require.Equal(ht, setID, htlc.Amp.SetId)
|
||||||
|
|
||||||
// Parse the child hash and child preimage, and assert they are
|
// Parse the child hash and child preimage, and assert they are
|
||||||
// well-formed.
|
// well-formed.
|
||||||
childHash, err := lntypes.MakeHash(htlc.Amp.Hash)
|
childHash, err := lntypes.MakeHash(htlc.Amp.Hash)
|
||||||
require.NoError(t.t, err)
|
require.NoError(ht, err)
|
||||||
childPreimage, err := lntypes.MakePreimage(htlc.Amp.Preimage)
|
childPreimage, err := lntypes.MakePreimage(htlc.Amp.Preimage)
|
||||||
require.NoError(t.t, err)
|
require.NoError(ht, err)
|
||||||
|
|
||||||
// Assert that the preimage actually matches the hashes.
|
// Assert that the preimage actually matches the hashes.
|
||||||
validPreimage := childPreimage.Matches(childHash)
|
validPreimage := childPreimage.Matches(childHash)
|
||||||
require.True(t.t, validPreimage)
|
require.True(ht, validPreimage)
|
||||||
}
|
}
|
||||||
|
|
||||||
// The set ID we extract above should be shown in the final settled
|
// The set ID we extract above should be shown in the final settled
|
||||||
// state.
|
// state.
|
||||||
ampState := rpcInvoice.AmpInvoiceState[hex.EncodeToString(setID)]
|
ampState := rpcInvoice.AmpInvoiceState[hex.EncodeToString(setID)]
|
||||||
require.Equal(t.t, lnrpc.InvoiceHTLCState_SETTLED, ampState.State)
|
require.Equal(ht, lnrpc.InvoiceHTLCState_SETTLED, ampState.State)
|
||||||
|
|
||||||
|
// Finally, close all channels.
|
||||||
|
mts.closeChannels()
|
||||||
}
|
}
|
||||||
|
|
||||||
func testSendToRouteAMP(net *lntest.NetworkHarness, t *harnessTest) {
|
func testSendToRouteAMP(net *lntest.NetworkHarness, t *harnessTest) {
|
||||||
|
|||||||
@@ -44,10 +44,6 @@ var allTestCases = []*testCase{
|
|||||||
name: "sendtoroute amp",
|
name: "sendtoroute amp",
|
||||||
test: testSendToRouteAMP,
|
test: testSendToRouteAMP,
|
||||||
},
|
},
|
||||||
{
|
|
||||||
name: "sendpayment amp",
|
|
||||||
test: testSendPaymentAMP,
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
name: "forward interceptor",
|
name: "forward interceptor",
|
||||||
test: testForwardInterceptorBasic,
|
test: testForwardInterceptorBasic,
|
||||||
|
|||||||
Reference in new issue
Block a user