[NOD-885] Use database.Key and database.Bucket instead of byte slices (#692)

* [NOD-885] Create database.Key type

* [NOD-885] Rename FullKey()->FullKeyBytes() and Key()->KeyBytes()

* [NOD-885] Make Key.String return a hex string

* [NOD-885] Rename key parts

* [NOD-885] Rename separator->bucketSeparator

* [NOD-885] Rename SuffixBytes->Suffix and PrefixBytes->Prefix

* [NOD-885] Change comments

* [NOD-885] Change key prefix to bucket

* [NOD-885] Don't use database.NewKey inside dbaccess

* [NOD-885] Fix nil bug in Bucket.Path()

* [NOD-885] Rename helpers.go -> keys.go

* [NOD-885] Unexport database.NewKey

* [NOD-885] Remove redundant code in Bucket.Path()
This commit is contained in:
Ori Newman 2020-04-08 12:12:21 +03:00 committed by GitHub
parent df934990d7
commit 7609c50641
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
26 changed files with 174 additions and 127 deletions

View File

@ -324,7 +324,7 @@ func (dag *BlockDAG) initUTXOSet() (fullUTXOCollection utxoCollection, err error
if err != nil {
return nil, err
}
outpoint, err := deserializeOutpoint(bytes.NewReader(key))
outpoint, err := deserializeOutpoint(bytes.NewReader(key.Suffix()))
if err != nil {
return nil, err
}
@ -639,7 +639,7 @@ func (dag *BlockDAG) BlockHashesFrom(lowHash *daghash.Hash, limit int) ([]*dagha
if err != nil {
return nil, err
}
blockHash, err := blockHashFromBlockIndexKey(key)
blockHash, err := blockHashFromBlockIndexKey(key.Suffix())
if err != nil {
return nil, err
}

View File

@ -96,7 +96,7 @@ func (store *multisetStore) init(dbContext dbaccess.Context) error {
return err
}
hash, err := daghash.NewHash(key)
hash, err := daghash.NewHash(key.Suffix())
if err != nil {
return err
}

View File

@ -137,7 +137,7 @@ func (store *reachabilityStore) initReachabilityData(cursor database.Cursor) err
return err
}
hash, err := daghash.NewHash(key)
hash, err := daghash.NewHash(key.Suffix())
if err != nil {
return err
}
@ -155,7 +155,7 @@ func (store *reachabilityStore) loadReachabilityDataFromCursor(cursor database.C
return err
}
hash, err := daghash.NewHash(key)
hash, err := daghash.NewHash(key.Suffix())
if err != nil {
return err
}

View File

@ -1,51 +0,0 @@
package database
import "bytes"
var separator = []byte("/")
// Bucket is a helper type meant to combine buckets,
// sub-buckets, and keys into a single full key-value
// database key.
type Bucket struct {
path [][]byte
}
// MakeBucket creates a new Bucket using the given path
// of buckets.
func MakeBucket(path ...[]byte) *Bucket {
return &Bucket{path: path}
}
// Bucket returns the sub-bucket of the current bucket
// defined by bucketBytes.
func (b *Bucket) Bucket(bucketBytes []byte) *Bucket {
newPath := make([][]byte, len(b.path)+1)
copy(newPath, b.path)
copy(newPath[len(b.path):], [][]byte{bucketBytes})
return MakeBucket(newPath...)
}
// Key returns the key inside of the current bucket.
func (b *Bucket) Key(key []byte) []byte {
bucketPath := b.Path()
fullKeyLength := len(bucketPath) + len(key)
fullKey := make([]byte, fullKeyLength)
copy(fullKey, bucketPath)
copy(fullKey[len(bucketPath):], key)
return fullKey
}
// Path returns the full path of the current bucket.
func (b *Bucket) Path() []byte {
bucketPath := bytes.Join(b.path, separator)
bucketPathWithFinalSeparator := make([]byte, len(bucketPath)+len(separator))
copy(bucketPathWithFinalSeparator, bucketPath)
copy(bucketPathWithFinalSeparator[len(bucketPath):], separator)
return bucketPathWithFinalSeparator
}

View File

@ -13,13 +13,13 @@ type Cursor interface {
// Seek moves the iterator to the first key/value pair whose key is greater
// than or equal to the given key. It returns ErrNotFound if such pair does not
// exist.
Seek(key []byte) error
Seek(key *Key) error
// Key returns the key of the current key/value pair, or ErrNotFound if done.
// Note that the key is trimmed to not include the prefix the cursor was opened
// with. The caller should not modify the contents of the returned slice, and
// its contents may change on the next call to Next.
Key() ([]byte, error)
Key() (*Key, error)
// Value returns the value of the current key/value pair, or ErrNotFound if done.
// The caller should not modify the contents of the returned slice, and its

View File

@ -5,19 +5,19 @@ package database
type DataAccessor interface {
// Put sets the value for the given key. It overwrites
// any previous value for that key.
Put(key []byte, value []byte) error
Put(key *Key, value []byte) error
// Get gets the value for the given key. It returns
// ErrNotFound if the given key does not exist.
Get(key []byte) ([]byte, error)
Get(key *Key) ([]byte, error)
// Has returns true if the database does contains the
// given key.
Has(key []byte) (bool, error)
Has(key *Key) (bool, error)
// Delete deletes the value for the given key. Will not
// return an error if the key doesn't exist.
Delete(key []byte) error
Delete(key *Key) error
// AppendToStore appends the given data to the store
// defined by storeName. This function returns a serialized
@ -32,5 +32,5 @@ type DataAccessor interface {
RetrieveFromStore(storeName string, location []byte) ([]byte, error)
// Cursor begins a new cursor over the given bucket.
Cursor(bucket []byte) (Cursor, error)
Cursor(bucket *Bucket) (Cursor, error)
}

View File

@ -59,28 +59,28 @@ func (db *ffldb) Close() error {
// Put sets the value for the given key. It overwrites
// any previous value for that key.
// This method is part of the DataAccessor interface.
func (db *ffldb) Put(key []byte, value []byte) error {
func (db *ffldb) Put(key *database.Key, value []byte) error {
return db.levelDB.Put(key, value)
}
// Get gets the value for the given key. It returns
// ErrNotFound if the given key does not exist.
// This method is part of the DataAccessor interface.
func (db *ffldb) Get(key []byte) ([]byte, error) {
func (db *ffldb) Get(key *database.Key) ([]byte, error) {
return db.levelDB.Get(key)
}
// Has returns true if the database does contains the
// given key.
// This method is part of the DataAccessor interface.
func (db *ffldb) Has(key []byte) (bool, error) {
func (db *ffldb) Has(key *database.Key) (bool, error) {
return db.levelDB.Has(key)
}
// Delete deletes the value for the given key. Will not
// return an error if the key doesn't exist.
// This method is part of the DataAccessor interface.
func (db *ffldb) Delete(key []byte) error {
func (db *ffldb) Delete(key *database.Key) error {
return db.levelDB.Delete(key)
}
@ -155,8 +155,8 @@ func (db *ffldb) RetrieveFromStore(storeName string, location []byte) ([]byte, e
// Cursor begins a new cursor over the given bucket.
// This method is part of the DataAccessor interface.
func (db *ffldb) Cursor(bucket []byte) (database.Cursor, error) {
ldbCursor := db.levelDB.Cursor(bucket)
func (db *ffldb) Cursor(bucket *database.Bucket) (database.Cursor, error) {
ldbCursor := db.levelDB.Cursor(bucket.Path())
return ldbCursor, nil
}

View File

@ -33,7 +33,7 @@ func (db *ffldb) flatFiles() (map[string][]byte, error) {
if err != nil {
return nil, err
}
storeName := string(storeNameKey)
storeName := string(storeNameKey.Suffix())
currentLocation, err := flatFilesCursor.Value()
if err != nil {

View File

@ -2,7 +2,6 @@ package ldb
import (
"bytes"
"encoding/hex"
"github.com/kaspanet/kaspad/database"
"github.com/pkg/errors"
"github.com/syndtr/goleveldb/leveldb/iterator"
@ -48,14 +47,14 @@ func (c *LevelDBCursor) First() bool {
// Seek moves the iterator to the first key/value pair whose key is greater
// than or equal to the given key. It returns ErrNotFound if such pair does not
// exist.
func (c *LevelDBCursor) Seek(key []byte) error {
func (c *LevelDBCursor) Seek(key *database.Key) error {
if c.isClosed {
return errors.New("cannot seek a closed cursor")
}
notFoundErr := errors.Wrapf(database.ErrNotFound, "key %s not "+
"found", hex.EncodeToString(key))
found := c.ldbIterator.Seek(key)
"found", key)
found := c.ldbIterator.Seek(key.Bytes())
if !found {
return notFoundErr
}
@ -65,7 +64,7 @@ func (c *LevelDBCursor) Seek(key []byte) error {
if currentKey == nil {
return notFoundErr
}
if !bytes.Equal(currentKey, key) {
if !bytes.Equal(currentKey, key.Bytes()) {
return notFoundErr
}
@ -76,7 +75,7 @@ func (c *LevelDBCursor) Seek(key []byte) error {
// Note that the key is trimmed to not include the prefix the cursor was opened
// with. The caller should not modify the contents of the returned slice, and
// its contents may change on the next call to Next.
func (c *LevelDBCursor) Key() ([]byte, error) {
func (c *LevelDBCursor) Key() (*database.Key, error) {
if c.isClosed {
return nil, errors.New("cannot get the key of a closed cursor")
}
@ -85,8 +84,8 @@ func (c *LevelDBCursor) Key() ([]byte, error) {
return nil, errors.Wrapf(database.ErrNotFound, "cannot get the "+
"key of a done cursor")
}
key := bytes.TrimPrefix(fullKeyPath, c.prefix)
return key, nil
suffix := bytes.TrimPrefix(fullKeyPath, c.prefix)
return database.MakeBucket(c.prefix).Key(suffix), nil
}
// Value returns the value of the current key/value pair, or ErrNotFound if done.

View File

@ -1,7 +1,6 @@
package ldb
import (
"encoding/hex"
"github.com/kaspanet/kaspad/database"
"github.com/pkg/errors"
"github.com/syndtr/goleveldb/leveldb"
@ -52,19 +51,19 @@ func (db *LevelDB) Close() error {
// Put sets the value for the given key. It overwrites
// any previous value for that key.
func (db *LevelDB) Put(key []byte, value []byte) error {
err := db.ldb.Put(key, value, nil)
func (db *LevelDB) Put(key *database.Key, value []byte) error {
err := db.ldb.Put(key.Bytes(), value, nil)
return errors.WithStack(err)
}
// Get gets the value for the given key. It returns
// ErrNotFound if the given key does not exist.
func (db *LevelDB) Get(key []byte) ([]byte, error) {
data, err := db.ldb.Get(key, nil)
func (db *LevelDB) Get(key *database.Key) ([]byte, error) {
data, err := db.ldb.Get(key.Bytes(), nil)
if err != nil {
if errors.Is(err, leveldb.ErrNotFound) {
return nil, errors.Wrapf(database.ErrNotFound,
"key %s not found", hex.EncodeToString(key))
"key %s not found", key)
}
return nil, errors.WithStack(err)
}
@ -73,8 +72,8 @@ func (db *LevelDB) Get(key []byte) ([]byte, error) {
// Has returns true if the database does contains the
// given key.
func (db *LevelDB) Has(key []byte) (bool, error) {
exists, err := db.ldb.Has(key, nil)
func (db *LevelDB) Has(key *database.Key) (bool, error) {
exists, err := db.ldb.Has(key.Bytes(), nil)
if err != nil {
return false, errors.WithStack(err)
}
@ -83,7 +82,7 @@ func (db *LevelDB) Has(key []byte) (bool, error) {
// Delete deletes the value for the given key. Will not
// return an error if the key doesn't exist.
func (db *LevelDB) Delete(key []byte) error {
err := db.ldb.Delete(key, nil)
func (db *LevelDB) Delete(key *database.Key) error {
err := db.ldb.Delete(key.Bytes(), nil)
return errors.WithStack(err)
}

View File

@ -28,7 +28,7 @@ func TestLevelDBSanity(t *testing.T) {
}()
// Put something into the db
key := []byte("key")
key := database.MakeBucket().Key([]byte("key"))
putData := []byte("Hello world!")
err = ldb.Put(key, putData)
if err != nil {
@ -80,7 +80,7 @@ func TestLevelDBTransactionSanity(t *testing.T) {
}
// Put something into the transaction
key := []byte("key")
key := database.MakeBucket().Key([]byte("key"))
putData := []byte("Hello world!")
err = tx.Put(key, putData)
if err != nil {
@ -124,7 +124,7 @@ func TestLevelDBTransactionSanity(t *testing.T) {
// Case 2. Write directly to the DB and then read from a tx
// Put something into the db
key = []byte("key2")
key = database.MakeBucket().Key([]byte("key2"))
putData = []byte("Goodbye world!")
err = ldb.Put(key, putData)
if err != nil {

View File

@ -1,7 +1,6 @@
package ldb
import (
"encoding/hex"
"github.com/kaspanet/kaspad/database"
"github.com/pkg/errors"
"github.com/syndtr/goleveldb/leveldb"
@ -82,27 +81,27 @@ func (tx *LevelDBTransaction) RollbackUnlessClosed() error {
// Put sets the value for the given key. It overwrites
// any previous value for that key.
func (tx *LevelDBTransaction) Put(key []byte, value []byte) error {
func (tx *LevelDBTransaction) Put(key *database.Key, value []byte) error {
if tx.isClosed {
return errors.New("cannot put into a closed transaction")
}
tx.batch.Put(key, value)
tx.batch.Put(key.Bytes(), value)
return nil
}
// Get gets the value for the given key. It returns
// ErrNotFound if the given key does not exist.
func (tx *LevelDBTransaction) Get(key []byte) ([]byte, error) {
func (tx *LevelDBTransaction) Get(key *database.Key) ([]byte, error) {
if tx.isClosed {
return nil, errors.New("cannot get from a closed transaction")
}
data, err := tx.snapshot.Get(key, nil)
data, err := tx.snapshot.Get(key.Bytes(), nil)
if err != nil {
if errors.Is(err, leveldb.ErrNotFound) {
return nil, errors.Wrapf(database.ErrNotFound,
"key %s not found", hex.EncodeToString(key))
"key %s not found", key)
}
return nil, errors.WithStack(err)
}
@ -111,30 +110,30 @@ func (tx *LevelDBTransaction) Get(key []byte) ([]byte, error) {
// Has returns true if the database does contains the
// given key.
func (tx *LevelDBTransaction) Has(key []byte) (bool, error) {
func (tx *LevelDBTransaction) Has(key *database.Key) (bool, error) {
if tx.isClosed {
return false, errors.New("cannot has from a closed transaction")
}
return tx.snapshot.Has(key, nil)
return tx.snapshot.Has(key.Bytes(), nil)
}
// Delete deletes the value for the given key. Will not
// return an error if the key doesn't exist.
func (tx *LevelDBTransaction) Delete(key []byte) error {
func (tx *LevelDBTransaction) Delete(key *database.Key) error {
if tx.isClosed {
return errors.New("cannot delete from a closed transaction")
}
tx.batch.Delete(key)
tx.batch.Delete(key.Bytes())
return nil
}
// Cursor begins a new cursor over the given bucket.
func (tx *LevelDBTransaction) Cursor(bucket []byte) (*LevelDBCursor, error) {
func (tx *LevelDBTransaction) Cursor(bucket *database.Bucket) (*LevelDBCursor, error) {
if tx.isClosed {
return nil, errors.New("cannot open a cursor from a closed transaction")
}
return tx.db.Cursor(bucket), nil
return tx.db.Cursor(bucket.Path()), nil
}

View File

@ -20,28 +20,28 @@ type transaction struct {
// Put sets the value for the given key. It overwrites
// any previous value for that key.
// This method is part of the DataAccessor interface.
func (tx *transaction) Put(key []byte, value []byte) error {
func (tx *transaction) Put(key *database.Key, value []byte) error {
return tx.ldbTx.Put(key, value)
}
// Get gets the value for the given key. It returns
// ErrNotFound if the given key does not exist.
// This method is part of the DataAccessor interface.
func (tx *transaction) Get(key []byte) ([]byte, error) {
func (tx *transaction) Get(key *database.Key) ([]byte, error) {
return tx.ldbTx.Get(key)
}
// Has returns true if the database does contains the
// given key.
// This method is part of the DataAccessor interface.
func (tx *transaction) Has(key []byte) (bool, error) {
func (tx *transaction) Has(key *database.Key) (bool, error) {
return tx.ldbTx.Has(key)
}
// Delete deletes the value for the given key. Will not
// return an error if the key doesn't exist.
// This method is part of the DataAccessor interface.
func (tx *transaction) Delete(key []byte) error {
func (tx *transaction) Delete(key *database.Key) error {
return tx.ldbTx.Delete(key)
}
@ -66,7 +66,7 @@ func (tx *transaction) RetrieveFromStore(storeName string, location []byte) ([]b
// Cursor begins a new cursor over the given bucket.
// This method is part of the DataAccessor interface.
func (tx *transaction) Cursor(bucket []byte) (database.Cursor, error) {
func (tx *transaction) Cursor(bucket *database.Bucket) (database.Cursor, error) {
return tx.ldbTx.Cursor(bucket)
}

85
database/keys.go Normal file
View File

@ -0,0 +1,85 @@
package database
import (
"bytes"
"encoding/hex"
)
var bucketSeparator = []byte("/")
// Key is a helper type meant to combine prefix
// and suffix into a single database key.
type Key struct {
bucket *Bucket
suffix []byte
}
// Bytes returns the full key bytes that are consisted
// from the bucket path concatenated to the suffix.
func (k *Key) Bytes() []byte {
bucketPath := k.bucket.Path()
keyBytes := make([]byte, len(bucketPath)+len(k.suffix))
copy(keyBytes, bucketPath)
copy(keyBytes[len(bucketPath):], k.suffix)
return keyBytes
}
func (k *Key) String() string {
return hex.EncodeToString(k.Bytes())
}
// Bucket returns the key bucket.
func (k *Key) Bucket() *Bucket {
return k.bucket
}
// Suffix returns the key suffix.
func (k *Key) Suffix() []byte {
return k.suffix
}
// newKey returns a new key composed
// of the given bucket and suffix
func newKey(bucket *Bucket, suffix []byte) *Key {
return &Key{bucket: bucket, suffix: suffix}
}
// Bucket is a helper type meant to combine buckets
// and sub-buckets that can be used to create database
// keys and prefix-based cursors.
type Bucket struct {
path [][]byte
}
// MakeBucket creates a new Bucket using the given path
// of buckets.
func MakeBucket(path ...[]byte) *Bucket {
return &Bucket{path: path}
}
// Bucket returns the sub-bucket of the current bucket
// defined by bucketBytes.
func (b *Bucket) Bucket(bucketBytes []byte) *Bucket {
newPath := make([][]byte, len(b.path)+1)
copy(newPath, b.path)
copy(newPath[len(b.path):], [][]byte{bucketBytes})
return MakeBucket(newPath...)
}
// Key returns a key in the current bucket with the
// given suffix.
func (b *Bucket) Key(suffix []byte) *Key {
return newKey(b, suffix)
}
// Path returns the full path of the current bucket.
func (b *Bucket) Path() []byte {
bucketPath := bytes.Join(b.path, bucketSeparator)
bucketPathWithFinalSeparator := make([]byte, len(bucketPath)+len(bucketSeparator))
copy(bucketPathWithFinalSeparator, bucketPath)
copy(bucketPathWithFinalSeparator[len(bucketPath):], bucketSeparator)
return bucketPathWithFinalSeparator
}

View File

@ -1,6 +1,7 @@
package database
import (
"bytes"
"reflect"
"testing"
)
@ -45,17 +46,26 @@ func TestBucketKey(t *testing.T) {
tests := []struct {
bucketByteSlices [][]byte
key []byte
expectedKey []byte
expectedKeyBytes []byte
expectedKey *Key
}{
{
bucketByteSlices: [][]byte{[]byte("hello")},
key: []byte("test"),
expectedKey: []byte("hello/test"),
expectedKeyBytes: []byte("hello/test"),
expectedKey: &Key{
bucket: MakeBucket([]byte("hello")),
suffix: []byte("test"),
},
},
{
bucketByteSlices: [][]byte{[]byte("hello"), []byte("world")},
key: []byte("test"),
expectedKey: []byte("hello/world/test"),
expectedKeyBytes: []byte("hello/world/test"),
expectedKey: &Key{
bucket: MakeBucket([]byte("hello"), []byte("world")),
suffix: []byte("test"),
},
},
}
@ -63,7 +73,11 @@ func TestBucketKey(t *testing.T) {
resultKey := MakeBucket(test.bucketByteSlices...).Key(test.key)
if !reflect.DeepEqual(resultKey, test.expectedKey) {
t.Errorf("TestBucketKey: got wrong key. Want: %s, got: %s",
string(test.expectedKey), string(resultKey))
test.expectedKeyBytes, resultKey)
}
if !bytes.Equal(resultKey.Bytes(), test.expectedKeyBytes) {
t.Errorf("TestBucketKey: got wrong key bytes. Want: %s, got: %s",
test.expectedKeyBytes, resultKey.Bytes())
}
}
}

View File

@ -10,7 +10,7 @@ var (
acceptanceIndexBucket = database.MakeBucket([]byte("acceptance-index"))
)
func acceptanceIndexKey(hash *daghash.Hash) []byte {
func acceptanceIndexKey(hash *daghash.Hash) *database.Key {
return acceptanceIndexBucket.Key(hash[:])
}

View File

@ -14,7 +14,7 @@ var (
blockLocationsBucket = database.MakeBucket([]byte("block-locations"))
)
func blockLocationKey(hash *daghash.Hash) []byte {
func blockLocationKey(hash *daghash.Hash) *database.Key {
return blockLocationsBucket.Key(hash[:])
}

View File

@ -30,7 +30,7 @@ func BlockIndexCursor(context Context) (database.Cursor, error) {
return nil, err
}
return accessor.Cursor(blockIndexBucket.Path())
return accessor.Cursor(blockIndexBucket)
}
// BlockIndexCursorFrom opens a cursor over blocks-index blocks

View File

@ -11,8 +11,8 @@ func clearBucket(dbTx *TxContext, bucket *database.Bucket) error {
// Collect all of the keys before deleting them. We do this
// as to not modify the cursor while we're still iterating
// over it.
keys := make([][]byte, 0)
cursor, err := accessor.Cursor(bucket.Path())
keys := make([]*database.Key, 0)
cursor, err := accessor.Cursor(bucket)
if err != nil {
return err
}

View File

@ -1,7 +1,9 @@
package dbaccess
import "github.com/kaspanet/kaspad/database"
var (
dagStateKey = []byte("dag-state")
dagStateKey = database.MakeBucket().Key([]byte("dag-state"))
)
// StoreDAGState stores the DAG state in the database.

View File

@ -8,7 +8,7 @@ import (
var feeBucket = database.MakeBucket([]byte("fees"))
func feeDataKey(hash *daghash.Hash) []byte {
func feeDataKey(hash *daghash.Hash) *database.Key {
return feeBucket.Key(hash[:])
}

View File

@ -7,7 +7,7 @@ import (
var multisetBucket = database.MakeBucket([]byte("multiset"))
func multisetKey(hash *daghash.Hash) []byte {
func multisetKey(hash *daghash.Hash) *database.Key {
return multisetBucket.Key(hash[:])
}
@ -19,7 +19,7 @@ func MultisetCursor(context Context) (database.Cursor, error) {
return nil, err
}
return accessor.Cursor(multisetBucket.Path())
return accessor.Cursor(multisetBucket)
}
// StoreMultiset stores the multiset of a block by its hash.

View File

@ -7,7 +7,7 @@ import (
var reachabilityDataBucket = database.MakeBucket([]byte("reachability"))
func reachabilityKey(hash *daghash.Hash) []byte {
func reachabilityKey(hash *daghash.Hash) *database.Key {
return reachabilityDataBucket.Key(hash[:])
}
@ -19,7 +19,7 @@ func ReachabilityDataCursor(context Context) (database.Cursor, error) {
return nil, err
}
return accessor.Cursor(reachabilityDataBucket.Path())
return accessor.Cursor(reachabilityDataBucket)
}
// StoreReachabilityData stores the reachability data of a block by its hash.

View File

@ -7,7 +7,7 @@ import (
var subnetworkBucket = database.MakeBucket([]byte("subnetworks"))
func subnetworkKey(subnetworkID *subnetworkid.SubnetworkID) []byte {
func subnetworkKey(subnetworkID *subnetworkid.SubnetworkID) *database.Key {
return subnetworkBucket.Key(subnetworkID[:])
}

View File

@ -8,7 +8,7 @@ var (
utxoBucket = database.MakeBucket([]byte("utxo"))
)
func utxoKey(outpointKey []byte) []byte {
func utxoKey(outpointKey []byte) *database.Key {
return utxoBucket.Key(outpointKey)
}
@ -44,5 +44,5 @@ func UTXOSetCursor(context Context) (database.Cursor, error) {
return nil, err
}
return accessor.Cursor(utxoBucket.Path())
return accessor.Cursor(utxoBucket)
}

View File

@ -8,7 +8,7 @@ import (
var utxoDiffsBucket = database.MakeBucket([]byte("utxo-diffs"))
func utxoDiffKey(hash *daghash.Hash) []byte {
func utxoDiffKey(hash *daghash.Hash) *database.Key {
return utxoDiffsBucket.Key(hash[:])
}