From 71a89c230ac70e9fbb3664f41ca99967fb1653f7 Mon Sep 17 00:00:00 2001 From: Ekaterina Pavlova Date: Thu, 14 Nov 2024 15:49:00 +0300 Subject: [PATCH] *: remove range usage from smartcontracts Reverting a part of 1b83dc2, because ranging over integers is not supported by smart contract compiler, ref. #3525. Close #3671 Signed-off-by: Ekaterina Pavlova --- .../testdata/storage/storage_contract.go | 2 +- pkg/services/rpcsrv/server_test.go | 30 +++++++++--------- pkg/services/rpcsrv/testdata/testblocks.acc | Bin 35787 -> 35704 bytes 3 files changed, 16 insertions(+), 16 deletions(-) diff --git a/internal/basicchain/testdata/storage/storage_contract.go b/internal/basicchain/testdata/storage/storage_contract.go index 338e28a0f..f98772b8e 100644 --- a/internal/basicchain/testdata/storage/storage_contract.go +++ b/internal/basicchain/testdata/storage/storage_contract.go @@ -19,7 +19,7 @@ var valuesPrefix = []byte{0x01} func _deploy(data any, isUpdate bool) { if !isUpdate { ctx := storage.GetContext() - for i := range valuesCount { + for i := 0; i < valuesCount; i++ { key := append(valuesPrefix, byte(i)) storage.Put(ctx, key, i) } diff --git a/pkg/services/rpcsrv/server_test.go b/pkg/services/rpcsrv/server_test.go index 51bf37e68..127fa0a6f 100644 --- a/pkg/services/rpcsrv/server_test.go +++ b/pkg/services/rpcsrv/server_test.go @@ -74,22 +74,22 @@ type rpcTestCase struct { } const genesisBlockHash = "0f8fb4e17d2ab9f3097af75ca7fd16064160fb8043db94909e00dd4e257b9dc4" -const testContractHash = "565cff9508ebc75aadd7fe59f38dac610ab6093c" -const deploymentTxHash = "a14390941cc3a1d87393eff720a722e9cd350bd6ed233c5fe2001326c80eb68e" +const testContractHash = "449fe8fbd4523072f5e3a4dfa17a494c119d4c08" +const deploymentTxHash = "bbb8ec059dd320dc9de5a8fb8c75351d8e369fca0256f7a6bdb623dcf71861ed" const ( verifyContractHash = "06ed5314c2e4cb103029a60b86d46afa2fb8f67c" verifyContractAVM = "VwIAQS1RCDBwDBTunqIsJ+NL0BSPxBCOCPdOj1BIskrZMCQE2zBxaBPOStkoJATbKGlK2SgkBNsol0A=" - verifyWithArgsContractHash = "4dc916254efd2947c93b11207e8ffc0bb56161c5" - nnsContractHash = "892429fcd47c30f8451781acc627e8b20e0d64f3" + verifyWithArgsContractHash = "6261b3bf753bdc3d24c1327a23fd891e1c8a7ccd" + nnsContractHash = "450d1918a72fef97b48096bfec8d749961deef55" nnsToken1ID = "6e656f2e636f6d" - nfsoContractHash = "730ebe719ab8e3b69d11dafc95cdb9bf409db179" + nfsoContractHash = "2f5c1826bb4da1c764a8871427e4044cf3e82dbd" nfsoToken1ID = "7e244ffd6aa85fb1579d2ed22e9b761ab62e3486" storageContractHash = "ebc0c16a76c808cd4dde6bcc063f09e45e331ec7" faultedTxHashLE = "82279bfe9bada282ca0f8cb8e0bb124b921af36f00c69a518320322c6f4fef60" faultedTxBlock uint32 = 23 invokescriptContractAVM = "VwIADBQBDAMOBQYMDQIODw0DDgcJAAAAAErZMCQE2zBwaEH4J+yMqiYEEUAMFA0PAwIJAAIBAwcDBAUCAQAOBgwJStkwJATbMHFpQfgn7IyqJgQSQBNA" - block20StateRootLE = "858c873539d6d24a70f2be13f9dafc61aef2b63c2aa16bb440676de6e44e3cf1" + block20StateRootLE = "7e411d227a41b760e3c0309e12eb35c01064ffec59d237fcc495a69e97d8c033" ) var ( @@ -1386,7 +1386,7 @@ var rpcTestCases = map[string][]rpcTestCase{ script = append(script, 0x41, 0x62, 0x7d, 0x5b, 0x52) return &result.Invoke{ State: "HALT", - GasConsumed: 31922970, + GasConsumed: 31922730, Script: script, Stack: []stackitem.Item{stackitem.Make(true)}, Notifications: []state.NotificationEvent{{ @@ -1416,7 +1416,7 @@ var rpcTestCases = map[string][]rpcTestCase{ chg := []dboper.Operation{{ State: "Changed", Key: []byte{0xfa, 0xff, 0xff, 0xff, 0xb}, - Value: []byte{0x54, 0xb2, 0xd2, 0xa3, 0x51, 0x79, 0x12}, + Value: []byte{0xba, 0xaa, 0x3d, 0x19, 0x5e, 0x79, 0x12}, }, { State: "Added", Key: []byte{0xfb, 0xff, 0xff, 0xff, 0x14, 0xd6, 0x24, 0x87, 0x12, 0xff, 0x97, 0x22, 0x80, 0xa0, 0xae, 0xf5, 0x24, 0x1c, 0x96, 0x4d, 0x63, 0x78, 0x29, 0xcd, 0xb}, @@ -1428,7 +1428,7 @@ var rpcTestCases = map[string][]rpcTestCase{ }, { State: "Changed", Key: []byte{0xfa, 0xff, 0xff, 0xff, 0x14, 0xee, 0x9e, 0xa2, 0x2c, 0x27, 0xe3, 0x4b, 0xd0, 0x14, 0x8f, 0xc4, 0x10, 0x8e, 0x8, 0xf7, 0x4e, 0x8f, 0x50, 0x48, 0xb2}, - Value: []byte{0x41, 0x01, 0x21, 0x05, 0x0c, 0x76, 0x4f, 0xdf, 0x08}, + Value: []byte{0x41, 0x01, 0x21, 0x05, 0x52, 0xb0, 0xbb, 0x54, 0x15}, }} // Can be returned in any order. assert.ElementsMatch(t, chg, res.Diagnostics.Changes) @@ -1444,7 +1444,7 @@ var rpcTestCases = map[string][]rpcTestCase{ cryptoHash, _ := e.chain.GetNativeContractScriptHash(nativenames.CryptoLib) return &result.Invoke{ State: "HALT", - GasConsumed: 13970250, + GasConsumed: 13969170, Script: script, Stack: []stackitem.Item{stackitem.Make("1.2.3.4")}, Notifications: []state.NotificationEvent{}, @@ -1537,7 +1537,7 @@ var rpcTestCases = map[string][]rpcTestCase{ script = append(script, 0x41, 0x62, 0x7d, 0x5b, 0x52) return &result.Invoke{ State: "HALT", - GasConsumed: 31922970, + GasConsumed: 31922730, Script: script, Stack: []stackitem.Item{stackitem.Make(true)}, Notifications: []state.NotificationEvent{{ @@ -1563,7 +1563,7 @@ var rpcTestCases = map[string][]rpcTestCase{ cryptoHash, _ := e.chain.GetNativeContractScriptHash(nativenames.CryptoLib) return &result.Invoke{ State: "HALT", - GasConsumed: 13970250, + GasConsumed: 13969170, Script: script, Stack: []stackitem.Item{stackitem.Make("1.2.3.4")}, Notifications: []state.NotificationEvent{}, @@ -3265,7 +3265,7 @@ func testRPCProtocol(t *testing.T, doRPCCall func(string, string, *testing.T) [] t.Run("contract-based verification with parameters", func(t *testing.T) { verAcc, err := util.Uint160DecodeStringLE(verifyWithArgsContractHash) require.NoError(t, err) - checkContract(t, verAcc, []byte{}, 244130) // No C# match, but we believe it's OK and it differs from the one above. + checkContract(t, verAcc, []byte{}, 244010) // No C# match, but we believe it's OK and it differs from the one above. }) t.Run("contract-based verification with invocation script", func(t *testing.T) { verAcc, err := util.Uint160DecodeStringLE(verifyWithArgsContractHash) @@ -3275,7 +3275,7 @@ func testRPCProtocol(t *testing.T, doRPCCall func(string, string, *testing.T) [] emit.Int(invocWriter.BinWriter, 5) emit.String(invocWriter.BinWriter, "") invocScript := invocWriter.Bytes() - checkContract(t, verAcc, invocScript, 146960) // No C# match, but we believe it's OK and it has a specific invocation script overriding anything server-side. + checkContract(t, verAcc, invocScript, 146840) // No C# match, but we believe it's OK and it has a specific invocation script overriding anything server-side. }) t.Run("execution limit, ok", func(t *testing.T) { // 1_4000_0000 GAS with the default 1.5 allowed by Policy @@ -3580,7 +3580,7 @@ func checkNep17Balances(t *testing.T, e *executor, acc any) { }, { Asset: e.chain.UtilityTokenHash(), - Amount: "37106285100", + Amount: "90615919730", LastUpdated: 23, Decimals: 8, Name: "GasToken", diff --git a/pkg/services/rpcsrv/testdata/testblocks.acc b/pkg/services/rpcsrv/testdata/testblocks.acc index 173d18a8ce8bfe5999e3e205b0cb30e1e021a1eb..2a0707f0a1f72f101e32907404814c077adb9162 100644 GIT binary patch delta 10703 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 BdoBO~ delta 10839 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 VJoH5C-GdU3trmhQfr&eh{};Ybv0nfH