Skip to content

Commit

Permalink
Merge pull request #545 from XinFinOrg/traceCall2
Browse files Browse the repository at this point in the history
TraceCall API
  • Loading branch information
wgr523 authored May 20, 2024
2 parents 09eb612 + b2605e6 commit d6a5095
Show file tree
Hide file tree
Showing 10 changed files with 283 additions and 21 deletions.
12 changes: 11 additions & 1 deletion cmd/utils/flags.go
Original file line number Diff line number Diff line change
Expand Up @@ -118,7 +118,7 @@ var (
Enable0xPrefixFlag = cli.BoolFlag{
Name: "enable-0x-prefix",
Usage: "Addres use 0x-prefix (Deprecated: this is on by default, to use xdc prefix use --enable-xdc-prefix)",
}
}
EnableXDCPrefixFlag = cli.BoolFlag{
Name: "enable-xdc-prefix",
Usage: "Addres use xdc-prefix (default = false)",
Expand Down Expand Up @@ -358,6 +358,11 @@ var (
Name: "vmdebug",
Usage: "Record information useful for VM and contract debugging",
}
RPCGlobalGasCapFlag = cli.Uint64Flag{
Name: "rpc.gascap",
Usage: "Sets a cap on gas that can be used in eth_call/estimateGas (0=infinite)",
Value: eth.DefaultConfig.RPCGasCap,
}
// Logging and debug settings
EthStatsURLFlag = cli.StringFlag{
Name: "ethstats",
Expand Down Expand Up @@ -1176,6 +1181,11 @@ func SetEthConfig(ctx *cli.Context, stack *node.Node, cfg *eth.Config) {
// TODO(fjl): force-enable this in --dev mode
cfg.EnablePreimageRecording = ctx.GlobalBool(VMEnableDebugFlag.Name)
}
if cfg.RPCGasCap != 0 {
log.Info("Set global gas cap", "cap", cfg.RPCGasCap)
} else {
log.Info("Global gas cap disabled")
}
if ctx.GlobalIsSet(StoreRewardFlag.Name) {
common.StoreRewardFolder = filepath.Join(stack.DataDir(), "XDC", "rewards")
if _, err := os.Stat(common.StoreRewardFolder); os.IsNotExist(err) {
Expand Down
8 changes: 8 additions & 0 deletions eth/api_backend.go
Original file line number Diff line number Diff line change
Expand Up @@ -348,6 +348,10 @@ func (b *EthApiBackend) EventMux() *event.TypeMux {
return b.eth.EventMux()
}

func (b *EthApiBackend) RPCGasCap() uint64 {
return b.eth.config.RPCGasCap
}

func (b *EthApiBackend) AccountManager() *accounts.Manager {
return b.eth.AccountManager()
}
Expand Down Expand Up @@ -377,6 +381,10 @@ func (b *EthApiBackend) GetEngine() consensus.Engine {
return b.eth.engine
}

func (b *EthApiBackend) StateAtBlock(ctx context.Context, block *types.Block, reexec uint64, base *state.StateDB, checkLive bool) (*state.StateDB, error) {
return b.eth.stateAtBlock(block, reexec, base, checkLive)
}

func (s *EthApiBackend) GetRewardByHash(hash common.Hash) map[string]map[string]map[string]*big.Int {
header := s.eth.blockchain.GetHeaderByHash(hash)
if header != nil {
Expand Down
60 changes: 60 additions & 0 deletions eth/api_tracer.go
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,13 @@ type txTraceContext struct {
block common.Hash // Hash of the block containing the transaction
}

// TraceCallConfig is the config for traceCall API. It holds one more
// field to override the state for tracing.
type TraceCallConfig struct {
TraceConfig
StateOverrides *ethapi.StateOverride
}

// txTraceResult is the result of a single transaction trace.
type txTraceResult struct {
Result interface{} `json:"result,omitempty"` // Trace results produced by the tracer
Expand Down Expand Up @@ -622,6 +629,59 @@ func (api *PrivateDebugAPI) TraceTransaction(ctx context.Context, hash common.Ha
return api.traceTx(ctx, msg, txctx, vmctx, statedb, config)
}

// TraceCall lets you trace a given eth_call. It collects the structured logs
// created during the execution of EVM if the given transaction was added on
// top of the provided block and returns them as a JSON object.
// You can provide -2 as a block number to trace on top of the pending block.
func (api *PrivateDebugAPI) TraceCall(ctx context.Context, args ethapi.CallArgs, blockNrOrHash rpc.BlockNumberOrHash, config *TraceCallConfig) (interface{}, error) {
// Try to retrieve the specified block
var (
err error
block *types.Block
)
if hash, ok := blockNrOrHash.Hash(); ok {
block, err = api.eth.ApiBackend.BlockByHash(ctx, hash)
} else if number, ok := blockNrOrHash.Number(); ok {
if number == rpc.PendingBlockNumber {
// We don't have access to the miner here. For tracing 'future' transactions,
// it can be done with block- and state-overrides instead, which offers
// more flexibility and stability than trying to trace on 'pending', since
// the contents of 'pending' is unstable and probably not a true representation
// of what the next actual block is likely to contain.
return nil, errors.New("tracing on top of pending is not supported")
}
block, err = api.eth.ApiBackend.BlockByNumber(ctx, number)
} else {
return nil, errors.New("invalid arguments; neither block nor hash specified")
}
if err != nil {
return nil, err
}
// try to recompute the state
reexec := defaultTraceReexec
if config != nil && config.Reexec != nil {
reexec = *config.Reexec
}
statedb, err := api.eth.ApiBackend.StateAtBlock(ctx, block, reexec, nil, true)
if err != nil {
return nil, err
}
// Apply the customized state rules if required.
if config != nil {
if err := config.StateOverrides.Apply(statedb); err != nil {
return nil, err
}
}
// Execute the trace
msg := args.ToMessage(api.eth.ApiBackend, block.Number(), api.eth.ApiBackend.RPCGasCap())
vmctx := core.NewEVMContext(msg, block.Header(), api.eth.blockchain, nil)
var traceConfig *TraceConfig
if config != nil {
traceConfig = &config.TraceConfig
}
return api.traceTx(ctx, msg, new(txTraceContext), vmctx, statedb, traceConfig)
}

// traceTx configures a new tracer according to the provided configuration, and
// executes the given message in the provided environment. The return value will
// be tracer dependent.
Expand Down
6 changes: 5 additions & 1 deletion eth/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,8 @@ var DefaultConfig = Config{
TrieTimeout: 5 * time.Minute,
GasPrice: big.NewInt(0.25 * params.Shannon),

TxPool: core.DefaultTxPoolConfig,
TxPool: core.DefaultTxPoolConfig,
RPCGasCap: 25000000,
GPO: gasprice.Config{
Blocks: 20,
Percentile: 60,
Expand Down Expand Up @@ -114,6 +115,9 @@ type Config struct {

// Miscellaneous options
DocRoot string `toml:"-"`

// RPCGasCap is the global gas cap for eth-call variants.
RPCGasCap uint64
}

type configMarshaling struct {
Expand Down
36 changes: 30 additions & 6 deletions eth/gen_config.go

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

Loading

0 comments on commit d6a5095

Please sign in to comment.