264dfef370
add close function to storage interface add common defer function call which will close db connection remove context as soon as it's not needed anymore updated unit tests
92 lines
2.3 KiB
Go
92 lines
2.3 KiB
Go
package storage
|
|
|
|
import (
|
|
"encoding/binary"
|
|
"errors"
|
|
)
|
|
|
|
// KeyPrefix constants.
|
|
const (
|
|
DataBlock KeyPrefix = 0x01
|
|
DataTransaction KeyPrefix = 0x02
|
|
STAccount KeyPrefix = 0x40
|
|
STCoin KeyPrefix = 0x44
|
|
STSpentCoin KeyPrefix = 0x45
|
|
STValidator KeyPrefix = 0x48
|
|
STAsset KeyPrefix = 0x4c
|
|
STContract KeyPrefix = 0x50
|
|
STStorage KeyPrefix = 0x70
|
|
IXHeaderHashList KeyPrefix = 0x80
|
|
IXValidatorsCount KeyPrefix = 0x90
|
|
SYSCurrentBlock KeyPrefix = 0xc0
|
|
SYSCurrentHeader KeyPrefix = 0xc1
|
|
SYSVersion KeyPrefix = 0xf0
|
|
)
|
|
|
|
// ErrKeyNotFound is an error returned by Store implementations
|
|
// when a certain key is not found.
|
|
var ErrKeyNotFound = errors.New("key not found")
|
|
|
|
type (
|
|
// Store is anything that can persist and retrieve the blockchain.
|
|
// information.
|
|
Store interface {
|
|
Batch() Batch
|
|
Get([]byte) ([]byte, error)
|
|
Put(k, v []byte) error
|
|
PutBatch(Batch) error
|
|
Seek(k []byte, f func(k, v []byte))
|
|
Close() error
|
|
}
|
|
|
|
// Batch represents an abstraction on top of batch operations.
|
|
// Each Store implementation is responsible of casting a Batch
|
|
// to its appropriate type.
|
|
Batch interface {
|
|
Put(k, v []byte)
|
|
Len() int
|
|
}
|
|
|
|
// KeyPrefix is a constant byte added as a prefix for each key
|
|
// stored.
|
|
KeyPrefix uint8
|
|
)
|
|
|
|
// Bytes returns the bytes representation of KeyPrefix.
|
|
func (k KeyPrefix) Bytes() []byte {
|
|
return []byte{byte(k)}
|
|
}
|
|
|
|
// AppendPrefix append byteslice b to the given KeyPrefix.
|
|
// AppendKeyPrefix(SYSVersion, []byte{0x00, 0x01})
|
|
func AppendPrefix(k KeyPrefix, b []byte) []byte {
|
|
dest := make([]byte, len(b)+1)
|
|
dest[0] = byte(k)
|
|
copy(dest[1:], b)
|
|
return dest
|
|
}
|
|
|
|
// AppendPrefixInt append int n to the given KeyPrefix.
|
|
// AppendPrefixInt(SYSCurrentHeader, 10001)
|
|
func AppendPrefixInt(k KeyPrefix, n int) []byte {
|
|
b := make([]byte, 4)
|
|
binary.LittleEndian.PutUint32(b, uint32(n))
|
|
return AppendPrefix(k, b)
|
|
}
|
|
|
|
// NewStore creates storage with preselected in configuration database type.
|
|
func NewStore(cfg DBConfiguration) (Store, error) {
|
|
var store Store
|
|
var err error
|
|
switch cfg.Type {
|
|
case "leveldb":
|
|
store, err = NewLevelDBStore(cfg.LevelDBOptions)
|
|
case "inmemory":
|
|
store = NewMemoryStore()
|
|
case "redis":
|
|
store, err = NewRedisStore(cfg.RedisDBOptions)
|
|
case "boltdb":
|
|
store, err = NewBoltDBStore(cfg.BoltDBOptions)
|
|
}
|
|
return store, err
|
|
}
|