From 236e633ee488889a63f59ac9649cbfc10e4783d3 Mon Sep 17 00:00:00 2001 From: Roman Khimov Date: Wed, 7 Dec 2022 15:13:17 +0300 Subject: [PATCH] native: make management compatible with C# node 3.5.0 It doesn't store id->hash mappings for native contracts. We need blockchain's GetContractScriptHash to serve both anyway, so it was changed a bit. The only other direct user of native.GetContractScriptHash is the VM CLI, but I doubt anyone will use it for native contracts (they have ~zero VM code anyway). --- pkg/core/blockchain.go | 8 ++++++++ pkg/core/native/management.go | 6 ++++-- pkg/core/native/native_test/management_test.go | 2 ++ pkg/services/rpcsrv/client_test.go | 3 ++- pkg/services/rpcsrv/server_test.go | 2 +- 5 files changed, 17 insertions(+), 4 deletions(-) diff --git a/pkg/core/blockchain.go b/pkg/core/blockchain.go index 3b3fd0770..e751ca666 100644 --- a/pkg/core/blockchain.go +++ b/pkg/core/blockchain.go @@ -2091,6 +2091,14 @@ func (bc *Blockchain) GetContractState(hash util.Uint160) *state.Contract { // GetContractScriptHash returns contract script hash by its ID. func (bc *Blockchain) GetContractScriptHash(id int32) (util.Uint160, error) { + if id < 0 { + for _, n := range bc.contracts.Contracts { + nc := n.Metadata().NativeContract + if nc.ID == id { + return nc.Hash, nil + } + } + } return native.GetContractScriptHash(bc.dao, id) } diff --git a/pkg/core/native/management.go b/pkg/core/native/management.go index 2b26ad36f..c56159398 100644 --- a/pkg/core/native/management.go +++ b/pkg/core/native/management.go @@ -688,8 +688,10 @@ func putContractState(d *dao.Simple, cs *state.Contract, updateCache bool) error if cs.UpdateCounter != 0 { // Update. return nil } - key = putHashKey(key, cs.ID) - d.PutStorageItem(ManagementContractID, key, cs.Hash.BytesBE()) + if cs.ID > 0 { + key = putHashKey(key, cs.ID) + d.PutStorageItem(ManagementContractID, key, cs.Hash.BytesBE()) + } return nil } diff --git a/pkg/core/native/native_test/management_test.go b/pkg/core/native/native_test/management_test.go index 22b8669d6..dd5535cdb 100644 --- a/pkg/core/native/native_test/management_test.go +++ b/pkg/core/native/native_test/management_test.go @@ -566,6 +566,7 @@ func TestManagement_GetContract(t *testing.T) { t.Run("by ID, positive", func(t *testing.T) { managementInvoker.Invoke(t, si, "getContractById", cs1.ID) }) + /* C# compatibility t.Run("by ID, native", func(t *testing.T) { csm := managementInvoker.Executor.Chain.GetContractState(managementInvoker.Hash) require.NotNil(t, csm) @@ -573,6 +574,7 @@ func TestManagement_GetContract(t *testing.T) { require.NoError(t, err) managementInvoker.Invoke(t, sim, "getContractById", -1) }) + */ t.Run("by ID, empty", func(t *testing.T) { managementInvoker.Invoke(t, stackitem.Null{}, "getContractById", -100) }) diff --git a/pkg/services/rpcsrv/client_test.go b/pkg/services/rpcsrv/client_test.go index e80eacc2c..c36b2023f 100644 --- a/pkg/services/rpcsrv/client_test.go +++ b/pkg/services/rpcsrv/client_test.go @@ -256,10 +256,11 @@ func TestClientManagementContract(t *testing.T) { cs2, err := c.GetContractStateByHash(gas.Hash) require.NoError(t, err) require.Equal(t, cs2, cs1) + /* C# compat cs1, err = manReader.GetContractByID(-6) require.NoError(t, err) require.Equal(t, cs2, cs1) - + */ ret, err := manReader.HasMethod(gas.Hash, "transfer", 4) require.NoError(t, err) require.True(t, ret) diff --git a/pkg/services/rpcsrv/server_test.go b/pkg/services/rpcsrv/server_test.go index 19b22b244..a6851a841 100644 --- a/pkg/services/rpcsrv/server_test.go +++ b/pkg/services/rpcsrv/server_test.go @@ -82,7 +82,7 @@ const ( faultedTxHashLE = "82279bfe9bada282ca0f8cb8e0bb124b921af36f00c69a518320322c6f4fef60" faultedTxBlock uint32 = 23 invokescriptContractAVM = "VwIADBQBDAMOBQYMDQIODw0DDgcJAAAAAErZMCQE2zBwaEH4J+yMqiYEEUAMFA0PAwIJAAIBAwcDBAUCAQAOBgwJStkwJATbMHFpQfgn7IyqJgQSQBNA" - block20StateRootLE = "13620fef0fb28060523a0b73ce574ee4658fca5d0d24078a73e74a349c37a854" + block20StateRootLE = "811a287a0235cfb3c7def100ae7029335a10e8b90d0ca59c460955c0546a0414" ) var (