From c0e482fe6cb441bd32b6d2902dfabe35f04726aa Mon Sep 17 00:00:00 2001 From: Evgenii Stratonikov Date: Thu, 18 Jun 2020 22:56:42 +0300 Subject: [PATCH 1/8] rpc: restructure `getapplicationlog` response Move VM-related fields to top-level. --- pkg/rpc/client/rpc_test.go | 23 +++++++--------------- pkg/rpc/client/wsclient_test.go | 4 ++-- pkg/rpc/response/result/application_log.go | 23 +++++----------------- pkg/rpc/server/server.go | 12 ++--------- pkg/rpc/server/server_test.go | 5 ++--- pkg/rpc/server/subscription.go | 2 +- pkg/rpc/server/subscription_test.go | 4 +--- 7 files changed, 20 insertions(+), 53 deletions(-) diff --git a/pkg/rpc/client/rpc_test.go b/pkg/rpc/client/rpc_test.go index bdfd08d67..f023be82c 100644 --- a/pkg/rpc/client/rpc_test.go +++ b/pkg/rpc/client/rpc_test.go @@ -103,28 +103,19 @@ var rpcClientTestCases = map[string][]rpcClientTestCase{ invoke: func(c *Client) (interface{}, error) { return c.GetApplicationLog(util.Uint256{}) }, - serverResponse: `{"id":1,"jsonrpc":"2.0","result":{"txid":"0x17145a039fca704fcdbeb46e6b210af98a1a9e5b9768e46ffc38f71c79ac2521","executions":[{"trigger":"Application","contract":"0xb9fa3b421eb749d5dd585fe1c1133b311a14bcb1","vmstate":"HALT","gas_consumed":"1","stack":[{"type":"Integer","value":1}],"notifications":[]}]}}`, + serverResponse: `{"id":1,"jsonrpc":"2.0","result":{"txid":"0x17145a039fca704fcdbeb46e6b210af98a1a9e5b9768e46ffc38f71c79ac2521","trigger":"Application","vmstate":"HALT","gas_consumed":"1","stack":[{"type":"Integer","value":1}],"notifications":[]}}`, result: func(c *Client) interface{} { txHash, err := util.Uint256DecodeStringLE("17145a039fca704fcdbeb46e6b210af98a1a9e5b9768e46ffc38f71c79ac2521") if err != nil { panic(err) } - scriptHash, err := util.Uint160DecodeStringLE("b9fa3b421eb749d5dd585fe1c1133b311a14bcb1") - if err != nil { - panic(err) - } return &result.ApplicationLog{ - TxHash: txHash, - Executions: []result.Execution{ - { - Trigger: "Application", - ScriptHash: scriptHash, - VMState: "HALT", - GasConsumed: util.Fixed8FromInt64(1), - Stack: []smartcontract.Parameter{{Type: smartcontract.IntegerType, Value: int64(1)}}, - Events: []result.NotificationEvent{}, - }, - }, + TxHash: txHash, + Trigger: "Application", + VMState: "HALT", + GasConsumed: util.Fixed8FromInt64(1), + Stack: []smartcontract.Parameter{{Type: smartcontract.IntegerType, Value: int64(1)}}, + Events: []result.NotificationEvent{}, } }, }, diff --git a/pkg/rpc/client/wsclient_test.go b/pkg/rpc/client/wsclient_test.go index 17693093e..f2221a675 100644 --- a/pkg/rpc/client/wsclient_test.go +++ b/pkg/rpc/client/wsclient_test.go @@ -116,9 +116,9 @@ func TestWSClientEvents(t *testing.T) { var ok bool // Events from RPC server test chain. var events = []string{ - `{"jsonrpc":"2.0","method":"transaction_executed","params":[{"txid":"0xe1cd5e57e721d2a2e05fb1f08721b12057b25ab1dd7fd0f33ee1639932fdfad7","executions":[{"trigger":"Application","contract":"0x0000000000000000000000000000000000000000","vmstate":"HALT","gas_consumed":"2.291","stack":[],"notifications":[{"contract":"0x1b4357bff5a01bdf2a6581247cf9ed1e24629176","state":{"type":"Array","value":[{"type":"ByteArray","value":"Y29udHJhY3QgY2FsbA=="},{"type":"ByteArray","value":"dHJhbnNmZXI="},{"type":"Array","value":[{"type":"ByteArray","value":"dpFiJB7t+XwkgWUq3xug9b9XQxs="},{"type":"ByteArray","value":"MW6FEDkBnTnfwsN9bD/uGf1YCYc="},{"type":"Integer","value":"1000"}]}]}},{"contract":"0x1b4357bff5a01bdf2a6581247cf9ed1e24629176","state":{"type":"Array","value":[{"type":"ByteArray","value":"dHJhbnNmZXI="},{"type":"ByteArray","value":"dpFiJB7t+XwkgWUq3xug9b9XQxs="},{"type":"ByteArray","value":"MW6FEDkBnTnfwsN9bD/uGf1YCYc="},{"type":"Integer","value":"1000"}]}}]}]}]}`, + `{"jsonrpc":"2.0","method":"transaction_executed","params":[{"txid":"0xe1cd5e57e721d2a2e05fb1f08721b12057b25ab1dd7fd0f33ee1639932fdfad7","trigger":"Application","vmstate":"HALT","gas_consumed":"2.291","stack":[],"notifications":[{"contract":"0x1b4357bff5a01bdf2a6581247cf9ed1e24629176","state":{"type":"Array","value":[{"type":"ByteArray","value":"Y29udHJhY3QgY2FsbA=="},{"type":"ByteArray","value":"dHJhbnNmZXI="},{"type":"Array","value":[{"type":"ByteArray","value":"dpFiJB7t+XwkgWUq3xug9b9XQxs="},{"type":"ByteArray","value":"MW6FEDkBnTnfwsN9bD/uGf1YCYc="},{"type":"Integer","value":"1000"}]}]}},{"contract":"0x1b4357bff5a01bdf2a6581247cf9ed1e24629176","state":{"type":"Array","value":[{"type":"ByteArray","value":"dHJhbnNmZXI="},{"type":"ByteArray","value":"dpFiJB7t+XwkgWUq3xug9b9XQxs="},{"type":"ByteArray","value":"MW6FEDkBnTnfwsN9bD/uGf1YCYc="},{"type":"Integer","value":"1000"}]}}]}]}`, `{"jsonrpc":"2.0","method":"notification_from_execution","params":[{"contract":"0x1b4357bff5a01bdf2a6581247cf9ed1e24629176","state":{"type":"Array","value":[{"type":"ByteArray","value":"Y29udHJhY3QgY2FsbA=="},{"type":"ByteArray","value":"dHJhbnNmZXI="},{"type":"Array","value":[{"type":"ByteArray","value":"dpFiJB7t+XwkgWUq3xug9b9XQxs="},{"type":"ByteArray","value":"MW6FEDkBnTnfwsN9bD/uGf1YCYc="},{"type":"Integer","value":"1000"}]}]}}]}`, - `{"jsonrpc":"2.0","method":"transaction_executed","params":[{"txid":"0xf97a72b7722c109f909a8bc16c22368c5023d85828b09b127b237aace33cf099","executions":[{"trigger":"Application","contract":"0x0000000000000000000000000000000000000000","vmstate":"HALT","gas_consumed":"0.0604261","stack":[],"notifications":[{"contract":"0xe65ff7b3a02d207b584a5c27057d4e9862ef01da","state":{"type":"Array","value":[{"type":"ByteArray","value":"Y29udHJhY3QgY2FsbA=="},{"type":"ByteArray","value":"dHJhbnNmZXI="},{"type":"Array","value":[{"type":"ByteArray","value":"MW6FEDkBnTnfwsN9bD/uGf1YCYc="},{"type":"ByteArray","value":"IHKCdK+vw29DoHHTKM+j5inZy7A="},{"type":"Integer","value":"123"}]}]}},{"contract":"0xe65ff7b3a02d207b584a5c27057d4e9862ef01da","state":{"type":"Array","value":[{"type":"ByteArray","value":"dHJhbnNmZXI="},{"type":"ByteArray","value":"MW6FEDkBnTnfwsN9bD/uGf1YCYc="},{"type":"ByteArray","value":"IHKCdK+vw29DoHHTKM+j5inZy7A="},{"type":"Integer","value":"123"}]}}]}]}]}`, + `{"jsonrpc":"2.0","method":"transaction_executed","params":[{"txid":"0xf97a72b7722c109f909a8bc16c22368c5023d85828b09b127b237aace33cf099","trigger":"Application","vmstate":"HALT","gas_consumed":"0.0604261","stack":[],"notifications":[{"contract":"0xe65ff7b3a02d207b584a5c27057d4e9862ef01da","state":{"type":"Array","value":[{"type":"ByteArray","value":"Y29udHJhY3QgY2FsbA=="},{"type":"ByteArray","value":"dHJhbnNmZXI="},{"type":"Array","value":[{"type":"ByteArray","value":"MW6FEDkBnTnfwsN9bD/uGf1YCYc="},{"type":"ByteArray","value":"IHKCdK+vw29DoHHTKM+j5inZy7A="},{"type":"Integer","value":"123"}]}]}},{"contract":"0xe65ff7b3a02d207b584a5c27057d4e9862ef01da","state":{"type":"Array","value":[{"type":"ByteArray","value":"dHJhbnNmZXI="},{"type":"ByteArray","value":"MW6FEDkBnTnfwsN9bD/uGf1YCYc="},{"type":"ByteArray","value":"IHKCdK+vw29DoHHTKM+j5inZy7A="},{"type":"Integer","value":"123"}]}}]}]}`, `{"jsonrpc":"2.0","method":"block_added","params":[{"hash":"0x2d312f6379ead13cf62634c703091b750e7903728df2a3cf5bd96ce80b84a849","version":0,"previousblockhash":"0xb8237d34c156cac6be7b01578decf8ac8c99a62f0b6f774d622aad7be0fe189d","merkleroot":"0xf89169e89361692b71e671f13c088e84c5325015c413e8f89e7ba38efdb41287","time":1592472500006,"index":6,"nextconsensus":"Nbb1qkwcwNSBs9pAnrVVrnFbWnbWBk91U2","witnesses":[{"invocation":"DEDblVguNGXWbUswDvBfVJzBt76BJyJ0Ga6siquyjioGn4Dbr6zy1IvcLl3xN5akcejRy9e+Mr1qvpe/gkLgtW4QDEDRwPISZagMFjE/plXTnZ/gEU0IbBAAe23U29zVWteUmzRsPxF/MdzXvdffR9W0edkj17AmkWpn+5rqzH9aCOpLDECEvjgxZaRoAHEDNzp1REllLcGzMwrwSjudtzfgRglQL3g1BKerDx6cGHH73medRVkL9QVm4KzSxlywVtvhwBMrDEBuPKvzg5TtakFW2jr/bfmy1bn2FiLARlOySwaGdKRV93ozA5lVEIAvHbBlJtT4/5H8jHjbncXXMrP3OUHqebZz","verification":"EwwhAhA6f33QFlWFl/eWDSfFFqQ5T9loueZRVetLAT5AQEBuDCECp7xV/oaE4BGXaNEEujB5W9zIZhnoZK3SYVZyPtGFzWIMIQKzYiv0AXvf4xfFiu1fTHU/IGt9uJYEb6fXdLvEv3+NwgwhA9kMB99j5pDOd5EuEKtRrMlEtmhgI3tgjE+PgwnnHuaZFAtBMHOzuw=="}],"consensus_data":{"primary":0,"nonce":"0000000000000457"},"tx":[{"txid":"0xf97a72b7722c109f909a8bc16c22368c5023d85828b09b127b237aace33cf099","size":265,"version":0,"nonce":9,"sender":"NQRLhCpAru9BjGsMwk67vdMwmzKMRgsnnN","sys_fee":"0","net_fee":"0.0036521","valid_until_block":1200,"attributes":[],"cosigners":[{"account":"0x870958fd19ee3f6c7dc3c2df399d013910856e31","scopes":"CalledByEntry"}],"script":"AHsMFCBygnSvr8NvQ6Bx0yjPo+Yp2cuwDBQxboUQOQGdOd/Cw31sP+4Z/VgJhxPADAh0cmFuc2ZlcgwU2gHvYphOfQUnXEpYeyAtoLP3X+ZBYn1bUjg=","scripts":[{"invocation":"DECwklSj3liZOJbktRtkVdUCu8U2LQlrU6Dv8NtMgd0xXbk5lXjc2p68xv6xtJXbJ4aoFMJZ9lkcNpGoeUCcaCet","verification":"DCECs2Ir9AF73+MXxYrtX0x1PyBrfbiWBG+n13S7xL9/jcILQQqQatQ="}]}]}]}`, `{"jsonrpc":"2.0","method":"event_missed","params":[]}`, } diff --git a/pkg/rpc/response/result/application_log.go b/pkg/rpc/response/result/application_log.go index 8852cb773..b4bbd24aa 100644 --- a/pkg/rpc/response/result/application_log.go +++ b/pkg/rpc/response/result/application_log.go @@ -10,14 +10,8 @@ import ( // ApplicationLog wrapper used for the representation of the // state.AppExecResult based on the specific tx on the RPC Server. type ApplicationLog struct { - TxHash util.Uint256 `json:"txid"` - Executions []Execution `json:"executions"` -} - -// Execution response wrapper -type Execution struct { + TxHash util.Uint256 `json:"txid"` Trigger string `json:"trigger"` - ScriptHash util.Uint160 `json:"contract"` VMState string `json:"vmstate"` GasConsumed util.Fixed8 `json:"gas_consumed"` Stack []smartcontract.Parameter `json:"stack"` @@ -42,25 +36,18 @@ func StateEventToResultNotification(event state.NotificationEvent) NotificationE } // NewApplicationLog creates a new ApplicationLog wrapper. -func NewApplicationLog(appExecRes *state.AppExecResult, scriptHash util.Uint160) ApplicationLog { +func NewApplicationLog(appExecRes *state.AppExecResult) ApplicationLog { events := make([]NotificationEvent, 0, len(appExecRes.Events)) for _, e := range appExecRes.Events { events = append(events, StateEventToResultNotification(e)) } - triggerString := appExecRes.Trigger.String() - - executions := []Execution{{ - Trigger: triggerString, - ScriptHash: scriptHash, + return ApplicationLog{ + TxHash: appExecRes.TxHash, + Trigger: appExecRes.Trigger.String(), VMState: appExecRes.VMState, GasConsumed: appExecRes.GasConsumed, Stack: appExecRes.Stack, Events: events, - }} - - return ApplicationLog{ - TxHash: appExecRes.TxHash, - Executions: executions, } } diff --git a/pkg/rpc/server/server.go b/pkg/rpc/server/server.go index 898b1b61b..41676bcbc 100644 --- a/pkg/rpc/server/server.go +++ b/pkg/rpc/server/server.go @@ -19,7 +19,6 @@ import ( "github.com/nspcc-dev/neo-go/pkg/core/blockchainer" "github.com/nspcc-dev/neo-go/pkg/core/state" "github.com/nspcc-dev/neo-go/pkg/core/transaction" - "github.com/nspcc-dev/neo-go/pkg/crypto/hash" "github.com/nspcc-dev/neo-go/pkg/crypto/keys" "github.com/nspcc-dev/neo-go/pkg/encoding/address" "github.com/nspcc-dev/neo-go/pkg/encoding/bigint" @@ -497,14 +496,7 @@ func (s *Server) getApplicationLog(reqParams request.Params) (interface{}, *resp return nil, response.NewRPCError("Unknown transaction", "", nil) } - tx, _, err := s.chain.GetTransaction(txHash) - if err != nil { - return nil, response.NewRPCError("Error while getting transaction", "", nil) - } - - scriptHash := hash.Hash160(tx.Script) - - return result.NewApplicationLog(appExecResult, scriptHash), nil + return result.NewApplicationLog(appExecResult), nil } func (s *Server) getNEP5Balances(ps request.Params) (interface{}, *response.Error) { @@ -1153,7 +1145,7 @@ chloop: resp.Payload[0] = b case execution := <-s.executionCh: resp.Event = response.ExecutionEventID - resp.Payload[0] = result.NewApplicationLog(execution, util.Uint160{}) + resp.Payload[0] = result.NewApplicationLog(execution) case notification := <-s.notificationCh: resp.Event = response.NotificationEventID resp.Payload[0] = result.StateEventToResultNotification(*notification) diff --git a/pkg/rpc/server/server_test.go b/pkg/rpc/server/server_test.go index 7cd510479..755ab12fa 100644 --- a/pkg/rpc/server/server_test.go +++ b/pkg/rpc/server/server_test.go @@ -65,9 +65,8 @@ var rpcTestCases = map[string][]rpcTestCase{ expectedTxHash, err := util.Uint256DecodeStringLE(deploymentTxHash) require.NoError(t, err) assert.Equal(t, expectedTxHash, res.TxHash) - assert.Equal(t, 1, len(res.Executions)) - assert.Equal(t, "Application", res.Executions[0].Trigger) - assert.Equal(t, "HALT", res.Executions[0].VMState) + assert.Equal(t, "Application", res.Trigger) + assert.Equal(t, "HALT", res.VMState) }, }, { diff --git a/pkg/rpc/server/subscription.go b/pkg/rpc/server/subscription.go index 16433ce51..d4409e3e4 100644 --- a/pkg/rpc/server/subscription.go +++ b/pkg/rpc/server/subscription.go @@ -77,7 +77,7 @@ func (f *feed) Matches(r *response.Notification) bool { case response.ExecutionEventID: filt := f.filter.(request.ExecutionFilter) applog := r.Payload[0].(result.ApplicationLog) - return len(applog.Executions) != 0 && applog.Executions[0].VMState == filt.State + return applog.VMState == filt.State } return false } diff --git a/pkg/rpc/server/subscription_test.go b/pkg/rpc/server/subscription_test.go index 850b219de..01befb3e7 100644 --- a/pkg/rpc/server/subscription_test.go +++ b/pkg/rpc/server/subscription_test.go @@ -185,9 +185,7 @@ func TestFilteredSubscriptions(t *testing.T) { check: func(t *testing.T, resp *response.Notification) { rmap := resp.Payload[0].(map[string]interface{}) require.Equal(t, response.ExecutionEventID, resp.Event) - execs := rmap["executions"].([]interface{}) - exec0 := execs[0].(map[string]interface{}) - st := exec0["vmstate"].(string) + st := rmap["vmstate"].(string) require.Equal(t, "HALT", st) }, }, From a980cac0b3b76dd9a59b86f8d752f926c072d13f Mon Sep 17 00:00:00 2001 From: Evgenii Stratonikov Date: Thu, 18 Jun 2020 23:22:15 +0300 Subject: [PATCH 2/8] stackitem: support Null item (de-)serialization It's binary representation contains just type (AnyT). --- pkg/vm/stackitem/serialization.go | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/pkg/vm/stackitem/serialization.go b/pkg/vm/stackitem/serialization.go index e6cd51d90..17b3dec95 100644 --- a/pkg/vm/stackitem/serialization.go +++ b/pkg/vm/stackitem/serialization.go @@ -70,6 +70,8 @@ func serializeItemTo(item Item, w *io.BinWriter, seen map[Item]bool) { serializeItemTo(t.Value().([]MapElement)[i].Key, w, seen) serializeItemTo(t.Value().([]MapElement)[i].Value, w, seen) } + case Null: + w.WriteB(byte(AnyT)) } } @@ -127,6 +129,8 @@ func DecodeBinaryStackItem(r *io.BinReader) Item { m.Add(key, value) } return m + case AnyT: + return Null{} default: r.Err = errors.New("unknown type") return nil From 3a0be5ce282f7780f35c76d9fb8b33e2b29d7676 Mon Sep 17 00:00:00 2001 From: Evgenii Stratonikov Date: Thu, 18 Jun 2020 23:09:24 +0300 Subject: [PATCH 3/8] rpc: allow to invoke `getapplicationlog` with block hash Support retrieving native contract persist results by block hash. All necessary support is already here, just add test. --- pkg/rpc/server/server_test.go | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/pkg/rpc/server/server_test.go b/pkg/rpc/server/server_test.go index 755ab12fa..14729e5ed 100644 --- a/pkg/rpc/server/server_test.go +++ b/pkg/rpc/server/server_test.go @@ -823,6 +823,16 @@ func testRPCProtocol(t *testing.T, doRPCCall func(string, string, *testing.T) [] }) } + t.Run("getapplicationlog for block", func(t *testing.T) { + rpc := `{"jsonrpc": "2.0", "id": 1, "method": "getapplicationlog", "params": ["%s"]}` + body := doRPCCall(fmt.Sprintf(rpc, e.chain.GetHeaderHash(1).StringLE()), httpSrv.URL, t) + data := checkErrGetResult(t, body, false) + var res result.ApplicationLog + require.NoError(t, json.Unmarshal(data, &res)) + require.Equal(t, "System", res.Trigger) + require.Equal(t, "HALT", res.VMState) + }) + t.Run("submit", func(t *testing.T) { rpc := `{"jsonrpc": "2.0", "id": 1, "method": "submitblock", "params": ["%s"]}` t.Run("invalid signature", func(t *testing.T) { From b9e260a704a259e42a867514d1147fff5a3fe5ff Mon Sep 17 00:00:00 2001 From: Evgenii Stratonikov Date: Fri, 19 Jun 2020 10:44:05 +0300 Subject: [PATCH 4/8] smartcontract: omit empty value in JSON for Interop/Any parameters --- pkg/smartcontract/parameter.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pkg/smartcontract/parameter.go b/pkg/smartcontract/parameter.go index 4242cb08a..e3ce46f1e 100644 --- a/pkg/smartcontract/parameter.go +++ b/pkg/smartcontract/parameter.go @@ -53,7 +53,7 @@ func NewParameter(t ParamType) Parameter { type rawParameter struct { Type ParamType `json:"type"` - Value json.RawMessage `json:"value"` + Value json.RawMessage `json:"value,omitempty"` } // MarshalJSON implements Marshaler interface. @@ -88,7 +88,7 @@ func (p *Parameter) MarshalJSON() ([]byte, error) { ppair := p.Value.([]ParameterPair) resultRawValue, resultErr = json.Marshal(ppair) case InteropInterfaceType, AnyType: - resultRawValue = []byte("null") + resultRawValue = nil default: resultErr = errors.Errorf("Marshaller for type %s not implemented", p.Type) } From 81adb7ce832ce711006c84984e1f2491dc6debb9 Mon Sep 17 00:00:00 2001 From: Evgenii Stratonikov Date: Fri, 19 Jun 2020 11:09:38 +0300 Subject: [PATCH 5/8] core: set price getter for native contract persist routine --- pkg/core/blockchain.go | 1 + 1 file changed, 1 insertion(+) diff --git a/pkg/core/blockchain.go b/pkg/core/blockchain.go index 1d4c6de18..19531bca9 100644 --- a/pkg/core/blockchain.go +++ b/pkg/core/blockchain.go @@ -565,6 +565,7 @@ func (bc *Blockchain) storeBlock(block *block.Block) error { systemInterop := bc.newInteropContext(trigger.System, cache, block, nil) v := SpawnVM(systemInterop) v.LoadScriptWithFlags(bc.contracts.GetPersistScript(), smartcontract.AllowModifyStates|smartcontract.AllowCall) + v.SetPriceGetter(getPrice) if err := v.Run(); err != nil { return errors.Wrap(err, "can't persist native contracts") } else if _, err := systemInterop.DAO.Persist(); err != nil { From 6a2161207afcdcb699fc2ad9776e03959c1aa016 Mon Sep 17 00:00:00 2001 From: Evgenii Stratonikov Date: Fri, 19 Jun 2020 11:14:20 +0300 Subject: [PATCH 6/8] smartcontract: rename ByteArray to ByteString in JSON for smartcontract parameters --- pkg/smartcontract/param_type.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pkg/smartcontract/param_type.go b/pkg/smartcontract/param_type.go index 3c2ab38c1..4d0b45666 100644 --- a/pkg/smartcontract/param_type.go +++ b/pkg/smartcontract/param_type.go @@ -48,7 +48,7 @@ func (pt ParamType) String() string { case Hash256Type: return "Hash256" case ByteArrayType: - return "ByteArray" + return "ByteString" case PublicKeyType: return "PublicKey" case StringType: @@ -143,7 +143,7 @@ func ParseParamType(typ string) (ParamType, error) { return Hash160Type, nil case "hash256": return Hash256Type, nil - case "bytes", "bytearray": + case "bytes", "bytearray", "bytestring": return ByteArrayType, nil case "key", "publickey": return PublicKeyType, nil From 3787a8895eaed4412d4cf80941a238be2edd212a Mon Sep 17 00:00:00 2001 From: Evgenii Stratonikov Date: Fri, 19 Jun 2020 11:28:31 +0300 Subject: [PATCH 7/8] rpc: marshal GasConsumed `getapplicationlog` as string Also there is no more decimal point. --- pkg/rpc/client/rpc_test.go | 2 +- pkg/rpc/response/result/application_log.go | 6 ++++-- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/pkg/rpc/client/rpc_test.go b/pkg/rpc/client/rpc_test.go index f023be82c..1cc52f28b 100644 --- a/pkg/rpc/client/rpc_test.go +++ b/pkg/rpc/client/rpc_test.go @@ -113,7 +113,7 @@ var rpcClientTestCases = map[string][]rpcClientTestCase{ TxHash: txHash, Trigger: "Application", VMState: "HALT", - GasConsumed: util.Fixed8FromInt64(1), + GasConsumed: "1", Stack: []smartcontract.Parameter{{Type: smartcontract.IntegerType, Value: int64(1)}}, Events: []result.NotificationEvent{}, } diff --git a/pkg/rpc/response/result/application_log.go b/pkg/rpc/response/result/application_log.go index b4bbd24aa..d08eac7f2 100644 --- a/pkg/rpc/response/result/application_log.go +++ b/pkg/rpc/response/result/application_log.go @@ -1,6 +1,8 @@ package result import ( + "strconv" + "github.com/nspcc-dev/neo-go/pkg/core/state" "github.com/nspcc-dev/neo-go/pkg/smartcontract" "github.com/nspcc-dev/neo-go/pkg/util" @@ -13,7 +15,7 @@ type ApplicationLog struct { TxHash util.Uint256 `json:"txid"` Trigger string `json:"trigger"` VMState string `json:"vmstate"` - GasConsumed util.Fixed8 `json:"gas_consumed"` + GasConsumed string `json:"gas_consumed"` Stack []smartcontract.Parameter `json:"stack"` Events []NotificationEvent `json:"notifications"` } @@ -46,7 +48,7 @@ func NewApplicationLog(appExecRes *state.AppExecResult) ApplicationLog { TxHash: appExecRes.TxHash, Trigger: appExecRes.Trigger.String(), VMState: appExecRes.VMState, - GasConsumed: appExecRes.GasConsumed, + GasConsumed: strconv.FormatInt(int64(appExecRes.GasConsumed), 10), Stack: appExecRes.Stack, Events: events, } From 05dad10e82856a6320912a11d6a7b2e20a12fc88 Mon Sep 17 00:00:00 2001 From: Evgenii Stratonikov Date: Fri, 19 Jun 2020 11:55:22 +0300 Subject: [PATCH 8/8] native: fix native contract `onPersist` script C# implementation uses NEWARRAY for creating arguments. Don't change our implementation in `emit`, because PACK is cheaper and this script must not depend on the internal details of `emit` package anyway. --- pkg/core/native/contract.go | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/pkg/core/native/contract.go b/pkg/core/native/contract.go index 55ff6230a..e9dc4f418 100644 --- a/pkg/core/native/contract.go +++ b/pkg/core/native/contract.go @@ -8,6 +8,7 @@ import ( "github.com/nspcc-dev/neo-go/pkg/util" "github.com/nspcc-dev/neo-go/pkg/vm" "github.com/nspcc-dev/neo-go/pkg/vm/emit" + "github.com/nspcc-dev/neo-go/pkg/vm/opcode" "github.com/pkg/errors" ) @@ -65,7 +66,10 @@ func (cs *Contracts) GetPersistScript() []byte { w := io.NewBufBinWriter() for i := range cs.Contracts { md := cs.Contracts[i].Metadata() - emit.AppCallWithOperationAndArgs(w.BinWriter, md.Hash, "onPersist") + emit.Int(w.BinWriter, 0) + emit.Opcode(w.BinWriter, opcode.NEWARRAY) + emit.String(w.BinWriter, "onPersist") + emit.AppCall(w.BinWriter, md.Hash) } cs.persistScript = w.Bytes() return cs.persistScript