Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
17 commits
Select commit Hold shift + click to select a range
3231596
core/tracing: add hooks for live tracing of block processing and tran…
chiphamskymavis May 5, 2025
557172b
core: add VM new tracing support with new configuration options
chiphamskymavis May 7, 2025
357a8ad
core/state: add tracing hook to state db and state object (#73)
sonhv0212 May 13, 2025
092dcce
core/state: add BalanceChangeReason to state db and state object (#74)
sonhv0212 May 14, 2025
aa5ea8f
core: state transition, processor, evm support live tracer (#75)
sonhv0212 May 14, 2025
de68990
core: blockchain supports live tracer (#77)
sonhv0212 May 14, 2025
e67515e
all: replace the older tracer by live tracer (#78)
sonhv0212 May 16, 2025
9de17e6
core, tests: add missing usages of live tracer in blockchain and stat…
sonhv0212 May 17, 2025
289c404
eth/tracer/live: add supply live tracer (#84)
sonhv0212 May 19, 2025
31d467f
core, eth/tracers: move chainconfig to tracers and some refactors (#86)
sonhv0212 May 20, 2025
97d6aa8
evm: remove EVMLogger interface (#91)
chiphamskymavis May 27, 2025
823a68e
core: minor cleanup in stateDB and Call (#96)
sonhv0212 Jun 2, 2025
9017971
core/vm: update gas usage to use Tracer instead of LiveTracer in EIP-…
chiphamskymavis Jul 1, 2025
89fa0f5
eth/tracers/internal/tracetest: disable KotaroBlock in pre-Cancun tests
sonhv0212 Jul 1, 2025
caffb1b
core/vm/runtime: fix type error
sonhv0212 Jul 1, 2025
c1a8e80
core/tracing: extends tracing.Hooks with OnSystemCallStartV2 (#30786)
sonhv0212 Jul 1, 2025
3813cd0
core: capture on gas change when applying eip-7623
sonhv0212 Jul 1, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions .github/workflows/ci-test-and-coverage.yml
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,11 @@ on:
push:
branches:
- main
- evm-tracer*
pull_request:
branches:
- main
- evm-tracer*

concurrency:
group: ${{ github.head_ref || github.run_id }}
Expand Down
3 changes: 2 additions & 1 deletion accounts/abi/bind/backends/simulated.go
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ import (
"github.com/ethereum/go-ethereum/core/bloombits"
"github.com/ethereum/go-ethereum/core/rawdb"
"github.com/ethereum/go-ethereum/core/state"
"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/filters"
Expand Down Expand Up @@ -620,7 +621,7 @@ func (b *SimulatedBackend) callContract(ctx context.Context, call ethereum.CallM
}
// Set infinite balance to the fake caller account.
from := stateDB.GetOrNewStateObject(call.From)
from.SetBalance(math.MaxBig256)
from.SetBalance(math.MaxBig256, tracing.BalanceChangeUnspecified)

// Execute the call.
msg := core.NewMessage(
Expand Down
17 changes: 11 additions & 6 deletions cmd/evm/internal/t8ntool/execution.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ package t8ntool

import (
"fmt"
"io"
"math/big"
"os"

Expand All @@ -28,9 +29,11 @@ import (
"github.com/ethereum/go-ethereum/core"
"github.com/ethereum/go-ethereum/core/rawdb"
"github.com/ethereum/go-ethereum/core/state"
"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/crypto"
"github.com/ethereum/go-ethereum/eth/tracers"
"github.com/ethereum/go-ethereum/ethdb"
"github.com/ethereum/go-ethereum/log"
"github.com/ethereum/go-ethereum/params"
Expand Down Expand Up @@ -97,7 +100,7 @@ type rejectedTx struct {
// Apply applies a set of transactions to a pre-state
func (pre *Prestate) Apply(vmConfig vm.Config, chainConfig *params.ChainConfig,
txs types.Transactions, miningReward int64,
getTracerFn func(txIndex int, txHash common.Hash) (tracer vm.EVMLogger, err error),
getTracerFn func(txIndex int, txHash common.Hash) (*tracers.Tracer, io.WriteCloser, error),
) (*state.StateDB, *ExecutionResult, error) {
// Capture errors for BLOCKHASH operation, if we haven't been supplied the
// required blockhashes
Expand Down Expand Up @@ -154,11 +157,13 @@ func (pre *Prestate) Apply(vmConfig vm.Config, chainConfig *params.ChainConfig,
rejectedTxs = append(rejectedTxs, &rejectedTx{i, err.Error()})
continue
}
tracer, err := getTracerFn(txIndex, tx.Hash())
tracer, _, err := getTracerFn(txIndex, tx.Hash())
if err != nil {
return nil, nil, err
}
vmConfig.Tracer = tracer
if tracer != nil {
vmConfig.Tracer = tracer.Hooks
}
vmConfig.Debug = (tracer != nil)
statedb.SetTxContext(tx.Hash(), txIndex)
txContext := core.NewEVMTxContext(msg)
Expand Down Expand Up @@ -237,9 +242,9 @@ func (pre *Prestate) Apply(vmConfig vm.Config, chainConfig *params.ChainConfig,
reward.Sub(reward, big.NewInt(0).SetUint64(ommer.Delta))
reward.Mul(reward, blockReward)
reward.Div(reward, big.NewInt(8))
statedb.AddBalance(ommer.Address, reward)
statedb.AddBalance(ommer.Address, reward, tracing.BalanceIncreaseRewardMineUncle)
}
statedb.AddBalance(pre.Env.Coinbase, minerReward)
statedb.AddBalance(pre.Env.Coinbase, minerReward, tracing.BalanceIncreaseRewardMineBlock)
}
// Commit block
root, err := statedb.Commit(vmContext.BlockNumber.Uint64(), chainConfig.IsEIP158(vmContext.BlockNumber))
Expand Down Expand Up @@ -273,7 +278,7 @@ func MakePreState(db ethdb.Database, accounts types.GenesisAlloc) *state.StateDB
for addr, a := range accounts {
statedb.SetCode(addr, a.Code)
statedb.SetNonce(addr, a.Nonce)
statedb.SetBalance(addr, a.Balance)
statedb.SetBalance(addr, a.Balance, tracing.BalanceIncreaseGenesisBalance)
for k, v := range a.Storage {
statedb.SetState(addr, k, v)
}
Expand Down
36 changes: 17 additions & 19 deletions cmd/evm/internal/t8ntool/transition.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,12 +21,15 @@ import (
"encoding/json"
"errors"
"fmt"
"io"
"io/ioutil"
"math/big"
"os"
"path"
"path/filepath"
"strings"

"github.com/ethereum/go-ethereum/eth/tracers"
"github.com/ethereum/go-ethereum/eth/tracers/logger"

"github.com/ethereum/go-ethereum/common"
Expand Down Expand Up @@ -91,10 +94,9 @@ func Transition(ctx *cli.Context) error {
log.Root().SetHandler(glogger)

var (
err error
tracer vm.EVMLogger
err error
)
var getTracer func(txIndex int, txHash common.Hash) (vm.EVMLogger, error)
var getTracer = func(txIndex int, txHash common.Hash) (*tracers.Tracer, io.WriteCloser, error) { return nil, nil, nil }

baseDir, err := createBasedir(ctx)
if err != nil {
Expand Down Expand Up @@ -127,20 +129,19 @@ func Transition(ctx *cli.Context) error {
prevFile.Close()
}
}()
getTracer = func(txIndex int, txHash common.Hash) (vm.EVMLogger, error) {
if prevFile != nil {
prevFile.Close()
}
traceFile, err := os.Create(path.Join(baseDir, fmt.Sprintf("trace-%d-%v.jsonl", txIndex, txHash.String())))
getTracer = func(txIndex int, txHash common.Hash) (*tracers.Tracer, io.WriteCloser, error) {
traceFile, err := os.Create(filepath.Join(baseDir, fmt.Sprintf("trace-%d-%v.jsonl", txIndex, txHash.String())))
if err != nil {
return nil, NewError(ErrorIO, fmt.Errorf("failed creating trace-file: %v", err))
return nil, nil, NewError(ErrorIO, fmt.Errorf("failed creating trace-file: %v", err))
}
prevFile = traceFile
return logger.NewJSONLogger(logConfig, traceFile), nil
}
} else {
getTracer = func(txIndex int, txHash common.Hash) (tracer vm.EVMLogger, err error) {
return nil, nil
logger := logger.NewJSONLogger(logConfig, traceFile)
tracer := &tracers.Tracer{
Hooks: logger,
// jsonLogger streams out result to file.
GetResult: func() (json.RawMessage, error) { return nil, nil },
Stop: func(err error) {},
}
return tracer, traceFile, nil
}
}
// We need to load three things: alloc, env and transactions. May be either in
Expand Down Expand Up @@ -179,10 +180,7 @@ func Transition(ctx *cli.Context) error {
}
prestate.Env = *inputData.Env

vmConfig := vm.Config{
Tracer: tracer,
Debug: (tracer != nil),
}
vmConfig := vm.Config{}
// Construct the chainconfig
var chainConfig *params.ChainConfig
if cConf, extraEips, err := tests.GetChainConfig(ctx.String(ForknameFlag.Name)); err != nil {
Expand Down
5 changes: 3 additions & 2 deletions cmd/evm/runner.go
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ import (
"github.com/ethereum/go-ethereum/core"
"github.com/ethereum/go-ethereum/core/rawdb"
"github.com/ethereum/go-ethereum/core/state"
"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/core/vm/runtime"
Expand Down Expand Up @@ -122,7 +123,7 @@ func runCmd(ctx *cli.Context) error {
}

var (
tracer vm.EVMLogger
tracer *tracing.Hooks
debugLogger *logger.StructLogger
statedb *state.StateDB
chainConfig *params.ChainConfig
Expand All @@ -134,7 +135,7 @@ func runCmd(ctx *cli.Context) error {
tracer = logger.NewJSONLogger(logconfig, os.Stdout)
} else if ctx.Bool(DebugFlag.Name) {
debugLogger = logger.NewStructLogger(logconfig)
tracer = debugLogger
tracer = debugLogger.Hooks()
} else {
debugLogger = logger.NewStructLogger(logconfig)
}
Expand Down
5 changes: 3 additions & 2 deletions cmd/evm/staterunner.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ import (
"github.com/ethereum/go-ethereum/core/rawdb"
"github.com/ethereum/go-ethereum/core/state"
"github.com/ethereum/go-ethereum/core/state/snapshot"
"github.com/ethereum/go-ethereum/core/tracing"
"github.com/ethereum/go-ethereum/core/vm"
"github.com/ethereum/go-ethereum/log"
"github.com/ethereum/go-ethereum/tests"
Expand Down Expand Up @@ -68,7 +69,7 @@ func stateTestCmd(ctx *cli.Context) error {
EnableReturnData: !ctx.Bool(DisableReturnDataFlag.Name),
}
var (
tracer vm.EVMLogger
tracer *tracing.Hooks
debugger *logger.StructLogger
)
switch {
Expand All @@ -77,7 +78,7 @@ func stateTestCmd(ctx *cli.Context) error {

case ctx.Bool(DebugFlag.Name):
debugger = logger.NewStructLogger(config)
tracer = debugger
tracer = debugger.Hooks()

default:
debugger = logger.NewStructLogger(config)
Expand Down
31 changes: 29 additions & 2 deletions cmd/utils/flags.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ package utils

import (
"crypto/ecdsa"
"encoding/json"
"fmt"
"io/ioutil"
"math"
Expand Down Expand Up @@ -641,6 +642,17 @@ var (
Usage: "Record information useful for VM and contract debugging",
Category: flags.VMCategory,
}
VMTraceFlag = &cli.StringFlag{
Name: "vmtrace",
Usage: "Name of tracer which should record internal VM operations (costly)",
Category: flags.VMCategory,
}
VMTraceConfigFlag = &cli.StringFlag{
Name: "vmtrace.config",
Usage: "Tracer configuration (JSON)",
Value: "{}",
Category: flags.VMCategory,
}
RPCGlobalGasCapFlag = &cli.Uint64Flag{
Name: "rpc.gascap",
Usage: "Sets a cap on gas that can be used in eth_call/estimateGas (0=infinite)",
Expand Down Expand Up @@ -1349,7 +1361,6 @@ func setWS(ctx *cli.Context, cfg *node.Config) {

cfg.WSReadBuffer = ctx.Int(WSReadBufferFlag.Name)
cfg.WSWriteBuffer = ctx.Int(WSWriteBufferFlag.Name)

}

// setIPC creates an IPC path configuration from the set command line flags,
Expand Down Expand Up @@ -2134,6 +2145,13 @@ func SetEthConfig(ctx *cli.Context, stack *node.Node, cfg *ethconfig.Config) {
if err := kzg4844.UseCKZG(ctx.String(CryptoKZGFlag.Name) == "ckzg"); err != nil {
Fatalf("Failed to set KZG library implementation to %s: %v", ctx.String(CryptoKZGFlag.Name), err)
}
// VM tracing config.
if ctx.IsSet(VMTraceFlag.Name) {
if name := ctx.String(VMTraceFlag.Name); name != "" {
cfg.VMTrace = name
cfg.VMTraceConfig = ctx.String(VMTraceConfigFlag.Name)
}
}
if ctx.IsSet(DisableTxBroadcastFromFlag.Name) {
scheme := enode.V4ID{}
nodeIds := SplitAndTrim(ctx.String(DisableTxBroadcastFromFlag.Name))
Expand Down Expand Up @@ -2404,7 +2422,16 @@ func MakeChain(ctx *cli.Context, stack *node.Node) (chain *core.BlockChain, chai
cache.TrieDirtyLimit = ctx.Int(CacheFlag.Name) * ctx.Int(CacheGCFlag.Name) / 100
}
vmcfg := vm.Config{EnablePreimageRecording: ctx.Bool(VMEnableDebugFlag.Name)}

if ctx.IsSet(VMTraceFlag.Name) {
if name := ctx.String(VMTraceFlag.Name); name != "" {
config := json.RawMessage(ctx.String(VMTraceConfigFlag.Name))
t, err := tracers.LiveDirectory.New(name, config)
if err != nil {
Fatalf("Failed to create tracer %q: %v", name, err)
}
vmcfg.Tracer = t
}
}
// TODO(rjl493456442) disable snapshot generation/wiping if the chain is read only.
// Disable transaction indexing/unindexing by default.
chain, err = core.NewBlockChain(chainDb, cache, gpec, nil, engine, vmcfg, nil, nil)
Expand Down
5 changes: 3 additions & 2 deletions consensus/consortium/common/contract.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ import (
"github.com/ethereum/go-ethereum/consensus/consortium/generated_contracts/staking"
"github.com/ethereum/go-ethereum/core"
"github.com/ethereum/go-ethereum/core/state"
"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/crypto"
Expand Down Expand Up @@ -224,8 +225,8 @@ func (c *ContractIntegrator) WrapUpEpoch(opts *ApplyTransactOpts) error {
func (c *ContractIntegrator) SubmitBlockReward(opts *ApplyTransactOpts) error {
coinbase := opts.Header.Coinbase
balance := opts.State.GetBalance(consensus.SystemAddress)
opts.State.SetBalance(consensus.SystemAddress, big.NewInt(0))
opts.State.AddBalance(coinbase, balance)
opts.State.SetBalance(consensus.SystemAddress, big.NewInt(0), tracing.BalanceDecreaseSystemAddress)
opts.State.AddBalance(coinbase, balance, tracing.BalanceIncreaseRewardMineBlock)

nonce := opts.State.GetNonce(c.coinbase)
isVenoki := c.chainConfig.IsVenoki(opts.Header.Number)
Expand Down
3 changes: 2 additions & 1 deletion consensus/consortium/common/contract_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ import (
"github.com/ethereum/go-ethereum/core"
"github.com/ethereum/go-ethereum/core/rawdb"
"github.com/ethereum/go-ethereum/core/state"
"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/crypto"
Expand Down Expand Up @@ -64,7 +65,7 @@ func TestApplyTransactionSender(t *testing.T) {

// Sender is not an empty account but still has no code, we must
// not get core.ErrSenderNoEOA
state.SetBalance(sender, common.Big1)
state.SetBalance(sender, common.Big1, tracing.BalanceChangeUnspecified)
err = ApplyTransaction(
msg,
&ApplyTransactOpts{
Expand Down
5 changes: 3 additions & 2 deletions consensus/consortium/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import (
"github.com/ethereum/go-ethereum/consensus/consortium/v2/finality"
"github.com/ethereum/go-ethereum/core"
"github.com/ethereum/go-ethereum/core/state"
"github.com/ethereum/go-ethereum/core/tracing"
"github.com/ethereum/go-ethereum/core/types"
"github.com/ethereum/go-ethereum/ethdb"
"github.com/ethereum/go-ethereum/internal/ethapi"
Expand Down Expand Up @@ -283,8 +284,8 @@ func HandleSystemTransaction(engine consensus.Engine, statedb *state.StateDB, ms
if isSystemMsg {
if msg.Amount.Cmp(common.Big0) > 0 {
balance := statedb.GetBalance(consensus.SystemAddress)
statedb.SetBalance(consensus.SystemAddress, big.NewInt(0))
statedb.AddBalance(block.Coinbase(), balance)
statedb.SetBalance(consensus.SystemAddress, big.NewInt(0), tracing.BalanceDecreaseSystemAddress)
statedb.AddBalance(block.Coinbase(), balance, tracing.BalanceIncreaseRewardMineBlock)
}

return true
Expand Down
5 changes: 3 additions & 2 deletions consensus/ethash/consensus.go
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ import (
"github.com/ethereum/go-ethereum/consensus/misc"
"github.com/ethereum/go-ethereum/consensus/misc/eip1559"
"github.com/ethereum/go-ethereum/core/state"
"github.com/ethereum/go-ethereum/core/tracing"
"github.com/ethereum/go-ethereum/core/types"
"github.com/ethereum/go-ethereum/params"
"github.com/ethereum/go-ethereum/rlp"
Expand Down Expand Up @@ -675,10 +676,10 @@ func accumulateRewards(config *params.ChainConfig, state *state.StateDB, header
r.Sub(r, header.Number)
r.Mul(r, blockReward)
r.Div(r, big8)
state.AddBalance(uncle.Coinbase, r)
state.AddBalance(uncle.Coinbase, r, tracing.BalanceIncreaseRewardMineUncle)

r.Div(blockReward, big32)
reward.Add(reward, r)
}
state.AddBalance(header.Coinbase, reward)
state.AddBalance(header.Coinbase, reward, tracing.BalanceIncreaseRewardMineBlock)
}
14 changes: 8 additions & 6 deletions consensus/misc/dao.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ import (
"math/big"

"github.com/ethereum/go-ethereum/core/state"
"github.com/ethereum/go-ethereum/core/tracing"
"github.com/ethereum/go-ethereum/core/types"
"github.com/ethereum/go-ethereum/params"
)
Expand All @@ -40,10 +41,11 @@ var (
// ensure it conforms to DAO hard-fork rules.
//
// DAO hard-fork extension to the header validity:
// a) if the node is no-fork, do not accept blocks in the [fork, fork+10) range
// with the fork specific extra-data set
// b) if the node is pro-fork, require blocks in the specific range to have the
// unique extra-data set.
//
// a) if the node is no-fork, do not accept blocks in the [fork, fork+10) range
// with the fork specific extra-data set
// b) if the node is pro-fork, require blocks in the specific range to have the
// unique extra-data set.
func VerifyDAOHeaderExtraData(config *params.ChainConfig, header *types.Header) error {
// Short circuit validation if the node doesn't care about the DAO fork
if config.DAOForkBlock == nil {
Expand Down Expand Up @@ -79,7 +81,7 @@ func ApplyDAOHardFork(statedb *state.StateDB) {

// Move every DAO account and extra-balance account funds into the refund contract
for _, addr := range params.DAODrainList() {
statedb.AddBalance(params.DAORefundContract, statedb.GetBalance(addr))
statedb.SetBalance(addr, new(big.Int))
statedb.AddBalance(params.DAORefundContract, statedb.GetBalance(addr), tracing.BalanceIncreaseDaoContract)
statedb.SetBalance(addr, new(big.Int), tracing.BalanceDecreaseDaoAccount)
}
}
Loading