Do not return interface{} from trace api methods

This commit is contained in:
Fridrik Asmundsson 2023-08-22 11:05:28 +00:00
parent ebb54bc381
commit 4068e0710d
10 changed files with 137 additions and 77 deletions

View File

@ -871,9 +871,9 @@ type FullNode interface {
// TraceAPI related methods
//
// Returns traces created at given block
TraceBlock(ctx context.Context, blkNum string) (interface{}, error) //perm:read
TraceBlock(ctx context.Context, blkNum string) ([]*ethtypes.TraceBlock, error) //perm:read
// Replays all transactions in a block returning the requested traces for each transaction
TraceReplayBlockTransactions(ctx context.Context, blkNum string, traceTypes []string) (interface{}, error) //perm:read
TraceReplayBlockTransactions(ctx context.Context, blkNum string, traceTypes []string) ([]*ethtypes.TraceReplayBlockTransaction, error) //perm:read
// CreateBackup creates node backup onder the specified file name. The
// method requires that the lotus daemon is running with the

View File

@ -127,6 +127,6 @@ type Gateway interface {
EthSubscribe(ctx context.Context, params jsonrpc.RawParams) (ethtypes.EthSubscriptionID, error)
EthUnsubscribe(ctx context.Context, id ethtypes.EthSubscriptionID) (bool, error)
Web3ClientVersion(ctx context.Context) (string, error)
TraceBlock(ctx context.Context, blkNum string) (interface{}, error)
TraceReplayBlockTransactions(ctx context.Context, blkNum string, traceTypes []string) (interface{}, error)
TraceBlock(ctx context.Context, blkNum string) ([]*ethtypes.TraceBlock, error)
TraceReplayBlockTransactions(ctx context.Context, blkNum string, traceTypes []string) ([]*ethtypes.TraceReplayBlockTransaction, error)
}

View File

@ -4024,10 +4024,10 @@ func (mr *MockFullNodeMockRecorder) SyncValidateTipset(arg0, arg1 interface{}) *
}
// TraceBlock mocks base method.
func (m *MockFullNode) TraceBlock(arg0 context.Context, arg1 string) (interface{}, error) {
func (m *MockFullNode) TraceBlock(arg0 context.Context, arg1 string) ([]*ethtypes.TraceBlock, error) {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "TraceBlock", arg0, arg1)
ret0, _ := ret[0].(interface{})
ret0, _ := ret[0].([]*ethtypes.TraceBlock)
ret1, _ := ret[1].(error)
return ret0, ret1
}
@ -4039,10 +4039,10 @@ func (mr *MockFullNodeMockRecorder) TraceBlock(arg0, arg1 interface{}) *gomock.C
}
// TraceReplayBlockTransactions mocks base method.
func (m *MockFullNode) TraceReplayBlockTransactions(arg0 context.Context, arg1 string, arg2 []string) (interface{}, error) {
func (m *MockFullNode) TraceReplayBlockTransactions(arg0 context.Context, arg1 string, arg2 []string) ([]*ethtypes.TraceReplayBlockTransaction, error) {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "TraceReplayBlockTransactions", arg0, arg1, arg2)
ret0, _ := ret[0].(interface{})
ret0, _ := ret[0].([]*ethtypes.TraceReplayBlockTransaction)
ret1, _ := ret[1].(error)
return ret0, ret1
}

View File

