test: extend testInvoiceSubscriptions to test historical notification dispatch

This commit is contained in:
Olaoluwa Osuntokun 2018-06-29 18:07:55 -07:00
parent 6891729b5c
commit 43d1d1f4f2
No known key found for this signature in database
GPG Key ID: 964EA263DD637C21

@ -19,6 +19,7 @@ import (
"reflect"
"crypto/rand"
"crypto/sha256"
prand "math/rand"
"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)
}
// Create a new nodes (Carol and Charlie), load her with some funds, then establish
// a connection between Carol and Charlie with a channel that has
// identical capacity to the one created above.Then we will get route via queryroutes call
// which will be fake route for Alice -> Bob graph.
// Create a new nodes (Carol and Charlie), load her with some funds,
// then establish a connection between Carol and Charlie with a channel
// that has identical capacity to the one created above.Then we will
// 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.
carol, err := net.NewNode("Carol", nil)
@ -4298,17 +4300,18 @@ func testInvoiceSubscriptions(net *lntest.NetworkHarness, t *harnessTest) {
if err != nil {
t.Fatalf("unable to add invoice: %v", err)
}
lastAddIndex := invoiceResp.AddIndex
// Create a new invoice subscription client for Bob, the notification
// should be dispatched shortly below.
req := &lnrpc.InvoiceSubscription{}
ctx, cancelFunc := context.WithCancel(context.Background())
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 cancelFunc()
var settleIndex uint64
quit := make(chan struct{})
updateSent := make(chan struct{})
go func() {
@ -4338,6 +4341,12 @@ func testInvoiceSubscriptions(net *lntest.NetworkHarness, t *harnessTest) {
invoice.RPreimage, invoiceUpdate.RPreimage)
}
if invoiceUpdate.SettleIndex == 0 {
t.Fatalf("invoice should have settle index")
}
settleIndex = invoiceUpdate.SettleIndex
close(updateSent)
}()
@ -4375,6 +4384,126 @@ func testInvoiceSubscriptions(net *lntest.NetworkHarness, t *harnessTest) {
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)
closeChannelAndAssert(ctxt, t, net, net.Alice, chanPoint, false)
}