From af34c01b90cbd1951f4b2eb8aea7930712feb20d Mon Sep 17 00:00:00 2001 From: Gary Rong Date: Tue, 30 Sep 2025 11:51:38 +0800 Subject: [PATCH] core/tracing: reshape the comments in core/tracing --- core/tracing/hooks.go | 191 ++++++++++++++++++++++++++-------------- core/tracing/journal.go | 30 +++++-- 2 files changed, 151 insertions(+), 70 deletions(-) diff --git a/core/tracing/hooks.go b/core/tracing/hooks.go index 4abb231c1e..3078d607e5 100644 --- a/core/tracing/hooks.go +++ b/core/tracing/hooks.go @@ -127,7 +127,6 @@ type ( CloseHook = func() // BlockStartHook is called before executing `block`. - // `td` is the total difficulty prior to `block`. BlockStartHook = func(event BlockEvent) // BlockEndHook is called after executing a block. @@ -141,24 +140,25 @@ type ( // GenesisBlockHook is called when the genesis block is being processed. GenesisBlockHook = func(genesis *types.Block, alloc types.GenesisAlloc) - // OnSystemCallStartHook is called when a system call is about to be executed. Today, - // this hook is invoked when the EIP-4788 system call is about to be executed to set the - // beacon block root. + // OnSystemCallStartHook is called when a system call is about to be executed. + // Today, this hook is invoked when the EIP-4788 system call is about to be + // executed to set the beacon block root. // - // After this hook, the EVM call tracing will happened as usual so you will receive a `OnEnter/OnExit` - // as well as state hooks between this hook and the `OnSystemCallEndHook`. + // After this hook, the EVM call tracing will happened as usual so you will + // receive a `OnEnter/OnExit` as well as state hooks between this hook and + // the `OnSystemCallEndHook`. // - // Note that system call happens outside normal transaction execution, so the `OnTxStart/OnTxEnd` hooks - // will not be invoked. + // Note that system call happens outside normal transaction execution, so + // the `OnTxStart/OnTxEnd` hooks will not be invoked. OnSystemCallStartHook = func() - // OnSystemCallStartHookV2 is called when a system call is about to be executed. Refer - // to `OnSystemCallStartHook` for more information. + // OnSystemCallStartHookV2 is called when a system call is about to be executed. + // Refer to `OnSystemCallStartHook` for more information. 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. + // 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. OnSystemCallEndHook = func() /* @@ -207,6 +207,7 @@ type Hooks struct { OnOpcode OpcodeHook OnFault FaultHook OnGasChange GasChangeHook + // Chain events OnBlockchainInit BlockchainInitHook OnClose CloseHook @@ -233,6 +234,7 @@ type Hooks struct { //State read events OnColdStorageRead ColdStorageReadHook OnColdAccountRead ColdAccountReadHook + // Block hash read OnBlockHashRead BlockHashReadHook } @@ -249,57 +251,74 @@ const ( // 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 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 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 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 (WrapWithJournal). + // 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 (WrapWithJournal). 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. +// 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. +// 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 //go:generate go run golang.org/x/tools/cmd/stringer -type=GasChangeReason -trimprefix=GasChange -output gen_gas_change_reason_stringer.go @@ -307,61 +326,100 @@ 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 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 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 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 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 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 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 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 event + // will be emitted. GasChangeCallLeftOverRefunded GasChangeReason = 7 - // GasChangeCallContractCreation is the amount of gas that will be burned for a CREATE. + + // GasChangeCallContractCreation is the amount of gas that will be burned + // for a CREATE. GasChangeCallContractCreation GasChangeReason = 8 - // GasChangeCallContractCreation2 is the amount of gas that will be burned for a CREATE2. + + // GasChangeCallContractCreation2 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 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 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 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 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 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 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 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 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 flags the event of adding to the + // witness when checking for contract address collision. GasChangeWitnessContractCollisionCheck GasChangeReason = 18 - // GasChangeTxDataFloor is the amount of extra gas the transaction has to pay to reach the minimum gas requirement for the - // transaction data. This change will always be a negative change. + + // GasChangeTxDataFloor is the amount of extra gas the transaction has to + // pay to reach the minimum gas requirement for the transaction data. + // This change will always be a negative change. GasChangeTxDataFloor GasChangeReason = 19 - // 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 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 ) @@ -385,11 +443,12 @@ const ( // NonceChangeNewContract is the nonce change of a newly created contract. NonceChangeNewContract NonceChangeReason = 4 - // NonceChangeTransaction is the nonce change due to a EIP-7702 authorization. + // NonceChangeAuthorization is the nonce change due to a EIP-7702 authorization. NonceChangeAuthorization NonceChangeReason = 5 - // NonceChangeRevert is emitted when the nonce 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 (WrapWithJournal). + // NonceChangeRevert is emitted when the nonce 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 (WrapWithJournal). NonceChangeRevert NonceChangeReason = 6 // NonceChangeSelfdestruct is emitted when the nonce is reset to zero due to a self-destruct @@ -404,22 +463,26 @@ type CodeChangeReason byte const ( CodeChangeUnspecified CodeChangeReason = 0 - // CodeChangeContractCreation is when a new contract is deployed via CREATE/CREATE2 operations. + // CodeChangeContractCreation is when a new contract is deployed via + // CREATE/CREATE2 operations. CodeChangeContractCreation CodeChangeReason = 1 - // CodeChangeGenesis is when contract code is set during blockchain genesis or initial setup. + // CodeChangeGenesis is when contract code is set during blockchain genesis + // or initial setup. CodeChangeGenesis CodeChangeReason = 2 // CodeChangeAuthorization is when code is set via EIP-7702 Set Code Authorization. CodeChangeAuthorization CodeChangeReason = 3 - // CodeChangeAuthorizationClear is when EIP-7702 delegation is cleared by setting to zero address. + // CodeChangeAuthorizationClear is when EIP-7702 delegation is cleared by + // setting to zero address. CodeChangeAuthorizationClear CodeChangeReason = 4 // CodeChangeSelfDestruct is when contract code is cleared due to self-destruct. CodeChangeSelfDestruct CodeChangeReason = 5 - // CodeChangeRevert is emitted when the code 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 (WrapWithJournal). + // CodeChangeRevert is emitted when the code 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 (WrapWithJournal). CodeChangeRevert CodeChangeReason = 6 ) diff --git a/core/tracing/journal.go b/core/tracing/journal.go index 4269bdc0b1..b7ee8f23e2 100644 --- a/core/tracing/journal.go +++ b/core/tracing/journal.go @@ -42,7 +42,9 @@ func WrapWithJournal(hooks *Hooks) (*Hooks, error) { return nil, errors.New("wrapping nil tracer") } // No state change to journal, return the wrapped hooks as is - if hooks.OnBalanceChange == nil && hooks.OnNonceChange == nil && hooks.OnNonceChangeV2 == nil && hooks.OnCodeChange == nil && hooks.OnCodeChangeV2 == nil && hooks.OnStorageChange == nil { + if hooks.OnBalanceChange == nil && hooks.OnNonceChange == nil && hooks.OnNonceChangeV2 == nil && + hooks.OnCodeChange == nil && hooks.OnCodeChangeV2 == nil && hooks.OnStorageChange == nil { + // TODO(sina) hooks.OnLog should also be handled here return hooks, nil } if hooks.OnNonceChange != nil && hooks.OnNonceChangeV2 != nil { @@ -56,11 +58,14 @@ func WrapWithJournal(hooks *Hooks) (*Hooks, error) { wrapped := *hooks // Create journal - j := &journal{hooks: hooks} + j := &journal{ + hooks: hooks, + } // Scope hooks need to be re-implemented. wrapped.OnTxEnd = j.OnTxEnd wrapped.OnEnter = j.OnEnter wrapped.OnExit = j.OnExit + // Wrap state change hooks. if hooks.OnBalanceChange != nil { wrapped.OnBalanceChange = j.OnBalanceChange @@ -69,6 +74,7 @@ func WrapWithJournal(hooks *Hooks) (*Hooks, error) { // Regardless of which hook version is used in the tracer, // the journal will want to capture the nonce change reason. wrapped.OnNonceChangeV2 = j.OnNonceChangeV2 + // A precaution to ensure EVM doesn't call both hooks. wrapped.OnNonceChange = nil } @@ -81,7 +87,6 @@ func WrapWithJournal(hooks *Hooks) (*Hooks, error) { if hooks.OnStorageChange != nil { wrapped.OnStorageChange = j.OnStorageChange } - return &wrapped, nil } @@ -160,7 +165,11 @@ func (j *journal) OnColdAccountLoad(address common.Address) { } func (j *journal) OnBalanceChange(addr common.Address, prev, new *big.Int, reason BalanceChangeReason) { - j.entries = append(j.entries, balanceChange{addr: addr, prev: prev, new: new}) + j.entries = append(j.entries, balanceChange{ + addr: addr, + prev: prev, + new: new, + }) if j.hooks.OnBalanceChange != nil { j.hooks.OnBalanceChange(addr, prev, new, reason) } @@ -170,7 +179,11 @@ func (j *journal) OnNonceChangeV2(addr common.Address, prev, new uint64, reason // When a contract is created, the nonce of the creator is incremented. // This change is not reverted when the creation fails. if reason != NonceChangeContractCreator { - j.entries = append(j.entries, nonceChange{addr: addr, prev: prev, new: new}) + j.entries = append(j.entries, nonceChange{ + addr: addr, + prev: prev, + new: new, + }) } if j.hooks.OnNonceChangeV2 != nil { j.hooks.OnNonceChangeV2(addr, prev, new, reason) @@ -206,7 +219,12 @@ func (j *journal) OnCodeChangeV2(addr common.Address, prevCodeHash common.Hash, } func (j *journal) OnStorageChange(addr common.Address, slot common.Hash, prev, new common.Hash) { - j.entries = append(j.entries, storageChange{addr: addr, slot: slot, prev: prev, new: new}) + j.entries = append(j.entries, storageChange{ + addr: addr, + slot: slot, + prev: prev, + new: new, + }) if j.hooks.OnStorageChange != nil { j.hooks.OnStorageChange(addr, slot, prev, new) }