Merge pull request #1317 from nspcc-dev/rpc/getapplicationlog

rpc: marshal `getapplicationlog` stack as []stackitem.Item
This commit is contained in:
Roman Khimov 2020-08-13 17:54:08 +03:00 committed by GitHub
commit 8da092d532
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 64 additions and 14 deletions

View file

@ -107,7 +107,7 @@ var rpcClientTestCases = map[string][]rpcClientTestCase{
invoke: func(c *Client) (interface{}, error) { invoke: func(c *Client) (interface{}, error) {
return c.GetApplicationLog(util.Uint256{}) return c.GetApplicationLog(util.Uint256{})
}, },
serverResponse: `{"id":1,"jsonrpc":"2.0","result":{"txid":"0x17145a039fca704fcdbeb46e6b210af98a1a9e5b9768e46ffc38f71c79ac2521","trigger":"Application","vmstate":"HALT","gasconsumed":"1","stack":[{"type":"Integer","value":1}],"notifications":[]}}`, serverResponse: `{"id":1,"jsonrpc":"2.0","result":{"txid":"0x17145a039fca704fcdbeb46e6b210af98a1a9e5b9768e46ffc38f71c79ac2521","trigger":"Application","vmstate":"HALT","gasconsumed":"1","stack":[{"type":"Integer","value":"1"}],"notifications":[]}}`,
result: func(c *Client) interface{} { result: func(c *Client) interface{} {
txHash, err := util.Uint256DecodeStringLE("17145a039fca704fcdbeb46e6b210af98a1a9e5b9768e46ffc38f71c79ac2521") txHash, err := util.Uint256DecodeStringLE("17145a039fca704fcdbeb46e6b210af98a1a9e5b9768e46ffc38f71c79ac2521")
if err != nil { if err != nil {
@ -118,7 +118,7 @@ var rpcClientTestCases = map[string][]rpcClientTestCase{
Trigger: "Application", Trigger: "Application",
VMState: "HALT", VMState: "HALT",
GasConsumed: 1, GasConsumed: 1,
Stack: []smartcontract.Parameter{{Type: smartcontract.IntegerType, Value: int64(1)}}, Stack: []stackitem.Item{stackitem.NewBigInteger(big.NewInt(1))},
Events: []result.NotificationEvent{}, Events: []result.NotificationEvent{},
} }
}, },

View file

@ -1,6 +1,8 @@
package result package result
import ( import (
"encoding/json"
"github.com/nspcc-dev/neo-go/pkg/core/state" "github.com/nspcc-dev/neo-go/pkg/core/state"
"github.com/nspcc-dev/neo-go/pkg/smartcontract" "github.com/nspcc-dev/neo-go/pkg/smartcontract"
"github.com/nspcc-dev/neo-go/pkg/util" "github.com/nspcc-dev/neo-go/pkg/util"
@ -10,12 +12,12 @@ import (
// ApplicationLog wrapper used for the representation of the // ApplicationLog wrapper used for the representation of the
// state.AppExecResult based on the specific tx on the RPC Server. // state.AppExecResult based on the specific tx on the RPC Server.
type ApplicationLog struct { type ApplicationLog struct {
TxHash util.Uint256 `json:"txid"` TxHash util.Uint256
Trigger string `json:"trigger"` Trigger string
VMState string `json:"vmstate"` VMState string
GasConsumed int64 `json:"gasconsumed,string"` GasConsumed int64
Stack []smartcontract.Parameter `json:"stack"` Stack []stackitem.Item
Events []NotificationEvent `json:"notifications"` Events []NotificationEvent
} }
//NotificationEvent response wrapper //NotificationEvent response wrapper
@ -25,6 +27,59 @@ type NotificationEvent struct {
Item smartcontract.Parameter `json:"state"` Item smartcontract.Parameter `json:"state"`
} }
type applicationLogAux struct {
TxHash util.Uint256 `json:"txid"`
Trigger string `json:"trigger"`
VMState string `json:"vmstate"`
GasConsumed int64 `json:"gasconsumed,string"`
Stack []json.RawMessage `json:"stack"`
Events []NotificationEvent `json:"notifications"`
}
// MarshalJSON implements json.Marshaler.
func (l ApplicationLog) MarshalJSON() ([]byte, error) {
arr := make([]json.RawMessage, len(l.Stack))
for i := range arr {
data, err := stackitem.ToJSONWithTypes(l.Stack[i])
if err != nil {
return nil, err
}
arr[i] = data
}
return json.Marshal(&applicationLogAux{
TxHash: l.TxHash,
Trigger: l.Trigger,
VMState: l.VMState,
GasConsumed: l.GasConsumed,
Stack: arr,
Events: l.Events,
})
}
// UnmarshalJSON implements json.Unmarshaler.
func (l *ApplicationLog) UnmarshalJSON(data []byte) error {
aux := new(applicationLogAux)
if err := json.Unmarshal(data, aux); err != nil {
return err
}
st := make([]stackitem.Item, len(aux.Stack))
var err error
for i := range st {
st[i], err = stackitem.FromJSONWithTypes(aux.Stack[i])
if err != nil {
return err
}
}
l.Stack = st
l.Trigger = aux.Trigger
l.TxHash = aux.TxHash
l.VMState = aux.VMState
l.Events = aux.Events
l.GasConsumed = aux.GasConsumed
return nil
}
// StateEventToResultNotification converts state.NotificationEvent to // StateEventToResultNotification converts state.NotificationEvent to
// result.NotificationEvent. // result.NotificationEvent.
func StateEventToResultNotification(event state.NotificationEvent) NotificationEvent { func StateEventToResultNotification(event state.NotificationEvent) NotificationEvent {
@ -43,17 +98,12 @@ func NewApplicationLog(appExecRes *state.AppExecResult) ApplicationLog {
for _, e := range appExecRes.Events { for _, e := range appExecRes.Events {
events = append(events, StateEventToResultNotification(e)) events = append(events, StateEventToResultNotification(e))
} }
st := make([]smartcontract.Parameter, len(appExecRes.Stack))
seen := make(map[stackitem.Item]bool)
for i := range appExecRes.Stack {
st[i] = smartcontract.ParameterFromStackItem(appExecRes.Stack[i], seen)
}
return ApplicationLog{ return ApplicationLog{
TxHash: appExecRes.TxHash, TxHash: appExecRes.TxHash,
Trigger: appExecRes.Trigger.String(), Trigger: appExecRes.Trigger.String(),
VMState: appExecRes.VMState.String(), VMState: appExecRes.VMState.String(),
GasConsumed: appExecRes.GasConsumed, GasConsumed: appExecRes.GasConsumed,
Stack: st, Stack: appExecRes.Stack,
Events: events, Events: events,
} }
} }