From aed572c9fd11f4c858013c8a1e59e787c5159d6e Mon Sep 17 00:00:00 2001 From: Sina Mahmoodi Date: Mon, 14 Oct 2024 06:43:02 +0200 Subject: [PATCH 1/5] Add HooksV2 --- core/tracing/hooks.go | 60 +++++++++++++++++++++++++++++++++++++++---- eth/tracers/live.go | 22 ++++++++++++---- 2 files changed, 72 insertions(+), 10 deletions(-) diff --git a/core/tracing/hooks.go b/core/tracing/hooks.go index 51bac8e7a674..65f428ab7f6f 100644 --- a/core/tracing/hooks.go +++ b/core/tracing/hooks.go @@ -17,6 +17,7 @@ package tracing import ( + "encoding/json" "math/big" "reflect" @@ -71,6 +72,12 @@ type BlockEvent struct { } type ( + // LiveConstructor is the constructor for a live tracer. + LiveConstructor = func(config json.RawMessage) (*Hooks, error) + + // LiveConstructorV2 is the v2 constructor for a live tracer. + LiveConstructorV2 = func(config json.RawMessage) (*HooksV2, error) + /* - VM events - */ @@ -148,7 +155,11 @@ type ( // // Note that system call happens outside normal transaction execution, so the `OnTxStart/OnTxEnd` hooks // will not be invoked. - OnSystemCallStartHook = func(vm *VMContext) + OnSystemCallStartHook = func() + + // OnSystemCallStartHookV2 is called when a system call is about to be executed. Refer + // to docs for OnSystemCallStartHook. + OnSystemCallStartHookV2 = func(vm *VMContext) // OnSystemCallEndHook is called when a system call has finished executing. Today, // this hook is invoked when the EIP-4788 system call is about to be executed to set the @@ -212,7 +223,6 @@ type Hooks struct { OnBlockEnd BlockEndHook OnSkippedBlock SkippedBlockHook OnGenesisBlock GenesisBlockHook - OnReorg ReorgHook OnSystemCallStart OnSystemCallStartHook OnSystemCallEnd OnSystemCallEndHook // State events @@ -221,6 +231,36 @@ type Hooks struct { OnCodeChange CodeChangeHook OnStorageChange StorageChangeHook OnLog LogHook +} + +type HooksV2 struct { + // V1 hooks minus OnBlockchainInit which is removed. + // VM events + OnTxStart TxStartHook + OnTxEnd TxEndHook + OnEnter EnterHook + OnExit ExitHook + OnOpcode OpcodeHook + OnFault FaultHook + OnGasChange GasChangeHook + // Chain events + OnBlockchainInit BlockchainInitHook + OnClose CloseHook + OnBlockStart BlockStartHook + OnBlockEnd BlockEndHook + OnSkippedBlock SkippedBlockHook + OnGenesisBlock GenesisBlockHook + OnSystemCallEnd OnSystemCallEndHook + // State events + OnBalanceChange BalanceChangeHook + OnNonceChange NonceChangeHook + OnCodeChange CodeChangeHook + OnStorageChange StorageChangeHook + OnLog LogHook + + // V2 changes + OnReorg ReorgHook + OnSystemCallStart OnSystemCallStartHookV2 // State reads OnBalanceRead BalanceReadHook OnNonceRead NonceReadHook @@ -232,9 +272,9 @@ type Hooks struct { OnBlockHashRead BlockHashReadHook } -// Copy creates a new Hooks instance with all implemented hooks copied from the original. -func (h *Hooks) Copy() *Hooks { - copied := &Hooks{} +// copyHooks creates a new instance of T with all implemented hooks copied from the original. +func copyHooks[T any](h *T) *T { + copied := new(T) srcValue := reflect.ValueOf(h).Elem() dstValue := reflect.ValueOf(copied).Elem() @@ -247,6 +287,16 @@ func (h *Hooks) Copy() *Hooks { return copied } +// Copy creates a new Hooks instance with all implemented hooks copied from the original. +func (h *Hooks) Copy() *Hooks { + return copyHooks(h) +} + +// Copy creates a new HooksV2 instance with all implemented hooks copied from the original. +func (h *HooksV2) Copy() *HooksV2 { + return copyHooks(h) +} + // BalanceChangeReason is used to indicate the reason for a balance change, useful // for tracing and reporting. type BalanceChangeReason byte diff --git a/eth/tracers/live.go b/eth/tracers/live.go index ffb2303af4f1..ab9bc2310260 100644 --- a/eth/tracers/live.go +++ b/eth/tracers/live.go @@ -7,21 +7,25 @@ import ( "github.com/ethereum/go-ethereum/core/tracing" ) -type ctorFunc func(config json.RawMessage) (*tracing.Hooks, error) - // LiveDirectory is the collection of tracers which can be used // during normal block import operations. -var LiveDirectory = liveDirectory{elems: make(map[string]ctorFunc)} +var LiveDirectory = liveDirectory{elems: make(map[string]tracing.LiveConstructor)} type liveDirectory struct { - elems map[string]ctorFunc + elems map[string]tracing.LiveConstructor + elemsV2 map[string]tracing.LiveConstructorV2 } // Register registers a tracer constructor by name. -func (d *liveDirectory) Register(name string, f ctorFunc) { +func (d *liveDirectory) Register(name string, f tracing.LiveConstructor) { d.elems[name] = f } +// RegisterV2 registers a tracer constructor by name. +func (d *liveDirectory) RegisterV2(name string, f tracing.LiveConstructorV2) { + d.elemsV2[name] = f +} + // New instantiates a tracer by name. func (d *liveDirectory) New(name string, config json.RawMessage) (*tracing.Hooks, error) { if f, ok := d.elems[name]; ok { @@ -29,3 +33,11 @@ func (d *liveDirectory) New(name string, config json.RawMessage) (*tracing.Hooks } return nil, errors.New("not found") } + +// NewV2 instantiates a tracer by name. +func (d *liveDirectory) NewV2(name string, config json.RawMessage) (*tracing.HooksV2, error) { + if f, ok := d.elemsV2[name]; ok { + return f(config) + } + return nil, errors.New("not found") +} From 49d8bd1d06a3c45115ae16cc44ffb2f641a98d69 Mon Sep 17 00:00:00 2001 From: Sina Mahmoodi Date: Tue, 15 Oct 2024 13:19:40 +0200 Subject: [PATCH 2/5] migrate codebase to hooksV2 --- cmd/evm/blockrunner.go | 2 +- cmd/evm/internal/t8ntool/transition.go | 4 +- cmd/evm/runner.go | 2 +- cmd/utils/flags.go | 2 +- core/blockchain.go | 2 +- core/state/statedb.go | 4 +- core/tracing/hooks.go | 38 ++++-- core/tracing/journal.go | 18 +-- core/tracing/journal_test.go | 6 +- core/vm/contract.go | 4 +- core/vm/contracts.go | 2 +- core/vm/interpreter.go | 2 +- eth/backend.go | 2 +- eth/tracers/api.go | 6 +- eth/tracers/dir.go | 7 +- eth/tracers/js/goja.go | 2 +- eth/tracers/live.go | 29 +++-- eth/tracers/live/noop.go | 48 ++++---- eth/tracers/live/noopv2.go | 141 +++++++++++++++++++++++ eth/tracers/live/supply.go | 6 +- eth/tracers/logger/access_list_tracer.go | 4 +- eth/tracers/logger/logger.go | 8 +- eth/tracers/logger/logger_json.go | 12 +- eth/tracers/native/4byte.go | 2 +- eth/tracers/native/call.go | 2 +- eth/tracers/native/call_flat.go | 2 +- eth/tracers/native/mux.go | 2 +- eth/tracers/native/noop.go | 2 +- eth/tracers/native/prestate.go | 2 +- internal/ethapi/logtracer.go | 4 +- tests/block_test_util.go | 2 +- 31 files changed, 270 insertions(+), 99 deletions(-) create mode 100644 eth/tracers/live/noopv2.go diff --git a/cmd/evm/blockrunner.go b/cmd/evm/blockrunner.go index d5cd8d8e3de2..8f7009e2f671 100644 --- a/cmd/evm/blockrunner.go +++ b/cmd/evm/blockrunner.go @@ -51,7 +51,7 @@ func blockTestCmd(ctx *cli.Context) error { return errors.New("path-to-test argument required") } - var tracer *tracing.Hooks + var tracer *tracing.HooksV2 // Configure the EVM logger if ctx.Bool(MachineFlag.Name) { tracer = logger.NewJSONLogger(&logger.Config{ diff --git a/cmd/evm/internal/t8ntool/transition.go b/cmd/evm/internal/t8ntool/transition.go index fa052f59549b..ee543cc06436 100644 --- a/cmd/evm/internal/t8ntool/transition.go +++ b/cmd/evm/internal/t8ntool/transition.go @@ -102,14 +102,14 @@ func Transition(ctx *cli.Context) error { if err != nil { return nil, nil, NewError(ErrorIO, fmt.Errorf("failed creating trace-file: %v", err)) } - var l *tracing.Hooks + var l *tracing.HooksV2 if ctx.Bool(TraceEnableCallFramesFlag.Name) { l = logger.NewJSONLoggerWithCallFrames(logConfig, traceFile) } else { l = logger.NewJSONLogger(logConfig, traceFile) } tracer := &tracers.Tracer{ - Hooks: l, + HooksV2: l, // jsonLogger streams out result to file. GetResult: func() (json.RawMessage, error) { return nil, nil }, Stop: func(err error) {}, diff --git a/cmd/evm/runner.go b/cmd/evm/runner.go index 235fed66302a..ec0748c9480d 100644 --- a/cmd/evm/runner.go +++ b/cmd/evm/runner.go @@ -117,7 +117,7 @@ func runCmd(ctx *cli.Context) error { } var ( - tracer *tracing.Hooks + tracer *tracing.HooksV2 debugLogger *logger.StructLogger statedb *state.StateDB chainConfig *params.ChainConfig diff --git a/cmd/utils/flags.go b/cmd/utils/flags.go index 6db88ff66183..d0b2cb0b0e2b 100644 --- a/cmd/utils/flags.go +++ b/cmd/utils/flags.go @@ -2190,7 +2190,7 @@ func MakeChain(ctx *cli.Context, stack *node.Node, readonly bool) (*core.BlockCh if ctx.IsSet(VMTraceJsonConfigFlag.Name) { config = json.RawMessage(ctx.String(VMTraceJsonConfigFlag.Name)) } - t, err := tracers.LiveDirectory.New(name, config) + t, err := tracers.LiveDirectory.NewV2(name, config) if err != nil { Fatalf("Failed to create tracer %q: %v", name, err) } diff --git a/core/blockchain.go b/core/blockchain.go index 0b8e1b7ad2e4..c033292bfe88 100644 --- a/core/blockchain.go +++ b/core/blockchain.go @@ -258,7 +258,7 @@ type BlockChain struct { prefetcher Prefetcher processor Processor // Block transaction processor interface vmConfig vm.Config - logger *tracing.Hooks + logger *tracing.HooksV2 } // NewBlockChain returns a fully initialised block chain using information diff --git a/core/state/statedb.go b/core/state/statedb.go index 8206dfc86040..5cd210d06c3b 100644 --- a/core/state/statedb.go +++ b/core/state/statedb.go @@ -82,7 +82,7 @@ type StateDB struct { db Database prefetcher *triePrefetcher trie Trie - logger *tracing.Hooks + logger *tracing.HooksV2 reader Reader // originalRoot is the pre-state root, before any changes were made. @@ -191,7 +191,7 @@ func New(root common.Hash, db Database) (*StateDB, error) { } // SetLogger sets the logger for account update hooks. -func (s *StateDB) SetLogger(l *tracing.Hooks) { +func (s *StateDB) SetLogger(l *tracing.HooksV2) { s.logger = l } diff --git a/core/tracing/hooks.go b/core/tracing/hooks.go index 65f428ab7f6f..ec37fdb3297f 100644 --- a/core/tracing/hooks.go +++ b/core/tracing/hooks.go @@ -272,29 +272,51 @@ type HooksV2 struct { OnBlockHashRead BlockHashReadHook } -// copyHooks creates a new instance of T with all implemented hooks copied from the original. -func copyHooks[T any](h *T) *T { - copied := new(T) +// copyHooks creates a new instance of U with all implemented hooks copied from the original T, +// except for those specified in the exclude parameter. +func copyHooks[T, U any](h *T, exclude ...string) *U { + copied := new(U) srcValue := reflect.ValueOf(h).Elem() dstValue := reflect.ValueOf(copied).Elem() + excludeMap := make(map[string]bool) + for _, field := range exclude { + excludeMap[field] = true + } + for i := 0; i < srcValue.NumField(); i++ { - field := srcValue.Field(i) - if !field.IsNil() { - dstValue.Field(i).Set(field) + srcField := srcValue.Type().Field(i) + srcFieldValue := srcValue.Field(i) + + if srcFieldValue.IsNil() || excludeMap[srcField.Name] { + continue + } + + dstField := dstValue.FieldByName(srcField.Name) + if dstField.IsValid() && dstField.CanSet() { + dstField.Set(srcFieldValue) } } + return copied } // Copy creates a new Hooks instance with all implemented hooks copied from the original. func (h *Hooks) Copy() *Hooks { - return copyHooks(h) + return copyHooks[Hooks, Hooks](h) } // Copy creates a new HooksV2 instance with all implemented hooks copied from the original. func (h *HooksV2) Copy() *HooksV2 { - return copyHooks(h) + return copyHooks[HooksV2, HooksV2](h) +} + +// ToV2 converts a Hooks instance to a HooksV2 instance. +// +// Note that OnSystemCallStart hook is excluded from the copy as it is +// changed in a backwards-incompatible way. +func (h *Hooks) ToV2() *HooksV2 { + return copyHooks[Hooks, HooksV2](h, "OnSystemCallStart") } // BalanceChangeReason is used to indicate the reason for a balance change, useful diff --git a/core/tracing/journal.go b/core/tracing/journal.go index 5ec405edf27f..2225039e4eb0 100644 --- a/core/tracing/journal.go +++ b/core/tracing/journal.go @@ -34,7 +34,7 @@ type revision struct { // It will emit the state change hooks with reverse values when a call reverts. type journal struct { entries []entry - hooks *Hooks + hooks *HooksV2 validRevisions []revision nextRevisionId int @@ -42,11 +42,11 @@ type journal struct { } type entry interface { - revert(tracer *Hooks) + revert(tracer *HooksV2) } // WrapWithJournal wraps the given tracer with a journaling layer. -func WrapWithJournal(hooks *Hooks) (*Hooks, error) { +func WrapWithJournal(hooks *HooksV2) (*HooksV2, error) { if hooks == nil { return nil, fmt.Errorf("wrapping nil tracer") } @@ -98,7 +98,7 @@ func (j *journal) snapshot() int { } // revertToSnapshot reverts all state changes made since the given revision. -func (j *journal) revertToSnapshot(revid int, hooks *Hooks) { +func (j *journal) revertToSnapshot(revid int, hooks *HooksV2) { // Find the snapshot in the stack of valid snapshots. idx := sort.Search(len(j.validRevisions), func(i int) bool { return j.validRevisions[i].id >= revid @@ -114,7 +114,7 @@ func (j *journal) revertToSnapshot(revid int, hooks *Hooks) { } // revert undoes a batch of journaled modifications. -func (j *journal) revert(hooks *Hooks, snapshot int) { +func (j *journal) revert(hooks *HooksV2, snapshot int) { for i := len(j.entries) - 1; i >= snapshot; i-- { // Undo the changes made by the operation j.entries[i].revert(hooks) @@ -212,25 +212,25 @@ type ( } ) -func (b balanceChange) revert(hooks *Hooks) { +func (b balanceChange) revert(hooks *HooksV2) { if hooks.OnBalanceChange != nil { hooks.OnBalanceChange(b.addr, b.new, b.prev, BalanceChangeRevert) } } -func (n nonceChange) revert(hooks *Hooks) { +func (n nonceChange) revert(hooks *HooksV2) { if hooks.OnNonceChange != nil { hooks.OnNonceChange(n.addr, n.new, n.prev) } } -func (c codeChange) revert(hooks *Hooks) { +func (c codeChange) revert(hooks *HooksV2) { if hooks.OnCodeChange != nil { hooks.OnCodeChange(c.addr, c.newCodeHash, c.newCode, c.prevCodeHash, c.prevCode) } } -func (s storageChange) revert(hooks *Hooks) { +func (s storageChange) revert(hooks *HooksV2) { if hooks.OnStorageChange != nil { hooks.OnStorageChange(s.addr, s.slot, s.new, s.prev) } diff --git a/core/tracing/journal_test.go b/core/tracing/journal_test.go index 4ae26df7e6df..eec9b13cd0f0 100644 --- a/core/tracing/journal_test.go +++ b/core/tracing/journal_test.go @@ -56,7 +56,7 @@ func (t *testTracer) OnStorageChange(addr common.Address, slot common.Hash, prev func TestJournalIntegration(t *testing.T) { tr := &testTracer{} - wr, err := WrapWithJournal(&Hooks{OnBalanceChange: tr.OnBalanceChange, OnNonceChange: tr.OnNonceChange, OnCodeChange: tr.OnCodeChange, OnStorageChange: tr.OnStorageChange}) + wr, err := WrapWithJournal(&HooksV2{OnBalanceChange: tr.OnBalanceChange, OnNonceChange: tr.OnNonceChange, OnCodeChange: tr.OnCodeChange, OnStorageChange: tr.OnStorageChange}) if err != nil { t.Fatalf("failed to wrap test tracer: %v", err) } @@ -92,7 +92,7 @@ func TestJournalIntegration(t *testing.T) { func TestJournalTopRevert(t *testing.T) { tr := &testTracer{} - wr, err := WrapWithJournal(&Hooks{OnBalanceChange: tr.OnBalanceChange, OnNonceChange: tr.OnNonceChange}) + wr, err := WrapWithJournal(&HooksV2{OnBalanceChange: tr.OnBalanceChange, OnNonceChange: tr.OnNonceChange}) if err != nil { t.Fatalf("failed to wrap test tracer: %v", err) } @@ -115,7 +115,7 @@ func TestJournalTopRevert(t *testing.T) { func TestJournalNestedCalls(t *testing.T) { tr := &testTracer{} - wr, err := WrapWithJournal(&Hooks{OnBalanceChange: tr.OnBalanceChange, OnNonceChange: tr.OnNonceChange}) + wr, err := WrapWithJournal(&HooksV2{OnBalanceChange: tr.OnBalanceChange, OnNonceChange: tr.OnNonceChange}) if err != nil { t.Fatalf("failed to wrap test tracer: %v", err) } diff --git a/core/vm/contract.go b/core/vm/contract.go index cfda75b27e11..f312e63a660c 100644 --- a/core/vm/contract.go +++ b/core/vm/contract.go @@ -161,7 +161,7 @@ func (c *Contract) Caller() common.Address { } // UseGas attempts the use gas and subtracts it and returns true on success -func (c *Contract) UseGas(gas uint64, logger *tracing.Hooks, reason tracing.GasChangeReason) (ok bool) { +func (c *Contract) UseGas(gas uint64, logger *tracing.HooksV2, reason tracing.GasChangeReason) (ok bool) { if c.Gas < gas { return false } @@ -173,7 +173,7 @@ func (c *Contract) UseGas(gas uint64, logger *tracing.Hooks, reason tracing.GasC } // RefundGas refunds gas to the contract -func (c *Contract) RefundGas(gas uint64, logger *tracing.Hooks, reason tracing.GasChangeReason) { +func (c *Contract) RefundGas(gas uint64, logger *tracing.HooksV2, reason tracing.GasChangeReason) { if gas == 0 { return } diff --git a/core/vm/contracts.go b/core/vm/contracts.go index 104d2ba814b2..1d5265cb5e05 100644 --- a/core/vm/contracts.go +++ b/core/vm/contracts.go @@ -220,7 +220,7 @@ func ActivePrecompiles(rules params.Rules) []common.Address { // - the returned bytes, // - the _remaining_ gas, // - any error that occurred -func RunPrecompiledContract(p PrecompiledContract, input []byte, suppliedGas uint64, logger *tracing.Hooks) (ret []byte, remainingGas uint64, err error) { +func RunPrecompiledContract(p PrecompiledContract, input []byte, suppliedGas uint64, logger *tracing.HooksV2) (ret []byte, remainingGas uint64, err error) { gasCost := p.RequiredGas(input) if suppliedGas < gasCost { return nil, 0, ErrOutOfGas diff --git a/core/vm/interpreter.go b/core/vm/interpreter.go index 793f398367a7..257b518c3e35 100644 --- a/core/vm/interpreter.go +++ b/core/vm/interpreter.go @@ -29,7 +29,7 @@ import ( // Config are the configuration options for the Interpreter type Config struct { - Tracer *tracing.Hooks + Tracer *tracing.HooksV2 NoBaseFee bool // Forces the EIP-1559 baseFee to 0 (needed for 0 price calls) EnablePreimageRecording bool // Enables recording of SHA3/keccak preimages ExtraEips []int // Additional EIPS that are to be enabled diff --git a/eth/backend.go b/eth/backend.go index f10d99c3a70b..1979af9a5ed8 100644 --- a/eth/backend.go +++ b/eth/backend.go @@ -201,7 +201,7 @@ func New(stack *node.Node, config *ethconfig.Config) (*Ethereum, error) { if config.VMTraceJsonConfig != "" { traceConfig = json.RawMessage(config.VMTraceJsonConfig) } - t, err := tracers.LiveDirectory.New(config.VMTrace, traceConfig) + t, err := tracers.LiveDirectory.NewV2(config.VMTrace, traceConfig) if err != nil { return nil, fmt.Errorf("failed to create tracer %s: %v", config.VMTrace, err) } diff --git a/eth/tracers/api.go b/eth/tracers/api.go index a8289512069b..67caa0f006a3 100644 --- a/eth/tracers/api.go +++ b/eth/tracers/api.go @@ -1004,7 +1004,7 @@ func (api *API) traceTx(ctx context.Context, tx *types.Transaction, message *cor if config.Tracer == nil { logger := logger.NewStructLogger(config.Config) tracer = &Tracer{ - Hooks: logger.Hooks(), + HooksV2: logger.Hooks(), GetResult: logger.GetResult, Stop: logger.Stop, } @@ -1015,8 +1015,8 @@ func (api *API) traceTx(ctx context.Context, tx *types.Transaction, message *cor } } // The actual TxContext will be created as part of ApplyTransactionWithEVM. - vmenv := vm.NewEVM(vmctx, vm.TxContext{GasPrice: message.GasPrice, BlobFeeCap: message.BlobGasFeeCap}, statedb, api.backend.ChainConfig(), vm.Config{Tracer: tracer.Hooks, NoBaseFee: true}) - statedb.SetLogger(tracer.Hooks) + vmenv := vm.NewEVM(vmctx, vm.TxContext{GasPrice: message.GasPrice, BlobFeeCap: message.BlobGasFeeCap}, statedb, api.backend.ChainConfig(), vm.Config{Tracer: tracer.Hooks(), NoBaseFee: true}) + statedb.SetLogger(tracer.Hooks()) // Define a meaningful timeout of a single transaction trace if config.Timeout != nil { diff --git a/eth/tracers/dir.go b/eth/tracers/dir.go index 650815350b37..e60adf2852f4 100644 --- a/eth/tracers/dir.go +++ b/eth/tracers/dir.go @@ -38,12 +38,17 @@ type Context struct { // This involves a method to retrieve results and one to // stop tracing. type Tracer struct { - *tracing.Hooks + *tracing.HooksV2 GetResult func() (json.RawMessage, error) // Stop terminates execution of the tracer at the first opportune moment. Stop func(err error) } +// Hooks returns the hooks of the tracer. +func (t *Tracer) Hooks() *tracing.HooksV2 { + return t.HooksV2 +} + type ctorFn func(*Context, json.RawMessage) (*Tracer, error) type jsCtorFn func(string, *Context, json.RawMessage) (*Tracer, error) diff --git a/eth/tracers/js/goja.go b/eth/tracers/js/goja.go index b823ef740a86..644514d4885d 100644 --- a/eth/tracers/js/goja.go +++ b/eth/tracers/js/goja.go @@ -223,7 +223,7 @@ func newJsTracer(code string, ctx *tracers.Context, cfg json.RawMessage) (*trace t.logValue = t.log.setupObject() return &tracers.Tracer{ - Hooks: &tracing.Hooks{ + HooksV2: &tracing.HooksV2{ OnTxStart: t.OnTxStart, OnTxEnd: t.OnTxEnd, OnEnter: t.OnEnter, diff --git a/eth/tracers/live.go b/eth/tracers/live.go index ab9bc2310260..a6508296142c 100644 --- a/eth/tracers/live.go +++ b/eth/tracers/live.go @@ -9,35 +9,40 @@ import ( // LiveDirectory is the collection of tracers which can be used // during normal block import operations. -var LiveDirectory = liveDirectory{elems: make(map[string]tracing.LiveConstructor)} +var LiveDirectory = liveDirectory{elems: make(map[string]tracing.LiveConstructorV2)} type liveDirectory struct { - elems map[string]tracing.LiveConstructor - elemsV2 map[string]tracing.LiveConstructorV2 + elems map[string]tracing.LiveConstructorV2 } // Register registers a tracer constructor by name. func (d *liveDirectory) Register(name string, f tracing.LiveConstructor) { - d.elems[name] = f + d.elems[name] = wrapV1(f) } // RegisterV2 registers a tracer constructor by name. func (d *liveDirectory) RegisterV2(name string, f tracing.LiveConstructorV2) { - d.elemsV2[name] = f + d.elems[name] = f } -// New instantiates a tracer by name. -func (d *liveDirectory) New(name string, config json.RawMessage) (*tracing.Hooks, error) { +// NewV2 instantiates a tracer by name. +func (d *liveDirectory) NewV2(name string, config json.RawMessage) (*tracing.HooksV2, error) { if f, ok := d.elems[name]; ok { return f(config) } return nil, errors.New("not found") } -// NewV2 instantiates a tracer by name. -func (d *liveDirectory) NewV2(name string, config json.RawMessage) (*tracing.HooksV2, error) { - if f, ok := d.elemsV2[name]; ok { - return f(config) +func wrapV1(ctor tracing.LiveConstructor) tracing.LiveConstructorV2 { + return func(config json.RawMessage) (*tracing.HooksV2, error) { + hooks, err := ctor(config) + if err != nil { + return nil, err + } + v2 := hooks.ToV2() + v2.OnSystemCallStart = func(ctx *tracing.VMContext) { + hooks.OnSystemCallStart() + } + return v2, nil } - return nil, errors.New("not found") } diff --git a/eth/tracers/live/noop.go b/eth/tracers/live/noop.go index 614a2c554b18..069063a6fa1c 100644 --- a/eth/tracers/live/noop.go +++ b/eth/tracers/live/noop.go @@ -24,31 +24,25 @@ type noop struct{} func newNoopTracer(_ json.RawMessage) (*tracing.Hooks, error) { t := &noop{} return &tracing.Hooks{ - OnTxStart: t.OnTxStart, - OnTxEnd: t.OnTxEnd, - OnEnter: t.OnEnter, - OnExit: t.OnExit, - OnOpcode: t.OnOpcode, - OnFault: t.OnFault, - OnGasChange: t.OnGasChange, - OnBlockchainInit: t.OnBlockchainInit, - OnBlockStart: t.OnBlockStart, - OnBlockEnd: t.OnBlockEnd, - OnSkippedBlock: t.OnSkippedBlock, - OnGenesisBlock: t.OnGenesisBlock, - OnReorg: t.OnReorg, - OnBalanceChange: t.OnBalanceChange, - OnNonceChange: t.OnNonceChange, - OnCodeChange: t.OnCodeChange, - OnStorageChange: t.OnStorageChange, - OnLog: t.OnLog, - OnBalanceRead: t.OnBalanceRead, - OnNonceRead: t.OnNonceRead, - OnCodeRead: t.OnCodeRead, - OnCodeSizeRead: t.OnCodeSizeRead, - OnCodeHashRead: t.OnCodeHashRead, - OnStorageRead: t.OnStorageRead, - OnBlockHashRead: t.OnBlockHashRead, + OnTxStart: t.OnTxStart, + OnTxEnd: t.OnTxEnd, + OnEnter: t.OnEnter, + OnExit: t.OnExit, + OnOpcode: t.OnOpcode, + OnFault: t.OnFault, + OnGasChange: t.OnGasChange, + OnBlockchainInit: t.OnBlockchainInit, + OnBlockStart: t.OnBlockStart, + OnBlockEnd: t.OnBlockEnd, + OnSkippedBlock: t.OnSkippedBlock, + OnGenesisBlock: t.OnGenesisBlock, + OnSystemCallStart: t.OnSystemCallStart, + OnSystemCallEnd: t.OnSystemCallEnd, + OnBalanceChange: t.OnBalanceChange, + OnNonceChange: t.OnNonceChange, + OnCodeChange: t.OnCodeChange, + OnStorageChange: t.OnStorageChange, + OnLog: t.OnLog, }, nil } @@ -84,6 +78,10 @@ func (t *noop) OnBlockchainInit(chainConfig *params.ChainConfig) { func (t *noop) OnGenesisBlock(b *types.Block, alloc types.GenesisAlloc) { } +func (t *noop) OnSystemCallStart() {} + +func (t *noop) OnSystemCallEnd() {} + func (t *noop) OnReorg(reverted []*types.Block) {} func (t *noop) OnBalanceChange(a common.Address, prev, new *big.Int, reason tracing.BalanceChangeReason) { diff --git a/eth/tracers/live/noopv2.go b/eth/tracers/live/noopv2.go new file mode 100644 index 000000000000..2b5f72812b07 --- /dev/null +++ b/eth/tracers/live/noopv2.go @@ -0,0 +1,141 @@ +// Copyright 2024 The go-ethereum Authors +// This file is part of the go-ethereum library. +// +// The go-ethereum library is free software: you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// The go-ethereum library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with the go-ethereum library. If not, see . + +package live + +import ( + "encoding/json" + "math/big" + + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/core/tracing" + "github.com/ethereum/go-ethereum/core/types" + "github.com/ethereum/go-ethereum/eth/tracers" + "github.com/ethereum/go-ethereum/params" +) + +func init() { + tracers.LiveDirectory.RegisterV2("noopv2", newNoopV2Tracer) +} + +// noopV2 is a no-op live tracer. It's there to +// catch changes in the tracing interface, as well as +// for testing live tracing performance. Can be removed +// as soon as we have a real live tracer. +type noopV2 struct{} + +func newNoopV2Tracer(_ json.RawMessage) (*tracing.HooksV2, error) { + t := &noopV2{} + return &tracing.HooksV2{ + OnTxStart: t.OnTxStart, + OnTxEnd: t.OnTxEnd, + OnEnter: t.OnEnter, + OnExit: t.OnExit, + OnOpcode: t.OnOpcode, + OnFault: t.OnFault, + OnGasChange: t.OnGasChange, + OnBlockchainInit: t.OnBlockchainInit, + OnBlockStart: t.OnBlockStart, + OnBlockEnd: t.OnBlockEnd, + OnSkippedBlock: t.OnSkippedBlock, + OnGenesisBlock: t.OnGenesisBlock, + OnSystemCallStart: t.OnSystemCallStart, + OnSystemCallEnd: t.OnSystemCallEnd, + OnReorg: t.OnReorg, + OnBalanceChange: t.OnBalanceChange, + OnNonceChange: t.OnNonceChange, + OnCodeChange: t.OnCodeChange, + OnStorageChange: t.OnStorageChange, + OnLog: t.OnLog, + OnBalanceRead: t.OnBalanceRead, + OnNonceRead: t.OnNonceRead, + OnCodeRead: t.OnCodeRead, + OnCodeSizeRead: t.OnCodeSizeRead, + OnCodeHashRead: t.OnCodeHashRead, + OnStorageRead: t.OnStorageRead, + OnBlockHashRead: t.OnBlockHashRead, + }, nil +} + +func (t *noopV2) OnOpcode(pc uint64, op byte, gas, cost uint64, scope tracing.OpContext, rData []byte, depth int, err error) { +} + +func (t *noopV2) OnFault(pc uint64, op byte, gas, cost uint64, _ tracing.OpContext, depth int, err error) { +} + +func (t *noopV2) OnEnter(depth int, typ byte, from common.Address, to common.Address, input []byte, gas uint64, value *big.Int) { +} + +func (t *noopV2) OnExit(depth int, output []byte, gasUsed uint64, err error, reverted bool) { +} + +func (t *noopV2) OnTxStart(vm *tracing.VMContext, tx *types.Transaction, from common.Address) { +} + +func (t *noopV2) OnTxEnd(receipt *types.Receipt, err error) { +} + +func (t *noopV2) OnBlockStart(ev tracing.BlockEvent) { +} + +func (t *noopV2) OnBlockEnd(err error) { +} + +func (t *noopV2) OnSkippedBlock(ev tracing.BlockEvent) {} + +func (t *noopV2) OnBlockchainInit(chainConfig *params.ChainConfig) { +} + +func (t *noopV2) OnGenesisBlock(b *types.Block, alloc types.GenesisAlloc) { +} + +func (t *noopV2) OnSystemCallStart(ctx *tracing.VMContext) {} + +func (t *noopV2) OnSystemCallEnd() {} + +func (t *noopV2) OnReorg(reverted []*types.Block) {} + +func (t *noopV2) OnBalanceChange(a common.Address, prev, new *big.Int, reason tracing.BalanceChangeReason) { +} + +func (t *noopV2) OnNonceChange(a common.Address, prev, new uint64) { +} + +func (t *noopV2) OnCodeChange(a common.Address, prevCodeHash common.Hash, prev []byte, codeHash common.Hash, code []byte) { +} + +func (t *noopV2) OnStorageChange(a common.Address, k, prev, new common.Hash) { +} + +func (t *noopV2) OnLog(l *types.Log) { + +} + +func (t *noopV2) OnBalanceRead(addr common.Address, bal *big.Int) {} + +func (t *noopV2) OnNonceRead(addr common.Address, nonce uint64) {} + +func (t *noopV2) OnCodeRead(addr common.Address, code []byte) {} + +func (t *noopV2) OnCodeSizeRead(addr common.Address, size int) {} + +func (t *noopV2) OnCodeHashRead(addr common.Address, hash common.Hash) {} + +func (t *noopV2) OnStorageRead(addr common.Address, slot, val common.Hash) {} + +func (t *noopV2) OnBlockHashRead(number uint64, hash common.Hash) {} + +func (t *noopV2) OnGasChange(old, new uint64, reason tracing.GasChangeReason) {} diff --git a/eth/tracers/live/supply.go b/eth/tracers/live/supply.go index 96f70594548c..2ab4c6c59b1c 100644 --- a/eth/tracers/live/supply.go +++ b/eth/tracers/live/supply.go @@ -19,7 +19,7 @@ import ( ) func init() { - tracers.LiveDirectory.Register("supply", newSupply) + tracers.LiveDirectory.RegisterV2("supply", newSupply) } type supplyInfoIssuance struct { @@ -74,7 +74,7 @@ type supplyTracerConfig struct { 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) { +func newSupply(cfg json.RawMessage) (*tracing.HooksV2, error) { var config supplyTracerConfig if cfg != nil { if err := json.Unmarshal(cfg, &config); err != nil { @@ -97,7 +97,7 @@ func newSupply(cfg json.RawMessage) (*tracing.Hooks, error) { delta: newSupplyInfo(), logger: logger, } - return &tracing.Hooks{ + return &tracing.HooksV2{ OnBlockStart: t.OnBlockStart, OnBlockEnd: t.OnBlockEnd, OnGenesisBlock: t.OnGenesisBlock, diff --git a/eth/tracers/logger/access_list_tracer.go b/eth/tracers/logger/access_list_tracer.go index e8231461b0cf..76144ac15297 100644 --- a/eth/tracers/logger/access_list_tracer.go +++ b/eth/tracers/logger/access_list_tracer.go @@ -125,8 +125,8 @@ func NewAccessListTracer(acl types.AccessList, from, to common.Address, precompi } } -func (a *AccessListTracer) Hooks() *tracing.Hooks { - return &tracing.Hooks{ +func (a *AccessListTracer) Hooks() *tracing.HooksV2 { + return &tracing.HooksV2{ OnOpcode: a.OnOpcode, } } diff --git a/eth/tracers/logger/logger.go b/eth/tracers/logger/logger.go index b952c822863f..7f6bbb0ebbda 100644 --- a/eth/tracers/logger/logger.go +++ b/eth/tracers/logger/logger.go @@ -132,8 +132,8 @@ func NewStructLogger(cfg *Config) *StructLogger { return logger } -func (l *StructLogger) Hooks() *tracing.Hooks { - return &tracing.Hooks{ +func (l *StructLogger) Hooks() *tracing.HooksV2 { + return &tracing.HooksV2{ OnTxStart: l.OnTxStart, OnTxEnd: l.OnTxEnd, OnExit: l.OnExit, @@ -345,8 +345,8 @@ func NewMarkdownLogger(cfg *Config, writer io.Writer) *mdLogger { return l } -func (t *mdLogger) Hooks() *tracing.Hooks { - return &tracing.Hooks{ +func (t *mdLogger) Hooks() *tracing.HooksV2 { + return &tracing.HooksV2{ OnTxStart: t.OnTxStart, OnEnter: t.OnEnter, OnExit: t.OnExit, diff --git a/eth/tracers/logger/logger_json.go b/eth/tracers/logger/logger_json.go index de021e74bef8..3f5fa415cf01 100644 --- a/eth/tracers/logger/logger_json.go +++ b/eth/tracers/logger/logger_json.go @@ -58,17 +58,17 @@ type jsonLogger struct { encoder *json.Encoder cfg *Config env *tracing.VMContext - hooks *tracing.Hooks + hooks *tracing.HooksV2 } // NewJSONLogger creates a new EVM tracer that prints execution steps as JSON objects // into the provided stream. -func NewJSONLogger(cfg *Config, writer io.Writer) *tracing.Hooks { +func NewJSONLogger(cfg *Config, writer io.Writer) *tracing.HooksV2 { l := &jsonLogger{encoder: json.NewEncoder(writer), cfg: cfg} if l.cfg == nil { l.cfg = &Config{} } - l.hooks = &tracing.Hooks{ + l.hooks = &tracing.HooksV2{ OnTxStart: l.OnTxStart, OnSystemCallStart: l.onSystemCallStart, OnExit: l.OnEnd, @@ -80,12 +80,12 @@ func NewJSONLogger(cfg *Config, writer io.Writer) *tracing.Hooks { // NewJSONLoggerWithCallFrames creates a new EVM tracer that prints execution steps as JSON objects // into the provided stream. It also includes call frames in the output. -func NewJSONLoggerWithCallFrames(cfg *Config, writer io.Writer) *tracing.Hooks { +func NewJSONLoggerWithCallFrames(cfg *Config, writer io.Writer) *tracing.HooksV2 { l := &jsonLogger{encoder: json.NewEncoder(writer), cfg: cfg} if l.cfg == nil { l.cfg = &Config{} } - l.hooks = &tracing.Hooks{ + l.hooks = &tracing.HooksV2{ OnTxStart: l.OnTxStart, OnSystemCallStart: l.onSystemCallStart, OnEnter: l.OnEnter, @@ -130,7 +130,7 @@ func (l *jsonLogger) OnOpcode(pc uint64, op byte, gas, cost uint64, scope tracin func (l *jsonLogger) onSystemCallStart(_ *tracing.VMContext) { // Process no events while in system call. hooks := *l.hooks - *l.hooks = tracing.Hooks{ + *l.hooks = tracing.HooksV2{ OnSystemCallEnd: func() { *l.hooks = hooks }, diff --git a/eth/tracers/native/4byte.go b/eth/tracers/native/4byte.go index 6cb0e433d27d..e175bc829d47 100644 --- a/eth/tracers/native/4byte.go +++ b/eth/tracers/native/4byte.go @@ -61,7 +61,7 @@ func newFourByteTracer(ctx *tracers.Context, _ json.RawMessage) (*tracers.Tracer ids: make(map[string]int), } return &tracers.Tracer{ - Hooks: &tracing.Hooks{ + HooksV2: &tracing.HooksV2{ OnTxStart: t.OnTxStart, OnEnter: t.OnEnter, }, diff --git a/eth/tracers/native/call.go b/eth/tracers/native/call.go index 1b94dd7b6771..f79790bc17fa 100644 --- a/eth/tracers/native/call.go +++ b/eth/tracers/native/call.go @@ -131,7 +131,7 @@ func newCallTracer(ctx *tracers.Context, cfg json.RawMessage) (*tracers.Tracer, return nil, err } return &tracers.Tracer{ - Hooks: &tracing.Hooks{ + HooksV2: &tracing.HooksV2{ OnTxStart: t.OnTxStart, OnTxEnd: t.OnTxEnd, OnEnter: t.OnEnter, diff --git a/eth/tracers/native/call_flat.go b/eth/tracers/native/call_flat.go index a47b79f8df26..f68050f39fb3 100644 --- a/eth/tracers/native/call_flat.go +++ b/eth/tracers/native/call_flat.go @@ -142,7 +142,7 @@ func newFlatCallTracer(ctx *tracers.Context, cfg json.RawMessage) (*tracers.Trac ft := &flatCallTracer{tracer: t, ctx: ctx, config: config} return &tracers.Tracer{ - Hooks: &tracing.Hooks{ + HooksV2: &tracing.HooksV2{ OnTxStart: ft.OnTxStart, OnTxEnd: ft.OnTxEnd, OnEnter: ft.OnEnter, diff --git a/eth/tracers/native/mux.go b/eth/tracers/native/mux.go index c3b1d9f8cafa..aa8aa75c226e 100644 --- a/eth/tracers/native/mux.go +++ b/eth/tracers/native/mux.go @@ -58,7 +58,7 @@ func newMuxTracer(ctx *tracers.Context, cfg json.RawMessage) (*tracers.Tracer, e t := &muxTracer{names: names, tracers: objects} return &tracers.Tracer{ - Hooks: &tracing.Hooks{ + HooksV2: &tracing.HooksV2{ OnTxStart: t.OnTxStart, OnTxEnd: t.OnTxEnd, OnEnter: t.OnEnter, diff --git a/eth/tracers/native/noop.go b/eth/tracers/native/noop.go index f147134610c0..4dd4dfa3d275 100644 --- a/eth/tracers/native/noop.go +++ b/eth/tracers/native/noop.go @@ -38,7 +38,7 @@ type noopTracer struct{} func newNoopTracer(ctx *tracers.Context, _ json.RawMessage) (*tracers.Tracer, error) { t := &noopTracer{} return &tracers.Tracer{ - Hooks: &tracing.Hooks{ + HooksV2: &tracing.HooksV2{ OnTxStart: t.OnTxStart, OnTxEnd: t.OnTxEnd, OnEnter: t.OnEnter, diff --git a/eth/tracers/native/prestate.go b/eth/tracers/native/prestate.go index b353c0696067..29da03c92515 100644 --- a/eth/tracers/native/prestate.go +++ b/eth/tracers/native/prestate.go @@ -89,7 +89,7 @@ func newPrestateTracer(ctx *tracers.Context, cfg json.RawMessage) (*tracers.Trac deleted: make(map[common.Address]bool), } return &tracers.Tracer{ - Hooks: &tracing.Hooks{ + HooksV2: &tracing.HooksV2{ OnTxStart: t.OnTxStart, OnTxEnd: t.OnTxEnd, OnOpcode: t.OnOpcode, diff --git a/internal/ethapi/logtracer.go b/internal/ethapi/logtracer.go index 456aa937367f..be25f92a59a0 100644 --- a/internal/ethapi/logtracer.go +++ b/internal/ethapi/logtracer.go @@ -68,8 +68,8 @@ func newTracer(traceTransfers bool, blockNumber uint64, blockHash, txHash common } } -func (t *tracer) Hooks() *tracing.Hooks { - return &tracing.Hooks{ +func (t *tracer) Hooks() *tracing.HooksV2 { + return &tracing.HooksV2{ OnEnter: t.onEnter, OnExit: t.onExit, OnLog: t.onLog, diff --git a/tests/block_test_util.go b/tests/block_test_util.go index b0a31a69720b..1f440b488939 100644 --- a/tests/block_test_util.go +++ b/tests/block_test_util.go @@ -110,7 +110,7 @@ type btHeaderMarshaling struct { ExcessBlobGas *math.HexOrDecimal64 } -func (t *BlockTest) Run(snapshotter bool, scheme string, witness bool, tracer *tracing.Hooks, postCheck func(error, *core.BlockChain)) (result error) { +func (t *BlockTest) Run(snapshotter bool, scheme string, witness bool, tracer *tracing.HooksV2, postCheck func(error, *core.BlockChain)) (result error) { config, ok := Forks[t.json.Network] if !ok { return UnsupportedForkError{t.json.Network} From 2681f9bdac16cd5a960e81a524c3116d2f28a1ef Mon Sep 17 00:00:00 2001 From: Sina Mahmoodi Date: Fri, 25 Oct 2024 15:58:31 +0200 Subject: [PATCH 3/5] move to v2 directory --- cmd/evm/blockrunner.go | 4 +- cmd/evm/internal/t8ntool/transition.go | 6 +- cmd/evm/runner.go | 4 +- cmd/utils/flags.go | 3 +- consensus/beacon/consensus.go | 2 +- consensus/ethash/consensus.go | 2 +- consensus/misc/dao.go | 2 +- core/blockchain.go | 4 +- core/evm.go | 2 +- core/genesis.go | 2 +- core/state/statedb.go | 2 +- core/state/statedb_hooked.go | 8 +-- core/state_transition.go | 2 +- core/tracing/hooks.go | 86 +----------------------- core/tracing/{ => v2}/journal.go | 20 +++--- core/tracing/{ => v2}/journal_test.go | 8 +-- core/vm/contract.go | 6 +- core/vm/contracts.go | 4 +- core/vm/eips.go | 2 +- core/vm/evm.go | 2 +- core/vm/instructions.go | 2 +- core/vm/interface.go | 2 +- core/vm/interpreter.go | 4 +- core/vm/operations_acl.go | 2 +- eth/backend.go | 4 +- eth/tracers/api.go | 4 +- eth/tracers/dir.go | 9 +-- eth/tracers/js/goja.go | 4 +- eth/tracers/live.go | 41 +++++------ eth/tracers/live/noopv2.go | 10 ++- eth/tracers/live/supply.go | 9 ++- eth/tracers/logger/access_list_tracer.go | 6 +- eth/tracers/logger/logger.go | 10 +-- eth/tracers/logger/logger_json.go | 14 ++-- eth/tracers/native/4byte.go | 4 +- eth/tracers/native/call.go | 4 +- eth/tracers/native/call_flat.go | 4 +- eth/tracers/native/mux.go | 4 +- eth/tracers/native/noop.go | 4 +- eth/tracers/native/prestate.go | 4 +- internal/ethapi/api.go | 2 +- internal/ethapi/logtracer.go | 6 +- tests/block_test_util.go | 4 +- 43 files changed, 118 insertions(+), 210 deletions(-) rename core/tracing/{ => v2}/journal.go (93%) rename core/tracing/{ => v2}/journal_test.go (94%) diff --git a/cmd/evm/blockrunner.go b/cmd/evm/blockrunner.go index 8f7009e2f671..44477296cc6a 100644 --- a/cmd/evm/blockrunner.go +++ b/cmd/evm/blockrunner.go @@ -26,7 +26,7 @@ import ( "github.com/ethereum/go-ethereum/core" "github.com/ethereum/go-ethereum/core/rawdb" - "github.com/ethereum/go-ethereum/core/tracing" + tracing "github.com/ethereum/go-ethereum/core/tracing/v2" "github.com/ethereum/go-ethereum/eth/tracers/logger" "github.com/ethereum/go-ethereum/tests" "github.com/urfave/cli/v2" @@ -51,7 +51,7 @@ func blockTestCmd(ctx *cli.Context) error { return errors.New("path-to-test argument required") } - var tracer *tracing.HooksV2 + var tracer *tracing.Hooks // Configure the EVM logger if ctx.Bool(MachineFlag.Name) { tracer = logger.NewJSONLogger(&logger.Config{ diff --git a/cmd/evm/internal/t8ntool/transition.go b/cmd/evm/internal/t8ntool/transition.go index 1160f512cc62..fa477dec1127 100644 --- a/cmd/evm/internal/t8ntool/transition.go +++ b/cmd/evm/internal/t8ntool/transition.go @@ -29,7 +29,7 @@ import ( "github.com/ethereum/go-ethereum/common/hexutil" "github.com/ethereum/go-ethereum/consensus/misc/eip1559" "github.com/ethereum/go-ethereum/core/state" - "github.com/ethereum/go-ethereum/core/tracing" + tracing "github.com/ethereum/go-ethereum/core/tracing/v2" "github.com/ethereum/go-ethereum/core/types" "github.com/ethereum/go-ethereum/core/vm" "github.com/ethereum/go-ethereum/eth/tracers" @@ -104,14 +104,14 @@ func Transition(ctx *cli.Context) error { if err != nil { return nil, nil, NewError(ErrorIO, fmt.Errorf("failed creating trace-file: %v", err)) } - var l *tracing.HooksV2 + var l *tracing.Hooks if ctx.Bool(TraceEnableCallFramesFlag.Name) { l = logger.NewJSONLoggerWithCallFrames(logConfig, traceFile) } else { l = logger.NewJSONLogger(logConfig, traceFile) } tracer := &tracers.Tracer{ - HooksV2: l, + Hooks: l, // jsonLogger streams out result to file. GetResult: func() (json.RawMessage, error) { return nil, nil }, Stop: func(err error) {}, diff --git a/cmd/evm/runner.go b/cmd/evm/runner.go index ec0748c9480d..af12b7a0fe81 100644 --- a/cmd/evm/runner.go +++ b/cmd/evm/runner.go @@ -33,7 +33,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" + tracing "github.com/ethereum/go-ethereum/core/tracing/v2" "github.com/ethereum/go-ethereum/core/vm" "github.com/ethereum/go-ethereum/core/vm/runtime" "github.com/ethereum/go-ethereum/eth/tracers/logger" @@ -117,7 +117,7 @@ func runCmd(ctx *cli.Context) error { } var ( - tracer *tracing.HooksV2 + tracer *tracing.Hooks debugLogger *logger.StructLogger statedb *state.StateDB chainConfig *params.ChainConfig diff --git a/cmd/utils/flags.go b/cmd/utils/flags.go index 65a410eed34c..1ab126ed51b6 100644 --- a/cmd/utils/flags.go +++ b/cmd/utils/flags.go @@ -42,6 +42,7 @@ import ( "github.com/ethereum/go-ethereum/common/fdlimit" "github.com/ethereum/go-ethereum/core" "github.com/ethereum/go-ethereum/core/rawdb" + tracing "github.com/ethereum/go-ethereum/core/tracing/v2" "github.com/ethereum/go-ethereum/core/txpool/blobpool" "github.com/ethereum/go-ethereum/core/txpool/legacypool" "github.com/ethereum/go-ethereum/core/vm" @@ -2180,7 +2181,7 @@ func MakeChain(ctx *cli.Context, stack *node.Node, readonly bool) (*core.BlockCh if ctx.IsSet(VMTraceFlag.Name) { if name := ctx.String(VMTraceFlag.Name); name != "" { config := json.RawMessage(ctx.String(VMTraceJsonConfigFlag.Name)) - t, err := tracers.LiveDirectory.NewV2(name, config) + t, err := tracing.LiveDirectory.New(name, config) if err != nil { Fatalf("Failed to create tracer %q: %v", name, err) } diff --git a/consensus/beacon/consensus.go b/consensus/beacon/consensus.go index 4ee19c7d4d6e..ebe9f89547a2 100644 --- a/consensus/beacon/consensus.go +++ b/consensus/beacon/consensus.go @@ -26,7 +26,7 @@ import ( "github.com/ethereum/go-ethereum/consensus/misc/eip1559" "github.com/ethereum/go-ethereum/consensus/misc/eip4844" "github.com/ethereum/go-ethereum/core/state" - "github.com/ethereum/go-ethereum/core/tracing" + tracing "github.com/ethereum/go-ethereum/core/tracing/v2" "github.com/ethereum/go-ethereum/core/types" "github.com/ethereum/go-ethereum/core/vm" "github.com/ethereum/go-ethereum/params" diff --git a/consensus/ethash/consensus.go b/consensus/ethash/consensus.go index 4f92f1282b9e..4890286381d8 100644 --- a/consensus/ethash/consensus.go +++ b/consensus/ethash/consensus.go @@ -28,7 +28,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" + tracing "github.com/ethereum/go-ethereum/core/tracing/v2" "github.com/ethereum/go-ethereum/core/types" "github.com/ethereum/go-ethereum/core/vm" "github.com/ethereum/go-ethereum/params" diff --git a/consensus/misc/dao.go b/consensus/misc/dao.go index b80c1b833a47..83857ec68b48 100644 --- a/consensus/misc/dao.go +++ b/consensus/misc/dao.go @@ -21,7 +21,7 @@ import ( "errors" "math/big" - "github.com/ethereum/go-ethereum/core/tracing" + tracing "github.com/ethereum/go-ethereum/core/tracing/v2" "github.com/ethereum/go-ethereum/core/types" "github.com/ethereum/go-ethereum/core/vm" "github.com/ethereum/go-ethereum/params" diff --git a/core/blockchain.go b/core/blockchain.go index c361f755e014..ae1e6451401e 100644 --- a/core/blockchain.go +++ b/core/blockchain.go @@ -39,7 +39,7 @@ import ( "github.com/ethereum/go-ethereum/core/state" "github.com/ethereum/go-ethereum/core/state/snapshot" "github.com/ethereum/go-ethereum/core/stateless" - "github.com/ethereum/go-ethereum/core/tracing" + tracing "github.com/ethereum/go-ethereum/core/tracing/v2" "github.com/ethereum/go-ethereum/core/types" "github.com/ethereum/go-ethereum/core/vm" "github.com/ethereum/go-ethereum/ethdb" @@ -258,7 +258,7 @@ type BlockChain struct { prefetcher Prefetcher processor Processor // Block transaction processor interface vmConfig vm.Config - logger *tracing.HooksV2 + logger *tracing.Hooks } // NewBlockChain returns a fully initialised block chain using information diff --git a/core/evm.go b/core/evm.go index 5d3c454d7c47..b5ac9c88cdff 100644 --- a/core/evm.go +++ b/core/evm.go @@ -22,7 +22,7 @@ import ( "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/consensus" "github.com/ethereum/go-ethereum/consensus/misc/eip4844" - "github.com/ethereum/go-ethereum/core/tracing" + tracing "github.com/ethereum/go-ethereum/core/tracing/v2" "github.com/ethereum/go-ethereum/core/types" "github.com/ethereum/go-ethereum/core/vm" "github.com/holiman/uint256" diff --git a/core/genesis.go b/core/genesis.go index eff92084ebad..50a2cba60647 100644 --- a/core/genesis.go +++ b/core/genesis.go @@ -29,7 +29,7 @@ import ( "github.com/ethereum/go-ethereum/common/math" "github.com/ethereum/go-ethereum/core/rawdb" "github.com/ethereum/go-ethereum/core/state" - "github.com/ethereum/go-ethereum/core/tracing" + tracing "github.com/ethereum/go-ethereum/core/tracing/v2" "github.com/ethereum/go-ethereum/core/types" "github.com/ethereum/go-ethereum/crypto" "github.com/ethereum/go-ethereum/ethdb" diff --git a/core/state/statedb.go b/core/state/statedb.go index 0183c14480df..593b0d0f6487 100644 --- a/core/state/statedb.go +++ b/core/state/statedb.go @@ -30,7 +30,7 @@ import ( "github.com/ethereum/go-ethereum/core/rawdb" "github.com/ethereum/go-ethereum/core/state/snapshot" "github.com/ethereum/go-ethereum/core/stateless" - "github.com/ethereum/go-ethereum/core/tracing" + tracing "github.com/ethereum/go-ethereum/core/tracing/v2" "github.com/ethereum/go-ethereum/core/types" "github.com/ethereum/go-ethereum/crypto" "github.com/ethereum/go-ethereum/log" diff --git a/core/state/statedb_hooked.go b/core/state/statedb_hooked.go index 5cbb128d97b6..f880fa1e2387 100644 --- a/core/state/statedb_hooked.go +++ b/core/state/statedb_hooked.go @@ -21,7 +21,7 @@ import ( "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/core/stateless" - "github.com/ethereum/go-ethereum/core/tracing" + tracing "github.com/ethereum/go-ethereum/core/tracing/v2" "github.com/ethereum/go-ethereum/core/types" "github.com/ethereum/go-ethereum/crypto" "github.com/ethereum/go-ethereum/params" @@ -33,14 +33,14 @@ import ( // on state operations. type hookedStateDB struct { inner *StateDB - hooks *tracing.HooksV2 + hooks *tracing.Hooks } // NewHookedState wraps the given stateDb with the given hooks -func NewHookedState(stateDb *StateDB, hooks *tracing.HooksV2) *hookedStateDB { +func NewHookedState(stateDb *StateDB, hooks *tracing.Hooks) *hookedStateDB { s := &hookedStateDB{stateDb, hooks} if s.hooks == nil { - s.hooks = new(tracing.HooksV2) + s.hooks = new(tracing.Hooks) } return s } diff --git a/core/state_transition.go b/core/state_transition.go index 4bd3c00167fc..ef86ab442aa7 100644 --- a/core/state_transition.go +++ b/core/state_transition.go @@ -22,7 +22,7 @@ import ( "math/big" "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/core/tracing" + tracing "github.com/ethereum/go-ethereum/core/tracing/v2" "github.com/ethereum/go-ethereum/core/types" "github.com/ethereum/go-ethereum/core/vm" "github.com/ethereum/go-ethereum/crypto/kzg4844" diff --git a/core/tracing/hooks.go b/core/tracing/hooks.go index 2417f3749caa..e7c85ee85c0b 100644 --- a/core/tracing/hooks.go +++ b/core/tracing/hooks.go @@ -75,9 +75,6 @@ type ( // LiveConstructor is the constructor for a live tracer. LiveConstructor = func(config json.RawMessage) (*Hooks, error) - // LiveConstructorV2 is the v2 constructor for a live tracer. - LiveConstructorV2 = func(config json.RawMessage) (*HooksV2, error) - /* - VM events - */ @@ -157,10 +154,6 @@ type ( // will not be invoked. OnSystemCallStartHook = func() - // OnSystemCallStartHookV2 is called when a system call is about to be executed. Refer - // to docs for OnSystemCallStartHook. - OnSystemCallStartHookV2 = func(vm *VMContext) - // OnSystemCallEndHook is called when a system call has finished executing. Today, // this hook is invoked when the EIP-4788 system call is about to be executed to set the // beacon block root. @@ -184,27 +177,6 @@ type ( // LogHook is called when a log is emitted. LogHook = func(log *types.Log) - - // BalanceReadHook is called when EVM reads the balance of an account. - BalanceReadHook = func(addr common.Address, bal *big.Int) - - // NonceReadHook is called when EVM reads the nonce of an account. - NonceReadHook = func(addr common.Address, nonce uint64) - - // CodeReadHook is called when EVM reads the code of an account. - CodeReadHook = func(addr common.Address, code []byte) - - // CodeSizeReadHook is called when EVM reads the code size of an account. - CodeSizeReadHook = func(addr common.Address, size int) - - // CodeHashReadHook is called when EVM reads the code hash of an account. - CodeHashReadHook = func(addr common.Address, hash common.Hash) - - // StorageReadHook is called when EVM reads a storage slot of an account. - StorageReadHook = func(addr common.Address, slot, value common.Hash) - - // BlockHashReadHook is called when EVM reads the blockhash of a block. - BlockHashReadHook = func(blockNumber uint64, hash common.Hash) ) type Hooks struct { @@ -233,48 +205,9 @@ type Hooks struct { OnLog LogHook } -type HooksV2 struct { - // V1 hooks minus OnBlockchainInit which is removed. - // VM events - OnTxStart TxStartHook - OnTxEnd TxEndHook - OnEnter EnterHook - OnExit ExitHook - OnOpcode OpcodeHook - OnFault FaultHook - OnGasChange GasChangeHook - // Chain events - OnBlockchainInit BlockchainInitHook - OnClose CloseHook - OnBlockStart BlockStartHook - OnBlockEnd BlockEndHook - OnSkippedBlock SkippedBlockHook - OnGenesisBlock GenesisBlockHook - OnSystemCallEnd OnSystemCallEndHook - // State events - OnBalanceChange BalanceChangeHook - OnNonceChange NonceChangeHook - OnCodeChange CodeChangeHook - OnStorageChange StorageChangeHook - OnLog LogHook - - // V2 changes - OnReorg ReorgHook - OnSystemCallStart OnSystemCallStartHookV2 - // State reads - OnBalanceRead BalanceReadHook - OnNonceRead NonceReadHook - OnCodeRead CodeReadHook - OnCodeSizeRead CodeSizeReadHook - OnCodeHashRead CodeHashReadHook - OnStorageRead StorageReadHook - // Block hash read - OnBlockHashRead BlockHashReadHook -} - -// copyHooks creates a new instance of U with all implemented hooks copied from the original T, +// CopyHooks creates a new instance of U with all implemented hooks copied from the original T, // except for those specified in the exclude parameter. -func copyHooks[T, U any](h *T, exclude ...string) *U { +func CopyHooks[T, U any](h *T, exclude ...string) *U { copied := new(U) srcValue := reflect.ValueOf(h).Elem() dstValue := reflect.ValueOf(copied).Elem() @@ -303,20 +236,7 @@ func copyHooks[T, U any](h *T, exclude ...string) *U { // Copy creates a new Hooks instance with all implemented hooks copied from the original. func (h *Hooks) Copy() *Hooks { - return copyHooks[Hooks, Hooks](h) -} - -// Copy creates a new HooksV2 instance with all implemented hooks copied from the original. -func (h *HooksV2) Copy() *HooksV2 { - return copyHooks[HooksV2, HooksV2](h) -} - -// ToV2 converts a Hooks instance to a HooksV2 instance. -// -// Note that OnSystemCallStart hook is excluded from the copy as it is -// changed in a backwards-incompatible way. -func (h *Hooks) ToV2() *HooksV2 { - return copyHooks[Hooks, HooksV2](h, "OnSystemCallStart") + return CopyHooks[Hooks, Hooks](h) } // BalanceChangeReason is used to indicate the reason for a balance change, useful diff --git a/core/tracing/journal.go b/core/tracing/v2/journal.go similarity index 93% rename from core/tracing/journal.go rename to core/tracing/v2/journal.go index 11b3595b64c7..10584c1ba2d6 100644 --- a/core/tracing/journal.go +++ b/core/tracing/v2/journal.go @@ -14,7 +14,7 @@ // You should have received a copy of the GNU Lesser General Public License // along with the go-ethereum library. If not, see . -package tracing +package v2 import ( "fmt" @@ -34,7 +34,7 @@ type revision struct { // It will emit the state change hooks with reverse values when a call reverts. type journal struct { entries []entry - hooks *HooksV2 + hooks *Hooks validRevisions []revision nextRevisionId int @@ -42,11 +42,11 @@ type journal struct { } type entry interface { - revert(tracer *HooksV2) + revert(tracer *Hooks) } // WrapWithJournal wraps the given tracer with a journaling layer. -func WrapWithJournal(hooks *HooksV2) (*HooksV2, error) { +func WrapWithJournal(hooks *Hooks) (*Hooks, error) { if hooks == nil { return nil, fmt.Errorf("wrapping nil tracer") } @@ -98,7 +98,7 @@ func (j *journal) snapshot() int { } // revertToSnapshot reverts all state changes made since the given revision. -func (j *journal) revertToSnapshot(revid int, hooks *HooksV2) { +func (j *journal) revertToSnapshot(revid int, hooks *Hooks) { // Find the snapshot in the stack of valid snapshots. idx := sort.Search(len(j.validRevisions), func(i int) bool { return j.validRevisions[i].id >= revid @@ -114,7 +114,7 @@ func (j *journal) revertToSnapshot(revid int, hooks *HooksV2) { } // revert undoes a batch of journaled modifications. -func (j *journal) revert(hooks *HooksV2, snapshot int) { +func (j *journal) revert(hooks *Hooks, snapshot int) { for i := len(j.entries) - 1; i >= snapshot; i-- { // Undo the changes made by the operation j.entries[i].revert(hooks) @@ -215,25 +215,25 @@ type ( } ) -func (b balanceChange) revert(hooks *HooksV2) { +func (b balanceChange) revert(hooks *Hooks) { if hooks.OnBalanceChange != nil { hooks.OnBalanceChange(b.addr, b.new, b.prev, BalanceChangeRevert) } } -func (n nonceChange) revert(hooks *HooksV2) { +func (n nonceChange) revert(hooks *Hooks) { if hooks.OnNonceChange != nil { hooks.OnNonceChange(n.addr, n.new, n.prev) } } -func (c codeChange) revert(hooks *HooksV2) { +func (c codeChange) revert(hooks *Hooks) { if hooks.OnCodeChange != nil { hooks.OnCodeChange(c.addr, c.newCodeHash, c.newCode, c.prevCodeHash, c.prevCode) } } -func (s storageChange) revert(hooks *HooksV2) { +func (s storageChange) revert(hooks *Hooks) { if hooks.OnStorageChange != nil { hooks.OnStorageChange(s.addr, s.slot, s.new, s.prev) } diff --git a/core/tracing/journal_test.go b/core/tracing/v2/journal_test.go similarity index 94% rename from core/tracing/journal_test.go rename to core/tracing/v2/journal_test.go index ef01914a523b..01d8e6d3dd7b 100644 --- a/core/tracing/journal_test.go +++ b/core/tracing/v2/journal_test.go @@ -14,7 +14,7 @@ // You should have received a copy of the GNU Lesser General Public License // along with the go-ethereum library. If not, see . -package tracing +package v2 import ( "errors" @@ -57,7 +57,7 @@ func (t *testTracer) OnStorageChange(addr common.Address, slot common.Hash, prev func TestJournalIntegration(t *testing.T) { tr := &testTracer{} - wr, err := WrapWithJournal(&HooksV2{OnBalanceChange: tr.OnBalanceChange, OnNonceChange: tr.OnNonceChange, OnCodeChange: tr.OnCodeChange, OnStorageChange: tr.OnStorageChange}) + wr, err := WrapWithJournal(&Hooks{OnBalanceChange: tr.OnBalanceChange, OnNonceChange: tr.OnNonceChange, OnCodeChange: tr.OnCodeChange, OnStorageChange: tr.OnStorageChange}) if err != nil { t.Fatalf("failed to wrap test tracer: %v", err) } @@ -93,7 +93,7 @@ func TestJournalIntegration(t *testing.T) { func TestJournalTopRevert(t *testing.T) { tr := &testTracer{} - wr, err := WrapWithJournal(&HooksV2{OnBalanceChange: tr.OnBalanceChange, OnNonceChange: tr.OnNonceChange}) + wr, err := WrapWithJournal(&Hooks{OnBalanceChange: tr.OnBalanceChange, OnNonceChange: tr.OnNonceChange}) if err != nil { t.Fatalf("failed to wrap test tracer: %v", err) } @@ -116,7 +116,7 @@ func TestJournalTopRevert(t *testing.T) { func TestJournalNestedCalls(t *testing.T) { tr := &testTracer{} - wr, err := WrapWithJournal(&HooksV2{OnBalanceChange: tr.OnBalanceChange, OnNonceChange: tr.OnNonceChange}) + wr, err := WrapWithJournal(&Hooks{OnBalanceChange: tr.OnBalanceChange, OnNonceChange: tr.OnNonceChange}) if err != nil { t.Fatalf("failed to wrap test tracer: %v", err) } diff --git a/core/vm/contract.go b/core/vm/contract.go index f312e63a660c..f6ef95f1d3eb 100644 --- a/core/vm/contract.go +++ b/core/vm/contract.go @@ -18,7 +18,7 @@ package vm import ( "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/core/tracing" + tracing "github.com/ethereum/go-ethereum/core/tracing/v2" "github.com/holiman/uint256" ) @@ -161,7 +161,7 @@ func (c *Contract) Caller() common.Address { } // UseGas attempts the use gas and subtracts it and returns true on success -func (c *Contract) UseGas(gas uint64, logger *tracing.HooksV2, reason tracing.GasChangeReason) (ok bool) { +func (c *Contract) UseGas(gas uint64, logger *tracing.Hooks, reason tracing.GasChangeReason) (ok bool) { if c.Gas < gas { return false } @@ -173,7 +173,7 @@ func (c *Contract) UseGas(gas uint64, logger *tracing.HooksV2, reason tracing.Ga } // RefundGas refunds gas to the contract -func (c *Contract) RefundGas(gas uint64, logger *tracing.HooksV2, reason tracing.GasChangeReason) { +func (c *Contract) RefundGas(gas uint64, logger *tracing.Hooks, reason tracing.GasChangeReason) { if gas == 0 { return } diff --git a/core/vm/contracts.go b/core/vm/contracts.go index ec4e99570b65..623700c3a5d7 100644 --- a/core/vm/contracts.go +++ b/core/vm/contracts.go @@ -30,7 +30,7 @@ import ( "github.com/consensys/gnark-crypto/ecc/bls12-381/fp" "github.com/consensys/gnark-crypto/ecc/bls12-381/fr" "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/core/tracing" + tracing "github.com/ethereum/go-ethereum/core/tracing/v2" "github.com/ethereum/go-ethereum/crypto" "github.com/ethereum/go-ethereum/crypto/blake2b" "github.com/ethereum/go-ethereum/crypto/bn256" @@ -220,7 +220,7 @@ func ActivePrecompiles(rules params.Rules) []common.Address { // - the returned bytes, // - the _remaining_ gas, // - any error that occurred -func RunPrecompiledContract(p PrecompiledContract, input []byte, suppliedGas uint64, logger *tracing.HooksV2) (ret []byte, remainingGas uint64, err error) { +func RunPrecompiledContract(p PrecompiledContract, input []byte, suppliedGas uint64, logger *tracing.Hooks) (ret []byte, remainingGas uint64, err error) { gasCost := p.RequiredGas(input) if suppliedGas < gasCost { return nil, 0, ErrOutOfGas diff --git a/core/vm/eips.go b/core/vm/eips.go index 71d51f81efe0..e28cca7b0890 100644 --- a/core/vm/eips.go +++ b/core/vm/eips.go @@ -22,7 +22,7 @@ import ( "sort" "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/core/tracing" + tracing "github.com/ethereum/go-ethereum/core/tracing/v2" "github.com/ethereum/go-ethereum/params" "github.com/holiman/uint256" ) diff --git a/core/vm/evm.go b/core/vm/evm.go index 26ff495579f1..4eebd67a1b89 100644 --- a/core/vm/evm.go +++ b/core/vm/evm.go @@ -23,7 +23,7 @@ import ( "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/core/state" - "github.com/ethereum/go-ethereum/core/tracing" + tracing "github.com/ethereum/go-ethereum/core/tracing/v2" "github.com/ethereum/go-ethereum/core/types" "github.com/ethereum/go-ethereum/crypto" "github.com/ethereum/go-ethereum/params" diff --git a/core/vm/instructions.go b/core/vm/instructions.go index 540f0e508dae..b11f5228f065 100644 --- a/core/vm/instructions.go +++ b/core/vm/instructions.go @@ -20,7 +20,7 @@ import ( "math" "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/core/tracing" + tracing "github.com/ethereum/go-ethereum/core/tracing/v2" "github.com/ethereum/go-ethereum/core/types" "github.com/ethereum/go-ethereum/crypto" "github.com/ethereum/go-ethereum/params" diff --git a/core/vm/interface.go b/core/vm/interface.go index 9229f4d2cd95..fd3919b0c079 100644 --- a/core/vm/interface.go +++ b/core/vm/interface.go @@ -21,7 +21,7 @@ import ( "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/core/stateless" - "github.com/ethereum/go-ethereum/core/tracing" + tracing "github.com/ethereum/go-ethereum/core/tracing/v2" "github.com/ethereum/go-ethereum/core/types" "github.com/ethereum/go-ethereum/params" "github.com/ethereum/go-ethereum/trie/utils" diff --git a/core/vm/interpreter.go b/core/vm/interpreter.go index 257b518c3e35..7f62e1f3d745 100644 --- a/core/vm/interpreter.go +++ b/core/vm/interpreter.go @@ -21,7 +21,7 @@ import ( "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/common/math" - "github.com/ethereum/go-ethereum/core/tracing" + tracing "github.com/ethereum/go-ethereum/core/tracing/v2" "github.com/ethereum/go-ethereum/crypto" "github.com/ethereum/go-ethereum/log" "github.com/holiman/uint256" @@ -29,7 +29,7 @@ import ( // Config are the configuration options for the Interpreter type Config struct { - Tracer *tracing.HooksV2 + Tracer *tracing.Hooks NoBaseFee bool // Forces the EIP-1559 baseFee to 0 (needed for 0 price calls) EnablePreimageRecording bool // Enables recording of SHA3/keccak preimages ExtraEips []int // Additional EIPS that are to be enabled diff --git a/core/vm/operations_acl.go b/core/vm/operations_acl.go index b993b651ffbb..12885e88f448 100644 --- a/core/vm/operations_acl.go +++ b/core/vm/operations_acl.go @@ -21,7 +21,7 @@ import ( "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/common/math" - "github.com/ethereum/go-ethereum/core/tracing" + tracing "github.com/ethereum/go-ethereum/core/tracing/v2" "github.com/ethereum/go-ethereum/params" ) diff --git a/eth/backend.go b/eth/backend.go index f02690f97878..9e4f132225b5 100644 --- a/eth/backend.go +++ b/eth/backend.go @@ -32,6 +32,7 @@ import ( "github.com/ethereum/go-ethereum/core/bloombits" "github.com/ethereum/go-ethereum/core/rawdb" "github.com/ethereum/go-ethereum/core/state/pruner" + tracing "github.com/ethereum/go-ethereum/core/tracing/v2" "github.com/ethereum/go-ethereum/core/txpool" "github.com/ethereum/go-ethereum/core/txpool/blobpool" "github.com/ethereum/go-ethereum/core/txpool/legacypool" @@ -42,7 +43,6 @@ import ( "github.com/ethereum/go-ethereum/eth/gasprice" "github.com/ethereum/go-ethereum/eth/protocols/eth" "github.com/ethereum/go-ethereum/eth/protocols/snap" - "github.com/ethereum/go-ethereum/eth/tracers" "github.com/ethereum/go-ethereum/ethdb" "github.com/ethereum/go-ethereum/event" "github.com/ethereum/go-ethereum/internal/ethapi" @@ -203,7 +203,7 @@ func New(stack *node.Node, config *ethconfig.Config) (*Ethereum, error) { if config.VMTraceJsonConfig != "" { traceConfig = json.RawMessage(config.VMTraceJsonConfig) } - t, err := tracers.LiveDirectory.NewV2(config.VMTrace, traceConfig) + t, err := tracing.LiveDirectory.New(config.VMTrace, traceConfig) if err != nil { return nil, fmt.Errorf("failed to create tracer %s: %v", config.VMTrace, err) } diff --git a/eth/tracers/api.go b/eth/tracers/api.go index 3347dda07a58..7d8191c25bd6 100644 --- a/eth/tracers/api.go +++ b/eth/tracers/api.go @@ -1006,7 +1006,7 @@ func (api *API) traceTx(ctx context.Context, tx *types.Transaction, message *cor if config.Tracer == nil { logger := logger.NewStructLogger(config.Config) tracer = &Tracer{ - HooksV2: logger.Hooks(), + Hooks: logger.Hooks(), GetResult: logger.GetResult, Stop: logger.Stop, } @@ -1017,7 +1017,7 @@ func (api *API) traceTx(ctx context.Context, tx *types.Transaction, message *cor } } // The actual TxContext will be created as part of ApplyTransactionWithEVM. - vmenv := vm.NewEVM(vmctx, vm.TxContext{GasPrice: message.GasPrice, BlobFeeCap: message.BlobGasFeeCap}, statedb, api.backend.ChainConfig(), vm.Config{Tracer: tracer.Hooks(), NoBaseFee: true}) + vmenv := vm.NewEVM(vmctx, vm.TxContext{GasPrice: message.GasPrice, BlobFeeCap: message.BlobGasFeeCap}, statedb, api.backend.ChainConfig(), vm.Config{Tracer: tracer.Hooks, NoBaseFee: true}) // Define a meaningful timeout of a single transaction trace if config.Timeout != nil { diff --git a/eth/tracers/dir.go b/eth/tracers/dir.go index 5f219fb56b0f..342d449e73fc 100644 --- a/eth/tracers/dir.go +++ b/eth/tracers/dir.go @@ -21,7 +21,7 @@ import ( "math/big" "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/core/tracing" + tracing "github.com/ethereum/go-ethereum/core/tracing/v2" "github.com/ethereum/go-ethereum/params" ) @@ -39,17 +39,12 @@ type Context struct { // This involves a method to retrieve results and one to // stop tracing. type Tracer struct { - *tracing.HooksV2 + *tracing.Hooks GetResult func() (json.RawMessage, error) // Stop terminates execution of the tracer at the first opportune moment. Stop func(err error) } -// Hooks returns the hooks of the tracer. -func (t *Tracer) Hooks() *tracing.HooksV2 { - return t.HooksV2 -} - type ctorFn func(*Context, json.RawMessage, *params.ChainConfig) (*Tracer, error) type jsCtorFn func(string, *Context, json.RawMessage, *params.ChainConfig) (*Tracer, error) diff --git a/eth/tracers/js/goja.go b/eth/tracers/js/goja.go index d739735bc10c..e74b0c71b50a 100644 --- a/eth/tracers/js/goja.go +++ b/eth/tracers/js/goja.go @@ -25,7 +25,7 @@ import ( "sync" "github.com/dop251/goja" - "github.com/ethereum/go-ethereum/core/tracing" + tracing "github.com/ethereum/go-ethereum/core/tracing/v2" "github.com/ethereum/go-ethereum/core/types" "github.com/ethereum/go-ethereum/eth/tracers" "github.com/ethereum/go-ethereum/eth/tracers/internal" @@ -235,7 +235,7 @@ func newJsTracer(code string, ctx *tracers.Context, cfg json.RawMessage, chainCo t.logValue = t.log.setupObject() return &tracers.Tracer{ - HooksV2: &tracing.HooksV2{ + Hooks: &tracing.Hooks{ OnTxStart: t.OnTxStart, OnTxEnd: t.OnTxEnd, OnEnter: t.OnEnter, diff --git a/eth/tracers/live.go b/eth/tracers/live.go index c341b9ddb355..b796c2927a70 100644 --- a/eth/tracers/live.go +++ b/eth/tracers/live.go @@ -18,47 +18,42 @@ package tracers import ( "encoding/json" - "errors" + "math/big" + "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/core/tracing" + tracingV2 "github.com/ethereum/go-ethereum/core/tracing/v2" ) // LiveDirectory is the collection of tracers which can be used // during normal block import operations. -var LiveDirectory = liveDirectory{elems: make(map[string]tracing.LiveConstructorV2)} +// +// Deprecated: It is left for backwards-compatibility with v1 tracers. +var LiveDirectory = liveDirectory{} -type liveDirectory struct { - elems map[string]tracing.LiveConstructorV2 -} +type liveDirectory struct{} // Register registers a tracer constructor by name. func (d *liveDirectory) Register(name string, f tracing.LiveConstructor) { - d.elems[name] = wrapV1(f) + tracingV2.LiveDirectory.Register(name, wrapV1(f)) } -// RegisterV2 registers a tracer constructor by name. -func (d *liveDirectory) RegisterV2(name string, f tracing.LiveConstructorV2) { - d.elems[name] = f -} - -// NewV2 instantiates a tracer by name. -func (d *liveDirectory) NewV2(name string, config json.RawMessage) (*tracing.HooksV2, error) { - if f, ok := d.elems[name]; ok { - return f(config) - } - return nil, errors.New("not found") -} - -func wrapV1(ctor tracing.LiveConstructor) tracing.LiveConstructorV2 { - return func(config json.RawMessage) (*tracing.HooksV2, error) { +func wrapV1(ctor tracing.LiveConstructor) tracingV2.NewLiveTracer { + return func(config json.RawMessage) (*tracingV2.Hooks, error) { hooks, err := ctor(config) if err != nil { return nil, err } - v2 := hooks.ToV2() - v2.OnSystemCallStart = func(ctx *tracing.VMContext) { + v2 := tracingV2.ToV2(hooks) + v2.OnSystemCallStart = func(ctx *tracingV2.VMContext) { hooks.OnSystemCallStart() } + v2.OnBalanceChange = func(addr common.Address, prev, new *big.Int, reason tracingV2.BalanceChangeReason) { + hooks.OnBalanceChange(addr, prev, new, tracing.BalanceChangeReason(reason)) + } + v2.OnGasChange = func(prev, new uint64, reason tracingV2.GasChangeReason) { + hooks.OnGasChange(prev, new, tracing.GasChangeReason(reason)) + } return v2, nil } } diff --git a/eth/tracers/live/noopv2.go b/eth/tracers/live/noopv2.go index 2b5f72812b07..37300cc9c8a8 100644 --- a/eth/tracers/live/noopv2.go +++ b/eth/tracers/live/noopv2.go @@ -21,14 +21,13 @@ import ( "math/big" "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/core/tracing" + tracing "github.com/ethereum/go-ethereum/core/tracing/v2" "github.com/ethereum/go-ethereum/core/types" - "github.com/ethereum/go-ethereum/eth/tracers" "github.com/ethereum/go-ethereum/params" ) func init() { - tracers.LiveDirectory.RegisterV2("noopv2", newNoopV2Tracer) + tracing.LiveDirectory.Register("noopv2", newNoopV2Tracer) } // noopV2 is a no-op live tracer. It's there to @@ -37,9 +36,9 @@ func init() { // as soon as we have a real live tracer. type noopV2 struct{} -func newNoopV2Tracer(_ json.RawMessage) (*tracing.HooksV2, error) { +func newNoopV2Tracer(_ json.RawMessage) (*tracing.Hooks, error) { t := &noopV2{} - return &tracing.HooksV2{ + return &tracing.Hooks{ OnTxStart: t.OnTxStart, OnTxEnd: t.OnTxEnd, OnEnter: t.OnEnter, @@ -54,7 +53,6 @@ func newNoopV2Tracer(_ json.RawMessage) (*tracing.HooksV2, error) { OnGenesisBlock: t.OnGenesisBlock, OnSystemCallStart: t.OnSystemCallStart, OnSystemCallEnd: t.OnSystemCallEnd, - OnReorg: t.OnReorg, OnBalanceChange: t.OnBalanceChange, OnNonceChange: t.OnNonceChange, OnCodeChange: t.OnCodeChange, diff --git a/eth/tracers/live/supply.go b/eth/tracers/live/supply.go index 1b4f4bf42d27..5f7853f5c6d9 100644 --- a/eth/tracers/live/supply.go +++ b/eth/tracers/live/supply.go @@ -26,16 +26,15 @@ import ( "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/common/hexutil" "github.com/ethereum/go-ethereum/consensus/misc/eip4844" - "github.com/ethereum/go-ethereum/core/tracing" + tracing "github.com/ethereum/go-ethereum/core/tracing/v2" "github.com/ethereum/go-ethereum/core/types" "github.com/ethereum/go-ethereum/core/vm" - "github.com/ethereum/go-ethereum/eth/tracers" "github.com/ethereum/go-ethereum/log" "gopkg.in/natefinch/lumberjack.v2" ) func init() { - tracers.LiveDirectory.RegisterV2("supply", newSupplyTracer) + tracing.LiveDirectory.Register("supply", newSupplyTracer) } type supplyInfoIssuance struct { @@ -90,7 +89,7 @@ type supplyTracerConfig struct { 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 newSupplyTracer(cfg json.RawMessage) (*tracing.HooksV2, error) { +func newSupplyTracer(cfg json.RawMessage) (*tracing.Hooks, error) { var config supplyTracerConfig if err := json.Unmarshal(cfg, &config); err != nil { return nil, fmt.Errorf("failed to parse config: %v", err) @@ -111,7 +110,7 @@ func newSupplyTracer(cfg json.RawMessage) (*tracing.HooksV2, error) { delta: newSupplyInfo(), logger: logger, } - return &tracing.HooksV2{ + return &tracing.Hooks{ OnBlockStart: t.onBlockStart, OnBlockEnd: t.onBlockEnd, OnGenesisBlock: t.onGenesisBlock, diff --git a/eth/tracers/logger/access_list_tracer.go b/eth/tracers/logger/access_list_tracer.go index 76144ac15297..55cdc5ee9ced 100644 --- a/eth/tracers/logger/access_list_tracer.go +++ b/eth/tracers/logger/access_list_tracer.go @@ -20,7 +20,7 @@ import ( "maps" "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/core/tracing" + tracing "github.com/ethereum/go-ethereum/core/tracing/v2" "github.com/ethereum/go-ethereum/core/types" "github.com/ethereum/go-ethereum/core/vm" ) @@ -125,8 +125,8 @@ func NewAccessListTracer(acl types.AccessList, from, to common.Address, precompi } } -func (a *AccessListTracer) Hooks() *tracing.HooksV2 { - return &tracing.HooksV2{ +func (a *AccessListTracer) Hooks() *tracing.Hooks { + return &tracing.Hooks{ OnOpcode: a.OnOpcode, } } diff --git a/eth/tracers/logger/logger.go b/eth/tracers/logger/logger.go index d0a6a617719a..0c4e025b9110 100644 --- a/eth/tracers/logger/logger.go +++ b/eth/tracers/logger/logger.go @@ -28,7 +28,7 @@ import ( "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/common/hexutil" "github.com/ethereum/go-ethereum/common/math" - "github.com/ethereum/go-ethereum/core/tracing" + tracing "github.com/ethereum/go-ethereum/core/tracing/v2" "github.com/ethereum/go-ethereum/core/types" "github.com/ethereum/go-ethereum/core/vm" "github.com/ethereum/go-ethereum/params" @@ -132,8 +132,8 @@ func NewStructLogger(cfg *Config) *StructLogger { return logger } -func (l *StructLogger) Hooks() *tracing.HooksV2 { - return &tracing.HooksV2{ +func (l *StructLogger) Hooks() *tracing.Hooks { + return &tracing.Hooks{ OnTxStart: l.OnTxStart, OnTxEnd: l.OnTxEnd, OnExit: l.OnExit, @@ -345,8 +345,8 @@ func NewMarkdownLogger(cfg *Config, writer io.Writer) *mdLogger { return l } -func (t *mdLogger) Hooks() *tracing.HooksV2 { - return &tracing.HooksV2{ +func (t *mdLogger) Hooks() *tracing.Hooks { + return &tracing.Hooks{ OnTxStart: t.OnTxStart, OnEnter: t.OnEnter, OnExit: t.OnExit, diff --git a/eth/tracers/logger/logger_json.go b/eth/tracers/logger/logger_json.go index 158ac1dbb727..4a1f3b37bdf4 100644 --- a/eth/tracers/logger/logger_json.go +++ b/eth/tracers/logger/logger_json.go @@ -24,7 +24,7 @@ import ( "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/common/hexutil" "github.com/ethereum/go-ethereum/common/math" - "github.com/ethereum/go-ethereum/core/tracing" + tracing "github.com/ethereum/go-ethereum/core/tracing/v2" "github.com/ethereum/go-ethereum/core/types" "github.com/ethereum/go-ethereum/core/vm" ) @@ -58,17 +58,17 @@ type jsonLogger struct { encoder *json.Encoder cfg *Config env *tracing.VMContext - hooks *tracing.HooksV2 + hooks *tracing.Hooks } // NewJSONLogger creates a new EVM tracer that prints execution steps as JSON objects // into the provided stream. -func NewJSONLogger(cfg *Config, writer io.Writer) *tracing.HooksV2 { +func NewJSONLogger(cfg *Config, writer io.Writer) *tracing.Hooks { l := &jsonLogger{encoder: json.NewEncoder(writer), cfg: cfg} if l.cfg == nil { l.cfg = &Config{} } - l.hooks = &tracing.HooksV2{ + l.hooks = &tracing.Hooks{ OnTxStart: l.OnTxStart, OnSystemCallStart: l.onSystemCallStart, OnExit: l.OnEnd, @@ -80,12 +80,12 @@ func NewJSONLogger(cfg *Config, writer io.Writer) *tracing.HooksV2 { // NewJSONLoggerWithCallFrames creates a new EVM tracer that prints execution steps as JSON objects // into the provided stream. It also includes call frames in the output. -func NewJSONLoggerWithCallFrames(cfg *Config, writer io.Writer) *tracing.HooksV2 { +func NewJSONLoggerWithCallFrames(cfg *Config, writer io.Writer) *tracing.Hooks { l := &jsonLogger{encoder: json.NewEncoder(writer), cfg: cfg} if l.cfg == nil { l.cfg = &Config{} } - l.hooks = &tracing.HooksV2{ + l.hooks = &tracing.Hooks{ OnTxStart: l.OnTxStart, OnSystemCallStart: l.onSystemCallStart, OnEnter: l.OnEnter, @@ -130,7 +130,7 @@ func (l *jsonLogger) OnOpcode(pc uint64, op byte, gas, cost uint64, scope tracin func (l *jsonLogger) onSystemCallStart(ctx *tracing.VMContext) { // Process no events while in system call. hooks := *l.hooks - *l.hooks = tracing.HooksV2{ + *l.hooks = tracing.Hooks{ OnSystemCallEnd: func() { *l.hooks = hooks }, diff --git a/eth/tracers/native/4byte.go b/eth/tracers/native/4byte.go index eaecf35495f6..3e65c82ffc19 100644 --- a/eth/tracers/native/4byte.go +++ b/eth/tracers/native/4byte.go @@ -23,7 +23,7 @@ import ( "sync/atomic" "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/core/tracing" + tracing "github.com/ethereum/go-ethereum/core/tracing/v2" "github.com/ethereum/go-ethereum/core/types" "github.com/ethereum/go-ethereum/core/vm" "github.com/ethereum/go-ethereum/eth/tracers" @@ -64,7 +64,7 @@ func newFourByteTracer(ctx *tracers.Context, cfg json.RawMessage, chainConfig *p chainConfig: chainConfig, } return &tracers.Tracer{ - HooksV2: &tracing.HooksV2{ + Hooks: &tracing.Hooks{ OnTxStart: t.OnTxStart, OnEnter: t.OnEnter, }, diff --git a/eth/tracers/native/call.go b/eth/tracers/native/call.go index 5e5d83798ed2..cc93e79904d3 100644 --- a/eth/tracers/native/call.go +++ b/eth/tracers/native/call.go @@ -25,7 +25,7 @@ import ( "github.com/ethereum/go-ethereum/accounts/abi" "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/common/hexutil" - "github.com/ethereum/go-ethereum/core/tracing" + tracing "github.com/ethereum/go-ethereum/core/tracing/v2" "github.com/ethereum/go-ethereum/core/types" "github.com/ethereum/go-ethereum/core/vm" "github.com/ethereum/go-ethereum/eth/tracers" @@ -132,7 +132,7 @@ func newCallTracer(ctx *tracers.Context, cfg json.RawMessage, chainConfig *param return nil, err } return &tracers.Tracer{ - HooksV2: &tracing.HooksV2{ + Hooks: &tracing.Hooks{ OnTxStart: t.OnTxStart, OnTxEnd: t.OnTxEnd, OnEnter: t.OnEnter, diff --git a/eth/tracers/native/call_flat.go b/eth/tracers/native/call_flat.go index 05086e70f76f..4be4ba49df05 100644 --- a/eth/tracers/native/call_flat.go +++ b/eth/tracers/native/call_flat.go @@ -27,7 +27,7 @@ import ( "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/common/hexutil" - "github.com/ethereum/go-ethereum/core/tracing" + tracing "github.com/ethereum/go-ethereum/core/tracing/v2" "github.com/ethereum/go-ethereum/core/types" "github.com/ethereum/go-ethereum/core/vm" "github.com/ethereum/go-ethereum/eth/tracers" @@ -142,7 +142,7 @@ func newFlatCallTracer(ctx *tracers.Context, cfg json.RawMessage, chainConfig *p ft := &flatCallTracer{tracer: t, ctx: ctx, config: config, chainConfig: chainConfig} return &tracers.Tracer{ - HooksV2: &tracing.HooksV2{ + Hooks: &tracing.Hooks{ OnTxStart: ft.OnTxStart, OnTxEnd: ft.OnTxEnd, OnEnter: ft.OnEnter, diff --git a/eth/tracers/native/mux.go b/eth/tracers/native/mux.go index 0be7db5197b8..dd76c274f863 100644 --- a/eth/tracers/native/mux.go +++ b/eth/tracers/native/mux.go @@ -21,7 +21,7 @@ import ( "math/big" "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/core/tracing" + tracing "github.com/ethereum/go-ethereum/core/tracing/v2" "github.com/ethereum/go-ethereum/core/types" "github.com/ethereum/go-ethereum/eth/tracers" "github.com/ethereum/go-ethereum/params" @@ -57,7 +57,7 @@ func newMuxTracer(ctx *tracers.Context, cfg json.RawMessage, chainConfig *params t := &muxTracer{names: names, tracers: objects} return &tracers.Tracer{ - HooksV2: &tracing.HooksV2{ + Hooks: &tracing.Hooks{ OnTxStart: t.OnTxStart, OnTxEnd: t.OnTxEnd, OnEnter: t.OnEnter, diff --git a/eth/tracers/native/noop.go b/eth/tracers/native/noop.go index a44fa563e329..5770f19fba53 100644 --- a/eth/tracers/native/noop.go +++ b/eth/tracers/native/noop.go @@ -21,7 +21,7 @@ import ( "math/big" "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/core/tracing" + tracing "github.com/ethereum/go-ethereum/core/tracing/v2" "github.com/ethereum/go-ethereum/core/types" "github.com/ethereum/go-ethereum/eth/tracers" "github.com/ethereum/go-ethereum/params" @@ -39,7 +39,7 @@ type noopTracer struct{} func newNoopTracer(ctx *tracers.Context, cfg json.RawMessage, chainConfig *params.ChainConfig) (*tracers.Tracer, error) { t := &noopTracer{} return &tracers.Tracer{ - HooksV2: &tracing.HooksV2{ + Hooks: &tracing.Hooks{ OnTxStart: t.OnTxStart, OnTxEnd: t.OnTxEnd, OnEnter: t.OnEnter, diff --git a/eth/tracers/native/prestate.go b/eth/tracers/native/prestate.go index 4bd86da9e8e1..899d5cda8552 100644 --- a/eth/tracers/native/prestate.go +++ b/eth/tracers/native/prestate.go @@ -24,7 +24,7 @@ import ( "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/common/hexutil" - "github.com/ethereum/go-ethereum/core/tracing" + tracing "github.com/ethereum/go-ethereum/core/tracing/v2" "github.com/ethereum/go-ethereum/core/types" "github.com/ethereum/go-ethereum/core/vm" "github.com/ethereum/go-ethereum/crypto" @@ -88,7 +88,7 @@ func newPrestateTracer(ctx *tracers.Context, cfg json.RawMessage, chainConfig *p deleted: make(map[common.Address]bool), } return &tracers.Tracer{ - HooksV2: &tracing.HooksV2{ + Hooks: &tracing.Hooks{ OnTxStart: t.OnTxStart, OnTxEnd: t.OnTxEnd, OnOpcode: t.OnOpcode, diff --git a/internal/ethapi/api.go b/internal/ethapi/api.go index 10d79c85ae06..8be8b110a3ef 100644 --- a/internal/ethapi/api.go +++ b/internal/ethapi/api.go @@ -38,7 +38,7 @@ import ( "github.com/ethereum/go-ethereum/consensus/misc/eip1559" "github.com/ethereum/go-ethereum/core" "github.com/ethereum/go-ethereum/core/state" - "github.com/ethereum/go-ethereum/core/tracing" + tracing "github.com/ethereum/go-ethereum/core/tracing/v2" "github.com/ethereum/go-ethereum/core/types" "github.com/ethereum/go-ethereum/core/vm" "github.com/ethereum/go-ethereum/crypto" diff --git a/internal/ethapi/logtracer.go b/internal/ethapi/logtracer.go index be25f92a59a0..565b6b0b59bf 100644 --- a/internal/ethapi/logtracer.go +++ b/internal/ethapi/logtracer.go @@ -20,7 +20,7 @@ import ( "math/big" "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/core/tracing" + tracing "github.com/ethereum/go-ethereum/core/tracing/v2" "github.com/ethereum/go-ethereum/core/types" "github.com/ethereum/go-ethereum/core/vm" ) @@ -68,8 +68,8 @@ func newTracer(traceTransfers bool, blockNumber uint64, blockHash, txHash common } } -func (t *tracer) Hooks() *tracing.HooksV2 { - return &tracing.HooksV2{ +func (t *tracer) Hooks() *tracing.Hooks { + return &tracing.Hooks{ OnEnter: t.onEnter, OnExit: t.onExit, OnLog: t.onLog, diff --git a/tests/block_test_util.go b/tests/block_test_util.go index 7f9cb1ecced4..4c53bb84b9ec 100644 --- a/tests/block_test_util.go +++ b/tests/block_test_util.go @@ -35,7 +35,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" + tracing "github.com/ethereum/go-ethereum/core/tracing/v2" "github.com/ethereum/go-ethereum/core/types" "github.com/ethereum/go-ethereum/core/vm" "github.com/ethereum/go-ethereum/log" @@ -111,7 +111,7 @@ type btHeaderMarshaling struct { ExcessBlobGas *math.HexOrDecimal64 } -func (t *BlockTest) Run(snapshotter bool, scheme string, witness bool, tracer *tracing.HooksV2, postCheck func(error, *core.BlockChain)) (result error) { +func (t *BlockTest) Run(snapshotter bool, scheme string, witness bool, tracer *tracing.Hooks, postCheck func(error, *core.BlockChain)) (result error) { config, ok := Forks[t.json.Network] if !ok { return UnsupportedForkError{t.json.Network} From 20f300e22aab9f571ec60cb0cadab1339f0469de Mon Sep 17 00:00:00 2001 From: Sina Mahmoodi Date: Fri, 25 Oct 2024 15:58:55 +0200 Subject: [PATCH 4/5] forgot v2/hooks file --- core/tracing/v2/hooks.go | 250 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 250 insertions(+) create mode 100644 core/tracing/v2/hooks.go diff --git a/core/tracing/v2/hooks.go b/core/tracing/v2/hooks.go new file mode 100644 index 000000000000..631abea2605f --- /dev/null +++ b/core/tracing/v2/hooks.go @@ -0,0 +1,250 @@ +package v2 + +import ( + "encoding/json" + "errors" + "math/big" + + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/core/tracing" +) + +// Type aliases so tracers don't have to import both versions. +type ( + VMContext = tracing.VMContext + OpContext = tracing.OpContext + BlockEvent = tracing.BlockEvent + StateDB = tracing.StateDB +) + +type ( + // NewLiveTracer is the v2 constructor for a live tracer. + NewLiveTracer = func(config json.RawMessage) (*Hooks, error) + + // BalanceChangeHook is called when the balance of an account changes. + BalanceChangeHook = func(addr common.Address, prev, new *big.Int, reason BalanceChangeReason) + + // GasChangeHook is invoked when the gas changes. + GasChangeHook = func(old, new uint64, reason GasChangeReason) + + // OnSystemCallStartHookV2 is called when a system call is about to be executed. Refer + // to docs for OnSystemCallStartHook. + OnSystemCallStartHookV2 = func(vm *tracing.VMContext) + + // BalanceReadHook is called when EVM reads the balance of an account. + BalanceReadHook = func(addr common.Address, bal *big.Int) + + // NonceReadHook is called when EVM reads the nonce of an account. + NonceReadHook = func(addr common.Address, nonce uint64) + + // CodeReadHook is called when EVM reads the code of an account. + CodeReadHook = func(addr common.Address, code []byte) + + // CodeSizeReadHook is called when EVM reads the code size of an account. + CodeSizeReadHook = func(addr common.Address, size int) + + // CodeHashReadHook is called when EVM reads the code hash of an account. + CodeHashReadHook = func(addr common.Address, hash common.Hash) + + // StorageReadHook is called when EVM reads a storage slot of an account. + StorageReadHook = func(addr common.Address, slot, value common.Hash) + + // BlockHashReadHook is called when EVM reads the blockhash of a block. + BlockHashReadHook = func(blockNumber uint64, hash common.Hash) +) + +type Hooks struct { + // V1 hooks minus OnBlockchainInit which is removed. + // VM events + OnTxStart tracing.TxStartHook + OnTxEnd tracing.TxEndHook + OnEnter tracing.EnterHook + OnExit tracing.ExitHook + OnOpcode tracing.OpcodeHook + OnFault tracing.FaultHook + // Chain events + OnBlockchainInit tracing.BlockchainInitHook + OnClose tracing.CloseHook + OnBlockStart tracing.BlockStartHook + OnBlockEnd tracing.BlockEndHook + OnSkippedBlock tracing.SkippedBlockHook + OnGenesisBlock tracing.GenesisBlockHook + OnSystemCallEnd tracing.OnSystemCallEndHook + // State events + OnNonceChange tracing.NonceChangeHook + OnCodeChange tracing.CodeChangeHook + OnStorageChange tracing.StorageChangeHook + OnLog tracing.LogHook + + OnBalanceChange BalanceChangeHook + OnGasChange GasChangeHook + + // V2 changes + OnSystemCallStart OnSystemCallStartHookV2 + // State reads + OnBalanceRead BalanceReadHook + OnNonceRead NonceReadHook + OnCodeRead CodeReadHook + OnCodeSizeRead CodeSizeReadHook + OnCodeHashRead CodeHashReadHook + OnStorageRead StorageReadHook + // Block hash read + OnBlockHashRead BlockHashReadHook +} + +// Copy creates a new Hooks instance with all implemented hooks copied from the original. +func (h *Hooks) Copy() *Hooks { + return tracing.CopyHooks[Hooks, Hooks](h) +} + +// ToV2 converts a Hooks instance to a Hooks instance. +// +// Note that OnSystemCallStart hook is excluded from the copy as it is +// changed in a backwards-incompatible way. +func ToV2(h *tracing.Hooks) *Hooks { + return tracing.CopyHooks[tracing.Hooks, Hooks](h, "OnSystemCallStart", "OnBalanceChange", "OnGasChange") +} + +// LiveDirectory is the collection of tracers which can be used +// during normal block import operations. +var LiveDirectory = liveDirectory{elems: make(map[string]NewLiveTracer)} + +type liveDirectory struct { + elems map[string]NewLiveTracer +} + +// RegisterV2 registers a tracer constructor by name. +func (d *liveDirectory) Register(name string, f NewLiveTracer) { + d.elems[name] = f +} + +// New instantiates a tracer by name. +func (d *liveDirectory) New(name string, config json.RawMessage) (*Hooks, error) { + if f, ok := d.elems[name]; ok { + return f(config) + } + return nil, errors.New("not found") +} + +// BalanceChangeReason is used to indicate the reason for a balance change, useful +// for tracing and reporting. +type BalanceChangeReason byte + +//go:generate go run golang.org/x/tools/cmd/stringer -type=BalanceChangeReason -output gen_balance_change_reason_stringer.go + +const ( + BalanceChangeUnspecified BalanceChangeReason = 0 + + // Issuance + // BalanceIncreaseRewardMineUncle is a reward for mining an uncle block. + BalanceIncreaseRewardMineUncle BalanceChangeReason = 1 + // BalanceIncreaseRewardMineBlock is a reward for mining a block. + BalanceIncreaseRewardMineBlock BalanceChangeReason = 2 + // BalanceIncreaseWithdrawal is ether withdrawn from the beacon chain. + BalanceIncreaseWithdrawal BalanceChangeReason = 3 + // BalanceIncreaseGenesisBalance is ether allocated at the genesis block. + BalanceIncreaseGenesisBalance BalanceChangeReason = 4 + + // Transaction fees + // BalanceIncreaseRewardTransactionFee is the transaction tip increasing block builder's balance. + BalanceIncreaseRewardTransactionFee BalanceChangeReason = 5 + // BalanceDecreaseGasBuy is spent to purchase gas for execution a transaction. + // Part of this gas will be burnt as per EIP-1559 rules. + BalanceDecreaseGasBuy BalanceChangeReason = 6 + // BalanceIncreaseGasReturn is ether returned for unused gas at the end of execution. + BalanceIncreaseGasReturn BalanceChangeReason = 7 + + // DAO fork + // BalanceIncreaseDaoContract is ether sent to the DAO refund contract. + BalanceIncreaseDaoContract BalanceChangeReason = 8 + // BalanceDecreaseDaoAccount is ether taken from a DAO account to be moved to the refund contract. + BalanceDecreaseDaoAccount BalanceChangeReason = 9 + + // BalanceChangeTransfer is ether transferred via a call. + // it is a decrease for the sender and an increase for the recipient. + BalanceChangeTransfer BalanceChangeReason = 10 + // BalanceChangeTouchAccount is a transfer of zero value. It is only there to + // touch-create an account. + BalanceChangeTouchAccount BalanceChangeReason = 11 + + // BalanceIncreaseSelfdestruct is added to the recipient as indicated by a selfdestructing account. + BalanceIncreaseSelfdestruct BalanceChangeReason = 12 + // BalanceDecreaseSelfdestruct is deducted from a contract due to self-destruct. + BalanceDecreaseSelfdestruct BalanceChangeReason = 13 + // BalanceDecreaseSelfdestructBurn is ether that is sent to an already self-destructed + // account within the same tx (captured at end of tx). + // Note it doesn't account for a self-destruct which appoints itself as recipient. + BalanceDecreaseSelfdestructBurn BalanceChangeReason = 14 + + // BalanceChangeRevert is emitted when the balance is reverted back to a previous value due to call failure. + // It is only emitted when the tracer has opted in to use the journaling wrapper. + BalanceChangeRevert BalanceChangeReason = 15 +) + +// GasChangeReason is used to indicate the reason for a gas change, useful +// for tracing and reporting. +// +// There is essentially two types of gas changes, those that can be emitted once per transaction +// and those that can be emitted on a call basis, so possibly multiple times per transaction. +// +// They can be recognized easily by their name, those that start with `GasChangeTx` are emitted +// once per transaction, while those that start with `GasChangeCall` are emitted on a call basis. +type GasChangeReason byte + +const ( + GasChangeUnspecified GasChangeReason = 0 + + // GasChangeTxInitialBalance is the initial balance for the call which will be equal to the gasLimit of the call. There is only + // one such gas change per transaction. + GasChangeTxInitialBalance GasChangeReason = 1 + // GasChangeTxIntrinsicGas is the amount of gas that will be charged for the intrinsic cost of the transaction, there is + // always exactly one of those per transaction. + GasChangeTxIntrinsicGas GasChangeReason = 2 + // GasChangeTxRefunds is the sum of all refunds which happened during the tx execution (e.g. storage slot being cleared) + // this generates an increase in gas. There is at most one of such gas change per transaction. + GasChangeTxRefunds GasChangeReason = 3 + // GasChangeTxLeftOverReturned is the amount of gas left over at the end of transaction's execution that will be returned + // to the chain. This change will always be a negative change as we "drain" left over gas towards 0. If there was no gas + // left at the end of execution, no such even will be emitted. The returned gas's value in Wei is returned to caller. + // There is at most one of such gas change per transaction. + GasChangeTxLeftOverReturned GasChangeReason = 4 + + // GasChangeCallInitialBalance is the initial balance for the call which will be equal to the gasLimit of the call. There is only + // one such gas change per call. + GasChangeCallInitialBalance GasChangeReason = 5 + // GasChangeCallLeftOverReturned is the amount of gas left over that will be returned to the caller, this change will always + // be a negative change as we "drain" left over gas towards 0. If there was no gas left at the end of execution, no such even + // will be emitted. + GasChangeCallLeftOverReturned GasChangeReason = 6 + // GasChangeCallLeftOverRefunded is the amount of gas that will be refunded to the call after the child call execution it + // executed completed. This value is always positive as we are giving gas back to the you, the left over gas of the child. + // If there was no gas left to be refunded, no such even will be emitted. + GasChangeCallLeftOverRefunded GasChangeReason = 7 + // GasChangeCallContractCreation is the amount of gas that will be burned for a CREATE. + GasChangeCallContractCreation GasChangeReason = 8 + // GasChangeContractCreation is the amount of gas that will be burned for a CREATE2. + GasChangeCallContractCreation2 GasChangeReason = 9 + // GasChangeCallCodeStorage is the amount of gas that will be charged for code storage. + GasChangeCallCodeStorage GasChangeReason = 10 + // GasChangeCallOpCode is the amount of gas that will be charged for an opcode executed by the EVM, exact opcode that was + // performed can be check by `OnOpcode` handling. + GasChangeCallOpCode GasChangeReason = 11 + // GasChangeCallPrecompiledContract is the amount of gas that will be charged for a precompiled contract execution. + GasChangeCallPrecompiledContract GasChangeReason = 12 + // GasChangeCallStorageColdAccess is the amount of gas that will be charged for a cold storage access as controlled by EIP2929 rules. + GasChangeCallStorageColdAccess GasChangeReason = 13 + // GasChangeCallFailedExecution is the burning of the remaining gas when the execution failed without a revert. + GasChangeCallFailedExecution GasChangeReason = 14 + // GasChangeWitnessContractInit flags the event of adding to the witness during the contract creation initialization step. + GasChangeWitnessContractInit GasChangeReason = 15 + // GasChangeWitnessContractCreation flags the event of adding to the witness during the contract creation finalization step. + GasChangeWitnessContractCreation GasChangeReason = 16 + // GasChangeWitnessCodeChunk flags the event of adding one or more contract code chunks to the witness. + GasChangeWitnessCodeChunk GasChangeReason = 17 + // GasChangeWitnessContractCollisionCheck flags the event of adding to the witness when checking for contract address collision. + GasChangeWitnessContractCollisionCheck GasChangeReason = 18 + + // GasChangeIgnored is a special value that can be used to indicate that the gas change should be ignored as + // it will be "manually" tracked by a direct emit of the gas change event. + GasChangeIgnored GasChangeReason = 0xFF +) From f6d764dd14ca262452243352bb0b4f9f529d0317 Mon Sep 17 00:00:00 2001 From: Sina Mahmoodi Date: Mon, 28 Oct 2024 08:04:04 +0100 Subject: [PATCH 5/5] add comments --- core/tracing/hooks.go | 3 +++ core/tracing/v2/hooks.go | 24 ++++++++++++++++++------ 2 files changed, 21 insertions(+), 6 deletions(-) diff --git a/core/tracing/hooks.go b/core/tracing/hooks.go index e7c85ee85c0b..f3a250f614f0 100644 --- a/core/tracing/hooks.go +++ b/core/tracing/hooks.go @@ -179,6 +179,9 @@ type ( LogHook = func(log *types.Log) ) +// Hooks is a collection of hooks in EVM execution, blockchain, and state logic. +// It is used by live tracers which run parallel to the node's execution, as well +// as the debug tracing API. type Hooks struct { // VM events OnTxStart TxStartHook diff --git a/core/tracing/v2/hooks.go b/core/tracing/v2/hooks.go index 631abea2605f..4f2a7db03e4e 100644 --- a/core/tracing/v2/hooks.go +++ b/core/tracing/v2/hooks.go @@ -11,10 +11,19 @@ import ( // Type aliases so tracers don't have to import both versions. type ( - VMContext = tracing.VMContext - OpContext = tracing.OpContext + // VMContext provides the context for the EVM execution. + VMContext = tracing.VMContext + + // OpContext provides the context at which the opcode is being + // executed in, including the memory, stack and various contract-level information. + OpContext = tracing.OpContext + + // BlockEvent is emitted upon tracing an incoming block. + // It contains the block as well as consensus related information. BlockEvent = tracing.BlockEvent - StateDB = tracing.StateDB + + // StateDB gives tracers access to the whole state. + StateDB = tracing.StateDB ) type ( @@ -27,9 +36,9 @@ type ( // GasChangeHook is invoked when the gas changes. GasChangeHook = func(old, new uint64, reason GasChangeReason) - // OnSystemCallStartHookV2 is called when a system call is about to be executed. Refer + // OnSystemCallStartHook is called when a system call is about to be executed. Refer // to docs for OnSystemCallStartHook. - OnSystemCallStartHookV2 = func(vm *tracing.VMContext) + OnSystemCallStartHook = func(vm *tracing.VMContext) // BalanceReadHook is called when EVM reads the balance of an account. BalanceReadHook = func(addr common.Address, bal *big.Int) @@ -53,6 +62,9 @@ type ( BlockHashReadHook = func(blockNumber uint64, hash common.Hash) ) +// Hooks is a collection of hooks in EVM execution, blockchain, and state logic. +// It is used by live tracers which run parallel to the node's execution, as well +// as the debug tracing API. type Hooks struct { // V1 hooks minus OnBlockchainInit which is removed. // VM events @@ -80,7 +92,7 @@ type Hooks struct { OnGasChange GasChangeHook // V2 changes - OnSystemCallStart OnSystemCallStartHookV2 + OnSystemCallStart OnSystemCallStartHook // State reads OnBalanceRead BalanceReadHook OnNonceRead NonceReadHook