eip2935 redesign: insert all 256 ancestors upon transition (#362)

* eip2935 redesign: only read target block hash

* review fixes

* fix: t8n tool
This commit is contained in:
Guillaume Ballet 2024-02-06 09:52:24 +01:00
parent 61ffef7961
commit 2e671ea446
5 changed files with 34 additions and 20 deletions

View file

@ -184,7 +184,10 @@ func (pre *Prestate) Apply(vmConfig vm.Config, chainConfig *params.ChainConfig,
misc.ApplyDAOHardFork(statedb)
}
if chainConfig.IsPrague(big.NewInt(int64(pre.Env.Number)), pre.Env.Timestamp) {
core.ProcessParentBlockHash(statedb, pre.Env.Number-1, *pre.Env.ParentHash)
// insert all parent hashes in the contract
for i := pre.Env.Number - 1; i > 0 && i >= pre.Env.Number-257; i-- {
core.ProcessParentBlockHash(statedb, i, pre.Env.BlockHashes[math.HexOrDecimal64(i)])
}
}
var blobGasUsed uint64
for i, tx := range txs {

View file

@ -386,8 +386,13 @@ func GenerateVerkleChain(config *params.ChainConfig, parent *types.Block, engine
fmt.Println("prestate", preState.GetTrie().(*trie.VerkleTrie).ToDot())
if config.IsPrague(b.header.Number, b.header.Time) {
if !config.IsPrague(b.parent.Number(), b.parent.Time()) {
// Transition case: insert all 256 ancestors
InsertBlockHashHistoryAtEip2935Fork(statedb, b.header.Number.Uint64()-1, b.header.ParentHash, chainreader)
} else {
ProcessParentBlockHash(statedb, b.header.Number.Uint64()-1, b.header.ParentHash)
}
}
// Mutate the state and block according to any hard-fork specs
if daoBlock := config.DAOForkBlock; daoBlock != nil {

View file

@ -87,8 +87,13 @@ func (p *StateProcessor) Process(block *types.Block, statedb *state.StateDB, cfg
signer = types.MakeSigner(p.config, header.Number, header.Time)
)
if p.config.IsPrague(block.Number(), block.Time()) {
parent := p.bc.GetBlockByHash(block.ParentHash())
if !p.config.IsPrague(parent.Number(), parent.Time()) {
InsertBlockHashHistoryAtEip2935Fork(statedb, block.NumberU64()-1, block.ParentHash(), p.bc)
} else {
ProcessParentBlockHash(statedb, block.NumberU64()-1, block.ParentHash())
}
}
// Iterate over and process the individual transactions
for i, tx := range block.Transactions() {
msg, err := TransactionToMessage(tx, signer, header.BaseFee)
@ -364,6 +369,14 @@ func (kvm *keyValueMigrator) migrateCollectedKeyValues(tree *trie.VerkleTrie) er
return nil
}
func InsertBlockHashHistoryAtEip2935Fork(statedb *state.StateDB, prevNumber uint64, prevHash common.Hash, chain consensus.ChainHeaderReader) {
ancestor := chain.GetHeader(prevHash, prevNumber)
for i := prevNumber; i > 0 && i >= prevNumber-256; i-- {
ProcessParentBlockHash(statedb, i, ancestor.Hash())
ancestor = chain.GetHeader(ancestor.ParentHash, ancestor.Number.Uint64()-1)
}
}
func ProcessParentBlockHash(statedb *state.StateDB, prevNumber uint64, prevHash common.Hash) {
var key common.Hash
binary.BigEndian.PutUint64(key[24:], prevNumber)

View file

@ -515,24 +515,12 @@ func opBlockhash(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) (
}
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 evm.chainRules.IsPrague && bnum > 256 {
if getBlockHashFromContract(bnum-256, evm.StateDB, evm.Accesses) != (common.Hash{}) {
// EIP-2935 case: get the block number from the fork, as we are 256 blocks
// after the fork activation.
// 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
}
// 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 {

View file

@ -921,8 +921,13 @@ func (w *worker) prepareWork(genParams *generateParams) (*environment, error) {
return nil, err
}
if w.chainConfig.IsPrague(header.Number, header.Time) {
parent := w.chain.GetHeaderByNumber(header.Number.Uint64() - 1)
if !w.chain.Config().IsPrague(parent.Number, parent.Time) {
core.InsertBlockHashHistoryAtEip2935Fork(env.state, header.Number.Uint64()-1, header.ParentHash, w.chain)
} else {
core.ProcessParentBlockHash(env.state, header.Number.Uint64()-1, header.ParentHash)
}
}
return env, nil
}