mirror of
https://github.com/muun/recovery.git
synced 2025-11-11 06:20:16 -05:00
Release v0.1.0
This commit is contained in:
16
vendor/github.com/btcsuite/btcwallet/walletdb/LICENSE
generated
vendored
Normal file
16
vendor/github.com/btcsuite/btcwallet/walletdb/LICENSE
generated
vendored
Normal file
@@ -0,0 +1,16 @@
|
||||
ISC License
|
||||
|
||||
Copyright (c) 2013-2017 The btcsuite developers
|
||||
Copyright (c) 2015-2016 The Decred developers
|
||||
|
||||
Permission to use, copy, modify, and distribute this software for any
|
||||
purpose with or without fee is hereby granted, provided that the above
|
||||
copyright notice and this permission notice appear in all copies.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
75
vendor/github.com/btcsuite/btcwallet/walletdb/README.md
generated
vendored
Normal file
75
vendor/github.com/btcsuite/btcwallet/walletdb/README.md
generated
vendored
Normal file
@@ -0,0 +1,75 @@
|
||||
walletdb
|
||||
========
|
||||
|
||||
[]
|
||||
(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
|
||||
|
||||
[]
|
||||
(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
|
||||
|
||||
```bash
|
||||
$ go get github.com/btcsuite/btcwallet/walletdb
|
||||
```
|
||||
|
||||
## Examples
|
||||
|
||||
* [Basic Usage Example]
|
||||
(http://godoc.org/github.com/btcsuite/btcwallet/walletdb#example-package--BasicUsage)
|
||||
Demonstrates creating a new database, getting a namespace from it, and using a
|
||||
managed read-write transaction against the namespace to store and retrieve
|
||||
data.
|
||||
|
||||
|
||||
## License
|
||||
|
||||
Package walletdb is licensed under the [copyfree](http://copyfree.org) ISC
|
||||
License.
|
||||
46
vendor/github.com/btcsuite/btcwallet/walletdb/bdb/README.md
generated
vendored
Normal file
46
vendor/github.com/btcsuite/btcwallet/walletdb/bdb/README.md
generated
vendored
Normal file
@@ -0,0 +1,46 @@
|
||||
bdb
|
||||
===
|
||||
|
||||
[]
|
||||
(https://travis-ci.org/btcsuite/btcwallet)
|
||||
|
||||
Package bdb implements an driver for walletdb that uses boltdb for the backing
|
||||
datastore. Package bdb is licensed under the copyfree ISC license.
|
||||
|
||||
## Usage
|
||||
|
||||
This package is only a driver to the walletdb package and provides the database
|
||||
type of "bdb". The only parameter the Open and Create functions take is the
|
||||
database path as a string:
|
||||
|
||||
```Go
|
||||
db, err := walletdb.Open("bdb", "path/to/database.db")
|
||||
if err != nil {
|
||||
// Handle error
|
||||
}
|
||||
```
|
||||
|
||||
```Go
|
||||
db, err := walletdb.Create("bdb", "path/to/database.db")
|
||||
if err != nil {
|
||||
// Handle error
|
||||
}
|
||||
```
|
||||
|
||||
## Documentation
|
||||
|
||||
[]
|
||||
(http://godoc.org/github.com/btcsuite/btcwallet/walletdb/bdb)
|
||||
|
||||
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/bdb
|
||||
|
||||
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/bdb
|
||||
|
||||
## License
|
||||
|
||||
Package bdb is licensed under the [copyfree](http://copyfree.org) ISC
|
||||
License.
|
||||
356
vendor/github.com/btcsuite/btcwallet/walletdb/bdb/db.go
generated
vendored
Normal file
356
vendor/github.com/btcsuite/btcwallet/walletdb/bdb/db.go
generated
vendored
Normal file
@@ -0,0 +1,356 @@
|
||||
// Copyright (c) 2014 The btcsuite developers
|
||||
// Use of this source code is governed by an ISC
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package bdb
|
||||
|
||||
import (
|
||||
"io"
|
||||
"os"
|
||||
|
||||
"github.com/btcsuite/btcwallet/walletdb"
|
||||
"github.com/coreos/bbolt"
|
||||
)
|
||||
|
||||
// convertErr converts some bolt errors to the equivalent walletdb error.
|
||||
func convertErr(err error) error {
|
||||
switch err {
|
||||
// Database open/create errors.
|
||||
case bbolt.ErrDatabaseNotOpen:
|
||||
return walletdb.ErrDbNotOpen
|
||||
case bbolt.ErrInvalid:
|
||||
return walletdb.ErrInvalid
|
||||
|
||||
// Transaction errors.
|
||||
case bbolt.ErrTxNotWritable:
|
||||
return walletdb.ErrTxNotWritable
|
||||
case bbolt.ErrTxClosed:
|
||||
return walletdb.ErrTxClosed
|
||||
|
||||
// Value/bucket errors.
|
||||
case bbolt.ErrBucketNotFound:
|
||||
return walletdb.ErrBucketNotFound
|
||||
case bbolt.ErrBucketExists:
|
||||
return walletdb.ErrBucketExists
|
||||
case bbolt.ErrBucketNameRequired:
|
||||
return walletdb.ErrBucketNameRequired
|
||||
case bbolt.ErrKeyRequired:
|
||||
return walletdb.ErrKeyRequired
|
||||
case bbolt.ErrKeyTooLarge:
|
||||
return walletdb.ErrKeyTooLarge
|
||||
case bbolt.ErrValueTooLarge:
|
||||
return walletdb.ErrValueTooLarge
|
||||
case bbolt.ErrIncompatibleValue:
|
||||
return walletdb.ErrIncompatibleValue
|
||||
}
|
||||
|
||||
// Return the original error if none of the above applies.
|
||||
return err
|
||||
}
|
||||
|
||||
// transaction represents a database transaction. It can either by read-only or
|
||||
// read-write and implements the walletdb Tx interfaces. The transaction
|
||||
// provides a root bucket against which all read and writes occur.
|
||||
type transaction struct {
|
||||
boltTx *bbolt.Tx
|
||||
}
|
||||
|
||||
func (tx *transaction) ReadBucket(key []byte) walletdb.ReadBucket {
|
||||
return tx.ReadWriteBucket(key)
|
||||
}
|
||||
|
||||
func (tx *transaction) ReadWriteBucket(key []byte) walletdb.ReadWriteBucket {
|
||||
boltBucket := tx.boltTx.Bucket(key)
|
||||
if boltBucket == nil {
|
||||
return nil
|
||||
}
|
||||
return (*bucket)(boltBucket)
|
||||
}
|
||||
|
||||
func (tx *transaction) CreateTopLevelBucket(key []byte) (walletdb.ReadWriteBucket, error) {
|
||||
boltBucket, err := tx.boltTx.CreateBucket(key)
|
||||
if err != nil {
|
||||
return nil, convertErr(err)
|
||||
}
|
||||
return (*bucket)(boltBucket), nil
|
||||
}
|
||||
|
||||
func (tx *transaction) DeleteTopLevelBucket(key []byte) error {
|
||||
err := tx.boltTx.DeleteBucket(key)
|
||||
if err != nil {
|
||||
return convertErr(err)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// Commit commits all changes that have been made through the root bucket and
|
||||
// all of its sub-buckets to persistent storage.
|
||||
//
|
||||
// This function is part of the walletdb.ReadWriteTx interface implementation.
|
||||
func (tx *transaction) Commit() error {
|
||||
return convertErr(tx.boltTx.Commit())
|
||||
}
|
||||
|
||||
// Rollback undoes all changes that have been made to the root bucket and all of
|
||||
// its sub-buckets.
|
||||
//
|
||||
// This function is part of the walletdb.ReadTx interface implementation.
|
||||
func (tx *transaction) Rollback() error {
|
||||
return convertErr(tx.boltTx.Rollback())
|
||||
}
|
||||
|
||||
// OnCommit takes a function closure that will be executed when the transaction
|
||||
// successfully gets committed.
|
||||
//
|
||||
// This function is part of the walletdb.ReadWriteTx interface implementation.
|
||||
func (tx *transaction) OnCommit(f func()) {
|
||||
tx.boltTx.OnCommit(f)
|
||||
}
|
||||
|
||||
// bucket is an internal type used to represent a collection of key/value pairs
|
||||
// and implements the walletdb Bucket interfaces.
|
||||
type bucket bbolt.Bucket
|
||||
|
||||
// Enforce bucket implements the walletdb Bucket interfaces.
|
||||
var _ walletdb.ReadWriteBucket = (*bucket)(nil)
|
||||
|
||||
// NestedReadWriteBucket retrieves a nested bucket with the given key. Returns
|
||||
// nil if the bucket does not exist.
|
||||
//
|
||||
// This function is part of the walletdb.ReadWriteBucket interface implementation.
|
||||
func (b *bucket) NestedReadWriteBucket(key []byte) walletdb.ReadWriteBucket {
|
||||
boltBucket := (*bbolt.Bucket)(b).Bucket(key)
|
||||
// Don't return a non-nil interface to a nil pointer.
|
||||
if boltBucket == nil {
|
||||
return nil
|
||||
}
|
||||
return (*bucket)(boltBucket)
|
||||
}
|
||||
|
||||
func (b *bucket) NestedReadBucket(key []byte) walletdb.ReadBucket {
|
||||
return b.NestedReadWriteBucket(key)
|
||||
}
|
||||
|
||||
// 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.
|
||||
//
|
||||
// This function is part of the walletdb.ReadWriteBucket interface implementation.
|
||||
func (b *bucket) CreateBucket(key []byte) (walletdb.ReadWriteBucket, error) {
|
||||
boltBucket, err := (*bbolt.Bucket)(b).CreateBucket(key)
|
||||
if err != nil {
|
||||
return nil, convertErr(err)
|
||||
}
|
||||
return (*bucket)(boltBucket), nil
|
||||
}
|
||||
|
||||
// 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.
|
||||
//
|
||||
// This function is part of the walletdb.ReadWriteBucket interface implementation.
|
||||
func (b *bucket) CreateBucketIfNotExists(key []byte) (walletdb.ReadWriteBucket, error) {
|
||||
boltBucket, err := (*bbolt.Bucket)(b).CreateBucketIfNotExists(key)
|
||||
if err != nil {
|
||||
return nil, convertErr(err)
|
||||
}
|
||||
return (*bucket)(boltBucket), nil
|
||||
}
|
||||
|
||||
// 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.
|
||||
//
|
||||
// This function is part of the walletdb.ReadWriteBucket interface implementation.
|
||||
func (b *bucket) DeleteNestedBucket(key []byte) error {
|
||||
return convertErr((*bbolt.Bucket)(b).DeleteBucket(key))
|
||||
}
|
||||
|
||||
// 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 will
|
||||
// likely result in an access violation.
|
||||
//
|
||||
// This function is part of the walletdb.ReadBucket interface implementation.
|
||||
func (b *bucket) ForEach(fn func(k, v []byte) error) error {
|
||||
return convertErr((*bbolt.Bucket)(b).ForEach(fn))
|
||||
}
|
||||
|
||||
// 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.
|
||||
//
|
||||
// This function is part of the walletdb.ReadWriteBucket interface implementation.
|
||||
func (b *bucket) Put(key, value []byte) error {
|
||||
return convertErr((*bbolt.Bucket)(b).Put(key, value))
|
||||
}
|
||||
|
||||
// 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
|
||||
// will likely result in an access violation.
|
||||
//
|
||||
// This function is part of the walletdb.ReadBucket interface implementation.
|
||||
func (b *bucket) Get(key []byte) []byte {
|
||||
return (*bbolt.Bucket)(b).Get(key)
|
||||
}
|
||||
|
||||
// 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.
|
||||
//
|
||||
// This function is part of the walletdb.ReadWriteBucket interface implementation.
|
||||
func (b *bucket) Delete(key []byte) error {
|
||||
return convertErr((*bbolt.Bucket)(b).Delete(key))
|
||||
}
|
||||
|
||||
func (b *bucket) ReadCursor() walletdb.ReadCursor {
|
||||
return b.ReadWriteCursor()
|
||||
}
|
||||
|
||||
// ReadWriteCursor returns a new cursor, allowing for iteration over the bucket's
|
||||
// key/value pairs and nested buckets in forward or backward order.
|
||||
//
|
||||
// This function is part of the walletdb.ReadWriteBucket interface implementation.
|
||||
func (b *bucket) ReadWriteCursor() walletdb.ReadWriteCursor {
|
||||
return (*cursor)((*bbolt.Bucket)(b).Cursor())
|
||||
}
|
||||
|
||||
// Tx returns the bucket's transaction.
|
||||
//
|
||||
// This function is part of the walletdb.ReadWriteBucket interface implementation.
|
||||
func (b *bucket) Tx() walletdb.ReadWriteTx {
|
||||
return &transaction{
|
||||
(*bbolt.Bucket)(b).Tx(),
|
||||
}
|
||||
}
|
||||
|
||||
// cursor represents a cursor over key/value pairs and nested buckets of a
|
||||
// bucket.
|
||||
//
|
||||
// Note that open cursors are not tracked on bucket changes and any
|
||||
// modifications to the bucket, with the exception of cursor.Delete, invalidate
|
||||
// the cursor. After invalidation, the cursor must be repositioned, or the keys
|
||||
// and values returned may be unpredictable.
|
||||
type cursor bbolt.Cursor
|
||||
|
||||
// Delete removes the current key/value pair the cursor is at without
|
||||
// invalidating the cursor. Returns ErrTxNotWritable if attempted on a read-only
|
||||
// transaction, or ErrIncompatibleValue if attempted when the cursor points to a
|
||||
// nested bucket.
|
||||
//
|
||||
// This function is part of the walletdb.ReadWriteCursor interface implementation.
|
||||
func (c *cursor) Delete() error {
|
||||
return convertErr((*bbolt.Cursor)(c).Delete())
|
||||
}
|
||||
|
||||
// First positions the cursor at the first key/value pair and returns the pair.
|
||||
//
|
||||
// This function is part of the walletdb.ReadCursor interface implementation.
|
||||
func (c *cursor) First() (key, value []byte) {
|
||||
return (*bbolt.Cursor)(c).First()
|
||||
}
|
||||
|
||||
// Last positions the cursor at the last key/value pair and returns the pair.
|
||||
//
|
||||
// This function is part of the walletdb.ReadCursor interface implementation.
|
||||
func (c *cursor) Last() (key, value []byte) {
|
||||
return (*bbolt.Cursor)(c).Last()
|
||||
}
|
||||
|
||||
// Next moves the cursor one key/value pair forward and returns the new pair.
|
||||
//
|
||||
// This function is part of the walletdb.ReadCursor interface implementation.
|
||||
func (c *cursor) Next() (key, value []byte) {
|
||||
return (*bbolt.Cursor)(c).Next()
|
||||
}
|
||||
|
||||
// Prev moves the cursor one key/value pair backward and returns the new pair.
|
||||
//
|
||||
// This function is part of the walletdb.ReadCursor interface implementation.
|
||||
func (c *cursor) Prev() (key, value []byte) {
|
||||
return (*bbolt.Cursor)(c).Prev()
|
||||
}
|
||||
|
||||
// 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.
|
||||
//
|
||||
// This function is part of the walletdb.ReadCursor interface implementation.
|
||||
func (c *cursor) Seek(seek []byte) (key, value []byte) {
|
||||
return (*bbolt.Cursor)(c).Seek(seek)
|
||||
}
|
||||
|
||||
// db represents a collection of namespaces which are persisted and implements
|
||||
// the walletdb.Db interface. All database access is performed through
|
||||
// transactions which are obtained through the specific Namespace.
|
||||
type db bbolt.DB
|
||||
|
||||
// Enforce db implements the walletdb.Db interface.
|
||||
var _ walletdb.DB = (*db)(nil)
|
||||
|
||||
func (db *db) beginTx(writable bool) (*transaction, error) {
|
||||
boltTx, err := (*bbolt.DB)(db).Begin(writable)
|
||||
if err != nil {
|
||||
return nil, convertErr(err)
|
||||
}
|
||||
return &transaction{boltTx: boltTx}, nil
|
||||
}
|
||||
|
||||
func (db *db) BeginReadTx() (walletdb.ReadTx, error) {
|
||||
return db.beginTx(false)
|
||||
}
|
||||
|
||||
func (db *db) BeginReadWriteTx() (walletdb.ReadWriteTx, error) {
|
||||
return db.beginTx(true)
|
||||
}
|
||||
|
||||
// Copy writes a copy of the database to the provided writer. This call will
|
||||
// start a read-only transaction to perform all operations.
|
||||
//
|
||||
// This function is part of the walletdb.Db interface implementation.
|
||||
func (db *db) Copy(w io.Writer) error {
|
||||
return convertErr((*bbolt.DB)(db).View(func(tx *bbolt.Tx) error {
|
||||
return tx.Copy(w)
|
||||
}))
|
||||
}
|
||||
|
||||
// Close cleanly shuts down the database and syncs all data.
|
||||
//
|
||||
// This function is part of the walletdb.Db interface implementation.
|
||||
func (db *db) Close() error {
|
||||
return convertErr((*bbolt.DB)(db).Close())
|
||||
}
|
||||
|
||||
// filesExists reports whether the named file or directory exists.
|
||||
func fileExists(name string) bool {
|
||||
if _, err := os.Stat(name); err != nil {
|
||||
if os.IsNotExist(err) {
|
||||
return false
|
||||
}
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
// openDB opens the database at the provided path. walletdb.ErrDbDoesNotExist
|
||||
// is returned if the database doesn't exist and the create flag is not set.
|
||||
func openDB(dbPath string, create bool) (walletdb.DB, error) {
|
||||
if !create && !fileExists(dbPath) {
|
||||
return nil, walletdb.ErrDbDoesNotExist
|
||||
}
|
||||
|
||||
// Specify bbolt freelist options to reduce heap pressure in case the
|
||||
// freelist grows to be very large.
|
||||
options := &bbolt.Options{
|
||||
NoFreelistSync: true,
|
||||
FreelistType: bbolt.FreelistMapType,
|
||||
}
|
||||
|
||||
boltDB, err := bbolt.Open(dbPath, 0600, options)
|
||||
return (*db)(boltDB), convertErr(err)
|
||||
}
|
||||
25
vendor/github.com/btcsuite/btcwallet/walletdb/bdb/doc.go
generated
vendored
Normal file
25
vendor/github.com/btcsuite/btcwallet/walletdb/bdb/doc.go
generated
vendored
Normal file
@@ -0,0 +1,25 @@
|
||||
// Copyright (c) 2014 The btcsuite developers
|
||||
// Use of this source code is governed by an ISC
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
/*
|
||||
Package bdb implements an instance of walletdb that uses boltdb for the backing
|
||||
datastore.
|
||||
|
||||
Usage
|
||||
|
||||
This package is only a driver to the walletdb package and provides the database
|
||||
type of "bdb". The only parameter the Open and Create functions take is the
|
||||
database path as a string:
|
||||
|
||||
db, err := walletdb.Open("bdb", "path/to/database.db")
|
||||
if err != nil {
|
||||
// Handle error
|
||||
}
|
||||
|
||||
db, err := walletdb.Create("bdb", "path/to/database.db")
|
||||
if err != nil {
|
||||
// Handle error
|
||||
}
|
||||
*/
|
||||
package bdb
|
||||
66
vendor/github.com/btcsuite/btcwallet/walletdb/bdb/driver.go
generated
vendored
Normal file
66
vendor/github.com/btcsuite/btcwallet/walletdb/bdb/driver.go
generated
vendored
Normal file
@@ -0,0 +1,66 @@
|
||||
// Copyright (c) 2014 The btcsuite developers
|
||||
// Use of this source code is governed by an ISC
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package bdb
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"github.com/btcsuite/btcwallet/walletdb"
|
||||
)
|
||||
|
||||
const (
|
||||
dbType = "bdb"
|
||||
)
|
||||
|
||||
// parseArgs parses the arguments from the walletdb Open/Create methods.
|
||||
func parseArgs(funcName string, args ...interface{}) (string, error) {
|
||||
if len(args) != 1 {
|
||||
return "", fmt.Errorf("invalid arguments to %s.%s -- "+
|
||||
"expected database path", dbType, funcName)
|
||||
}
|
||||
|
||||
dbPath, ok := args[0].(string)
|
||||
if !ok {
|
||||
return "", fmt.Errorf("first argument to %s.%s is invalid -- "+
|
||||
"expected database path string", dbType, funcName)
|
||||
}
|
||||
|
||||
return dbPath, nil
|
||||
}
|
||||
|
||||
// openDBDriver is the callback provided during driver registration that opens
|
||||
// an existing database for use.
|
||||
func openDBDriver(args ...interface{}) (walletdb.DB, error) {
|
||||
dbPath, err := parseArgs("Open", args...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return openDB(dbPath, false)
|
||||
}
|
||||
|
||||
// createDBDriver is the callback provided during driver registration that
|
||||
// creates, initializes, and opens a database for use.
|
||||
func createDBDriver(args ...interface{}) (walletdb.DB, error) {
|
||||
dbPath, err := parseArgs("Create", args...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return openDB(dbPath, true)
|
||||
}
|
||||
|
||||
func init() {
|
||||
// Register the driver.
|
||||
driver := walletdb.Driver{
|
||||
DbType: dbType,
|
||||
Create: createDBDriver,
|
||||
Open: openDBDriver,
|
||||
}
|
||||
if err := walletdb.RegisterDriver(driver); err != nil {
|
||||
panic(fmt.Sprintf("Failed to regiser database driver '%s': %v",
|
||||
dbType, err))
|
||||
}
|
||||
}
|
||||
7
vendor/github.com/btcsuite/btcwallet/walletdb/cov_report.sh
generated
vendored
Normal file
7
vendor/github.com/btcsuite/btcwallet/walletdb/cov_report.sh
generated
vendored
Normal file
@@ -0,0 +1,7 @@
|
||||
#!/bin/sh
|
||||
|
||||
# This script uses go tool cover to generate a test coverage report.
|
||||
go test -coverprofile=cov.out && go tool cover -func=cov.out && rm -f cov.out
|
||||
echo "============================================================"
|
||||
(cd bdb && go test -coverprofile=cov.out && go tool cover -func=cov.out && \
|
||||
rm -f cov.out)
|
||||
103
vendor/github.com/btcsuite/btcwallet/walletdb/doc.go
generated
vendored
Normal file
103
vendor/github.com/btcsuite/btcwallet/walletdb/doc.go
generated
vendored
Normal file
@@ -0,0 +1,103 @@
|
||||
// Copyright (c) 2014 The btcsuite developers
|
||||
// Use of this source code is governed by an ISC
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
/*
|
||||
Package walletdb provides a namespaced database interface for btcwallet.
|
||||
|
||||
Overview
|
||||
|
||||
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 pluggable driver, 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 quick overview of the features walletdb provides are as follows:
|
||||
|
||||
- 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
|
||||
|
||||
Database
|
||||
|
||||
The main entry point is the DB interface. It exposes functionality for
|
||||
creating, retrieving, and removing namespaces. It is obtained via the Create
|
||||
and Open functions which take a database type string that identifies the
|
||||
specific database driver (backend) to use as well as arguments specific to the
|
||||
specified driver.
|
||||
|
||||
Namespaces
|
||||
|
||||
The Namespace interface is an abstraction that provides facilities for obtaining
|
||||
transactions (the Tx interface) that are the basis of all database reads and
|
||||
writes. Unlike some database interfaces that support reading and writing
|
||||
without transactions, this interface requires transactions even when only
|
||||
reading or writing a single key.
|
||||
|
||||
The Begin function provides an unmanaged transaction while the View and Update
|
||||
functions provide a managed transaction. These are described in more detail
|
||||
below.
|
||||
|
||||
Transactions
|
||||
|
||||
The Tx interface provides facilities for rolling back or commiting changes that
|
||||
took place while the transaction was active. It also provides the root bucket
|
||||
under which all keys, values, and nested buckets are stored. A transaction
|
||||
can either be read-only or read-write and managed or unmanaged.
|
||||
|
||||
Managed versus Unmanaged Transactions
|
||||
|
||||
A managed transaction is one where the caller provides a function to execute
|
||||
within the context of the transaction and the commit or rollback is handled
|
||||
automatically depending on whether or not the provided function returns an
|
||||
error. Attempting to manually call Rollback or Commit on the managed
|
||||
transaction will result in a panic.
|
||||
|
||||
An unmanaged transaction, on the other hand, requires the caller to manually
|
||||
call Commit or Rollback when they are finished with it. Leaving transactions
|
||||
open for long periods of time can have several adverse effects, so it is
|
||||
recommended that managed transactions are used instead.
|
||||
|
||||
Buckets
|
||||
|
||||
The Bucket interface provides the ability to manipulate key/value pairs and
|
||||
nested buckets as well as iterate through them.
|
||||
|
||||
The Get, Put, and Delete functions work with key/value pairs, while the Bucket,
|
||||
CreateBucket, CreateBucketIfNotExists, and DeleteBucket functions work with
|
||||
buckets. The ForEach function allows the caller to provide a function to be
|
||||
called with each key/value pair and nested bucket in the current bucket.
|
||||
|
||||
Root Bucket
|
||||
|
||||
As discussed above, all of the functions which are used to manipulate key/value
|
||||
pairs and nested buckets exist on the Bucket interface. The root bucket is the
|
||||
upper-most bucket in a namespace under which data is stored and is created at
|
||||
the same time as the namespace. Use the RootBucket function on the Tx interface
|
||||
to retrieve it.
|
||||
|
||||
Nested Buckets
|
||||
|
||||
The CreateBucket and CreateBucketIfNotExists functions on the Bucket interface
|
||||
provide the ability to create an arbitrary number of nested buckets. It is
|
||||
a good idea to avoid a lot of buckets with little data in them as it could lead
|
||||
to poor page utilization depending on the specific driver in use.
|
||||
*/
|
||||
package walletdb
|
||||
80
vendor/github.com/btcsuite/btcwallet/walletdb/error.go
generated
vendored
Normal file
80
vendor/github.com/btcsuite/btcwallet/walletdb/error.go
generated
vendored
Normal file
@@ -0,0 +1,80 @@
|
||||
// Copyright (c) 2014 The btcsuite developers
|
||||
// Use of this source code is governed by an ISC
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package walletdb
|
||||
|
||||
import (
|
||||
"errors"
|
||||
)
|
||||
|
||||
// Errors that can occur during driver registration.
|
||||
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 the various database functions may return.
|
||||
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 can occur when beginning or committing a transaction.
|
||||
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 putting or deleting a value or bucket.
|
||||
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")
|
||||
)
|
||||
11
vendor/github.com/btcsuite/btcwallet/walletdb/go.mod
generated
vendored
Normal file
11
vendor/github.com/btcsuite/btcwallet/walletdb/go.mod
generated
vendored
Normal file
@@ -0,0 +1,11 @@
|
||||
module github.com/btcsuite/btcwallet/walletdb
|
||||
|
||||
go 1.12
|
||||
|
||||
require (
|
||||
github.com/btcsuite/btclog v0.0.0-20170628155309-84c8d2346e9f
|
||||
github.com/coreos/bbolt v1.3.3
|
||||
github.com/davecgh/go-spew v1.1.1
|
||||
go.etcd.io/bbolt v1.3.3 // indirect
|
||||
golang.org/x/sys v0.0.0-20190904154756-749cb33beabd // indirect
|
||||
)
|
||||
10
vendor/github.com/btcsuite/btcwallet/walletdb/go.sum
generated
vendored
Normal file
10
vendor/github.com/btcsuite/btcwallet/walletdb/go.sum
generated
vendored
Normal file
@@ -0,0 +1,10 @@
|
||||
github.com/btcsuite/btclog v0.0.0-20170628155309-84c8d2346e9f h1:bAs4lUbRJpnnkd9VhRV3jjAVU7DJVjMaK+IsvSeZvFo=
|
||||
github.com/btcsuite/btclog v0.0.0-20170628155309-84c8d2346e9f/go.mod h1:TdznJufoqS23FtqVCzL0ZqgP5MqXbb4fg/WgDys70nA=
|
||||
github.com/coreos/bbolt v1.3.3 h1:n6AiVyVRKQFNb6mJlwESEvvLoDyiTzXX7ORAUlkeBdY=
|
||||
github.com/coreos/bbolt v1.3.3/go.mod h1:iRUV2dpdMOn7Bo10OQBFzIJO9kkE559Wcmn+qkEiiKk=
|
||||
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
|
||||
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
go.etcd.io/bbolt v1.3.3 h1:MUGmc65QhB3pIlaQ5bB4LwqSj6GIonVJXpZiaKNyaKk=
|
||||
go.etcd.io/bbolt v1.3.3/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU=
|
||||
golang.org/x/sys v0.0.0-20190904154756-749cb33beabd h1:DBH9mDw0zluJT/R+nGuV3jWFWLFaHyYZWD4tOT+cjn0=
|
||||
golang.org/x/sys v0.0.0-20190904154756-749cb33beabd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
304
vendor/github.com/btcsuite/btcwallet/walletdb/interface.go
generated
vendored
Normal file
304
vendor/github.com/btcsuite/btcwallet/walletdb/interface.go
generated
vendored
Normal file
@@ -0,0 +1,304 @@
|
||||
// Copyright (c) 2014 The btcsuite developers
|
||||
// Use of this source code is governed by an ISC
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
// This interface was inspired heavily by the excellent boltdb project at
|
||||
// https://github.com/boltdb/bolt by Ben B. Johnson.
|
||||
|
||||
package walletdb
|
||||
|
||||
import "io"
|
||||
|
||||
// ReadTx represents a database transaction that can only be used for reads. If
|
||||
// a database update must occur, use a ReadWriteTx.
|
||||
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
|
||||
}
|
||||
|
||||
// ReadWriteTx represents a database transaction that can be used for both reads
|
||||
// and writes. When only reads are necessary, consider using a ReadTx instead.
|
||||
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())
|
||||
}
|
||||
|
||||
// ReadBucket represents a bucket (a hierarchical structure within the database)
|
||||
// that is only allowed to perform read operations.
|
||||
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
|
||||
}
|
||||
|
||||
// ReadWriteBucket represents a bucket (a hierarchical structure within the
|
||||
// database) that is allowed to perform both read and write operations.
|
||||
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
|
||||
|
||||
// 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
|
||||
}
|
||||
|
||||
// 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 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)
|
||||
}
|
||||
|
||||
// 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 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
|
||||
}
|
||||
|
||||
// BucketIsEmpty returns whether the bucket is empty, that is, whether there are
|
||||
// no key/value pairs or nested buckets.
|
||||
func BucketIsEmpty(bucket ReadBucket) bool {
|
||||
k, v := bucket.ReadCursor().First()
|
||||
return k == nil && v == nil
|
||||
}
|
||||
|
||||
// DB represents an ACID database. All database access is performed through
|
||||
// read or read+write transactions.
|
||||
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
|
||||
}
|
||||
|
||||
// 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).
|
||||
func View(db DB, f func(tx ReadTx) error) error {
|
||||
tx, err := db.BeginReadTx()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
err = f(tx)
|
||||
rollbackErr := tx.Rollback()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if rollbackErr != nil {
|
||||
return rollbackErr
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// 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 Update(db DB, f func(tx ReadWriteTx) error) error {
|
||||
tx, err := db.BeginReadWriteTx()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
err = f(tx)
|
||||
if err != nil {
|
||||
// Want to return the original error, not a rollback error if
|
||||
// any occur.
|
||||
_ = tx.Rollback()
|
||||
return err
|
||||
}
|
||||
return tx.Commit()
|
||||
}
|
||||
|
||||
// Driver defines a structure for backend drivers to use when they registered
|
||||
// themselves as a backend which implements the Db interface.
|
||||
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)
|
||||
}
|
||||
|
||||
// driverList holds all of the registered database backends.
|
||||
var drivers = make(map[string]*Driver)
|
||||
|
||||
// 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 RegisterDriver(driver Driver) error {
|
||||
if _, exists := drivers[driver.DbType]; exists {
|
||||
return ErrDbTypeRegistered
|
||||
}
|
||||
|
||||
drivers[driver.DbType] = &driver
|
||||
return nil
|
||||
}
|
||||
|
||||
// SupportedDrivers returns a slice of strings that represent the database
|
||||
// drivers that have been registered and are therefore supported.
|
||||
func SupportedDrivers() []string {
|
||||
supportedDBs := make([]string, 0, len(drivers))
|
||||
for _, drv := range drivers {
|
||||
supportedDBs = append(supportedDBs, drv.DbType)
|
||||
}
|
||||
return supportedDBs
|
||||
}
|
||||
|
||||
// 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 Create(dbType string, args ...interface{}) (DB, error) {
|
||||
drv, exists := drivers[dbType]
|
||||
if !exists {
|
||||
return nil, ErrDbUnknownType
|
||||
}
|
||||
|
||||
return drv.Create(args...)
|
||||
}
|
||||
|
||||
// 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.
|
||||
func Open(dbType string, args ...interface{}) (DB, error) {
|
||||
drv, exists := drivers[dbType]
|
||||
if !exists {
|
||||
return nil, ErrDbUnknownType
|
||||
}
|
||||
|
||||
return drv.Open(args...)
|
||||
}
|
||||
43
vendor/github.com/btcsuite/btcwallet/walletdb/migration/log.go
generated
vendored
Normal file
43
vendor/github.com/btcsuite/btcwallet/walletdb/migration/log.go
generated
vendored
Normal file
@@ -0,0 +1,43 @@
|
||||
package migration
|
||||
|
||||
import "github.com/btcsuite/btclog"
|
||||
|
||||
// log is a logger that is initialized with no output filters. This
|
||||
// means the package will not perform any logging by default until the caller
|
||||
// requests it.
|
||||
var log btclog.Logger
|
||||
|
||||
// The default amount of logging is none.
|
||||
func init() {
|
||||
DisableLog()
|
||||
}
|
||||
|
||||
// DisableLog disables all library log output. Logging output is disabled
|
||||
// by default until either UseLogger or SetLogWriter are called.
|
||||
func DisableLog() {
|
||||
UseLogger(btclog.Disabled)
|
||||
}
|
||||
|
||||
// UseLogger uses a specified Logger to output package logging info.
|
||||
// This should be used in preference to SetLogWriter if the caller is also
|
||||
// using btclog.
|
||||
func UseLogger(logger btclog.Logger) {
|
||||
log = logger
|
||||
}
|
||||
|
||||
// LogClosure is a closure that can be printed with %v to be used to
|
||||
// generate expensive-to-create data for a detailed log level and avoid doing
|
||||
// the work if the data isn't printed.
|
||||
type logClosure func() string
|
||||
|
||||
// String invokes the log closure and returns the results string.
|
||||
func (c logClosure) String() string {
|
||||
return c()
|
||||
}
|
||||
|
||||
// newLogClosure returns a new closure over the passed function which allows
|
||||
// it to be used as a parameter in a logging function that is only invoked when
|
||||
// the logging level is such that the message will actually be logged.
|
||||
func newLogClosure(c func() string) logClosure {
|
||||
return logClosure(c)
|
||||
}
|
||||
162
vendor/github.com/btcsuite/btcwallet/walletdb/migration/manager.go
generated
vendored
Normal file
162
vendor/github.com/btcsuite/btcwallet/walletdb/migration/manager.go
generated
vendored
Normal file
@@ -0,0 +1,162 @@
|
||||
package migration
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"sort"
|
||||
|
||||
"github.com/btcsuite/btcwallet/walletdb"
|
||||
)
|
||||
|
||||
var (
|
||||
// ErrReversion is an error returned when an attempt to revert to a
|
||||
// previous version is detected. This is done to provide safety to users
|
||||
// as some upgrades may not be backwards-compatible.
|
||||
ErrReversion = errors.New("reverting to a previous version is not " +
|
||||
"supported")
|
||||
)
|
||||
|
||||
// Version denotes the version number of the database. A migration can be used
|
||||
// to bring a previous version of the database to a later one.
|
||||
type Version struct {
|
||||
// Number represents the number of this version.
|
||||
Number uint32
|
||||
|
||||
// Migration represents a migration function that modifies the database
|
||||
// state. Care must be taken so that consequent migrations build off of
|
||||
// the previous one in order to ensure the consistency of the database.
|
||||
Migration func(walletdb.ReadWriteBucket) error
|
||||
}
|
||||
|
||||
// Manager is an interface that exposes the necessary methods needed in order to
|
||||
// migrate/upgrade a service. Each service (i.e., an implementation of this
|
||||
// interface) can then use the Upgrade function to perform any required database
|
||||
// migrations.
|
||||
type Manager interface {
|
||||
// Name returns the name of the service we'll be attempting to upgrade.
|
||||
Name() string
|
||||
|
||||
// Namespace returns the top-level bucket of the service.
|
||||
Namespace() walletdb.ReadWriteBucket
|
||||
|
||||
// CurrentVersion returns the current version of the service's database.
|
||||
CurrentVersion(walletdb.ReadBucket) (uint32, error)
|
||||
|
||||
// SetVersion sets the version of the service's database.
|
||||
SetVersion(walletdb.ReadWriteBucket, uint32) error
|
||||
|
||||
// Versions returns all of the available database versions of the
|
||||
// service.
|
||||
Versions() []Version
|
||||
}
|
||||
|
||||
// GetLatestVersion returns the latest version available from the given slice.
|
||||
func GetLatestVersion(versions []Version) uint32 {
|
||||
if len(versions) == 0 {
|
||||
return 0
|
||||
}
|
||||
|
||||
// Before determining the latest version number, we'll sort the slice to
|
||||
// ensure it reflects the last element.
|
||||
sort.Slice(versions, func(i, j int) bool {
|
||||
return versions[i].Number < versions[j].Number
|
||||
})
|
||||
|
||||
return versions[len(versions)-1].Number
|
||||
}
|
||||
|
||||
// VersionsToApply determines which versions should be applied as migrations
|
||||
// based on the current version.
|
||||
func VersionsToApply(currentVersion uint32, versions []Version) []Version {
|
||||
// Assuming the migration versions are in increasing order, we'll apply
|
||||
// any migrations that have a version number lower than our current one.
|
||||
var upgradeVersions []Version
|
||||
for _, version := range versions {
|
||||
if version.Number > currentVersion {
|
||||
upgradeVersions = append(upgradeVersions, version)
|
||||
}
|
||||
}
|
||||
|
||||
// Before returning, we'll sort the slice by its version number to
|
||||
// ensure the migrations are applied in their intended order.
|
||||
sort.Slice(upgradeVersions, func(i, j int) bool {
|
||||
return upgradeVersions[i].Number < upgradeVersions[j].Number
|
||||
})
|
||||
|
||||
return upgradeVersions
|
||||
}
|
||||
|
||||
// Upgrade attempts to upgrade a group of services exposed through the Manager
|
||||
// interface. Each service will go through its available versions and determine
|
||||
// whether it needs to apply any.
|
||||
//
|
||||
// NOTE: In order to guarantee fault-tolerance, each service upgrade should
|
||||
// happen within the same database transaction.
|
||||
func Upgrade(mgrs ...Manager) error {
|
||||
for _, mgr := range mgrs {
|
||||
if err := upgrade(mgr); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// upgrade attempts to upgrade a service expose through its implementation of
|
||||
// the Manager interface. This function will determine whether any new versions
|
||||
// need to be applied based on the service's current version and latest
|
||||
// available one.
|
||||
func upgrade(mgr Manager) error {
|
||||
// We'll start by fetching the service's current and latest version.
|
||||
ns := mgr.Namespace()
|
||||
currentVersion, err := mgr.CurrentVersion(ns)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
versions := mgr.Versions()
|
||||
latestVersion := GetLatestVersion(versions)
|
||||
|
||||
switch {
|
||||
// If the current version is greater than the latest, then the service
|
||||
// is attempting to revert to a previous version that's possibly
|
||||
// backwards-incompatible. To prevent this, we'll return an error
|
||||
// indicating so.
|
||||
case currentVersion > latestVersion:
|
||||
return ErrReversion
|
||||
|
||||
// If the current version is behind the latest version, we'll need to
|
||||
// apply all of the newer versions in order to catch up to the latest.
|
||||
case currentVersion < latestVersion:
|
||||
versions := VersionsToApply(currentVersion, versions)
|
||||
mgrName := mgr.Name()
|
||||
ns := mgr.Namespace()
|
||||
|
||||
for _, version := range versions {
|
||||
log.Infof("Applying %v migration #%d", mgrName,
|
||||
version.Number)
|
||||
|
||||
// We'll only run a migration if there is one available
|
||||
// for this version.
|
||||
if version.Migration != nil {
|
||||
err := version.Migration(ns)
|
||||
if err != nil {
|
||||
log.Errorf("Unable to apply %v "+
|
||||
"migration #%d: %v", mgrName,
|
||||
version.Number, err)
|
||||
return err
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// With all of the versions applied, we can now reflect the
|
||||
// latest version upon the service.
|
||||
if err := mgr.SetVersion(ns, latestVersion); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// If the current version matches the latest one, there's no upgrade
|
||||
// needed and we can safely exit.
|
||||
case currentVersion == latestVersion:
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
39
vendor/github.com/btcsuite/btcwallet/walletdb/test_coverage.txt
generated
vendored
Normal file
39
vendor/github.com/btcsuite/btcwallet/walletdb/test_coverage.txt
generated
vendored
Normal file
@@ -0,0 +1,39 @@
|
||||
PASS
|
||||
coverage: 100.0% of statements
|
||||
ok github.com/conformal/btcwallet/walletdb 0.130s
|
||||
github.com\conformal\btcwallet\walletdb\interface.go:190: RegisterDriver 100.0%
|
||||
github.com\conformal\btcwallet\walletdb\interface.go:201: SupportedDrivers 100.0%
|
||||
github.com\conformal\btcwallet\walletdb\interface.go:214: Create 100.0%
|
||||
github.com\conformal\btcwallet\walletdb\interface.go:228: Open 100.0%
|
||||
total: (statements) 100.0%
|
||||
============================================================
|
||||
PASS
|
||||
coverage: 91.7% of statements
|
||||
ok github.com/conformal/btcwallet/walletdb/bdb 0.149s
|
||||
github.com\conformal\btcwallet\walletdb\bdb\db.go:28: convertErr 76.9%
|
||||
github.com\conformal\btcwallet\walletdb\bdb\db.go:74: Bucket 100.0%
|
||||
github.com\conformal\btcwallet\walletdb\bdb\db.go:90: CreateBucket 100.0%
|
||||
github.com\conformal\btcwallet\walletdb\bdb\db.go:103: CreateBucketIfNotExists 100.0%
|
||||
github.com\conformal\btcwallet\walletdb\bdb\db.go:116: DeleteBucket 100.0%
|
||||
github.com\conformal\btcwallet\walletdb\bdb\db.go:129: ForEach 100.0%
|
||||
github.com\conformal\btcwallet\walletdb\bdb\db.go:136: Writable 100.0%
|
||||
github.com\conformal\btcwallet\walletdb\bdb\db.go:145: Put 100.0%
|
||||
github.com\conformal\btcwallet\walletdb\bdb\db.go:157: Get 100.0%
|
||||
github.com\conformal\btcwallet\walletdb\bdb\db.go:166: Delete 100.0%
|
||||
github.com\conformal\btcwallet\walletdb\bdb\db.go:185: RootBucket 100.0%
|
||||
github.com\conformal\btcwallet\walletdb\bdb\db.go:193: Commit 100.0%
|
||||
github.com\conformal\btcwallet\walletdb\bdb\db.go:201: Rollback 100.0%
|
||||
github.com\conformal\btcwallet\walletdb\bdb\db.go:227: Begin 85.7%
|
||||
github.com\conformal\btcwallet\walletdb\bdb\db.go:249: View 100.0%
|
||||
github.com\conformal\btcwallet\walletdb\bdb\db.go:270: Update 100.0%
|
||||
github.com\conformal\btcwallet\walletdb\bdb\db.go:294: Namespace 93.3%
|
||||
github.com\conformal\btcwallet\walletdb\bdb\db.go:329: DeleteNamespace 100.0%
|
||||
github.com\conformal\btcwallet\walletdb\bdb\db.go:339: WriteTo 0.0%
|
||||
github.com\conformal\btcwallet\walletdb\bdb\db.go:348: Close 100.0%
|
||||
github.com\conformal\btcwallet\walletdb\bdb\db.go:353: fileExists 100.0%
|
||||
github.com\conformal\btcwallet\walletdb\bdb\db.go:364: openDB 100.0%
|
||||
github.com\conformal\btcwallet\walletdb\bdb\driver.go:34: parseArgs 100.0%
|
||||
github.com\conformal\btcwallet\walletdb\bdb\driver.go:50: openDBDriver 100.0%
|
||||
github.com\conformal\btcwallet\walletdb\bdb\driver.go:60: createDBDriver 100.0%
|
||||
github.com\conformal\btcwallet\walletdb\bdb\driver.go:69: init 66.7%
|
||||
total: (statements) 91.7%
|
||||
Reference in New Issue
Block a user