diff --git a/docs/developers/evm-tracing/built-in-tracers.md b/docs/developers/evm-tracing/built-in-tracers.md
index 2eb7e098c5..305acfc8aa 100644
--- a/docs/developers/evm-tracing/built-in-tracers.md
+++ b/docs/developers/evm-tracing/built-in-tracers.md
@@ -26,6 +26,15 @@ The struct logger (aka opcode logger) is a native Go tracer which executes a tra
Note that the fields `memory`, `stack`, `returnData`, and `storage` have dynamic size and depending on the exact transaction they could grow large in size. This is specially true for `memory` which could blow up the trace size. It is recommended to keep them disabled unless they are explicitly required for a given use case.
+### opcode config{#struct-opcode-config}
+
+- `enableMemory`: `BOOL`. Setting this to true will enable memory capture (default = false).
+- `disableStack`: `BOOL`. Setting this to true will disable stack capture (default = false).
+- `disableStorage`: `BOOL`. Setting this to true will disable storage capture (default = false).
+- `enableReturnData`: `BOOL`. Setting this to true will enable return data capture (default = false).
+- `debug`: `BOOL`. Setting this to true will print output during capture end (default = false).
+- `limit`: `INTEGER`. Setting this to a positive integer will limit the number of steps captured (default = 0, no limit).
+
It is also possible to configure the trace by passing Boolean (true/false) values for four parameters that tweak the verbosity of the trace. By default, the _EVM memory_ and _Return data_ are not reported but the _EVM stack_ and _EVM storage_ are. To report the maximum amount of data:
```sh
@@ -180,7 +189,7 @@ Things to note about the call tracer:
- In case the top level frame reverts, its `revertReason` field will contain the parsed reason of revert as returned by the Solidity contract
-#### Config
+#### callTracer config{#call-tracer-config}
`callTracer` accepts two options:
@@ -204,6 +213,10 @@ The prestate tracer has two modes: `prestate` and `diff`. The `prestate` mode re
| code | string | hex-encoded bytecode |
| storage | map[string]string | storage slots of the contract |
+#### prestateTracer config {#prestate-tracer-config}
+
+- `diffMode`: `BOOL`. Setting this to true will enable diff mode (default = false).
+
In `diff` mode the result object will contain a `pre` and a `post` object:
1. Any read-only access is omitted completely from the result. This mode is only concerned with state modifications.
@@ -485,7 +498,18 @@ Returns:
## State overrides {#state-overrides}
-It is possible to give temporary state modifications to Geth in order to simulate the effects of `eth_call`. For example, some new bytecode could be deployed to some address _temporarily just for the duration of the execution_ and then a transaction interacting with that address can be traced. This can be used for scenario testing or determining the outcome of some hypothetical transaction before executing for real.
+It is possible to give temporary state modifications to Geth in order to simulate the effects of `eth_call` or `debug_traceCall`. For example, some new bytecode could be deployed to some address _temporarily just for the duration of the execution_ and then a transaction interacting with that address can be traced. This can be used for scenario testing or determining the outcome of some hypothetical transaction before executing for real.
+
+Available state overrides are:
+
+- `nonce`: `hexdecimal`. The nonce of the account.
+- `code`: `string`. The bytecode of the account.
+- `balance`: `hexdecimal`. The balance of the account in Wei.
+- `state`: `map[common.Hash]common.Hash`. Clear all storage slots of the account and insert the ones given in the dictionary.
+- `stateDiff`: `map[common.Hash]common.Hash`. Update the given storage slots with new values.
+
+Note, `state` and `stateDiff` can't be specified at the same time. If `state` is
+set, message execution will only use the data in the given state. Otherwise if `statDiff` is set, all diff will be applied first and then execute the call.
To do this, the tracer is written as normal, but the parameter `stateOverrides` is passed an address and some bytecode.
@@ -495,6 +519,19 @@ var tracer = //tracer name
debug.traceCall({from: , to: , input: }, 'latest', {stateOverrides: {'0x...': {code: code}}, tracer: tracer})
```
+## Block overrides {#block-overrides}
+
+Similar to [State overrides](#state-overrides), it is also possible to override some of the execution's block context to simulate the effects of `eth_call` or `debug_traceCall`, we support the following override options:
+
+- `number`: `hexdecimal`. The block number.
+- `difficulty`: `hexdecimal`. The block difficulty.
+- `time`: `hexdecimal`. The block timestamp.
+- `gasLimit`: `hexdecimal`. The block gas limit.
+- `coinbase`: `common.Address`. The block coinbase.
+- `random`: `common.Hash`. The block PREVRANDAO.
+- `baseFee`: `hexdecimal`. The block base fee.
+- `blobBaseFee`: `hexdecimal`. The block blob base fee.
+
## Summary {#summary}
This page showed how to use the tracers that come bundled with Geth. There are a set written in Go and a set written in Javascript. They are invoked by passing their names when calling an API method. State overrides can be used in combination with tracers to examine precisely what the EVM will do in some hypothetical scenarios.
diff --git a/docs/developers/evm-tracing/custom-tracer.md b/docs/developers/evm-tracing/custom-tracer.md
index eccf43c5d1..79366fd271 100644
--- a/docs/developers/evm-tracing/custom-tracer.md
+++ b/docs/developers/evm-tracing/custom-tracer.md
@@ -15,87 +15,65 @@ In this section a simple native tracer that counts the number of opcodes will be
package native
import (
- "encoding/json"
- "math/big"
- "sync/atomic"
- "time"
+ "encoding/json"
+ "sync/atomic"
- "github.com/ethereum/go-ethereum/common"
- "github.com/ethereum/go-ethereum/core/vm"
- "github.com/ethereum/go-ethereum/eth/tracers"
+ "github.com/ethereum/go-ethereum/core/tracing"
+ "github.com/ethereum/go-ethereum/core/vm"
+ "github.com/ethereum/go-ethereum/eth/tracers"
)
func init() {
- // This is how Geth will become aware of the tracer and register it under a given name
- register("opcounter", newOpcounter)
+ tracers.DefaultDirectory.Register("opcounter", newOpcounter, false)
}
type opcounter struct {
- env *vm.EVM
- counts map[string]int // Store opcode counts
- interrupt uint32 // Atomic flag to signal execution interruption
- reason error // Textual reason for the interruption
+ counts map[string]int
+ interrupt uint32
+ reason error
}
-func newOpcounter(ctx *tracers.Context, cfg json.RawMessage) tracers.Tracer {
- return &opcounter{counts: make(map[string]int)}
+// newOpcounter returns a new opcode counting tracer.
+func newOpcounter(ctx *tracers.Context, _ json.RawMessage) (*tracers.Tracer, error) {
+ t := &opcounter{counts: make(map[string]int)}
+ return &tracers.Tracer{
+ Hooks: &tracing.Hooks{
+ OnOpcode: t.onOpcode,
+ },
+ GetResult: t.getResult,
+ Stop: t.stop,
+ }, nil
}
-// CaptureStart implements the EVMLogger interface to initialize the tracing operation.
-func (t *opcounter) CaptureStart(env *vm.EVM, from common.Address, to common.Address, create bool, input []byte, gas uint64, value *big.Int) {
- t.env = env
+func (t *opcounter) onOpcode(pc uint64, op byte, gas, cost uint64, scope tracing.OpContext, rData []byte, depth int, err error) {
+ // Skip if tracing was interrupted
+ if atomic.LoadUint32(&t.interrupt) > 0 {
+ return
+ }
+ name := vm.OpCode(op).String()
+ if _, ok := t.counts[name]; !ok {
+ t.counts[name] = 0
+ }
+ t.counts[name]++
}
-// CaptureState implements the EVMLogger interface to trace a single step of VM execution.
-func (t *opcounter) CaptureState(pc uint64, op vm.OpCode, gas, cost uint64, scope *vm.ScopeContext, rData []byte, depth int, err error) {
- // Skip if tracing was interrupted
- if atomic.LoadUint32(&t.interrupt) > 0 {
- t.env.Cancel()
- return
- }
-
- name := op.String()
- if _, ok := t.counts[name]; !ok {
- t.counts[name] = 0
- }
- t.counts[name]++
+func (t *opcounter) getResult() (json.RawMessage, error) {
+ res, err := json.Marshal(t.counts)
+ if err != nil {
+ return nil, err
+ }
+ return res, t.reason
}
-// CaptureEnter is called when EVM enters a new scope (via call, create or selfdestruct).
-func (t *opcounter) CaptureEnter(op vm.OpCode, from common.Address, to common.Address, input []byte, gas uint64, value *big.Int) {}
-
-// CaptureExit is called when EVM exits a scope, even if the scope didn't
-// execute any code.
-func (t *opcounter) CaptureExit(output []byte, gasUsed uint64, err error) {}
-
-// CaptureFault implements the EVMLogger interface to trace an execution fault.
-func (t *opcounter) CaptureFault(pc uint64, op vm.OpCode, gas, cost uint64, scope *vm.ScopeContext, depth int, err error) {}
-
-// CaptureEnd is called after the call finishes to finalize the tracing.
-func (t *opcounter) CaptureEnd(output []byte, gasUsed uint64, _ time.Duration, err error) {}
-
-func (*opcounter) CaptureTxStart(gasLimit uint64) {}
-
-func (*opcounter) CaptureTxEnd(restGas uint64) {}
-
-// GetResult returns the json-encoded nested list of call traces, and any
-// error arising from the encoding or forceful termination (via `Stop`).
-func (t *opcounter) GetResult() (json.RawMessage, error) {
- res, err := json.Marshal(t.counts)
- if err != nil {
- return nil, err
- }
- return res, t.reason
-}
-
-// Stop terminates execution of the tracer at the first opportune moment.
-func (t *opcounter) Stop(err error) {
- t.reason = err
- atomic.StoreUint32(&t.interrupt, 1)
+func (t *opcounter) stop(err error) {
+ t.reason = err
+ atomic.StoreUint32(&t.interrupt, 1)
}
```
-Every method of the [EVMLogger interface](https://pkg.go.dev/github.com/ethereum/go-ethereum/core/vm#EVMLogger) needs to be implemented (even if empty). Key parts to notice are the `init()` function which registers the tracer in Geth, the `CaptureState` hook where the opcode counts are incremented and `GetResult` where the result is serialized and delivered. Note that the constructor takes in a `cfg json.RawMessage`. This will be filled with a JSON object that user provides to the tracer to pass in optional config fields.
+Now let's walk through the different parts. First and foremost, the tracer will have to be registered with Geth as part of module initialization (`init()` function). This will give the tracer a name which can be used to invoke it later on through the API. What the API also needs is a way to fetch the final result from the tracer. This is done through the `GetResult` hook. The result should be JSON encoded. The `Stop` hook is used to signal the tracer to stop tracing. This will be done e.g. on a timeout. And finally, `OnOpcode` will be called for every opcode executed. This hook is used to do the tracing logic by tallying the count of each instruction.
+
+The full set of hooks available to tracers are documented [here](https://pkg.go.dev/github.com/ethereum/go-ethereum/core/tracing#Hooks). Additionally, note that the tracer constructor takes in a `cfg json.RawMessage`. This will be filled with a JSON object that user provides to the tracer to pass in optional config fields.
To test out this tracer the source is first compiled with `make geth`. Then in the console it can be invoked through the usual API methods by passing in the name it was registered under:
diff --git a/docs/developers/evm-tracing/live-tracing.md b/docs/developers/evm-tracing/live-tracing.md
new file mode 100644
index 0000000000..2f410bf6b3
--- /dev/null
+++ b/docs/developers/evm-tracing/live-tracing.md
@@ -0,0 +1,304 @@
+---
+title: Live tracing
+description: Continuous tracing of the blockchain
+---
+
+Geth v1.14.0 introduces a new optional feature, allowing users to stream (a subset of) all observable blockchain data in real-time. By writing some Go code you can develop a data indexing solution which will receive events from Geth as it is syncing and processing blocks. You may find the full list of events in the source code [here](https://github.com/ethereum/go-ethereum/blob/master/core/tracing/hooks.go), but below is a summary:
+
+- Initialization: receives chain configuration including hard forks and chain ID. Also receives the genesis block.
+- Block processing: receives the block which geth will process next and any error encountered during processing.
+- Transaction processing: receives the transaction which geth will process next and the receipt post-execution.
+- EVM:
+ - Call frame level events
+ - Opcode level events
+ - Logs
+ - Gas changes
+ - For more transparency into gas changes we have assigned a reason to each gas change.
+- State modifications: receives any changes to the accounts.
+ - Balance changes come with a reason for more transparency into the change.
+
+As this is a real-time stream, the data indexing solution must be able to handle chain reorgs. Upon receiving `OnBlock` events, it should check the chain of hashes it has already processed and unroll internal state that will be invalidated by the reorg.
+
+A live tracer can impact the performance of your node as it is run synchronously within the sync process. It is better to keep the tracer code minimal and only with the purpose of getting raw data out and doing heavy post-processing of data in a later stage.
+
+## Implementing a live tracer
+
+The process is very similar to implementing a [custom native tracer](/docs/developers/evm-tracing/custom-tracer). These are the main differences:
+
+- Custom native tracers are invoked through the API and will be instantiated for each request. Live tracers are instantiated once on startup and used throughout the lifetime of Geth.
+- Live tracers will receive chain-related events as opposed to custom native tracers.
+- The constructor for each of these types has a different signature. Live tracer constructors must return a `*tracing.Hooks` object, while custom native tracers must return a `*tracers.Tracer` object.
+
+Below is a tracer that tracks changes of Ether supply across blocks.
+
+### Set-up
+
+First follow the instructions to [clone and build](/docs/getting-started/installing-geth) Geth from source code.
+
+### Tracer code
+
+Save the following snippet to a file under `eth/tracers/live/`.
+
+```go
+package live
+
+import (
+ "encoding/json"
+ "errors"
+ "fmt"
+ "log"
+ "math/big"
+ "path/filepath"
+
+ "github.com/ethereum/go-ethereum/common"
+ "github.com/ethereum/go-ethereum/consensus/misc/eip4844"
+ "github.com/ethereum/go-ethereum/core/tracing"
+ "github.com/ethereum/go-ethereum/core/types"
+ "github.com/ethereum/go-ethereum/core/vm"
+ "github.com/ethereum/go-ethereum/eth/tracers"
+ "gopkg.in/natefinch/lumberjack.v2"
+)
+
+func init() {
+ tracers.LiveDirectory.Register("supply", newSupply)
+}
+
+type SupplyInfo struct {
+ Delta *big.Int `json:"delta"`
+ Reward *big.Int `json:"reward"`
+ Withdrawals *big.Int `json:"withdrawals"`
+ Burn *big.Int `json:"burn"`
+
+ // Block info
+ Number uint64 `json:"blockNumber"`
+ Hash common.Hash `json:"hash"`
+ ParentHash common.Hash `json:"parentHash"`
+}
+
+func newSupplyInfo() SupplyInfo {
+ return SupplyInfo{
+ Delta: big.NewInt(0),
+ Reward: big.NewInt(0),
+ Withdrawals: big.NewInt(0),
+ Burn: big.NewInt(0),
+
+ Number: 0,
+ Hash: common.Hash{},
+ ParentHash: common.Hash{},
+ }
+}
+
+func (s *SupplyInfo) burn(amount *big.Int) {
+ s.Burn.Add(s.Burn, amount)
+ s.Delta.Sub(s.Delta, amount)
+}
+
+type supplyTxCallstack struct {
+ calls []supplyTxCallstack
+ burn *big.Int
+}
+
+type Supply struct {
+ delta SupplyInfo
+ txCallstack []supplyTxCallstack // Callstack for current transaction
+ logger *log.Logger
+}
+
+type supplyTracerConfig struct {
+ Path string `json:"path"` // Path to the directory where the tracer logs will be stored
+ MaxSize int `json:"maxSize"` // MaxSize is the maximum size in megabytes of the tracer log file before it gets rotated. It defaults to 100 megabytes.
+}
+
+func newSupply(cfg json.RawMessage) (*tracing.Hooks, error) {
+ var config supplyTracerConfig
+ if cfg != nil {
+ if err := json.Unmarshal(cfg, &config); err != nil {
+ return nil, fmt.Errorf("failed to parse config: %v", err)
+ }
+ }
+
+ if config.Path == "" {
+ return nil, errors.New("supply tracer output path is required")
+ }
+
+ // Store traces in a rotating file
+ loggerOutput := &lumberjack.Logger{
+ Filename: filepath.Join(config.Path, "supply.jsonl"),
+ }
+
+ if config.MaxSize > 0 {
+ loggerOutput.MaxSize = config.MaxSize
+ }
+
+ logger := log.New(loggerOutput, "", 0)
+
+ supplyInfo := newSupplyInfo()
+
+ t := &Supply{
+ delta: supplyInfo,
+ logger: logger,
+ }
+ return &tracing.Hooks{
+ OnBlockStart: t.OnBlockStart,
+ OnBlockEnd: t.OnBlockEnd,
+ OnGenesisBlock: t.OnGenesisBlock,
+ OnTxStart: t.OnTxStart,
+ OnBalanceChange: t.OnBalanceChange,
+ OnEnter: t.OnEnter,
+ OnExit: t.OnExit,
+ }, nil
+}
+
+func (s *Supply) resetDelta() {
+ s.delta = newSupplyInfo()
+}
+
+func (s *Supply) OnBlockStart(ev tracing.BlockEvent) {
+ s.resetDelta()
+
+ s.delta.Number = ev.Block.NumberU64()
+ s.delta.Hash = ev.Block.Hash()
+ s.delta.ParentHash = ev.Block.ParentHash()
+
+ // Calculate Burn for this block
+ if ev.Block.BaseFee() != nil {
+ burn := new(big.Int).Mul(new(big.Int).SetUint64(ev.Block.GasUsed()), ev.Block.BaseFee())
+ s.delta.burn(burn)
+ }
+ // Blob burnt gas
+ if blobGas := ev.Block.BlobGasUsed(); blobGas != nil && *blobGas > 0 && ev.Block.ExcessBlobGas() != nil {
+ var (
+ excess = *ev.Block.ExcessBlobGas()
+ baseFee = eip4844.CalcBlobFee(excess)
+ burn = new(big.Int).Mul(new(big.Int).SetUint64(*blobGas), baseFee)
+ )
+ s.delta.burn(burn)
+ }
+}
+
+func (s *Supply) OnBlockEnd(err error) {
+ out, _ := json.Marshal(s.delta)
+ s.logger.Println(string(out))
+}
+
+func (s *Supply) OnGenesisBlock(b *types.Block, alloc types.GenesisAlloc) {
+ s.resetDelta()
+
+ s.delta.Number = b.NumberU64()
+ s.delta.Hash = b.Hash()
+ s.delta.ParentHash = b.ParentHash()
+
+ // Initialize supply with total allocation in genesis block
+ for _, account := range alloc {
+ s.delta.Delta.Add(s.delta.Delta, account.Balance)
+ }
+
+ out, _ := json.Marshal(s.delta)
+ s.logger.Println(string(out))
+}
+
+func (s *Supply) OnBalanceChange(a common.Address, prevBalance, newBalance *big.Int, reason tracing.BalanceChangeReason) {
+ diff := new(big.Int).Sub(newBalance, prevBalance)
+
+ // NOTE: don't handle "BalanceIncreaseGenesisBalance" because it is handled in OnGenesisBlock
+ switch reason {
+ case tracing.BalanceIncreaseRewardMineUncle:
+ case tracing.BalanceIncreaseRewardMineBlock:
+ s.delta.Reward.Add(s.delta.Reward, diff)
+ case tracing.BalanceIncreaseWithdrawal:
+ s.delta.Withdrawals.Add(s.delta.Withdrawals, diff)
+ case tracing.BalanceDecreaseSelfdestructBurn:
+ // BalanceDecreaseSelfdestructBurn is non-reversible as it happens
+ // at the end of the transaction.
+ s.delta.Burn.Sub(s.delta.Burn, diff)
+ default:
+ return
+ }
+
+ s.delta.Delta.Add(s.delta.Delta, diff)
+}
+
+func (s *Supply) OnTxStart(vm *tracing.VMContext, tx *types.Transaction, from common.Address) {
+ s.txCallstack = make([]supplyTxCallstack, 0, 1)
+}
+
+// internalTxsHandler handles internal transactions burned amount
+func (s *Supply) internalTxsHandler(call *supplyTxCallstack) {
+ // Handle Burned amount
+ if call.burn != nil {
+ s.delta.burn(call.burn)
+ }
+
+ if len(call.calls) > 0 {
+ // Recursivelly handle internal calls
+ for _, call := range call.calls {
+ callCopy := call
+ s.interalTxsHandler(&callCopy)
+ }
+ }
+}
+
+func (s *Supply) OnEnter(depth int, typ byte, from common.Address, to common.Address, input []byte, gas uint64, value *big.Int) {
+ call := supplyTxCallstack{
+ calls: make([]supplyTxCallstack, 0),
+ }
+
+ // This is a special case of burned amount which has to be handled here
+ // which happens when type == selfdestruct and from == to.
+ if vm.OpCode(typ) == vm.SELFDESTRUCT && from == to && value.Cmp(common.Big0) == 1 {
+ call.burn = value
+ }
+
+ // Append call to the callstack, so we can fill the details in OnExit
+ s.txCallstack = append(s.txCallstack, call)
+}
+
+func (s *Supply) OnExit(depth int, output []byte, gasUsed uint64, err error, reverted bool) {
+ if depth == 0 {
+ // No need to handle Burned amount if transaction is reverted
+ if !reverted {
+ s.interalTxsHandler(&s.txCallstack[0])
+ }
+ return
+ }
+
+ size := len(s.txCallstack)
+ if size <= 1 {
+ return
+ }
+ // Pop call
+ call := s.txCallstack[size-1]
+ s.txCallstack = s.txCallstack[:size-1]
+ size -= 1
+
+ // In case of a revert, we can drop the call and all its subcalls.
+ // Caution, that this has to happen after popping the call from the stack.
+ if reverted {
+ return
+ }
+ s.txCallstack[size-1].calls = append(s.txCallstack[size-1].calls, call)
+}
+```
+
+Note-worthy explanations:
+
+- Tracer is registered in the Live Tracer directory as part of the `init()` function.
+- It is possible to configure the tracer, e.g. pass in the path where the logs will be stored.
+- Tracers don't have access to Geth's database. They will have to implement their own persistence layer or a way to extract data. In this example, the tracer logs the data to a file.
+- Note that we are resetting the delta on every new block, because the same tracer instance will be used all the time.
+
+### Running the tracer
+
+First compile the source by running `make geth`. Then run the following command:
+
+```bash
+./build/bin/geth --vmtrace --vmtrace.config '{"config": "supply-logs"}' [OTHER_GETH_FLAGS]
+```
+
+Soon you will see `supply-logs/supply.jsonl` file being populated with lines such as:
+
+```json lines
+{"delta":97373601373111356,"reward":0,"withdrawals":466087699000000000,"burn":368714097626888644,"blockNumber":19503066,"hash":"0x6ad7b65b1ba0de044c490df739ea1e6605cbcae3685dcb69cca9afeb4edeb86b","parentHash":"0x8e68cc87ea7cef3643955f376aacf02ebfe3ff6ac6a28f30683fbd1da0fa0482"}
+{"delta":-78769000248388266,"reward":0,"withdrawals":336059502000000000,"burn":414828502248388266,"blockNumber":19503067,"hash":"0xa17379379ecac8c37358ba26d6ef7de6e059aba18c752177b0b4aeb4d3377888","parentHash":"0x6ad7b65b1ba0de044c490df739ea1e6605cbcae3685dcb69cca9afeb4edeb86b"}
+{"delta":201614678898811488,"reward":0,"withdrawals":335502106000000000,"burn":133887427101188512,"blockNumber":19503068,"hash":"0xbfb71586616e4d73ae0e12d9123b39168af71f2b52ab6cf94298cc8619a79b09","parentHash":"0xa17379379ecac8c37358ba26d6ef7de6e059aba18c752177b0b4aeb4d3377888"}
+```
\ No newline at end of file
diff --git a/docs/interacting-with-geth/rpc/ns-debug.md b/docs/interacting-with-geth/rpc/ns-debug.md
index 57bba549c2..0ce5bf6eb8 100644
--- a/docs/interacting-with-geth/rpc/ns-debug.md
+++ b/docs/interacting-with-geth/rpc/ns-debug.md
@@ -362,9 +362,9 @@ For example the value `0s` will essentially turn on archive mode. If set to `1h`
Returns a printed representation of the stacks of all goroutines. Note that the web3 wrapper for this method takes care of the printing and does not return the string.
-| Client | Method invocation |
-| :------ | ------------------------------------------ |
-| Console | `debug.stacks(filter *string)` |
+| Client | Method invocation |
+| :------ | ------------------------------------------------ |
+| Console | `debug.stacks(filter *string)` |
| RPC | `{"method": "debug_stacks", "params": [filter]}` |
### debug_standardTraceBlockToFile
@@ -455,7 +455,7 @@ Stops writing the Go runtime trace.
| Client | Method invocation |
| :------ | ----------------------------------------------- |
-| Console | `debug.stopGoTrace()` |
+| Console | `debug.stopGoTrace()` |
| RPC | `{"method": "debug_stopGoTrace", "params": []}` |
### debug_storageRangeAt
@@ -579,13 +579,21 @@ References:
### debug_traceCall
-The `debug_traceCall` method lets you run an `eth_call` within the context of the given block execution using the final state of parent block as the base. The first argument (just as in `eth_call`) is a [transaction object](/docs/interacting-with-geth/rpc/objects#transaction-call-object). The block can be specified either by hash or by number as the second argument. The trace can be configured similar to `debug_traceTransaction`, see [TraceConfig](#traceconfig). The method returns the same output as `debug_traceTransaction`.
+The `debug_traceCall` method lets you run an `eth_call` within the context of the given block execution using the final state of parent block as the base. The first argument (just as in `eth_call`) is a [transaction object](/docs/interacting-with-geth/rpc/objects#transaction-call-object). The block can be specified either by hash or by number as the second argument. The trace can be configured similar to `debug_traceTransaction`, see [TraceCallConfig](#tracecallconfig). The method returns the same output as `debug_traceTransaction`.
-| Client | Method invocation |
-| :-----: | --------------------------------------------------------------------------------------------------------------------------- |
-| Go | `debug.TraceCall(args ethapi.CallArgs, blockNrOrHash rpc.BlockNumberOrHash, config *TraceConfig) (*ExecutionResult, error)` |
-| Console | `debug.traceCall(object, blockNrOrHash, [options])` |
-| RPC | `{"method": "debug_traceCall", "params": [object, blockNrOrHash, {}]}` |
+| Client | Method invocation |
+| :-----: | ------------------------------------------------------------------------------------------------------------------------------- |
+| Go | `debug.TraceCall(args ethapi.CallArgs, blockNrOrHash rpc.BlockNumberOrHash, config *TraceCallConfig) (*ExecutionResult, error)` |
+| Console | `debug.traceCall(object, blockNrOrHash, [options])` |
+| RPC | `{"method": "debug_traceCall", "params": [object, blockNrOrHash, {}]}` |
+
+#### TraceCallConfig
+
+TraceCallConfig is a superset of [TraceConfig](#traceconfig), providing additional arguments in addition to those provided by [TraceConfig](#traceconfig):
+
+- `stateOverrides`: `StateOverride`. Overrides for the state data (accounts/storage) for the call, see [StateOverride](/docs/developers/evm-tracing/built-in-tracers#state-overrides) for more details.
+- `blockOverrides`: `BlockOverrides`. Overrides for the block data (number, timestamp etc) for the call, see [BlockOverrides](/docs/developers/evm-tracing/built-in-tracers#block-overrides) for more details.
+- `txIndex`: `NUMBER`. If set, the state at the the given transaction index will be used to tracing (default = the last transaction index in the block).
**Example:**
@@ -604,14 +612,14 @@ No specific call options:
Tracing a call with a destination and specific sender, disabling the storage and memory output (less data returned over RPC)
```js
-debug.traceCall(
+> debug.traceCall(
{
- from: '0xdeadbeef29292929192939494959594933929292',
- to: '0xde929f939d939d393f939393f93939f393929023',
- gas: '0x7a120',
- data: '0xf00d4b5d00000000000000000000000001291230982139282304923482304912923823920000000000000000000000001293123098123928310239129839291010293810'
+ from: "0xdeadbeef29292929192939494959594933929292",
+ to: "0xde929f939d939d393f939393f93939f393929023",
+ gas: "0x7a120",
+ data: "0xf00d4b5d00000000000000000000000001291230982139282304923482304912923823920000000000000000000000001293123098123928310239129839291010293810"
},
- 'latest',
+ "latest",
{ disableStorage: true, disableMemory: true }
);
```
@@ -619,16 +627,18 @@ debug.traceCall(
It is possible to supply 'overrides' for both state-data (accounts/storage) and block data (number, timestamp etc). In the example below, a call which executes `NUMBER` is performed, and the overridden number is placed on the stack:
```js
-> debug.traceCall({
+> debug.traceCall(
+ {
from: eth.accounts[0],
- value:"0x1",
+ value: "0x1",
gasPrice: "0xffffffff",
gas: "0xffff",
- input: "0x43"},
- "latest",
- {"blockoverrides":
- {"number": "0x50"}
- })
+ input: "0x43"
+ },
+ "latest",
+ {
+ "blockOverrides": {"number": "0x50"}
+ })
{
failed: false,
gas: 53018,
@@ -685,19 +695,25 @@ hash.
In addition to the hash of the transaction you may give it a secondary _optional_ argument, which specifies the options for this specific call. The possible options are:
-- `disableStorage`: `BOOL`. Setting this to true will disable storage capture (default = false).
-- `disableStack`: `BOOL`. Setting this to true will disable stack capture (default = false).
-- `enableMemory`: `BOOL`. Setting this to true will enable memory capture (default = false).
-- `enableReturnData`: `BOOL`. Setting this to true will enable return data capture (default = false).
-- `tracer`: `STRING`. Name for built-in tracer or Javascript expression. See below for more details.
+| Field | Type | Description |
+|----------------|--------|---------------------------------------------------------------------------------------------------------------------------------------------------------------|
+| `tracer` | String | Name for built-in tracer or Javascript expression. See below for more details. |
+| `tracerConfig` | String | Config for the specified tracer formatted as a JSON object (see below) |
+| `timeout` | String | Overrides the default timeout of 5 seconds for each transaction tracing, valid values are described [here] ( https://golang.org/pkg/time/#ParseDuration). |
+| `reexec` | uint64 | The number of blocks the tracer is willing to go back and re-execute to produce missing historical state necessary to run a specific trace. (default is 128). |
-If set, the previous four arguments will be ignored.
+Geth comes with a bundle of [built-in tracers](/docs/developers/evm-tracing/built-in-tracers), each providing various data about a transaction. The `tracer` field can be set to either a [JS expression](/docs/developers/evm-tracing/custom-tracer#custom-javascript-tracing) or the name of a built-in or [custom native tracer](/docs/developers/evm-tracing/custom-tracer#custom-go-tracing). If `tracer` is left empty the [opcode logger](/docs/developers/evm-tracing/built-in-tracers#structopcode-logger) will be chosen as default.
-- `timeout`: `STRING`. Overrides the default timeout of 5 seconds for JavaScript-based tracing calls.
- Valid values are described [here](https://golang.org/pkg/time/#ParseDuration).
-- `tracerConfig`: Config for the specified `tracer`. For example see callTracer's [config](/docs/developers/evm-tracing/built-in-tracers#config).
+`TraceConfig` object has more fields that are specific to the [opcode logger](/docs/developers/evm-tracing/built-in-tracers#structopcode-logger) and which will be ignored when `tracer` field is set to any value. For configuration of built-in tracers refer to their respective documentation. The fields are:
-Geth comes with a bundle of [built-in tracers](/docs/developers/evm-tracing/built-in-tracers), each providing various data about a transaction. This method defaults to the [struct logger](/docs/developers/evm-tracing/built-in-tracers#structopcode-logger). The `tracer` field of the second parameter can be set to use any of the other tracers. Alternatively a [custom tracer](/docs/developers/evm-tracing/custom-tracer) can be implemented in either Go or Javascript.
+| field | type | description |
+| ------------------ | --------- | ---------------------------------------------------------------------------------------------------------- |
+| `enableMemory` | `BOOL` | Enable memory capture (default = false) |
+| `disableStack` | `BOOL` | Disable stack capture (default = false) |
+| `disableStorage` | `BOOL` | Disable storage capture (default = false) |
+| `enableReturnData` | `BOOL` | Enable return data capture (default = false) |
+| `debug` | `BOOL` | Print output during capture end (default = false) |
+| `limit` | `INTEGER` | Limit the number of steps captured (default = 0, no limit) |
**Example:**
@@ -735,15 +751,16 @@ Geth comes with a bundle of [built-in tracers](/docs/developers/evm-tracing/buil
}]
```
+
### debug_verbosity
Sets the logging verbosity ceiling. Log messages with level up to and including the given level will be printed.
The verbosity of individual packages and source files can be raised using `debug_vmodule`.
-| Client | Method invocation |
-| :------ | ------------------------------------------------- |
-| Console | `debug.verbosity(level)` |
+| Client | Method invocation |
+| :------ | --------------------------------------------------- |
+| Console | `debug.verbosity(level)` |
| RPC | `{"method": "debug_verbosity", "params": [number]}` |
### debug_vmodule
diff --git a/src/components/UI/docs/MDComponents.tsx b/src/components/UI/docs/MDComponents.tsx
index d1d1899a24..a169eb8779 100644
--- a/src/components/UI/docs/MDComponents.tsx
+++ b/src/components/UI/docs/MDComponents.tsx
@@ -128,7 +128,7 @@ const MDComponents = {
ul: ({ children }: any) => {
return (
-
+
{children}
@@ -137,7 +137,7 @@ const MDComponents = {
ol: ({ children }: any) => {
return (
-
+
{children}
diff --git a/src/data/documentation-links.yaml b/src/data/documentation-links.yaml
index 2bf181eaf0..b8fe37fa5a 100644
--- a/src/data/documentation-links.yaml
+++ b/src/data/documentation-links.yaml
@@ -102,6 +102,8 @@
to: /docs/developers/evm-tracing/built-in-tracers
- id: Custom EVM tracer
to: /docs/developers/evm-tracing/custom-tracer
+ - id: Live tracing
+ to: /docs/developers/evm-tracing/live-tracing
- id: Tutorial for Javascript tracing
to: /docs/developers/evm-tracing/javascript-tutorial
- id: Geth developer