func storeRandomLockID(metadata *bbolt.Bucket) error {
	var lockID wtxmgr.LockID
	if _, err := rand.Read(lockID[:]); err != nil {
		return err
	}
	return metadata.Put(lockIDKey, lockID[:])
}
storeRandomLockID generates a random lock ID backed by the system's CSPRNG
and stores it under the metadata bucket.
package clientdb
import (
	"crypto/rand"
	"errors"
	"fmt"
	"github.com/btcsuite/btcwallet/wtxmgr"
	"github.com/lightninglabs/pool/clientdb/migrations"
	"go.etcd.io/bbolt"
)
type migration func(tx *bbolt.Tx) error
var (
	metadataBucketKey = []byte("metadata")
	dbVersionKey = []byte("version")
	lockIDKey = []byte("lock-id")
	ErrDBReversion = errors.New("cannot revert to prior version")
	dbVersions = []migration{
		migrations.AddInitialOrderTimestamps,
	}
	latestDBVersion = uint32(len(dbVersions))
)
func getDBVersion(bucket *bbolt.Bucket) (uint32, error) {
	versionBytes := bucket.Get(dbVersionKey)
	if versionBytes == nil {
		return 0, errors.New("database version not found")
	}
	return byteOrder.Uint32(versionBytes), nil
}
func setDBVersion(bucket *bbolt.Bucket, version uint32) error {
	var b [4]byte
	byteOrder.PutUint32(b[:], version)
	return bucket.Put(dbVersionKey, b[:])
}
func getBucket(tx *bbolt.Tx, key []byte) (*bbolt.Bucket, error) {
	bucket := tx.Bucket(key)
	if bucket == nil {
		return nil, fmt.Errorf("bucket \"%v\" does not exist",
			string(key))
	}
	return bucket, nil
}
func getNestedBucket(bucket *bbolt.Bucket, key []byte,
	create bool) (*bbolt.Bucket, error) {
	nestedBucket := bucket.Bucket(key)
	if nestedBucket == nil && create {
		return bucket.CreateBucketIfNotExists(key)
	}
	if nestedBucket == nil {
		return nil, fmt.Errorf("nested bucket \"%v\" does not exist",
			string(key))
	}
	return nestedBucket, nil
}
func syncVersions(db *bbolt.DB) error {
	var currentVersion uint32
	err := db.View(func(tx *bbolt.Tx) error {
		metadata, err := getBucket(tx, metadataBucketKey)
		if err != nil {
			return err
		}
		currentVersion, err = getDBVersion(metadata)
		return err
	})
	if err != nil {
		return err
	}
	log.Infof("Checking for schema update: latest_version=%v, "+
		"db_version=%v", latestDBVersion, currentVersion)
	switch {
	case currentVersion > latestDBVersion:
		log.Errorf("Refusing to revert from db_version=%d to "+
			"lower version=%d", currentVersion,
			latestDBVersion)
		return ErrDBReversion
	case currentVersion == latestDBVersion:
		return nil
	}
	log.Infof("Performing database schema migration")
	return db.Update(func(tx *bbolt.Tx) error {
		for v := currentVersion; v < latestDBVersion; v++ {
			log.Infof("Applying migration #%v", v+1)
			migration := dbVersions[v]
			if err := migration(tx); err != nil {
				log.Infof("Unable to apply migration #%v", v+1)
				return err
			}
		}
		metadata, err := getBucket(tx, metadataBucketKey)
		if err != nil {
			return err
		}
		return setDBVersion(metadata, latestDBVersion)
	})
}