@ -596,9 +596,9 @@ type FullNodeMethods struct {
SyncValidateTipset func(p0 context.Context, p1 types.TipSetKey) (bool, error) `perm:"read"`
TraceBlock func(p0 context.Context, p1 string) (interface{}, error) `perm:"read"`
TraceBlock func(p0 context.Context, p1 string) ([]*ethtypes.TraceBlock, error) `perm:"read"`
TraceReplayBlockTransactions func(p0 context.Context, p1 string, p2 []string) (interface{}, error) `perm:"read"`
TraceReplayBlockTransactions func(p0 context.Context, p1 string, p2 []string) ([]*ethtypes.TraceReplayBlockTransaction, error) `perm:"read"`
WalletBalance func(p0 context.Context, p1 address.Address) (types.BigInt, error) `perm:"read"`
@ -818,9 +818,9 @@ type GatewayMethods struct {
StateWaitMsg func(p0 context.Context, p1 cid.Cid, p2 uint64, p3 abi.ChainEpoch, p4 bool) (*MsgLookup, error) ``
TraceBlock func(p0 context.Context, p1 string) (interface{}, error) ``
TraceBlock func(p0 context.Context, p1 string) ([]*ethtypes.TraceBlock, error) ``
TraceReplayBlockTransactions func(p0 context.Context, p1 string, p2 []string) (interface{}, error) ``
TraceReplayBlockTransactions func(p0 context.Context, p1 string, p2 []string) ([]*ethtypes.TraceReplayBlockTransaction, error) ``
Version func(p0 context.Context) (APIVersion, error) ``
@ -4005,26 +4005,26 @@ func (s *FullNodeStub) SyncValidateTipset(p0 context.Context, p1 types.TipSetKey
return false, ErrNotSupported
}
func (s *FullNodeStruct) TraceBlock(p0 context.Context, p1 string) (interface{}, error) {
func (s *FullNodeStruct) TraceBlock(p0 context.Context, p1 string) ([]*ethtypes.TraceBlock, error) {
if s.Internal.TraceBlock == nil {
return nil, ErrNotSupported
return *new([]*ethtypes.TraceBlock), ErrNotSupported
}
return s.Internal.TraceBlock(p0, p1)
}
func (s *FullNodeStub) TraceBlock(p0 context.Context, p1 string) (interface{}, error) {
return nil, ErrNotSupported
func (s *FullNodeStub) TraceBlock(p0 context.Context, p1 string) ([]*ethtypes.TraceBlock, error) {
return *new([]*ethtypes.TraceBlock), ErrNotSupported
}
func (s *FullNodeStruct) TraceReplayBlockTransactions(p0 context.Context, p1 string, p2 []string) (interface{}, error) {
func (s *FullNodeStruct) TraceReplayBlockTransactions(p0 context.Context, p1 string, p2 []string) ([]*ethtypes.TraceReplayBlockTransaction, error) {
if s.Internal.TraceReplayBlockTransactions == nil {
return nil, ErrNotSupported
return *new([]*ethtypes.TraceReplayBlockTransaction), ErrNotSupported
}
return s.Internal.TraceReplayBlockTransactions(p0, p1, p2)
}
func (s *FullNodeStub) TraceReplayBlockTransactions(p0 context.Context, p1 string, p2 []string) (interface{}, error) {
return nil, ErrNotSupported
func (s *FullNodeStub) TraceReplayBlockTransactions(p0 context.Context, p1 string, p2 []string) ([]*ethtypes.TraceReplayBlockTransaction, error) {
return *new([]*ethtypes.TraceReplayBlockTransaction), ErrNotSupported
}
func (s *FullNodeStruct) WalletBalance(p0 context.Context, p1 address.Address) (types.BigInt, error) {
@ -5160,26 +5160,26 @@ func (s *GatewayStub) StateWaitMsg(p0 context.Context, p1 cid.Cid, p2 uint64, p3
return nil, ErrNotSupported
}
func (s *GatewayStruct) TraceBlock(p0 context.Context, p1 string) (interface{}, error) {
func (s *GatewayStruct) TraceBlock(p0 context.Context, p1 string) ([]*ethtypes.TraceBlock, error) {
if s.Internal.TraceBlock == nil {
return nil, ErrNotSupported
return *new([]*ethtypes.TraceBlock), ErrNotSupported
}
return s.Internal.TraceBlock(p0, p1)
}
func (s *GatewayStub) TraceBlock(p0 context.Context, p1 string) (interface{}, error) {
return nil, ErrNotSupported
func (s *GatewayStub) TraceBlock(p0 context.Context, p1 string) ([]*ethtypes.TraceBlock, error) {
return *new([]*ethtypes.TraceBlock), ErrNotSupported
}
func (s *GatewayStruct) TraceReplayBlockTransactions(p0 context.Context, p1 string, p2 []string) (interface{}, error) {
func (s *GatewayStruct) TraceReplayBlockTransactions(p0 context.Context, p1 string, p2 []string) ([]*ethtypes.TraceReplayBlockTransaction, error) {
if s.Internal.TraceReplayBlockTransactions == nil {
return nil, ErrNotSupported
return *new([]*ethtypes.TraceReplayBlockTransaction), ErrNotSupported
}
return s.Internal.TraceReplayBlockTransactions(p0, p1, p2)
}
func (s *GatewayStub) TraceReplayBlockTransactions(p0 context.Context, p1 string, p2 []string) (interface{}, error) {
return nil, ErrNotSupported
func (s *GatewayStub) TraceReplayBlockTransactions(p0 context.Context, p1 string, p2 []string) ([]*ethtypes.TraceReplayBlockTransaction, error) {
return *new([]*ethtypes.TraceReplayBlockTransaction), ErrNotSupported
}
func (s *GatewayStruct) Version(p0 context.Context) (APIVersion, error) {

View File

@ -1,4 +1,4 @@
package full
package ethtypes
import (
"bytes"
@ -8,6 +8,7 @@ import (
"io"
"github.com/ipfs/go-cid"
logging "github.com/ipfs/go-log/v2"
"github.com/filecoin-project/go-state-types/abi"
"github.com/filecoin-project/go-state-types/builtin"
@ -15,9 +16,10 @@ import (
builtinactors "github.com/filecoin-project/lotus/chain/actors/builtin"
"github.com/filecoin-project/lotus/chain/types"
"github.com/filecoin-project/lotus/chain/types/ethtypes"
)
var log = logging.Logger("traceapi")
type Trace struct {
Action Action `json:"action"`
Result Result `json:"result"`
@ -35,51 +37,51 @@ func (t *Trace) setCallType(callType string) {
type TraceBlock struct {
*Trace
BlockHash ethtypes.EthHash `json:"blockHash"`
BlockNumber int64 `json:"blockNumber"`
TransactionHash ethtypes.EthHash `json:"transactionHash"`
TransactionPosition int `json:"transactionPosition"`
BlockHash EthHash `json:"blockHash"`
BlockNumber int64 `json:"blockNumber"`
TransactionHash EthHash `json:"transactionHash"`
TransactionPosition int `json:"transactionPosition"`
}
type TraceReplayBlockTransaction struct {
Output string `json:"output"`
StateDiff *string `json:"stateDiff"`
Trace []*Trace `json:"trace"`
TransactionHash ethtypes.EthHash `json:"transactionHash"`
VmTrace *string `json:"vmTrace"`
Output string `json:"output"`
StateDiff *string `json:"stateDiff"`
Trace []*Trace `json:"trace"`
TransactionHash EthHash `json:"transactionHash"`
VmTrace *string `json:"vmTrace"`
}
type Action struct {
CallType string `json:"callType"`
From string `json:"from"`
To string `json:"to"`
Gas ethtypes.EthUint64 `json:"gas"`
Input string `json:"input"`
Value ethtypes.EthBigInt `json:"value"`
CallType string `json:"callType"`
From string `json:"from"`
To string `json:"to"`
Gas EthUint64 `json:"gas"`
Input string `json:"input"`
Value EthBigInt `json:"value"`
method abi.MethodNum `json:"-"`
codeCid cid.Cid `json:"-"`
}
type Result struct {
GasUsed ethtypes.EthUint64 `json:"gasUsed"`
Output string `json:"output"`
GasUsed EthUint64 `json:"gasUsed"`
Output string `json:"output"`
}
// buildTraces recursively builds the traces for a given ExecutionTrace by walking the subcalls
func buildTraces(traces *[]*Trace, parent *Trace, addr []int, et types.ExecutionTrace, height int64) error {
// BuildTraces recursively builds the traces for a given ExecutionTrace by walking the subcalls
func BuildTraces(traces *[]*Trace, parent *Trace, addr []int, et types.ExecutionTrace, height int64) error {
trace := &Trace{
Action: Action{
From: et.Msg.From.String(),
To: et.Msg.To.String(),
Gas: ethtypes.EthUint64(et.Msg.GasLimit),
Gas: EthUint64(et.Msg.GasLimit),
Input: hex.EncodeToString(et.Msg.Params),
Value: ethtypes.EthBigInt(et.Msg.Value),
Value: EthBigInt(et.Msg.Value),
method: et.Msg.Method,
codeCid: et.Msg.CodeCid,
},
Result: Result{
GasUsed: ethtypes.EthUint64(et.SumGas().TotalGas),
GasUsed: EthUint64(et.SumGas().TotalGas),
Output: hex.EncodeToString(et.MsgRct.Return),
},
Subtraces: len(et.Subcalls),
@ -218,7 +220,7 @@ func buildTraces(traces *[]*Trace, parent *Trace, addr []int, et types.Execution
*traces = append(*traces, trace)
for i, call := range et.Subcalls {
err := buildTraces(traces, trace, append(addr, i), call, height)
err := BuildTraces(traces, trace, append(addr, i), call, height)
if err != nil {
return err
}

View File

@ -8841,7 +8841,34 @@ Inputs:
]
```
Response: `{}`
Response:
```json
[
{
"action": {
"callType": "string value",
"from": "string value",
"to": "string value",
"gas": "0x5",
"input": "string value",
"value": "0x0"
},
"result": {
"gasUsed": "0x5",
"output": "string value"
},
"subtraces": 123,
"traceAddress": [
123
],
"Type": "string value",
"blockHash": "0x37690cfec6c1bf4c3b9288c7a5d783e98731e90b0a4c177c2a374c7a9427355e",
"blockNumber": 9,
"transactionHash": "0x37690cfec6c1bf4c3b9288c7a5d783e98731e90b0a4c177c2a374c7a9427355e",
"transactionPosition": 123
}
]
```
### TraceReplayBlockTransactions
Replays all transactions in a block returning the requested traces for each transaction
@ -8859,7 +8886,38 @@ Inputs:
]
```
Response: `{}`
Response:
```json
[
{
"output": "string value",
"stateDiff": "string value",
"trace": [
{
"action": {
"callType": "string value",
"from": "string value",
"to": "string value",
"gas": "0x5",
"input": "string value",
"value": "0x0"
},
"result": {
"gasUsed": "0x5",
"output": "string value"
},
"subtraces": 123,
"traceAddress": [
123
],
"Type": "string value"
}
],
"transactionHash": "0x37690cfec6c1bf4c3b9288c7a5d783e98731e90b0a4c177c2a374c7a9427355e",
"vmTrace": "string value"
}
]
```
## Wallet

View File

@ -144,8 +144,8 @@ type TargetAPI interface {
EthSubscribe(ctx context.Context, params jsonrpc.RawParams) (ethtypes.EthSubscriptionID, error)
EthUnsubscribe(ctx context.Context, id ethtypes.EthSubscriptionID) (bool, error)
Web3ClientVersion(ctx context.Context) (string, error)
TraceBlock(ctx context.Context, blkNum string) (interface{}, error)
TraceReplayBlockTransactions(ctx context.Context, blkNum string, traceTypes []string) (interface{}, error)
TraceBlock(ctx context.Context, blkNum string) ([]*ethtypes.TraceBlock, error)
TraceReplayBlockTransactions(ctx context.Context, blkNum string, traceTypes []string) ([]*ethtypes.TraceReplayBlockTransaction, error)
}
var _ TargetAPI = *new(api.FullNode) // gateway depends on latest

View File

@ -582,25 +582,25 @@ func (gw *Node) Web3ClientVersion(ctx context.Context) (string, error) {
return gw.target.Web3ClientVersion(ctx)
}
func (gw *Node) TraceBlock(ctx context.Context, blkNum string) (interface{}, error) {
func (gw *Node) TraceBlock(ctx context.Context, blkNum string) ([]*ethtypes.TraceBlock, error) {
if err := gw.limit(ctx, stateRateLimitTokens); err != nil {
return 0, err
return nil, err
}
if err := gw.checkBlkParam(ctx, blkNum, 0); err != nil {
return ethtypes.EthBlock{}, err
return nil, err
}
return gw.target.TraceBlock(ctx, blkNum)
}
func (gw *Node) TraceReplayBlockTransactions(ctx context.Context, blkNum string, traceTypes []string) (interface{}, error) {
func (gw *Node) TraceReplayBlockTransactions(ctx context.Context, blkNum string, traceTypes []string) ([]*ethtypes.TraceReplayBlockTransaction, error) {
if err := gw.limit(ctx, stateRateLimitTokens); err != nil {
return 0, err
return nil, err
}
if err := gw.checkBlkParam(ctx, blkNum, 0); err != nil {
return ethtypes.EthBlock{}, err
return nil, err
}
return gw.target.TraceReplayBlockTransactions(ctx, blkNum, traceTypes)

View File

@ -178,11 +178,11 @@ func (e *EthModuleDummy) EthUnsubscribe(ctx context.Context, id ethtypes.EthSubs
return false, ErrModuleDisabled
}
func (e *EthModuleDummy) TraceBlock(ctx context.Context, blkNum string) (interface{}, error) {
func (e *EthModuleDummy) TraceBlock(ctx context.Context, blkNum string) ([]*ethtypes.TraceBlock, error) {
return nil, ErrModuleDisabled
}
func (e *EthModuleDummy) TraceReplayBlockTransactions(ctx context.Context, blkNum string, traceTypes []string) (interface{}, error) {
func (e *EthModuleDummy) TraceReplayBlockTransactions(ctx context.Context, blkNum string, traceTypes []string) ([]*ethtypes.TraceReplayBlockTransaction, error) {
return nil, ErrModuleDisabled
}

View File

@ -71,8 +71,8 @@ type EthModuleAPI interface {
EthMaxPriorityFeePerGas(ctx context.Context) (ethtypes.EthBigInt, error)
EthSendRawTransaction(ctx context.Context, rawTx ethtypes.EthBytes) (ethtypes.EthHash, error)
Web3ClientVersion(ctx context.Context) (string, error)
TraceBlock(ctx context.Context, blkNum string) (interface{}, error)
TraceReplayBlockTransactions(ctx context.Context, blkNum string, traceTypes []string) (interface{}, error)
TraceBlock(ctx context.Context, blkNum string) ([]*ethtypes.TraceBlock, error)
TraceReplayBlockTransactions(ctx context.Context, blkNum string, traceTypes []string) ([]*ethtypes.TraceReplayBlockTransaction, error)
}
type EthEventAPI interface {
@ -825,7 +825,7 @@ func (a *EthModule) Web3ClientVersion(ctx context.Context) (string, error) {
return build.UserVersion(), nil
}
func (a *EthModule) TraceBlock(ctx context.Context, blkNum string) (interface{}, error) {
func (a *EthModule) TraceBlock(ctx context.Context, blkNum string) ([]*ethtypes.TraceBlock, error) {
ts, err := getTipsetByBlockNr(ctx, a.Chain, blkNum, false)
if err != nil {
return nil, err
@ -856,7 +856,7 @@ func (a *EthModule) TraceBlock(ctx context.Context, blkNum string) (interface{},
return nil, err
}
allTraces := make([]*TraceBlock, 0, len(trace))
allTraces := make([]*ethtypes.TraceBlock, 0, len(trace))
for _, ir := range trace {
// ignore messages from f00
if ir.Msg.From.String() == "f00" {
@ -884,15 +884,15 @@ func (a *EthModule) TraceBlock(ctx context.Context, blkNum string) (interface{},
continue
}
traces := []*Trace{}
err = buildTraces(&traces, nil, []int{}, ir.ExecutionTrace, int64(ts.Height()))
traces := []*ethtypes.Trace{}
err = ethtypes.BuildTraces(&traces, nil, []int{}, ir.ExecutionTrace, int64(ts.Height()))
if err != nil {
return nil, xerrors.Errorf("failed when building traces: %w", err)
}
traceBlocks := make([]*TraceBlock, 0, len(trace))
traceBlocks := make([]*ethtypes.TraceBlock, 0, len(trace))
for _, trace := range traces {
traceBlocks = append(traceBlocks, &TraceBlock{
traceBlocks = append(traceBlocks, &ethtypes.TraceBlock{
Trace: trace,
BlockHash: blkHash,
BlockNumber: int64(ts.Height()),
@ -907,7 +907,7 @@ func (a *EthModule) TraceBlock(ctx context.Context, blkNum string) (interface{},
return allTraces, nil
}
func (a *EthModule) TraceReplayBlockTransactions(ctx context.Context, blkNum string, traceTypes []string) (interface{}, error) {
func (a *EthModule) TraceReplayBlockTransactions(ctx context.Context, blkNum string, traceTypes []string) ([]*ethtypes.TraceReplayBlockTransaction, error) {
if len(traceTypes) != 1 || traceTypes[0] != "trace" {
return nil, fmt.Errorf("only 'trace' is supported")
}
@ -922,7 +922,7 @@ func (a *EthModule) TraceReplayBlockTransactions(ctx context.Context, blkNum str
return nil, xerrors.Errorf("failed when calling ExecutionTrace: %w", err)
}
allTraces := make([]*TraceReplayBlockTransaction, 0, len(trace))
allTraces := make([]*ethtypes.TraceReplayBlockTransaction, 0, len(trace))
for _, ir := range trace {
// ignore messages from f00
if ir.Msg.From.String() == "f00" {
@ -938,14 +938,14 @@ func (a *EthModule) TraceReplayBlockTransactions(ctx context.Context, blkNum str
continue
}
t := TraceReplayBlockTransaction{
t := ethtypes.TraceReplayBlockTransaction{
Output: hex.EncodeToString(ir.MsgRct.Return),
TransactionHash: *txHash,
StateDiff: nil,
VmTrace: nil,
}
err = buildTraces(&t.Trace, nil, []int{}, ir.ExecutionTrace, int64(ts.Height()))
err = ethtypes.BuildTraces(&t.Trace, nil, []int{}, ir.ExecutionTrace, int64(ts.Height()))
if err != nil {
return nil, xerrors.Errorf("failed when building traces: %w", err)
}