Merge pull request #9438 from bhandras/invoice-bucket-tombstone

channeldb+lnd: set invoice bucket tombstone after migration
This commit is contained in:
András Bánki-Horváth authored and GitHub committed 2025-02-01 10:59:51 +01:00
commit 327eb8d8ca
5 files changed
+125 -1

No files matched your search

+25
View File
@@ -103,3 +103,28 @@ func TestEncodeDecodeAmpInvoiceState(t *testing.T) {
// The two states should match.
require.Equal(t, ampState, ampState2)
}
// TestInvoiceBucketTombstone tests the behavior of setting and checking the
// invoice bucket tombstone. It verifies that the tombstone can be set correctly
// and detected when present in the database.
func TestInvoiceBucketTombstone(t *testing.T) {
t.Parallel()
// Initialize a test database.
db, err := MakeTestDB(t)
require.NoError(t, err, "unable to initialize db")
// Ensure the tombstone doesn't exist initially.
tombstoneExists, err := db.GetInvoiceBucketTombstone()
require.NoError(t, err)
require.False(t, tombstoneExists)
// Set the tombstone.
err = db.SetInvoiceBucketTombstone()
require.NoError(t, err)
// Verify that the tombstone exists after setting it.
tombstoneExists, err = db.GetInvoiceBucketTombstone()
require.NoError(t, err)
require.True(t, tombstoneExists)
}
+53
View File
@@ -80,6 +80,13 @@ var (
//
// settleIndexNo => invoiceKey
settleIndexBucket = []byte("invoice-settle-index")
// invoiceBucketTombstone is a special key that indicates the invoice
// bucket has been permanently closed. Its purpose is to prevent the
// invoice bucket from being reopened in the future. A key use case for
// the tombstone is to ensure users cannot switch back to the KV invoice
// database after migrating to the native SQL database.
invoiceBucketTombstone = []byte("invoice-tombstone")
)
const (
@@ -2400,3 +2407,49 @@ func (d *DB) DeleteInvoice(_ context.Context,
return err
}
// SetInvoiceBucketTombstone sets the tombstone key in the invoice bucket to
// mark the bucket as permanently closed. This prevents it from being reopened
// in the future.
func (d *DB) SetInvoiceBucketTombstone() error {
return kvdb.Update(d, func(tx kvdb.RwTx) error {
// Access the top-level invoice bucket.
invoices := tx.ReadWriteBucket(invoiceBucket)
if invoices == nil {
return fmt.Errorf("invoice bucket does not exist")
}
// Add the tombstone key to the invoice bucket.
err := invoices.Put(invoiceBucketTombstone, []byte("1"))
if err != nil {
return fmt.Errorf("failed to set tombstone: %w", err)
}
return nil
}, func() {})
}
// GetInvoiceBucketTombstone checks if the tombstone key exists in the invoice
// bucket. It returns true if the tombstone is present and false otherwise.
func (d *DB) GetInvoiceBucketTombstone() (bool, error) {
var tombstoneExists bool
err := kvdb.View(d, func(tx kvdb.RTx) error {
// Access the top-level invoice bucket.
invoices := tx.ReadBucket(invoiceBucket)
if invoices == nil {
return fmt.Errorf("invoice bucket does not exist")
}
// Check if the tombstone key exists.
tombstone := invoices.Get(invoiceBucketTombstone)
tombstoneExists = tombstone != nil
return nil
}, func() {})
if err != nil {
return false, err
}
return tombstoneExists, nil
}