Merge pull request #1387 from nspcc-dev/rpc/notifications_state_serialisation
rpc: replace result.ApplicationLog with state.AppExecResult
This commit is contained in:
commit
49e9c1aa0f
13 changed files with 282 additions and 138 deletions
|
@ -1,7 +1,9 @@
|
|||
package state
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"fmt"
|
||||
|
||||
"github.com/nspcc-dev/neo-go/pkg/io"
|
||||
"github.com/nspcc-dev/neo-go/pkg/smartcontract/trigger"
|
||||
|
@ -13,9 +15,9 @@ import (
|
|||
// NotificationEvent is a tuple of scripthash that emitted the Item as a
|
||||
// notification and that item itself.
|
||||
type NotificationEvent struct {
|
||||
ScriptHash util.Uint160
|
||||
Name string
|
||||
Item *stackitem.Array
|
||||
ScriptHash util.Uint160 `json:"contract"`
|
||||
Name string `json:"eventname"`
|
||||
Item *stackitem.Array `json:"state"`
|
||||
}
|
||||
|
||||
// AppExecResult represent the result of the script execution, gathering together
|
||||
|
@ -79,3 +81,119 @@ func (aer *AppExecResult) DecodeBinary(r *io.BinReader) {
|
|||
}
|
||||
r.ReadArray(&aer.Events)
|
||||
}
|
||||
|
||||
// notificationEventAux is an auxiliary struct for NotificationEvent JSON marshalling.
|
||||
type notificationEventAux struct {
|
||||
ScriptHash util.Uint160 `json:"contract"`
|
||||
Name string `json:"eventname"`
|
||||
Item json.RawMessage `json:"state"`
|
||||
}
|
||||
|
||||
// MarshalJSON implements implements json.Marshaler interface.
|
||||
func (ne *NotificationEvent) MarshalJSON() ([]byte, error) {
|
||||
item, err := stackitem.ToJSONWithTypes(ne.Item)
|
||||
if err != nil {
|
||||
item = []byte(`"error: recursive reference"`)
|
||||
}
|
||||
return json.Marshal(¬ificationEventAux{
|
||||
ScriptHash: ne.ScriptHash,
|
||||
Name: ne.Name,
|
||||
Item: item,
|
||||
})
|
||||
}
|
||||
|
||||
// UnmarshalJSON implements json.Unmarshaler interface.
|
||||
func (ne *NotificationEvent) UnmarshalJSON(data []byte) error {
|
||||
aux := new(notificationEventAux)
|
||||
if err := json.Unmarshal(data, aux); err != nil {
|
||||
return err
|
||||
}
|
||||
item, err := stackitem.FromJSONWithTypes(aux.Item)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if t := item.Type(); t != stackitem.ArrayT {
|
||||
return fmt.Errorf("failed to convert notification event state of type %s to array", t.String())
|
||||
}
|
||||
ne.Item = item.(*stackitem.Array)
|
||||
ne.Name = aux.Name
|
||||
ne.ScriptHash = aux.ScriptHash
|
||||
return nil
|
||||
}
|
||||
|
||||
// appExecResultAux is an auxiliary struct for JSON marshalling
|
||||
type appExecResultAux 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 implements json.Marshaler interface.
|
||||
func (aer *AppExecResult) MarshalJSON() ([]byte, error) {
|
||||
var st json.RawMessage
|
||||
arr := make([]json.RawMessage, len(aer.Stack))
|
||||
for i := range arr {
|
||||
data, err := stackitem.ToJSONWithTypes(aer.Stack[i])
|
||||
if err != nil {
|
||||
st = []byte(`"error: recursive reference"`)
|
||||
break
|
||||
}
|
||||
arr[i] = data
|
||||
}
|
||||
|
||||
var err error
|
||||
if st == nil {
|
||||
st, err = json.Marshal(arr)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
return json.Marshal(&appExecResultAux{
|
||||
TxHash: aer.TxHash,
|
||||
Trigger: aer.Trigger.String(),
|
||||
VMState: aer.VMState.String(),
|
||||
GasConsumed: aer.GasConsumed,
|
||||
Stack: st,
|
||||
Events: aer.Events,
|
||||
})
|
||||
}
|
||||
|
||||
// UnmarshalJSON implements implements json.Unmarshaler interface.
|
||||
func (aer *AppExecResult) UnmarshalJSON(data []byte) error {
|
||||
aux := new(appExecResultAux)
|
||||
if err := json.Unmarshal(data, aux); err != nil {
|
||||
return err
|
||||
}
|
||||
var arr []json.RawMessage
|
||||
if err := json.Unmarshal(aux.Stack, &arr); err == nil {
|
||||
st := make([]stackitem.Item, len(arr))
|
||||
for i := range arr {
|
||||
st[i], err = stackitem.FromJSONWithTypes(arr[i])
|
||||
if err != nil {
|
||||
break
|
||||
}
|
||||
}
|
||||
if err == nil {
|
||||
aer.Stack = st
|
||||
}
|
||||
}
|
||||
|
||||
trigger, err := trigger.FromString(aux.Trigger)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
aer.Trigger = trigger
|
||||
aer.TxHash = aux.TxHash
|
||||
state, err := vm.StateFromString(aux.VMState)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
aer.VMState = state
|
||||
aer.Events = aux.Events
|
||||
aer.GasConsumed = aux.GasConsumed
|
||||
|
||||
return nil
|
||||
}
|
||||
|
|
|
@ -1,12 +1,14 @@
|
|||
package state
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"testing"
|
||||
|
||||
"github.com/nspcc-dev/neo-go/pkg/internal/random"
|
||||
"github.com/nspcc-dev/neo-go/pkg/internal/testserdes"
|
||||
"github.com/nspcc-dev/neo-go/pkg/vm"
|
||||
"github.com/nspcc-dev/neo-go/pkg/vm/stackitem"
|
||||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
|
||||
func TestEncodeDecodeNotificationEvent(t *testing.T) {
|
||||
|
@ -31,3 +33,92 @@ func TestEncodeDecodeAppExecResult(t *testing.T) {
|
|||
|
||||
testserdes.EncodeDecodeBinary(t, appExecResult, new(AppExecResult))
|
||||
}
|
||||
|
||||
func TestMarshalUnmarshalJSONNotificationEvent(t *testing.T) {
|
||||
t.Run("positive", func(t *testing.T) {
|
||||
ne := &NotificationEvent{
|
||||
ScriptHash: random.Uint160(),
|
||||
Name: "my_ne",
|
||||
Item: stackitem.NewArray([]stackitem.Item{
|
||||
stackitem.NewBool(true),
|
||||
}),
|
||||
}
|
||||
testserdes.MarshalUnmarshalJSON(t, ne, new(NotificationEvent))
|
||||
})
|
||||
|
||||
t.Run("MarshalJSON recursive reference", func(t *testing.T) {
|
||||
i := make([]stackitem.Item, 1)
|
||||
recursive := stackitem.NewArray(i)
|
||||
i[0] = recursive
|
||||
ne := &NotificationEvent{
|
||||
Item: recursive,
|
||||
}
|
||||
_, err := json.Marshal(ne)
|
||||
require.NoError(t, err)
|
||||
})
|
||||
|
||||
t.Run("UnmarshalJSON error", func(t *testing.T) {
|
||||
errorCases := []string{
|
||||
`{"contract":"0xBadHash","eventname":"my_ne","state":{"type":"Array","value":[{"type":"Boolean","value":true}]}}`,
|
||||
`{"contract":"0xab2f820e2aa7cca1e081283c58a7d7943c33a2f1","eventname":"my_ne","state":{"type":"Array","value":[{"type":"BadType","value":true}]}}`,
|
||||
`{"contract":"0xab2f820e2aa7cca1e081283c58a7d7943c33a2f1","eventname":"my_ne","state":{"type":"Boolean", "value":true}}`,
|
||||
}
|
||||
for _, errCase := range errorCases {
|
||||
err := json.Unmarshal([]byte(errCase), new(NotificationEvent))
|
||||
require.Error(t, err)
|
||||
}
|
||||
|
||||
})
|
||||
}
|
||||
|
||||
func TestMarshalUnmarshalJSONAppExecResult(t *testing.T) {
|
||||
t.Run("positive", func(t *testing.T) {
|
||||
appExecResult := &AppExecResult{
|
||||
TxHash: random.Uint256(),
|
||||
Trigger: 1,
|
||||
VMState: vm.HaltState,
|
||||
GasConsumed: 10,
|
||||
Stack: []stackitem.Item{},
|
||||
Events: []NotificationEvent{},
|
||||
}
|
||||
testserdes.MarshalUnmarshalJSON(t, appExecResult, new(AppExecResult))
|
||||
})
|
||||
|
||||
t.Run("MarshalJSON recursive reference", func(t *testing.T) {
|
||||
i := make([]stackitem.Item, 1)
|
||||
recursive := stackitem.NewArray(i)
|
||||
i[0] = recursive
|
||||
errorCases := []*AppExecResult{
|
||||
{
|
||||
Stack: i,
|
||||
},
|
||||
}
|
||||
for _, errCase := range errorCases {
|
||||
_, err := json.Marshal(errCase)
|
||||
require.NoError(t, err)
|
||||
}
|
||||
})
|
||||
|
||||
t.Run("UnmarshalJSON error", func(t *testing.T) {
|
||||
nilStackCases := []string{
|
||||
`{"txid":"0x17145a039fca704fcdbeb46e6b210af98a1a9e5b9768e46ffc38f71c79ac2521","trigger":"Application","vmstate":"HALT","gasconsumed":"1","stack":[{"type":"WrongType","value":"1"}],"notifications":[]}`,
|
||||
}
|
||||
for _, str := range nilStackCases {
|
||||
actual := new(AppExecResult)
|
||||
err := json.Unmarshal([]byte(str), actual)
|
||||
require.NoError(t, err)
|
||||
require.Nil(t, actual.Stack)
|
||||
}
|
||||
|
||||
errorCases := []string{
|
||||
`{"txid":"0xBadHash","trigger":"Application","vmstate":"HALT","gasconsumed":"1","stack":[{"type":"Integer","value":"1"}],"notifications":[]}`,
|
||||
`{"txid":"0x17145a039fca704fcdbeb46e6b210af98a1a9e5b9768e46ffc38f71c79ac2521","trigger":"Application","vmstate":"BadState","gasconsumed":"1","stack":[{"type":"Integer","value":"1"}],"notifications":[]}`,
|
||||
`{"txid":"0x17145a039fca704fcdbeb46e6b210af98a1a9e5b9768e46ffc38f71c79ac2521","trigger":"BadTrigger","vmstate":"HALT","gasconsumed":"1","stack":[{"type":"Integer","value":"1"}],"notifications":[]}`,
|
||||
}
|
||||
for _, str := range errorCases {
|
||||
actual := new(AppExecResult)
|
||||
err := json.Unmarshal([]byte(str), actual)
|
||||
require.Error(t, err)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
|
|
@ -19,10 +19,10 @@ import (
|
|||
)
|
||||
|
||||
// GetApplicationLog returns the contract log based on the specified txid.
|
||||
func (c *Client) GetApplicationLog(hash util.Uint256) (*result.ApplicationLog, error) {
|
||||
func (c *Client) GetApplicationLog(hash util.Uint256) (*state.AppExecResult, error) {
|
||||
var (
|
||||
params = request.NewRawParams(hash.StringLE())
|
||||
resp = &result.ApplicationLog{}
|
||||
resp = new(state.AppExecResult)
|
||||
)
|
||||
if err := c.performRequest("getapplicationlog", params, resp); err != nil {
|
||||
return nil, err
|
||||
|
|
|
@ -25,7 +25,9 @@ import (
|
|||
"github.com/nspcc-dev/neo-go/pkg/rpc/response/result"
|
||||
"github.com/nspcc-dev/neo-go/pkg/smartcontract"
|
||||
"github.com/nspcc-dev/neo-go/pkg/smartcontract/manifest"
|
||||
"github.com/nspcc-dev/neo-go/pkg/smartcontract/trigger"
|
||||
"github.com/nspcc-dev/neo-go/pkg/util"
|
||||
"github.com/nspcc-dev/neo-go/pkg/vm"
|
||||
"github.com/nspcc-dev/neo-go/pkg/vm/opcode"
|
||||
"github.com/nspcc-dev/neo-go/pkg/vm/stackitem"
|
||||
"github.com/stretchr/testify/assert"
|
||||
|
@ -113,13 +115,13 @@ var rpcClientTestCases = map[string][]rpcClientTestCase{
|
|||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
return &result.ApplicationLog{
|
||||
return &state.AppExecResult{
|
||||
TxHash: txHash,
|
||||
Trigger: "Application",
|
||||
VMState: "HALT",
|
||||
Trigger: trigger.Application,
|
||||
VMState: vm.HaltState,
|
||||
GasConsumed: 1,
|
||||
Stack: []stackitem.Item{stackitem.NewBigInteger(big.NewInt(1))},
|
||||
Events: []result.NotificationEvent{},
|
||||
Events: []state.NotificationEvent{},
|
||||
}
|
||||
},
|
||||
},
|
||||
|
|
|
@ -8,10 +8,10 @@ import (
|
|||
|
||||
"github.com/gorilla/websocket"
|
||||
"github.com/nspcc-dev/neo-go/pkg/core/block"
|
||||
"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/rpc/request"
|
||||
"github.com/nspcc-dev/neo-go/pkg/rpc/response"
|
||||
"github.com/nspcc-dev/neo-go/pkg/rpc/response/result"
|
||||
"github.com/nspcc-dev/neo-go/pkg/util"
|
||||
)
|
||||
|
||||
|
@ -141,9 +141,9 @@ readloop:
|
|||
case response.TransactionEventID:
|
||||
val = &transaction.Transaction{Network: c.opts.Network}
|
||||
case response.NotificationEventID:
|
||||
val = new(result.NotificationEvent)
|
||||
val = new(state.NotificationEvent)
|
||||
case response.ExecutionEventID:
|
||||
val = new(result.ApplicationLog)
|
||||
val = new(state.AppExecResult)
|
||||
case response.MissedEventID:
|
||||
// No value.
|
||||
default:
|
||||
|
|
|
@ -1,109 +0,0 @@
|
|||
package result
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
|
||||
"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"
|
||||
"github.com/nspcc-dev/neo-go/pkg/vm/stackitem"
|
||||
)
|
||||
|
||||
// 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
|
||||
Trigger string
|
||||
VMState string
|
||||
GasConsumed int64
|
||||
Stack []stackitem.Item
|
||||
Events []NotificationEvent
|
||||
}
|
||||
|
||||
//NotificationEvent response wrapper
|
||||
type NotificationEvent struct {
|
||||
Contract util.Uint160 `json:"contract"`
|
||||
Name string `json:"eventname"`
|
||||
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
|
||||
// result.NotificationEvent.
|
||||
func StateEventToResultNotification(event state.NotificationEvent) NotificationEvent {
|
||||
seen := make(map[stackitem.Item]bool)
|
||||
item := smartcontract.ParameterFromStackItem(event.Item, seen)
|
||||
return NotificationEvent{
|
||||
Contract: event.ScriptHash,
|
||||
Name: event.Name,
|
||||
Item: item,
|
||||
}
|
||||
}
|
||||
|
||||
// NewApplicationLog creates a new ApplicationLog wrapper.
|
||||
func NewApplicationLog(appExecRes *state.AppExecResult) ApplicationLog {
|
||||
events := make([]NotificationEvent, 0, len(appExecRes.Events))
|
||||
for _, e := range appExecRes.Events {
|
||||
events = append(events, StateEventToResultNotification(e))
|
||||
}
|
||||
return ApplicationLog{
|
||||
TxHash: appExecRes.TxHash,
|
||||
Trigger: appExecRes.Trigger.String(),
|
||||
VMState: appExecRes.VMState.String(),
|
||||
GasConsumed: appExecRes.GasConsumed,
|
||||
Stack: appExecRes.Stack,
|
||||
Events: events,
|
||||
}
|
||||
}
|
|
@ -29,7 +29,7 @@ func (r Invoke) MarshalJSON() ([]byte, error) {
|
|||
for i := range arr {
|
||||
data, err := stackitem.ToJSONWithTypes(r.Stack[i])
|
||||
if err != nil {
|
||||
st = []byte("error: recursive reference")
|
||||
st = []byte(`"error: recursive reference"`)
|
||||
break
|
||||
}
|
||||
arr[i] = data
|
||||
|
|
|
@ -498,7 +498,7 @@ func (s *Server) getApplicationLog(reqParams request.Params) (interface{}, *resp
|
|||
return nil, response.NewRPCError("Unknown transaction", "", err)
|
||||
}
|
||||
|
||||
return result.NewApplicationLog(appExecResult), nil
|
||||
return appExecResult, nil
|
||||
}
|
||||
|
||||
func (s *Server) getNEP5Balances(ps request.Params) (interface{}, *response.Error) {
|
||||
|
@ -1159,10 +1159,10 @@ chloop:
|
|||
resp.Payload[0] = b
|
||||
case execution := <-s.executionCh:
|
||||
resp.Event = response.ExecutionEventID
|
||||
resp.Payload[0] = result.NewApplicationLog(execution)
|
||||
resp.Payload[0] = execution
|
||||
case notification := <-s.notificationCh:
|
||||
resp.Event = response.NotificationEventID
|
||||
resp.Payload[0] = result.StateEventToResultNotification(*notification)
|
||||
resp.Payload[0] = *notification
|
||||
case tx := <-s.transactionCh:
|
||||
resp.Event = response.TransactionEventID
|
||||
resp.Payload[0] = tx
|
||||
|
|
|
@ -26,7 +26,9 @@ import (
|
|||
"github.com/nspcc-dev/neo-go/pkg/io"
|
||||
"github.com/nspcc-dev/neo-go/pkg/rpc/response"
|
||||
"github.com/nspcc-dev/neo-go/pkg/rpc/response/result"
|
||||
"github.com/nspcc-dev/neo-go/pkg/smartcontract/trigger"
|
||||
"github.com/nspcc-dev/neo-go/pkg/util"
|
||||
"github.com/nspcc-dev/neo-go/pkg/vm"
|
||||
"github.com/nspcc-dev/neo-go/pkg/vm/opcode"
|
||||
"github.com/nspcc-dev/neo-go/pkg/wallet"
|
||||
"github.com/stretchr/testify/assert"
|
||||
|
@ -62,15 +64,15 @@ var rpcTestCases = map[string][]rpcTestCase{
|
|||
{
|
||||
name: "positive",
|
||||
params: `["` + deploymentTxHash + `"]`,
|
||||
result: func(e *executor) interface{} { return &result.ApplicationLog{} },
|
||||
result: func(e *executor) interface{} { return &state.AppExecResult{} },
|
||||
check: func(t *testing.T, e *executor, acc interface{}) {
|
||||
res, ok := acc.(*result.ApplicationLog)
|
||||
res, ok := acc.(*state.AppExecResult)
|
||||
require.True(t, ok)
|
||||
expectedTxHash, err := util.Uint256DecodeStringLE(deploymentTxHash)
|
||||
require.NoError(t, err)
|
||||
assert.Equal(t, expectedTxHash, res.TxHash)
|
||||
assert.Equal(t, "Application", res.Trigger)
|
||||
assert.Equal(t, "HALT", res.VMState)
|
||||
assert.Equal(t, trigger.Application, res.Trigger)
|
||||
assert.Equal(t, vm.HaltState, res.VMState)
|
||||
},
|
||||
},
|
||||
{
|
||||
|
@ -722,10 +724,10 @@ func testRPCProtocol(t *testing.T, doRPCCall func(string, string, *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
|
||||
var res state.AppExecResult
|
||||
require.NoError(t, json.Unmarshal(data, &res))
|
||||
require.Equal(t, "System", res.Trigger)
|
||||
require.Equal(t, "HALT", res.VMState)
|
||||
require.Equal(t, trigger.System, res.Trigger)
|
||||
require.Equal(t, vm.HaltState, res.VMState)
|
||||
})
|
||||
|
||||
t.Run("submit", func(t *testing.T) {
|
||||
|
|
|
@ -3,10 +3,10 @@ package server
|
|||
import (
|
||||
"github.com/gorilla/websocket"
|
||||
"github.com/nspcc-dev/neo-go/pkg/core/block"
|
||||
"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/rpc/request"
|
||||
"github.com/nspcc-dev/neo-go/pkg/rpc/response"
|
||||
"github.com/nspcc-dev/neo-go/pkg/rpc/response/result"
|
||||
"go.uber.org/atomic"
|
||||
)
|
||||
|
||||
|
@ -72,14 +72,14 @@ func (f *feed) Matches(r *response.Notification) bool {
|
|||
return senderOK && signerOK
|
||||
case response.NotificationEventID:
|
||||
filt := f.filter.(request.NotificationFilter)
|
||||
notification := r.Payload[0].(result.NotificationEvent)
|
||||
hashOk := filt.Contract == nil || notification.Contract.Equals(*filt.Contract)
|
||||
notification := r.Payload[0].(state.NotificationEvent)
|
||||
hashOk := filt.Contract == nil || notification.ScriptHash.Equals(*filt.Contract)
|
||||
nameOk := filt.Name == nil || notification.Name == *filt.Name
|
||||
return hashOk && nameOk
|
||||
case response.ExecutionEventID:
|
||||
filt := f.filter.(request.ExecutionFilter)
|
||||
applog := r.Payload[0].(result.ApplicationLog)
|
||||
return applog.VMState == filt.State
|
||||
applog := r.Payload[0].(*state.AppExecResult)
|
||||
return applog.VMState.String() == filt.State
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
|
|
@ -1,5 +1,7 @@
|
|||
package trigger
|
||||
|
||||
import "fmt"
|
||||
|
||||
//go:generate stringer -type=Type -output=trigger_type_string.go
|
||||
|
||||
// Type represents trigger type used in C# reference node: https://github.com/neo-project/neo/blob/c64748ecbac3baeb8045b16af0d518398a6ced24/neo/SmartContract/TriggerType.cs#L3
|
||||
|
@ -25,5 +27,16 @@ const (
|
|||
Application Type = 0x40
|
||||
|
||||
// All represents any trigger type.
|
||||
All = System | Verification | Application
|
||||
All Type = System | Verification | Application
|
||||
)
|
||||
|
||||
// FromString converts string to trigger Type
|
||||
func FromString(str string) (Type, error) {
|
||||
triggers := []Type{System, Verification, Application, All}
|
||||
for _, t := range triggers {
|
||||
if t.String() == str {
|
||||
return t, nil
|
||||
}
|
||||
}
|
||||
return 0, fmt.Errorf("unknown trigger type: %s", str)
|
||||
}
|
||||
|
|
|
@ -11,12 +11,14 @@ func _() {
|
|||
_ = x[System-1]
|
||||
_ = x[Verification-32]
|
||||
_ = x[Application-64]
|
||||
_ = x[All-97]
|
||||
}
|
||||
|
||||
const (
|
||||
_Type_name_0 = "System"
|
||||
_Type_name_1 = "Verification"
|
||||
_Type_name_2 = "Application"
|
||||
_Type_name_3 = "All"
|
||||
)
|
||||
|
||||
func (i Type) String() string {
|
||||
|
@ -27,6 +29,8 @@ func (i Type) String() string {
|
|||
return _Type_name_1
|
||||
case i == 64:
|
||||
return _Type_name_2
|
||||
case i == 97:
|
||||
return _Type_name_3
|
||||
default:
|
||||
return "Type(" + strconv.FormatInt(int64(i), 10) + ")"
|
||||
}
|
||||
|
|
|
@ -4,6 +4,7 @@ import (
|
|||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
|
||||
func TestStringer(t *testing.T) {
|
||||
|
@ -38,3 +39,25 @@ func TestDecodeBynary(t *testing.T) {
|
|||
assert.Equal(t, o, Type(b))
|
||||
}
|
||||
}
|
||||
|
||||
func TestFromString(t *testing.T) {
|
||||
testCases := map[string]Type{
|
||||
"System": System,
|
||||
"Application": Application,
|
||||
"Verification": Verification,
|
||||
"All": All,
|
||||
}
|
||||
for str, expected := range testCases {
|
||||
actual, err := FromString(str)
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, expected, actual)
|
||||
}
|
||||
errorCases := []string{
|
||||
"",
|
||||
"Unknown",
|
||||
}
|
||||
for _, str := range errorCases {
|
||||
_, err := FromString(str)
|
||||
require.Error(t, err)
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue