Skip to content

Commit

Permalink
Merge 1189e70 into 90d4a72
Browse files Browse the repository at this point in the history
  • Loading branch information
Roasbeef committed Jul 11, 2018
2 parents 90d4a72 + 1189e70 commit 8df615e
Show file tree
Hide file tree
Showing 19 changed files with 1,771 additions and 532 deletions.
6 changes: 6 additions & 0 deletions channeldb/db.go
Expand Up @@ -47,6 +47,12 @@ var (
number: 1,
migration: migrateNodeAndEdgeUpdateIndex,
},
{
// The DB version that added the invoice event time
// series.
number: 2,
migration: migrateInvoiceTimeSeries,
},
}

// Big endian is the preferred byte order, due to cursor scans over
Expand Down
177 changes: 168 additions & 9 deletions channeldb/invoice_test.go
Expand Up @@ -70,7 +70,7 @@ func TestInvoiceWorkflow(t *testing.T) {
// Add the invoice to the database, this should succeed as there aren't
// any existing invoices within the database with the same payment
// hash.
if err := db.AddInvoice(fakeInvoice); err != nil {
if _, err := db.AddInvoice(fakeInvoice); err != nil {
t.Fatalf("unable to find invoice: %v", err)
}

Expand All @@ -82,15 +82,24 @@ func TestInvoiceWorkflow(t *testing.T) {
if err != nil {
t.Fatalf("unable to find invoice: %v", err)
}
if !reflect.DeepEqual(fakeInvoice, dbInvoice) {
if !reflect.DeepEqual(*fakeInvoice, dbInvoice) {
t.Fatalf("invoice fetched from db doesn't match original %v vs %v",
spew.Sdump(fakeInvoice), spew.Sdump(dbInvoice))
}

// The add index of the invoice retrieved from the database should now
// be fully populated. As this is the first index written to the DB,
// the addIndex should be 1.
if dbInvoice.AddIndex != 1 {
t.Fatalf("wrong add index: expected %v, got %v", 1,
dbInvoice.AddIndex)
}

// Settle the invoice, the version retrieved from the database should
// now have the settled bit toggle to true and a non-default
// SettledDate
if err := db.SettleInvoice(paymentHash); err != nil {
payAmt := fakeInvoice.Terms.Value * 2
if _, err := db.SettleInvoice(paymentHash, payAmt); err != nil {
t.Fatalf("unable to settle invoice: %v", err)
}
dbInvoice2, err := db.LookupInvoice(paymentHash)
Expand All @@ -100,14 +109,24 @@ func TestInvoiceWorkflow(t *testing.T) {
if !dbInvoice2.Terms.Settled {
t.Fatalf("invoice should now be settled but isn't")
}

if dbInvoice2.SettleDate.IsZero() {
t.Fatalf("invoice should have non-zero SettledDate but isn't")
}

// Our 2x payment should be reflected, and also the settle index of 1
// should also have been committed for this index.
if dbInvoice2.AmtPaid != payAmt {
t.Fatalf("wrong amt paid: expected %v, got %v", payAmt,
dbInvoice2.AmtPaid)
}
if dbInvoice2.SettleIndex != 1 {
t.Fatalf("wrong settle index: expected %v, got %v", 1,
dbInvoice2.SettleIndex)
}

// Attempt to insert generated above again, this should fail as
// duplicates are rejected by the processing logic.
if err := db.AddInvoice(fakeInvoice); err != ErrDuplicateInvoice {
if _, err := db.AddInvoice(fakeInvoice); err != ErrDuplicateInvoice {
t.Fatalf("invoice insertion should fail due to duplication, "+
"instead %v", err)
}
Expand All @@ -119,18 +138,18 @@ func TestInvoiceWorkflow(t *testing.T) {
t.Fatalf("lookup should have failed, instead %v", err)
}

// Add 100 random invoices.
// Add 10 random invoices.
const numInvoices = 10
amt := lnwire.NewMSatFromSatoshis(1000)
invoices := make([]*Invoice, numInvoices+1)
invoices[0] = dbInvoice2
invoices[0] = &dbInvoice2
for i := 1; i < len(invoices)-1; i++ {
invoice, err := randInvoice(amt)
if err != nil {
t.Fatalf("unable to create invoice: %v", err)
}

if err := db.AddInvoice(invoice); err != nil {
if _, err := db.AddInvoice(invoice); err != nil {
t.Fatalf("unable to add invoice %v", err)
}

Expand All @@ -148,10 +167,150 @@ func TestInvoiceWorkflow(t *testing.T) {
// order (and the primary key should be incremented with each
// insertion).
for i := 0; i < len(invoices)-1; i++ {
if !reflect.DeepEqual(invoices[i], dbInvoices[i]) {
if !reflect.DeepEqual(*invoices[i], dbInvoices[i]) {
t.Fatalf("retrieved invoices don't match %v vs %v",
spew.Sdump(invoices[i]),
spew.Sdump(dbInvoices[i]))
}
}
}

// TestInvoiceTimeSeries tests that newly added invoices invoices, as well as
// settled invoices are added to the database are properly placed in the add
// add or settle index which serves as an event time series.
func TestInvoiceAddTimeSeries(t *testing.T) {
t.Parallel()

db, cleanUp, err := makeTestDB()
defer cleanUp()
if err != nil {
t.Fatalf("unable to make test db: %v", err)
}

// We'll start off by creating 20 random invoices, and inserting them
// into the database.
const numInvoices = 20
amt := lnwire.NewMSatFromSatoshis(1000)
invoices := make([]Invoice, numInvoices)
for i := 0; i < len(invoices); i++ {
invoice, err := randInvoice(amt)
if err != nil {
t.Fatalf("unable to create invoice: %v", err)
}

if _, err := db.AddInvoice(invoice); err != nil {
t.Fatalf("unable to add invoice %v", err)
}

invoices[i] = *invoice
}

// With the invoices constructed, we'll now create a series of queries
// that we'll use to assert expected return values of
// InvoicesAddedSince.
addQueries := []struct {
sinceAddIndex uint64

resp []Invoice
}{
// If we specify a value of zero, we shouldn't get any invoices
// back.
{
sinceAddIndex: 0,
},

// If we specify a value well beyond the number of inserted
// invoices, we shouldn't get any invoices back.
{
sinceAddIndex: 99999999,
},

// Using an index of 1 should result in all values, but the
// first one being returned.
{
sinceAddIndex: 1,
resp: invoices[1:],
},

// If we use an index of 10, then we should retrieve the
// reaming 10 invoices.
{
sinceAddIndex: 10,
resp: invoices[10:],
},
}

for i, query := range addQueries {
resp, err := db.InvoicesAddedSince(query.sinceAddIndex)
if err != nil {
t.Fatalf("unable to query: %v", err)
}

if !reflect.DeepEqual(query.resp, resp) {
t.Fatalf("test #%v: expected %v, got %v", i,
spew.Sdump(query.resp), spew.Sdump(resp))
}
}

// We'll now only settle the latter half of each of those invoices.
for i := 10; i < len(invoices); i++ {
invoice := &invoices[i]

paymentHash := sha256.Sum256(
invoice.Terms.PaymentPreimage[:],
)

_, err := db.SettleInvoice(paymentHash, 0)
if err != nil {
t.Fatalf("unable to settle invoice: %v", err)
}
}

invoices, err = db.FetchAllInvoices(false)
if err != nil {
t.Fatalf("unable to fetch invoices: %v", err)
}

// We'll slice off the first 10 invoices, as we only settled the last
// 10.
invoices = invoices[10:]

// We'll now prepare an additional set of queries to ensure the settle
// time series has properly been maintained in the database.
settleQueries := []struct {
sinceSettleIndex uint64

resp []Invoice
}{
// If we specify a value of zero, we shouldn't get any settled
// invoices back.
{
sinceSettleIndex: 0,
},

// If we specify a value well beyond the number of settled
// invoices, we shouldn't get any invoices back.
{
sinceSettleIndex: 99999999,
},

// Using an index of 1 should result in the final 10 invoices
// being returned, as we only settled those.
{
sinceSettleIndex: 1,
resp: invoices[1:],
},
}

for i, query := range settleQueries {
resp, err := db.InvoicesSettledSince(query.sinceSettleIndex)
if err != nil {
t.Fatalf("unable to query: %v", err)
}

if !reflect.DeepEqual(query.resp, resp) {
t.Fatalf("test #%v: expected %v, got %v", i,
spew.Sdump(query.resp), spew.Sdump(resp))
}
}
}

0 comments on commit 8df615e

Please sign in to comment.