walletdb

package
v0.0.0-...-5a930d7 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jun 13, 2023 License: MIT Imports: 2 Imported by: 0

README

walletdb

[Build Status] (https://travis-ci.org/btcsuite/btcwallet)

Package walletdb provides a namespaced database interface for btcwallet.

A wallet essentially consists of a multitude of stored data such as private and public keys, key derivation bits, pay-to-script-hash scripts, and various metadata. One of the issues with many wallets is they are tightly integrated. Designing a wallet with loosely coupled components that provide specific functionality is ideal, however it presents a challenge in regards to data storage since each component needs to store its own data without knowing the internals of other components or breaking atomicity.

This package solves this issue by providing a namespaced database interface that is intended to be used by the main wallet daemon. This allows the potential for any backend database type with a suitable driver. Each component, which will typically be a package, can then implement various functionality such as address management, voting pools, and colored coin metadata in their own namespace without having to worry about conflicts with other packages even though they are sharing the same database that is managed by the wallet.

A suite of tests is provided to ensure proper functionality. See test_coverage.txt for the gocov coverage report. Alternatively, if you are running a POSIX OS, you can run the cov_report.sh script for a real-time report. Package walletdb is licensed under the copyfree ISC license.

This interfaces provided by this package were heavily inspired by the excellent boltdb project at https://github.com/boltdb/bolt by Ben B. Johnson.

Feature Overview

  • Key/value store
  • Namespace support
    • Allows multiple packages to have their own area in the database without worrying about conflicts
  • Read-only and read-write transactions with both manual and managed modes
  • Nested buckets
  • Supports registration of backend databases
  • Comprehensive test coverage

Documentation

[GoDoc] (http://godoc.org/github.com/btcsuite/btcwallet/walletdb)

Full go doc style documentation for the project can be viewed online without installing this package by using the GoDoc site here: http://godoc.org/github.com/btcsuite/btcwallet/walletdb

You can also view the documentation locally once the package is installed with the godoc tool by running godoc -http=":6060" and pointing your browser to http://localhost:6060/pkg/github.com/btcsuite/btcwallet/walletdb

Installation

$ go get github.com/btcsuite/btcwallet/walletdb

Examples

License

Package walletdb is licensed under the copyfree ISC License.

Documentation

Index

Constants

This section is empty.

Variables

View Source
var (
	// ErrDbUnknownType is returned when there is no driver registered for
	// the specified database type.
	ErrDbUnknownType = errors.New("unknown database type")

	// ErrDbDoesNotExist is returned when open is called for a database that
	// does not exist.
	ErrDbDoesNotExist = errors.New("database does not exist")

	// ErrDbExists is returned when create is called for a database that
	// already exists.
	ErrDbExists = errors.New("database already exists")

	// ErrDbNotOpen is returned when a database instance is accessed before
	// it is opened or after it is closed.
	ErrDbNotOpen = errors.New("database not open")

	// ErrDbAlreadyOpen is returned when open is called on a database that
	// is already open.
	ErrDbAlreadyOpen = errors.New("database already open")

	// ErrInvalid is returned if the specified database is not valid.
	ErrInvalid = errors.New("invalid database")
)

Errors that the various database functions may return.

View Source
var (
	// ErrTxClosed is returned when attempting to commit or rollback a
	// transaction that has already had one of those operations performed.
	ErrTxClosed = errors.New("tx closed")

	// ErrTxNotWritable is returned when an operation that requires write
	// access to the database is attempted against a read-only transaction.
	ErrTxNotWritable = errors.New("tx not writable")
)

Errors that can occur when beginning or committing a transaction.

View Source
var (
	// ErrBucketNotFound is returned when trying to access a bucket that has
	// not been created yet.
	ErrBucketNotFound = errors.New("bucket not found")

	// ErrBucketExists is returned when creating a bucket that already exists.
	ErrBucketExists = errors.New("bucket already exists")

	// ErrBucketNameRequired is returned when creating a bucket with a blank name.
	ErrBucketNameRequired = errors.New("bucket name required")

	// ErrKeyRequired is returned when inserting a zero-length key.
	ErrKeyRequired = errors.New("key required")

	// ErrKeyTooLarge is returned when inserting a key that is larger than MaxKeySize.
	ErrKeyTooLarge = errors.New("key too large")

	// ErrValueTooLarge is returned when inserting a value that is larger than MaxValueSize.
	ErrValueTooLarge = errors.New("value too large")

	// ErrIncompatibleValue is returned when trying create or delete a
	// bucket on an existing non-bucket key or when trying to create or
	// delete a non-bucket key on an existing bucket key.
	ErrIncompatibleValue = errors.New("incompatible value")
)

Errors that can occur when putting or deleting a value or bucket.

View Source
var (
	// ErrDbTypeRegistered is returned when two different database drivers
	// attempt to register with the name database type.
	ErrDbTypeRegistered = errors.New("database type already registered")
)

Errors that can occur during driver registration.

Functions

func BucketIsEmpty

func BucketIsEmpty(bucket ReadBucket) bool

BucketIsEmpty returns whether the bucket is empty, that is, whether there are no key/value pairs or nested buckets.

func RegisterDriver

func RegisterDriver(driver Driver) error

RegisterDriver adds a backend database driver to available interfaces. ErrDbTypeRegistered will be retruned if the database type for the driver has already been registered.

func SupportedDrivers

func SupportedDrivers() []string

SupportedDrivers returns a slice of strings that represent the database drivers that have been registered and are therefore supported.

func Update

func Update(db DB, f func(tx ReadWriteTx) error) error

Update opens a database read/write transaction and executes the function f with the transaction passed as a parameter. After f exits, if f did not error, the transaction is committed. Otherwise, if f did error, the transaction is rolled back. If the rollback fails, the original error returned by f is still returned. If the commit fails, the commit error is returned.

func View

func View(db DB, f func(tx ReadTx) error) error

View opens a database read transaction and executes the function f with the transaction passed as a parameter. After f exits, the transaction is rolled back. If f errors, its error is returned, not a rollback error (if any occur).

Types

type DB

type DB interface {
	// BeginReadTx opens a database read transaction.
	BeginReadTx() (ReadTx, error)

	// BeginReadWriteTx opens a database read+write transaction.
	BeginReadWriteTx() (ReadWriteTx, error)

	// Copy writes a copy of the database to the provided writer.  This
	// call will start a read-only transaction to perform all operations.
	Copy(w io.Writer) error

	// Close cleanly shuts down the database and syncs all data.
	Close() error
}

DB represents an ACID database. All database access is performed through read or read+write transactions.

func Create

func Create(dbType string, args ...interface{}) (DB, error)

Create intializes and opens a database for the specified type. The arguments are specific to the database type driver. See the documentation for the database driver for further details.

ErrDbUnknownType will be returned if the the database type is not registered.

func Open

func Open(dbType string, args ...interface{}) (DB, error)

Open opens an existing database for the specified type. The arguments are specific to the database type driver. See the documentation for the database driver for further details.

ErrDbUnknownType will be returned if the the database type is not registered.

type Driver

type Driver struct {
	// DbType is the identifier used to uniquely identify a specific
	// database driver.  There can be only one driver with the same name.
	DbType string

	// Create is the function that will be invoked with all user-specified
	// arguments to create the database.  This function must return
	// ErrDbExists if the database already exists.
	Create func(args ...interface{}) (DB, error)

	// Open is the function that will be invoked with all user-specified
	// arguments to open the database.  This function must return
	// ErrDbDoesNotExist if the database has not already been created.
	Open func(args ...interface{}) (DB, error)
}

Driver defines a structure for backend drivers to use when they registered themselves as a backend which implements the Db interface.

type ReadBucket

type ReadBucket interface {
	// NestedReadBucket retrieves a nested bucket with the given key.
	// Returns nil if the bucket does not exist.
	NestedReadBucket(key []byte) ReadBucket
	// ForEach invokes the passed function with every key/value pair in
	// the bucket.  This includes nested buckets, in which case the value
	// is nil, but it does not include the key/value pairs within those
	// nested buckets.
	//
	// NOTE: The values returned by this function are only valid during a
	// transaction.  Attempting to access them after a transaction has ended
	// results in undefined behavior.  This constraint prevents additional
	// data copies and allows support for memory-mapped database
	// implementations.
	ForEach(func(k, v []byte) error) error

	// Get returns the value for the given key.  Returns nil if the key does
	// not exist in this bucket (or nested buckets).
	//
	// NOTE: The value returned by this function is only valid during a
	// transaction.  Attempting to access it after a transaction has ended
	// results in undefined behavior.  This constraint prevents additional
	// data copies and allows support for memory-mapped database
	// implementations.
	Get(key []byte) []byte

	ReadCursor() ReadCursor
}

ReadBucket represents a bucket (a hierarchical structure within the database) that is only allowed to perform read operations.

type ReadCursor

type ReadCursor interface {
	// First positions the cursor at the first key/value pair and returns
	// the pair.
	First() (key, value []byte)

	// Last positions the cursor at the last key/value pair and returns the
	// pair.
	Last() (key, value []byte)

	// Next moves the cursor one key/value pair forward and returns the new
	// pair.
	Next() (key, value []byte)

	// Prev moves the cursor one key/value pair backward and returns the new
	// pair.
	Prev() (key, value []byte)

	// Seek positions the cursor at the passed seek key.  If the key does
	// not exist, the cursor is moved to the next key after seek.  Returns
	// the new pair.
	Seek(seek []byte) (key, value []byte)
}

ReadCursor represents a bucket cursor that can be positioned at the start or end of the bucket's key/value pairs and iterate over pairs in the bucket. This type is only allowed to perform database read operations.

type ReadTx

type ReadTx interface {
	// ReadBucket opens the root bucket for read only access.  If the bucket
	// described by the key does not exist, nil is returned.
	ReadBucket(key []byte) ReadBucket

	// Rollback closes the transaction, discarding changes (if any) if the
	// database was modified by a write transaction.
	Rollback() error
}

ReadTx represents a database transaction that can only be used for reads. If a database update must occur, use a ReadWriteTx.

type ReadWriteBucket

type ReadWriteBucket interface {
	ReadBucket

	// NestedReadWriteBucket retrieves a nested bucket with the given key.
	// Returns nil if the bucket does not exist.
	NestedReadWriteBucket(key []byte) ReadWriteBucket

	NestedAndCreateReadWriteBucket(key []byte) ReadWriteBucket

	// CreateBucket creates and returns a new nested bucket with the given
	// key.  Returns ErrBucketExists if the bucket already exists,
	// ErrBucketNameRequired if the key is empty, or ErrIncompatibleValue
	// if the key value is otherwise invalid for the particular database
	// implementation.  Other errors are possible depending on the
	// implementation.
	CreateBucket(key []byte) (ReadWriteBucket, error)

	// CreateBucketIfNotExists creates and returns a new nested bucket with
	// the given key if it does not already exist.  Returns
	// ErrBucketNameRequired if the key is empty or ErrIncompatibleValue
	// if the key value is otherwise invalid for the particular database
	// backend.  Other errors are possible depending on the implementation.
	CreateBucketIfNotExists(key []byte) (ReadWriteBucket, error)

	// DeleteNestedBucket removes a nested bucket with the given key.
	// Returns ErrTxNotWritable if attempted against a read-only transaction
	// and ErrBucketNotFound if the specified bucket does not exist.
	DeleteNestedBucket(key []byte) error

	// Put saves the specified key/value pair to the bucket.  Keys that do
	// not already exist are added and keys that already exist are
	// overwritten.  Returns ErrTxNotWritable if attempted against a
	// read-only transaction.
	Put(key, value []byte) error

	// Delete removes the specified key from the bucket.  Deleting a key
	// that does not exist does not return an error.  Returns
	// ErrTxNotWritable if attempted against a read-only transaction.
	Delete(key []byte) error

	// Cursor returns a new cursor, allowing for iteration over the bucket's
	// key/value pairs and nested buckets in forward or backward order.
	ReadWriteCursor() ReadWriteCursor

	// Tx returns the bucket's transaction.
	Tx() ReadWriteTx
}

ReadWriteBucket represents a bucket (a hierarchical structure within the database) that is allowed to perform both read and write operations.

type ReadWriteCursor

type ReadWriteCursor interface {
	ReadCursor

	// Delete removes the current key/value pair the cursor is at without
	// invalidating the cursor.  Returns ErrIncompatibleValue if attempted
	// when the cursor points to a nested bucket.
	Delete() error
}

ReadWriteCursor represents a bucket cursor that can be positioned at the start or end of the bucket's key/value pairs and iterate over pairs in the bucket. This abstraction is allowed to perform both database read and write operations.

type ReadWriteTx

type ReadWriteTx interface {
	ReadTx

	// ReadWriteBucket opens the root bucket for read/write access.  If the
	// bucket described by the key does not exist, nil is returned.
	ReadWriteBucket(key []byte) ReadWriteBucket

	// CreateTopLevelBucket creates the top level bucket for a key if it
	// does not exist.  The newly-created bucket it returned.
	CreateTopLevelBucket(key []byte) (ReadWriteBucket, error)

	// DeleteTopLevelBucket deletes the top level bucket for a key.  This
	// errors if the bucket can not be found or the key keys a single value
	// instead of a bucket.
	DeleteTopLevelBucket(key []byte) error

	// Commit commits all changes that have been on the transaction's root
	// buckets and all of their sub-buckets to persistent storage.
	Commit() error

	// OnCommit takes a function closure that will be executed when the
	// transaction successfully gets committed.
	OnCommit(func())
}

ReadWriteTx represents a database transaction that can be used for both reads and writes. When only reads are necessary, consider using a ReadTx instead.

Directories

Path Synopsis

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL