native: ignore decoding errors during cache init

Bad contract -> no contract. Unfortunately we've got a broken
6f1837723768f27a6f6a14452977e3e0e264f2cc contract on the mainnet which can't
be decoded (even though it had been saved successfully), so this is a
temporary fix for #2801 to be able to start mainnet node after shutdown.
This commit is contained in:
Roman Khimov 2022-11-16 11:36:04 +03:00
parent 0402a75d20
commit 822722bd2e
3 changed files with 7 additions and 9 deletions

View file

@ -207,6 +207,7 @@ func TestBlockchain_StartFromExistingDB(t *testing.T) {
require.Error(t, err) require.Error(t, err)
require.True(t, strings.Contains(err.Error(), "can't init MPT at height"), err) require.True(t, strings.Contains(err.Error(), "can't init MPT at height"), err)
}) })
/* See #2801
t.Run("failed native Management initialisation", func(t *testing.T) { t.Run("failed native Management initialisation", func(t *testing.T) {
ps = newPS(t) ps = newPS(t)
@ -223,6 +224,7 @@ func TestBlockchain_StartFromExistingDB(t *testing.T) {
require.Error(t, err) require.Error(t, err)
require.True(t, strings.Contains(err.Error(), "can't init cache for Management native contract"), err) require.True(t, strings.Contains(err.Error(), "can't init cache for Management native contract"), err)
}) })
*/
t.Run("invalid native contract deactivation", func(t *testing.T) { t.Run("invalid native contract deactivation", func(t *testing.T) {
ps = newPS(t) ps = newPS(t)
_, _, _, err := chain.NewMultiWithCustomConfigAndStoreNoCheck(t, func(c *config.ProtocolConfiguration) { _, _, _, err := chain.NewMultiWithCustomConfigAndStoreNoCheck(t, func(c *config.ProtocolConfiguration) {

View file

@ -539,19 +539,13 @@ func (m *Management) InitializeCache(d *dao.Simple) error {
nep17: make(map[util.Uint160]struct{}), nep17: make(map[util.Uint160]struct{}),
} }
var initErr error d.Seek(m.ID, storage.SeekRange{Prefix: []byte{PrefixContract}}, func(k, v []byte) bool {
d.Seek(m.ID, storage.SeekRange{Prefix: []byte{PrefixContract}}, func(_, v []byte) bool {
var cs = new(state.Contract) var cs = new(state.Contract)
initErr = stackitem.DeserializeConvertible(v, cs) if stackitem.DeserializeConvertible(v, cs) == nil {
if initErr != nil {
return false
}
updateContractCache(cache, cs) updateContractCache(cache, cs)
}
return true return true
}) })
if initErr != nil {
return initErr
}
d.SetCache(m.ID, cache) d.SetCache(m.ID, cache)
return nil return nil
} }

View file

@ -78,12 +78,14 @@ func TestManagement_Initialize(t *testing.T) {
mgmt := newManagement() mgmt := newManagement()
require.NoError(t, mgmt.InitializeCache(d)) require.NoError(t, mgmt.InitializeCache(d))
}) })
/* See #2801
t.Run("invalid contract state", func(t *testing.T) { t.Run("invalid contract state", func(t *testing.T) {
d := dao.NewSimple(storage.NewMemoryStore(), false, false) d := dao.NewSimple(storage.NewMemoryStore(), false, false)
mgmt := newManagement() mgmt := newManagement()
d.PutStorageItem(mgmt.ID, []byte{PrefixContract}, state.StorageItem{0xFF}) d.PutStorageItem(mgmt.ID, []byte{PrefixContract}, state.StorageItem{0xFF})
require.Error(t, mgmt.InitializeCache(d)) require.Error(t, mgmt.InitializeCache(d))
}) })
*/
} }
func TestManagement_GetNEP17Contracts(t *testing.T) { func TestManagement_GetNEP17Contracts(t *testing.T) {