dao: include settings in Version

Signed-off-by: Evgeniy Stratonikov <evgeniy@nspcc.ru>
This commit is contained in:
Evgeniy Stratonikov 2021-10-20 17:19:16 +03:00
parent 856385b106
commit 6c5a7d9b29
3 changed files with 63 additions and 14 deletions

View file

@ -45,7 +45,7 @@ import (
// Tuning parameters.
const (
headerBatchCount = 2000
version = "0.1.5"
version = "0.2.0"
defaultInitialGAS = 52000000_00000000
defaultMemPoolSize = 50000
@ -311,7 +311,8 @@ func (bc *Blockchain) init() error {
ver, err := bc.dao.GetVersion()
if err != nil {
bc.log.Info("no storage version found! creating genesis block")
if err = bc.dao.PutVersion(version); err != nil {
v := dao.Version{Prefix: storage.STStorage, Value: version}
if err = bc.dao.PutVersion(v); err != nil {
return err
}
genesisBlock, err := createGenesisBlock(bc.config)
@ -328,9 +329,11 @@ func (bc *Blockchain) init() error {
}
return bc.storeBlock(genesisBlock, nil)
}
if ver != version {
return fmt.Errorf("storage version mismatch betweeen %s and %s", version, ver)
if ver.Value != version {
return fmt.Errorf("storage version mismatch betweeen %s and %s", version, ver.Value)
}
bc.dao.StoragePrefix = ver.Prefix
bc.persistent.StoragePrefix = ver.Prefix // not strictly needed but we better be consistent here
// At this point there was no version found in the storage which
// implies a creating fresh storage with the version specified

View file

@ -50,7 +50,7 @@ type DAO interface {
GetStorageItems(id int32) ([]state.StorageItemWithKey, error)
GetStorageItemsWithPrefix(id int32, prefix []byte) ([]state.StorageItemWithKey, error)
GetTransaction(hash util.Uint256) (*transaction.Transaction, uint32, error)
GetVersion() (string, error)
GetVersion() (Version, error)
GetWrapped() DAO
HasTransaction(hash util.Uint256) error
Persist() (int, error)
@ -63,7 +63,7 @@ type DAO interface {
PutStateSyncPoint(p uint32) error
PutStateSyncCurrentBlockHeight(h uint32) error
PutStorageItem(id int32, key []byte, si state.StorageItem) error
PutVersion(v string) error
PutVersion(v Version) error
Seek(id int32, prefix []byte, f func(k, v []byte))
SeekAsync(ctx context.Context, id int32, prefix []byte) chan storage.KeyValue
StoreAsBlock(block *block.Block, buf *io.BufBinWriter) error
@ -378,11 +378,46 @@ func (dao *Simple) GetBlock(hash util.Uint256) (*block.Block, error) {
return block, nil
}
// Version represents current dao version.
type Version struct {
Prefix storage.KeyPrefix
Value string
}
// FromBytes decodes v from a byte-slice.
func (v *Version) FromBytes(data []byte) error {
if len(data) == 0 {
return errors.New("missing version")
}
i := 0
for ; i < len(data) && data[i] != '\x00'; i++ {
}
if i == len(data) {
v.Value = string(data)
return nil
}
v.Value = string(data[:i])
v.Prefix = storage.KeyPrefix(data[i+1])
return nil
}
// Bytes encodes v to a byte-slice.
func (v *Version) Bytes() []byte {
return append([]byte(v.Value), '\x00', byte(v.Prefix))
}
// GetVersion attempts to get the current version stored in the
// underlying store.
func (dao *Simple) GetVersion() (string, error) {
version, err := dao.Store.Get(storage.SYSVersion.Bytes())
return string(version), err
func (dao *Simple) GetVersion() (Version, error) {
var version Version
data, err := dao.Store.Get(storage.SYSVersion.Bytes())
if err == nil {
err = version.FromBytes(data)
}
return version, err
}
// GetCurrentBlockHeight returns the current block height found in the
@ -485,8 +520,9 @@ func (dao *Simple) GetTransaction(hash util.Uint256) (*transaction.Transaction,
}
// PutVersion stores the given version in the underlying store.
func (dao *Simple) PutVersion(v string) error {
return dao.Store.Put(storage.SYSVersion.Bytes(), []byte(v))
func (dao *Simple) PutVersion(v Version) error {
dao.StoragePrefix = v.Prefix
return dao.Store.Put(storage.SYSVersion.Bytes(), v.Bytes())
}
// PutCurrentHeader stores current header.

View file

@ -115,16 +115,26 @@ func TestGetVersion_NoVersion(t *testing.T) {
dao := NewSimple(storage.NewMemoryStore(), false, false)
version, err := dao.GetVersion()
require.Error(t, err)
require.Equal(t, "", version)
require.Equal(t, "", version.Value)
}
func TestGetVersion(t *testing.T) {
dao := NewSimple(storage.NewMemoryStore(), false, false)
err := dao.PutVersion("testVersion")
err := dao.PutVersion(Version{Prefix: 0x42, Value: "testVersion"})
require.NoError(t, err)
version, err := dao.GetVersion()
require.NoError(t, err)
require.NotNil(t, version)
require.EqualValues(t, 0x42, version.Prefix)
require.Equal(t, "testVersion", version.Value)
t.Run("old format", func(t *testing.T) {
dao := NewSimple(storage.NewMemoryStore(), false, false)
require.NoError(t, dao.Store.Put(storage.SYSVersion.Bytes(), []byte("0.1.2")))
version, err := dao.GetVersion()
require.NoError(t, err)
require.Equal(t, "0.1.2", version.Value)
})
}
func TestGetCurrentHeaderHeight_NoHeader(t *testing.T) {