diff --git a/core/blockchain_test.go b/core/blockchain_test.go index 87e7b01b5eb7..1cc989f38db0 100644 --- a/core/blockchain_test.go +++ b/core/blockchain_test.go @@ -3722,7 +3722,7 @@ func TestCurieTransition(t *testing.T) { b, _ := json.Marshal(params.AllEthashProtocolChanges) json.Unmarshal(b, &config) config.CurieBlock = big.NewInt(2) - config.DescartesBlock = nil + config.DescartesTime = nil var ( db = rawdb.NewMemoryDatabase() diff --git a/core/state_processor_test.go b/core/state_processor_test.go index e6f1246d85c1..723340060f00 100644 --- a/core/state_processor_test.go +++ b/core/state_processor_test.go @@ -58,7 +58,7 @@ func TestStateProcessorErrors(t *testing.T) { ShanghaiBlock: big.NewInt(0), BernoulliBlock: big.NewInt(0), CurieBlock: big.NewInt(0), - DescartesBlock: big.NewInt(0), + DescartesTime: new(uint64), Ethash: new(params.EthashConfig), } signer = types.LatestSigner(config) diff --git a/core/state_transition.go b/core/state_transition.go index eb292ba27e45..b498ca44c5ea 100644 --- a/core/state_transition.go +++ b/core/state_transition.go @@ -358,7 +358,7 @@ func (st *StateTransition) TransitionDb() (*ExecutionResult, error) { var ( msg = st.msg sender = vm.AccountRef(msg.From()) - rules = st.evm.ChainConfig().Rules(st.evm.Context.BlockNumber) + rules = st.evm.ChainConfig().Rules(st.evm.Context.BlockNumber, st.evm.Context.Time.Uint64()) contractCreation = msg.To() == nil ) diff --git a/core/vm/evm.go b/core/vm/evm.go index d6f6a6c8271e..07872c4a950e 100644 --- a/core/vm/evm.go +++ b/core/vm/evm.go @@ -138,7 +138,7 @@ func NewEVM(blockCtx BlockContext, txCtx TxContext, statedb StateDB, chainConfig StateDB: statedb, Config: config, chainConfig: chainConfig, - chainRules: chainConfig.Rules(blockCtx.BlockNumber), + chainRules: chainConfig.Rules(blockCtx.BlockNumber, blockCtx.Time.Uint64()), } evm.interpreter = NewEVMInterpreter(evm, config) return evm diff --git a/core/vm/runtime/runtime.go b/core/vm/runtime/runtime.go index bdfedde8c9ac..8526eebd28b3 100644 --- a/core/vm/runtime/runtime.go +++ b/core/vm/runtime/runtime.go @@ -72,7 +72,7 @@ func setDefaults(cfg *Config) { ShanghaiBlock: new(big.Int), BernoulliBlock: new(big.Int), CurieBlock: new(big.Int), - DescartesBlock: new(big.Int), + DescartesTime: new(uint64), } } @@ -122,7 +122,7 @@ func Execute(code, input []byte, cfg *Config) ([]byte, *state.StateDB, error) { address = common.BytesToAddress([]byte("contract")) vmenv = NewEnv(cfg) sender = vm.AccountRef(cfg.Origin) - rules = cfg.ChainConfig.Rules(vmenv.Context.BlockNumber) + rules = cfg.ChainConfig.Rules(vmenv.Context.BlockNumber, vmenv.Context.Time.Uint64()) ) // Execute the preparatory steps for state transition which includes: // - prepare accessList(post-berlin) @@ -156,7 +156,7 @@ func Create(input []byte, cfg *Config) ([]byte, common.Address, uint64, error) { var ( vmenv = NewEnv(cfg) sender = vm.AccountRef(cfg.Origin) - rules = cfg.ChainConfig.Rules(vmenv.Context.BlockNumber) + rules = cfg.ChainConfig.Rules(vmenv.Context.BlockNumber, vmenv.Context.Time.Uint64()) ) // Execute the preparatory steps for state transition which includes: // - prepare accessList(post-berlin) @@ -185,7 +185,7 @@ func Call(address common.Address, input []byte, cfg *Config) ([]byte, uint64, er vmenv = NewEnv(cfg) sender = cfg.State.GetOrNewStateObject(cfg.Origin) statedb = cfg.State - rules = cfg.ChainConfig.Rules(vmenv.Context.BlockNumber) + rules = cfg.ChainConfig.Rules(vmenv.Context.BlockNumber, vmenv.Context.Time.Uint64()) ) // Execute the preparatory steps for state transition which includes: // - prepare accessList(post-berlin) diff --git a/eth/gasprice/gasprice_test.go b/eth/gasprice/gasprice_test.go index b27046546cfe..5acd93b53157 100644 --- a/eth/gasprice/gasprice_test.go +++ b/eth/gasprice/gasprice_test.go @@ -118,7 +118,7 @@ func newTestBackend(t *testing.T, londonBlock *big.Int, pending bool, pendingTxC config.ShanghaiBlock = londonBlock config.BernoulliBlock = londonBlock config.CurieBlock = londonBlock - config.DescartesBlock = londonBlock + config.DescartesTime = nil engine := ethash.NewFaker() db := rawdb.NewMemoryDatabase() genesis, err := gspec.Commit(db) diff --git a/eth/tracers/js/tracer.go b/eth/tracers/js/tracer.go index 08a88e0de3f8..de375d0a3b05 100644 --- a/eth/tracers/js/tracer.go +++ b/eth/tracers/js/tracer.go @@ -698,7 +698,7 @@ func (jst *jsTracer) CaptureStart(env *vm.EVM, from common.Address, to common.Ad jst.ctx["block"] = env.Context.BlockNumber.Uint64() jst.dbWrapper.db = env.StateDB // Update list of precompiles based on current block - rules := env.ChainConfig().Rules(env.Context.BlockNumber) + rules := env.ChainConfig().Rules(env.Context.BlockNumber, env.Context.Time.Uint64()) jst.activePrecompiles = vm.ActivePrecompiles(rules) // Compute intrinsic gas diff --git a/eth/tracers/native/4byte.go b/eth/tracers/native/4byte.go index 8f94bb975134..0a20d2100205 100644 --- a/eth/tracers/native/4byte.go +++ b/eth/tracers/native/4byte.go @@ -83,7 +83,7 @@ func (t *fourByteTracer) CaptureStart(env *vm.EVM, from common.Address, to commo t.env = env // Update list of precompiles based on current block - rules := env.ChainConfig().Rules(env.Context.BlockNumber) + rules := env.ChainConfig().Rules(env.Context.BlockNumber, env.Context.Time.Uint64()) t.activePrecompiles = vm.ActivePrecompiles(rules) // Save the outer calldata also diff --git a/internal/ethapi/api.go b/internal/ethapi/api.go index 1ff887004df0..67bf83af6bfc 100644 --- a/internal/ethapi/api.go +++ b/internal/ethapi/api.go @@ -1492,7 +1492,7 @@ func AccessList(ctx context.Context, b Backend, blockNrOrHash rpc.BlockNumberOrH to = crypto.CreateAddress(args.from(), uint64(*args.Nonce)) } // Retrieve the precompiles since they don't need to be added to the access list - precompiles := vm.ActivePrecompiles(b.ChainConfig().Rules(header.Number)) + precompiles := vm.ActivePrecompiles(b.ChainConfig().Rules(header.Number, header.Time)) // Create an initial tracer prevTracer := vm.NewAccessListTracer(nil, args.from(), to, precompiles) diff --git a/params/config.go b/params/config.go index d9119790b8e4..5fd5fccea8e7 100644 --- a/params/config.go +++ b/params/config.go @@ -281,7 +281,7 @@ var ( ShanghaiBlock: nil, BernoulliBlock: nil, CurieBlock: nil, - DescartesBlock: nil, + DescartesTime: nil, Clique: &CliqueConfig{ Period: 3, Epoch: 30000, @@ -320,7 +320,7 @@ var ( ShanghaiBlock: big.NewInt(0), BernoulliBlock: big.NewInt(3747132), CurieBlock: big.NewInt(4740239), - DescartesBlock: nil, + DescartesTime: nil, Clique: &CliqueConfig{ Period: 3, Epoch: 30000, @@ -359,7 +359,7 @@ var ( ShanghaiBlock: big.NewInt(0), BernoulliBlock: big.NewInt(5220340), CurieBlock: big.NewInt(7096836), - DescartesBlock: nil, + DescartesTime: nil, Clique: &CliqueConfig{ Period: 3, Epoch: 30000, @@ -404,7 +404,7 @@ var ( ShanghaiBlock: big.NewInt(0), BernoulliBlock: big.NewInt(0), CurieBlock: big.NewInt(0), - DescartesBlock: big.NewInt(0), + DescartesTime: new(uint64), TerminalTotalDifficulty: nil, Ethash: new(EthashConfig), Clique: nil, @@ -447,7 +447,7 @@ var ( ShanghaiBlock: big.NewInt(0), BernoulliBlock: big.NewInt(0), CurieBlock: big.NewInt(0), - DescartesBlock: big.NewInt(0), + DescartesTime: new(uint64), TerminalTotalDifficulty: nil, Ethash: nil, Clique: &CliqueConfig{Period: 0, Epoch: 30000}, @@ -485,7 +485,7 @@ var ( ShanghaiBlock: big.NewInt(0), BernoulliBlock: big.NewInt(0), CurieBlock: big.NewInt(0), - DescartesBlock: big.NewInt(0), + DescartesTime: new(uint64), TerminalTotalDifficulty: nil, Ethash: new(EthashConfig), Clique: nil, @@ -501,7 +501,7 @@ var ( ScrollChainAddress: common.HexToAddress("0x0000000000000000000000000000000000000000"), }, }} - TestRules = TestChainConfig.Rules(new(big.Int)) + TestRules = TestChainConfig.Rules(new(big.Int), 0) TestNoL1DataFeeChainConfig = &ChainConfig{ ChainID: big.NewInt(1), @@ -524,7 +524,7 @@ var ( ShanghaiBlock: big.NewInt(0), BernoulliBlock: big.NewInt(0), CurieBlock: big.NewInt(0), - DescartesBlock: big.NewInt(0), + DescartesTime: new(uint64), TerminalTotalDifficulty: nil, Ethash: new(EthashConfig), Clique: nil, @@ -622,7 +622,7 @@ type ChainConfig struct { ShanghaiBlock *big.Int `json:"shanghaiBlock,omitempty"` // Shanghai switch block (nil = no fork, 0 = already on shanghai) BernoulliBlock *big.Int `json:"bernoulliBlock,omitempty"` // Bernoulli switch block (nil = no fork, 0 = already on bernoulli) CurieBlock *big.Int `json:"curieBlock,omitempty"` // Curie switch block (nil = no fork, 0 = already on curie) - DescartesBlock *big.Int `json:"descartesBlock,omitempty"` // Descartes switch block (nil = no fork, 0 = already on descartes) + DescartesTime *uint64 `json:"descartesTime,omitempty"` // Descartes switch time (nil = no fork, 0 = already on descartes) // TerminalTotalDifficulty is the amount of total difficulty reached by // the network that triggers the consensus upgrade. @@ -759,7 +759,7 @@ func (c *ChainConfig) String() string { c.ShanghaiBlock, c.BernoulliBlock, c.CurieBlock, - c.DescartesBlock, + c.DescartesTime, engine, c.Scroll, ) @@ -853,8 +853,8 @@ func (c *ChainConfig) IsCurie(num *big.Int) bool { } // IsDescartes returns whether num is either equal to the Descartes fork block or greater. -func (c *ChainConfig) IsDescartes(num *big.Int) bool { - return isForked(c.DescartesBlock, num) +func (c *ChainConfig) IsDescartes(now uint64) bool { + return isForkedTime(now, c.DescartesTime) } // IsTerminalPoWBlock returns whether the given block is the last block of PoW stage. @@ -910,7 +910,6 @@ func (c *ChainConfig) CheckConfigForkOrder() error { {name: "shanghaiBlock", block: c.ShanghaiBlock, optional: true}, {name: "bernoulliBlock", block: c.BernoulliBlock, optional: true}, {name: "curieBlock", block: c.CurieBlock, optional: true}, - {name: "descartesBlock", block: c.DescartesBlock, optional: true}, } { if lastFork.name != "" { // Next one must be higher number @@ -995,9 +994,6 @@ func (c *ChainConfig) checkCompatible(newcfg *ChainConfig, head *big.Int) *Confi if isForkIncompatible(c.CurieBlock, newcfg.CurieBlock, head) { return newCompatError("Curie fork block", c.CurieBlock, newcfg.CurieBlock) } - if isForkIncompatible(c.DescartesBlock, newcfg.DescartesBlock, head) { - return newCompatError("Descartes fork block", c.DescartesBlock, newcfg.DescartesBlock) - } return nil } @@ -1015,6 +1011,13 @@ func isForked(s, head *big.Int) bool { return s.Cmp(head) <= 0 } +func isForkedTime(now uint64, forkTime *uint64) bool { + if forkTime == nil { + return false + } + return now >= *forkTime +} + func configNumEqual(x, y *big.Int) bool { if x == nil { return y == nil @@ -1070,7 +1073,7 @@ type Rules struct { } // Rules ensures c's ChainID is not nil. -func (c *ChainConfig) Rules(num *big.Int) Rules { +func (c *ChainConfig) Rules(num *big.Int, time uint64) Rules { chainID := c.ChainID if chainID == nil { chainID = new(big.Int) @@ -1091,6 +1094,6 @@ func (c *ChainConfig) Rules(num *big.Int) Rules { IsShanghai: c.IsShanghai(num), IsBernoulli: c.IsBernoulli(num), IsCurie: c.IsCurie(num), - IsDescartes: c.IsDescartes(num), + IsDescartes: c.IsDescartes(time), } } diff --git a/params/config_test.go b/params/config_test.go index 3c8ebaf4a511..26c8e6662b31 100644 --- a/params/config_test.go +++ b/params/config_test.go @@ -20,6 +20,8 @@ import ( "math/big" "reflect" "testing" + + "github.com/stretchr/testify/require" ) func TestCheckCompatible(t *testing.T) { @@ -96,3 +98,41 @@ func TestCheckCompatible(t *testing.T) { } } } + +func TestIsForkedTime(t *testing.T) { + timePtr := func(t uint64) *uint64 { + return &t + } + + tests := map[string]struct { + forkTime *uint64 + now uint64 + isForked bool + }{ + "not configured": { + forkTime: nil, + isForked: false, + }, + "before fork time": { + forkTime: timePtr(10), + now: 3, + isForked: false, + }, + "on fork time": { + forkTime: timePtr(10), + now: 10, + isForked: true, + }, + "after fork time": { + forkTime: timePtr(10), + now: 11, + isForked: true, + }, + } + + for desc, test := range tests { + t.Run(desc, func(t *testing.T) { + require.Equal(t, test.isForked, isForkedTime(test.now, test.forkTime)) + }) + } +} diff --git a/params/version.go b/params/version.go index 185dd6a22ec5..100539112d5a 100644 --- a/params/version.go +++ b/params/version.go @@ -24,7 +24,7 @@ import ( const ( VersionMajor = 5 // Major version component of the current release VersionMinor = 5 // Minor version component of the current release - VersionPatch = 0 // Patch version component of the current release + VersionPatch = 1 // Patch version component of the current release VersionMeta = "mainnet" // Version metadata to append to the version string )