rpc: add trigger parameter to getapplicationlog

This commit is contained in:
Anna Shaleva 2020-11-10 14:30:00 +03:00
parent 7ca93e76ac
commit 0b15ca8bd0
5 changed files with 67 additions and 12 deletions

View file

@ -18,6 +18,7 @@ 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/wallet"
)
@ -25,11 +26,14 @@ import (
var errNetworkNotInitialized = errors.New("RPC client network is not initialized")
// 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, trig *trigger.Type) (*result.ApplicationLog, error) {
var (
params = request.NewRawParams(hash.StringLE())
resp = new(result.ApplicationLog)
)
if trig != nil {
params.Values = append(params.Values, trig.String())
}
if err := c.performRequest("getapplicationlog", params, resp); err != nil {
return nil, err
}

View file

@ -108,7 +108,7 @@ var rpcClientTestCases = map[string][]rpcClientTestCase{
{
name: "positive",
invoke: func(c *Client) (interface{}, error) {
return c.GetApplicationLog(util.Uint256{})
return c.GetApplicationLog(util.Uint256{}, nil)
},
serverResponse: `{"id":1,"jsonrpc":"2.0","result":{"txid":"0x17145a039fca704fcdbeb46e6b210af98a1a9e5b9768e46ffc38f71c79ac2521","executions":[{"trigger":"Application","vmstate":"HALT","gasconsumed":"1","stack":[{"type":"Integer","value":"1"}],"notifications":[]}]}}`,
result: func(c *Client) interface{} {
@ -973,7 +973,7 @@ var rpcClientErrorCases = map[string][]rpcClientErrorCase{
{
name: "getapplicationlog_invalid_params_error",
invoke: func(c *Client) (interface{}, error) {
return c.GetApplicationLog(util.Uint256{})
return c.GetApplicationLog(util.Uint256{}, nil)
},
},
{
@ -1148,7 +1148,7 @@ var rpcClientErrorCases = map[string][]rpcClientErrorCase{
{
name: "getapplicationlog_unmarshalling_error",
invoke: func(c *Client) (interface{}, error) {
return c.GetApplicationLog(util.Uint256{})
return c.GetApplicationLog(util.Uint256{}, nil)
},
},
{

View file

@ -12,8 +12,9 @@ import (
// ApplicationLog represent the results of the script executions for block or transaction.
type ApplicationLog struct {
Container util.Uint256
Executions []state.Execution
Container util.Uint256
IsTransaction bool
Executions []state.Execution
}
// applicationLogAux is an auxiliary struct for ApplicationLog JSON marshalling.
@ -28,7 +29,7 @@ func (l ApplicationLog) MarshalJSON() ([]byte, error) {
result := &applicationLogAux{
Executions: make([]json.RawMessage, len(l.Executions)),
}
if l.Executions[0].Trigger == trigger.Application {
if l.IsTransaction {
result.TxHash = &l.Container
} else {
result.BlockHash = &l.Container
@ -67,13 +68,17 @@ func (l *ApplicationLog) UnmarshalJSON(data []byte) error {
return nil
}
// NewApplicationLog creates ApplicationLog from a set of several application execution results.
func NewApplicationLog(hash util.Uint256, aers []state.AppExecResult) ApplicationLog {
// NewApplicationLog creates ApplicationLog from a set of several application execution results
// including only the results with the specified trigger.
func NewApplicationLog(hash util.Uint256, aers []state.AppExecResult, trig trigger.Type) ApplicationLog {
result := ApplicationLog{
Container: hash,
Container: hash,
IsTransaction: aers[0].Trigger == trigger.Application,
}
for _, aer := range aers {
result.Executions = append(result.Executions, aer.Execution)
if aer.Trigger&trig != 0 {
result.Executions = append(result.Executions, aer.Execution)
}
}
return result
}

View file

@ -527,11 +527,19 @@ func (s *Server) getApplicationLog(reqParams request.Params) (interface{}, *resp
return nil, response.ErrInvalidParams
}
trig := trigger.All
if len(reqParams) > 1 {
trig, err = trigger.FromString(reqParams.ValueWithType(1, request.StringT).String())
if err != nil {
return nil, response.ErrInvalidParams
}
}
appExecResults, err := s.chain.GetAppExecResults(hash, trigger.All)
if err != nil {
return nil, response.NewRPCError("Unknown transaction or block", "", err)
}
return result.NewApplicationLog(hash, appExecResults), nil
return result.NewApplicationLog(hash, appExecResults, trig), nil
}
func (s *Server) getNEP5Balances(ps request.Params) (interface{}, *response.Error) {

View file

@ -58,6 +58,7 @@ type rpcTestCase struct {
const testContractHash = "b0fda4dd46b8e5d207e86e774a4a133c6db69ee7"
const deploymentTxHash = "59f7b22b90e26f883a56b916c1580e3ee4f13caded686353cd77577e6194c173"
const genesisBlockHash = "a496577895eb8c227bb866dc44f99f21c0cf06417ca8f2a877cc5d761a50dac0"
const verifyContractHash = "c1213693b22cb0454a436d6e0bd76b8c0a3bfdf7"
const verifyContractAVM = "570300412d51083021700c14aa8acf859d4fe402b34e673f2156821796a488ebdb30716813cedb2869db289740"
@ -80,6 +81,43 @@ var rpcTestCases = map[string][]rpcTestCase{
assert.Equal(t, vm.HaltState, res.Executions[0].VMState)
},
},
{
name: "positive, genesis block",
params: `["` + genesisBlockHash + `"]`,
result: func(e *executor) interface{} { return &result.ApplicationLog{} },
check: func(t *testing.T, e *executor, acc interface{}) {
res, ok := acc.(*result.ApplicationLog)
require.True(t, ok)
assert.Equal(t, genesisBlockHash, res.Container.StringLE())
assert.Equal(t, 1, len(res.Executions))
assert.Equal(t, trigger.PostPersist, res.Executions[0].Trigger) // no onPersist for genesis block
assert.Equal(t, vm.HaltState, res.Executions[0].VMState)
},
},
{
name: "positive, genesis block, postPersist",
params: `["` + genesisBlockHash + `", "PostPersist"]`,
result: func(e *executor) interface{} { return &result.ApplicationLog{} },
check: func(t *testing.T, e *executor, acc interface{}) {
res, ok := acc.(*result.ApplicationLog)
require.True(t, ok)
assert.Equal(t, genesisBlockHash, res.Container.StringLE())
assert.Equal(t, 1, len(res.Executions))
assert.Equal(t, trigger.PostPersist, res.Executions[0].Trigger) // no onPersist for genesis block
assert.Equal(t, vm.HaltState, res.Executions[0].VMState)
},
},
{
name: "positive, genesis block, onPersist",
params: `["` + genesisBlockHash + `", "OnPersist"]`,
result: func(e *executor) interface{} { return &result.ApplicationLog{} },
check: func(t *testing.T, e *executor, acc interface{}) {
res, ok := acc.(*result.ApplicationLog)
require.True(t, ok)
assert.Equal(t, genesisBlockHash, res.Container.StringLE())
assert.Equal(t, 0, len(res.Executions)) // no onPersist for genesis block
},
},
{
name: "no params",
params: `[]`,