mirror of
https://gitlab.com/pulsechaincom/erigon-pulse.git
synced 2025-01-05 10:32:19 +00:00
144 lines
4.3 KiB
Go
144 lines
4.3 KiB
Go
package requests
|
|
|
|
import (
|
|
"encoding/json"
|
|
"fmt"
|
|
|
|
"github.com/ledgerwatch/erigon-lib/common/hexutil"
|
|
|
|
libcommon "github.com/ledgerwatch/erigon-lib/common"
|
|
"github.com/ledgerwatch/erigon-lib/common/hexutility"
|
|
"github.com/ledgerwatch/erigon/rpc"
|
|
"github.com/ledgerwatch/erigon/turbo/adapter/ethapi"
|
|
)
|
|
|
|
type TraceCall struct {
|
|
CommonResponse
|
|
Result TraceCallResult `json:"result"`
|
|
}
|
|
|
|
type TraceCallResult struct {
|
|
Output hexutility.Bytes `json:"output"`
|
|
Trace []CallTrace `json:"trace"`
|
|
StateDiff map[libcommon.Address]TraceCallStateDiff `json:"stateDiff"`
|
|
}
|
|
|
|
type CallTrace struct {
|
|
Type string `json:"type"`
|
|
Action TraceCallAction `json:"action"`
|
|
Result *CallResult `json:"result"`
|
|
Subtraces int `json:"subtraces"`
|
|
TraceAddress []int `json:"traceAddress"`
|
|
Error string `json:"error"`
|
|
}
|
|
|
|
// TraceCallAction is superset of all possible action types
|
|
type TraceCallAction struct {
|
|
From libcommon.Address `json:"from"`
|
|
To libcommon.Address `json:"to"`
|
|
Address libcommon.Address `json:"address"`
|
|
RefundAddress libcommon.Address `json:"refundAddress"`
|
|
Gas hexutil.Big `json:"gas"`
|
|
Value hexutil.Big `json:"value"`
|
|
Balance hexutil.Big `json:"balance"`
|
|
Init hexutility.Bytes `json:"init"`
|
|
Input hexutility.Bytes `json:"input"`
|
|
CallType string `json:"callType"`
|
|
}
|
|
|
|
type CallResult struct {
|
|
GasUsed hexutil.Big `json:"gasUsed"`
|
|
Output hexutility.Bytes `json:"output"`
|
|
Address libcommon.Address `json:"address"`
|
|
Code hexutility.Bytes `json:"code"`
|
|
}
|
|
|
|
type TraceCallStateDiff struct {
|
|
Balance interface{} `json:"balance"`
|
|
Nonce interface{} `json:"nonce"`
|
|
Code interface{} `json:"code"`
|
|
Storage map[libcommon.Hash]map[string]TraceCallStateDiffStorage `json:"storage"`
|
|
}
|
|
|
|
type TraceCallStateDiffStorage struct {
|
|
From libcommon.Hash `json:"from"`
|
|
To libcommon.Hash `json:"to"`
|
|
}
|
|
|
|
type TransactionTrace struct {
|
|
Type string `json:"type"`
|
|
Action TraceCallAction `json:"action"`
|
|
Result *CallResult `json:"result"`
|
|
Error string `json:"error"`
|
|
BlockHash libcommon.Hash `json:"blockHash"`
|
|
BlockNumber uint64 `json:"blockNumber"`
|
|
TransactionHash libcommon.Hash `json:"transactionHash"`
|
|
TransactionPosition uint64 `json:"transactionPosition"`
|
|
Subtraces int `json:"subtraces"`
|
|
TraceAddress []int `json:"traceAddress"`
|
|
}
|
|
|
|
type TraceOpt string
|
|
|
|
var TraceOpts = struct {
|
|
VmTrace TraceOpt
|
|
Trace TraceOpt
|
|
StateDiff TraceOpt
|
|
}{
|
|
VmTrace: "vmTrace",
|
|
Trace: "trace",
|
|
StateDiff: "stateDiff",
|
|
}
|
|
|
|
func (reqGen *requestGenerator) TraceCall(blockRef rpc.BlockReference, args ethapi.CallArgs, traceOpts ...TraceOpt) (*TraceCallResult, error) {
|
|
var b TraceCall
|
|
|
|
if args.Data == nil {
|
|
args.Data = &hexutility.Bytes{}
|
|
}
|
|
|
|
argsVal, err := json.Marshal(args)
|
|
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
if len(traceOpts) == 0 {
|
|
traceOpts = []TraceOpt{TraceOpts.Trace, TraceOpts.StateDiff}
|
|
}
|
|
|
|
optsVal, err := json.Marshal(traceOpts)
|
|
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
method, body := reqGen.traceCall(blockRef, string(argsVal), string(optsVal))
|
|
res := reqGen.rpcCallJSON(method, body, &b)
|
|
|
|
if res.Err != nil {
|
|
return nil, fmt.Errorf("TraceCall rpc failed: %w", res.Err)
|
|
}
|
|
|
|
if b.Error != nil {
|
|
return nil, fmt.Errorf("TraceCall rpc failed: %w", b.Error)
|
|
}
|
|
|
|
return &b.Result, nil
|
|
}
|
|
|
|
func (req *requestGenerator) traceCall(blockRef rpc.BlockReference, callArgs string, traceOpts string) (RPCMethod, string) {
|
|
const template = `{"jsonrpc":"2.0","method":%q,"params":[%s,%s,"%s"],"id":%d}`
|
|
return Methods.TraceCall, fmt.Sprintf(template, Methods.TraceCall, callArgs, traceOpts, blockRef.String(), req.reqID)
|
|
}
|
|
|
|
func (reqGen *requestGenerator) TraceTransaction(hash libcommon.Hash) ([]TransactionTrace, error) {
|
|
var result []TransactionTrace
|
|
|
|
if err := reqGen.rpcCall(&result, Methods.TraceTransaction, hash); err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
return result, nil
|
|
}
|