diff --git a/core/genesis.go b/core/genesis.go index ae3dca01cb..39b3a01397 100644 --- a/core/genesis.go +++ b/core/genesis.go @@ -246,7 +246,8 @@ func (g *Genesis) toBlock(db ethdb.Database, triedb *triedb.Database) *types.Blo } // Configure any stateful precompiles that should be enabled in the genesis. - err = ApplyPrecompileActivations(g.Config, nil, types.NewBlockWithHeader(head), statedb) + blockContext := NewBlockContext(head.Number, head.Time) + err = ApplyPrecompileActivations(g.Config, nil, blockContext, statedb) if err != nil { panic(fmt.Sprintf("unable to configure precompiles in genesis block: %v", err)) } diff --git a/core/state_processor.go b/core/state_processor.go index d8d79fa42f..563485f67e 100644 --- a/core/state_processor.go +++ b/core/state_processor.go @@ -78,7 +78,8 @@ func (p *StateProcessor) Process(block *types.Block, parent *types.Header, state ) // Configure any upgrades that should go into effect during this block. - err := ApplyUpgrades(p.config, &parent.Time, block, statedb) + blockContext := NewBlockContext(block.Number(), block.Time()) + err := ApplyUpgrades(p.config, &parent.Time, blockContext, statedb) if err != nil { log.Error("failed to configure precompiles processing block", "hash", block.Hash(), "number", block.NumberU64(), "timestamp", block.Time(), "err", err) return nil, nil, 0, err diff --git a/core/state_processor_ext.go b/core/state_processor_ext.go index ea89957321..e1d6ef43b9 100644 --- a/core/state_processor_ext.go +++ b/core/state_processor_ext.go @@ -4,6 +4,7 @@ package core import ( "encoding/json" "fmt" + "math/big" "github.com/ava-labs/coreth/core/extstate" "github.com/ava-labs/coreth/core/state" @@ -73,3 +74,23 @@ func ApplyPrecompileActivations(c *params.ChainConfig, parentTimestamp *uint64, func ApplyUpgrades(c *params.ChainConfig, parentTimestamp *uint64, blockContext contract.ConfigurationBlockContext, statedb *state.StateDB) error { return ApplyPrecompileActivations(c, parentTimestamp, blockContext, statedb) } + +// BlockContext implements the `contract.ConfigurationBlockContext` interface. +type BlockContext struct { + number *big.Int + timestamp uint64 +} + +// NewBlockContext creates a new block context using the block number +// and block time provided. This function is usually necessary to convert +// a `*types.Block` to be passed as a `contract.ConfigurationBlockContext` +// interface to [ApplyUpgrades]. +func NewBlockContext(number *big.Int, timestamp uint64) *BlockContext { + return &BlockContext{ + number: number, + timestamp: timestamp, + } +} + +func (bc *BlockContext) Number() *big.Int { return bc.number } +func (bc *BlockContext) Timestamp() uint64 { return bc.timestamp } diff --git a/core/types/block.go b/core/types/block.go index f7cf4da018..b47048fa62 100644 --- a/core/types/block.go +++ b/core/types/block.go @@ -339,7 +339,6 @@ func (b *Block) GasLimit() uint64 { return b.header.GasLimit } func (b *Block) GasUsed() uint64 { return b.header.GasUsed } func (b *Block) Difficulty() *big.Int { return new(big.Int).Set(b.header.Difficulty) } func (b *Block) Time() uint64 { return b.header.Time } -func (b *Block) Timestamp() uint64 { return b.header.Time } func (b *Block) NumberU64() uint64 { return b.header.Number.Uint64() } func (b *Block) MixDigest() common.Hash { return b.header.MixDigest } diff --git a/eth/state_accessor.go b/eth/state_accessor.go index ea5afa3b85..858fa7ce73 100644 --- a/eth/state_accessor.go +++ b/eth/state_accessor.go @@ -284,7 +284,8 @@ func (eth *Ethereum) StateAtNextBlock(ctx context.Context, parent *types.Block, } // Apply upgrades here for the [nextBlock] - err = core.ApplyUpgrades(eth.blockchain.Config(), &parent.Header().Time, nextBlock, statedb) + blockContext := core.NewBlockContext(nextBlock.Number(), nextBlock.Time()) + err = core.ApplyUpgrades(eth.blockchain.Config(), &parent.Header().Time, blockContext, statedb) if err != nil { release() return nil, nil, err diff --git a/eth/tracers/api.go b/eth/tracers/api.go index 2f3eef2fc1..b439f3171d 100644 --- a/eth/tracers/api.go +++ b/eth/tracers/api.go @@ -966,7 +966,8 @@ func (api *API) TraceCall(ctx context.Context, args ethapi.TransactionArgs, bloc config.BlockOverrides.Apply(&vmctx) // Apply all relevant upgrades from [originalTime] to the block time set in the override. // Should be applied before the state overrides. - err = core.ApplyUpgrades(api.backend.ChainConfig(), &originalTime, block, statedb) + blockContext := core.NewBlockContext(block.Number(), block.Time()) + err = core.ApplyUpgrades(api.backend.ChainConfig(), &originalTime, blockContext, statedb) if err != nil { return nil, err } diff --git a/eth/tracers/api_test.go b/eth/tracers/api_test.go index e1b5641869..e91108822d 100644 --- a/eth/tracers/api_test.go +++ b/eth/tracers/api_test.go @@ -181,7 +181,8 @@ func (b *testBackend) StateAtNextBlock(ctx context.Context, parent, nextBlock *t return nil, nil, err } // Apply upgrades to the parent state - err = core.ApplyUpgrades(b.chainConfig, &parent.Header().Time, nextBlock, statedb) + blockContext := core.NewBlockContext(nextBlock.Number(), nextBlock.Time()) + err = core.ApplyUpgrades(b.chainConfig, &parent.Header().Time, blockContext, statedb) if err != nil { release() return nil, nil, err diff --git a/miner/worker.go b/miner/worker.go index b73190f9e3..cc3af7cabd 100644 --- a/miner/worker.go +++ b/miner/worker.go @@ -212,7 +212,8 @@ func (w *worker) commitNewWork(predicateContext *precompileconfig.PredicateConte env.state.StopPrefetcher() }() // Configure any upgrades that should go into effect during this block. - err = core.ApplyUpgrades(w.chainConfig, &parent.Time, types.NewBlockWithHeader(header), env.state) + blockContext := core.NewBlockContext(header.Number, header.Time) + err = core.ApplyUpgrades(w.chainConfig, &parent.Time, blockContext, env.state) if err != nil { log.Error("failed to configure precompiles mining new block", "parent", parent.Hash(), "number", header.Number, "timestamp", header.Time, "err", err) return nil, err diff --git a/plugin/evm/block.go b/plugin/evm/block.go index bcc7e7e995..766167e21f 100644 --- a/plugin/evm/block.go +++ b/plugin/evm/block.go @@ -151,7 +151,7 @@ func (b *Block) Accept(context.Context) error { // Call Accept for relevant precompile logs. Note we do this prior to // calling Accept on the blockChain so any side effects (eg warp signatures) // take place before the accepted log is emitted to subscribers. - rules := b.vm.chainConfig.Rules(b.ethBlock.Number(), params.IsMergeTODO, b.ethBlock.Timestamp()) + rules := b.vm.chainConfig.Rules(b.ethBlock.Number(), params.IsMergeTODO, b.ethBlock.Time()) if err := b.handlePrecompileAccept(*params.GetRulesExtra(rules)); err != nil { return err } @@ -279,7 +279,7 @@ func (b *Block) Verify(context.Context) error { // ShouldVerifyWithContext implements the block.WithVerifyContext interface func (b *Block) ShouldVerifyWithContext(context.Context) (bool, error) { - rules := params.GetRulesExtra(b.vm.chainConfig.Rules(b.ethBlock.Number(), params.IsMergeTODO, b.ethBlock.Timestamp())) + rules := params.GetRulesExtra(b.vm.chainConfig.Rules(b.ethBlock.Number(), params.IsMergeTODO, b.ethBlock.Time())) predicates := rules.Predicaters // Short circuit early if there are no predicates to verify if len(predicates) == 0 { @@ -360,7 +360,7 @@ func (b *Block) verify(predicateContext *precompileconfig.PredicateContext, writ // verifyPredicates verifies the predicates in the block are valid according to predicateContext. func (b *Block) verifyPredicates(predicateContext *precompileconfig.PredicateContext) error { - rules := b.vm.chainConfig.Rules(b.ethBlock.Number(), params.IsMergeTODO, b.ethBlock.Timestamp()) + rules := b.vm.chainConfig.Rules(b.ethBlock.Number(), params.IsMergeTODO, b.ethBlock.Time()) rulesExtra := params.GetRulesExtra(rules) switch {