2018-03-17 11:53:21 +00:00
|
|
|
package storage
|
|
|
|
|
|
|
|
import (
|
|
|
|
"encoding/binary"
|
|
|
|
"errors"
|
2020-08-24 16:00:16 +00:00
|
|
|
"fmt"
|
2018-03-17 11:53:21 +00:00
|
|
|
)
|
|
|
|
|
|
|
|
// KeyPrefix constants.
|
|
|
|
const (
|
2020-04-26 07:15:59 +00:00
|
|
|
DataBlock KeyPrefix = 0x01
|
|
|
|
DataTransaction KeyPrefix = 0x02
|
2020-05-22 07:37:07 +00:00
|
|
|
DataMPT KeyPrefix = 0x03
|
2020-04-26 07:15:59 +00:00
|
|
|
STAccount KeyPrefix = 0x40
|
|
|
|
STNotification KeyPrefix = 0x4d
|
|
|
|
STContract KeyPrefix = 0x50
|
2020-07-28 13:36:47 +00:00
|
|
|
STContractID KeyPrefix = 0x51
|
2020-04-26 07:15:59 +00:00
|
|
|
STStorage KeyPrefix = 0x70
|
2020-11-24 08:14:25 +00:00
|
|
|
STNEP17Transfers KeyPrefix = 0x72
|
|
|
|
STNEP17Balances KeyPrefix = 0x73
|
2020-04-26 07:15:59 +00:00
|
|
|
IXHeaderHashList KeyPrefix = 0x80
|
|
|
|
SYSCurrentBlock KeyPrefix = 0xc0
|
|
|
|
SYSCurrentHeader KeyPrefix = 0xc1
|
2020-06-09 12:12:23 +00:00
|
|
|
SYSContractID KeyPrefix = 0xc2
|
2020-04-26 07:15:59 +00:00
|
|
|
SYSVersion KeyPrefix = 0xf0
|
2018-03-17 11:53:21 +00:00
|
|
|
)
|
|
|
|
|
|
|
|
// 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
|
2019-10-07 14:08:09 +00:00
|
|
|
Delete(k []byte) error
|
2018-03-17 11:53:21 +00:00
|
|
|
Get([]byte) ([]byte, error)
|
|
|
|
Put(k, v []byte) error
|
2018-04-09 16:58:09 +00:00
|
|
|
PutBatch(Batch) error
|
2020-10-10 09:37:46 +00:00
|
|
|
// Seek can guarantee that provided key (k) and value (v) are the only valid until the next call to f.
|
|
|
|
// Key and value slices should not be modified.
|
2018-03-17 11:53:21 +00:00
|
|
|
Seek(k []byte, f func(k, v []byte))
|
2019-09-16 15:52:47 +00:00
|
|
|
Close() error
|
2018-03-17 11:53:21 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// Batch represents an abstraction on top of batch operations.
|
|
|
|
// Each Store implementation is responsible of casting a Batch
|
|
|
|
// to its appropriate type.
|
|
|
|
Batch interface {
|
2019-10-07 14:08:09 +00:00
|
|
|
Delete(k []byte)
|
2018-03-17 11:53:21 +00:00
|
|
|
Put(k, v []byte)
|
|
|
|
}
|
|
|
|
|
|
|
|
// 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)}
|
|
|
|
}
|
|
|
|
|
2019-10-22 14:56:03 +00:00
|
|
|
// AppendPrefix appends byteslice b to the given KeyPrefix.
|
|
|
|
// AppendKeyPrefix(SYSVersion, []byte{0x00, 0x01})
|
2018-03-17 11:53:21 +00:00
|
|
|
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.
|
2019-10-22 14:56:03 +00:00
|
|
|
//AppendPrefixInt(SYSCurrentHeader, 10001)
|
2018-03-17 11:53:21 +00:00
|
|
|
func AppendPrefixInt(k KeyPrefix, n int) []byte {
|
|
|
|
b := make([]byte, 4)
|
|
|
|
binary.LittleEndian.PutUint32(b, uint32(n))
|
|
|
|
return AppendPrefix(k, b)
|
|
|
|
}
|
2019-09-10 14:22:21 +00:00
|
|
|
|
|
|
|
// NewStore creates storage with preselected in configuration database type.
|
2019-09-16 15:52:47 +00:00
|
|
|
func NewStore(cfg DBConfiguration) (Store, error) {
|
2019-09-10 14:22:21 +00:00
|
|
|
var store Store
|
|
|
|
var err error
|
|
|
|
switch cfg.Type {
|
|
|
|
case "leveldb":
|
2019-09-16 15:52:47 +00:00
|
|
|
store, err = NewLevelDBStore(cfg.LevelDBOptions)
|
2019-09-10 14:22:21 +00:00
|
|
|
case "inmemory":
|
|
|
|
store = NewMemoryStore()
|
|
|
|
case "redis":
|
|
|
|
store, err = NewRedisStore(cfg.RedisDBOptions)
|
2019-09-14 07:28:43 +00:00
|
|
|
case "boltdb":
|
2019-09-16 15:52:47 +00:00
|
|
|
store, err = NewBoltDBStore(cfg.BoltDBOptions)
|
2020-04-08 14:14:58 +00:00
|
|
|
case "badgerdb":
|
|
|
|
store, err = NewBadgerDBStore(cfg.BadgerDBOptions)
|
2020-08-24 16:00:16 +00:00
|
|
|
default:
|
|
|
|
return nil, fmt.Errorf("unknown storage: %s", cfg.Type)
|
2019-09-10 14:22:21 +00:00
|
|
|
}
|
|
|
|
return store, err
|
|
|
|
}
|