diff --git a/accounts/abi/bind/precompilebind/precompile_module_template.go b/accounts/abi/bind/precompilebind/precompile_module_template.go index e9dd8e7275..8ae72f641e 100644 --- a/accounts/abi/bind/precompilebind/precompile_module_template.go +++ b/accounts/abi/bind/precompilebind/precompile_module_template.go @@ -12,6 +12,7 @@ package {{.Package}} import ( "fmt" + "math/big" "github.com/ava-labs/subnet-evm/precompile/precompileconfig" "github.com/ava-labs/subnet-evm/precompile/contract" @@ -59,7 +60,7 @@ func (*configurator) MakeConfig() precompileconfig.Config { // This function is called by the EVM once per precompile contract activation. // You can use this function to set up your precompile contract's initial state, // by using the [cfg] config and [state] stateDB. -func (*configurator) Configure(chainConfig precompileconfig.ChainConfig, cfg precompileconfig.Config, state contract.StateDB, blockContext contract.ConfigurationBlockContext) error { +func (*configurator) Configure(chainConfig precompileconfig.ChainConfig, cfg precompileconfig.Config, state contract.StateDB, blockNumber *big.Int, blockTime uint64) error { // CUSTOM CODE STARTS HERE {{- if .Contract.AllowList}} config, ok := cfg.(*Config) @@ -68,7 +69,7 @@ func (*configurator) Configure(chainConfig precompileconfig.ChainConfig, cfg pre } // AllowList is activated for this precompile. Configuring allowlist addresses here. - return config.AllowListConfig.Configure(chainConfig, ContractAddress, state, blockContext) + return config.AllowListConfig.Configure(chainConfig, ContractAddress, state) {{- else}} if _, ok := cfg.(*Config); !ok { return fmt.Errorf("expected config type %T, got %T: %v", &Config{}, cfg, cfg) diff --git a/core/chain_makers.go b/core/chain_makers.go index 6b8467dc3c..8bf3964575 100644 --- a/core/chain_makers.go +++ b/core/chain_makers.go @@ -284,7 +284,7 @@ func GenerateChain(config *params.ChainConfig, parent *types.Block, engine conse b := &BlockGen{i: i, cm: cm, parent: parent, statedb: statedb, engine: engine} b.header = cm.makeHeader(parent, gap, statedb, b.engine) - err := ApplyUpgrades(config, &parent.Header().Time, b, statedb) + err := ApplyUpgrades(config, &parent.Header().Time, b.Number(), b.Timestamp(), statedb) if err != nil { return nil, nil, fmt.Errorf("failed to configure precompiles %w", err) } diff --git a/core/genesis.go b/core/genesis.go index e08f186981..1fe32d7d45 100644 --- a/core/genesis.go +++ b/core/genesis.go @@ -278,7 +278,7 @@ 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) + err = ApplyPrecompileActivations(g.Config, nil, head.Number, head.Time, 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 7853810f43..9c154bd806 100644 --- a/core/state_processor.go +++ b/core/state_processor.go @@ -36,7 +36,6 @@ import ( "github.com/ava-labs/subnet-evm/core/types" "github.com/ava-labs/subnet-evm/core/vm" "github.com/ava-labs/subnet-evm/params" - "github.com/ava-labs/subnet-evm/precompile/contract" "github.com/ava-labs/subnet-evm/precompile/modules" "github.com/ava-labs/subnet-evm/stateupgrade" "github.com/ethereum/go-ethereum/common" @@ -82,7 +81,7 @@ 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) + err := ApplyUpgrades(p.config, &parent.Time, header.Number, header.Time, 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 @@ -208,14 +207,13 @@ func ProcessBeaconBlockRoot(beaconRoot common.Hash, vmenv *vm.EVM, statedb *stat // to apply the necessary state transitions for the upgrade. // This function is called within genesis setup to configure the starting state for precompiles enabled at genesis. // In block processing and building, ApplyUpgrades is called instead which also applies state upgrades. -func ApplyPrecompileActivations(c *params.ChainConfig, parentTimestamp *uint64, blockContext contract.ConfigurationBlockContext, statedb *state.StateDB) error { - blockTimestamp := blockContext.Timestamp() +func ApplyPrecompileActivations(c *params.ChainConfig, parentTimestamp *uint64, blockNumber *big.Int, blockTime uint64, statedb *state.StateDB) error { // Note: RegisteredModules returns precompiles sorted by module addresses. // This ensures that the order we call Configure for each precompile is consistent. // This ensures even if precompiles read/write state other than their own they will observe // an identical global state in a deterministic order when they are configured. for _, module := range modules.RegisteredModules() { - for _, activatingConfig := range c.GetActivatingPrecompileConfigs(module.Address, parentTimestamp, blockTimestamp, c.PrecompileUpgrades) { + for _, activatingConfig := range c.GetActivatingPrecompileConfigs(module.Address, parentTimestamp, blockTime, c.PrecompileUpgrades) { // If this transition activates the upgrade, configure the stateful precompile. // (or deconfigure it if it is being disabled.) if activatingConfig.IsDisabled() { @@ -243,7 +241,7 @@ func ApplyPrecompileActivations(c *params.ChainConfig, parentTimestamp *uint64, // can be called from within Solidity contracts. Solidity adds a check before invoking a contract to ensure // that it does not attempt to invoke a non-existent contract. statedb.SetCode(module.Address, []byte{0x1}) - if err := module.Configure(c, activatingConfig, statedb, blockContext); err != nil { + if err := module.Configure(c, activatingConfig, statedb, blockNumber, blockTime); err != nil { return fmt.Errorf("could not configure precompile, name: %s, reason: %w", module.ConfigKey, err) } } @@ -255,11 +253,11 @@ func ApplyPrecompileActivations(c *params.ChainConfig, parentTimestamp *uint64, // applyStateUpgrades checks if any of the state upgrades specified by the chain config are activated by the block // transition from [parentTimestamp] to the timestamp set in [header]. If this is the case, it calls [Configure] // to apply the necessary state transitions for the upgrade. -func applyStateUpgrades(c *params.ChainConfig, parentTimestamp *uint64, blockContext contract.ConfigurationBlockContext, statedb *state.StateDB) error { +func applyStateUpgrades(c *params.ChainConfig, parentTimestamp *uint64, blockNumber *big.Int, blockTime uint64, statedb *state.StateDB) error { // Apply state upgrades - for _, upgrade := range c.GetActivatingStateUpgrades(parentTimestamp, blockContext.Timestamp(), c.StateUpgrades) { - log.Info("Applying state upgrade", "blockNumber", blockContext.Number(), "upgrade", upgrade) - if err := stateupgrade.Configure(&upgrade, c, statedb, blockContext); err != nil { + for _, upgrade := range c.GetActivatingStateUpgrades(parentTimestamp, blockTime, c.StateUpgrades) { + log.Info("Applying state upgrade", "blockNumber", blockNumber, "upgrade", upgrade) + if err := stateupgrade.Configure(&upgrade, c, statedb, blockNumber); err != nil { return fmt.Errorf("could not configure state upgrade: %w", err) } } @@ -272,9 +270,9 @@ func applyStateUpgrades(c *params.ChainConfig, parentTimestamp *uint64, blockCon // This function is called: // - in block processing to update the state when processing a block. // - in the miner to apply the state upgrades when producing a block. -func ApplyUpgrades(c *params.ChainConfig, parentTimestamp *uint64, blockContext contract.ConfigurationBlockContext, statedb *state.StateDB) error { - if err := ApplyPrecompileActivations(c, parentTimestamp, blockContext, statedb); err != nil { +func ApplyUpgrades(c *params.ChainConfig, parentTimestamp *uint64, blockNumber *big.Int, blockTime uint64, statedb *state.StateDB) error { + if err := ApplyPrecompileActivations(c, parentTimestamp, blockNumber, blockTime, statedb); err != nil { return err } - return applyStateUpgrades(c, parentTimestamp, blockContext, statedb) + return applyStateUpgrades(c, parentTimestamp, blockNumber, blockTime, statedb) } diff --git a/core/types/block.go b/core/types/block.go index 81393e52ee..a18ea6b3f0 100644 --- a/core/types/block.go +++ b/core/types/block.go @@ -317,7 +317,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/core/vm/evm.go b/core/vm/evm.go index 90a9ff4c9f..11e08907df 100644 --- a/core/vm/evm.go +++ b/core/vm/evm.go @@ -48,7 +48,7 @@ import ( var ( _ contract.AccessibleState = &EVM{} - _ contract.BlockContext = &BlockContext{} + _ contract.BlockContext = &PrecompileBlockContext{} ) // IsProhibited returns true if [addr] is in the prohibited list of addresses which should @@ -125,15 +125,17 @@ type BlockContext struct { BlobBaseFee *big.Int // Provides information for BLOBBASEFEE (0 if vm runs with NoBaseFee flag and 0 blob gas price) } -func (b *BlockContext) Number() *big.Int { +type PrecompileBlockContext struct{ BlockContext } + +func (b *PrecompileBlockContext) Number() *big.Int { return b.BlockNumber } -func (b *BlockContext) Timestamp() uint64 { - return b.Time +func (b *PrecompileBlockContext) Time() uint64 { + return b.BlockContext.Time } -func (b *BlockContext) GetPredicateResults(txHash common.Hash, address common.Address) []byte { +func (b *PrecompileBlockContext) GetPredicateResults(txHash common.Hash, address common.Address) []byte { if b.PredicateResults == nil { return nil } @@ -242,7 +244,7 @@ func (evm *EVM) GetStateDB() contract.StateDB { // GetBlockContext returns the evm's BlockContext func (evm *EVM) GetBlockContext() contract.BlockContext { - return &evm.Context + return &PrecompileBlockContext{evm.Context} } // Interpreter returns the current interpreter diff --git a/eth/state_accessor.go b/eth/state_accessor.go index 89876b182a..84ce859c7f 100644 --- a/eth/state_accessor.go +++ b/eth/state_accessor.go @@ -284,7 +284,7 @@ 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) + err = core.ApplyUpgrades(eth.blockchain.Config(), &parent.Header().Time, nextBlock.Number(), nextBlock.Time(), statedb) if err != nil { release() return nil, nil, err diff --git a/eth/tracers/api.go b/eth/tracers/api.go index 1be62dacaa..9e9cd79deb 100644 --- a/eth/tracers/api.go +++ b/eth/tracers/api.go @@ -965,7 +965,7 @@ 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, &vmctx, statedb) + err = core.ApplyUpgrades(api.backend.ChainConfig(), &originalTime, vmctx.BlockNumber, vmctx.Time, statedb) if err != nil { return nil, err } diff --git a/eth/tracers/api_test.go b/eth/tracers/api_test.go index 1f1b32492e..5f374c532c 100644 --- a/eth/tracers/api_test.go +++ b/eth/tracers/api_test.go @@ -181,7 +181,7 @@ 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) + err = core.ApplyUpgrades(b.chainConfig, &parent.Header().Time, nextBlock.Number(), nextBlock.Time(), statedb) if err != nil { release() return nil, nil, err diff --git a/miner/worker.go b/miner/worker.go index b7b5e7b9b8..f3f492be1a 100644 --- a/miner/worker.go +++ b/miner/worker.go @@ -227,7 +227,7 @@ 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) + err = core.ApplyUpgrades(w.chainConfig, &parent.Time, header.Number, header.Time, 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 1c37e98086..ea6ddba807 100644 --- a/plugin/evm/block.go +++ b/plugin/evm/block.go @@ -62,7 +62,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(), b.ethBlock.Timestamp()) + rules := b.vm.chainConfig.Rules(b.ethBlock.Number(), b.ethBlock.Time()) if err := b.handlePrecompileAccept(rules); err != nil { return err } @@ -153,7 +153,7 @@ func (b *Block) Verify(context.Context) error { // ShouldVerifyWithContext implements the block.WithVerifyContext interface func (b *Block) ShouldVerifyWithContext(context.Context) (bool, error) { - predicates := b.vm.chainConfig.Rules(b.ethBlock.Number(), b.ethBlock.Timestamp()).Predicaters + predicates := b.vm.chainConfig.Rules(b.ethBlock.Number(), b.ethBlock.Time()).Predicaters // Short circuit early if there are no predicates to verify if len(predicates) == 0 { return false, nil @@ -219,7 +219,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(), b.ethBlock.Timestamp()) + rules := b.vm.chainConfig.Rules(b.ethBlock.Number(), b.ethBlock.Time()) switch { case !rules.IsDurango && rules.PredicatersExist(): diff --git a/plugin/evm/vm_test.go b/plugin/evm/vm_test.go index cb06575af6..9c2361369c 100644 --- a/plugin/evm/vm_test.go +++ b/plugin/evm/vm_test.go @@ -2393,7 +2393,7 @@ func TestTxAllowListDisablePrecompile(t *testing.T) { require.Equal(t, signedTx0.Hash(), txs[0].Hash()) // verify the issued block is after the network upgrade - require.GreaterOrEqual(t, int64(block.Timestamp()), disableAllowListTimestamp.Unix()) + require.GreaterOrEqual(t, int64(block.Time()), disableAllowListTimestamp.Unix()) <-newTxPoolHeadChan // wait for new head in tx pool @@ -2772,7 +2772,7 @@ func TestRewardManagerPrecompileSetRewardAddress(t *testing.T) { // to determine the coinbase for this block before full deactivation in the // next block. require.Equal(t, testAddr, ethBlock.Coinbase()) - require.GreaterOrEqual(t, int64(ethBlock.Timestamp()), disableTime.Unix()) + require.GreaterOrEqual(t, int64(ethBlock.Time()), disableTime.Unix()) vm.clock.Set(vm.clock.Time().Add(3 * time.Hour)) // let time pass to decrease gas price // issue another block to verify that the reward manager is disabled @@ -2792,7 +2792,7 @@ func TestRewardManagerPrecompileSetRewardAddress(t *testing.T) { // reward manager was disabled at previous block // so this block should revert back to enabling fee recipients require.Equal(t, etherBase, ethBlock.Coinbase()) - require.GreaterOrEqual(t, int64(ethBlock.Timestamp()), disableTime.Unix()) + require.GreaterOrEqual(t, int64(ethBlock.Time()), disableTime.Unix()) // Verify that Blackhole has received fees blkState, err = vm.blockChain.StateAt(ethBlock.Root()) @@ -2906,7 +2906,7 @@ func TestRewardManagerPrecompileAllowFeeRecipients(t *testing.T) { require.Equal(t, newHead.Head.Hash(), common.Hash(blk.ID())) ethBlock = blk.(*chain.BlockWrapper).Block.(*Block).ethBlock require.Equal(t, etherBase, ethBlock.Coinbase()) // reward address was activated at previous block - require.GreaterOrEqual(t, int64(ethBlock.Timestamp()), disableTime.Unix()) + require.GreaterOrEqual(t, int64(ethBlock.Time()), disableTime.Unix()) vm.clock.Set(vm.clock.Time().Add(3 * time.Hour)) // let time pass so that gas price is reduced tx2 = types.NewTransaction(uint64(2), testEthAddrs[0], big.NewInt(2), 21000, big.NewInt(testMinGasPrice), nil) @@ -2923,7 +2923,7 @@ func TestRewardManagerPrecompileAllowFeeRecipients(t *testing.T) { require.Equal(t, newHead.Head.Hash(), common.Hash(blk.ID())) ethBlock = blk.(*chain.BlockWrapper).Block.(*Block).ethBlock require.Equal(t, constants.BlackholeAddr, ethBlock.Coinbase()) // reward address was activated at previous block - require.Greater(t, int64(ethBlock.Timestamp()), disableTime.Unix()) + require.Greater(t, int64(ethBlock.Time()), disableTime.Unix()) // Verify that Blackhole has received fees blkState, err = vm.blockChain.StateAt(ethBlock.Root()) diff --git a/plugin/evm/vm_upgrade_bytes_test.go b/plugin/evm/vm_upgrade_bytes_test.go index f8043e3499..61cbf46dda 100644 --- a/plugin/evm/vm_upgrade_bytes_test.go +++ b/plugin/evm/vm_upgrade_bytes_test.go @@ -145,7 +145,7 @@ func TestVMUpgradeBytesPrecompile(t *testing.T) { assert.Equal(t, signedTx0.Hash(), txs[0].Hash()) // verify the issued block is after the network upgrade - assert.GreaterOrEqual(t, int64(block.Timestamp()), disableAllowListTimestamp.Unix()) + assert.GreaterOrEqual(t, int64(block.Time()), disableAllowListTimestamp.Unix()) <-newTxPoolHeadChan // wait for new head in tx pool diff --git a/precompile/allowlist/allowlist_test.go b/precompile/allowlist/allowlist_test.go index ebbcf6b69e..78d6696e35 100644 --- a/precompile/allowlist/allowlist_test.go +++ b/precompile/allowlist/allowlist_test.go @@ -4,6 +4,7 @@ package allowlist import ( + "math/big" "testing" "github.com/ava-labs/subnet-evm/core/state" @@ -49,10 +50,11 @@ func (d *dummyConfigurator) Configure( chainConfig precompileconfig.ChainConfig, precompileConfig precompileconfig.Config, state contract.StateDB, - blockContext contract.ConfigurationBlockContext, + blockNumber *big.Int, + blockTime uint64, ) error { cfg := precompileConfig.(*dummyConfig) - return cfg.AllowListConfig.Configure(chainConfig, dummyAddr, state, blockContext) + return cfg.AllowListConfig.Configure(chainConfig, dummyAddr, state) } func TestAllowListRun(t *testing.T) { diff --git a/precompile/allowlist/config.go b/precompile/allowlist/config.go index 520021f511..a410ccc8fa 100644 --- a/precompile/allowlist/config.go +++ b/precompile/allowlist/config.go @@ -21,8 +21,8 @@ type AllowListConfig struct { } // Configure initializes the address space of [precompileAddr] by initializing the role of each of -// the addresses in [AllowListAdmins]. -func (c *AllowListConfig) Configure(chainConfig precompileconfig.ChainConfig, precompileAddr common.Address, state contract.StateDB, blockContext contract.ConfigurationBlockContext) error { +// the addresses in [AllowListConfig]. +func (c *AllowListConfig) Configure(chainConfig precompileconfig.ChainConfig, precompileAddr common.Address, state contract.StateDB) error { for _, enabledAddr := range c.EnabledAddresses { SetAllowListRole(state, precompileAddr, enabledAddr, EnabledRole) } diff --git a/precompile/contract/interfaces.go b/precompile/contract/interfaces.go index 2cb3693fbd..c542ad0c74 100644 --- a/precompile/contract/interfaces.go +++ b/precompile/contract/interfaces.go @@ -52,14 +52,9 @@ type AccessibleState interface { GetChainConfig() precompileconfig.ChainConfig } -// ConfigurationBlockContext defines the interface required to configure a precompile. -type ConfigurationBlockContext interface { - Number() *big.Int - Timestamp() uint64 -} - type BlockContext interface { - ConfigurationBlockContext + Number() *big.Int + Time() uint64 // GetPredicateResults returns an arbitrary byte array result of verifying the predicates // of the given transaction, precompile address pair. GetPredicateResults(txHash common.Hash, precompileAddress common.Address) []byte @@ -71,6 +66,7 @@ type Configurator interface { chainConfig precompileconfig.ChainConfig, precompileconfig precompileconfig.Config, state StateDB, - blockContext ConfigurationBlockContext, + blockNumber *big.Int, + blockTime uint64, ) error } diff --git a/precompile/contract/mocks.go b/precompile/contract/mocks.go index c82db74e3f..2a59039140 100644 --- a/precompile/contract/mocks.go +++ b/precompile/contract/mocks.go @@ -71,18 +71,18 @@ func (mr *MockBlockContextMockRecorder) Number() *gomock.Call { return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Number", reflect.TypeOf((*MockBlockContext)(nil).Number)) } -// Timestamp mocks base method. -func (m *MockBlockContext) Timestamp() uint64 { +// Time mocks base method. +func (m *MockBlockContext) Time() uint64 { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "Timestamp") + ret := m.ctrl.Call(m, "Time") ret0, _ := ret[0].(uint64) return ret0 } -// Timestamp indicates an expected call of Timestamp. -func (mr *MockBlockContextMockRecorder) Timestamp() *gomock.Call { +// Time indicates an expected call of Time. +func (mr *MockBlockContextMockRecorder) Time() *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Timestamp", reflect.TypeOf((*MockBlockContext)(nil).Timestamp)) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Time", reflect.TypeOf((*MockBlockContext)(nil).Time)) } // MockAccessibleState is a mock of AccessibleState interface. diff --git a/precompile/contract/utils.go b/precompile/contract/utils.go index 4b7eff94bb..2e7e2fa152 100644 --- a/precompile/contract/utils.go +++ b/precompile/contract/utils.go @@ -60,5 +60,5 @@ func ParseABI(rawABI string) abi.ABI { } func IsDurangoActivated(evm AccessibleState) bool { - return evm.GetChainConfig().IsDurango(evm.GetBlockContext().Timestamp()) + return evm.GetChainConfig().IsDurango(evm.GetBlockContext().Time()) } diff --git a/precompile/contracts/deployerallowlist/module.go b/precompile/contracts/deployerallowlist/module.go index 17f7431ab0..14bdff22d3 100644 --- a/precompile/contracts/deployerallowlist/module.go +++ b/precompile/contracts/deployerallowlist/module.go @@ -5,6 +5,7 @@ package deployerallowlist import ( "fmt" + "math/big" "github.com/ava-labs/subnet-evm/precompile/contract" "github.com/ava-labs/subnet-evm/precompile/modules" @@ -43,10 +44,10 @@ func (*configurator) MakeConfig() precompileconfig.Config { // Configure configures [state] with the given [cfg] precompileconfig. // This function is called by the EVM once per precompile contract activation. -func (c *configurator) Configure(chainConfig precompileconfig.ChainConfig, cfg precompileconfig.Config, state contract.StateDB, blockContext contract.ConfigurationBlockContext) error { +func (c *configurator) Configure(chainConfig precompileconfig.ChainConfig, cfg precompileconfig.Config, state contract.StateDB, blockNumber *big.Int, blockTime uint64) error { config, ok := cfg.(*Config) if !ok { return fmt.Errorf("expected config type %T, got %T: %v", &Config{}, cfg, cfg) } - return config.AllowListConfig.Configure(chainConfig, ContractAddress, state, blockContext) + return config.AllowListConfig.Configure(chainConfig, ContractAddress, state) } diff --git a/precompile/contracts/feemanager/contract.go b/precompile/contracts/feemanager/contract.go index 2e7cad7ec5..b29d1d0479 100644 --- a/precompile/contracts/feemanager/contract.go +++ b/precompile/contracts/feemanager/contract.go @@ -117,7 +117,7 @@ func GetFeeConfigLastChangedAt(stateDB contract.StateDB) *big.Int { // StoreFeeConfig stores given [feeConfig] and block number in the [blockContext] to the [stateDB]. // A validation on [feeConfig] is done before storing. -func StoreFeeConfig(stateDB contract.StateDB, feeConfig commontype.FeeConfig, blockContext contract.ConfigurationBlockContext) error { +func StoreFeeConfig(stateDB contract.StateDB, feeConfig commontype.FeeConfig, blockNumber *big.Int) error { if err := feeConfig.Verify(); err != nil { return fmt.Errorf("cannot verify fee config: %w", err) } @@ -148,7 +148,6 @@ func StoreFeeConfig(stateDB contract.StateDB, feeConfig commontype.FeeConfig, bl stateDB.SetState(ContractAddress, common.Hash{byte(i)}, input) } - blockNumber := blockContext.Number() if blockNumber == nil { return fmt.Errorf("blockNumber cannot be nil") } @@ -249,7 +248,8 @@ func setFeeConfig(accessibleState contract.AccessibleState, caller common.Addres ) } - if err := StoreFeeConfig(stateDB, feeConfig, accessibleState.GetBlockContext()); err != nil { + blockNumber := accessibleState.GetBlockContext().Number() + if err := StoreFeeConfig(stateDB, feeConfig, blockNumber); err != nil { return nil, remainingGas, err } diff --git a/precompile/contracts/feemanager/contract_test.go b/precompile/contracts/feemanager/contract_test.go index ee4c6cf1f7..90df1c6e01 100644 --- a/precompile/contracts/feemanager/contract_test.go +++ b/precompile/contracts/feemanager/contract_test.go @@ -144,7 +144,7 @@ var ( ExpectedRes: []byte{}, SetupBlockContext: func(mbc *contract.MockBlockContext) { mbc.EXPECT().Number().Return(testBlockNumber).AnyTimes() - mbc.EXPECT().Timestamp().Return(uint64(0)).AnyTimes() + mbc.EXPECT().Time().Return(uint64(0)).AnyTimes() }, AfterHook: func(t testing.TB, state contract.StateDB) { feeConfig := GetStoredFeeConfig(state) @@ -159,10 +159,8 @@ var ( "get fee config from non-enabled address": { Caller: allowlist.TestNoRoleAddr, BeforeHook: func(t testing.TB, state contract.StateDB) { - blockContext := contract.NewMockBlockContext(gomock.NewController(t)) - blockContext.EXPECT().Number().Return(big.NewInt(6)).Times(1) allowlist.SetDefaultRoles(Module.Address)(t, state) - err := StoreFeeConfig(state, testFeeConfig, blockContext) + err := StoreFeeConfig(state, testFeeConfig, big.NewInt(6)) require.NoError(t, err) }, InputFn: func(t testing.TB) []byte { @@ -210,6 +208,7 @@ var ( }(), SetupBlockContext: func(mbc *contract.MockBlockContext) { mbc.EXPECT().Number().Return(testBlockNumber) + mbc.EXPECT().Time().Return(uint64(0)) // not used }, AfterHook: func(t testing.TB, state contract.StateDB) { feeConfig := GetStoredFeeConfig(state) @@ -221,10 +220,8 @@ var ( "get last changed at from non-enabled address": { Caller: allowlist.TestNoRoleAddr, BeforeHook: func(t testing.TB, state contract.StateDB) { - blockContext := contract.NewMockBlockContext(gomock.NewController(t)) - blockContext.EXPECT().Number().Return(testBlockNumber).Times(1) allowlist.SetDefaultRoles(Module.Address)(t, state) - err := StoreFeeConfig(state, testFeeConfig, blockContext) + err := StoreFeeConfig(state, testFeeConfig, testBlockNumber) require.NoError(t, err) }, InputFn: func(t testing.TB) []byte { @@ -321,7 +318,7 @@ var ( ExpectedErr: ErrInvalidLen.Error(), SetupBlockContext: func(mbc *contract.MockBlockContext) { mbc.EXPECT().Number().Return(testBlockNumber).AnyTimes() - mbc.EXPECT().Timestamp().Return(uint64(0)).AnyTimes() + mbc.EXPECT().Time().Return(uint64(0)).AnyTimes() }, }, "set config with extra padded bytes should succeed with Durango": { @@ -344,7 +341,7 @@ var ( ExpectedRes: []byte{}, SetupBlockContext: func(mbc *contract.MockBlockContext) { mbc.EXPECT().Number().Return(testBlockNumber).AnyTimes() - mbc.EXPECT().Timestamp().Return(uint64(0)).AnyTimes() + mbc.EXPECT().Time().Return(uint64(0)).AnyTimes() }, AfterHook: func(t testing.TB, state contract.StateDB) { feeConfig := GetStoredFeeConfig(state) @@ -371,7 +368,7 @@ var ( ReadOnly: false, SetupBlockContext: func(mbc *contract.MockBlockContext) { mbc.EXPECT().Number().Return(testBlockNumber).AnyTimes() - mbc.EXPECT().Timestamp().Return(uint64(0)).AnyTimes() + mbc.EXPECT().Time().Return(uint64(0)).AnyTimes() }, }, "setFeeConfig regression test should succeed after Durango": { @@ -388,7 +385,7 @@ var ( ExpectedRes: []byte{}, SetupBlockContext: func(mbc *contract.MockBlockContext) { mbc.EXPECT().Number().Return(testBlockNumber).AnyTimes() - mbc.EXPECT().Timestamp().Return(uint64(0)).AnyTimes() + mbc.EXPECT().Time().Return(uint64(0)).AnyTimes() }, AfterHook: func(t testing.TB, state contract.StateDB) { feeConfig := GetStoredFeeConfig(state) diff --git a/precompile/contracts/feemanager/module.go b/precompile/contracts/feemanager/module.go index e67e5e1115..0198329aba 100644 --- a/precompile/contracts/feemanager/module.go +++ b/precompile/contracts/feemanager/module.go @@ -5,6 +5,7 @@ package feemanager import ( "fmt" + "math/big" "github.com/ava-labs/subnet-evm/precompile/contract" "github.com/ava-labs/subnet-evm/precompile/modules" @@ -46,22 +47,23 @@ func (*configurator) MakeConfig() precompileconfig.Config { // Configure configures [state] with the given [cfg] precompileconfig. // This function is called by the EVM once per precompile contract activation. -func (*configurator) Configure(chainConfig precompileconfig.ChainConfig, cfg precompileconfig.Config, state contract.StateDB, blockContext contract.ConfigurationBlockContext) error { +func (*configurator) Configure(chainConfig precompileconfig.ChainConfig, cfg precompileconfig.Config, state contract.StateDB, blockNumber *big.Int, blockTime uint64) error { config, ok := cfg.(*Config) if !ok { return fmt.Errorf("expected config type %T, got %T: %v", &Config{}, cfg, cfg) } + // Store the initial fee config into the state when the fee manager activates. if config.InitialFeeConfig != nil { - if err := StoreFeeConfig(state, *config.InitialFeeConfig, blockContext); err != nil { + if err := StoreFeeConfig(state, *config.InitialFeeConfig, blockNumber); err != nil { // This should not happen since we already checked this config with Verify() return fmt.Errorf("cannot configure given initial fee config: %w", err) } } else { - if err := StoreFeeConfig(state, chainConfig.GetFeeConfig(), blockContext); err != nil { + if err := StoreFeeConfig(state, chainConfig.GetFeeConfig(), blockNumber); err != nil { // This should not happen since we already checked the chain config in the genesis creation. return fmt.Errorf("cannot configure fee config in chain config: %w", err) } } - return config.AllowListConfig.Configure(chainConfig, ContractAddress, state, blockContext) + return config.AllowListConfig.Configure(chainConfig, ContractAddress, state) } diff --git a/precompile/contracts/nativeminter/module.go b/precompile/contracts/nativeminter/module.go index 02529e2432..590dd8413d 100644 --- a/precompile/contracts/nativeminter/module.go +++ b/precompile/contracts/nativeminter/module.go @@ -46,7 +46,7 @@ func (*configurator) MakeConfig() precompileconfig.Config { // Configure configures [state] with the given [cfg] precompileconfig. // This function is called by the EVM once per precompile contract activation. -func (*configurator) Configure(chainConfig precompileconfig.ChainConfig, cfg precompileconfig.Config, state contract.StateDB, blockContext contract.ConfigurationBlockContext) error { +func (*configurator) Configure(chainConfig precompileconfig.ChainConfig, cfg precompileconfig.Config, state contract.StateDB, blockNumber *big.Int, blockTime uint64) error { config, ok := cfg.(*Config) if !ok { return fmt.Errorf("expected config type %T, got %T: %v", &Config{}, cfg, cfg) @@ -59,5 +59,5 @@ func (*configurator) Configure(chainConfig precompileconfig.ChainConfig, cfg pre } } - return config.AllowListConfig.Configure(chainConfig, ContractAddress, state, blockContext) + return config.AllowListConfig.Configure(chainConfig, ContractAddress, state) } diff --git a/precompile/contracts/rewardmanager/module.go b/precompile/contracts/rewardmanager/module.go index 272547c212..5086b310a5 100644 --- a/precompile/contracts/rewardmanager/module.go +++ b/precompile/contracts/rewardmanager/module.go @@ -5,6 +5,7 @@ package rewardmanager import ( "fmt" + "math/big" "github.com/ava-labs/subnet-evm/precompile/contract" "github.com/ava-labs/subnet-evm/precompile/modules" @@ -49,7 +50,7 @@ func (*configurator) MakeConfig() precompileconfig.Config { // This function is called by the EVM once per precompile contract activation. // You can use this function to set up your precompile contract's initial state, // by using the [cfg] config and [state] stateDB. -func (*configurator) Configure(chainConfig precompileconfig.ChainConfig, cfg precompileconfig.Config, state contract.StateDB, blockContext contract.ConfigurationBlockContext) error { +func (*configurator) Configure(chainConfig precompileconfig.ChainConfig, cfg precompileconfig.Config, state contract.StateDB, blockNumber *big.Int, blockTime uint64) error { config, ok := cfg.(*Config) if !ok { return fmt.Errorf("expected config type %T, got %T: %v", &Config{}, cfg, cfg) @@ -66,5 +67,5 @@ func (*configurator) Configure(chainConfig precompileconfig.ChainConfig, cfg pre // default to disabling rewards DisableFeeRewards(state) } - return config.AllowListConfig.Configure(chainConfig, ContractAddress, state, blockContext) + return config.AllowListConfig.Configure(chainConfig, ContractAddress, state) } diff --git a/precompile/contracts/txallowlist/module.go b/precompile/contracts/txallowlist/module.go index f7333613c7..18f879b612 100644 --- a/precompile/contracts/txallowlist/module.go +++ b/precompile/contracts/txallowlist/module.go @@ -5,6 +5,7 @@ package txallowlist import ( "fmt" + "math/big" "github.com/ava-labs/subnet-evm/precompile/contract" "github.com/ava-labs/subnet-evm/precompile/modules" @@ -43,10 +44,10 @@ func (*configurator) MakeConfig() precompileconfig.Config { // Configure configures [state] with the given [cfg] precompileconfig. // This function is called by the EVM once per precompile contract activation. -func (*configurator) Configure(chainConfig precompileconfig.ChainConfig, cfg precompileconfig.Config, state contract.StateDB, blockContext contract.ConfigurationBlockContext) error { +func (*configurator) Configure(chainConfig precompileconfig.ChainConfig, cfg precompileconfig.Config, state contract.StateDB, blockNumber *big.Int, blockTime uint64) error { config, ok := cfg.(*Config) if !ok { return fmt.Errorf("expected config type %T, got %T: %v", &Config{}, cfg, cfg) } - return config.AllowListConfig.Configure(chainConfig, ContractAddress, state, blockContext) + return config.AllowListConfig.Configure(chainConfig, ContractAddress, state) } diff --git a/precompile/contracts/warp/module.go b/precompile/contracts/warp/module.go index 37b7451184..c5cd8e2630 100644 --- a/precompile/contracts/warp/module.go +++ b/precompile/contracts/warp/module.go @@ -5,6 +5,7 @@ package warp import ( "fmt" + "math/big" "github.com/ava-labs/subnet-evm/precompile/contract" "github.com/ava-labs/subnet-evm/precompile/modules" @@ -47,7 +48,7 @@ func (*configurator) MakeConfig() precompileconfig.Config { } // Configure is a no-op for warp since it does not need to store any information in the state -func (*configurator) Configure(chainConfig precompileconfig.ChainConfig, cfg precompileconfig.Config, state contract.StateDB, _ contract.ConfigurationBlockContext) error { +func (*configurator) Configure(chainConfig precompileconfig.ChainConfig, cfg precompileconfig.Config, state contract.StateDB, blockNumber *big.Int, blockTime uint64) error { if _, ok := cfg.(*Config); !ok { return fmt.Errorf("expected config type %T, got %T: %v", &Config{}, cfg, cfg) } diff --git a/precompile/testutils/test_precompile.go b/precompile/testutils/test_precompile.go index c1a1eac813..cb2739c978 100644 --- a/precompile/testutils/test_precompile.go +++ b/precompile/testutils/test_precompile.go @@ -106,7 +106,7 @@ func (test PrecompileTest) setup(t testing.TB, module modules.Module, state cont test.SetupBlockContext(blockContext) } else { blockContext.EXPECT().Number().Return(big.NewInt(0)).AnyTimes() - blockContext.EXPECT().Timestamp().Return(uint64(time.Now().Unix())).AnyTimes() + blockContext.EXPECT().Time().Return(uint64(time.Now().Unix())).AnyTimes() } snowContext := utils.TestSnowContext() @@ -117,7 +117,7 @@ func (test PrecompileTest) setup(t testing.TB, module modules.Module, state cont accessibleState.EXPECT().GetChainConfig().Return(chainConfig).AnyTimes() if test.Config != nil { - err := module.Configure(chainConfig, test.Config, state, blockContext) + err := module.Configure(chainConfig, test.Config, state, blockContext.Number(), blockContext.Time()) require.NoError(t, err) } diff --git a/stateupgrade/state_upgrade.go b/stateupgrade/state_upgrade.go index 65a1f2dc69..f767e72e14 100644 --- a/stateupgrade/state_upgrade.go +++ b/stateupgrade/state_upgrade.go @@ -12,8 +12,8 @@ import ( ) // Configure applies the state upgrade to the state. -func Configure(stateUpgrade *params.StateUpgrade, chainConfig ChainContext, state StateDB, blockContext BlockContext) error { - isEIP158 := chainConfig.IsEIP158(blockContext.Number()) +func Configure(stateUpgrade *params.StateUpgrade, chainConfig ChainContext, state StateDB, blockNumber *big.Int) error { + isEIP158 := chainConfig.IsEIP158(blockNumber) for account, upgrade := range stateUpgrade.StateUpgradeAccounts { if err := upgradeAccount(account, upgrade, state, isEIP158); err != nil { return err