Skip to content

Commit

Permalink
eip2935 redesign: insert all 256 ancestors upon transition (#362)
Browse files Browse the repository at this point in the history
* eip2935 redesign: only read target block hash

* review fixes

* fix: t8n tool
  • Loading branch information
gballet committed May 7, 2024
1 parent e658861 commit 32dc1a9
Show file tree
Hide file tree
Showing 5 changed files with 34 additions and 20 deletions.
5 changes: 4 additions & 1 deletion cmd/evm/internal/t8ntool/execution.go
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down
7 changes: 6 additions & 1 deletion core/chain_makers.go
Original file line number Diff line number Diff line change
Expand Up @@ -386,7 +386,12 @@ 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) {
ProcessParentBlockHash(statedb, b.header.Number.Uint64()-1, b.header.ParentHash)
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
Expand Down
15 changes: 14 additions & 1 deletion core/state_processor.go
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,12 @@ 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()) {
ProcessParentBlockHash(statedb, block.NumberU64()-1, block.ParentHash())
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() {
Expand Down Expand Up @@ -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)
Expand Down
20 changes: 4 additions & 16 deletions core/vm/instructions.go
Original file line number Diff line number Diff line change
Expand Up @@ -515,22 +515,10 @@ 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.

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.
// 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
Expand Down
7 changes: 6 additions & 1 deletion miner/worker.go
Original file line number Diff line number Diff line change
Expand Up @@ -921,7 +921,12 @@ func (w *worker) prepareWork(genParams *generateParams) (*environment, error) {
return nil, err
}
if w.chainConfig.IsPrague(header.Number, header.Time) {
core.ProcessParentBlockHash(env.state, header.Number.Uint64()-1, header.ParentHash)
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
}
Expand Down

0 comments on commit 32dc1a9

Please sign in to comment.