Merge pull request #3551 from joostjager/safe-invoice-migration
channeldb: safe invoice migration
This commit is contained in:
3 files changed
+72
-37
No files matched your search
@@ -70,6 +70,9 @@ func applyMigration(t *testing.T, beforeMigration, afterMigration func(d *DB),
|
|||||||
|
|
||||||
// Sync with the latest version - applying migration function.
|
// Sync with the latest version - applying migration function.
|
||||||
err = cdb.syncVersions(versions)
|
err = cdb.syncVersions(versions)
|
||||||
|
if err != nil {
|
||||||
|
log.Error(err)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// TestVersionFetchPut checks the propernces of fetch/put methods
|
// TestVersionFetchPut checks the propernces of fetch/put methods
|
||||||
|
|||||||
@@ -69,6 +69,11 @@ func migrateInvoices(tx *bbolt.Tx) error {
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if invoice.Terms.State == ContractAccepted {
|
||||||
|
return fmt.Errorf("cannot upgrade with invoice(s) " +
|
||||||
|
"in accepted state, see release notes")
|
||||||
|
}
|
||||||
|
|
||||||
// Try to decode the payment request for every possible net to
|
// Try to decode the payment request for every possible net to
|
||||||
// avoid passing a the active network to channeldb. This would
|
// avoid passing a the active network to channeldb. This would
|
||||||
// be a layering violation, while this migration is only running
|
// be a layering violation, while this migration is only running
|
||||||
|
|||||||
@@ -24,6 +24,43 @@ var (
|
|||||||
testCltvDelta = int32(50)
|
testCltvDelta = int32(50)
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// beforeMigrationFuncV11 insert the test invoices in the database.
|
||||||
|
func beforeMigrationFuncV11(t *testing.T, d *DB, invoices []Invoice) {
|
||||||
|
err := d.Update(func(tx *bbolt.Tx) error {
|
||||||
|
invoicesBucket, err := tx.CreateBucketIfNotExists(
|
||||||
|
invoiceBucket,
|
||||||
|
)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
invoiceNum := uint32(1)
|
||||||
|
for _, invoice := range invoices {
|
||||||
|
var invoiceKey [4]byte
|
||||||
|
byteOrder.PutUint32(invoiceKey[:], invoiceNum)
|
||||||
|
invoiceNum++
|
||||||
|
|
||||||
|
var buf bytes.Buffer
|
||||||
|
err := serializeInvoiceLegacy(&buf, &invoice) // nolint:scopelint
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
err = invoicesBucket.Put(
|
||||||
|
invoiceKey[:], buf.Bytes(),
|
||||||
|
)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// TestMigrateInvoices checks that invoices are migrated correctly.
|
// TestMigrateInvoices checks that invoices are migrated correctly.
|
||||||
func TestMigrateInvoices(t *testing.T) {
|
func TestMigrateInvoices(t *testing.T) {
|
||||||
t.Parallel()
|
t.Parallel()
|
||||||
@@ -49,42 +86,6 @@ func TestMigrateInvoices(t *testing.T) {
|
|||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
beforeMigrationFunc := func(d *DB) {
|
|
||||||
err := d.Update(func(tx *bbolt.Tx) error {
|
|
||||||
invoicesBucket, err := tx.CreateBucketIfNotExists(
|
|
||||||
invoiceBucket,
|
|
||||||
)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
invoiceNum := uint32(1)
|
|
||||||
for _, invoice := range invoices {
|
|
||||||
var invoiceKey [4]byte
|
|
||||||
byteOrder.PutUint32(invoiceKey[:], invoiceNum)
|
|
||||||
invoiceNum++
|
|
||||||
|
|
||||||
var buf bytes.Buffer
|
|
||||||
err := serializeInvoiceLegacy(&buf, &invoice)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
err = invoicesBucket.Put(
|
|
||||||
invoiceKey[:], buf.Bytes(),
|
|
||||||
)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return nil
|
|
||||||
})
|
|
||||||
if err != nil {
|
|
||||||
t.Fatal(err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Verify that all invoices were migrated.
|
// Verify that all invoices were migrated.
|
||||||
afterMigrationFunc := func(d *DB) {
|
afterMigrationFunc := func(d *DB) {
|
||||||
meta, err := d.FetchMeta(nil)
|
meta, err := d.FetchMeta(nil)
|
||||||
@@ -120,12 +121,38 @@ func TestMigrateInvoices(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
applyMigration(t,
|
applyMigration(t,
|
||||||
beforeMigrationFunc,
|
func(d *DB) { beforeMigrationFuncV11(t, d, invoices) },
|
||||||
afterMigrationFunc,
|
afterMigrationFunc,
|
||||||
migrateInvoices,
|
migrateInvoices,
|
||||||
false)
|
false)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TestMigrateInvoicesHodl checks that a hodl invoice in the accepted state
|
||||||
|
// fails the migration.
|
||||||
|
func TestMigrateInvoicesHodl(t *testing.T) {
|
||||||
|
t.Parallel()
|
||||||
|
|
||||||
|
payReqBtc, err := getPayReq(&bitcoinCfg.MainNetParams)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
invoices := []Invoice{
|
||||||
|
{
|
||||||
|
PaymentRequest: []byte(payReqBtc),
|
||||||
|
Terms: ContractTerm{
|
||||||
|
State: ContractAccepted,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
applyMigration(t,
|
||||||
|
func(d *DB) { beforeMigrationFuncV11(t, d, invoices) },
|
||||||
|
func(d *DB) {},
|
||||||
|
migrateInvoices,
|
||||||
|
true)
|
||||||
|
}
|
||||||
|
|
||||||
// signDigestCompact generates a test signature to be used in the generation of
|
// signDigestCompact generates a test signature to be used in the generation of
|
||||||
// test payment requests.
|
// test payment requests.
|
||||||
func signDigestCompact(hash []byte) ([]byte, error) {
|
func signDigestCompact(hash []byte) ([]byte, error) {
|
||||||
|
|||||||
Reference in new issue
Block a user