diff --git a/lntest/itest/lnd_single_hop_invoice_test.go b/lntest/itest/lnd_single_hop_invoice_test.go new file mode 100644 index 00000000..55fe8774 --- /dev/null +++ b/lntest/itest/lnd_single_hop_invoice_test.go @@ -0,0 +1,143 @@ +// +build rpctest + +package itest + +import ( + "bytes" + "context" + "time" + + "github.com/btcsuite/btcutil" + "github.com/davecgh/go-spew/spew" + "github.com/lightningnetwork/lnd/lnrpc" + "github.com/lightningnetwork/lnd/lntest" + "github.com/lightningnetwork/lnd/lntest/wait" +) + +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, + } + ctxt, _ = context.WithTimeout(ctxt, defaultTimeout) + 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. + sendReq := &lnrpc.SendRequest{ + PaymentRequest: invoiceResp.PaymentRequest, + } + ctxt, _ = context.WithTimeout(ctxb, defaultTimeout) + resp, err := net.Alice.SendPaymentSync(ctxt, sendReq) + if err != nil { + t.Fatalf("unable to send payment: %v", err) + } + + // Ensure we obtain the proper preimage in the response. + if resp.PaymentError != "" { + t.Fatalf("error when attempting recv: %v", resp.PaymentError) + } else if !bytes.Equal(preimage, resp.PaymentPreimage) { + t.Fatalf("preimage mismatch: expected %v, got %v", preimage, + resp.GetPaymentPreimage()) + } + + // 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. + sendReq = &lnrpc.SendRequest{ + PaymentRequest: invoiceResp.PaymentRequest, + } + ctxt, _ = context.WithTimeout(ctxb, defaultTimeout) + resp, err = net.Alice.SendPaymentSync(ctxt, sendReq) + if err != nil { + t.Fatalf("unable to send payment: %v", err) + } + if resp.PaymentError != "" { + t.Fatalf("error when attempting recv: %v", resp.PaymentError) + } + + // 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()) + } + + ctxt, _ = context.WithTimeout(ctxb, channelCloseTimeout) + closeChannelAndAssert(ctxt, t, net, net.Alice, chanPoint, false) +} diff --git a/lntest/itest/lnd_test.go b/lntest/itest/lnd_test.go index f8e22543..38b43430 100644 --- a/lntest/itest/lnd_test.go +++ b/lntest/itest/lnd_test.go @@ -3910,134 +3910,6 @@ func testSphinxReplayPersistence(net *lntest.NetworkHarness, t *harnessTest) { cleanupForceClose(t, net, carol, chanPoint) } -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, - } - ctxt, _ = context.WithTimeout(ctxt, defaultTimeout) - 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. - sendReq := &lnrpc.SendRequest{ - PaymentRequest: invoiceResp.PaymentRequest, - } - ctxt, _ = context.WithTimeout(ctxb, defaultTimeout) - resp, err := net.Alice.SendPaymentSync(ctxt, sendReq) - if err != nil { - t.Fatalf("unable to send payment: %v", err) - } - - // Ensure we obtain the proper preimage in the response. - if resp.PaymentError != "" { - t.Fatalf("error when attempting recv: %v", resp.PaymentError) - } else if !bytes.Equal(preimage, resp.PaymentPreimage) { - t.Fatalf("preimage mismatch: expected %v, got %v", preimage, - resp.GetPaymentPreimage()) - } - - // 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. - sendReq = &lnrpc.SendRequest{ - PaymentRequest: invoiceResp.PaymentRequest, - } - ctxt, _ = context.WithTimeout(ctxb, defaultTimeout) - resp, err = net.Alice.SendPaymentSync(ctxt, sendReq) - if err != nil { - t.Fatalf("unable to send payment: %v", err) - } - if resp.PaymentError != "" { - t.Fatalf("error when attempting recv: %v", resp.PaymentError) - } - - // 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()) - } - - ctxt, _ = context.WithTimeout(ctxb, channelCloseTimeout) - closeChannelAndAssert(ctxt, t, net, net.Alice, chanPoint, false) -} - func testListPayments(net *lntest.NetworkHarness, t *harnessTest) { ctxb := context.Background()