diff --git a/domain/ethereum.go b/domain/ethereum.go index bddb984..2a3a6f0 100644 --- a/domain/ethereum.go +++ b/domain/ethereum.go @@ -289,8 +289,8 @@ type TransactionReceipt struct { TransactionIndex *string `json:"transactionIndex"` } -// DebugTraceCallTransaction The transaction call object which contains the following fields -type DebugTraceCallTransaction struct { +// TraceCallTransaction contains the fields of the to-be-simulated transaction. +type TraceCallTransaction struct { From string `json:"from"` To string `json:"to"` Gas *int64 `json:"gas,omitempty"` @@ -299,7 +299,18 @@ type DebugTraceCallTransaction struct { Data string `json:"data"` } -type CustomDebugTraceCallResult struct{} +// TraceCallConfig contains the tracer configuration to be used while simulating the transaction. +type TraceCallConfig struct { + Tracer string `json:"tracer,omitempty"` + TracerConfig *TracerConfig `json:"tracerConfig,omitempty"` + StateOverrides map[string]interface{} `json:"stateOverrides,omitempty"` +} + +// TracerConfig contains some extra tracer parameters. +type TracerConfig struct { + WithLog bool `json:"withLog,omitempty"` + OnlyTopCall bool `json:"onlyTopCall,omitempty"` +} // TraceAction is an element of a trace_block Trace response type TraceAction struct { diff --git a/ethereum/client.go b/ethereum/client.go index 3b988d4..b6eeff4 100644 --- a/ethereum/client.go +++ b/ethereum/client.go @@ -63,7 +63,11 @@ type Client interface { TransactionReceipt(ctx context.Context, txHash string) (*domain.TransactionReceipt, error) ChainID(ctx context.Context) (*big.Int, error) TraceBlock(ctx context.Context, number *big.Int) ([]domain.Trace, error) - CustomDebugTraceCall(ctx context.Context, req domain.DebugTraceCallTransaction, stateOverrides map[string]interface{}) (*domain.CustomDebugTraceCallResult, error) + DebugTraceCall( + ctx context.Context, req *domain.TraceCallTransaction, + block *rpc.BlockNumberOrHash, traceCallConfig domain.TraceCallConfig, + result interface{}, + ) error GetLogs(ctx context.Context, q ethereum.FilterQuery) ([]types.Log, error) SubscribeToHead(ctx context.Context) (domain.HeaderCh, error) @@ -246,17 +250,15 @@ func (e *streamEthClient) TraceBlock(ctx context.Context, number *big.Int) ([]do return result, err } -// CustomDebugTraceCall returns traced call with custom js tracer -func (e *streamEthClient) CustomDebugTraceCall( - ctx context.Context, req domain.DebugTraceCallTransaction, stateOverrides map[string]interface{}, -) (*domain.CustomDebugTraceCallResult, error) { +// DebugTraceCall returns the traces of a call. +func (e *streamEthClient) DebugTraceCall( + ctx context.Context, req *domain.TraceCallTransaction, + block *rpc.BlockNumberOrHash, traceCallConfig domain.TraceCallConfig, + result interface{}, +) error { name := fmt.Sprintf("%s(%v)", debugTraceCall, req) log.Debugf(name) - var result domain.CustomDebugTraceCallResult - args := []interface{}{req, []string{"trace"}, "latest"} - if stateOverrides != nil { - args = append(args, map[string]interface{}{"stateOverrides": stateOverrides}) - } + args := []interface{}{req, block, traceCallConfig} err := withBackoff(ctx, name, func(ctx context.Context) error { err := e.rpcClient.CallContext(ctx, &result, debugTraceCall, args...) @@ -270,8 +272,7 @@ func (e *streamEthClient) CustomDebugTraceCall( MaxElapsedTime: pointDur(1 * time.Minute), MaxBackoff: pointDur(e.retryInterval), }, nil, nil) - - return &result, err + return err } // GetLogs returns the set of logs for a block diff --git a/ethereum/mocks/mock_client.go b/ethereum/mocks/mock_client.go index 51b827e..00867c9 100644 --- a/ethereum/mocks/mock_client.go +++ b/ethereum/mocks/mock_client.go @@ -13,6 +13,7 @@ import ( ethereum "github.com/ethereum/go-ethereum" common "github.com/ethereum/go-ethereum/common" types "github.com/ethereum/go-ethereum/core/types" + rpc "github.com/ethereum/go-ethereum/rpc" health "github.com/forta-network/forta-core-go/clients/health" domain "github.com/forta-network/forta-core-go/domain" gomock "github.com/golang/mock/gomock" @@ -570,19 +571,18 @@ func (mr *MockClientMockRecorder) Close() *gomock.Call { return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Close", reflect.TypeOf((*MockClient)(nil).Close)) } -// CustomDebugTraceCall mocks base method. -func (m *MockClient) CustomDebugTraceCall(ctx context.Context, req domain.DebugTraceCallTransaction, stateOverrides map[string]interface{}) (*domain.CustomDebugTraceCallResult, error) { +// DebugTraceCall mocks base method. +func (m *MockClient) DebugTraceCall(ctx context.Context, req *domain.TraceCallTransaction, block *rpc.BlockNumberOrHash, traceCallConfig domain.TraceCallConfig, result interface{}) error { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "CustomDebugTraceCall", ctx, req, stateOverrides) - ret0, _ := ret[0].(*domain.CustomDebugTraceCallResult) - ret1, _ := ret[1].(error) - return ret0, ret1 + ret := m.ctrl.Call(m, "DebugTraceCall", ctx, req, block, traceCallConfig, result) + ret0, _ := ret[0].(error) + return ret0 } -// CustomDebugTraceCall indicates an expected call of CustomDebugTraceCall. -func (mr *MockClientMockRecorder) CustomDebugTraceCall(ctx, req, stateOverrides interface{}) *gomock.Call { +// DebugTraceCall indicates an expected call of DebugTraceCall. +func (mr *MockClientMockRecorder) DebugTraceCall(ctx, req, block, traceCallConfig, result interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "CustomDebugTraceCall", reflect.TypeOf((*MockClient)(nil).CustomDebugTraceCall), ctx, req, stateOverrides) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DebugTraceCall", reflect.TypeOf((*MockClient)(nil).DebugTraceCall), ctx, req, block, traceCallConfig, result) } // GetLogs mocks base method.