Merge pull request #2867 from nspcc-dev/store-magic-in-db

core: store magic in the DB version, fix #2847
This commit is contained in:
Roman Khimov 2023-01-11 20:42:00 +07:00 committed by GitHub
commit 9a6fa84f70
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 24 additions and 2 deletions

View file

@ -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

View file

@ -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)

View file

@ -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 {