kvdb/sqlbase: define migration bulk KV interfaces
What changed, and why it matters
This commit only adds new Go interface definitions for a future database migration feature. There is no executable code, no bug fixes, and no behavior changes to the running application. It cannot be exploited or cause security issues on its own.
No security action required. Review the concrete implementations when they are submitted to ensure bulk-load transactions, truncation, and verification paths are safe.
Security signals we found
No strong security signals were identified.
Evidence from the diff
The change introduces a set of migration-only interfaces in kvdb/sqlbase/migration_bulk.go. These interfaces (MigrationBackend, MigrationBulkKVStore, MigrationBulkKVTx, MigrationBulkKVVerifier, and related structs) define contracts for bulk-loading and verifying key/value data during a one-time KV-to-SQL migration. The file contains no concrete implementations, no SQL queries, no logic, and no changes to existing APIs. It is purely a type-definition commit guarded by existing SQL backend build tags.
Changed components
kvdb/sqlbase/migration_bulk.goInspect captured patch +109 / −0
diff --git a/kvdb/sqlbase/migration_bulk.go b/kvdb/sqlbase/migration_bulk.go
new file mode 100644
index 0000000..3b4f1dc
--- /dev/null
+++ b/kvdb/sqlbase/migration_bulk.go
@@ -0,0 +1,109 @@
+//go:build kvdb_postgres || (kvdb_sqlite && !(windows && (arm || 386)) && !(linux && (ppc64 || mips || mipsle || mips64)))
+
+package sqlbase
+
+import (
+ "context"
+
+ "github.com/btcsuite/btcwallet/walletdb"
+)
+
+// MigrationBackend combines the regular walletdb database operations with the
+// migration-only bulk capabilities guaranteed by a migration backend.
+type MigrationBackend interface {
+ walletdb.DB
+ MigrationBulkKVStore
+}
+
+// MigrationBulkKVStore exposes migration-only helpers for loading and verifying
+// the SQL KV schema directly. Normal application code should continue to use
+// the walletdb/kvdb bucket APIs.
+type MigrationBulkKVStore interface {
+ // CheckEmpty returns whether the underlying KV table has no rows.
+ CheckEmpty(ctx context.Context) (bool, error)
+
+ // TruncateTargetTable unconditionally and irreversibly removes every
+ // row from the underlying KV table. It is only intended for fresh-only
+ // migration recovery when the caller owns the whole target table.
+ TruncateTargetTable(ctx context.Context) error
+
+ // BeginBulk opens a destination write transaction for bulk loading.
+ // Callers must defer Rollback immediately after a successful open; the
+ // rollback is a no-op after Commit and releases locks/connections on
+ // all other exits.
+ BeginBulk(ctx context.Context) (MigrationBulkKVTx, error)
+
+ // BeginBulkVerify opens a read transaction for batched verification.
+ // Callers must defer Rollback immediately after a successful open so
+ // the read transaction lock is always released.
+ BeginBulkVerify(ctx context.Context) (MigrationBulkKVVerifier, error)
+}
+
+// MigrationBulkLeaf is a leaf key/value row to be inserted under ParentID.
+// ParentID must be a positive row ID returned by InsertBucket. Top-level leaves
+// are not supported by the migration bulk API.
+type MigrationBulkLeaf struct {
+ ParentID int64
+
+ // Key must be non-empty.
+ Key []byte
+ Value []byte
+}
+
+// MigrationBulkKVTx is a migration-only transaction for bulk-loading SQL KV
+// data.
+type MigrationBulkKVTx interface {
+ // InsertBucket inserts a bucket row with a non-empty key. It returns
+ // the generated id. A nil parentID creates a top-level bucket.
+ InsertBucket(ctx context.Context, parentID *int64, key []byte,
+ seq uint64) (int64, error)
+
+ // InsertLeaves inserts leaf rows with non-empty keys. Implementations
+ // may choose COPY, multi-row INSERT, or another backend-specific
+ // strategy.
+ InsertLeaves(ctx context.Context, leaves []MigrationBulkLeaf) error
+
+ // Commit atomically commits the bulk load transaction.
+ Commit() error
+
+ // Rollback aborts the bulk load transaction.
+ Rollback() error
+}
+
+// MigrationBulkChild is a single SQL KV row returned by the verifier helpers.
+type MigrationBulkChild struct {
+ // ID is the SQL row id.
+ ID int64
+
+ // ParentID is nil for top-level rows.
+ ParentID *int64
+
+ // Key is the bucket key or leaf key.
+ Key []byte
+
+ // Value is the leaf value. It is nil for buckets.
+ Value []byte
+
+ // IsBucket identifies bucket rows explicitly. This avoids ambiguity
+ // between SQL NULL bucket markers and empty leaf values decoded as nil.
+ IsBucket bool
+
+ // Sequence is the bucket sequence number. It is zero for unset
+ // sequences and for leaf rows.
+ Sequence uint64
+}
+
+// MigrationBulkKVVerifier reads SQL KV rows in batches for migration
+// verification.
+type MigrationBulkKVVerifier interface {
+ // FetchTopLevel returns all top-level rows ordered by key.
+ FetchTopLevel(ctx context.Context) ([]MigrationBulkChild, error)
+
+ // FetchChildren returns direct children for the given bucket ids,
+ // ordered by parent id and key.
+ FetchChildren(ctx context.Context,
+ parentIDs []int64) ([]MigrationBulkChild, error)
+
+ // Rollback closes the verifier transaction.
+ Rollback() error
+}
Why this scored 15/100
Community notes
Notes can correct, qualify, or add evidence to the AI analysis. Every note shown here has been validated by a human moderator.
The AI analysis stands alone for now. Submit a note if you can add evidence or important context.