github.com/ethereum/go-ethereum@v1.16.1/core/tracing/hooks.go (about) 1 // Copyright 2024 The go-ethereum Authors 2 // This file is part of the go-ethereum library. 3 // 4 // The go-ethereum library is free software: you can redistribute it and/or modify 5 // it under the terms of the GNU Lesser General Public License as published by 6 // the Free Software Foundation, either version 3 of the License, or 7 // (at your option) any later version. 8 // 9 // The go-ethereum library is distributed in the hope that it will be useful, 10 // but WITHOUT ANY WARRANTY; without even the implied warranty of 11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 // GNU Lesser General Public License for more details. 13 // 14 // You should have received a copy of the GNU Lesser General Public License 15 // along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>. 16 17 // Package tracing defines hooks for 'live tracing' of block processing and transaction 18 // execution. Here we define the low-level [Hooks] object that carries hooks which are 19 // invoked by the go-ethereum core at various points in the state transition. 20 // 21 // To create a tracer that can be invoked with Geth, you need to register it using 22 // [github.com/ethereum/go-ethereum/eth/tracers.LiveDirectory.Register]. 23 // 24 // See https://geth.ethereum.org/docs/developers/evm-tracing/live-tracing for a tutorial. 25 package tracing 26 27 import ( 28 "math/big" 29 30 "github.com/ethereum/go-ethereum/common" 31 "github.com/ethereum/go-ethereum/core/types" 32 "github.com/ethereum/go-ethereum/params" 33 "github.com/holiman/uint256" 34 ) 35 36 // OpContext provides the context at which the opcode is being 37 // executed in, including the memory, stack and various contract-level information. 38 type OpContext interface { 39 MemoryData() []byte 40 StackData() []uint256.Int 41 Caller() common.Address 42 Address() common.Address 43 CallValue() *uint256.Int 44 CallInput() []byte 45 ContractCode() []byte 46 } 47 48 // StateDB gives tracers access to the whole state. 49 type StateDB interface { 50 GetBalance(common.Address) *uint256.Int 51 GetNonce(common.Address) uint64 52 GetCode(common.Address) []byte 53 GetCodeHash(common.Address) common.Hash 54 GetState(common.Address, common.Hash) common.Hash 55 GetTransientState(common.Address, common.Hash) common.Hash 56 Exist(common.Address) bool 57 GetRefund() uint64 58 } 59 60 // VMContext provides the context for the EVM execution. 61 type VMContext struct { 62 Coinbase common.Address 63 BlockNumber *big.Int 64 Time uint64 65 Random *common.Hash 66 BaseFee *big.Int 67 StateDB StateDB 68 } 69 70 // BlockEvent is emitted upon tracing an incoming block. 71 // It contains the block as well as consensus related information. 72 type BlockEvent struct { 73 Block *types.Block 74 Finalized *types.Header 75 Safe *types.Header 76 } 77 78 type ( 79 /* 80 - VM events - 81 */ 82 83 // TxStartHook is called before the execution of a transaction starts. 84 // Call simulations don't come with a valid signature. `from` field 85 // to be used for address of the caller. 86 TxStartHook = func(vm *VMContext, tx *types.Transaction, from common.Address) 87 88 // TxEndHook is called after the execution of a transaction ends. 89 TxEndHook = func(receipt *types.Receipt, err error) 90 91 // EnterHook is invoked when the processing of a message starts. 92 // 93 // Take note that EnterHook, when in the context of a live tracer, can be invoked 94 // outside of the `OnTxStart` and `OnTxEnd` hooks when dealing with system calls, 95 // see [OnSystemCallStartHook] and [OnSystemCallEndHook] for more information. 96 EnterHook = func(depth int, typ byte, from common.Address, to common.Address, input []byte, gas uint64, value *big.Int) 97 98 // ExitHook is invoked when the processing of a message ends. 99 // `revert` is true when there was an error during the execution. 100 // Exceptionally, before the homestead hardfork a contract creation that 101 // ran out of gas when attempting to persist the code to database did not 102 // count as a call failure and did not cause a revert of the call. This will 103 // be indicated by `reverted == false` and `err == ErrCodeStoreOutOfGas`. 104 // 105 // Take note that ExitHook, when in the context of a live tracer, can be invoked 106 // outside of the `OnTxStart` and `OnTxEnd` hooks when dealing with system calls, 107 // see [OnSystemCallStartHook] and [OnSystemCallEndHook] for more information. 108 ExitHook = func(depth int, output []byte, gasUsed uint64, err error, reverted bool) 109 110 // OpcodeHook is invoked just prior to the execution of an opcode. 111 OpcodeHook = func(pc uint64, op byte, gas, cost uint64, scope OpContext, rData []byte, depth int, err error) 112 113 // FaultHook is invoked when an error occurs during the execution of an opcode. 114 FaultHook = func(pc uint64, op byte, gas, cost uint64, scope OpContext, depth int, err error) 115 116 // GasChangeHook is invoked when the gas changes. 117 GasChangeHook = func(old, new uint64, reason GasChangeReason) 118 119 /* 120 - Chain events - 121 */ 122 123 // BlockchainInitHook is called when the blockchain is initialized. 124 BlockchainInitHook = func(chainConfig *params.ChainConfig) 125 126 // CloseHook is called when the blockchain closes. 127 CloseHook = func() 128 129 // BlockStartHook is called before executing `block`. 130 // `td` is the total difficulty prior to `block`. 131 BlockStartHook = func(event BlockEvent) 132 133 // BlockEndHook is called after executing a block. 134 BlockEndHook = func(err error) 135 136 // SkippedBlockHook indicates a block was skipped during processing 137 // due to it being known previously. This can happen e.g. when recovering 138 // from a crash. 139 SkippedBlockHook = func(event BlockEvent) 140 141 // GenesisBlockHook is called when the genesis block is being processed. 142 GenesisBlockHook = func(genesis *types.Block, alloc types.GenesisAlloc) 143 144 // OnSystemCallStartHook is called when a system call is about to be executed. Today, 145 // this hook is invoked when the EIP-4788 system call is about to be executed to set the 146 // beacon block root. 147 // 148 // After this hook, the EVM call tracing will happened as usual so you will receive a `OnEnter/OnExit` 149 // as well as state hooks between this hook and the `OnSystemCallEndHook`. 150 // 151 // Note that system call happens outside normal transaction execution, so the `OnTxStart/OnTxEnd` hooks 152 // will not be invoked. 153 OnSystemCallStartHook = func() 154 155 // OnSystemCallStartHookV2 is called when a system call is about to be executed. Refer 156 // to `OnSystemCallStartHook` for more information. 157 OnSystemCallStartHookV2 = func(vm *VMContext) 158 159 // OnSystemCallEndHook is called when a system call has finished executing. Today, 160 // this hook is invoked when the EIP-4788 system call is about to be executed to set the 161 // beacon block root. 162 OnSystemCallEndHook = func() 163 164 /* 165 - State events - 166 */ 167 168 // BalanceChangeHook is called when the balance of an account changes. 169 BalanceChangeHook = func(addr common.Address, prev, new *big.Int, reason BalanceChangeReason) 170 171 // NonceChangeHook is called when the nonce of an account changes. 172 NonceChangeHook = func(addr common.Address, prev, new uint64) 173 174 // NonceChangeHookV2 is called when the nonce of an account changes. 175 NonceChangeHookV2 = func(addr common.Address, prev, new uint64, reason NonceChangeReason) 176 177 // CodeChangeHook is called when the code of an account changes. 178 CodeChangeHook = func(addr common.Address, prevCodeHash common.Hash, prevCode []byte, codeHash common.Hash, code []byte) 179 180 // StorageChangeHook is called when the storage of an account changes. 181 StorageChangeHook = func(addr common.Address, slot common.Hash, prev, new common.Hash) 182 183 // LogHook is called when a log is emitted. 184 LogHook = func(log *types.Log) 185 186 // BlockHashReadHook is called when EVM reads the blockhash of a block. 187 BlockHashReadHook = func(blockNumber uint64, hash common.Hash) 188 ) 189 190 type Hooks struct { 191 // VM events 192 OnTxStart TxStartHook 193 OnTxEnd TxEndHook 194 OnEnter EnterHook 195 OnExit ExitHook 196 OnOpcode OpcodeHook 197 OnFault FaultHook 198 OnGasChange GasChangeHook 199 // Chain events 200 OnBlockchainInit BlockchainInitHook 201 OnClose CloseHook 202 OnBlockStart BlockStartHook 203 OnBlockEnd BlockEndHook 204 OnSkippedBlock SkippedBlockHook 205 OnGenesisBlock GenesisBlockHook 206 OnSystemCallStart OnSystemCallStartHook 207 OnSystemCallStartV2 OnSystemCallStartHookV2 208 OnSystemCallEnd OnSystemCallEndHook 209 // State events 210 OnBalanceChange BalanceChangeHook 211 OnNonceChange NonceChangeHook 212 OnNonceChangeV2 NonceChangeHookV2 213 OnCodeChange CodeChangeHook 214 OnStorageChange StorageChangeHook 215 OnLog LogHook 216 // Block hash read 217 OnBlockHashRead BlockHashReadHook 218 } 219 220 // BalanceChangeReason is used to indicate the reason for a balance change, useful 221 // for tracing and reporting. 222 type BalanceChangeReason byte 223 224 //go:generate go run golang.org/x/tools/cmd/stringer -type=BalanceChangeReason -trimprefix=BalanceChange -output gen_balance_change_reason_stringer.go 225 226 const ( 227 BalanceChangeUnspecified BalanceChangeReason = 0 228 229 // Issuance 230 // BalanceIncreaseRewardMineUncle is a reward for mining an uncle block. 231 BalanceIncreaseRewardMineUncle BalanceChangeReason = 1 232 // BalanceIncreaseRewardMineBlock is a reward for mining a block. 233 BalanceIncreaseRewardMineBlock BalanceChangeReason = 2 234 // BalanceIncreaseWithdrawal is ether withdrawn from the beacon chain. 235 BalanceIncreaseWithdrawal BalanceChangeReason = 3 236 // BalanceIncreaseGenesisBalance is ether allocated at the genesis block. 237 BalanceIncreaseGenesisBalance BalanceChangeReason = 4 238 239 // Transaction fees 240 // BalanceIncreaseRewardTransactionFee is the transaction tip increasing block builder's balance. 241 BalanceIncreaseRewardTransactionFee BalanceChangeReason = 5 242 // BalanceDecreaseGasBuy is spent to purchase gas for execution a transaction. 243 // Part of this gas will be burnt as per EIP-1559 rules. 244 BalanceDecreaseGasBuy BalanceChangeReason = 6 245 // BalanceIncreaseGasReturn is ether returned for unused gas at the end of execution. 246 BalanceIncreaseGasReturn BalanceChangeReason = 7 247 248 // DAO fork 249 // BalanceIncreaseDaoContract is ether sent to the DAO refund contract. 250 BalanceIncreaseDaoContract BalanceChangeReason = 8 251 // BalanceDecreaseDaoAccount is ether taken from a DAO account to be moved to the refund contract. 252 BalanceDecreaseDaoAccount BalanceChangeReason = 9 253 254 // BalanceChangeTransfer is ether transferred via a call. 255 // it is a decrease for the sender and an increase for the recipient. 256 BalanceChangeTransfer BalanceChangeReason = 10 257 // BalanceChangeTouchAccount is a transfer of zero value. It is only there to 258 // touch-create an account. 259 BalanceChangeTouchAccount BalanceChangeReason = 11 260 261 // BalanceIncreaseSelfdestruct is added to the recipient as indicated by a selfdestructing account. 262 BalanceIncreaseSelfdestruct BalanceChangeReason = 12 263 // BalanceDecreaseSelfdestruct is deducted from a contract due to self-destruct. 264 BalanceDecreaseSelfdestruct BalanceChangeReason = 13 265 // BalanceDecreaseSelfdestructBurn is ether that is sent to an already self-destructed 266 // account within the same tx (captured at end of tx). 267 // Note it doesn't account for a self-destruct which appoints itself as recipient. 268 BalanceDecreaseSelfdestructBurn BalanceChangeReason = 14 269 270 // BalanceChangeRevert is emitted when the balance is reverted back to a previous value due to call failure. 271 // It is only emitted when the tracer has opted in to use the journaling wrapper (WrapWithJournal). 272 BalanceChangeRevert BalanceChangeReason = 15 273 ) 274 275 // GasChangeReason is used to indicate the reason for a gas change, useful 276 // for tracing and reporting. 277 // 278 // There is essentially two types of gas changes, those that can be emitted once per transaction 279 // and those that can be emitted on a call basis, so possibly multiple times per transaction. 280 // 281 // They can be recognized easily by their name, those that start with `GasChangeTx` are emitted 282 // once per transaction, while those that start with `GasChangeCall` are emitted on a call basis. 283 type GasChangeReason byte 284 285 //go:generate go run golang.org/x/tools/cmd/stringer -type=GasChangeReason -trimprefix=GasChange -output gen_gas_change_reason_stringer.go 286 287 const ( 288 GasChangeUnspecified GasChangeReason = 0 289 290 // GasChangeTxInitialBalance is the initial balance for the call which will be equal to the gasLimit of the call. There is only 291 // one such gas change per transaction. 292 GasChangeTxInitialBalance GasChangeReason = 1 293 // GasChangeTxIntrinsicGas is the amount of gas that will be charged for the intrinsic cost of the transaction, there is 294 // always exactly one of those per transaction. 295 GasChangeTxIntrinsicGas GasChangeReason = 2 296 // GasChangeTxRefunds is the sum of all refunds which happened during the tx execution (e.g. storage slot being cleared) 297 // this generates an increase in gas. There is at most one of such gas change per transaction. 298 GasChangeTxRefunds GasChangeReason = 3 299 // GasChangeTxLeftOverReturned is the amount of gas left over at the end of transaction's execution that will be returned 300 // to the chain. This change will always be a negative change as we "drain" left over gas towards 0. If there was no gas 301 // left at the end of execution, no such even will be emitted. The returned gas's value in Wei is returned to caller. 302 // There is at most one of such gas change per transaction. 303 GasChangeTxLeftOverReturned GasChangeReason = 4 304 305 // GasChangeCallInitialBalance is the initial balance for the call which will be equal to the gasLimit of the call. There is only 306 // one such gas change per call. 307 GasChangeCallInitialBalance GasChangeReason = 5 308 // GasChangeCallLeftOverReturned is the amount of gas left over that will be returned to the caller, this change will always 309 // 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 310 // will be emitted. 311 GasChangeCallLeftOverReturned GasChangeReason = 6 312 // GasChangeCallLeftOverRefunded is the amount of gas that will be refunded to the call after the child call execution it 313 // executed completed. This value is always positive as we are giving gas back to the you, the left over gas of the child. 314 // If there was no gas left to be refunded, no such even will be emitted. 315 GasChangeCallLeftOverRefunded GasChangeReason = 7 316 // GasChangeCallContractCreation is the amount of gas that will be burned for a CREATE. 317 GasChangeCallContractCreation GasChangeReason = 8 318 // GasChangeCallContractCreation2 is the amount of gas that will be burned for a CREATE2. 319 GasChangeCallContractCreation2 GasChangeReason = 9 320 // GasChangeCallCodeStorage is the amount of gas that will be charged for code storage. 321 GasChangeCallCodeStorage GasChangeReason = 10 322 // GasChangeCallOpCode is the amount of gas that will be charged for an opcode executed by the EVM, exact opcode that was 323 // performed can be check by `OnOpcode` handling. 324 GasChangeCallOpCode GasChangeReason = 11 325 // GasChangeCallPrecompiledContract is the amount of gas that will be charged for a precompiled contract execution. 326 GasChangeCallPrecompiledContract GasChangeReason = 12 327 // GasChangeCallStorageColdAccess is the amount of gas that will be charged for a cold storage access as controlled by EIP2929 rules. 328 GasChangeCallStorageColdAccess GasChangeReason = 13 329 // GasChangeCallFailedExecution is the burning of the remaining gas when the execution failed without a revert. 330 GasChangeCallFailedExecution GasChangeReason = 14 331 // GasChangeWitnessContractInit flags the event of adding to the witness during the contract creation initialization step. 332 GasChangeWitnessContractInit GasChangeReason = 15 333 // GasChangeWitnessContractCreation flags the event of adding to the witness during the contract creation finalization step. 334 GasChangeWitnessContractCreation GasChangeReason = 16 335 // GasChangeWitnessCodeChunk flags the event of adding one or more contract code chunks to the witness. 336 GasChangeWitnessCodeChunk GasChangeReason = 17 337 // GasChangeWitnessContractCollisionCheck flags the event of adding to the witness when checking for contract address collision. 338 GasChangeWitnessContractCollisionCheck GasChangeReason = 18 339 // GasChangeTxDataFloor is the amount of extra gas the transaction has to pay to reach the minimum gas requirement for the 340 // transaction data. This change will always be a negative change. 341 GasChangeTxDataFloor GasChangeReason = 19 342 343 // GasChangeIgnored is a special value that can be used to indicate that the gas change should be ignored as 344 // it will be "manually" tracked by a direct emit of the gas change event. 345 GasChangeIgnored GasChangeReason = 0xFF 346 ) 347 348 // NonceChangeReason is used to indicate the reason for a nonce change. 349 type NonceChangeReason byte 350 351 //go:generate go run golang.org/x/tools/cmd/stringer -type=NonceChangeReason -trimprefix NonceChange -output gen_nonce_change_reason_stringer.go 352 353 const ( 354 NonceChangeUnspecified NonceChangeReason = 0 355 356 // NonceChangeGenesis is the nonce allocated to accounts at genesis. 357 NonceChangeGenesis NonceChangeReason = 1 358 359 // NonceChangeEoACall is the nonce change due to an EoA call. 360 NonceChangeEoACall NonceChangeReason = 2 361 362 // NonceChangeContractCreator is the nonce change of an account creating a contract. 363 NonceChangeContractCreator NonceChangeReason = 3 364 365 // NonceChangeNewContract is the nonce change of a newly created contract. 366 NonceChangeNewContract NonceChangeReason = 4 367 368 // NonceChangeTransaction is the nonce change due to a EIP-7702 authorization. 369 NonceChangeAuthorization NonceChangeReason = 5 370 371 // NonceChangeRevert is emitted when the nonce is reverted back to a previous value due to call failure. 372 // It is only emitted when the tracer has opted in to use the journaling wrapper (WrapWithJournal). 373 NonceChangeRevert NonceChangeReason = 6 374 )