From 1c4c783c3a7e10cf54e35aa79d7ccfbfdbab4d25 Mon Sep 17 00:00:00 2001 From: Roman Khimov Date: Wed, 11 Jan 2023 12:05:05 +0300 Subject: [PATCH] core: store magic in the DB version, fix #2847 --- pkg/core/blockchain.go | 7 ++++++- pkg/core/blockchain_neotest_test.go | 9 +++++++++ pkg/core/dao/dao.go | 12 ++++++++++-- 3 files changed, 25 insertions(+), 3 deletions(-) diff --git a/pkg/core/blockchain.go b/pkg/core/blockchain.go index 6ac36da8f..f80cecb6f 100644 --- a/pkg/core/blockchain.go +++ b/pkg/core/blockchain.go @@ -45,7 +45,7 @@ import ( // Tuning parameters. const ( - version = "0.2.7" + version = "0.2.8" defaultInitialGAS = 52000000_00000000 defaultGCPeriod = 10000 @@ -381,6 +381,7 @@ func (bc *Blockchain) init() error { P2PSigExtensions: bc.config.P2PSigExtensions, P2PStateExchangeExtensions: bc.config.P2PStateExchangeExtensions, KeepOnlyLatestState: bc.config.Ledger.KeepOnlyLatestState, + Magic: uint32(bc.config.Magic), Value: version, } bc.dao.PutVersion(ver) @@ -415,6 +416,10 @@ func (bc *Blockchain) init() error { return fmt.Errorf("KeepOnlyLatestState setting mismatch (old=%v, new=%v)", ver.KeepOnlyLatestState, bc.config.Ledger.KeepOnlyLatestState) } + if ver.Magic != uint32(bc.config.Magic) { + return fmt.Errorf("protocol configuration Magic mismatch (old=%v, new=%v)", + ver.Magic, bc.config.Magic) + } bc.dao.Version = ver bc.persistent.Version = ver diff --git a/pkg/core/blockchain_neotest_test.go b/pkg/core/blockchain_neotest_test.go index cacfe126c..f71b8890b 100644 --- a/pkg/core/blockchain_neotest_test.go +++ b/pkg/core/blockchain_neotest_test.go @@ -141,6 +141,15 @@ func TestBlockchain_StartFromExistingDB(t *testing.T) { require.Error(t, err) require.True(t, strings.Contains(err.Error(), "KeepOnlyLatestState setting mismatch"), err) }) + t.Run("Magic mismatch", func(t *testing.T) { + ps = newPS(t) + _, _, _, err := chain.NewMultiWithCustomConfigAndStoreNoCheck(t, func(c *config.Blockchain) { + customConfig(c) + c.Magic = 100500 + }, ps) + require.Error(t, err) + require.True(t, strings.Contains(err.Error(), "protocol configuration Magic mismatch"), err) + }) t.Run("corrupted headers", func(t *testing.T) { ps = newPS(t) diff --git a/pkg/core/dao/dao.go b/pkg/core/dao/dao.go index 844490dd0..54a9cd85a 100644 --- a/pkg/core/dao/dao.go +++ b/pkg/core/dao/dao.go @@ -440,6 +440,7 @@ type Version struct { P2PSigExtensions bool P2PStateExchangeExtensions bool KeepOnlyLatestState bool + Magic uint32 Value string } @@ -464,7 +465,7 @@ func (v *Version) FromBytes(data []byte) error { return nil } - if len(data) != i+3 { + if len(data) < i+3 { return errors.New("version is invalid") } @@ -474,6 +475,11 @@ func (v *Version) FromBytes(data []byte) error { v.P2PSigExtensions = data[i+2]&p2pSigExtensionsBit != 0 v.P2PStateExchangeExtensions = data[i+2]&p2pStateExchangeExtensionsBit != 0 v.KeepOnlyLatestState = data[i+2]&keepOnlyLatestStateBit != 0 + + m := i + 3 + if len(data) == m+4 { + v.Magic = binary.LittleEndian.Uint32(data[m:]) + } return nil } @@ -492,7 +498,9 @@ func (v *Version) Bytes() []byte { if v.KeepOnlyLatestState { mask |= keepOnlyLatestStateBit } - return append([]byte(v.Value), '\x00', byte(v.StoragePrefix), mask) + res := append([]byte(v.Value), '\x00', byte(v.StoragePrefix), mask, 0, 0, 0, 0) + binary.LittleEndian.PutUint32(res[len(res)-4:], v.Magic) + return res } func (dao *Simple) mkKeyPrefix(k storage.KeyPrefix) []byte {