test: extend testInvoiceSubscriptions to test historical notification dispatch
This commit is contained in:
1 file changed
+135
-6
+135
-6
@@ -19,6 +19,7 @@ import (
|
|||||||
"reflect"
|
"reflect"
|
||||||
|
|
||||||
"crypto/rand"
|
"crypto/rand"
|
||||||
|
"crypto/sha256"
|
||||||
prand "math/rand"
|
prand "math/rand"
|
||||||
|
|
||||||
"github.com/btcsuite/btclog"
|
"github.com/btcsuite/btclog"
|
||||||
@@ -3452,10 +3453,11 @@ func testSendToRouteErrorPropagation(net *lntest.NetworkHarness, t *harnessTest)
|
|||||||
t.Fatalf("alice didn't advertise her channel: %v", err)
|
t.Fatalf("alice didn't advertise her channel: %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Create a new nodes (Carol and Charlie), load her with some funds, then establish
|
// Create a new nodes (Carol and Charlie), load her with some funds,
|
||||||
// a connection between Carol and Charlie with a channel that has
|
// then establish a connection between Carol and Charlie with a channel
|
||||||
// identical capacity to the one created above.Then we will get route via queryroutes call
|
// that has identical capacity to the one created above.Then we will
|
||||||
// which will be fake route for Alice -> Bob graph.
|
// get route via queryroutes call which will be fake route for Alice ->
|
||||||
|
// Bob graph.
|
||||||
//
|
//
|
||||||
// The network topology should now look like: Alice -> Bob; Carol -> Charlie.
|
// The network topology should now look like: Alice -> Bob; Carol -> Charlie.
|
||||||
carol, err := net.NewNode("Carol", nil)
|
carol, err := net.NewNode("Carol", nil)
|
||||||
@@ -4298,17 +4300,18 @@ func testInvoiceSubscriptions(net *lntest.NetworkHarness, t *harnessTest) {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("unable to add invoice: %v", err)
|
t.Fatalf("unable to add invoice: %v", err)
|
||||||
}
|
}
|
||||||
|
lastAddIndex := invoiceResp.AddIndex
|
||||||
|
|
||||||
// Create a new invoice subscription client for Bob, the notification
|
// Create a new invoice subscription client for Bob, the notification
|
||||||
// should be dispatched shortly below.
|
// should be dispatched shortly below.
|
||||||
req := &lnrpc.InvoiceSubscription{}
|
req := &lnrpc.InvoiceSubscription{}
|
||||||
ctx, cancelFunc := context.WithCancel(context.Background())
|
ctx, cancelInvoiceSubscription := context.WithCancel(context.Background())
|
||||||
bobInvoiceSubscription, err := net.Bob.SubscribeInvoices(ctx, req)
|
bobInvoiceSubscription, err := net.Bob.SubscribeInvoices(ctx, req)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("unable to subscribe to bob's invoice updates: %v", err)
|
t.Fatalf("unable to subscribe to bob's invoice updates: %v", err)
|
||||||
}
|
}
|
||||||
defer cancelFunc()
|
|
||||||
|
|
||||||
|
var settleIndex uint64
|
||||||
quit := make(chan struct{})
|
quit := make(chan struct{})
|
||||||
updateSent := make(chan struct{})
|
updateSent := make(chan struct{})
|
||||||
go func() {
|
go func() {
|
||||||
@@ -4338,6 +4341,12 @@ func testInvoiceSubscriptions(net *lntest.NetworkHarness, t *harnessTest) {
|
|||||||
invoice.RPreimage, invoiceUpdate.RPreimage)
|
invoice.RPreimage, invoiceUpdate.RPreimage)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if invoiceUpdate.SettleIndex == 0 {
|
||||||
|
t.Fatalf("invoice should have settle index")
|
||||||
|
}
|
||||||
|
|
||||||
|
settleIndex = invoiceUpdate.SettleIndex
|
||||||
|
|
||||||
close(updateSent)
|
close(updateSent)
|
||||||
}()
|
}()
|
||||||
|
|
||||||
@@ -4375,6 +4384,126 @@ func testInvoiceSubscriptions(net *lntest.NetworkHarness, t *harnessTest) {
|
|||||||
case <-updateSent: // Fall through on success
|
case <-updateSent: // Fall through on success
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// With the base case working, we'll now cancel Bob's current
|
||||||
|
// subscription in order to exercise the backlog fill behavior.
|
||||||
|
cancelInvoiceSubscription()
|
||||||
|
|
||||||
|
// We'll now add 3 more invoices to Bob's invoice registry.
|
||||||
|
const numInvoices = 3
|
||||||
|
newInvoices := make([]*lnrpc.Invoice, numInvoices)
|
||||||
|
payReqs := make([]string, numInvoices)
|
||||||
|
for i := 0; i < numInvoices; i++ {
|
||||||
|
preimage := bytes.Repeat([]byte{byte(90 + 1 + i)}, 32)
|
||||||
|
invoice := &lnrpc.Invoice{
|
||||||
|
Memo: "testing",
|
||||||
|
RPreimage: preimage,
|
||||||
|
Value: paymentAmt,
|
||||||
|
}
|
||||||
|
resp, err := net.Bob.AddInvoice(ctxb, invoice)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("unable to add invoice: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
newInvoices[i] = invoice
|
||||||
|
payReqs[i] = resp.PaymentRequest
|
||||||
|
}
|
||||||
|
|
||||||
|
// Now that the set of invoices has been added, we'll re-register for
|
||||||
|
// streaming invoice notifications for Bob, this time specifying the
|
||||||
|
// add invoice of the last prior invoice.
|
||||||
|
req = &lnrpc.InvoiceSubscription{
|
||||||
|
AddIndex: lastAddIndex,
|
||||||
|
}
|
||||||
|
ctx, cancelInvoiceSubscription = context.WithCancel(context.Background())
|
||||||
|
bobInvoiceSubscription, err = net.Bob.SubscribeInvoices(ctx, req)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("unable to subscribe to bob's invoice updates: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Since we specified a value of the prior add index above, we should
|
||||||
|
// now immediately get the invoices we just added as we should get the
|
||||||
|
// backlog of notifications.
|
||||||
|
for i := 0; i < numInvoices; i++ {
|
||||||
|
invoiceUpdate, err := bobInvoiceSubscription.Recv()
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("unable to receive subscription")
|
||||||
|
}
|
||||||
|
|
||||||
|
// We should now get the ith invoice we added, as they should
|
||||||
|
// be returned in order.
|
||||||
|
if invoiceUpdate.Settled {
|
||||||
|
t.Fatalf("should have only received add events")
|
||||||
|
}
|
||||||
|
originalInvoice := newInvoices[i]
|
||||||
|
rHash := sha256.Sum256(originalInvoice.RPreimage[:])
|
||||||
|
if !bytes.Equal(invoiceUpdate.RHash, rHash[:]) {
|
||||||
|
t.Fatalf("invoices have mismatched payment hashes: "+
|
||||||
|
"expected %x, got %x", rHash[:],
|
||||||
|
invoiceUpdate.RHash)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
cancelInvoiceSubscription()
|
||||||
|
|
||||||
|
// We'll now have Bob settle out the remainder of these invoices so we
|
||||||
|
// can test that all settled invoices are properly notified.
|
||||||
|
ctxt, _ = context.WithTimeout(ctxb, timeout)
|
||||||
|
err = completePaymentRequests(
|
||||||
|
ctxt, net.Alice, payReqs, true,
|
||||||
|
)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("unable to send payment: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
// With the set of invoices paid, we'll now cancel the old
|
||||||
|
// subscription, and create a new one for Bob, this time using the
|
||||||
|
// settle index to obtain the backlog of settled invoices.
|
||||||
|
req = &lnrpc.InvoiceSubscription{
|
||||||
|
SettleIndex: settleIndex,
|
||||||
|
}
|
||||||
|
ctx, cancelInvoiceSubscription = context.WithCancel(context.Background())
|
||||||
|
bobInvoiceSubscription, err = net.Bob.SubscribeInvoices(ctx, req)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("unable to subscribe to bob's invoice updates: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
defer cancelInvoiceSubscription()
|
||||||
|
|
||||||
|
// As we specified the index of the past settle index, we should now
|
||||||
|
// receive notifications for the three HTLCs that we just settled. As
|
||||||
|
// the order that the HTLCs will be settled in is partially randomized,
|
||||||
|
// we'll use a map to assert that the proper set has been settled.
|
||||||
|
settledInvoices := make(map[[32]byte]struct{})
|
||||||
|
for _, invoice := range newInvoices {
|
||||||
|
rHash := sha256.Sum256(invoice.RPreimage[:])
|
||||||
|
settledInvoices[rHash] = struct{}{}
|
||||||
|
}
|
||||||
|
for i := 0; i < numInvoices; i++ {
|
||||||
|
invoiceUpdate, err := bobInvoiceSubscription.Recv()
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("unable to receive subscription")
|
||||||
|
}
|
||||||
|
|
||||||
|
// We should now get the ith invoice we added, as they should
|
||||||
|
// be returned in order.
|
||||||
|
if !invoiceUpdate.Settled {
|
||||||
|
t.Fatalf("should have only received settle events")
|
||||||
|
}
|
||||||
|
|
||||||
|
var rHash [32]byte
|
||||||
|
copy(rHash[:], invoiceUpdate.RHash)
|
||||||
|
if _, ok := settledInvoices[rHash]; !ok {
|
||||||
|
t.Fatalf("unknown invoice settled: %x", rHash)
|
||||||
|
}
|
||||||
|
|
||||||
|
delete(settledInvoices, rHash)
|
||||||
|
}
|
||||||
|
|
||||||
|
// At this point, all the invoices should be fully settled.
|
||||||
|
if len(settledInvoices) != 0 {
|
||||||
|
t.Fatalf("not all invoices settled")
|
||||||
|
}
|
||||||
|
|
||||||
ctxt, _ = context.WithTimeout(ctxb, timeout)
|
ctxt, _ = context.WithTimeout(ctxb, timeout)
|
||||||
closeChannelAndAssert(ctxt, t, net, net.Alice, chanPoint, false)
|
closeChannelAndAssert(ctxt, t, net, net.Alice, chanPoint, false)
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in new issue
Block a user