From aa3a5fc4920bbf20996a36d3cfe522978be1858b Mon Sep 17 00:00:00 2001 From: Anna Shaleva Date: Wed, 22 Jun 2022 13:23:55 +0300 Subject: [PATCH] rpc: adjust script creation with empty parameters list Always use NEWARRAY0 where possible, see https://github.com/neo-project/neo/blob/26d04a642ac5a1dd1827dabf5602767e0acba25c/src/neo/VM/Helper.cs#L41. Compatibility is tested: ``` anna@kiwi:~/Documents/GitProjects/nspcc-dev/neo-go$ curl -d '{ "jsonrpc": "2.0", "id": 1, "method": "invokefunction", "params": ["50befd26fdf6e4d957c11e078b24ebce6291456f", "a", [] ]}' seed1.neo.org:10332 | json_pp % Total % Received % Xferd Average Speed Time Time Time Current Dload Upload Total Spent Left Speed 100 370 0 248 100 122 127 62 0:00:01 0:00:01 --:--:-- 190 { "result" : { "notifications" : [], "stack" : [], "script" : "wh8MAWEMFG9FkWLO6ySLBx7BV9nk9v0m/b5QQWJ9W1I=", "gasconsumed" : "98403", "state" : "FAULT", "exception" : "Called Contract Does Not Exist: 0x50befd26fdf6e4d957c11e078b24ebce6291456f" }, "jsonrpc" : "2.0", "id" : 1 } ``` --- pkg/rpc/request/txBuilder.go | 24 ++++++++++++++++++------ pkg/rpc/request/tx_builder_test.go | 2 +- 2 files changed, 19 insertions(+), 7 deletions(-) diff --git a/pkg/rpc/request/txBuilder.go b/pkg/rpc/request/txBuilder.go index ef204d921..84215314d 100644 --- a/pkg/rpc/request/txBuilder.go +++ b/pkg/rpc/request/txBuilder.go @@ -83,12 +83,10 @@ func ExpandArrayIntoScript(script *io.BinWriter, slice []Param) error { if err != nil { return err } - err = ExpandArrayIntoScript(script, val) + err = ExpandArrayIntoScriptAndPack(script, val) if err != nil { return err } - emit.Int(script, int64(len(val))) - emit.Opcodes(script, opcode.PACK) case smartcontract.AnyType: if fp.Value.IsNull() { emit.Opcodes(script, opcode.PUSHNULL) @@ -100,6 +98,22 @@ func ExpandArrayIntoScript(script *io.BinWriter, slice []Param) error { return script.Err } +// ExpandArrayIntoScriptAndPack expands provided array into script and packs the +// resulting items in the array. +func ExpandArrayIntoScriptAndPack(script *io.BinWriter, slice []Param) error { + if len(slice) == 0 { + emit.Opcodes(script, opcode.NEWARRAY0) + return script.Err + } + err := ExpandArrayIntoScript(script, slice) + if err != nil { + return err + } + emit.Int(script, int64(len(slice))) + emit.Opcodes(script, opcode.PACK) + return script.Err +} + // CreateFunctionInvocationScript creates a script to invoke the given contract with // the given parameters. func CreateFunctionInvocationScript(contract util.Uint160, method string, param *Param) ([]byte, error) { @@ -107,12 +121,10 @@ func CreateFunctionInvocationScript(contract util.Uint160, method string, param if param == nil { emit.Opcodes(script.BinWriter, opcode.NEWARRAY0) } else if slice, err := param.GetArray(); err == nil { - err = ExpandArrayIntoScript(script.BinWriter, slice) + err = ExpandArrayIntoScriptAndPack(script.BinWriter, slice) if err != nil { return nil, err } - emit.Int(script.BinWriter, int64(len(slice))) - emit.Opcodes(script.BinWriter, opcode.PACK) } else { return nil, fmt.Errorf("failed to convert %s to script parameter", param) } diff --git a/pkg/rpc/request/tx_builder_test.go b/pkg/rpc/request/tx_builder_test.go index 64a46370c..55e450398 100644 --- a/pkg/rpc/request/tx_builder_test.go +++ b/pkg/rpc/request/tx_builder_test.go @@ -29,7 +29,7 @@ func TestInvocationScriptCreationGood(t *testing.T) { script: "wh8MAjQyDBRvRZFizuskiwcewVfZ5Pb9Jv2+UEFifVtS", }, { ps: Params{{RawMessage: []byte(`"a"`)}, {RawMessage: []byte(`[]`)}}, - script: "EMAfDAFhDBRvRZFizuskiwcewVfZ5Pb9Jv2+UEFifVtS", + script: "wh8MAWEMFG9FkWLO6ySLBx7BV9nk9v0m/b5QQWJ9W1I=", }, { ps: Params{{RawMessage: []byte(`"a"`)}, {RawMessage: []byte(`[{"type": "ByteString", "value": "AwEtR+diEK7HO+Oas9GG4KQP6Nhr+j1Pq/2le6E7iPlq"}]`)}}, script: "DCEDAS1H52IQrsc745qz0YbgpA/o2Gv6PU+r/aV7oTuI+WoRwB8MAWEMFG9FkWLO6ySLBx7BV9nk9v0m/b5QQWJ9W1I=",