eip2935 BLOCKHASH

This commit is contained in:
Guillaume Ballet 2024-01-25 18:02:42 +01:00
parent b4460a8f74
commit 7f330c1c0b

View file

@ -17,6 +17,8 @@
package vm package vm
import ( import (
"encoding/binary"
"github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/core/types" "github.com/ethereum/go-ethereum/core/types"
"github.com/ethereum/go-ethereum/crypto" "github.com/ethereum/go-ethereum/crypto"
@ -432,6 +434,12 @@ func opGasprice(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([
return nil, nil 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) { func opBlockhash(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) {
num := scope.Stack.peek() num := scope.Stack.peek()
num64, overflow := num.Uint64WithOverflow() num64, overflow := num.Uint64WithOverflow()
@ -439,6 +447,26 @@ func opBlockhash(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) (
num.Clear() num.Clear()
return nil, nil 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 var upper, lower uint64
upper = interpreter.evm.Context.BlockNumber.Uint64() upper = interpreter.evm.Context.BlockNumber.Uint64()
if upper < 257 { if upper < 257 {