diff --git a/pkg/core/blockchain.go b/pkg/core/blockchain.go index 527af9b49..5d0c55d31 100644 --- a/pkg/core/blockchain.go +++ b/pkg/core/blockchain.go @@ -883,7 +883,7 @@ func (bc *Blockchain) GetTransaction(hash util.Uint256) (*transaction.Transactio } // GetAppExecResult returns application execution result by the given -// tx hash. +// tx hash or block hash. func (bc *Blockchain) GetAppExecResult(hash util.Uint256) (*state.AppExecResult, error) { return bc.dao.GetAppExecResult(hash) } diff --git a/pkg/core/state/notification_event.go b/pkg/core/state/notification_event.go index 99e5046cf..296ee7905 100644 --- a/pkg/core/state/notification_event.go +++ b/pkg/core/state/notification_event.go @@ -123,7 +123,7 @@ func (ne *NotificationEvent) UnmarshalJSON(data []byte) error { // appExecResultAux is an auxiliary struct for JSON marshalling type appExecResultAux struct { - TxHash util.Uint256 `json:"txid"` + TxHash *util.Uint256 `json:"txid"` Trigger string `json:"trigger"` VMState string `json:"vmstate"` GasConsumed int64 `json:"gasconsumed,string"` @@ -151,8 +151,14 @@ func (aer *AppExecResult) MarshalJSON() ([]byte, error) { return nil, err } } + + // do not marshal block hash + var hash *util.Uint256 + if aer.Trigger == trigger.Application { + hash = &aer.TxHash + } return json.Marshal(&appExecResultAux{ - TxHash: aer.TxHash, + TxHash: hash, Trigger: aer.Trigger.String(), VMState: aer.VMState.String(), GasConsumed: aer.GasConsumed, @@ -186,7 +192,9 @@ func (aer *AppExecResult) UnmarshalJSON(data []byte) error { return err } aer.Trigger = trigger - aer.TxHash = aux.TxHash + if aux.TxHash != nil { + aer.TxHash = *aux.TxHash + } state, err := vm.StateFromString(aux.VMState) if err != nil { return err diff --git a/pkg/core/state/notification_event_test.go b/pkg/core/state/notification_event_test.go index f5376e6e8..c038ece08 100644 --- a/pkg/core/state/notification_event_test.go +++ b/pkg/core/state/notification_event_test.go @@ -6,6 +6,8 @@ import ( "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/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/stackitem" "github.com/stretchr/testify/require" @@ -72,10 +74,10 @@ func TestMarshalUnmarshalJSONNotificationEvent(t *testing.T) { } func TestMarshalUnmarshalJSONAppExecResult(t *testing.T) { - t.Run("positive", func(t *testing.T) { + t.Run("positive, transaction", func(t *testing.T) { appExecResult := &AppExecResult{ TxHash: random.Uint256(), - Trigger: 1, + Trigger: trigger.Application, VMState: vm.HaltState, GasConsumed: 10, Stack: []stackitem.Item{}, @@ -84,6 +86,31 @@ func TestMarshalUnmarshalJSONAppExecResult(t *testing.T) { testserdes.MarshalUnmarshalJSON(t, appExecResult, new(AppExecResult)) }) + t.Run("positive, block", func(t *testing.T) { + appExecResult := &AppExecResult{ + TxHash: random.Uint256(), + Trigger: trigger.System, + VMState: vm.HaltState, + GasConsumed: 10, + Stack: []stackitem.Item{}, + Events: []NotificationEvent{}, + } + data, err := json.Marshal(appExecResult) + require.NoError(t, err) + actual := new(AppExecResult) + require.NoError(t, json.Unmarshal(data, actual)) + expected := &AppExecResult{ + // we have no way to restore block hash as it was not marshalled + TxHash: util.Uint256{}, + Trigger: appExecResult.Trigger, + VMState: appExecResult.VMState, + GasConsumed: appExecResult.GasConsumed, + Stack: appExecResult.Stack, + Events: appExecResult.Events, + } + require.Equal(t, expected, actual) + }) + t.Run("MarshalJSON recursive reference", func(t *testing.T) { i := make([]stackitem.Item, 1) recursive := stackitem.NewArray(i) diff --git a/pkg/rpc/server/server.go b/pkg/rpc/server/server.go index 6668e7510..2ff4d216c 100644 --- a/pkg/rpc/server/server.go +++ b/pkg/rpc/server/server.go @@ -500,16 +500,16 @@ func (s *Server) validateAddress(reqParams request.Params) (interface{}, *respon return validateAddress(param.Value), nil } -// getApplicationLog returns the contract log based on the specified txid. +// getApplicationLog returns the contract log based on the specified txid or blockid. func (s *Server) getApplicationLog(reqParams request.Params) (interface{}, *response.Error) { - txHash, err := reqParams.Value(0).GetUint256() + hash, err := reqParams.Value(0).GetUint256() if err != nil { return nil, response.ErrInvalidParams } - appExecResult, err := s.chain.GetAppExecResult(txHash) + appExecResult, err := s.chain.GetAppExecResult(hash) if err != nil { - return nil, response.NewRPCError("Unknown transaction", "", err) + return nil, response.NewRPCError("Unknown transaction or block", "", err) } return appExecResult, nil