From 822722bd2e8ed0b923d704227a06f538db0ab851 Mon Sep 17 00:00:00 2001 From: Roman Khimov Date: Wed, 16 Nov 2022 11:36:04 +0300 Subject: [PATCH] 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. --- pkg/core/blockchain_neotest_test.go | 2 ++ pkg/core/native/management.go | 12 +++--------- pkg/core/native/management_test.go | 2 ++ 3 files changed, 7 insertions(+), 9 deletions(-) diff --git a/pkg/core/blockchain_neotest_test.go b/pkg/core/blockchain_neotest_test.go index 7ab6c53a2..4cf2f8137 100644 --- a/pkg/core/blockchain_neotest_test.go +++ b/pkg/core/blockchain_neotest_test.go @@ -207,6 +207,7 @@ func TestBlockchain_StartFromExistingDB(t *testing.T) { require.Error(t, 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) { ps = newPS(t) @@ -223,6 +224,7 @@ func TestBlockchain_StartFromExistingDB(t *testing.T) { require.Error(t, 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) { ps = newPS(t) _, _, _, err := chain.NewMultiWithCustomConfigAndStoreNoCheck(t, func(c *config.ProtocolConfiguration) { diff --git a/pkg/core/native/management.go b/pkg/core/native/management.go index 444cf07fd..faa2d4e4a 100644 --- a/pkg/core/native/management.go +++ b/pkg/core/native/management.go @@ -539,19 +539,13 @@ func (m *Management) InitializeCache(d *dao.Simple) error { nep17: make(map[util.Uint160]struct{}), } - var initErr error - d.Seek(m.ID, storage.SeekRange{Prefix: []byte{PrefixContract}}, func(_, v []byte) bool { + d.Seek(m.ID, storage.SeekRange{Prefix: []byte{PrefixContract}}, func(k, v []byte) bool { var cs = new(state.Contract) - initErr = stackitem.DeserializeConvertible(v, cs) - if initErr != nil { - return false + if stackitem.DeserializeConvertible(v, cs) == nil { + updateContractCache(cache, cs) } - updateContractCache(cache, cs) return true }) - if initErr != nil { - return initErr - } d.SetCache(m.ID, cache) return nil } diff --git a/pkg/core/native/management_test.go b/pkg/core/native/management_test.go index 123e67f3a..2b3a71df5 100644 --- a/pkg/core/native/management_test.go +++ b/pkg/core/native/management_test.go @@ -78,12 +78,14 @@ func TestManagement_Initialize(t *testing.T) { mgmt := newManagement() require.NoError(t, mgmt.InitializeCache(d)) }) + /* See #2801 t.Run("invalid contract state", func(t *testing.T) { d := dao.NewSimple(storage.NewMemoryStore(), false, false) mgmt := newManagement() d.PutStorageItem(mgmt.ID, []byte{PrefixContract}, state.StorageItem{0xFF}) require.Error(t, mgmt.InitializeCache(d)) }) + */ } func TestManagement_GetNEP17Contracts(t *testing.T) {