Here we add a Go API for running tracing plugins within the main block import process.
As an advanced user of geth, you can now create a Go file in eth/tracers/live/, and within
that file register your custom tracer implementation. Then recompile geth and select your tracer
on the command line. Hooks defined in the tracer will run whenever a block is processed.
The hook system is defined in package core/tracing. It uses a struct with callbacks, instead of
requiring an interface, for several reasons:
- We plan to keep this API stable long-term. The core/tracing hook API does not depend on
on deep geth internals.
- There are a lot of hooks, and tracers will only need some of them. Using a struct allows you
to implement only the hooks you want to actually use.
All existing tracers in eth/tracers/native have been rewritten to use the new hook system.
This change breaks compatibility with the vm.EVMLogger interface that we used to have.
If you are a user of vm.EVMLogger, please migrate to core/tracing, and sorry for breaking
your stuff. But we just couldn't have both the old and new tracing APIs coexist in the EVM.
---------
Co-authored-by: Matthieu Vachon <matthieu.o.vachon@gmail.com>
Co-authored-by: Delweng <delweng@gmail.com>
Co-authored-by: Martin HS <martin@swende.se>
The prestateTracer was reporting an inaccurate nonce for the contract being created in
post EIP-158 transactions. Correct nonce is 0, due to the issue nonce was being reported as 1.
This change makes use of uin256 to represent balance in state. It touches primarily upon statedb, stateobject and state processing, trying to avoid changes in transaction pools, core types, rpc and tracers.
Currently, one can use the "withLogs" parameter to include logs in the
callTracer results, which allows the user to see at which trace level
was each log emitted.
This commit adds a position field to the logs which determine
the exact ordering of a call's logs and its subcalls. This would
be useful e.g. for explorers wishing to display the flow of execution.
Co-authored-by: jsvisa <delweng@gmail.com>
Use the new atomic types in package eth/tracers
---------
Co-authored-by: Martin Holst Swende <martin@swende.se>
Co-authored-by: Sina Mahmoodi <itz.s1na@gmail.com>
This includes a semantic change to the `callTracer` as well as `flatCallTracer`.
The value of field `gas` in the **first** call frame will change as follows:
- It previously contained gas available after initial deductions (i.e. tx costs)
- It will now contain the full tx gasLimit value
Signed-off-by: jsvisa <delweng@gmail.com>
This PR fixes OOM panic in the callTracer as well as panicing on
opcode validation errors (e.g. stack underflow) in callTracer and
prestateTracer.
Co-authored-by: Martin Holst Swende <martin@swende.se>
Adds support for a native call tracer with the Parity format, which outputs call frames
in a flat array. This tracer accepts the following options:
- `convertParityErrors: true` will convert error messages to match those of Parity
- `includePrecompiles: true` will report all calls to precompiles. The default
matches Parity's behavior where CALL and STATICCALLs to precompiles are excluded
Incompatibilities with Parity include:
- Parity removes the result object in case of failure. This behavior is maintained
with the exception of reverts. Revert output usually contains useful information,
i.e. Solidity revert reason.
- The `gasUsed` field accounts for intrinsic gas (e.g. 21000 for simple transfers)
and refunds unlike Parity
- Block rewards are not reported
Co-authored-by: Sina Mahmoodi <itz.s1na@gmail.com>
This makes non-JS tracers execute all block txs on a single goroutine.
In the previous implementation, we used to prepare every tx pre-state
on one goroutine, and then run the transactions again with tracing enabled.
Native tracers are usually faster, so it is faster overall to use their output as
the pre-state for tracing the next transaction.
Co-authored-by: Sina Mahmoodi <itz.s1na@gmail.com>
This removes the 'time' field from logs, as well as from the tracer interface. This change makes the trace output deterministic. If a tracer needs the time they can measure it themselves. No need for evm to do this.
Co-authored-by: Sina Mahmoodi <itz.s1na@gmail.com>
In some cases, it is desirable to capture what is triggered by each trace, when using the `callTracer`. For example: call `USDT.transfer` will trigger a `Transfer(from, to, value)` event.
This PR adds the option to capture logs to the call tracer, by specifying `{"withLog": true}` in the tracerconfig.
Any logs belonging to failed/reverted call-scopes are removed from the output, to prevent interpretation mistakes.
Signed-off-by: Delweng <delweng@gmail.com>
Co-authored-by: Sina Mahmoodi <itz.s1na@gmail.com>
Inner call reverts will now return the reason similar to the top-level call. Separately, if top-level call is of type CREATE and it fails, its `to` field will now be cleared to `0x00...00` instead of being set to the created address.
* eth/tracers: fix gasUsed in call tracer
* fix js tracers gasUsed
* fix legacy prestate tracer
* fix restGas in test
* drop intrinsicGas field from js tracers
The prestate tracer did not report accounts that existed at a given address prior to a contract being created at that address.
Signed-off-by: Delweng <delweng@gmail.com>
Co-authored-by: Sina Mahmoodi <itz.s1na@gmail.com>
In some cases, inner contract creation may not be successful, and an inner contract was not created. This PR fixes a crash that could occur when doing tracing in such situations.
Backwards compatibility warning: The result will from now on omit empty fields instead
of including a zero value (e.g. no more `balance: '0x'`).
The prestateTracer will now take an option `diffMode: bool`. In this mode
the tracer will output the pre state and post data for the modified parts of state.
Read-only accesses will be completely omitted. Creations (be it account or slot)
will be signified by omission in the `pre` list and inclusion in `post`. Whereas
deletion (be it account or slot) will be signified by inclusion in `pre` and omission
in `post` list.
Signed-off-by: Delweng <delweng@gmail.com>
The call tracer and prestate tracer store data JSON-encoded in memory. In order to support alternative encodings (specifically RLP), it's better to keep data a native format during tracing. This PR does marshalling at the end, using gencodec.
OBS!
This PR changes the call tracer result slightly:
- Order of type and value fields are changed (should not matter).
- Output fields are completely omitted when they're empty (no more output: "0x"). Previously, this was only _sometimes_ omitted (e.g. when call ended in a non-revert error) and otherwise 0x when the output was actually empty.
This changes the CI / release builds to use the latest Go version. It also
upgrades golangci-lint to a newer version compatible with Go 1.19.
In Go 1.19, godoc has gained official support for links and lists. The
syntax for code blocks in doc comments has changed and now requires a
leading tab character. gofmt adapts comments to the new syntax
automatically, so there are a lot of comment re-formatting changes in this
PR. We need to apply the new format in order to pass the CI lint stage with
Go 1.19.
With the linter upgrade, I have decided to disable 'gosec' - it produces
too many false-positive warnings. The 'deadcode' and 'varcheck' linters
have also been removed because golangci-lint warns about them being
unmaintained. 'unused' provides similar coverage and we already have it
enabled, so we don't lose much with this change.
This PR allows users to pass in a config object directly to the tracers. Previously only the struct logger was configurable.
It also adds an option to the call tracer which if enabled makes it ignore any subcall and collect only information about the top-level call. See #25419 for discussion.
The tracers will silently ignore if they are passed a config they don't care about.
Adds a native tracer that returns that in case of failure returns the error message or the revert reason of a transaction.
Co-authored-by: Martin Holst Swende <martin@swende.se>
* core,eth: add empty tx logger hooks
* core,eth: add initial and remaining gas to tx hooks
* store tx gasLimit in js tracer
* use gasLimit to compute intrinsic cost for js tracer
* re-use rules in transitiondb
* rm logs
* rm logs
* Mv some fields from Start to TxStart
* simplify sender lookup in prestate tracer
* mv env to TxStart
* Revert "mv env to TxStart"
This reverts commit 656939634b9aff19f55a1cd167345faf8b1ec310.
* Revert "simplify sender lookup in prestate tracer"
This reverts commit ab65bce48007cab99e68232e7aac2fe008338d50.
* Revert "Mv some fields from Start to TxStart"
This reverts commit aa50d3d9b2559addc80df966111ef5fb5d0c1b6b.
* fix intrinsic gas for prestate tracer
* add comments
* refactor
* fix test case
* simplify consumedGas calc in prestate tracer
* eth/tracers: add initial native prestate tracer
* fix balance hex
* handle prestate for tx from and to
* drop created contract from prestate
* fix sender balance
* use switch instead
Co-authored-by: Martin Holst Swende <martin@swende.se>
* minor fix
* lookup create2 account
* mv code around a bit
* check stackLen for create2
* fix transfer tx for js prestate tracer
* fix create2 addr
* track extcodehash in js prestate tracer
Co-authored-by: Martin Holst Swende <martin@swende.se>
* core: implement eip-4399 random opcode
* core: make vmconfig threadsafe
* core: miner: pass vmConfig by value not reference
* all: enable 4399 by Rules
* core: remove diff (f)
* tests: set proper difficulty (f)
* smaller diff (f)
* eth/catalyst: nit
* core: make RANDOM a pointer which is only set post-merge
* cmd/evm/internal/t8ntool: fix t8n tracing of 4399
* tests: set difficulty
* cmd/evm/internal/t8ntool: check that baserules are london before applying the merge chainrules