From 7f330c1c0b7f2b1d3601d4a1d162ce2114b4bbbf Mon Sep 17 00:00:00 2001 From: Guillaume Ballet <3272758+gballet@users.noreply.github.com> Date: Thu, 25 Jan 2024 18:02:42 +0100 Subject: [PATCH] eip2935 BLOCKHASH --- core/vm/instructions.go | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) diff --git a/core/vm/instructions.go b/core/vm/instructions.go index 56ff350201..5a2b0fc4ab 100644 --- a/core/vm/instructions.go +++ b/core/vm/instructions.go @@ -17,6 +17,8 @@ package vm import ( + "encoding/binary" + "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/core/types" "github.com/ethereum/go-ethereum/crypto" @@ -432,6 +434,12 @@ func opGasprice(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([ return nil, nil } +func getBlockHashFromContract(number uint64, statedb StateDB) common.Hash { + var pnum common.Hash + binary.BigEndian.PutUint64(pnum[24:], number) + return statedb.GetState(params.HistoryStorageAddress, pnum) +} + func opBlockhash(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) { num := scope.Stack.peek() num64, overflow := num.Uint64WithOverflow() @@ -439,6 +447,26 @@ func opBlockhash(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ( num.Clear() return nil, nil } + + evm := interpreter.evm + bnum := evm.Context.BlockNumber.Uint64() + // if Prague is active, check if we are past the 256th block so that + // reading from the contract can be activated (EIP 2935). + if interpreter.evm.chainRules.IsPrague && bnum > 256 { + if getBlockHashFromContract(bnum-256, evm.StateDB) != (common.Hash{}) { + // EIP-2935 case: get the block number from the fork, as we are 256 blocks + // after the fork activation. + + num.SetBytes(getBlockHashFromContract(num64, evm.StateDB).Bytes()) + return nil, nil + } + + // if the 256th ancestor didn't have its hash stored in the + // history contract, then we are within 256 blocks of the + // fork activation, and the former behavior should be retained. + // Fall through the legacy use case. + } + var upper, lower uint64 upper = interpreter.evm.Context.BlockNumber.Uint64() if upper < 257 {