Use circular buffer for BLOCKHASH history (#402)

* eip2935: use ring buffer

Signed-off-by: Ignacio Hagopian <jsign.uy@gmail.com>

* limit resolving scope

Signed-off-by: Ignacio Hagopian <jsign.uy@gmail.com>

---------

Signed-off-by: Ignacio Hagopian <jsign.uy@gmail.com>
This commit is contained in:
Ignacio Hagopian 2024-03-12 10:30:40 -03:00 committed by Guillaume Ballet
parent 631099322c
commit 40d5153941
2 changed files with 10 additions and 8 deletions

View file

@ -378,8 +378,9 @@ func InsertBlockHashHistoryAtEip2935Fork(statedb *state.StateDB, prevNumber uint
} }
func ProcessParentBlockHash(statedb *state.StateDB, prevNumber uint64, prevHash common.Hash) { func ProcessParentBlockHash(statedb *state.StateDB, prevNumber uint64, prevHash common.Hash) {
ringIndex := prevNumber % 256
var key common.Hash var key common.Hash
binary.BigEndian.PutUint64(key[24:], prevNumber) binary.BigEndian.PutUint64(key[24:], ringIndex)
statedb.SetState(params.HistoryStorageAddress, key, prevHash) statedb.SetState(params.HistoryStorageAddress, key, prevHash)
index, suffix := utils.GetTreeKeyStorageSlotTreeIndexes(key[:]) index, suffix := utils.GetTreeKeyStorageSlotTreeIndexes(key[:])
statedb.Witness().TouchAddressOnWriteAndComputeGas(params.HistoryStorageAddress[:], *index, suffix) statedb.Witness().TouchAddressOnWriteAndComputeGas(params.HistoryStorageAddress[:], *index, suffix)

View file

@ -517,8 +517,9 @@ func opGasprice(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([
} }
func getBlockHashFromContract(number uint64, statedb StateDB, witness *state.AccessWitness) common.Hash { func getBlockHashFromContract(number uint64, statedb StateDB, witness *state.AccessWitness) common.Hash {
ringIndex := number % 256
var pnum common.Hash var pnum common.Hash
binary.BigEndian.PutUint64(pnum[24:], number) binary.BigEndian.PutUint64(pnum[24:], ringIndex)
treeIndex, suffix := utils.GetTreeKeyStorageSlotTreeIndexes(pnum.Bytes()) treeIndex, suffix := utils.GetTreeKeyStorageSlotTreeIndexes(pnum.Bytes())
witness.TouchAddressOnReadAndComputeGas(params.HistoryStorageAddress[:], *treeIndex, suffix) witness.TouchAddressOnReadAndComputeGas(params.HistoryStorageAddress[:], *treeIndex, suffix)
return statedb.GetState(params.HistoryStorageAddress, pnum) return statedb.GetState(params.HistoryStorageAddress, pnum)
@ -533,11 +534,6 @@ func opBlockhash(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) (
} }
evm := interpreter.evm evm := interpreter.evm
// if Prague is active, read it from the history contract (EIP 2935).
if evm.chainRules.IsPrague {
num.SetBytes(getBlockHashFromContract(num64, evm.StateDB, evm.Accesses).Bytes())
return nil, nil
}
var upper, lower uint64 var upper, lower uint64
upper = interpreter.evm.Context.BlockNumber.Uint64() upper = interpreter.evm.Context.BlockNumber.Uint64()
@ -547,7 +543,12 @@ func opBlockhash(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) (
lower = upper - 256 lower = upper - 256
} }
if num64 >= lower && num64 < upper { if num64 >= lower && num64 < upper {
num.SetBytes(interpreter.evm.Context.GetHash(num64).Bytes()) // if Prague is active, read it from the history contract (EIP 2935).
if evm.chainRules.IsPrague {
num.SetBytes(getBlockHashFromContract(num64, evm.StateDB, evm.Accesses).Bytes())
} else {
num.SetBytes(interpreter.evm.Context.GetHash(num64).Bytes())
}
} else { } else {
num.Clear() num.Clear()
} }