diff --git a/core/tracing/hooks.go b/core/tracing/hooks.go index 8bd57903f5..59e3f92a9d 100644 --- a/core/tracing/hooks.go +++ b/core/tracing/hooks.go @@ -189,6 +189,9 @@ type ( // 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 { @@ -223,6 +226,8 @@ type Hooks struct { OnCodeSizeRead CodeSizeReadHook OnCodeHashRead CodeHashReadHook OnStorageRead StorageReadHook + // Block hash read + OnBlockHashRead BlockHashReadHook } // BalanceChangeReason is used to indicate the reason for a balance change, useful diff --git a/core/vm/instructions.go b/core/vm/instructions.go index 35d6393fba..40b26c1cab 100644 --- a/core/vm/instructions.go +++ b/core/vm/instructions.go @@ -455,6 +455,9 @@ func opBlockhash(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ( if witness := interpreter.evm.StateDB.Witness(); witness != nil { witness.AddBlockHash(num64) } + if tracer := interpreter.evm.Config.Tracer; tracer != nil && tracer.OnBlockHashRead != nil { + tracer.OnBlockHashRead(num64, res) + } num.SetBytes(res[:]) } else { num.Clear() diff --git a/eth/tracers/live/noop.go b/eth/tracers/live/noop.go index 83ea74c244..614a2c554b 100644 --- a/eth/tracers/live/noop.go +++ b/eth/tracers/live/noop.go @@ -48,6 +48,7 @@ func newNoopTracer(_ json.RawMessage) (*tracing.Hooks, error) { OnCodeSizeRead: t.OnCodeSizeRead, OnCodeHashRead: t.OnCodeHashRead, OnStorageRead: t.OnStorageRead, + OnBlockHashRead: t.OnBlockHashRead, }, nil } @@ -113,5 +114,7 @@ func (t *noop) OnCodeHashRead(addr common.Address, hash common.Hash) {} func (t *noop) OnStorageRead(addr common.Address, slot, val common.Hash) {} +func (t *noop) OnBlockHashRead(number uint64, hash common.Hash) {} + func (t *noop) OnGasChange(old, new uint64, reason tracing.GasChangeReason) { }