719e32830d
We fix all linter issues except for the 'lostcontext' and 'unparam' ones as those are too numerous and would increase the diff even more. Therefore we silence them in the itest directory for now. Because the linter is still not build tag aware, we also have to silence the unused and deadcode sub linters to not get false positives.
167 lines
4.5 KiB
Go
167 lines
4.5 KiB
Go
package itest
|
|
|
|
import (
|
|
"bytes"
|
|
"context"
|
|
"encoding/hex"
|
|
"time"
|
|
|
|
"github.com/btcsuite/btcutil"
|
|
"github.com/davecgh/go-spew/spew"
|
|
"github.com/lightningnetwork/lnd/lnrpc"
|
|
"github.com/lightningnetwork/lnd/lnrpc/routerrpc"
|
|
"github.com/lightningnetwork/lnd/lntest"
|
|
"github.com/lightningnetwork/lnd/lntest/wait"
|
|
"github.com/lightningnetwork/lnd/lntypes"
|
|
"github.com/lightningnetwork/lnd/record"
|
|
)
|
|
|
|
func testSingleHopInvoice(net *lntest.NetworkHarness, t *harnessTest) {
|
|
ctxb := context.Background()
|
|
|
|
// Open a channel with 100k satoshis between Alice and Bob with Alice being
|
|
// the sole funder of the channel.
|
|
ctxt, _ := context.WithTimeout(ctxb, channelOpenTimeout)
|
|
chanAmt := btcutil.Amount(100000)
|
|
chanPoint := openChannelAndAssert(
|
|
ctxt, t, net, net.Alice, net.Bob,
|
|
lntest.OpenChannelParams{
|
|
Amt: chanAmt,
|
|
},
|
|
)
|
|
|
|
// Now that the channel is open, create an invoice for Bob which
|
|
// expects a payment of 1000 satoshis from Alice paid via a particular
|
|
// preimage.
|
|
const paymentAmt = 1000
|
|
preimage := bytes.Repeat([]byte("A"), 32)
|
|
invoice := &lnrpc.Invoice{
|
|
Memo: "testing",
|
|
RPreimage: preimage,
|
|
Value: paymentAmt,
|
|
}
|
|
invoiceResp, err := net.Bob.AddInvoice(ctxb, invoice)
|
|
if err != nil {
|
|
t.Fatalf("unable to add invoice: %v", err)
|
|
}
|
|
|
|
// Wait for Alice to recognize and advertise the new channel generated
|
|
// above.
|
|
ctxt, _ = context.WithTimeout(ctxb, defaultTimeout)
|
|
err = net.Alice.WaitForNetworkChannelOpen(ctxt, chanPoint)
|
|
if err != nil {
|
|
t.Fatalf("alice didn't advertise channel before "+
|
|
"timeout: %v", err)
|
|
}
|
|
err = net.Bob.WaitForNetworkChannelOpen(ctxt, 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
|
|
// to the above generated invoice.
|
|
resp := sendAndAssertSuccess(
|
|
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.
|
|
payHash := &lnrpc.PaymentHash{
|
|
RHash: invoiceResp.RHash,
|
|
}
|
|
ctxt, _ = context.WithTimeout(ctxt, defaultTimeout)
|
|
dbInvoice, err := net.Bob.LookupInvoice(ctxt, payHash)
|
|
if err != nil {
|
|
t.Fatalf("unable to lookup invoice: %v", err)
|
|
}
|
|
if !dbInvoice.Settled {
|
|
t.Fatalf("bob's invoice should be marked as settled: %v",
|
|
spew.Sdump(dbInvoice))
|
|
}
|
|
|
|
// With the payment completed all balance related stats should be
|
|
// properly updated.
|
|
err = wait.NoError(
|
|
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
|
|
// to one will be randomly generated. We'll test the proper
|
|
// encoding/decoding of the zpay32 payment requests.
|
|
invoice = &lnrpc.Invoice{
|
|
Memo: "test3",
|
|
Value: paymentAmt,
|
|
}
|
|
ctxt, _ = context.WithTimeout(ctxt, defaultTimeout)
|
|
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
|
|
// invoice rather than manually specifying the payment details.
|
|
sendAndAssertSuccess(
|
|
t, net.Alice,
|
|
&routerrpc.SendPaymentRequest{
|
|
PaymentRequest: invoiceResp.PaymentRequest,
|
|
TimeoutSeconds: 60,
|
|
FeeLimitMsat: noFeeLimitMsat,
|
|
},
|
|
)
|
|
|
|
// The second payment should also have succeeded, with the balances
|
|
// being update accordingly.
|
|
err = wait.NoError(
|
|
assertAmountSent(2*paymentAmt, net.Alice, net.Bob),
|
|
3*time.Second,
|
|
)
|
|
if err != nil {
|
|
t.Fatalf(err.Error())
|
|
}
|
|
|
|
// Next send a keysend payment.
|
|
keySendPreimage := lntypes.Preimage{3, 4, 5, 11}
|
|
keySendHash := keySendPreimage.Hash()
|
|
|
|
sendAndAssertSuccess(
|
|
t, net.Alice,
|
|
&routerrpc.SendPaymentRequest{
|
|
Dest: net.Bob.PubKey[:],
|
|
Amt: paymentAmt,
|
|
FinalCltvDelta: 40,
|
|
PaymentHash: keySendHash[:],
|
|
DestCustomRecords: map[uint64][]byte{
|
|
record.KeySendType: keySendPreimage[:],
|
|
},
|
|
TimeoutSeconds: 60,
|
|
FeeLimitMsat: noFeeLimitMsat,
|
|
},
|
|
)
|
|
|
|
// The keysend payment should also have succeeded, with the balances
|
|
// being update accordingly.
|
|
err = wait.NoError(
|
|
assertAmountSent(3*paymentAmt, net.Alice, net.Bob),
|
|
3*time.Second,
|
|
)
|
|
if err != nil {
|
|
t.Fatalf(err.Error())
|
|
}
|
|
|
|
ctxt, _ = context.WithTimeout(ctxb, channelCloseTimeout)
|
|
closeChannelAndAssert(ctxt, t, net, net.Alice, chanPoint, false)
|
|
}
|