dao: add stateroot-related settings to Version
Signed-off-by: Evgeniy Stratonikov <evgeniy@nspcc.ru>
This commit is contained in:
parent
856e9cf67b
commit
f7e2d3d717
7 changed files with 91 additions and 46 deletions
|
@ -305,10 +305,17 @@ func (bc *Blockchain) init() error {
|
||||||
ver, err := bc.dao.GetVersion()
|
ver, err := bc.dao.GetVersion()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
bc.log.Info("no storage version found! creating genesis block")
|
bc.log.Info("no storage version found! creating genesis block")
|
||||||
v := dao.Version{Prefix: storage.STStorage, Value: version}
|
ver = dao.Version{
|
||||||
if err = bc.dao.PutVersion(v); err != nil {
|
StoragePrefix: storage.STStorage,
|
||||||
|
StateRootInHeader: bc.config.StateRootInHeader,
|
||||||
|
P2PSigExtensions: bc.config.P2PSigExtensions,
|
||||||
|
Value: version,
|
||||||
|
}
|
||||||
|
if err = bc.dao.PutVersion(ver); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
bc.dao.Version = ver
|
||||||
|
bc.persistent.Version = ver
|
||||||
genesisBlock, err := createGenesisBlock(bc.config)
|
genesisBlock, err := createGenesisBlock(bc.config)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
|
@ -326,8 +333,16 @@ func (bc *Blockchain) init() error {
|
||||||
if ver.Value != version {
|
if ver.Value != version {
|
||||||
return fmt.Errorf("storage version mismatch betweeen %s and %s", version, ver.Value)
|
return fmt.Errorf("storage version mismatch betweeen %s and %s", version, ver.Value)
|
||||||
}
|
}
|
||||||
bc.dao.StoragePrefix = ver.Prefix
|
if ver.StateRootInHeader != bc.config.StateRootInHeader {
|
||||||
bc.persistent.StoragePrefix = ver.Prefix // not strictly needed but we better be consistent here
|
return fmt.Errorf("StateRootInHeader setting mismatch (config=%t, db=%t)",
|
||||||
|
ver.StateRootInHeader, bc.config.StateRootInHeader)
|
||||||
|
}
|
||||||
|
if ver.P2PSigExtensions != bc.config.P2PSigExtensions {
|
||||||
|
return fmt.Errorf("P2PSigExtensions setting mismatch (old=%t, new=%t",
|
||||||
|
ver.P2PSigExtensions, bc.config.P2PSigExtensions)
|
||||||
|
}
|
||||||
|
bc.dao.Version = ver
|
||||||
|
bc.persistent.Version = ver
|
||||||
|
|
||||||
// At this point there was no version found in the storage which
|
// At this point there was no version found in the storage which
|
||||||
// implies a creating fresh storage with the version specified
|
// implies a creating fresh storage with the version specified
|
||||||
|
@ -487,7 +502,7 @@ func (bc *Blockchain) jumpToStateInternal(p uint32, stage stateJumpStage) error
|
||||||
// Replace old storage items by new ones, it should be done step-by step.
|
// Replace old storage items by new ones, it should be done step-by step.
|
||||||
// Firstly, remove all old genesis-related items.
|
// Firstly, remove all old genesis-related items.
|
||||||
b := bc.dao.Store.Batch()
|
b := bc.dao.Store.Batch()
|
||||||
bc.dao.Store.Seek([]byte{byte(bc.dao.StoragePrefix)}, func(k, _ []byte) {
|
bc.dao.Store.Seek([]byte{byte(bc.dao.Version.StoragePrefix)}, func(k, _ []byte) {
|
||||||
// #1468, but don't need to copy here, because it is done by Store.
|
// #1468, but don't need to copy here, because it is done by Store.
|
||||||
b.Delete(k)
|
b.Delete(k)
|
||||||
})
|
})
|
||||||
|
@ -498,16 +513,16 @@ func (bc *Blockchain) jumpToStateInternal(p uint32, stage stateJumpStage) error
|
||||||
}
|
}
|
||||||
fallthrough
|
fallthrough
|
||||||
case oldStorageItemsRemoved:
|
case oldStorageItemsRemoved:
|
||||||
newPrefix := statesync.TemporaryPrefix(bc.dao.StoragePrefix)
|
newPrefix := statesync.TemporaryPrefix(bc.dao.Version.StoragePrefix)
|
||||||
v, err := bc.dao.GetVersion()
|
v, err := bc.dao.GetVersion()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("failed to get dao.Version: %w", err)
|
return fmt.Errorf("failed to get dao.Version: %w", err)
|
||||||
}
|
}
|
||||||
v.Prefix = newPrefix
|
v.StoragePrefix = newPrefix
|
||||||
if err := bc.dao.PutVersion(v); err != nil {
|
if err := bc.dao.PutVersion(v); err != nil {
|
||||||
return fmt.Errorf("failed to update dao.Version: %w", err)
|
return fmt.Errorf("failed to update dao.Version: %w", err)
|
||||||
}
|
}
|
||||||
bc.persistent.StoragePrefix = newPrefix
|
bc.persistent.Version = v
|
||||||
|
|
||||||
err = bc.dao.Store.Put(jumpStageKey, []byte{byte(newStorageItemsAdded)})
|
err = bc.dao.Store.Put(jumpStageKey, []byte{byte(newStorageItemsAdded)})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
|
@ -1766,10 +1766,10 @@ func TestBlockchain_InitWithIncompleteStateJump(t *testing.T) {
|
||||||
// put storage items with STTemp prefix
|
// put storage items with STTemp prefix
|
||||||
batch := bcSpout.dao.Store.Batch()
|
batch := bcSpout.dao.Store.Batch()
|
||||||
tempPrefix := storage.STTempStorage
|
tempPrefix := storage.STTempStorage
|
||||||
if bcSpout.dao.StoragePrefix == tempPrefix {
|
if bcSpout.dao.Version.StoragePrefix == tempPrefix {
|
||||||
tempPrefix = storage.STStorage
|
tempPrefix = storage.STStorage
|
||||||
}
|
}
|
||||||
bcSpout.dao.Store.Seek(bcSpout.dao.StoragePrefix.Bytes(), func(k, v []byte) {
|
bcSpout.dao.Store.Seek(bcSpout.dao.Version.StoragePrefix.Bytes(), func(k, v []byte) {
|
||||||
key := slice.Copy(k)
|
key := slice.Copy(k)
|
||||||
key[0] = byte(tempPrefix)
|
key[0] = byte(tempPrefix)
|
||||||
value := slice.Copy(v)
|
value := slice.Copy(v)
|
||||||
|
|
|
@ -74,22 +74,20 @@ type DAO interface {
|
||||||
|
|
||||||
// Simple is memCached wrapper around DB, simple DAO implementation.
|
// Simple is memCached wrapper around DB, simple DAO implementation.
|
||||||
type Simple struct {
|
type Simple struct {
|
||||||
StoragePrefix storage.KeyPrefix
|
Version Version
|
||||||
Store *storage.MemCachedStore
|
Store *storage.MemCachedStore
|
||||||
// stateRootInHeader specifies if block header contains state root.
|
|
||||||
stateRootInHeader bool
|
|
||||||
// p2pSigExtensions denotes whether P2PSignatureExtensions are enabled.
|
|
||||||
p2pSigExtensions bool
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewSimple creates new simple dao using provided backend store.
|
// NewSimple creates new simple dao using provided backend store.
|
||||||
func NewSimple(backend storage.Store, stateRootInHeader bool, p2pSigExtensions bool) *Simple {
|
func NewSimple(backend storage.Store, stateRootInHeader bool, p2pSigExtensions bool) *Simple {
|
||||||
st := storage.NewMemCachedStore(backend)
|
st := storage.NewMemCachedStore(backend)
|
||||||
return &Simple{
|
return &Simple{
|
||||||
|
Version: Version{
|
||||||
StoragePrefix: storage.STStorage,
|
StoragePrefix: storage.STStorage,
|
||||||
|
StateRootInHeader: stateRootInHeader,
|
||||||
|
P2PSigExtensions: p2pSigExtensions,
|
||||||
|
},
|
||||||
Store: st,
|
Store: st,
|
||||||
stateRootInHeader: stateRootInHeader,
|
|
||||||
p2pSigExtensions: p2pSigExtensions,
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -101,8 +99,8 @@ func (dao *Simple) GetBatch() *storage.MemBatch {
|
||||||
// GetWrapped returns new DAO instance with another layer of wrapped
|
// GetWrapped returns new DAO instance with another layer of wrapped
|
||||||
// MemCachedStore around the current DAO Store.
|
// MemCachedStore around the current DAO Store.
|
||||||
func (dao *Simple) GetWrapped() DAO {
|
func (dao *Simple) GetWrapped() DAO {
|
||||||
d := NewSimple(dao.Store, dao.stateRootInHeader, dao.p2pSigExtensions)
|
d := NewSimple(dao.Store, dao.Version.StateRootInHeader, dao.Version.P2PSigExtensions)
|
||||||
d.StoragePrefix = dao.StoragePrefix
|
d.Version = dao.Version
|
||||||
return d
|
return d
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -284,7 +282,7 @@ func (dao *Simple) PutAppExecResult(aer *state.AppExecResult, buf *io.BufBinWrit
|
||||||
|
|
||||||
// GetStorageItem returns StorageItem if it exists in the given store.
|
// GetStorageItem returns StorageItem if it exists in the given store.
|
||||||
func (dao *Simple) GetStorageItem(id int32, key []byte) state.StorageItem {
|
func (dao *Simple) GetStorageItem(id int32, key []byte) state.StorageItem {
|
||||||
b, err := dao.Store.Get(makeStorageItemKey(dao.StoragePrefix, id, key))
|
b, err := dao.Store.Get(makeStorageItemKey(dao.Version.StoragePrefix, id, key))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
@ -294,14 +292,14 @@ func (dao *Simple) GetStorageItem(id int32, key []byte) state.StorageItem {
|
||||||
// PutStorageItem puts given StorageItem for given id with given
|
// PutStorageItem puts given StorageItem for given id with given
|
||||||
// key into the given store.
|
// key into the given store.
|
||||||
func (dao *Simple) PutStorageItem(id int32, key []byte, si state.StorageItem) error {
|
func (dao *Simple) PutStorageItem(id int32, key []byte, si state.StorageItem) error {
|
||||||
stKey := makeStorageItemKey(dao.StoragePrefix, id, key)
|
stKey := makeStorageItemKey(dao.Version.StoragePrefix, id, key)
|
||||||
return dao.Store.Put(stKey, si)
|
return dao.Store.Put(stKey, si)
|
||||||
}
|
}
|
||||||
|
|
||||||
// DeleteStorageItem drops storage item for the given id with the
|
// DeleteStorageItem drops storage item for the given id with the
|
||||||
// given key from the store.
|
// given key from the store.
|
||||||
func (dao *Simple) DeleteStorageItem(id int32, key []byte) error {
|
func (dao *Simple) DeleteStorageItem(id int32, key []byte) error {
|
||||||
stKey := makeStorageItemKey(dao.StoragePrefix, id, key)
|
stKey := makeStorageItemKey(dao.Version.StoragePrefix, id, key)
|
||||||
return dao.Store.Delete(stKey)
|
return dao.Store.Delete(stKey)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -330,7 +328,7 @@ func (dao *Simple) GetStorageItemsWithPrefix(id int32, prefix []byte) ([]state.S
|
||||||
// Seek executes f for all items with a given prefix.
|
// Seek executes f for all items with a given prefix.
|
||||||
// If key is to be used outside of f, they may not be copied.
|
// If key is to be used outside of f, they may not be copied.
|
||||||
func (dao *Simple) Seek(id int32, prefix []byte, f func(k, v []byte)) {
|
func (dao *Simple) Seek(id int32, prefix []byte, f func(k, v []byte)) {
|
||||||
lookupKey := makeStorageItemKey(dao.StoragePrefix, id, nil)
|
lookupKey := makeStorageItemKey(dao.Version.StoragePrefix, id, nil)
|
||||||
if prefix != nil {
|
if prefix != nil {
|
||||||
lookupKey = append(lookupKey, prefix...)
|
lookupKey = append(lookupKey, prefix...)
|
||||||
}
|
}
|
||||||
|
@ -342,7 +340,7 @@ func (dao *Simple) Seek(id int32, prefix []byte, f func(k, v []byte)) {
|
||||||
// SeekAsync sends all storage items matching given prefix to a channel and returns
|
// SeekAsync sends all storage items matching given prefix to a channel and returns
|
||||||
// the channel. Resulting keys and values may not be copied.
|
// the channel. Resulting keys and values may not be copied.
|
||||||
func (dao *Simple) SeekAsync(ctx context.Context, id int32, prefix []byte) chan storage.KeyValue {
|
func (dao *Simple) SeekAsync(ctx context.Context, id int32, prefix []byte) chan storage.KeyValue {
|
||||||
lookupKey := makeStorageItemKey(dao.StoragePrefix, id, nil)
|
lookupKey := makeStorageItemKey(dao.Version.StoragePrefix, id, nil)
|
||||||
if prefix != nil {
|
if prefix != nil {
|
||||||
lookupKey = append(lookupKey, prefix...)
|
lookupKey = append(lookupKey, prefix...)
|
||||||
}
|
}
|
||||||
|
@ -371,7 +369,7 @@ func (dao *Simple) GetBlock(hash util.Uint256) (*block.Block, error) {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
block, err := block.NewBlockFromTrimmedBytes(dao.stateRootInHeader, b)
|
block, err := block.NewBlockFromTrimmedBytes(dao.Version.StateRootInHeader, b)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
@ -380,10 +378,17 @@ func (dao *Simple) GetBlock(hash util.Uint256) (*block.Block, error) {
|
||||||
|
|
||||||
// Version represents current dao version.
|
// Version represents current dao version.
|
||||||
type Version struct {
|
type Version struct {
|
||||||
Prefix storage.KeyPrefix
|
StoragePrefix storage.KeyPrefix
|
||||||
|
StateRootInHeader bool
|
||||||
|
P2PSigExtensions bool
|
||||||
Value string
|
Value string
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const (
|
||||||
|
stateRootInHeaderBit = 1 << iota
|
||||||
|
p2pSigExtensionsBit
|
||||||
|
)
|
||||||
|
|
||||||
// FromBytes decodes v from a byte-slice.
|
// FromBytes decodes v from a byte-slice.
|
||||||
func (v *Version) FromBytes(data []byte) error {
|
func (v *Version) FromBytes(data []byte) error {
|
||||||
if len(data) == 0 {
|
if len(data) == 0 {
|
||||||
|
@ -398,14 +403,27 @@ func (v *Version) FromBytes(data []byte) error {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if len(data) != i+3 {
|
||||||
|
return errors.New("version is invalid")
|
||||||
|
}
|
||||||
|
|
||||||
v.Value = string(data[:i])
|
v.Value = string(data[:i])
|
||||||
v.Prefix = storage.KeyPrefix(data[i+1])
|
v.StoragePrefix = storage.KeyPrefix(data[i+1])
|
||||||
|
v.StateRootInHeader = data[i+2]&stateRootInHeaderBit != 0
|
||||||
|
v.P2PSigExtensions = data[i+2]&p2pSigExtensionsBit != 0
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// Bytes encodes v to a byte-slice.
|
// Bytes encodes v to a byte-slice.
|
||||||
func (v *Version) Bytes() []byte {
|
func (v *Version) Bytes() []byte {
|
||||||
return append([]byte(v.Value), '\x00', byte(v.Prefix))
|
var mask byte
|
||||||
|
if v.StateRootInHeader {
|
||||||
|
mask |= stateRootInHeaderBit
|
||||||
|
}
|
||||||
|
if v.P2PSigExtensions {
|
||||||
|
mask |= p2pSigExtensionsBit
|
||||||
|
}
|
||||||
|
return append([]byte(v.Value), '\x00', byte(v.StoragePrefix), mask)
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetVersion attempts to get the current version stored in the
|
// GetVersion attempts to get the current version stored in the
|
||||||
|
@ -521,7 +539,7 @@ func (dao *Simple) GetTransaction(hash util.Uint256) (*transaction.Transaction,
|
||||||
|
|
||||||
// PutVersion stores the given version in the underlying store.
|
// PutVersion stores the given version in the underlying store.
|
||||||
func (dao *Simple) PutVersion(v Version) error {
|
func (dao *Simple) PutVersion(v Version) error {
|
||||||
dao.StoragePrefix = v.Prefix
|
dao.Version = v
|
||||||
return dao.Store.Put(storage.SYSVersion.Bytes(), v.Bytes())
|
return dao.Store.Put(storage.SYSVersion.Bytes(), v.Bytes())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -607,7 +625,7 @@ func (dao *Simple) DeleteBlock(h util.Uint256, w *io.BufBinWriter) error {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
b, err := block.NewBlockFromTrimmedBytes(dao.stateRootInHeader, bs)
|
b, err := block.NewBlockFromTrimmedBytes(dao.Version.StateRootInHeader, bs)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
@ -626,7 +644,7 @@ func (dao *Simple) DeleteBlock(h util.Uint256, w *io.BufBinWriter) error {
|
||||||
for _, tx := range b.Transactions {
|
for _, tx := range b.Transactions {
|
||||||
copy(key[1:], tx.Hash().BytesBE())
|
copy(key[1:], tx.Hash().BytesBE())
|
||||||
batch.Delete(key)
|
batch.Delete(key)
|
||||||
if dao.p2pSigExtensions {
|
if dao.Version.P2PSigExtensions {
|
||||||
for _, attr := range tx.GetAttributes(transaction.ConflictsT) {
|
for _, attr := range tx.GetAttributes(transaction.ConflictsT) {
|
||||||
hash := attr.Value.(*transaction.Conflicts).Hash
|
hash := attr.Value.(*transaction.Conflicts).Hash
|
||||||
copy(key[1:], hash.BytesBE())
|
copy(key[1:], hash.BytesBE())
|
||||||
|
@ -674,7 +692,7 @@ func (dao *Simple) StoreAsTransaction(tx *transaction.Transaction, index uint32,
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
if dao.p2pSigExtensions {
|
if dao.Version.P2PSigExtensions {
|
||||||
var value []byte
|
var value []byte
|
||||||
for _, attr := range tx.GetAttributes(transaction.ConflictsT) {
|
for _, attr := range tx.GetAttributes(transaction.ConflictsT) {
|
||||||
hash := attr.Value.(*transaction.Conflicts).Hash
|
hash := attr.Value.(*transaction.Conflicts).Hash
|
||||||
|
@ -710,7 +728,7 @@ func (dao *Simple) PersistSync() (int, error) {
|
||||||
// GetMPTBatch storage changes to be applied to MPT.
|
// GetMPTBatch storage changes to be applied to MPT.
|
||||||
func (dao *Simple) GetMPTBatch() mpt.Batch {
|
func (dao *Simple) GetMPTBatch() mpt.Batch {
|
||||||
var b mpt.Batch
|
var b mpt.Batch
|
||||||
dao.Store.MemoryStore.SeekAll([]byte{byte(dao.StoragePrefix)}, func(k, v []byte) {
|
dao.Store.MemoryStore.SeekAll([]byte{byte(dao.Version.StoragePrefix)}, func(k, v []byte) {
|
||||||
b.Add(k[1:], v)
|
b.Add(k[1:], v)
|
||||||
})
|
})
|
||||||
return b
|
return b
|
||||||
|
|
|
@ -120,13 +120,25 @@ func TestGetVersion_NoVersion(t *testing.T) {
|
||||||
|
|
||||||
func TestGetVersion(t *testing.T) {
|
func TestGetVersion(t *testing.T) {
|
||||||
dao := NewSimple(storage.NewMemoryStore(), false, false)
|
dao := NewSimple(storage.NewMemoryStore(), false, false)
|
||||||
err := dao.PutVersion(Version{Prefix: 0x42, Value: "testVersion"})
|
expected := Version{
|
||||||
|
StoragePrefix: 0x42,
|
||||||
|
P2PSigExtensions: true,
|
||||||
|
StateRootInHeader: true,
|
||||||
|
Value: "testVersion",
|
||||||
|
}
|
||||||
|
err := dao.PutVersion(expected)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
version, err := dao.GetVersion()
|
actual, err := dao.GetVersion()
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
require.EqualValues(t, 0x42, version.Prefix)
|
require.Equal(t, expected, actual)
|
||||||
require.Equal(t, "testVersion", version.Value)
|
|
||||||
|
|
||||||
|
t.Run("invalid", func(t *testing.T) {
|
||||||
|
dao := NewSimple(storage.NewMemoryStore(), false, false)
|
||||||
|
require.NoError(t, dao.Store.Put(storage.SYSVersion.Bytes(), []byte("0.1.2\x00x")))
|
||||||
|
|
||||||
|
_, err := dao.GetVersion()
|
||||||
|
require.Error(t, err)
|
||||||
|
})
|
||||||
t.Run("old format", func(t *testing.T) {
|
t.Run("old format", func(t *testing.T) {
|
||||||
dao := NewSimple(storage.NewMemoryStore(), false, false)
|
dao := NewSimple(storage.NewMemoryStore(), false, false)
|
||||||
require.NoError(t, dao.Store.Put(storage.SYSVersion.Bytes(), []byte("0.1.2")))
|
require.NoError(t, dao.Store.Put(storage.SYSVersion.Bytes(), []byte("0.1.2")))
|
||||||
|
|
|
@ -208,7 +208,7 @@ func (s *Module) defineSyncStage() error {
|
||||||
return fmt.Errorf("failed to get header to initialize MPT billet: %w", err)
|
return fmt.Errorf("failed to get header to initialize MPT billet: %w", err)
|
||||||
}
|
}
|
||||||
s.billet = mpt.NewBillet(header.PrevStateRoot, s.bc.GetConfig().KeepOnlyLatestState,
|
s.billet = mpt.NewBillet(header.PrevStateRoot, s.bc.GetConfig().KeepOnlyLatestState,
|
||||||
TemporaryPrefix(s.dao.StoragePrefix), s.dao.Store)
|
TemporaryPrefix(s.dao.Version.StoragePrefix), s.dao.Store)
|
||||||
s.log.Info("MPT billet initialized",
|
s.log.Info("MPT billet initialized",
|
||||||
zap.Uint32("height", s.syncPoint),
|
zap.Uint32("height", s.syncPoint),
|
||||||
zap.String("state root", header.PrevStateRoot.StringBE()))
|
zap.String("state root", header.PrevStateRoot.StringBE()))
|
||||||
|
|
|
@ -57,7 +57,7 @@ func TestModule_PR2019_discussion_r689629704(t *testing.T) {
|
||||||
mptpool: NewPool(),
|
mptpool: NewPool(),
|
||||||
}
|
}
|
||||||
stateSync.billet = mpt.NewBillet(sr, true,
|
stateSync.billet = mpt.NewBillet(sr, true,
|
||||||
TemporaryPrefix(stateSync.dao.StoragePrefix), actualStorage)
|
TemporaryPrefix(stateSync.dao.Version.StoragePrefix), actualStorage)
|
||||||
stateSync.mptpool.Add(sr, []byte{})
|
stateSync.mptpool.Add(sr, []byte{})
|
||||||
|
|
||||||
// The test itself: we'll ask state sync module to restore each node exactly once.
|
// The test itself: we'll ask state sync module to restore each node exactly once.
|
||||||
|
|
|
@ -423,7 +423,7 @@ func TestStateSyncModule_RestoreBasicChain(t *testing.T) {
|
||||||
// compare storage states
|
// compare storage states
|
||||||
fetchStorage := func(bc *Blockchain) []storage.KeyValue {
|
fetchStorage := func(bc *Blockchain) []storage.KeyValue {
|
||||||
var kv []storage.KeyValue
|
var kv []storage.KeyValue
|
||||||
bc.dao.Store.Seek(bc.dao.StoragePrefix.Bytes(), func(k, v []byte) {
|
bc.dao.Store.Seek(bc.dao.Version.StoragePrefix.Bytes(), func(k, v []byte) {
|
||||||
key := slice.Copy(k)
|
key := slice.Copy(k)
|
||||||
value := slice.Copy(v)
|
value := slice.Copy(v)
|
||||||
if key[0] == byte(storage.STTempStorage) {
|
if key[0] == byte(storage.STTempStorage) {
|
||||||
|
@ -450,6 +450,6 @@ func TestStateSyncModule_RestoreBasicChain(t *testing.T) {
|
||||||
bcBolt = initTestChain(t, bcBoltStore, boltCfg)
|
bcBolt = initTestChain(t, bcBoltStore, boltCfg)
|
||||||
go bcBolt.Run()
|
go bcBolt.Run()
|
||||||
defer bcBolt.Close()
|
defer bcBolt.Close()
|
||||||
require.Equal(t, storage.STTempStorage, bcBolt.dao.StoragePrefix)
|
require.Equal(t, storage.STTempStorage, bcBolt.dao.Version.StoragePrefix)
|
||||||
require.Equal(t, storage.STTempStorage, bcBolt.persistent.StoragePrefix)
|
require.Equal(t, storage.STTempStorage, bcBolt.persistent.Version.StoragePrefix)
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue