From 10efa7d582ece2e56aa1a72e154cff855f871a97 Mon Sep 17 00:00:00 2001 From: Wilmer Paulino Date: Tue, 9 Jun 2020 16:51:24 -0700 Subject: [PATCH] clientdb: store global random lock ID upon database initialization --- clientdb/db.go | 3 +++ clientdb/metadata.go | 40 ++++++++++++++++++++++++++++++++++++++++ 2 files changed, 43 insertions(+) diff --git a/clientdb/db.go b/clientdb/db.go index 59ef932..b6ba033 100644 --- a/clientdb/db.go +++ b/clientdb/db.go @@ -84,6 +84,9 @@ func initDB(filepath string, firstInit bool) (*bbolt.DB, error) { if err != nil { return err } + if err := storeRandomLockID(metadataBucket); err != nil { + return err + } } _, err = tx.CreateBucketIfNotExists(accountBucketKey) diff --git a/clientdb/metadata.go b/clientdb/metadata.go index 753d988..2c8e493 100644 --- a/clientdb/metadata.go +++ b/clientdb/metadata.go @@ -1,9 +1,11 @@ package clientdb import ( + "crypto/rand" "errors" "fmt" + "github.com/btcsuite/btcwallet/wtxmgr" "github.com/coreos/bbolt" ) @@ -21,6 +23,13 @@ var ( // database version. dbVersionKey = []byte("version") + // lockIDKey is the daabase key used for storing/retrieving the global + // lock ID to use when leasing outputs from the backing lnd node's + // wallet. This is mostly required so that calls to LeaseOutput are + // idempotent when attempting to lease an output we already have a lease + // for. + lockIDKey = []byte("lock-id") + // ErrDBReversion is returned when detecting an attempt to revert to a // prior database version. ErrDBReversion = errors.New("cannot revert to prior version") @@ -137,3 +146,34 @@ func syncVersions(db *bbolt.DB) error { return setDBVersion(metadata, latestDBVersion) }) } + +// storeRandomLockID generates a random lock ID backed by the system's CSPRNG +// and stores it under the metadata bucket. +func storeRandomLockID(metadata *bbolt.Bucket) error { + var lockID wtxmgr.LockID + if _, err := rand.Read(lockID[:]); err != nil { + return err + } + return metadata.Put(lockIDKey, lockID[:]) +} + +// LockID retrieves the database's global lock ID used to lease outputs from the +// backing lnd node's wallet. +func (db *DB) LockID() (wtxmgr.LockID, error) { + var lockID wtxmgr.LockID + err := db.View(func(tx *bbolt.Tx) error { + metadata, err := getBucket(tx, metadataBucketKey) + if err != nil { + return err + } + + lockIDBytes := metadata.Get(lockIDKey) + if lockIDBytes == nil { + return errors.New("lock ID not found") + } + + copy(lockID[:], lockIDBytes) + return nil + }) + return lockID, err +}