Skip to content

Commit

Permalink
Merge pull request #313 from forta-network/kisel/forta-1728-transacti…
Browse files Browse the repository at this point in the history
…on-forwarding

Debug and trace method in eth client
  • Loading branch information
dkeysil authored Aug 26, 2024
2 parents edccde9 + d44d6ee commit 04a9823
Show file tree
Hide file tree
Showing 3 changed files with 85 additions and 7 deletions.
23 changes: 23 additions & 0 deletions domain/ethereum.go
Original file line number Diff line number Diff line change
Expand Up @@ -289,6 +289,29 @@ type TransactionReceipt struct {
TransactionIndex *string `json:"transactionIndex"`
}

// 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"`
GasPrice *int64 `json:"gasPrice,omitempty"`
Value *int64 `json:"value,omitempty"`
Data string `json:"data"`
}

// 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 {
From *string `json:"from"`
Expand Down
55 changes: 48 additions & 7 deletions ethereum/client.go
Original file line number Diff line number Diff line change
Expand Up @@ -63,19 +63,27 @@ 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)
DebugTraceCall(
ctx context.Context, req *domain.TraceCallTransaction,
block any, traceCallConfig domain.TraceCallConfig,
result interface{},
) error
GetLogs(ctx context.Context, q ethereum.FilterQuery) ([]types.Log, error)
SubscribeToHead(ctx context.Context) (domain.HeaderCh, error)

health.Reporter
}

const blocksByNumber = "eth_getBlockByNumber"
const blocksByHash = "eth_getBlockByHash"
const blockNumber = "eth_blockNumber"
const getLogs = "eth_getLogs"
const transactionReceipt = "eth_getTransactionReceipt"
const traceBlock = "trace_block"
const chainId = "eth_chainId"
const (
blocksByNumber = "eth_getBlockByNumber"
blocksByHash = "eth_getBlockByHash"
blockNumber = "eth_blockNumber"
getLogs = "eth_getLogs"
transactionReceipt = "eth_getTransactionReceipt"
traceBlock = "trace_block"
debugTraceCall = "debug_traceCall"
chainId = "eth_chainId"
)

const defaultRetryInterval = time.Second * 15

Expand Down Expand Up @@ -242,6 +250,39 @@ func (e *streamEthClient) TraceBlock(ctx context.Context, number *big.Int) ([]do
return result, err
}

// DebugTraceCall returns the traces of a call.
func (e *streamEthClient) DebugTraceCall(
ctx context.Context, req *domain.TraceCallTransaction,
block any, traceCallConfig domain.TraceCallConfig,
result interface{},
) error {
name := fmt.Sprintf("%s(%v)", debugTraceCall, req)
log.Debugf(name)

switch block.(type) {
case string:
case *rpc.BlockNumberOrHash:
default:
return errors.New("invalid block number type")
}

args := []interface{}{req, block, traceCallConfig}

err := withBackoff(ctx, name, func(ctx context.Context) error {
err := e.rpcClient.CallContext(ctx, &result, debugTraceCall, args...)
if err != nil {
return err
}

return nil
}, RetryOptions{
MinBackoff: pointDur(e.retryInterval),
MaxElapsedTime: pointDur(1 * time.Minute),
MaxBackoff: pointDur(e.retryInterval),
}, nil, nil)
return err
}

// GetLogs returns the set of logs for a block
func (e *streamEthClient) GetLogs(ctx context.Context, q ethereum.FilterQuery) ([]types.Log, error) {
name := fmt.Sprintf("%s(%v)", getLogs, q)
Expand Down
14 changes: 14 additions & 0 deletions ethereum/mocks/mock_client.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

0 comments on commit 04a9823

Please sign in to comment.