diff --git a/consensus/dummy/consensus.go b/consensus/dummy/consensus.go index eb1fdd4930..8ab2f1c399 100644 --- a/consensus/dummy/consensus.go +++ b/consensus/dummy/consensus.go @@ -15,6 +15,7 @@ import ( "github.com/ava-labs/subnet-evm/core/state" "github.com/ava-labs/subnet-evm/core/types" "github.com/ava-labs/subnet-evm/params" + "github.com/ava-labs/subnet-evm/precompile" "github.com/ava-labs/subnet-evm/trie" "github.com/ava-labs/subnet-evm/vmerrs" "github.com/ethereum/go-ethereum/common" @@ -198,7 +199,7 @@ func (self *DummyEngine) verifyHeader(chain consensus.ChainHeaderReader, header } // Ensure that coinbase is valid if reward manager is enabled // If reward manager is disabled, this will be handled in syntactic verification - if config.IsRewardManager(timestamp) { + if config.IsPrecompileEnabled(precompile.RewardManagerAddress, timestamp) { if err := self.verifyCoinbase(config, header, parent, chain); err != nil { return err } diff --git a/core/blockchain_reader.go b/core/blockchain_reader.go index 552c738834..45918af3e6 100644 --- a/core/blockchain_reader.go +++ b/core/blockchain_reader.go @@ -348,7 +348,7 @@ func (bc *BlockChain) SubscribeAcceptedTransactionEvent(ch chan<- NewTxsEvent) e func (bc *BlockChain) GetFeeConfigAt(parent *types.Header) (commontype.FeeConfig, *big.Int, error) { config := bc.Config() bigTime := new(big.Int).SetUint64(parent.Time) - if !config.IsFeeConfigManager(bigTime) { + if !config.IsPrecompileEnabled(precompile.FeeConfigManagerAddress, bigTime) { return config.FeeConfig, common.Big0, nil } @@ -390,7 +390,7 @@ func (bc *BlockChain) GetCoinbaseAt(parent *types.Header) (common.Address, bool, return constants.BlackholeAddr, false, nil } - if !config.IsRewardManager(bigTime) { + if !config.IsPrecompileEnabled(precompile.RewardManagerAddress, bigTime) { if bc.chainConfig.AllowFeeRecipients { return common.Address{}, true, nil } else { diff --git a/core/state_transition.go b/core/state_transition.go index d039d0694c..acd81569e2 100644 --- a/core/state_transition.go +++ b/core/state_transition.go @@ -249,7 +249,7 @@ func (st *StateTransition) preCheck() error { } // Check that the sender is on the tx allow list if enabled - if st.evm.ChainConfig().IsTxAllowList(st.evm.Context.Time) { + if st.evm.ChainConfig().IsPrecompileEnabled(precompile.TxAllowListAddress, st.evm.Context.Time) { txAllowListRole := precompile.GetTxAllowListStatus(st.state, st.msg.From()) if !txAllowListRole.IsEnabled() { return fmt.Errorf("%w: %s", precompile.ErrSenderAddressNotAllowListed, st.msg.From()) diff --git a/core/tx_pool.go b/core/tx_pool.go index ed5502d94b..f927cb9589 100644 --- a/core/tx_pool.go +++ b/core/tx_pool.go @@ -693,7 +693,7 @@ func (pool *TxPool) checkTxState(from common.Address, tx *types.Transaction) err // If the tx allow list is enabled, return an error if the from address is not allow listed. headTimestamp := big.NewInt(int64(pool.currentHead.Time)) - if pool.chainconfig.IsTxAllowList(headTimestamp) { + if pool.chainconfig.IsPrecompileEnabled(precompile.TxAllowListAddress, headTimestamp) { txAllowListRole := precompile.GetTxAllowListStatus(pool.currentState, from) if !txAllowListRole.IsEnabled() { return fmt.Errorf("%w: %s", precompile.ErrSenderAddressNotAllowListed, from) @@ -1441,7 +1441,7 @@ func (pool *TxPool) reset(oldHead, newHead *types.Header) { // when we reset txPool we should explicitly check if fee struct for min base fee has changed // so that we can correctly drop txs with < minBaseFee from tx pool. - if pool.chainconfig.IsFeeConfigManager(new(big.Int).SetUint64(newHead.Time)) { + if pool.chainconfig.IsPrecompileEnabled(precompile.FeeConfigManagerAddress, new(big.Int).SetUint64(newHead.Time)) { feeConfig, _, err := pool.chain.GetFeeConfigAt(newHead) if err != nil { log.Error("Failed to get fee config state", "err", err, "root", newHead.Root) diff --git a/core/vm/evm.go b/core/vm/evm.go index c13db0def9..bb4b14b3e8 100644 --- a/core/vm/evm.go +++ b/core/vm/evm.go @@ -507,7 +507,7 @@ func (evm *EVM) create(caller ContractRef, codeAndHash *codeAndHash, gas uint64, return nil, common.Address{}, 0, vmerrs.ErrContractAddressCollision } // If the allow list is enabled, check that [evm.TxContext.Origin] has permission to deploy a contract. - if evm.chainRules.IsContractDeployerAllowListEnabled { + if evm.chainRules.IsPrecompileEnabled(precompile.ContractDeployerAllowListAddress) { allowListRole := precompile.GetContractDeployerAllowListStatus(evm.StateDB, evm.TxContext.Origin) if !allowListRole.IsEnabled() { return nil, common.Address{}, 0, fmt.Errorf("tx.origin %s is not authorized to deploy a contract", evm.TxContext.Origin) diff --git a/eth/gasprice/gasprice.go b/eth/gasprice/gasprice.go index 1554073693..48e3b938ea 100644 --- a/eth/gasprice/gasprice.go +++ b/eth/gasprice/gasprice.go @@ -39,6 +39,7 @@ import ( "github.com/ava-labs/subnet-evm/core" "github.com/ava-labs/subnet-evm/core/types" "github.com/ava-labs/subnet-evm/params" + "github.com/ava-labs/subnet-evm/precompile" "github.com/ava-labs/subnet-evm/rpc" "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/common/math" @@ -317,7 +318,7 @@ func (oracle *Oracle) suggestDynamicFees(ctx context.Context) (*big.Int, *big.In feeLastChangedAt *big.Int feeConfig commontype.FeeConfig ) - if oracle.backend.ChainConfig().IsFeeConfigManager(new(big.Int).SetUint64(head.Time)) { + if oracle.backend.ChainConfig().IsPrecompileEnabled(precompile.FeeConfigManagerAddress, new(big.Int).SetUint64(head.Time)) { feeConfig, feeLastChangedAt, err = oracle.backend.GetFeeConfigAt(head) if err != nil { return nil, nil, err diff --git a/params/config.go b/params/config.go index be024f6af8..1407ce1bb8 100644 --- a/params/config.go +++ b/params/config.go @@ -272,47 +272,12 @@ func (c *ChainConfig) IsSubnetEVM(blockTimestamp *big.Int) bool { return utils.IsForked(c.getNetworkUpgrades().SubnetEVMTimestamp, blockTimestamp) } -// PRECOMPILE UPGRADES START HERE - -// TODO: generalize these functions with IsPrecompileEnabled(address, blockTimestamp) -// IsContractDeployerAllowList returns whether [blockTimestamp] is either equal to the ContractDeployerAllowList fork block timestamp or greater. -func (c *ChainConfig) IsContractDeployerAllowList(blockTimestamp *big.Int) bool { - config := c.GetPrecompileConfig(precompile.ContractDeployerAllowListAddress, blockTimestamp) - return config != nil && !config.IsDisabled() -} - -// IsContractNativeMinter returns whether [blockTimestamp] is either equal to the NativeMinter fork block timestamp or greater. -func (c *ChainConfig) IsContractNativeMinter(blockTimestamp *big.Int) bool { - config := c.GetPrecompileConfig(precompile.ContractNativeMinterAddress, blockTimestamp) - return config != nil && !config.IsDisabled() -} - -// IsTxAllowList returns whether [blockTimestamp] is either equal to the TxAllowList fork block timestamp or greater. -func (c *ChainConfig) IsTxAllowList(blockTimestamp *big.Int) bool { - config := c.GetPrecompileConfig(precompile.TxAllowListAddress, blockTimestamp) - return config != nil && !config.IsDisabled() -} - -// IsFeeConfigManager returns whether [blockTimestamp] is either equal to the FeeConfigManager fork block timestamp or greater. -func (c *ChainConfig) IsFeeConfigManager(blockTimestamp *big.Int) bool { - config := c.GetPrecompileConfig(precompile.FeeConfigManagerAddress, blockTimestamp) +// IsPrecompileEnabled returns whether precompile with [address] is enabled at [blockTimestamp]. +func (c *ChainConfig) IsPrecompileEnabled(address common.Address, blockTimestamp *big.Int) bool { + config := c.GetPrecompileConfig(address, blockTimestamp) return config != nil && !config.IsDisabled() } -// IsRewardManager returns whether [blockTimestamp] is either equal to the RewardManager fork block timestamp or greater. -func (c *ChainConfig) IsRewardManager(blockTimestamp *big.Int) bool { - config := c.GetPrecompileConfig(precompile.RewardManagerAddress, blockTimestamp) - return config != nil && !config.IsDisabled() -} - -// ADD YOUR PRECOMPILE HERE -/* -func (c *ChainConfig) Is{YourPrecompile}(blockTimestamp *big.Int) bool { - config := c.GetPrecompileConfig(precompile.{YourPrecompile}Address, blockTimestamp) - return config != nil && !config.IsDisabled() -} -*/ - // CheckCompatible checks whether scheduled fork transitions have been imported // with a mismatching chain configuration. func (c *ChainConfig) CheckCompatible(newcfg *ChainConfig, height uint64, timestamp uint64) *ConfigCompatError { @@ -540,15 +505,6 @@ type Rules struct { // Rules for Avalanche releases IsSubnetEVM bool - // Optional stateful precompile rules - IsContractDeployerAllowListEnabled bool - IsContractNativeMinterEnabled bool - IsTxAllowListEnabled bool - IsFeeConfigManagerEnabled bool - IsRewardManagerEnabled bool - // ADD YOUR PRECOMPILE HERE - // Is{YourPrecompile}Enabled bool - // Precompiles maps addresses to stateful precompiled contracts that are enabled // for this rule set. // Note: none of these addresses should conflict with the address space used by @@ -556,6 +512,11 @@ type Rules struct { Precompiles map[common.Address]precompile.StatefulPrecompiledContract } +func (r *Rules) IsPrecompileEnabled(addr common.Address) bool { + _, ok := r.Precompiles[addr] + return ok +} + // Rules ensures c's ChainID is not nil. func (c *ChainConfig) rules(num *big.Int) Rules { chainID := c.ChainID @@ -581,13 +542,6 @@ func (c *ChainConfig) AvalancheRules(blockNum, blockTimestamp *big.Int) Rules { rules := c.rules(blockNum) rules.IsSubnetEVM = c.IsSubnetEVM(blockTimestamp) - rules.IsContractDeployerAllowListEnabled = c.IsContractDeployerAllowList(blockTimestamp) - rules.IsContractNativeMinterEnabled = c.IsContractNativeMinter(blockTimestamp) - rules.IsTxAllowListEnabled = c.IsTxAllowList(blockTimestamp) - rules.IsFeeConfigManagerEnabled = c.IsFeeConfigManager(blockTimestamp) - rules.IsRewardManagerEnabled = c.IsRewardManager(blockTimestamp) - // ADD YOUR PRECOMPILE HERE - // rules.Is{YourPrecompile}Enabled = c.{IsYourPrecompile}(blockTimestamp) // Initialize the stateful precompiles that should be enabled at [blockTimestamp]. rules.Precompiles = make(map[common.Address]precompile.StatefulPrecompiledContract) diff --git a/plugin/evm/block_verification.go b/plugin/evm/block_verification.go index e6d1fc4638..9e96553d52 100644 --- a/plugin/evm/block_verification.go +++ b/plugin/evm/block_verification.go @@ -12,6 +12,7 @@ import ( "github.com/ava-labs/subnet-evm/constants" "github.com/ava-labs/subnet-evm/core/types" "github.com/ava-labs/subnet-evm/params" + "github.com/ava-labs/subnet-evm/precompile" "github.com/ava-labs/subnet-evm/trie" "github.com/ava-labs/subnet-evm/vmerrs" ) @@ -98,7 +99,7 @@ func (v blockValidator) SyntacticVerify(b *Block, rules params.Rules) error { } switch { - case rules.IsRewardManagerEnabled: + case rules.IsPrecompileEnabled(precompile.RewardManagerAddress): // if reward manager is enabled, Coinbase depends on state. // State is not available here, so skip checking the coinbase here. case rules.IsSubnetEVM && b.vm.chainConfig.AllowFeeRecipients: