itest: refactor testSingleHopInvoice

This commit is contained in:
yyforyongyu committed 2023-01-17 07:26:57 +08:00
1 parent 8a4d2741a3
commit 05f198f34e
3 files changed
+66 -164

No files matched your search

+4
View File
@@ -361,4 +361,8 @@ var allTestCasesTemp = []*lntemp.TestCase{
Name: "stateless init", Name: "stateless init",
TestFunc: testStatelessInit, TestFunc: testStatelessInit,
}, },
{
Name: "single hop invoice",
TestFunc: testSingleHopInvoice,
},
} }
+62 -160
View File
@@ -2,35 +2,34 @@ package itest
import ( import (
"bytes" "bytes"
"context"
"encoding/hex" "encoding/hex"
"time"
"github.com/btcsuite/btcd/btcutil" "github.com/btcsuite/btcd/btcutil"
"github.com/davecgh/go-spew/spew"
"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/lightningnetwork/lnd/lntest/wait"
"github.com/lightningnetwork/lnd/lntypes" "github.com/lightningnetwork/lnd/lntypes"
"github.com/lightningnetwork/lnd/lnwire" "github.com/lightningnetwork/lnd/lnwire"
"github.com/lightningnetwork/lnd/record" "github.com/lightningnetwork/lnd/record"
"github.com/stretchr/testify/require" "github.com/stretchr/testify/require"
) )
func testSingleHopInvoice(net *lntest.NetworkHarness, t *harnessTest) { func testSingleHopInvoice(ht *lntemp.HarnessTest) {
ctxb := context.Background() // Open a channel with 100k satoshis between Alice and Bob with Alice
// being the sole funder of the channel.
// Open a channel with 100k satoshis between Alice and Bob with Alice being
// the sole funder of the channel.
chanAmt := btcutil.Amount(100000) chanAmt := btcutil.Amount(100000)
chanPoint := openChannelAndAssert( alice, bob := ht.Alice, ht.Bob
t, net, net.Alice, net.Bob, cp := ht.OpenChannel(
lntest.OpenChannelParams{ alice, bob, lntemp.OpenChannelParams{Amt: chanAmt},
Amt: chanAmt,
},
) )
// assertAmountPaid is a helper closure that asserts the amount paid by
// Alice and received by Bob are expected.
assertAmountPaid := func(expected int64) {
ht.AssertAmountPaid("alice -> bob", alice, cp, expected, 0)
ht.AssertAmountPaid("bob <- alice", bob, cp, 0, expected)
}
// Now that the channel is open, create an invoice for Bob which // Now that the channel is open, create an invoice for Bob which
// expects a payment of 1000 satoshis from Alice paid via a particular // expects a payment of 1000 satoshis from Alice paid via a particular
// preimage. // preimage.
@@ -41,61 +40,20 @@ func testSingleHopInvoice(net *lntest.NetworkHarness, t *harnessTest) {
RPreimage: preimage, RPreimage: preimage,
Value: paymentAmt, Value: paymentAmt,
} }
invoiceResp, err := net.Bob.AddInvoice(ctxb, invoice) invoiceResp := bob.RPC.AddInvoice(invoice)
if err != nil {
t.Fatalf("unable to add invoice: %v", err)
}
// Wait for Alice to recognize and advertise the new channel generated
// above.
err = net.Alice.WaitForNetworkChannelOpen(chanPoint)
if err != nil {
t.Fatalf("alice didn't advertise channel before "+
"timeout: %v", err)
}
err = net.Bob.WaitForNetworkChannelOpen(chanPoint)
if err != nil {
t.Fatalf("bob didn't advertise channel before "+
"timeout: %v", err)
}
// With the invoice for Bob added, send a payment towards Alice paying // With the invoice for Bob added, send a payment towards Alice paying
// to the above generated invoice. // to the above generated invoice.
resp := sendAndAssertSuccess( ht.CompletePaymentRequests(alice, []string{invoiceResp.PaymentRequest})
t, net.Alice, &routerrpc.SendPaymentRequest{
PaymentRequest: invoiceResp.PaymentRequest,
TimeoutSeconds: 60,
FeeLimitMsat: noFeeLimitMsat,
},
)
if hex.EncodeToString(preimage) != resp.PaymentPreimage {
t.Fatalf("preimage mismatch: expected %v, got %v", preimage,
resp.PaymentPreimage)
}
// Bob's invoice should now be found and marked as settled. // Bob's invoice should now be found and marked as settled.
payHash := &lnrpc.PaymentHash{ dbInvoice := bob.RPC.LookupInvoice(invoiceResp.RHash)
RHash: invoiceResp.RHash, require.Equal(ht, lnrpc.Invoice_SETTLED, dbInvoice.State,
} "bob's invoice should be marked as settled")
ctxt, _ := context.WithTimeout(ctxb, defaultTimeout)
dbInvoice, err := net.Bob.LookupInvoice(ctxt, payHash)
if err != nil {
t.Fatalf("unable to lookup invoice: %v", err)
}
if !dbInvoice.Settled { // nolint:staticcheck
t.Fatalf("bob's invoice should be marked as settled: %v",
spew.Sdump(dbInvoice))
}
// With the payment completed all balance related stats should be // With the payment completed all balance related stats should be
// properly updated. // properly updated.
err = wait.NoError( assertAmountPaid(paymentAmt)
assertAmountSent(paymentAmt, net.Alice, net.Bob),
3*time.Second,
)
if err != nil {
t.Fatalf(err.Error())
}
// Create another invoice for Bob, this time leaving off the preimage // Create another invoice for Bob, this time leaving off the preimage
// to one will be randomly generated. We'll test the proper // to one will be randomly generated. We'll test the proper
@@ -104,92 +62,58 @@ func testSingleHopInvoice(net *lntest.NetworkHarness, t *harnessTest) {
Memo: "test3", Memo: "test3",
Value: paymentAmt, Value: paymentAmt,
} }
ctxt, _ = context.WithTimeout(ctxb, defaultTimeout) invoiceResp = bob.RPC.AddInvoice(invoice)
invoiceResp, err = net.Bob.AddInvoice(ctxt, invoice)
if err != nil {
t.Fatalf("unable to add invoice: %v", err)
}
// Next send another payment, but this time using a zpay32 encoded // Next send another payment, but this time using a zpay32 encoded
// invoice rather than manually specifying the payment details. // invoice rather than manually specifying the payment details.
sendAndAssertSuccess( ht.CompletePaymentRequests(alice, []string{invoiceResp.PaymentRequest})
t, net.Alice, &routerrpc.SendPaymentRequest{
PaymentRequest: invoiceResp.PaymentRequest,
TimeoutSeconds: 60,
FeeLimitMsat: noFeeLimitMsat,
},
)
// The second payment should also have succeeded, with the balances // The second payment should also have succeeded, with the balances
// being update accordingly. // being update accordingly.
err = wait.NoError( assertAmountPaid(paymentAmt * 2)
assertAmountSent(2*paymentAmt, net.Alice, net.Bob),
3*time.Second,
)
if err != nil {
t.Fatalf(err.Error())
}
// Next send a keysend payment. // Next send a keysend payment.
keySendPreimage := lntypes.Preimage{3, 4, 5, 11} keySendPreimage := lntypes.Preimage{3, 4, 5, 11}
keySendHash := keySendPreimage.Hash() keySendHash := keySendPreimage.Hash()
sendAndAssertSuccess( req := &routerrpc.SendPaymentRequest{
t, net.Alice, &routerrpc.SendPaymentRequest{ Dest: bob.PubKey[:],
Dest: net.Bob.PubKey[:], Amt: paymentAmt,
Amt: paymentAmt, FinalCltvDelta: 40,
FinalCltvDelta: 40, PaymentHash: keySendHash[:],
PaymentHash: keySendHash[:], DestCustomRecords: map[uint64][]byte{
DestCustomRecords: map[uint64][]byte{ record.KeySendType: keySendPreimage[:],
record.KeySendType: keySendPreimage[:],
},
TimeoutSeconds: 60,
FeeLimitMsat: noFeeLimitMsat,
}, },
) TimeoutSeconds: 60,
FeeLimitMsat: noFeeLimitMsat,
}
ht.SendPaymentAssertSettled(alice, req)
// The keysend payment should also have succeeded, with the balances // The keysend payment should also have succeeded, with the balances
// being update accordingly. // being update accordingly.
err = wait.NoError( assertAmountPaid(paymentAmt * 3)
assertAmountSent(3*paymentAmt, net.Alice, net.Bob),
3*time.Second,
)
if err != nil {
t.Fatalf(err.Error())
}
// Assert that the invoice has the proper AMP fields set, since the // Assert that the invoice has the proper AMP fields set, since the
// legacy keysend payment should have been promoted into an AMP payment // legacy keysend payment should have been promoted into an AMP payment
// internally. // internally.
ctxt, _ = context.WithTimeout(ctxb, defaultTimeout) keysendInvoice := bob.RPC.LookupInvoice(keySendHash[:])
keysendInvoice, err := net.Bob.LookupInvoice( require.Len(ht, keysendInvoice.Htlcs, 1)
ctxt, &lnrpc.PaymentHash{
RHash: keySendHash[:],
},
)
require.NoError(t.t, err)
require.Equal(t.t, 1, len(keysendInvoice.Htlcs))
htlc := keysendInvoice.Htlcs[0] htlc := keysendInvoice.Htlcs[0]
require.Equal(t.t, uint64(0), htlc.MppTotalAmtMsat) require.Zero(ht, htlc.MppTotalAmtMsat)
require.Nil(t.t, htlc.Amp) require.Nil(ht, htlc.Amp)
// Now create an invoice and specify routing hints. // Now create an invoice and specify routing hints.
// We will test that the routing hints are encoded properly. // We will test that the routing hints are encoded properly.
hintChannel := lnwire.ShortChannelID{BlockHeight: 10} hintChannel := lnwire.ShortChannelID{BlockHeight: 10}
bobPubKey := hex.EncodeToString(net.Bob.PubKey[:]) bobPubKey := hex.EncodeToString(bob.PubKey[:])
hints := []*lnrpc.RouteHint{ hint := &lnrpc.HopHint{
{ NodeId: bobPubKey,
HopHints: []*lnrpc.HopHint{ ChanId: hintChannel.ToUint64(),
{ FeeBaseMsat: 1,
NodeId: bobPubKey, FeeProportionalMillionths: 1000000,
ChanId: hintChannel.ToUint64(), CltvExpiryDelta: 20,
FeeBaseMsat: 1,
FeeProportionalMillionths: 1000000,
CltvExpiryDelta: 20,
},
},
},
} }
hints := []*lnrpc.RouteHint{{HopHints: []*lnrpc.HopHint{hint}}}
invoice = &lnrpc.Invoice{ invoice = &lnrpc.Invoice{
Memo: "hints", Memo: "hints",
@@ -197,43 +121,21 @@ func testSingleHopInvoice(net *lntest.NetworkHarness, t *harnessTest) {
RouteHints: hints, RouteHints: hints,
} }
ctxt, _ = context.WithTimeout(ctxb, defaultTimeout) invoiceResp = bob.RPC.AddInvoice(invoice)
invoiceResp, err = net.Bob.AddInvoice(ctxt, invoice) payreq := bob.RPC.DecodePayReq(invoiceResp.PaymentRequest)
if err != nil { require.Len(ht, payreq.RouteHints, 1, "expected one routing hint")
t.Fatalf("unable to add invoice: %v", err)
}
payreq, err := net.Bob.DecodePayReq(ctxt, &lnrpc.PayReqString{PayReq: invoiceResp.PaymentRequest})
if err != nil {
t.Fatalf("failed to decode payment request %v", err)
}
if len(payreq.RouteHints) != 1 {
t.Fatalf("expected one routing hint")
}
routingHint := payreq.RouteHints[0] routingHint := payreq.RouteHints[0]
if len(routingHint.HopHints) != 1 { require.Len(ht, routingHint.HopHints, 1, "expected one hop hint")
t.Fatalf("expected one hop hint")
}
hopHint := routingHint.HopHints[0]
if hopHint.FeeProportionalMillionths != 1000000 {
t.Fatalf("wrong FeeProportionalMillionths %v",
hopHint.FeeProportionalMillionths)
}
if hopHint.NodeId != bobPubKey {
t.Fatalf("wrong NodeId %v",
hopHint.NodeId)
}
if hopHint.ChanId != hintChannel.ToUint64() {
t.Fatalf("wrong ChanId %v",
hopHint.ChanId)
}
if hopHint.FeeBaseMsat != 1 {
t.Fatalf("wrong FeeBaseMsat %v",
hopHint.FeeBaseMsat)
}
if hopHint.CltvExpiryDelta != 20 {
t.Fatalf("wrong CltvExpiryDelta %v",
hopHint.CltvExpiryDelta)
}
closeChannelAndAssert(t, net, net.Alice, chanPoint, false) hopHint := routingHint.HopHints[0]
require.EqualValues(ht, 1000000, hopHint.FeeProportionalMillionths,
"wrong FeeProportionalMillionths")
require.Equal(ht, bobPubKey, hopHint.NodeId, "wrong NodeId")
require.Equal(ht, hintChannel.ToUint64(), hopHint.ChanId,
"wrong ChanId")
require.EqualValues(ht, 1, hopHint.FeeBaseMsat, "wrong FeeBaseMsat")
require.EqualValues(ht, 20, hopHint.CltvExpiryDelta,
"wrong CltvExpiryDelta")
ht.CloseChannel(alice, cp)
} }
-4
View File
@@ -4,10 +4,6 @@
package itest package itest
var allTestCases = []*testCase{ var allTestCases = []*testCase{
{
name: "single hop invoice",
test: testSingleHopInvoice,
},
{ {
name: "multiple channel creation and update subscription", name: "multiple channel creation and update subscription",
test: testBasicChannelCreationAndUpdates, test: testBasicChannelCreationAndUpdates,