From 608713d3335f8b094e750d3dc9364b7650611c38 Mon Sep 17 00:00:00 2001 From: Ceyhun Onur Date: Sat, 11 Feb 2023 01:07:40 +0300 Subject: [PATCH 1/5] wip --- core/genesis_test.go | 3 +- core/state_processor.go | 17 +- core/state_processor_test.go | 3 +- core/test_blockchain.go | 3 +- core/vm/contracts.go | 4 +- core/vm/evm.go | 14 +- eth/gasprice/gasprice_test.go | 3 +- internal/ethapi/api.go | 11 +- params/chain_config_precompiles.go | 48 +++ params/config.go | 21 +- params/config_test.go | 211 ++++++++++++ params/precompile_config_test.go | 316 ++++++++++++++++++ params/precompile_upgrade.go | 26 +- params/precompile_upgrade_test.go | 285 ++++++++++++++++ plugin/evm/vm.go | 5 + plugin/evm/vm_test.go | 13 +- precompile/config/config.go | 39 +-- precompile/config/registry.go | 61 ---- precompile/contract/interfaces.go | 5 +- .../contracts/deployerallowlist/config.go | 2 - .../contracts/deployerallowlist/module.go | 4 - precompile/contracts/feemanager/config.go | 2 - precompile/contracts/feemanager/module.go | 6 +- precompile/contracts/nativeminter/config.go | 2 - precompile/contracts/nativeminter/module.go | 6 +- precompile/contracts/rewardmanager/config.go | 2 - precompile/contracts/rewardmanager/module.go | 6 +- precompile/contracts/txallowlist/config.go | 2 - precompile/contracts/txallowlist/module.go | 6 +- .../{registry => registerer}/registerer.go | 23 +- precompile/registry/registry.go | 29 +- 31 files changed, 954 insertions(+), 224 deletions(-) create mode 100644 params/chain_config_precompiles.go create mode 100644 params/config_test.go create mode 100644 params/precompile_config_test.go create mode 100644 params/precompile_upgrade_test.go delete mode 100644 precompile/config/registry.go rename precompile/{registry => registerer}/registerer.go (80%) diff --git a/core/genesis_test.go b/core/genesis_test.go index 01ce2c47ac..da89e9699f 100644 --- a/core/genesis_test.go +++ b/core/genesis_test.go @@ -39,7 +39,6 @@ import ( "github.com/ava-labs/subnet-evm/ethdb" "github.com/ava-labs/subnet-evm/params" "github.com/ava-labs/subnet-evm/precompile/allowlist" - precompileConfig "github.com/ava-labs/subnet-evm/precompile/config" "github.com/ava-labs/subnet-evm/precompile/contracts/deployerallowlist" "github.com/davecgh/go-spew/spew" "github.com/ethereum/go-ethereum/common" @@ -192,7 +191,7 @@ func TestStatefulPrecompilesConfigure(t *testing.T) { "allow list enabled in genesis": { getConfig: func() *params.ChainConfig { config := *params.TestChainConfig - config.GenesisPrecompiles = precompileConfig.Configs{ + config.GenesisPrecompiles = params.ChainConfigPrecompiles{ deployerallowlist.ConfigKey: deployerallowlist.NewContractDeployerAllowListConfig(big.NewInt(0), []common.Address{addr}, nil), } return &config diff --git a/core/state_processor.go b/core/state_processor.go index 515a7fb33b..66dcac6deb 100644 --- a/core/state_processor.go +++ b/core/state_processor.go @@ -35,9 +35,8 @@ 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/config" "github.com/ava-labs/subnet-evm/precompile/contract" - "github.com/ava-labs/subnet-evm/precompile/registry" + "github.com/ava-labs/subnet-evm/precompile/registerer" "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/crypto" "github.com/ethereum/go-ethereum/log" @@ -184,32 +183,32 @@ func ApplyPrecompileActivations(c *params.ChainConfig, parentTimestamp *big.Int, // Note: RegisteredModules returns precompiles in order they are registered. // This is important because we want to configure precompiles in the same order // so that the state is deterministic. - for _, config := range config.GetConfigs() { - key := config.Key() - for _, activatingConfig := range c.GetActivatingPrecompileConfigs(config.Address(), parentTimestamp, blockTimestamp, c.PrecompileUpgrades) { + for _, module := range registerer.RegisteredModules() { + key := module.NewConfig().Key() + for _, activatingConfig := range c.GetActivatingPrecompileConfigs(module.Address(), parentTimestamp, blockTimestamp, c.PrecompileUpgrades) { // If this transition activates the upgrade, configure the stateful precompile. // (or deconfigure it if it is being disabled.) if activatingConfig.IsDisabled() { log.Info("Disabling precompile", "name", key) - statedb.Suicide(config.Address()) + statedb.Suicide(module.Address()) // Calling Finalise here effectively commits Suicide call and wipes the contract state. // This enables re-configuration of the same contract state in the same block. // Without an immediate Finalise call after the Suicide, a reconfigured precompiled state can be wiped out // since Suicide will be committed after the reconfiguration. statedb.Finalise(true) } else { - module, ok := registry.GetPrecompileModule(key) + module, ok := registerer.GetPrecompileModule(key) if !ok { return fmt.Errorf("could not find module for activating precompile, name: %s", key) } log.Info("Activating new precompile", "name", key, "config", activatingConfig) // Set the nonce of the precompile's address (as is done when a contract is created) to ensure // that it is marked as non-empty and will not be cleaned up when the statedb is finalized. - statedb.SetNonce(activatingConfig.Address(), 1) + statedb.SetNonce(module.Address(), 1) // Set the code of the precompile's address to a non-zero length byte slice to ensure that the precompile // 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(activatingConfig.Address(), []byte{0x1}) + statedb.SetCode(module.Address(), []byte{0x1}) if err := module.Configure(c, activatingConfig, statedb, blockContext); err != nil { return fmt.Errorf("could not configure precompile, name: %s, reason: %w", key, err) } diff --git a/core/state_processor_test.go b/core/state_processor_test.go index f76f0f7640..44f11035d2 100644 --- a/core/state_processor_test.go +++ b/core/state_processor_test.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" - precompileConfig "github.com/ava-labs/subnet-evm/precompile/config" "github.com/ava-labs/subnet-evm/precompile/contracts/txallowlist" "github.com/ava-labs/subnet-evm/trie" "github.com/ethereum/go-ethereum/common" @@ -316,7 +315,7 @@ func TestBadTxAllowListBlock(t *testing.T) { NetworkUpgrades: params.NetworkUpgrades{ SubnetEVMTimestamp: big.NewInt(0), }, - GenesisPrecompiles: precompileConfig.Configs{ + GenesisPrecompiles: params.ChainConfigPrecompiles{ txallowlist.ConfigKey: txallowlist.NewTxAllowListConfig(big.NewInt(0), nil, nil), }, } diff --git a/core/test_blockchain.go b/core/test_blockchain.go index 57d1d21372..a69e98d568 100644 --- a/core/test_blockchain.go +++ b/core/test_blockchain.go @@ -17,7 +17,6 @@ import ( "github.com/ava-labs/subnet-evm/ethdb" "github.com/ava-labs/subnet-evm/params" "github.com/ava-labs/subnet-evm/precompile/allowlist" - precompileConfig "github.com/ava-labs/subnet-evm/precompile/config" "github.com/ava-labs/subnet-evm/precompile/contracts/deployerallowlist" "github.com/ava-labs/subnet-evm/precompile/contracts/feemanager" "github.com/ethereum/go-ethereum/common" @@ -1549,7 +1548,7 @@ func TestStatefulPrecompiles(t *testing.T, create func(db ethdb.Database, chainC genesisBalance := new(big.Int).Mul(big.NewInt(1000000), big.NewInt(params.Ether)) config := *params.TestChainConfig // Set all of the required config parameters - config.GenesisPrecompiles = precompileConfig.Configs{ + config.GenesisPrecompiles = params.ChainConfigPrecompiles{ deployerallowlist.ConfigKey: deployerallowlist.NewContractDeployerAllowListConfig(big.NewInt(0), []common.Address{addr1}, nil), feemanager.ConfigKey: feemanager.NewFeeManagerConfig(big.NewInt(0), []common.Address{addr1}, nil, nil), } diff --git a/core/vm/contracts.go b/core/vm/contracts.go index 3faceeb3f6..58da3ab21e 100644 --- a/core/vm/contracts.go +++ b/core/vm/contracts.go @@ -36,7 +36,7 @@ import ( "github.com/ava-labs/subnet-evm/constants" "github.com/ava-labs/subnet-evm/params" "github.com/ava-labs/subnet-evm/precompile/contract" - "github.com/ava-labs/subnet-evm/precompile/registry" + "github.com/ava-labs/subnet-evm/precompile/registerer" "github.com/ava-labs/subnet-evm/vmerrs" "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/common/math" @@ -159,7 +159,7 @@ func init() { // Ensure that this package will panic during init if there is a conflict present with the declared // precompile addresses. - for _, module := range registry.RegisteredModules() { + for _, module := range registerer.RegisteredModules() { address := module.Address() if _, ok := PrecompileAllNativeAddresses[address]; ok { panic(fmt.Errorf("precompile address collides with existing native address: %s", address)) diff --git a/core/vm/evm.go b/core/vm/evm.go index 962ed369e6..7c258e3cf9 100644 --- a/core/vm/evm.go +++ b/core/vm/evm.go @@ -37,7 +37,7 @@ import ( "github.com/ava-labs/subnet-evm/params" "github.com/ava-labs/subnet-evm/precompile/contract" "github.com/ava-labs/subnet-evm/precompile/contracts/deployerallowlist" - "github.com/ava-labs/subnet-evm/precompile/registry" + "github.com/ava-labs/subnet-evm/precompile/registerer" "github.com/ava-labs/subnet-evm/vmerrs" "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/crypto" @@ -56,7 +56,7 @@ func IsProhibited(addr common.Address) bool { return true } - return registry.ReservedAddress(addr) + return registerer.ReservedAddress(addr) } // emptyCodeHash is used by create to ensure deployment is disallowed to already @@ -93,13 +93,11 @@ func (evm *EVM) precompile(addr common.Address) (contract.StatefulPrecompiledCon } // Otherwise, check the chain rules for the additionally configured precompiles. - config, ok := evm.chainRules.ActivePrecompiles[addr] - if ok { - key := config.Key() - if module, ok := registry.GetPrecompileModule(key); ok { - return module.Contract(), true - } + if _, ok = evm.chainRules.ActivePrecompiles[addr]; ok { + module, ok := registerer.GetPrecompileModuleByAddress(addr) + return module.Contract(), ok } + return nil, false } diff --git a/eth/gasprice/gasprice_test.go b/eth/gasprice/gasprice_test.go index 51e93f75d4..67a19c9bf3 100644 --- a/eth/gasprice/gasprice_test.go +++ b/eth/gasprice/gasprice_test.go @@ -40,7 +40,6 @@ import ( "github.com/ava-labs/subnet-evm/core/vm" "github.com/ava-labs/subnet-evm/ethdb" "github.com/ava-labs/subnet-evm/params" - precompileConfig "github.com/ava-labs/subnet-evm/precompile/config" "github.com/ava-labs/subnet-evm/precompile/contracts/feemanager" "github.com/ava-labs/subnet-evm/rpc" "github.com/ethereum/go-ethereum/common" @@ -435,7 +434,7 @@ func TestSuggestGasPriceAfterFeeConfigUpdate(t *testing.T) { // create a chain config with fee manager enabled at genesis with [addr] as the admin chainConfig := *params.TestChainConfig - chainConfig.GenesisPrecompiles = precompileConfig.Configs{ + chainConfig.GenesisPrecompiles = params.ChainConfigPrecompiles{ feemanager.ConfigKey: feemanager.NewFeeManagerConfig(big.NewInt(0), []common.Address{addr}, nil, nil), } diff --git a/internal/ethapi/api.go b/internal/ethapi/api.go index deb7e8284d..787a9eedd0 100644 --- a/internal/ethapi/api.go +++ b/internal/ethapi/api.go @@ -44,8 +44,7 @@ import ( "github.com/ava-labs/subnet-evm/core/vm" "github.com/ava-labs/subnet-evm/eth/tracers/logger" "github.com/ava-labs/subnet-evm/params" - precompileConfig "github.com/ava-labs/subnet-evm/precompile/config" - "github.com/ava-labs/subnet-evm/precompile/registry" + "github.com/ava-labs/subnet-evm/precompile/registerer" "github.com/ava-labs/subnet-evm/rpc" "github.com/ava-labs/subnet-evm/vmerrs" "github.com/davecgh/go-spew/spew" @@ -628,15 +627,15 @@ func (api *BlockChainAPI) ChainId() *hexutil.Big { } // GetActivePrecompilesAt returns the active precompile configs at the given block timestamp. -func (s *BlockChainAPI) GetActivePrecompilesAt(ctx context.Context, blockTimestamp *big.Int) precompileConfig.Configs { +func (s *BlockChainAPI) GetActivePrecompilesAt(ctx context.Context, blockTimestamp *big.Int) params.ChainConfigPrecompiles { if blockTimestamp == nil { blockTimestampInt := s.b.CurrentHeader().Time blockTimestamp = new(big.Int).SetUint64(blockTimestampInt) } - res := make(precompileConfig.Configs) - for _, module := range registry.RegisteredModules() { + res := make(params.ChainConfigPrecompiles) + for _, module := range registerer.RegisteredModules() { if config := s.b.ChainConfig().GetActivePrecompileConfig(module.Address(), blockTimestamp); config != nil && !config.IsDisabled() { - res[module.Key()] = config + res[module.NewConfig().Key()] = config } } diff --git a/params/chain_config_precompiles.go b/params/chain_config_precompiles.go new file mode 100644 index 0000000000..c1a904ee55 --- /dev/null +++ b/params/chain_config_precompiles.go @@ -0,0 +1,48 @@ +// (c) 2023 Ava Labs, Inc. All rights reserved. +// See the file LICENSE for licensing terms. + +package params + +import ( + "encoding/json" + + "github.com/ava-labs/subnet-evm/precompile/config" + "github.com/ava-labs/subnet-evm/precompile/registerer" + "github.com/ethereum/go-ethereum/common" +) + +type ChainConfigPrecompiles map[string]config.Config + +func (ccp *ChainConfigPrecompiles) GetConfigByAddress(address common.Address) (config.Config, bool) { + module, ok := registerer.GetPrecompileModuleByAddress(address) + if !ok { + return nil, false + } + key := module.NewConfig().Key() + config, ok := (*ccp)[key] + return config, ok +} + +// UnmarshalJSON parses the JSON-encoded data into the ChainConfigPrecompiles. +// ChainConfigPrecompiles is a map of precompile module keys to their +// configuration. +func (ccp *ChainConfigPrecompiles) UnmarshalJSON(data []byte) error { + raw := make(map[string]json.RawMessage) + if err := json.Unmarshal(data, &raw); err != nil { + return err + } + + *ccp = make(ChainConfigPrecompiles) + for _, module := range registerer.RegisteredModules() { + key := module.NewConfig().Key() + if value, ok := raw[key]; ok { + conf := module.NewConfig() + err := json.Unmarshal(value, conf) + if err != nil { + return err + } + (*ccp)[key] = conf + } + } + return nil +} diff --git a/params/config.go b/params/config.go index 86ca242044..a967d10020 100644 --- a/params/config.go +++ b/params/config.go @@ -35,7 +35,7 @@ import ( "github.com/ava-labs/avalanchego/snow" "github.com/ava-labs/subnet-evm/commontype" "github.com/ava-labs/subnet-evm/precompile/config" - precompileConfig "github.com/ava-labs/subnet-evm/precompile/config" + "github.com/ava-labs/subnet-evm/precompile/registerer" "github.com/ava-labs/subnet-evm/utils" "github.com/ethereum/go-ethereum/common" ) @@ -84,7 +84,7 @@ var ( PetersburgBlock: big.NewInt(0), IstanbulBlock: big.NewInt(0), MuirGlacierBlock: big.NewInt(0), - GenesisPrecompiles: precompileConfig.Configs{}, + GenesisPrecompiles: ChainConfigPrecompiles{}, NetworkUpgrades: NetworkUpgrades{ SubnetEVMTimestamp: big.NewInt(0), }, @@ -106,7 +106,7 @@ var ( IstanbulBlock: big.NewInt(0), MuirGlacierBlock: big.NewInt(0), NetworkUpgrades: NetworkUpgrades{big.NewInt(0)}, - GenesisPrecompiles: precompileConfig.Configs{}, + GenesisPrecompiles: ChainConfigPrecompiles{}, UpgradeConfig: UpgradeConfig{}, } @@ -126,7 +126,7 @@ var ( IstanbulBlock: big.NewInt(0), MuirGlacierBlock: big.NewInt(0), NetworkUpgrades: NetworkUpgrades{}, - GenesisPrecompiles: precompileConfig.Configs{}, + GenesisPrecompiles: ChainConfigPrecompiles{}, UpgradeConfig: UpgradeConfig{}, } ) @@ -158,9 +158,9 @@ type ChainConfig struct { IstanbulBlock *big.Int `json:"istanbulBlock,omitempty"` // Istanbul switch block (nil = no fork, 0 = already on istanbul) MuirGlacierBlock *big.Int `json:"muirGlacierBlock,omitempty"` // Eip-2384 (bomb delay) switch block (nil = no fork, 0 = already activated) - NetworkUpgrades // Config for timestamps that enable avalanche network upgrades - GenesisPrecompiles precompileConfig.Configs `json:"-"` // Config for enabling precompiles from genesis. JSON encode/decode will be handled by the custom marshaler/unmarshaler. - UpgradeConfig `json:"-"` // Config specified in upgradeBytes (avalanche network upgrades or enable/disabling precompiles). Skip encoding/decoding directly into ChainConfig. + NetworkUpgrades // Config for timestamps that enable avalanche network upgrades + GenesisPrecompiles ChainConfigPrecompiles `json:"-"` // Config for enabling precompiles from genesis. JSON encode/decode will be handled by the custom marshaler/unmarshaler. + UpgradeConfig `json:"-"` // Config specified in upgradeBytes (avalanche network upgrades or enable/disabling precompiles). Skip encoding/decoding directly into ChainConfig. } // UnmarshalJSON parses the JSON-encoded data and stores the result in the @@ -596,11 +596,10 @@ func (c *ChainConfig) AvalancheRules(blockNum, blockTimestamp *big.Int) Rules { // Initialize the stateful precompiles that should be enabled at [blockTimestamp]. rules.ActivePrecompiles = make(map[common.Address]config.Config) - for _, config := range c.EnabledStatefulPrecompiles(blockTimestamp) { - if config.IsDisabled() { - continue + for _, module := range registerer.RegisteredModules() { + if config := c.GetActivePrecompileConfig(module.Address(), blockTimestamp); config != nil { + rules.ActivePrecompiles[module.Address()] = config } - rules.ActivePrecompiles[config.Address()] = config } return rules diff --git a/params/config_test.go b/params/config_test.go new file mode 100644 index 0000000000..d74ec53b59 --- /dev/null +++ b/params/config_test.go @@ -0,0 +1,211 @@ +// (c) 2019-2020, Ava Labs, Inc. +// +// This file is a derived work, based on the go-ethereum library whose original +// notices appear below. +// +// It is distributed under a license compatible with the licensing terms of the +// original code from which it is derived. +// +// Much love to the original authors for their work. +// ********** +// Copyright 2017 The go-ethereum Authors +// This file is part of the go-ethereum library. +// +// The go-ethereum library is free software: you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// The go-ethereum library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with the go-ethereum library. If not, see . + +package params + +import ( + "encoding/json" + "math/big" + "reflect" + "testing" + + "github.com/ava-labs/subnet-evm/precompile/contracts/nativeminter" + "github.com/ava-labs/subnet-evm/precompile/contracts/rewardmanager" + "github.com/ava-labs/subnet-evm/precompile/registry" + "github.com/ethereum/go-ethereum/common" + "github.com/stretchr/testify/require" +) + +func init() { + // We need to explicitly register the precompiles here. + _ = registry.RegisterPrecompileModules() +} + +func TestCheckCompatible(t *testing.T) { + type test struct { + stored, new *ChainConfig + blockHeight, blockTimestamp uint64 + wantErr *ConfigCompatError + } + tests := []test{ + {stored: TestChainConfig, new: TestChainConfig, blockHeight: 0, blockTimestamp: 0, wantErr: nil}, + {stored: TestChainConfig, new: TestChainConfig, blockHeight: 100, blockTimestamp: 1000, wantErr: nil}, + { + stored: &ChainConfig{EIP150Block: big.NewInt(10)}, + new: &ChainConfig{EIP150Block: big.NewInt(20)}, + blockHeight: 9, + blockTimestamp: 90, + wantErr: nil, + }, + { + stored: TestChainConfig, + new: &ChainConfig{HomesteadBlock: nil}, + blockHeight: 3, + blockTimestamp: 30, + wantErr: &ConfigCompatError{ + What: "Homestead fork block", + StoredConfig: big.NewInt(0), + NewConfig: nil, + RewindTo: 0, + }, + }, + { + stored: TestChainConfig, + new: &ChainConfig{HomesteadBlock: big.NewInt(1)}, + blockHeight: 3, + blockTimestamp: 30, + wantErr: &ConfigCompatError{ + What: "Homestead fork block", + StoredConfig: big.NewInt(0), + NewConfig: big.NewInt(1), + RewindTo: 0, + }, + }, + { + stored: &ChainConfig{HomesteadBlock: big.NewInt(30), EIP150Block: big.NewInt(10)}, + new: &ChainConfig{HomesteadBlock: big.NewInt(25), EIP150Block: big.NewInt(20)}, + blockHeight: 25, + blockTimestamp: 250, + wantErr: &ConfigCompatError{ + What: "EIP150 fork block", + StoredConfig: big.NewInt(10), + NewConfig: big.NewInt(20), + RewindTo: 9, + }, + }, + { + stored: &ChainConfig{ConstantinopleBlock: big.NewInt(30)}, + new: &ChainConfig{ConstantinopleBlock: big.NewInt(30), PetersburgBlock: big.NewInt(30)}, + blockHeight: 40, + blockTimestamp: 400, + wantErr: nil, + }, + { + stored: &ChainConfig{ConstantinopleBlock: big.NewInt(30)}, + new: &ChainConfig{ConstantinopleBlock: big.NewInt(30), PetersburgBlock: big.NewInt(31)}, + blockHeight: 40, + blockTimestamp: 400, + wantErr: &ConfigCompatError{ + What: "Petersburg fork block", + StoredConfig: nil, + NewConfig: big.NewInt(31), + RewindTo: 30, + }, + }, + { + stored: TestChainConfig, + new: TestPreSubnetEVMConfig, + blockHeight: 0, + blockTimestamp: 0, + wantErr: &ConfigCompatError{ + What: "SubnetEVM fork block timestamp", + StoredConfig: big.NewInt(0), + NewConfig: nil, + RewindTo: 0, + }, + }, + { + stored: TestChainConfig, + new: TestPreSubnetEVMConfig, + blockHeight: 10, + blockTimestamp: 100, + wantErr: &ConfigCompatError{ + What: "SubnetEVM fork block timestamp", + StoredConfig: big.NewInt(0), + NewConfig: nil, + RewindTo: 0, + }, + }, + } + + for _, test := range tests { + err := test.stored.CheckCompatible(test.new, test.blockHeight, test.blockTimestamp) + if !reflect.DeepEqual(err, test.wantErr) { + t.Errorf("error mismatch:\nstored: %v\nnew: %v\nblockHeight: %v\nerr: %v\nwant: %v", test.stored, test.new, test.blockHeight, err, test.wantErr) + } + } +} + +func TestConfigUnmarshalJSON(t *testing.T) { + require := require.New(t) + + testRewardManagerConfig := rewardmanager.NewRewardManagerConfig( + big.NewInt(1671542573), + []common.Address{common.HexToAddress("0x8db97C7cEcE249c2b98bDC0226Cc4C2A57BF52FC")}, + nil, + &rewardmanager.InitialRewardConfig{ + AllowFeeRecipients: true, + }) + + testContractNativeMinterConfig := nativeminter.NewContractNativeMinterConfig(big.NewInt(0), + []common.Address{common.HexToAddress("0x8db97C7cEcE249c2b98bDC0226Cc4C2A57BF52FC")}, + nil, + nil, + ) + + config := []byte(`{ + "chainId": 43214, + "allowFeeRecipients": true, + "rewardManagerConfig": { + "blockTimestamp": 1671542573, + "adminAddresses": [ + "0x8db97C7cEcE249c2b98bDC0226Cc4C2A57BF52FC" + ], + "initialRewardConfig": { + "allowFeeRecipients": true + } + }, + "contractNativeMinterConfig": { + "blockTimestamp": 0, + "adminAddresses": [ + "0x8db97C7cEcE249c2b98bDC0226Cc4C2A57BF52FC" + ] + } + }`) + c := ChainConfig{} + err := json.Unmarshal(config, &c) + require.NoError(err) + + require.Equal(c.ChainID, big.NewInt(43214)) + require.Equal(c.AllowFeeRecipients, true) + + rewardManagerConfig, ok := c.GenesisPrecompiles[rewardmanager.ConfigKey] + require.True(ok) + require.Equal(rewardManagerConfig.Key(), rewardmanager.ConfigKey) + require.True(rewardManagerConfig.Equal(testRewardManagerConfig)) + + contractNativeMinterConfig := c.GenesisPrecompiles[nativeminter.ConfigKey] + require.Equal(contractNativeMinterConfig.Key(), nativeminter.ConfigKey) + require.True(contractNativeMinterConfig.Equal(testContractNativeMinterConfig)) + + // Marshal and unmarshal again and check that the result is the same + marshaled, err := json.Marshal(c) + require.NoError(err) + c2 := ChainConfig{} + err = json.Unmarshal(marshaled, &c2) + require.NoError(err) + require.Equal(c, c2) +} diff --git a/params/precompile_config_test.go b/params/precompile_config_test.go new file mode 100644 index 0000000000..8087ac5b65 --- /dev/null +++ b/params/precompile_config_test.go @@ -0,0 +1,316 @@ +// (c) 2022 Ava Labs, Inc. All rights reserved. +// See the file LICENSE for licensing terms. + +package params + +import ( + "encoding/json" + "math/big" + "testing" + + "github.com/ava-labs/subnet-evm/commontype" + "github.com/ava-labs/subnet-evm/precompile/contracts/deployerallowlist" + "github.com/ava-labs/subnet-evm/precompile/contracts/feemanager" + "github.com/ava-labs/subnet-evm/precompile/contracts/nativeminter" + "github.com/ava-labs/subnet-evm/precompile/contracts/rewardmanager" + "github.com/ava-labs/subnet-evm/precompile/contracts/txallowlist" + "github.com/ethereum/go-ethereum/common" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" +) + +func TestVerifyWithChainConfig(t *testing.T) { + admins := []common.Address{{1}} + baseConfig := *SubnetEVMDefaultChainConfig + config := &baseConfig + config.GenesisPrecompiles = ChainConfigPrecompiles{ + txallowlist.ConfigKey: txallowlist.NewTxAllowListConfig(big.NewInt(2), nil, nil), + } + config.PrecompileUpgrades = []PrecompileUpgrade{ + { + // disable TxAllowList at timestamp 4 + txallowlist.NewDisableTxAllowListConfig(big.NewInt(4)), + }, + { + // re-enable TxAllowList at timestamp 5 + txallowlist.NewTxAllowListConfig(big.NewInt(5), admins, nil), + }, + } + + // check this config is valid + err := config.Verify() + assert.NoError(t, err) + + // same precompile cannot be configured twice for the same timestamp + badConfig := *config + badConfig.PrecompileUpgrades = append( + badConfig.PrecompileUpgrades, + PrecompileUpgrade{ + Config: txallowlist.NewDisableTxAllowListConfig(big.NewInt(5)), + }, + ) + err = badConfig.Verify() + assert.ErrorContains(t, err, "config block timestamp (5) <= previous timestamp (5) of same key") + + // cannot enable a precompile without disabling it first. + badConfig = *config + badConfig.PrecompileUpgrades = append( + badConfig.PrecompileUpgrades, + PrecompileUpgrade{ + Config: txallowlist.NewTxAllowListConfig(big.NewInt(5), admins, nil), + }, + ) + err = badConfig.Verify() + assert.ErrorContains(t, err, "disable should be [true]") +} + +func TestVerifyPrecompileUpgrades(t *testing.T) { + admins := []common.Address{{1}} + tests := []struct { + name string + upgrades []PrecompileUpgrade + expectedError string + }{ + { + name: "enable and disable tx allow list", + upgrades: []PrecompileUpgrade{ + { + Config: txallowlist.NewTxAllowListConfig(big.NewInt(1), admins, nil), + }, + { + Config: txallowlist.NewDisableTxAllowListConfig(big.NewInt(2)), + }, + }, + expectedError: "", + }, + { + name: "invalid allow list config in tx allowlist", + upgrades: []PrecompileUpgrade{ + { + Config: txallowlist.NewTxAllowListConfig(big.NewInt(1), admins, nil), + }, + { + Config: txallowlist.NewDisableTxAllowListConfig(big.NewInt(2)), + }, + { + Config: txallowlist.NewTxAllowListConfig(big.NewInt(3), admins, admins), + }, + }, + expectedError: "cannot set address", + }, + { + name: "invalid initial fee manager config", + upgrades: []PrecompileUpgrade{ + { + Config: feemanager.NewFeeManagerConfig(big.NewInt(3), admins, nil, + &commontype.FeeConfig{ + GasLimit: big.NewInt(-1), + }), + }, + }, + expectedError: "gasLimit = -1 cannot be less than or equal to 0", + }, + { + name: "invalid initial fee manager config gas limit 0", + upgrades: []PrecompileUpgrade{ + { + Config: feemanager.NewFeeManagerConfig(big.NewInt(3), admins, nil, + &commontype.FeeConfig{ + GasLimit: big.NewInt(0), + }), + }, + }, + expectedError: "gasLimit = 0 cannot be less than or equal to 0", + }, + { + name: "different upgrades are allowed to configure same timestamp for different precompiles", + upgrades: []PrecompileUpgrade{ + { + Config: txallowlist.NewTxAllowListConfig(big.NewInt(1), admins, nil), + }, + { + Config: feemanager.NewFeeManagerConfig(big.NewInt(1), admins, nil, nil), + }, + }, + expectedError: "", + }, + { + name: "different upgrades must be monotonically increasing", + upgrades: []PrecompileUpgrade{ + { + Config: txallowlist.NewTxAllowListConfig(big.NewInt(2), admins, nil), + }, + { + Config: feemanager.NewFeeManagerConfig(big.NewInt(1), admins, nil, nil), + }, + }, + expectedError: "config block timestamp (1) < previous timestamp (2)", + }, + { + name: "upgrades with same keys are not allowed to configure same timestamp for same precompiles", + upgrades: []PrecompileUpgrade{ + { + Config: txallowlist.NewTxAllowListConfig(big.NewInt(1), admins, nil), + }, + { + Config: txallowlist.NewDisableTxAllowListConfig(big.NewInt(1)), + }, + }, + expectedError: " config block timestamp (1) <= previous timestamp (1) of same key", + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + require := require.New(t) + baseConfig := *SubnetEVMDefaultChainConfig + config := &baseConfig + config.PrecompileUpgrades = tt.upgrades + + err := config.Verify() + if tt.expectedError == "" { + require.NoError(err) + } else { + require.ErrorContains(err, tt.expectedError) + } + }) + } +} + +func TestVerifyPrecompiles(t *testing.T) { + admins := []common.Address{{1}} + tests := []struct { + name string + upgrade ChainConfigPrecompiles + expectedError string + }{ + { + name: "invalid allow list config in tx allowlist", + upgrade: ChainConfigPrecompiles{ + txallowlist.ConfigKey: txallowlist.NewTxAllowListConfig(big.NewInt(3), admins, admins), + }, + expectedError: "cannot set address", + }, + { + name: "invalid initial fee manager config", + upgrade: ChainConfigPrecompiles{ + feemanager.ConfigKey: feemanager.NewFeeManagerConfig(big.NewInt(3), admins, nil, + &commontype.FeeConfig{ + GasLimit: big.NewInt(-1), + }), + }, + expectedError: "gasLimit = -1 cannot be less than or equal to 0", + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + require := require.New(t) + baseConfig := *SubnetEVMDefaultChainConfig + config := &baseConfig + config.GenesisPrecompiles = tt.upgrade + + err := config.Verify() + if tt.expectedError == "" { + require.NoError(err) + } else { + require.ErrorContains(err, tt.expectedError) + } + }) + } +} + +func TestVerifyRequiresSortedTimestamps(t *testing.T) { + admins := []common.Address{{1}} + baseConfig := *SubnetEVMDefaultChainConfig + config := &baseConfig + config.PrecompileUpgrades = []PrecompileUpgrade{ + { + Config: txallowlist.NewTxAllowListConfig(big.NewInt(2), admins, nil), + }, + { + Config: deployerallowlist.NewContractDeployerAllowListConfig(big.NewInt(1), admins, nil), + }, + } + + // block timestamps must be monotonically increasing, so this config is invalid + err := config.Verify() + assert.ErrorContains(t, err, "config block timestamp (1) < previous timestamp (2)") +} + +func TestGetPrecompileConfig(t *testing.T) { + assert := assert.New(t) + baseConfig := *SubnetEVMDefaultChainConfig + config := &baseConfig + config.GenesisPrecompiles = ChainConfigPrecompiles{ + deployerallowlist.ConfigKey: deployerallowlist.NewContractDeployerAllowListConfig(big.NewInt(10), nil, nil), + } + + deployerConfig := config.GetActivePrecompileConfig(deployerallowlist.ContractAddress, big.NewInt(0)) + assert.Nil(deployerConfig) + + deployerConfig = config.GetActivePrecompileConfig(deployerallowlist.ContractAddress, big.NewInt(10)) + assert.NotNil(deployerConfig) + + deployerConfig = config.GetActivePrecompileConfig(deployerallowlist.ContractAddress, big.NewInt(11)) + assert.NotNil(deployerConfig) + + txAllowListConfig := config.GetActivePrecompileConfig(txallowlist.ContractAddress, big.NewInt(0)) + assert.Nil(txAllowListConfig) +} + +func TestPrecompileUpgradeUnmarshalJSON(t *testing.T) { + require := require.New(t) + + upgradeBytes := []byte(` + { + "precompileUpgrades": [ + { + "rewardManagerConfig": { + "blockTimestamp": 1671542573, + "adminAddresses": [ + "0x8db97C7cEcE249c2b98bDC0226Cc4C2A57BF52FC" + ], + "initialRewardConfig": { + "allowFeeRecipients": true + } + } + }, + { + "contractNativeMinterConfig": { + "blockTimestamp": 1671543172, + "disable": false + } + } + ] + } + `) + + var upgradeConfig UpgradeConfig + err := json.Unmarshal(upgradeBytes, &upgradeConfig) + require.NoError(err) + + require.Len(upgradeConfig.PrecompileUpgrades, 2) + + rewardManagerConf := upgradeConfig.PrecompileUpgrades[0] + require.Equal(rewardManagerConf.Key(), rewardmanager.ConfigKey) + testRewardManagerConfig := rewardmanager.NewRewardManagerConfig( + big.NewInt(1671542573), + []common.Address{common.HexToAddress("0x8db97C7cEcE249c2b98bDC0226Cc4C2A57BF52FC")}, + nil, + &rewardmanager.InitialRewardConfig{ + AllowFeeRecipients: true, + }) + require.True(rewardManagerConf.Equal(testRewardManagerConfig)) + + contractNativeMinterConf := upgradeConfig.PrecompileUpgrades[1] + require.Equal(contractNativeMinterConf.Key(), nativeminter.ConfigKey) + testContractNativeMinterConfig := nativeminter.NewContractNativeMinterConfig(big.NewInt(1671543172), nil, nil, nil) + require.True(contractNativeMinterConf.Equal(testContractNativeMinterConfig)) + + // Marshal and unmarshal again and check that the result is the same + upgradeBytes2, err := json.Marshal(upgradeConfig) + require.NoError(err) + var upgradeConfig2 UpgradeConfig + err = json.Unmarshal(upgradeBytes2, &upgradeConfig2) + require.NoError(err) + require.Equal(upgradeConfig, upgradeConfig2) +} diff --git a/params/precompile_upgrade.go b/params/precompile_upgrade.go index a80813242e..527e2af8c0 100644 --- a/params/precompile_upgrade.go +++ b/params/precompile_upgrade.go @@ -11,6 +11,7 @@ import ( "github.com/ava-labs/subnet-evm/precompile/config" precompileConfig "github.com/ava-labs/subnet-evm/precompile/config" + "github.com/ava-labs/subnet-evm/precompile/registerer" "github.com/ava-labs/subnet-evm/utils" "github.com/ethereum/go-ethereum/common" ) @@ -42,10 +43,11 @@ func (u *PrecompileUpgrade) UnmarshalJSON(data []byte) error { return errMultipleKeys } for key, value := range raw { - config, ok := config.GetNewConfig(key) + module, ok := registerer.GetPrecompileModule(key) if !ok { return fmt.Errorf("unknown precompile config: %s", key) } + config := module.NewConfig() err := json.Unmarshal(value, config) if err != nil { return err @@ -58,7 +60,7 @@ func (u *PrecompileUpgrade) UnmarshalJSON(data []byte) error { // MarshalJSON marshal the precompile config into json based on the precompile key. // Ex: {"feeManagerConfig": {...}} where "feeManagerConfig" is the key func (u *PrecompileUpgrade) MarshalJSON() ([]byte, error) { - res := make(precompileConfig.Configs) + res := make(map[string]precompileConfig.Config) res[u.Key()] = u.Config return json.Marshal(res) } @@ -131,7 +133,7 @@ func (c *ChainConfig) verifyPrecompileUpgrades() error { // Verify specified timestamps are monotonically increasing across same precompile keys. // Note: It is NOT OK for multiple configs of the SAME key to specify the same timestamp. if lastTimestamp != nil && (upgradeTimestamp.Cmp(lastTimestamp) <= 0) { - return fmt.Errorf("PrecompileUpgrade (%s) at [%d]: config block timestamp (%v) <= previous timestamp of same key (%v)", key, i, upgradeTimestamp, lastTimestamp) + return fmt.Errorf("PrecompileUpgrade (%s) at [%d]: config block timestamp (%v) <= previous timestamp (%v) of same key", key, i, upgradeTimestamp, lastTimestamp) } if err := upgrade.Verify(); err != nil { @@ -164,16 +166,22 @@ func (c *ChainConfig) GetActivePrecompileConfig(address common.Address, blockTim func (c *ChainConfig) GetActivatingPrecompileConfigs(address common.Address, from *big.Int, to *big.Int, upgrades []PrecompileUpgrade) []config.Config { configs := make([]config.Config, 0) + // Get key from address. + module, ok := registerer.GetPrecompileModuleByAddress(address) + if !ok { + return configs + } + key := module.NewConfig().Key() // First check the embedded [upgrade] for precompiles configured // in the genesis chain config. - if config, ok := c.GenesisPrecompiles.GetConfigByAddress(address); ok { + if config, ok := c.GenesisPrecompiles[key]; ok { if utils.IsForkTransition(config.Timestamp(), from, to) { configs = append(configs, config) } } // Loop over all upgrades checking for the requested precompile config. for _, upgrade := range upgrades { - if upgrade.Address() == address { + if upgrade.Key() == key { // Check if the precompile activates in the specified range. if utils.IsForkTransition(upgrade.Timestamp(), from, to) { configs = append(configs, upgrade.Config) @@ -190,8 +198,8 @@ func (c *ChainConfig) GetActivatingPrecompileConfigs(address common.Address, fro // Assumes given timestamp is the last accepted block timestamp. // This ensures that as long as the node has not accepted a block with a different rule set it will allow a new upgrade to be applied as long as it activates after the last accepted block. func (c *ChainConfig) CheckPrecompilesCompatible(precompileUpgrades []PrecompileUpgrade, lastTimestamp *big.Int) *ConfigCompatError { - for _, address := range config.GetAddresses() { - if err := c.checkPrecompileCompatible(address, precompileUpgrades, lastTimestamp); err != nil { + for _, module := range registerer.RegisteredModules() { + if err := c.checkPrecompileCompatible(module.Address(), precompileUpgrades, lastTimestamp); err != nil { return err } } @@ -243,8 +251,8 @@ func (c *ChainConfig) checkPrecompileCompatible(address common.Address, precompi // have been activated through an upgrade. func (c *ChainConfig) EnabledStatefulPrecompiles(blockTimestamp *big.Int) []config.Config { statefulPrecompileConfigs := make([]config.Config, 0) - for _, address := range config.GetAddresses() { - if config := c.GetActivePrecompileConfig(address, blockTimestamp); config != nil { + for _, module := range registerer.RegisteredModules() { + if config := c.GetActivePrecompileConfig(module.Address(), blockTimestamp); config != nil { statefulPrecompileConfigs = append(statefulPrecompileConfigs, config) } } diff --git a/params/precompile_upgrade_test.go b/params/precompile_upgrade_test.go new file mode 100644 index 0000000000..a8a667cb87 --- /dev/null +++ b/params/precompile_upgrade_test.go @@ -0,0 +1,285 @@ +// (c) 2022, Ava Labs, Inc. All rights reserved. +// See the file LICENSE for licensing terms. + +package params + +import ( + "math/big" + "testing" + + "github.com/ava-labs/subnet-evm/precompile/contracts/deployerallowlist" + "github.com/ava-labs/subnet-evm/precompile/contracts/txallowlist" + "github.com/ethereum/go-ethereum/common" + "github.com/stretchr/testify/assert" +) + +func TestVerifyUpgradeConfig(t *testing.T) { + admins := []common.Address{{1}} + chainConfig := *TestChainConfig + chainConfig.GenesisPrecompiles = ChainConfigPrecompiles{ + txallowlist.ConfigKey: txallowlist.NewTxAllowListConfig(big.NewInt(1), admins, nil), + } + + type test struct { + upgrades []PrecompileUpgrade + expectedErrorString string + } + + tests := map[string]test{ + "upgrade bytes conflicts with genesis (re-enable without disable)": { + expectedErrorString: "disable should be [true]", + upgrades: []PrecompileUpgrade{ + { + Config: txallowlist.NewTxAllowListConfig(big.NewInt(2), admins, nil), + }, + }, + }, + "upgrade bytes conflicts with genesis (disable before enable)": { + expectedErrorString: "config block timestamp (0) <= previous timestamp (1) of same key", + upgrades: []PrecompileUpgrade{ + { + Config: txallowlist.NewDisableTxAllowListConfig(big.NewInt(0)), + }, + }, + }, + "upgrade bytes conflicts with genesis (disable same time as enable)": { + expectedErrorString: "config block timestamp (1) <= previous timestamp (1) of same key", + upgrades: []PrecompileUpgrade{ + { + Config: txallowlist.NewDisableTxAllowListConfig(big.NewInt(1)), + }, + }, + }, + } + + for name, tt := range tests { + t.Run(name, func(t *testing.T) { + // make a local copy of the chainConfig + chainConfig := chainConfig + + // verify with the upgrades from the test + chainConfig.UpgradeConfig.PrecompileUpgrades = tt.upgrades + err := chainConfig.Verify() + + if tt.expectedErrorString != "" { + assert.ErrorContains(t, err, tt.expectedErrorString) + } else { + assert.NoError(t, err) + } + }) + } +} + +func TestCheckCompatibleUpgradeConfigs(t *testing.T) { + admins := []common.Address{{1}} + chainConfig := *TestChainConfig + chainConfig.GenesisPrecompiles = ChainConfigPrecompiles{ + txallowlist.ConfigKey: txallowlist.NewTxAllowListConfig(big.NewInt(1), admins, nil), + deployerallowlist.ConfigKey: deployerallowlist.NewContractDeployerAllowListConfig(big.NewInt(10), admins, nil), + } + + type test struct { + configs []*UpgradeConfig + startTimestamps []*big.Int + expectedErrorString string + } + + tests := map[string]test{ + "disable and re-enable": { + startTimestamps: []*big.Int{big.NewInt(5)}, + configs: []*UpgradeConfig{ + { + PrecompileUpgrades: []PrecompileUpgrade{ + { + Config: txallowlist.NewDisableTxAllowListConfig(big.NewInt(6)), + }, + { + Config: txallowlist.NewTxAllowListConfig(big.NewInt(7), admins, nil), + }, + }, + }, + }, + }, + "disable and re-enable, reschedule upgrade before it happens": { + startTimestamps: []*big.Int{big.NewInt(5), big.NewInt(6)}, + configs: []*UpgradeConfig{ + { + PrecompileUpgrades: []PrecompileUpgrade{ + { + Config: txallowlist.NewDisableTxAllowListConfig(big.NewInt(6)), + }, + { + Config: txallowlist.NewTxAllowListConfig(big.NewInt(7), admins, nil), + }, + }, + }, + { + PrecompileUpgrades: []PrecompileUpgrade{ + { + Config: txallowlist.NewDisableTxAllowListConfig(big.NewInt(6)), + }, + { + Config: txallowlist.NewTxAllowListConfig(big.NewInt(8), admins, nil), + }, + }, + }, + }, + }, + "disable and re-enable, reschedule upgrade after it happens": { + expectedErrorString: "mismatching PrecompileUpgrade", + startTimestamps: []*big.Int{big.NewInt(5), big.NewInt(8)}, + configs: []*UpgradeConfig{ + { + PrecompileUpgrades: []PrecompileUpgrade{ + { + Config: txallowlist.NewDisableTxAllowListConfig(big.NewInt(6)), + }, + { + Config: txallowlist.NewTxAllowListConfig(big.NewInt(7), admins, nil), + }, + }, + }, + { + PrecompileUpgrades: []PrecompileUpgrade{ + { + Config: txallowlist.NewDisableTxAllowListConfig(big.NewInt(6)), + }, + { + Config: txallowlist.NewTxAllowListConfig(big.NewInt(8), admins, nil), + }, + }, + }, + }, + }, + "disable and re-enable, cancel upgrade before it happens": { + startTimestamps: []*big.Int{big.NewInt(5), big.NewInt(6)}, + configs: []*UpgradeConfig{ + { + PrecompileUpgrades: []PrecompileUpgrade{ + { + Config: txallowlist.NewDisableTxAllowListConfig(big.NewInt(6)), + }, + { + Config: txallowlist.NewTxAllowListConfig(big.NewInt(7), admins, nil), + }, + }, + }, + { + PrecompileUpgrades: []PrecompileUpgrade{ + { + Config: txallowlist.NewDisableTxAllowListConfig(big.NewInt(6)), + }, + }, + }, + }, + }, + "disable and re-enable, cancel upgrade after it happens": { + expectedErrorString: "mismatching missing PrecompileUpgrade", + startTimestamps: []*big.Int{big.NewInt(5), big.NewInt(8)}, + configs: []*UpgradeConfig{ + { + PrecompileUpgrades: []PrecompileUpgrade{ + { + Config: txallowlist.NewDisableTxAllowListConfig(big.NewInt(6)), + }, + { + Config: txallowlist.NewTxAllowListConfig(big.NewInt(7), admins, nil), + }, + }, + }, + { + PrecompileUpgrades: []PrecompileUpgrade{ + { + Config: txallowlist.NewDisableTxAllowListConfig(big.NewInt(6)), + }, + }, + }, + }, + }, + "disable and re-enable, change upgrade config after upgrade not allowed": { + expectedErrorString: "mismatching PrecompileUpgrade", + startTimestamps: []*big.Int{big.NewInt(5), big.NewInt(8)}, + configs: []*UpgradeConfig{ + { + PrecompileUpgrades: []PrecompileUpgrade{ + { + Config: txallowlist.NewDisableTxAllowListConfig(big.NewInt(6)), + }, + { + Config: txallowlist.NewTxAllowListConfig(big.NewInt(7), admins, nil), + }, + }, + }, + { + PrecompileUpgrades: []PrecompileUpgrade{ + { + Config: txallowlist.NewDisableTxAllowListConfig(big.NewInt(6)), + }, + { + // uses a different (empty) admin list, not allowed + Config: txallowlist.NewTxAllowListConfig(big.NewInt(7), []common.Address{}, nil), + }, + }, + }, + }, + }, + "disable and re-enable, identical upgrade config should be accepted": { + startTimestamps: []*big.Int{big.NewInt(5), big.NewInt(8)}, + configs: []*UpgradeConfig{ + { + PrecompileUpgrades: []PrecompileUpgrade{ + { + Config: txallowlist.NewDisableTxAllowListConfig(big.NewInt(6)), + }, + { + Config: txallowlist.NewTxAllowListConfig(big.NewInt(7), admins, nil), + }, + }, + }, + { + PrecompileUpgrades: []PrecompileUpgrade{ + { + Config: txallowlist.NewDisableTxAllowListConfig(big.NewInt(6)), + }, + { + Config: txallowlist.NewTxAllowListConfig(big.NewInt(7), admins, nil), + }, + }, + }, + }, + }, + } + + for name, tt := range tests { + t.Run(name, func(t *testing.T) { + // make a local copy of the chainConfig + chainConfig := chainConfig + + // apply all the upgrade bytes specified in order + for i, upgrade := range tt.configs { + newCfg := chainConfig + newCfg.UpgradeConfig = *upgrade + + err := chainConfig.checkCompatible(&newCfg, nil, tt.startTimestamps[i]) + + // if this is not the final upgradeBytes, continue applying + // the next upgradeBytes. (only check the result on the last apply) + if i != len(tt.configs)-1 { + if err != nil { + t.Fatalf("expecting ApplyUpgradeBytes call %d to return nil, got %s", i+1, err) + } + chainConfig = newCfg + continue + } + + if tt.expectedErrorString != "" { + assert.ErrorContains(t, err, tt.expectedErrorString) + } else { + if err != nil { + t.Fatal(err) + } + } + } + }) + } +} diff --git a/plugin/evm/vm.go b/plugin/evm/vm.go index ae114d010b..ce029a6e3d 100644 --- a/plugin/evm/vm.go +++ b/plugin/evm/vm.go @@ -32,6 +32,7 @@ import ( "github.com/ava-labs/subnet-evm/params" "github.com/ava-labs/subnet-evm/peer" "github.com/ava-labs/subnet-evm/plugin/evm/message" + "github.com/ava-labs/subnet-evm/precompile/registry" "github.com/ava-labs/subnet-evm/rpc" statesyncclient "github.com/ava-labs/subnet-evm/sync/client" "github.com/ava-labs/subnet-evm/sync/client/stats" @@ -280,6 +281,10 @@ func (vm *VM) Initialize( return err } + if err := registry.RegisterPrecompileModules(); err != nil { + return err + } + if g.Config == nil { g.Config = params.SubnetEVMDefaultChainConfig } diff --git a/plugin/evm/vm_test.go b/plugin/evm/vm_test.go index b5069ad990..888030dce8 100644 --- a/plugin/evm/vm_test.go +++ b/plugin/evm/vm_test.go @@ -20,7 +20,6 @@ import ( "github.com/ava-labs/subnet-evm/commontype" "github.com/ava-labs/subnet-evm/metrics" "github.com/ava-labs/subnet-evm/precompile/allowlist" - precompileConfig "github.com/ava-labs/subnet-evm/precompile/config" "github.com/ava-labs/subnet-evm/precompile/contracts/deployerallowlist" "github.com/ava-labs/subnet-evm/precompile/contracts/feemanager" "github.com/ava-labs/subnet-evm/precompile/contracts/rewardmanager" @@ -2121,7 +2120,7 @@ func TestBuildAllowListActivationBlock(t *testing.T) { if err := genesis.UnmarshalJSON([]byte(genesisJSONSubnetEVM)); err != nil { t.Fatal(err) } - genesis.Config.GenesisPrecompiles = precompileConfig.Configs{ + genesis.Config.GenesisPrecompiles = params.ChainConfigPrecompiles{ deployerallowlist.ConfigKey: deployerallowlist.NewContractDeployerAllowListConfig(big.NewInt(time.Now().Unix()), testEthAddrs, nil), } @@ -2187,7 +2186,7 @@ func TestTxAllowListSuccessfulTx(t *testing.T) { if err := genesis.UnmarshalJSON([]byte(genesisJSONSubnetEVM)); err != nil { t.Fatal(err) } - genesis.Config.GenesisPrecompiles = precompileConfig.Configs{ + genesis.Config.GenesisPrecompiles = params.ChainConfigPrecompiles{ txallowlist.ConfigKey: txallowlist.NewTxAllowListConfig(big.NewInt(0), testEthAddrs[0:1], nil), } genesisJSON, err := genesis.MarshalJSON() @@ -2265,7 +2264,7 @@ func TestTxAllowListDisablePrecompile(t *testing.T) { t.Fatal(err) } enableAllowListTimestamp := time.Unix(0, 0) // enable at genesis - genesis.Config.GenesisPrecompiles = precompileConfig.Configs{ + genesis.Config.GenesisPrecompiles = params.ChainConfigPrecompiles{ txallowlist.ConfigKey: txallowlist.NewTxAllowListConfig(big.NewInt(enableAllowListTimestamp.Unix()), testEthAddrs[0:1], nil), } genesisJSON, err := genesis.MarshalJSON() @@ -2379,7 +2378,7 @@ func TestFeeManagerChangeFee(t *testing.T) { if err := genesis.UnmarshalJSON([]byte(genesisJSONSubnetEVM)); err != nil { t.Fatal(err) } - genesis.Config.GenesisPrecompiles = precompileConfig.Configs{ + genesis.Config.GenesisPrecompiles = params.ChainConfigPrecompiles{ feemanager.ConfigKey: feemanager.NewFeeManagerConfig(big.NewInt(0), testEthAddrs[0:1], nil, nil), } @@ -2621,7 +2620,7 @@ func TestRewardManagerPrecompileSetRewardAddress(t *testing.T) { genesis := &core.Genesis{} require.NoError(t, genesis.UnmarshalJSON([]byte(genesisJSONSubnetEVM))) - genesis.Config.GenesisPrecompiles = precompileConfig.Configs{ + genesis.Config.GenesisPrecompiles = params.ChainConfigPrecompiles{ rewardmanager.ConfigKey: rewardmanager.NewRewardManagerConfig(common.Big0, testEthAddrs[0:1], nil, nil), } genesis.Config.AllowFeeRecipients = true // enable this in genesis to test if this is recognized by the reward manager @@ -2763,7 +2762,7 @@ func TestRewardManagerPrecompileAllowFeeRecipients(t *testing.T) { genesis := &core.Genesis{} require.NoError(t, genesis.UnmarshalJSON([]byte(genesisJSONSubnetEVM))) - genesis.Config.GenesisPrecompiles = precompileConfig.Configs{ + genesis.Config.GenesisPrecompiles = params.ChainConfigPrecompiles{ rewardmanager.ConfigKey: rewardmanager.NewRewardManagerConfig(common.Big0, testEthAddrs[0:1], nil, nil), } genesis.Config.AllowFeeRecipients = false // disable this in genesis diff --git a/precompile/config/config.go b/precompile/config/config.go index 5f73ee70d9..cbfbd59a5a 100644 --- a/precompile/config/config.go +++ b/precompile/config/config.go @@ -5,10 +5,7 @@ package config import ( - "encoding/json" "math/big" - - "github.com/ethereum/go-ethereum/common" ) type Factory interface { @@ -18,8 +15,8 @@ type Factory interface { // StatefulPrecompileConfig defines the interface for a stateful precompile to // be enabled via a network upgrade. type Config interface { + // Key returns the unique key for the stateful precompile. Key() string - Address() common.Address // Timestamp returns the timestamp at which this stateful precompile should be enabled. // 1) 0 indicates that the precompile should be enabled from genesis. // 2) n indicates that the precompile should be enabled in the first block with timestamp >= [n]. @@ -32,37 +29,3 @@ type Config interface { // Verify is called on startup and an error is treated as fatal. Configure can assume the Config has passed verification. Verify() error } - -type Configs map[string]Config - -func (ccp Configs) GetConfigByAddress(addr common.Address) (Config, bool) { - config, ok := addressToConfigFactory[addr] - if !ok { - return nil, false - } - config, exists := ccp[config.Key()] - return config, exists -} - -// UnmarshalJSON parses the JSON-encoded data into the ChainConfigPrecompiles. -// ChainConfigPrecompiles is a map of precompile module keys to their -// configuration. -func (ccp *Configs) UnmarshalJSON(data []byte) error { - raw := make(map[string]json.RawMessage) - if err := json.Unmarshal(data, &raw); err != nil { - return err - } - - *ccp = make(Configs) - for name, configFactory := range registry { - if value, ok := raw[name]; ok { - conf := configFactory.NewConfig() - err := json.Unmarshal(value, conf) - if err != nil { - return err - } - (*ccp)[name] = conf - } - } - return nil -} diff --git a/precompile/config/registry.go b/precompile/config/registry.go deleted file mode 100644 index f8fb501f02..0000000000 --- a/precompile/config/registry.go +++ /dev/null @@ -1,61 +0,0 @@ -// (c) 2023, Ava Labs, Inc. All rights reserved. -// See the file LICENSE for licensing terms. - -// Defines the stateless interface for unmarshalling an arbitrary config of a precompile -package config - -import ( - "fmt" - - "github.com/ethereum/go-ethereum/common" -) - -// params package -// - IMPORTANT - cannot import precompile or statedb directly -// imports precompile/config to unmarshal relevant configs and nothing else -// this means that we also need to stop using AvalancheRules to hold the precompile contracts -// switch instead to map address -> config -// ActivePrecompiles was previously used to check if a precompile was enabled at that address, so we can still use this with the new map -// also used in core/vm/evm.go to get the precompile contract -// we will need to import the precompile/exec package to look up the precompile at that address now. - -// update package -// import params package and precompile/exec -// used to Configure precompiles - -var ( - registry = make(map[string]Factory) - addressToConfigFactory = make(map[common.Address]Config) - addresses = make([]common.Address, 0) - configs = make([]Config, 0) -) - -func RegisterConfig(name string, addr common.Address, configFactory Factory) error { - _, exists := registry[name] - if exists { - return fmt.Errorf("cannot register duplicate config with the name: %s", name) - } - _, exists = addressToConfigFactory[addr] - if exists { - return fmt.Errorf("cannot register duplicate config with address: %s", addr) - } - registry[name] = configFactory - addressToConfigFactory[addr] = configFactory.NewConfig() - addresses = append(addresses, addr) - configs = append(configs, configFactory.NewConfig()) - return nil -} - -func GetNewConfig(name string) (Config, bool) { - config, ok := registry[name] - if !ok { - return nil, false - } - return config.NewConfig(), true -} - -func GetAddresses() []common.Address { return addresses } - -func GetConfigs() []Config { return configs } - -// TODO: add lookups as needed diff --git a/precompile/contract/interfaces.go b/precompile/contract/interfaces.go index 6c49e5aaab..32d7e2607a 100644 --- a/precompile/contract/interfaces.go +++ b/precompile/contract/interfaces.go @@ -10,7 +10,6 @@ import ( "github.com/ava-labs/avalanchego/snow" "github.com/ava-labs/subnet-evm/commontype" "github.com/ava-labs/subnet-evm/precompile/config" - precompileConfig "github.com/ava-labs/subnet-evm/precompile/config" "github.com/ethereum/go-ethereum/common" ) @@ -70,13 +69,11 @@ type BlockContext interface { } type Module interface { - // Key returns the unique key for the stateful precompile. - Key() string // Address returns the address where the stateful precompile is accessible. Address() common.Address // Contract returns a thread-safe singleton that can be used as the StatefulPrecompiledContract when // this config is enabled. - Configure(chainConfig ChainConfig, precompileConfig precompileConfig.Config, state StateDB, blockContext BlockContext) error + Configure(chainConfig ChainConfig, precompileConfig config.Config, state StateDB, blockContext BlockContext) error Contract() StatefulPrecompiledContract config.Factory diff --git a/precompile/contracts/deployerallowlist/config.go b/precompile/contracts/deployerallowlist/config.go index f49cb2c610..38e1f2d2be 100644 --- a/precompile/contracts/deployerallowlist/config.go +++ b/precompile/contracts/deployerallowlist/config.go @@ -45,8 +45,6 @@ func NewDisableContractDeployerAllowListConfig(blockTimestamp *big.Int) *Contrac func (ContractDeployerAllowListConfig) Key() string { return ConfigKey } -func (ContractDeployerAllowListConfig) Address() common.Address { return ContractAddress } - // Equal returns true if [cfg] is a [*ContractDeployerAllowListConfig] and it has been configured identical to [c]. func (c *ContractDeployerAllowListConfig) Equal(cfg config.Config) bool { // typecast before comparison diff --git a/precompile/contracts/deployerallowlist/module.go b/precompile/contracts/deployerallowlist/module.go index 4ca34e95ec..46616e0b57 100644 --- a/precompile/contracts/deployerallowlist/module.go +++ b/precompile/contracts/deployerallowlist/module.go @@ -21,10 +21,6 @@ var ContractAddress = common.HexToAddress("0x02000000000000000000000000000000000 type Module struct{} -func (Module) Key() string { - return ConfigKey -} - // Address returns the address of the contract deployer allow list. func (Module) Address() common.Address { return ContractAddress diff --git a/precompile/contracts/feemanager/config.go b/precompile/contracts/feemanager/config.go index 8e463529d9..0623bcbd95 100644 --- a/precompile/contracts/feemanager/config.go +++ b/precompile/contracts/feemanager/config.go @@ -48,8 +48,6 @@ func NewDisableFeeManagerConfig(blockTimestamp *big.Int) *FeeManagerConfig { func (FeeManagerConfig) Key() string { return ConfigKey } -func (FeeManagerConfig) Address() common.Address { return ContractAddress } - // Equal returns true if [cfg] is a [*FeeManagerConfig] and it has been configured identical to [c]. func (c *FeeManagerConfig) Equal(cfg config.Config) bool { // typecast before comparison diff --git a/precompile/contracts/feemanager/module.go b/precompile/contracts/feemanager/module.go index 890ca19249..bfbb68af63 100644 --- a/precompile/contracts/feemanager/module.go +++ b/precompile/contracts/feemanager/module.go @@ -11,7 +11,7 @@ import ( "github.com/ethereum/go-ethereum/common" ) -var _ contract.Module = Module{} +var _ contract.Module = &Module{} // ConfigKey is the key used in json config files to specify this precompile config. // must be unique across all precompiles. @@ -21,10 +21,6 @@ var ContractAddress = common.HexToAddress("0x02000000000000000000000000000000000 type Module struct{} -func (Module) Key() string { - return ConfigKey -} - // Address returns the address of the fee manager. func (Module) Address() common.Address { return ContractAddress diff --git a/precompile/contracts/nativeminter/config.go b/precompile/contracts/nativeminter/config.go index f3cc43a29b..65da84f400 100644 --- a/precompile/contracts/nativeminter/config.go +++ b/precompile/contracts/nativeminter/config.go @@ -49,8 +49,6 @@ func NewDisableContractNativeMinterConfig(blockTimestamp *big.Int) *ContractNati } func (ContractNativeMinterConfig) Key() string { return ConfigKey } -func (ContractNativeMinterConfig) Address() common.Address { return ContractAddress } - // Equal returns true if [cfg] is a [*ContractNativeMinterConfig] and it has been configured identical to [c]. func (c *ContractNativeMinterConfig) Equal(cfg config.Config) bool { // typecast before comparison diff --git a/precompile/contracts/nativeminter/module.go b/precompile/contracts/nativeminter/module.go index e67496bb2c..2a0302563b 100644 --- a/precompile/contracts/nativeminter/module.go +++ b/precompile/contracts/nativeminter/module.go @@ -12,7 +12,7 @@ import ( "github.com/ethereum/go-ethereum/common" ) -var _ contract.Module = Module{} +var _ contract.Module = &Module{} // ConfigKey is the key used in json config files to specify this precompile config. // must be unique across all precompiles. @@ -22,10 +22,6 @@ var ContractAddress = common.HexToAddress("0x02000000000000000000000000000000000 type Module struct{} -func (Module) Key() string { - return ConfigKey -} - // Address returns the address of the native minter. func (Module) Address() common.Address { return ContractAddress diff --git a/precompile/contracts/rewardmanager/config.go b/precompile/contracts/rewardmanager/config.go index c0a828d4f0..5495f7d602 100644 --- a/precompile/contracts/rewardmanager/config.go +++ b/precompile/contracts/rewardmanager/config.go @@ -86,8 +86,6 @@ func NewDisableRewardManagerConfig(blockTimestamp *big.Int) *RewardManagerConfig } } -func (RewardManagerConfig) Address() common.Address { return ContractAddress } - func (RewardManagerConfig) Key() string { return ConfigKey } func (c *RewardManagerConfig) Verify() error { diff --git a/precompile/contracts/rewardmanager/module.go b/precompile/contracts/rewardmanager/module.go index aef1acd19d..8f5bdf9041 100644 --- a/precompile/contracts/rewardmanager/module.go +++ b/precompile/contracts/rewardmanager/module.go @@ -11,6 +11,8 @@ import ( "github.com/ethereum/go-ethereum/common" ) +var _ contract.Module = &Module{} + // ConfigKey is the key used in json config files to specify this precompile config. // must be unique across all precompiles. const ConfigKey = "rewardManagerConfig" @@ -19,10 +21,6 @@ var ContractAddress = common.HexToAddress("0x02000000000000000000000000000000000 type Module struct{} -func (Module) Key() string { - return ConfigKey -} - // Address returns the address of the reward manager. func (Module) Address() common.Address { return ContractAddress diff --git a/precompile/contracts/txallowlist/config.go b/precompile/contracts/txallowlist/config.go index b16573e704..8f7bfddf42 100644 --- a/precompile/contracts/txallowlist/config.go +++ b/precompile/contracts/txallowlist/config.go @@ -43,8 +43,6 @@ func NewDisableTxAllowListConfig(blockTimestamp *big.Int) *TxAllowListConfig { } } -func (_ *TxAllowListConfig) Address() common.Address { return ContractAddress } - func (c *TxAllowListConfig) Key() string { return ConfigKey } // Equal returns true if [cfg] is a [*TxAllowListConfig] and it has been configured identical to [c]. diff --git a/precompile/contracts/txallowlist/module.go b/precompile/contracts/txallowlist/module.go index 686e45da9a..c3d43ca586 100644 --- a/precompile/contracts/txallowlist/module.go +++ b/precompile/contracts/txallowlist/module.go @@ -11,7 +11,7 @@ import ( "github.com/ethereum/go-ethereum/common" ) -var _ contract.Module = Module{} +var _ contract.Module = &Module{} // ConfigKey is the key used in json config files to specify this precompile config. // must be unique across all precompiles. @@ -21,10 +21,6 @@ var ContractAddress = common.HexToAddress("0x02000000000000000000000000000000000 type Module struct{} -func (Module) Key() string { - return ConfigKey -} - // Address returns the address of the reward manager. func (Module) Address() common.Address { return ContractAddress diff --git a/precompile/registry/registerer.go b/precompile/registerer/registerer.go similarity index 80% rename from precompile/registry/registerer.go rename to precompile/registerer/registerer.go index 1cbd763e19..fbd41821d1 100644 --- a/precompile/registry/registerer.go +++ b/precompile/registerer/registerer.go @@ -1,12 +1,11 @@ // (c) 2023, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. -package registry +package registerer import ( "fmt" - "github.com/ava-labs/subnet-evm/precompile/config" "github.com/ava-labs/subnet-evm/precompile/contract" "github.com/ava-labs/subnet-evm/utils" "github.com/ethereum/go-ethereum/common" @@ -48,25 +47,15 @@ func ReservedAddress(addr common.Address) bool { } // RegisterModule registers a stateful precompile module -// This function should be called in the init function of the module -// to ensure that the module is registered before the node starts -// and the module is available for use. -// This function will panic if the module cannot be registered. -func RegisterModule(stm contract.Module) { - if err := registerModule(stm); err != nil { - panic(err) - } -} - -func registerModule(stm contract.Module) error { +func RegisterModule(stm contract.Module) error { address := stm.Address() - key := stm.Key() + key := stm.NewConfig().Key() if !ReservedAddress(address) { return fmt.Errorf("address %s not in a reserved range", address) } for _, module := range registeredModules { - if module.Key() == key { + if module.NewConfig().Key() == key { return fmt.Errorf("name %s already used by a stateful precompile", key) } if module.Address() == address { @@ -76,7 +65,7 @@ func registerModule(stm contract.Module) error { registeredModulesIndex[address] = len(registeredModules) registeredModules = append(registeredModules, stm) - return config.RegisterConfig(key, address, stm) + return nil } func GetPrecompileModuleByAddress(address common.Address) (contract.Module, bool) { @@ -90,7 +79,7 @@ func GetPrecompileModuleByAddress(address common.Address) (contract.Module, bool func GetPrecompileModule(key string) (contract.Module, bool) { for _, stm := range registeredModules { - if stm.Key() == key { + if stm.NewConfig().Key() == key { return stm, true } } diff --git a/precompile/registry/registry.go b/precompile/registry/registry.go index 40f586897a..3b76a9a431 100644 --- a/precompile/registry/registry.go +++ b/precompile/registry/registry.go @@ -5,23 +5,30 @@ package registry import ( + "github.com/ava-labs/avalanchego/utils/wrappers" "github.com/ava-labs/subnet-evm/precompile/contracts/deployerallowlist" "github.com/ava-labs/subnet-evm/precompile/contracts/feemanager" "github.com/ava-labs/subnet-evm/precompile/contracts/nativeminter" "github.com/ava-labs/subnet-evm/precompile/contracts/rewardmanager" "github.com/ava-labs/subnet-evm/precompile/contracts/txallowlist" + "github.com/ava-labs/subnet-evm/precompile/registerer" ) -func init() { - // Order is important here. - // RegisterModule registers a precompile in the order it is registered. - // The order of registration is important because it determines the configuration order - // in the state. - RegisterModule(deployerallowlist.Module{}) - RegisterModule(nativeminter.Module{}) - RegisterModule(txallowlist.Module{}) - RegisterModule(feemanager.Module{}) - RegisterModule(rewardmanager.Module{}) +func RegisterPrecompileModules() error { + errs := wrappers.Errs{} + errs.Add( + // Order is important here. + // RegisterModule registers a precompile in the order it is registered. + // The order of registration is important because it determines the configuration order + // in the state. + registerer.RegisterModule(deployerallowlist.Module{}), + registerer.RegisterModule(nativeminter.Module{}), + registerer.RegisterModule(txallowlist.Module{}), + registerer.RegisterModule(feemanager.Module{}), + registerer.RegisterModule(rewardmanager.Module{}), // ADD YOUR PRECOMPILE HERE - // precompile.RegisterModule({yourPrecompilePackage}.{YourPrecompile}Config{}) + // precompile.RegisterModule({yourPrecompilePackage}.{YourPrecompile}Config{}), + ) + + return errs.Err } From 43540f71ccb99a18d501d1af361d5f5088dd1256 Mon Sep 17 00:00:00 2001 From: Ceyhun Onur Date: Tue, 14 Feb 2023 12:20:59 +0300 Subject: [PATCH 2/5] fix modules --- core/state_processor.go | 8 +-- core/vm/contracts.go | 2 +- core/vm/evm.go | 2 +- internal/ethapi/api.go | 2 +- params/config.go | 4 +- params/config_test.go | 6 -- params/precompile_upgrade.go | 4 +- plugin/evm/vm.go | 8 +-- plugin/evm/vm_test.go | 6 +- precompile/allowlist/role.go | 14 +++++ precompile/config/config.go | 4 -- precompile/contract/interfaces.go | 20 +++++-- .../contracts/deployerallowlist/module.go | 24 ++++---- .../contracts/feemanager/contract_test.go | 2 +- precompile/contracts/feemanager/module.go | 24 ++++---- .../contracts/nativeminter/contract_test.go | 2 +- precompile/contracts/nativeminter/module.go | 24 ++++---- .../contracts/rewardmanager/contract.go | 25 ++++---- .../contracts/rewardmanager/contract_test.go | 2 +- precompile/contracts/rewardmanager/module.go | 24 ++++---- precompile/contracts/txallowlist/module.go | 24 ++++---- precompile/registerer/registerer.go | 58 +++++++++++++------ precompile/registerer/registerer_test.go | 45 ++++++++++++++ precompile/registry/registry.go | 36 ++++-------- 24 files changed, 217 insertions(+), 153 deletions(-) create mode 100644 precompile/registerer/registerer_test.go diff --git a/core/state_processor.go b/core/state_processor.go index 66dcac6deb..d202eaf350 100644 --- a/core/state_processor.go +++ b/core/state_processor.go @@ -185,12 +185,12 @@ func ApplyPrecompileActivations(c *params.ChainConfig, parentTimestamp *big.Int, // so that the state is deterministic. for _, module := range registerer.RegisteredModules() { key := module.NewConfig().Key() - for _, activatingConfig := range c.GetActivatingPrecompileConfigs(module.Address(), parentTimestamp, blockTimestamp, c.PrecompileUpgrades) { + for _, activatingConfig := range c.GetActivatingPrecompileConfigs(module.Address, parentTimestamp, blockTimestamp, c.PrecompileUpgrades) { // If this transition activates the upgrade, configure the stateful precompile. // (or deconfigure it if it is being disabled.) if activatingConfig.IsDisabled() { log.Info("Disabling precompile", "name", key) - statedb.Suicide(module.Address()) + statedb.Suicide(module.Address) // Calling Finalise here effectively commits Suicide call and wipes the contract state. // This enables re-configuration of the same contract state in the same block. // Without an immediate Finalise call after the Suicide, a reconfigured precompiled state can be wiped out @@ -204,11 +204,11 @@ func ApplyPrecompileActivations(c *params.ChainConfig, parentTimestamp *big.Int, log.Info("Activating new precompile", "name", key, "config", activatingConfig) // Set the nonce of the precompile's address (as is done when a contract is created) to ensure // that it is marked as non-empty and will not be cleaned up when the statedb is finalized. - statedb.SetNonce(module.Address(), 1) + statedb.SetNonce(module.Address, 1) // Set the code of the precompile's address to a non-zero length byte slice to ensure that the precompile // 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}) + statedb.SetCode(module.Address, []byte{0x1}) if err := module.Configure(c, activatingConfig, statedb, blockContext); err != nil { return fmt.Errorf("could not configure precompile, name: %s, reason: %w", key, err) } diff --git a/core/vm/contracts.go b/core/vm/contracts.go index 58da3ab21e..60728cc5ed 100644 --- a/core/vm/contracts.go +++ b/core/vm/contracts.go @@ -160,7 +160,7 @@ func init() { // Ensure that this package will panic during init if there is a conflict present with the declared // precompile addresses. for _, module := range registerer.RegisteredModules() { - address := module.Address() + address := module.Address if _, ok := PrecompileAllNativeAddresses[address]; ok { panic(fmt.Errorf("precompile address collides with existing native address: %s", address)) } diff --git a/core/vm/evm.go b/core/vm/evm.go index 7c258e3cf9..5e3739705f 100644 --- a/core/vm/evm.go +++ b/core/vm/evm.go @@ -95,7 +95,7 @@ func (evm *EVM) precompile(addr common.Address) (contract.StatefulPrecompiledCon // Otherwise, check the chain rules for the additionally configured precompiles. if _, ok = evm.chainRules.ActivePrecompiles[addr]; ok { module, ok := registerer.GetPrecompileModuleByAddress(addr) - return module.Contract(), ok + return module.Contract, ok } return nil, false diff --git a/internal/ethapi/api.go b/internal/ethapi/api.go index 787a9eedd0..2b5852655a 100644 --- a/internal/ethapi/api.go +++ b/internal/ethapi/api.go @@ -634,7 +634,7 @@ func (s *BlockChainAPI) GetActivePrecompilesAt(ctx context.Context, blockTimesta } res := make(params.ChainConfigPrecompiles) for _, module := range registerer.RegisteredModules() { - if config := s.b.ChainConfig().GetActivePrecompileConfig(module.Address(), blockTimestamp); config != nil && !config.IsDisabled() { + if config := s.b.ChainConfig().GetActivePrecompileConfig(module.Address, blockTimestamp); config != nil && !config.IsDisabled() { res[module.NewConfig().Key()] = config } } diff --git a/params/config.go b/params/config.go index a967d10020..d8ed64d11b 100644 --- a/params/config.go +++ b/params/config.go @@ -597,8 +597,8 @@ func (c *ChainConfig) AvalancheRules(blockNum, blockTimestamp *big.Int) Rules { // Initialize the stateful precompiles that should be enabled at [blockTimestamp]. rules.ActivePrecompiles = make(map[common.Address]config.Config) for _, module := range registerer.RegisteredModules() { - if config := c.GetActivePrecompileConfig(module.Address(), blockTimestamp); config != nil { - rules.ActivePrecompiles[module.Address()] = config + if config := c.GetActivePrecompileConfig(module.Address, blockTimestamp); config != nil { + rules.ActivePrecompiles[module.Address] = config } } diff --git a/params/config_test.go b/params/config_test.go index d74ec53b59..b4f3b003bd 100644 --- a/params/config_test.go +++ b/params/config_test.go @@ -34,16 +34,10 @@ import ( "github.com/ava-labs/subnet-evm/precompile/contracts/nativeminter" "github.com/ava-labs/subnet-evm/precompile/contracts/rewardmanager" - "github.com/ava-labs/subnet-evm/precompile/registry" "github.com/ethereum/go-ethereum/common" "github.com/stretchr/testify/require" ) -func init() { - // We need to explicitly register the precompiles here. - _ = registry.RegisterPrecompileModules() -} - func TestCheckCompatible(t *testing.T) { type test struct { stored, new *ChainConfig diff --git a/params/precompile_upgrade.go b/params/precompile_upgrade.go index 527e2af8c0..694ac24c03 100644 --- a/params/precompile_upgrade.go +++ b/params/precompile_upgrade.go @@ -199,7 +199,7 @@ func (c *ChainConfig) GetActivatingPrecompileConfigs(address common.Address, fro // This ensures that as long as the node has not accepted a block with a different rule set it will allow a new upgrade to be applied as long as it activates after the last accepted block. func (c *ChainConfig) CheckPrecompilesCompatible(precompileUpgrades []PrecompileUpgrade, lastTimestamp *big.Int) *ConfigCompatError { for _, module := range registerer.RegisteredModules() { - if err := c.checkPrecompileCompatible(module.Address(), precompileUpgrades, lastTimestamp); err != nil { + if err := c.checkPrecompileCompatible(module.Address, precompileUpgrades, lastTimestamp); err != nil { return err } } @@ -252,7 +252,7 @@ func (c *ChainConfig) checkPrecompileCompatible(address common.Address, precompi func (c *ChainConfig) EnabledStatefulPrecompiles(blockTimestamp *big.Int) []config.Config { statefulPrecompileConfigs := make([]config.Config, 0) for _, module := range registerer.RegisteredModules() { - if config := c.GetActivePrecompileConfig(module.Address(), blockTimestamp); config != nil { + if config := c.GetActivePrecompileConfig(module.Address, blockTimestamp); config != nil { statefulPrecompileConfigs = append(statefulPrecompileConfigs, config) } } diff --git a/plugin/evm/vm.go b/plugin/evm/vm.go index ce029a6e3d..1721ed1f25 100644 --- a/plugin/evm/vm.go +++ b/plugin/evm/vm.go @@ -32,7 +32,6 @@ import ( "github.com/ava-labs/subnet-evm/params" "github.com/ava-labs/subnet-evm/peer" "github.com/ava-labs/subnet-evm/plugin/evm/message" - "github.com/ava-labs/subnet-evm/precompile/registry" "github.com/ava-labs/subnet-evm/rpc" statesyncclient "github.com/ava-labs/subnet-evm/sync/client" "github.com/ava-labs/subnet-evm/sync/client/stats" @@ -47,6 +46,9 @@ import ( // inside of cmd/geth. _ "github.com/ava-labs/subnet-evm/eth/tracers/native" + // Force-load precompiles to trigger registration + _ "github.com/ava-labs/subnet-evm/precompile/registry" + "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/log" "github.com/ethereum/go-ethereum/rlp" @@ -281,10 +283,6 @@ func (vm *VM) Initialize( return err } - if err := registry.RegisterPrecompileModules(); err != nil { - return err - } - if g.Config == nil { g.Config = params.SubnetEVMDefaultChainConfig } diff --git a/plugin/evm/vm_test.go b/plugin/evm/vm_test.go index 888030dce8..c7ddf0f3bf 100644 --- a/plugin/evm/vm_test.go +++ b/plugin/evm/vm_test.go @@ -2175,7 +2175,7 @@ func TestBuildAllowListActivationBlock(t *testing.T) { } role = deployerallowlist.GetContractDeployerAllowListStatus(blkState, testEthAddrs[0]) if role != allowlist.AdminRole { - t.Fatalf("Expected allow list status to be set to Admin: %s, but found: %s", allowlist.AdminRole, role) + t.Fatalf("Expected allow list status to be set role %s, but found: %s", allowlist.AdminRole, role) } } @@ -2420,11 +2420,11 @@ func TestFeeManagerChangeFee(t *testing.T) { // Check that address 0 is whitelisted and address 1 is not role := feemanager.GetFeeManagerStatus(genesisState, testEthAddrs[0]) if role != allowlist.AdminRole { - t.Fatalf("Expected fee manager list status to be set to admin: %s, but found: %s", feemanager.ContractAddress, role) + t.Fatalf("Expected fee manager list status to be set to admin: %s, but found: %s", allowlist.AdminRole, role) } role = feemanager.GetFeeManagerStatus(genesisState, testEthAddrs[1]) if role != allowlist.NoRole { - t.Fatalf("Expected fee manager list status to be set to no role: %s, but found: %s", feemanager.ContractAddress, role) + t.Fatalf("Expected fee manager list status to be set to no role: %s, but found: %s", allowlist.AdminRole, role) } // Contract is initialized but no preconfig is given, reader should return genesis fee config feeConfig, lastChangedAt, err := vm.blockChain.GetFeeConfigAt(vm.blockChain.Genesis().Header()) diff --git a/precompile/allowlist/role.go b/precompile/allowlist/role.go index 3666b818d1..aa55007662 100644 --- a/precompile/allowlist/role.go +++ b/precompile/allowlist/role.go @@ -47,3 +47,17 @@ func (s Role) IsEnabled() bool { return false } } + +// String returns a string representation of [s]. +func (s Role) String() string { + switch s { + case NoRole: + return "NoRole" + case EnabledRole: + return "EnabledRole" + case AdminRole: + return "AdminRole" + default: + return "UnknownRole" + } +} diff --git a/precompile/config/config.go b/precompile/config/config.go index cbfbd59a5a..63ccf43dad 100644 --- a/precompile/config/config.go +++ b/precompile/config/config.go @@ -8,10 +8,6 @@ import ( "math/big" ) -type Factory interface { - NewConfig() Config -} - // StatefulPrecompileConfig defines the interface for a stateful precompile to // be enabled via a network upgrade. type Config interface { diff --git a/precompile/contract/interfaces.go b/precompile/contract/interfaces.go index 32d7e2607a..94ce4d0cab 100644 --- a/precompile/contract/interfaces.go +++ b/precompile/contract/interfaces.go @@ -68,13 +68,21 @@ type BlockContext interface { Timestamp() *big.Int } -type Module interface { +type Configurator interface { + NewConfig() config.Config + Configure( + chainConfig ChainConfig, + precompileConfig config.Config, + state StateDB, + blockContext BlockContext, + ) error +} + +type Module struct { // Address returns the address where the stateful precompile is accessible. - Address() common.Address + Address common.Address // Contract returns a thread-safe singleton that can be used as the StatefulPrecompiledContract when // this config is enabled. - Configure(chainConfig ChainConfig, precompileConfig config.Config, state StateDB, blockContext BlockContext) error - Contract() StatefulPrecompiledContract - - config.Factory + Contract StatefulPrecompiledContract + Configurator } diff --git a/precompile/contracts/deployerallowlist/module.go b/precompile/contracts/deployerallowlist/module.go index 46616e0b57..b267fa05d9 100644 --- a/precompile/contracts/deployerallowlist/module.go +++ b/precompile/contracts/deployerallowlist/module.go @@ -8,37 +8,37 @@ import ( "github.com/ava-labs/subnet-evm/precompile/config" "github.com/ava-labs/subnet-evm/precompile/contract" + "github.com/ava-labs/subnet-evm/precompile/registerer" "github.com/ethereum/go-ethereum/common" ) -var _ contract.Module = Module{} - // ConfigKey is the key used in json config files to specify this precompile config. // must be unique across all precompiles. const ConfigKey = "contractDeployerAllowListConfig" var ContractAddress = common.HexToAddress("0x0200000000000000000000000000000000000000") -type Module struct{} +var Module = contract.Module{ + Address: ContractAddress, + Contract: ContractDeployerAllowListPrecompile, + Configurator: &configuror{}, +} + +type configuror struct{} -// Address returns the address of the contract deployer allow list. -func (Module) Address() common.Address { - return ContractAddress +func init() { + registerer.RegisterModule(Module) } -func (Module) NewConfig() config.Config { +func (*configuror) NewConfig() config.Config { return &ContractDeployerAllowListConfig{} } // Configure configures [state] with the desired admins based on [cfg]. -func (Module) Configure(_ contract.ChainConfig, cfg config.Config, state contract.StateDB, _ contract.BlockContext) error { +func (c *configuror) Configure(_ contract.ChainConfig, cfg config.Config, state contract.StateDB, _ contract.BlockContext) error { config, ok := cfg.(*ContractDeployerAllowListConfig) if !ok { return fmt.Errorf("incorrect config %T: %v", config, config) } return config.AllowListConfig.Configure(state, ContractAddress) } - -func (Module) Contract() contract.StatefulPrecompiledContract { - return ContractDeployerAllowListPrecompile -} diff --git a/precompile/contracts/feemanager/contract_test.go b/precompile/contracts/feemanager/contract_test.go index 5dc5d44b64..d28e3cb8c8 100644 --- a/precompile/contracts/feemanager/contract_test.go +++ b/precompile/contracts/feemanager/contract_test.go @@ -253,7 +253,7 @@ func TestFeeManagerRun(t *testing.T) { blockContext := contract.NewMockBlockContext(testBlockNumber, 0) accesibleState := contract.NewMockAccessibleState(state, blockContext, snow.DefaultContextTest()) if test.config != nil { - Module{}.Configure(nil, test.config, state, blockContext) + Module.Configure(nil, test.config, state, blockContext) } ret, remainingGas, err := FeeManagerPrecompile.Run(accesibleState, test.caller, ContractAddress, test.input(), test.suppliedGas, test.readOnly) if len(test.expectedErr) != 0 { diff --git a/precompile/contracts/feemanager/module.go b/precompile/contracts/feemanager/module.go index bfbb68af63..2b71c3e15f 100644 --- a/precompile/contracts/feemanager/module.go +++ b/precompile/contracts/feemanager/module.go @@ -8,30 +8,34 @@ import ( "github.com/ava-labs/subnet-evm/precompile/config" "github.com/ava-labs/subnet-evm/precompile/contract" + "github.com/ava-labs/subnet-evm/precompile/registerer" "github.com/ethereum/go-ethereum/common" ) -var _ contract.Module = &Module{} - // ConfigKey is the key used in json config files to specify this precompile config. // must be unique across all precompiles. const ConfigKey = "feeManagerConfig" var ContractAddress = common.HexToAddress("0x0200000000000000000000000000000000000003") -type Module struct{} +var Module = contract.Module{ + Address: ContractAddress, + Contract: FeeManagerPrecompile, + Configurator: &configuror{}, +} + +type configuror struct{} -// Address returns the address of the fee manager. -func (Module) Address() common.Address { - return ContractAddress +func init() { + registerer.RegisterModule(Module) } -func (Module) NewConfig() config.Config { +func (*configuror) NewConfig() config.Config { return &FeeManagerConfig{} } // Configure configures [state] with the desired admins based on [configIface]. -func (Module) Configure(chainConfig contract.ChainConfig, cfg config.Config, state contract.StateDB, blockContext contract.BlockContext) error { +func (*configuror) Configure(chainConfig contract.ChainConfig, cfg config.Config, state contract.StateDB, blockContext contract.BlockContext) error { config, ok := cfg.(*FeeManagerConfig) if !ok { return fmt.Errorf("incorrect config %T: %v", config, config) @@ -50,7 +54,3 @@ func (Module) Configure(chainConfig contract.ChainConfig, cfg config.Config, sta } return config.AllowListConfig.Configure(state, ContractAddress) } - -func (Module) Contract() contract.StatefulPrecompiledContract { - return FeeManagerPrecompile -} diff --git a/precompile/contracts/nativeminter/contract_test.go b/precompile/contracts/nativeminter/contract_test.go index bcd31a9fa9..f1cdfeb881 100644 --- a/precompile/contracts/nativeminter/contract_test.go +++ b/precompile/contracts/nativeminter/contract_test.go @@ -171,7 +171,7 @@ func TestContractNativeMinterRun(t *testing.T) { blockContext := contract.NewMockBlockContext(common.Big0, 0) accesibleState := contract.NewMockAccessibleState(state, blockContext, snow.DefaultContextTest()) if test.config != nil { - Module{}.Configure(params.TestChainConfig, test.config, state, blockContext) + Module.Configure(params.TestChainConfig, test.config, state, blockContext) } if test.input != nil { ret, remainingGas, err := ContractNativeMinterPrecompile.Run(accesibleState, test.caller, ContractAddress, test.input(), test.suppliedGas, test.readOnly) diff --git a/precompile/contracts/nativeminter/module.go b/precompile/contracts/nativeminter/module.go index 2a0302563b..f2eee9caf1 100644 --- a/precompile/contracts/nativeminter/module.go +++ b/precompile/contracts/nativeminter/module.go @@ -9,30 +9,34 @@ import ( "github.com/ava-labs/subnet-evm/precompile/config" "github.com/ava-labs/subnet-evm/precompile/contract" + "github.com/ava-labs/subnet-evm/precompile/registerer" "github.com/ethereum/go-ethereum/common" ) -var _ contract.Module = &Module{} - // ConfigKey is the key used in json config files to specify this precompile config. // must be unique across all precompiles. const ConfigKey = "contractNativeMinterConfig" var ContractAddress = common.HexToAddress("0x0200000000000000000000000000000000000001") -type Module struct{} +var Module = contract.Module{ + Address: ContractAddress, + Contract: ContractNativeMinterPrecompile, + Configurator: &configuror{}, +} + +type configuror struct{} -// Address returns the address of the native minter. -func (Module) Address() common.Address { - return ContractAddress +func init() { + registerer.RegisterModule(Module) } -func (Module) NewConfig() config.Config { +func (*configuror) NewConfig() config.Config { return &ContractNativeMinterConfig{} } // Configure configures [state] with the desired admins based on [cfg]. -func (Module) Configure(_ contract.ChainConfig, cfg config.Config, state contract.StateDB, _ contract.BlockContext) error { +func (*configuror) Configure(_ contract.ChainConfig, cfg config.Config, state contract.StateDB, _ contract.BlockContext) error { config, ok := cfg.(*ContractNativeMinterConfig) if !ok { return fmt.Errorf("incorrect config %T: %v", config, config) @@ -46,7 +50,3 @@ func (Module) Configure(_ contract.ChainConfig, cfg config.Config, state contrac return config.AllowListConfig.Configure(state, ContractAddress) } - -func (Module) Contract() contract.StatefulPrecompiledContract { - return ContractNativeMinterPrecompile -} diff --git a/precompile/contracts/rewardmanager/contract.go b/precompile/contracts/rewardmanager/contract.go index 9edc1d8e5f..1fc38790a4 100644 --- a/precompile/contracts/rewardmanager/contract.go +++ b/precompile/contracts/rewardmanager/contract.go @@ -45,23 +45,20 @@ var ( //go:embed contract.abi RewardManagerRawABI string - RewardManagerABI abi.ABI // will be initialized by init function - RewardManagerPrecompile contract.StatefulPrecompiledContract // will be initialized by init function + RewardManagerABI = parseABI(RewardManagerRawABI) + RewardManagerPrecompile = createRewardManagerPrecompile() // will be initialized by init function rewardAddressStorageKey = common.Hash{'r', 'a', 's', 'k'} allowFeeRecipientsAddressValue = common.Hash{'a', 'f', 'r', 'a', 'v'} ) -func init() { - parsed, err := abi.JSON(strings.NewReader(RewardManagerRawABI)) - if err != nil { - panic(err) - } - RewardManagerABI = parsed - RewardManagerPrecompile, err = createRewardManagerPrecompile() +func parseABI(rawABI string) abi.ABI { + parsed, err := abi.JSON(strings.NewReader(rawABI)) if err != nil { panic(err) } + + return parsed } // GetRewardManagerAllowListStatus returns the role of [address] for the RewardManager list. @@ -285,7 +282,7 @@ func disableRewards(accessibleState contract.AccessibleState, caller common.Addr // createRewardManagerPrecompile returns a StatefulPrecompiledContract with getters and setters for the precompile. // Access to the getters/setters is controlled by an allow list for [precompileAddr]. -func createRewardManagerPrecompile() (contract.StatefulPrecompiledContract, error) { +func createRewardManagerPrecompile() contract.StatefulPrecompiledContract { var functions []*contract.StatefulPrecompileFunction functions = append(functions, allowlist.CreateAllowListFunctions(ContractAddress)...) abiFunctionMap := map[string]contract.RunStatefulPrecompileFunc{ @@ -299,11 +296,15 @@ func createRewardManagerPrecompile() (contract.StatefulPrecompiledContract, erro for name, function := range abiFunctionMap { method, ok := RewardManagerABI.Methods[name] if !ok { - return nil, fmt.Errorf("given method (%s) does not exist in the ABI", name) + panic(fmt.Errorf("given method (%s) does not exist in the ABI", name)) } functions = append(functions, contract.NewStatefulPrecompileFunction(method.ID, function)) } // Construct the contract with no fallback function. - return contract.NewStatefulPrecompileContract(nil, functions) + statefulContract, err := contract.NewStatefulPrecompileContract(nil, functions) + if err != nil { + panic(err) + } + return statefulContract } diff --git a/precompile/contracts/rewardmanager/contract_test.go b/precompile/contracts/rewardmanager/contract_test.go index 1fd730523c..b511bbd79f 100644 --- a/precompile/contracts/rewardmanager/contract_test.go +++ b/precompile/contracts/rewardmanager/contract_test.go @@ -298,7 +298,7 @@ func TestRewardManagerRun(t *testing.T) { accesibleState := contract.NewMockAccessibleState(state, blockContext, snow.DefaultContextTest()) if test.config != nil { - Module{}.Configure(nil, test.config, state, blockContext) + Module.Configure(nil, test.config, state, blockContext) } ret, remainingGas, err := RewardManagerPrecompile.Run(accesibleState, test.caller, ContractAddress, test.input(), test.suppliedGas, test.readOnly) if len(test.expectedErr) != 0 { diff --git a/precompile/contracts/rewardmanager/module.go b/precompile/contracts/rewardmanager/module.go index 8f5bdf9041..8a1d901567 100644 --- a/precompile/contracts/rewardmanager/module.go +++ b/precompile/contracts/rewardmanager/module.go @@ -8,30 +8,34 @@ import ( "github.com/ava-labs/subnet-evm/precompile/config" "github.com/ava-labs/subnet-evm/precompile/contract" + "github.com/ava-labs/subnet-evm/precompile/registerer" "github.com/ethereum/go-ethereum/common" ) -var _ contract.Module = &Module{} - // ConfigKey is the key used in json config files to specify this precompile config. // must be unique across all precompiles. const ConfigKey = "rewardManagerConfig" var ContractAddress = common.HexToAddress("0x0200000000000000000000000000000000000004") -type Module struct{} +var Module = contract.Module{ + Address: ContractAddress, + Contract: RewardManagerPrecompile, + Configurator: &configuror{}, +} + +type configuror struct{} -// Address returns the address of the reward manager. -func (Module) Address() common.Address { - return ContractAddress +func init() { + registerer.RegisterModule(Module) } -func (Module) NewConfig() config.Config { +func (*configuror) NewConfig() config.Config { return &RewardManagerConfig{} } // Configure configures [state] with the desired admins based on [cfg]. -func (Module) Configure(chainConfig contract.ChainConfig, cfg config.Config, state contract.StateDB, _ contract.BlockContext) error { +func (*configuror) Configure(chainConfig contract.ChainConfig, cfg config.Config, state contract.StateDB, _ contract.BlockContext) error { config, ok := cfg.(*RewardManagerConfig) if !ok { return fmt.Errorf("incorrect config %T: %v", config, config) @@ -54,7 +58,3 @@ func (Module) Configure(chainConfig contract.ChainConfig, cfg config.Config, sta } return nil } - -func (Module) Contract() contract.StatefulPrecompiledContract { - return RewardManagerPrecompile -} diff --git a/precompile/contracts/txallowlist/module.go b/precompile/contracts/txallowlist/module.go index c3d43ca586..95018e1b24 100644 --- a/precompile/contracts/txallowlist/module.go +++ b/precompile/contracts/txallowlist/module.go @@ -8,37 +8,37 @@ import ( "github.com/ava-labs/subnet-evm/precompile/config" "github.com/ava-labs/subnet-evm/precompile/contract" + "github.com/ava-labs/subnet-evm/precompile/registerer" "github.com/ethereum/go-ethereum/common" ) -var _ contract.Module = &Module{} - // ConfigKey is the key used in json config files to specify this precompile config. // must be unique across all precompiles. const ConfigKey = "txAllowListConfig" var ContractAddress = common.HexToAddress("0x0200000000000000000000000000000000000002") -type Module struct{} +var Module = contract.Module{ + Address: ContractAddress, + Contract: TxAllowListPrecompile, + Configurator: &configuror{}, +} + +type configuror struct{} -// Address returns the address of the reward manager. -func (Module) Address() common.Address { - return ContractAddress +func init() { + registerer.RegisterModule(Module) } -func (Module) NewConfig() config.Config { +func (*configuror) NewConfig() config.Config { return &TxAllowListConfig{} } // Configure configures [state] with the desired admins based on [cfg]. -func (Module) Configure(chainConfig contract.ChainConfig, cfg config.Config, state contract.StateDB, _ contract.BlockContext) error { +func (*configuror) Configure(chainConfig contract.ChainConfig, cfg config.Config, state contract.StateDB, _ contract.BlockContext) error { config, ok := cfg.(*TxAllowListConfig) if !ok { return fmt.Errorf("incorrect config %T: %v", config, config) } return config.AllowListConfig.Configure(state, ContractAddress) } - -func (Module) Contract() contract.StatefulPrecompiledContract { - return TxAllowListPrecompile -} diff --git a/precompile/registerer/registerer.go b/precompile/registerer/registerer.go index fbd41821d1..485d704a31 100644 --- a/precompile/registerer/registerer.go +++ b/precompile/registerer/registerer.go @@ -4,6 +4,7 @@ package registerer import ( + "bytes" "fmt" "github.com/ava-labs/subnet-evm/precompile/contract" @@ -12,9 +13,6 @@ import ( ) var ( - // registeredModulesIndex is a map of key to Module - // used to quickly look up a module by key - registeredModulesIndex = make(map[common.Address]int, 0) // registeredModules is a list of Module to preserve order // for deterministic iteration registeredModules = make([]contract.Module, 0) @@ -48,33 +46,32 @@ func ReservedAddress(addr common.Address) bool { // RegisterModule registers a stateful precompile module func RegisterModule(stm contract.Module) error { - address := stm.Address() + address := stm.Address key := stm.NewConfig().Key() if !ReservedAddress(address) { return fmt.Errorf("address %s not in a reserved range", address) } - for _, module := range registeredModules { - if module.NewConfig().Key() == key { + for _, registeredModule := range registeredModules { + if registeredModule.NewConfig().Key() == key { return fmt.Errorf("name %s already used by a stateful precompile", key) } - if module.Address() == address { + if registeredModule.Address == address { return fmt.Errorf("address %s already used by a stateful precompile", address) } } - - registeredModulesIndex[address] = len(registeredModules) - registeredModules = append(registeredModules, stm) + // sort by address to ensure deterministic iteration + registeredModules = insertSortedByAddress(registeredModules, stm) return nil } func GetPrecompileModuleByAddress(address common.Address) (contract.Module, bool) { - index, ok := registeredModulesIndex[address] - if !ok { - return nil, false + for _, stm := range registeredModules { + if stm.Address == address { + return stm, true + } } - - return registeredModules[index], true + return contract.Module{}, false } func GetPrecompileModule(key string) (contract.Module, bool) { @@ -83,10 +80,37 @@ func GetPrecompileModule(key string) (contract.Module, bool) { return stm, true } } - - return nil, false + return contract.Module{}, false } func RegisteredModules() []contract.Module { return registeredModules } + +func insertSortedByAddress(data []contract.Module, stm contract.Module) []contract.Module { + // sort by address to ensure deterministic iteration + // start at the end of the list and work backwards + // this is faster than sorting the list every time + // since we expect sorted inserts + index := 0 + for i := len(data) - 1; i >= 0; i-- { + if bytes.Compare(stm.Address.Bytes(), data[i].Address.Bytes()) > 0 { + index = i + 1 + break + } + } + return insertAt(data, index, stm) +} + +func insertAt(data []contract.Module, index int, stm contract.Module) []contract.Module { + // if the index is out of bounds, append the module + if index >= len(data) { + data = append(data, stm) + return data + } + // shift the slice to the right and leave a space for the new element + data = append(data[:index+1], data[index:]...) + // Insert the new element. + data[index] = stm + return data +} diff --git a/precompile/registerer/registerer_test.go b/precompile/registerer/registerer_test.go new file mode 100644 index 0000000000..d8c3fb9b96 --- /dev/null +++ b/precompile/registerer/registerer_test.go @@ -0,0 +1,45 @@ +// (c) 2023, Ava Labs, Inc. All rights reserved. +// See the file LICENSE for licensing terms. + +package registerer + +import ( + "math/big" + "testing" + + "github.com/ava-labs/subnet-evm/precompile/contract" + "github.com/ethereum/go-ethereum/common" + "github.com/stretchr/testify/require" +) + +func TestRegisterModule(t *testing.T) { + data := make([]contract.Module, 0) + // test that the module is registered in sorted order + module1 := contract.Module{ + Address: common.BigToAddress(big.NewInt(1)), + } + data = insertSortedByAddress(data, module1) + + require.Equal(t, []contract.Module{module1}, data) + + module0 := contract.Module{ + Address: common.BigToAddress(big.NewInt(0)), + } + + data = insertSortedByAddress(data, module0) + require.Equal(t, []contract.Module{module0, module1}, data) + + module3 := contract.Module{ + Address: common.BigToAddress(big.NewInt(3)), + } + + data = insertSortedByAddress(data, module3) + require.Equal(t, []contract.Module{module0, module1, module3}, data) + + module2 := contract.Module{ + Address: common.BigToAddress(big.NewInt(2)), + } + + data = insertSortedByAddress(data, module2) + require.Equal(t, []contract.Module{module0, module1, module2, module3}, data) +} diff --git a/precompile/registry/registry.go b/precompile/registry/registry.go index 3b76a9a431..16d93a4531 100644 --- a/precompile/registry/registry.go +++ b/precompile/registry/registry.go @@ -4,31 +4,15 @@ // Defines the stateless interface for unmarshalling an arbitrary config of a precompile package registry +// Force imports of each precompile to ensure each precompile's init function runs and registers itself +// with the registry. +// import ( - "github.com/ava-labs/avalanchego/utils/wrappers" - "github.com/ava-labs/subnet-evm/precompile/contracts/deployerallowlist" - "github.com/ava-labs/subnet-evm/precompile/contracts/feemanager" - "github.com/ava-labs/subnet-evm/precompile/contracts/nativeminter" - "github.com/ava-labs/subnet-evm/precompile/contracts/rewardmanager" - "github.com/ava-labs/subnet-evm/precompile/contracts/txallowlist" - "github.com/ava-labs/subnet-evm/precompile/registerer" -) - -func RegisterPrecompileModules() error { - errs := wrappers.Errs{} - errs.Add( - // Order is important here. - // RegisterModule registers a precompile in the order it is registered. - // The order of registration is important because it determines the configuration order - // in the state. - registerer.RegisterModule(deployerallowlist.Module{}), - registerer.RegisterModule(nativeminter.Module{}), - registerer.RegisterModule(txallowlist.Module{}), - registerer.RegisterModule(feemanager.Module{}), - registerer.RegisterModule(rewardmanager.Module{}), + _ "github.com/ava-labs/subnet-evm/precompile/contracts/deployerallowlist" + _ "github.com/ava-labs/subnet-evm/precompile/contracts/feemanager" + _ "github.com/ava-labs/subnet-evm/precompile/contracts/nativeminter" + _ "github.com/ava-labs/subnet-evm/precompile/contracts/rewardmanager" + _ "github.com/ava-labs/subnet-evm/precompile/contracts/txallowlist" // ADD YOUR PRECOMPILE HERE - // precompile.RegisterModule({yourPrecompilePackage}.{YourPrecompile}Config{}), - ) - - return errs.Err -} + // _ "github.com/ava-labs/subnet-evm/precompile/contracts/yourprecompile" +) From 201745805fcebd99eb93e17da2d97f083d9de9ec Mon Sep 17 00:00:00 2001 From: Ceyhun Onur Date: Tue, 14 Feb 2023 13:18:30 +0300 Subject: [PATCH 3/5] more clean up --- core/state_processor.go | 8 +++--- core/vm/contracts.go | 4 +-- core/vm/evm.go | 6 ++--- internal/ethapi/api.go | 6 ++--- params/chain_config_precompiles.go | 10 +++---- params/config.go | 4 +-- params/precompile_upgrade.go | 12 ++++----- .../{mock_interface.go => mock_config.go} | 0 precompile/contract/interfaces.go | 9 ------- .../contracts/deployerallowlist/module.go | 7 ++--- precompile/contracts/feemanager/module.go | 7 ++--- precompile/contracts/nativeminter/module.go | 7 ++--- precompile/contracts/rewardmanager/module.go | 7 ++--- precompile/contracts/txallowlist/module.go | 7 ++--- precompile/modules/module.go | 20 ++++++++++++++ .../{registerer => modules}/registerer.go | 27 +++++++++---------- .../registerer_test.go | 21 +++++++-------- 17 files changed, 88 insertions(+), 74 deletions(-) rename precompile/config/{mock_interface.go => mock_config.go} (100%) create mode 100644 precompile/modules/module.go rename precompile/{registerer => modules}/registerer.go (78%) rename precompile/{registerer => modules}/registerer_test.go (59%) diff --git a/core/state_processor.go b/core/state_processor.go index d202eaf350..95c8899393 100644 --- a/core/state_processor.go +++ b/core/state_processor.go @@ -36,7 +36,7 @@ import ( "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/registerer" + "github.com/ava-labs/subnet-evm/precompile/modules" "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/crypto" "github.com/ethereum/go-ethereum/log" @@ -183,8 +183,8 @@ func ApplyPrecompileActivations(c *params.ChainConfig, parentTimestamp *big.Int, // Note: RegisteredModules returns precompiles in order they are registered. // This is important because we want to configure precompiles in the same order // so that the state is deterministic. - for _, module := range registerer.RegisteredModules() { - key := module.NewConfig().Key() + for _, module := range modules.RegisteredModules() { + key := module.ConfigKey for _, activatingConfig := range c.GetActivatingPrecompileConfigs(module.Address, parentTimestamp, blockTimestamp, c.PrecompileUpgrades) { // If this transition activates the upgrade, configure the stateful precompile. // (or deconfigure it if it is being disabled.) @@ -197,7 +197,7 @@ func ApplyPrecompileActivations(c *params.ChainConfig, parentTimestamp *big.Int, // since Suicide will be committed after the reconfiguration. statedb.Finalise(true) } else { - module, ok := registerer.GetPrecompileModule(key) + module, ok := modules.GetPrecompileModule(key) if !ok { return fmt.Errorf("could not find module for activating precompile, name: %s", key) } diff --git a/core/vm/contracts.go b/core/vm/contracts.go index 60728cc5ed..bdeb189fb5 100644 --- a/core/vm/contracts.go +++ b/core/vm/contracts.go @@ -36,7 +36,7 @@ import ( "github.com/ava-labs/subnet-evm/constants" "github.com/ava-labs/subnet-evm/params" "github.com/ava-labs/subnet-evm/precompile/contract" - "github.com/ava-labs/subnet-evm/precompile/registerer" + "github.com/ava-labs/subnet-evm/precompile/modules" "github.com/ava-labs/subnet-evm/vmerrs" "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/common/math" @@ -159,7 +159,7 @@ func init() { // Ensure that this package will panic during init if there is a conflict present with the declared // precompile addresses. - for _, module := range registerer.RegisteredModules() { + for _, module := range modules.RegisteredModules() { address := module.Address if _, ok := PrecompileAllNativeAddresses[address]; ok { panic(fmt.Errorf("precompile address collides with existing native address: %s", address)) diff --git a/core/vm/evm.go b/core/vm/evm.go index 5e3739705f..764bce4e65 100644 --- a/core/vm/evm.go +++ b/core/vm/evm.go @@ -37,7 +37,7 @@ import ( "github.com/ava-labs/subnet-evm/params" "github.com/ava-labs/subnet-evm/precompile/contract" "github.com/ava-labs/subnet-evm/precompile/contracts/deployerallowlist" - "github.com/ava-labs/subnet-evm/precompile/registerer" + "github.com/ava-labs/subnet-evm/precompile/modules" "github.com/ava-labs/subnet-evm/vmerrs" "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/crypto" @@ -56,7 +56,7 @@ func IsProhibited(addr common.Address) bool { return true } - return registerer.ReservedAddress(addr) + return modules.ReservedAddress(addr) } // emptyCodeHash is used by create to ensure deployment is disallowed to already @@ -94,7 +94,7 @@ func (evm *EVM) precompile(addr common.Address) (contract.StatefulPrecompiledCon // Otherwise, check the chain rules for the additionally configured precompiles. if _, ok = evm.chainRules.ActivePrecompiles[addr]; ok { - module, ok := registerer.GetPrecompileModuleByAddress(addr) + module, ok := modules.GetPrecompileModuleByAddress(addr) return module.Contract, ok } diff --git a/internal/ethapi/api.go b/internal/ethapi/api.go index 2b5852655a..5d3f1b0e55 100644 --- a/internal/ethapi/api.go +++ b/internal/ethapi/api.go @@ -44,7 +44,7 @@ import ( "github.com/ava-labs/subnet-evm/core/vm" "github.com/ava-labs/subnet-evm/eth/tracers/logger" "github.com/ava-labs/subnet-evm/params" - "github.com/ava-labs/subnet-evm/precompile/registerer" + "github.com/ava-labs/subnet-evm/precompile/modules" "github.com/ava-labs/subnet-evm/rpc" "github.com/ava-labs/subnet-evm/vmerrs" "github.com/davecgh/go-spew/spew" @@ -633,9 +633,9 @@ func (s *BlockChainAPI) GetActivePrecompilesAt(ctx context.Context, blockTimesta blockTimestamp = new(big.Int).SetUint64(blockTimestampInt) } res := make(params.ChainConfigPrecompiles) - for _, module := range registerer.RegisteredModules() { + for _, module := range modules.RegisteredModules() { if config := s.b.ChainConfig().GetActivePrecompileConfig(module.Address, blockTimestamp); config != nil && !config.IsDisabled() { - res[module.NewConfig().Key()] = config + res[module.ConfigKey] = config } } diff --git a/params/chain_config_precompiles.go b/params/chain_config_precompiles.go index c1a904ee55..6e75e9c3d1 100644 --- a/params/chain_config_precompiles.go +++ b/params/chain_config_precompiles.go @@ -7,18 +7,18 @@ import ( "encoding/json" "github.com/ava-labs/subnet-evm/precompile/config" - "github.com/ava-labs/subnet-evm/precompile/registerer" + "github.com/ava-labs/subnet-evm/precompile/modules" "github.com/ethereum/go-ethereum/common" ) type ChainConfigPrecompiles map[string]config.Config func (ccp *ChainConfigPrecompiles) GetConfigByAddress(address common.Address) (config.Config, bool) { - module, ok := registerer.GetPrecompileModuleByAddress(address) + module, ok := modules.GetPrecompileModuleByAddress(address) if !ok { return nil, false } - key := module.NewConfig().Key() + key := module.ConfigKey config, ok := (*ccp)[key] return config, ok } @@ -33,8 +33,8 @@ func (ccp *ChainConfigPrecompiles) UnmarshalJSON(data []byte) error { } *ccp = make(ChainConfigPrecompiles) - for _, module := range registerer.RegisteredModules() { - key := module.NewConfig().Key() + for _, module := range modules.RegisteredModules() { + key := module.ConfigKey if value, ok := raw[key]; ok { conf := module.NewConfig() err := json.Unmarshal(value, conf) diff --git a/params/config.go b/params/config.go index d8ed64d11b..680c7d6a9a 100644 --- a/params/config.go +++ b/params/config.go @@ -35,7 +35,7 @@ import ( "github.com/ava-labs/avalanchego/snow" "github.com/ava-labs/subnet-evm/commontype" "github.com/ava-labs/subnet-evm/precompile/config" - "github.com/ava-labs/subnet-evm/precompile/registerer" + "github.com/ava-labs/subnet-evm/precompile/modules" "github.com/ava-labs/subnet-evm/utils" "github.com/ethereum/go-ethereum/common" ) @@ -596,7 +596,7 @@ func (c *ChainConfig) AvalancheRules(blockNum, blockTimestamp *big.Int) Rules { // Initialize the stateful precompiles that should be enabled at [blockTimestamp]. rules.ActivePrecompiles = make(map[common.Address]config.Config) - for _, module := range registerer.RegisteredModules() { + for _, module := range modules.RegisteredModules() { if config := c.GetActivePrecompileConfig(module.Address, blockTimestamp); config != nil { rules.ActivePrecompiles[module.Address] = config } diff --git a/params/precompile_upgrade.go b/params/precompile_upgrade.go index 694ac24c03..4e7e99d242 100644 --- a/params/precompile_upgrade.go +++ b/params/precompile_upgrade.go @@ -11,7 +11,7 @@ import ( "github.com/ava-labs/subnet-evm/precompile/config" precompileConfig "github.com/ava-labs/subnet-evm/precompile/config" - "github.com/ava-labs/subnet-evm/precompile/registerer" + "github.com/ava-labs/subnet-evm/precompile/modules" "github.com/ava-labs/subnet-evm/utils" "github.com/ethereum/go-ethereum/common" ) @@ -43,7 +43,7 @@ func (u *PrecompileUpgrade) UnmarshalJSON(data []byte) error { return errMultipleKeys } for key, value := range raw { - module, ok := registerer.GetPrecompileModule(key) + module, ok := modules.GetPrecompileModule(key) if !ok { return fmt.Errorf("unknown precompile config: %s", key) } @@ -167,11 +167,11 @@ func (c *ChainConfig) GetActivatingPrecompileConfigs(address common.Address, fro configs := make([]config.Config, 0) // Get key from address. - module, ok := registerer.GetPrecompileModuleByAddress(address) + module, ok := modules.GetPrecompileModuleByAddress(address) if !ok { return configs } - key := module.NewConfig().Key() + key := module.ConfigKey // First check the embedded [upgrade] for precompiles configured // in the genesis chain config. if config, ok := c.GenesisPrecompiles[key]; ok { @@ -198,7 +198,7 @@ func (c *ChainConfig) GetActivatingPrecompileConfigs(address common.Address, fro // Assumes given timestamp is the last accepted block timestamp. // This ensures that as long as the node has not accepted a block with a different rule set it will allow a new upgrade to be applied as long as it activates after the last accepted block. func (c *ChainConfig) CheckPrecompilesCompatible(precompileUpgrades []PrecompileUpgrade, lastTimestamp *big.Int) *ConfigCompatError { - for _, module := range registerer.RegisteredModules() { + for _, module := range modules.RegisteredModules() { if err := c.checkPrecompileCompatible(module.Address, precompileUpgrades, lastTimestamp); err != nil { return err } @@ -251,7 +251,7 @@ func (c *ChainConfig) checkPrecompileCompatible(address common.Address, precompi // have been activated through an upgrade. func (c *ChainConfig) EnabledStatefulPrecompiles(blockTimestamp *big.Int) []config.Config { statefulPrecompileConfigs := make([]config.Config, 0) - for _, module := range registerer.RegisteredModules() { + for _, module := range modules.RegisteredModules() { if config := c.GetActivePrecompileConfig(module.Address, blockTimestamp); config != nil { statefulPrecompileConfigs = append(statefulPrecompileConfigs, config) } diff --git a/precompile/config/mock_interface.go b/precompile/config/mock_config.go similarity index 100% rename from precompile/config/mock_interface.go rename to precompile/config/mock_config.go diff --git a/precompile/contract/interfaces.go b/precompile/contract/interfaces.go index 94ce4d0cab..75f48980a1 100644 --- a/precompile/contract/interfaces.go +++ b/precompile/contract/interfaces.go @@ -77,12 +77,3 @@ type Configurator interface { blockContext BlockContext, ) error } - -type Module struct { - // Address returns the address where the stateful precompile is accessible. - Address common.Address - // Contract returns a thread-safe singleton that can be used as the StatefulPrecompiledContract when - // this config is enabled. - Contract StatefulPrecompiledContract - Configurator -} diff --git a/precompile/contracts/deployerallowlist/module.go b/precompile/contracts/deployerallowlist/module.go index b267fa05d9..c43a7cc4d8 100644 --- a/precompile/contracts/deployerallowlist/module.go +++ b/precompile/contracts/deployerallowlist/module.go @@ -8,7 +8,7 @@ import ( "github.com/ava-labs/subnet-evm/precompile/config" "github.com/ava-labs/subnet-evm/precompile/contract" - "github.com/ava-labs/subnet-evm/precompile/registerer" + "github.com/ava-labs/subnet-evm/precompile/modules" "github.com/ethereum/go-ethereum/common" ) @@ -18,7 +18,8 @@ const ConfigKey = "contractDeployerAllowListConfig" var ContractAddress = common.HexToAddress("0x0200000000000000000000000000000000000000") -var Module = contract.Module{ +var Module = modules.Module{ + ConfigKey: ConfigKey, Address: ContractAddress, Contract: ContractDeployerAllowListPrecompile, Configurator: &configuror{}, @@ -27,7 +28,7 @@ var Module = contract.Module{ type configuror struct{} func init() { - registerer.RegisterModule(Module) + modules.RegisterModule(Module) } func (*configuror) NewConfig() config.Config { diff --git a/precompile/contracts/feemanager/module.go b/precompile/contracts/feemanager/module.go index 2b71c3e15f..b345793c8c 100644 --- a/precompile/contracts/feemanager/module.go +++ b/precompile/contracts/feemanager/module.go @@ -8,7 +8,7 @@ import ( "github.com/ava-labs/subnet-evm/precompile/config" "github.com/ava-labs/subnet-evm/precompile/contract" - "github.com/ava-labs/subnet-evm/precompile/registerer" + "github.com/ava-labs/subnet-evm/precompile/modules" "github.com/ethereum/go-ethereum/common" ) @@ -18,7 +18,8 @@ const ConfigKey = "feeManagerConfig" var ContractAddress = common.HexToAddress("0x0200000000000000000000000000000000000003") -var Module = contract.Module{ +var Module = modules.Module{ + ConfigKey: ConfigKey, Address: ContractAddress, Contract: FeeManagerPrecompile, Configurator: &configuror{}, @@ -27,7 +28,7 @@ var Module = contract.Module{ type configuror struct{} func init() { - registerer.RegisterModule(Module) + modules.RegisterModule(Module) } func (*configuror) NewConfig() config.Config { diff --git a/precompile/contracts/nativeminter/module.go b/precompile/contracts/nativeminter/module.go index f2eee9caf1..5fa7dbbf7f 100644 --- a/precompile/contracts/nativeminter/module.go +++ b/precompile/contracts/nativeminter/module.go @@ -9,7 +9,7 @@ import ( "github.com/ava-labs/subnet-evm/precompile/config" "github.com/ava-labs/subnet-evm/precompile/contract" - "github.com/ava-labs/subnet-evm/precompile/registerer" + "github.com/ava-labs/subnet-evm/precompile/modules" "github.com/ethereum/go-ethereum/common" ) @@ -19,7 +19,8 @@ const ConfigKey = "contractNativeMinterConfig" var ContractAddress = common.HexToAddress("0x0200000000000000000000000000000000000001") -var Module = contract.Module{ +var Module = modules.Module{ + ConfigKey: ConfigKey, Address: ContractAddress, Contract: ContractNativeMinterPrecompile, Configurator: &configuror{}, @@ -28,7 +29,7 @@ var Module = contract.Module{ type configuror struct{} func init() { - registerer.RegisterModule(Module) + modules.RegisterModule(Module) } func (*configuror) NewConfig() config.Config { diff --git a/precompile/contracts/rewardmanager/module.go b/precompile/contracts/rewardmanager/module.go index 8a1d901567..7559f5ec1a 100644 --- a/precompile/contracts/rewardmanager/module.go +++ b/precompile/contracts/rewardmanager/module.go @@ -8,7 +8,7 @@ import ( "github.com/ava-labs/subnet-evm/precompile/config" "github.com/ava-labs/subnet-evm/precompile/contract" - "github.com/ava-labs/subnet-evm/precompile/registerer" + "github.com/ava-labs/subnet-evm/precompile/modules" "github.com/ethereum/go-ethereum/common" ) @@ -18,7 +18,8 @@ const ConfigKey = "rewardManagerConfig" var ContractAddress = common.HexToAddress("0x0200000000000000000000000000000000000004") -var Module = contract.Module{ +var Module = modules.Module{ + ConfigKey: ConfigKey, Address: ContractAddress, Contract: RewardManagerPrecompile, Configurator: &configuror{}, @@ -27,7 +28,7 @@ var Module = contract.Module{ type configuror struct{} func init() { - registerer.RegisterModule(Module) + modules.RegisterModule(Module) } func (*configuror) NewConfig() config.Config { diff --git a/precompile/contracts/txallowlist/module.go b/precompile/contracts/txallowlist/module.go index 95018e1b24..fe5314d04d 100644 --- a/precompile/contracts/txallowlist/module.go +++ b/precompile/contracts/txallowlist/module.go @@ -8,7 +8,7 @@ import ( "github.com/ava-labs/subnet-evm/precompile/config" "github.com/ava-labs/subnet-evm/precompile/contract" - "github.com/ava-labs/subnet-evm/precompile/registerer" + "github.com/ava-labs/subnet-evm/precompile/modules" "github.com/ethereum/go-ethereum/common" ) @@ -18,7 +18,8 @@ const ConfigKey = "txAllowListConfig" var ContractAddress = common.HexToAddress("0x0200000000000000000000000000000000000002") -var Module = contract.Module{ +var Module = modules.Module{ + ConfigKey: ConfigKey, Address: ContractAddress, Contract: TxAllowListPrecompile, Configurator: &configuror{}, @@ -27,7 +28,7 @@ var Module = contract.Module{ type configuror struct{} func init() { - registerer.RegisterModule(Module) + modules.RegisterModule(Module) } func (*configuror) NewConfig() config.Config { diff --git a/precompile/modules/module.go b/precompile/modules/module.go new file mode 100644 index 0000000000..fde25ab9d3 --- /dev/null +++ b/precompile/modules/module.go @@ -0,0 +1,20 @@ +// (c) 2023, Ava Labs, Inc. All rights reserved. +// See the file LICENSE for licensing terms. + +package modules + +import ( + "github.com/ava-labs/subnet-evm/precompile/contract" + "github.com/ethereum/go-ethereum/common" +) + +type Module struct { + // ConfigKey is the key used in json config files to specify this precompile config. + ConfigKey string + // Address returns the address where the stateful precompile is accessible. + Address common.Address + // Contract returns a thread-safe singleton that can be used as the StatefulPrecompiledContract when + // this config is enabled. + Contract contract.StatefulPrecompiledContract + contract.Configurator +} diff --git a/precompile/registerer/registerer.go b/precompile/modules/registerer.go similarity index 78% rename from precompile/registerer/registerer.go rename to precompile/modules/registerer.go index 485d704a31..45116739ad 100644 --- a/precompile/registerer/registerer.go +++ b/precompile/modules/registerer.go @@ -1,13 +1,12 @@ // (c) 2023, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. -package registerer +package modules import ( "bytes" "fmt" - "github.com/ava-labs/subnet-evm/precompile/contract" "github.com/ava-labs/subnet-evm/utils" "github.com/ethereum/go-ethereum/common" ) @@ -15,7 +14,7 @@ import ( var ( // registeredModules is a list of Module to preserve order // for deterministic iteration - registeredModules = make([]contract.Module, 0) + registeredModules = make([]Module, 0) reservedRanges = []utils.AddressRange{ { @@ -45,15 +44,15 @@ func ReservedAddress(addr common.Address) bool { } // RegisterModule registers a stateful precompile module -func RegisterModule(stm contract.Module) error { +func RegisterModule(stm Module) error { address := stm.Address - key := stm.NewConfig().Key() + key := stm.ConfigKey if !ReservedAddress(address) { return fmt.Errorf("address %s not in a reserved range", address) } for _, registeredModule := range registeredModules { - if registeredModule.NewConfig().Key() == key { + if registeredModule.ConfigKey == key { return fmt.Errorf("name %s already used by a stateful precompile", key) } if registeredModule.Address == address { @@ -65,29 +64,29 @@ func RegisterModule(stm contract.Module) error { return nil } -func GetPrecompileModuleByAddress(address common.Address) (contract.Module, bool) { +func GetPrecompileModuleByAddress(address common.Address) (Module, bool) { for _, stm := range registeredModules { if stm.Address == address { return stm, true } } - return contract.Module{}, false + return Module{}, false } -func GetPrecompileModule(key string) (contract.Module, bool) { +func GetPrecompileModule(key string) (Module, bool) { for _, stm := range registeredModules { - if stm.NewConfig().Key() == key { + if stm.ConfigKey == key { return stm, true } } - return contract.Module{}, false + return Module{}, false } -func RegisteredModules() []contract.Module { +func RegisteredModules() []Module { return registeredModules } -func insertSortedByAddress(data []contract.Module, stm contract.Module) []contract.Module { +func insertSortedByAddress(data []Module, stm Module) []Module { // sort by address to ensure deterministic iteration // start at the end of the list and work backwards // this is faster than sorting the list every time @@ -102,7 +101,7 @@ func insertSortedByAddress(data []contract.Module, stm contract.Module) []contra return insertAt(data, index, stm) } -func insertAt(data []contract.Module, index int, stm contract.Module) []contract.Module { +func insertAt(data []Module, index int, stm Module) []Module { // if the index is out of bounds, append the module if index >= len(data) { data = append(data, stm) diff --git a/precompile/registerer/registerer_test.go b/precompile/modules/registerer_test.go similarity index 59% rename from precompile/registerer/registerer_test.go rename to precompile/modules/registerer_test.go index d8c3fb9b96..b91e0b01ed 100644 --- a/precompile/registerer/registerer_test.go +++ b/precompile/modules/registerer_test.go @@ -1,45 +1,44 @@ // (c) 2023, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. -package registerer +package modules import ( "math/big" "testing" - "github.com/ava-labs/subnet-evm/precompile/contract" "github.com/ethereum/go-ethereum/common" "github.com/stretchr/testify/require" ) func TestRegisterModule(t *testing.T) { - data := make([]contract.Module, 0) + data := make([]Module, 0) // test that the module is registered in sorted order - module1 := contract.Module{ + module1 := Module{ Address: common.BigToAddress(big.NewInt(1)), } data = insertSortedByAddress(data, module1) - require.Equal(t, []contract.Module{module1}, data) + require.Equal(t, []Module{module1}, data) - module0 := contract.Module{ + module0 := Module{ Address: common.BigToAddress(big.NewInt(0)), } data = insertSortedByAddress(data, module0) - require.Equal(t, []contract.Module{module0, module1}, data) + require.Equal(t, []Module{module0, module1}, data) - module3 := contract.Module{ + module3 := Module{ Address: common.BigToAddress(big.NewInt(3)), } data = insertSortedByAddress(data, module3) - require.Equal(t, []contract.Module{module0, module1, module3}, data) + require.Equal(t, []Module{module0, module1, module3}, data) - module2 := contract.Module{ + module2 := Module{ Address: common.BigToAddress(big.NewInt(2)), } data = insertSortedByAddress(data, module2) - require.Equal(t, []contract.Module{module0, module1, module2, module3}, data) + require.Equal(t, []Module{module0, module1, module2, module3}, data) } From 2155fa7b0d4dba37f1d131dd0fea5252dc24384f Mon Sep 17 00:00:00 2001 From: Ceyhun Onur Date: Tue, 14 Feb 2023 13:27:17 +0300 Subject: [PATCH 4/5] Review fixes --- core/state_processor.go | 2 +- precompile/allowlist/allow_list_test.go | 6 ++-- precompile/allowlist/config.go | 10 +++---- precompile/allowlist/config_test.go | 28 +++++++++---------- precompile/config/upgradeable.go | 11 ++++---- .../contracts/deployerallowlist/config.go | 14 +++++----- .../contracts/deployerallowlist/module.go | 2 +- precompile/contracts/feemanager/config.go | 16 +++++------ precompile/contracts/feemanager/module.go | 2 +- precompile/contracts/nativeminter/config.go | 16 +++++------ precompile/contracts/nativeminter/module.go | 2 +- precompile/contracts/rewardmanager/config.go | 14 +++++----- precompile/contracts/rewardmanager/module.go | 2 +- precompile/contracts/txallowlist/config.go | 12 ++++---- precompile/contracts/txallowlist/module.go | 2 +- 15 files changed, 69 insertions(+), 70 deletions(-) diff --git a/core/state_processor.go b/core/state_processor.go index 95c8899393..d5eed20cc4 100644 --- a/core/state_processor.go +++ b/core/state_processor.go @@ -180,7 +180,7 @@ func ApplyTransaction(config *params.ChainConfig, bc ChainContext, author *commo // - during block producing to apply the precompile upgrades before producing the block. func ApplyPrecompileActivations(c *params.ChainConfig, parentTimestamp *big.Int, blockContext contract.BlockContext, statedb *state.StateDB) error { blockTimestamp := blockContext.Timestamp() - // Note: RegisteredModules returns precompiles in order they are registered. + // Note: RegisteredModules returns precompiles sorted by module addresses. // This is important because we want to configure precompiles in the same order // so that the state is deterministic. for _, module := range modules.RegisteredModules() { diff --git a/precompile/allowlist/allow_list_test.go b/precompile/allowlist/allow_list_test.go index 6122a7c818..3a9f4f2dd3 100644 --- a/precompile/allowlist/allow_list_test.go +++ b/precompile/allowlist/allow_list_test.go @@ -25,7 +25,7 @@ func TestAllowListRun(t *testing.T) { expectedRes []byte expectedErr string - config *AllowListConfig + config *Config assertState func(t *testing.T, state *state.StateDB) } @@ -221,7 +221,7 @@ func TestAllowListRun(t *testing.T) { expectedErr: vmerrs.ErrOutOfGas.Error(), }, "initial config sets admins": { - config: &AllowListConfig{ + config: &Config{ AdminAddresses: []common.Address{noRoleAddr, enabledAddr}, }, suppliedGas: 0, @@ -233,7 +233,7 @@ func TestAllowListRun(t *testing.T) { }, }, "initial config sets enabled": { - config: &AllowListConfig{ + config: &Config{ EnabledAddresses: []common.Address{noRoleAddr, adminAddr}, }, suppliedGas: 0, diff --git a/precompile/allowlist/config.go b/precompile/allowlist/config.go index 101432b1cc..1f47459183 100644 --- a/precompile/allowlist/config.go +++ b/precompile/allowlist/config.go @@ -10,15 +10,15 @@ import ( "github.com/ethereum/go-ethereum/common" ) -// AllowListConfig specifies the initial set of allow list admins. -type AllowListConfig struct { +// Config specifies the initial set of allow list admins. +type Config struct { AdminAddresses []common.Address `json:"adminAddresses,omitempty"` EnabledAddresses []common.Address `json:"enabledAddresses,omitempty"` // initial enabled addresses } // Configure initializes the address space of [precompileAddr] by initializing the role of each of // the addresses in [AllowListAdmins]. -func (c *AllowListConfig) Configure(state contract.StateDB, precompileAddr common.Address) error { +func (c *Config) Configure(state contract.StateDB, precompileAddr common.Address) error { for _, enabledAddr := range c.EnabledAddresses { SetAllowListRole(state, precompileAddr, enabledAddr, EnabledRole) } @@ -29,7 +29,7 @@ func (c *AllowListConfig) Configure(state contract.StateDB, precompileAddr commo } // Equal returns true iff [other] has the same admins in the same order in its allow list. -func (c *AllowListConfig) Equal(other *AllowListConfig) bool { +func (c *Config) Equal(other *Config) bool { if other == nil { return false } @@ -54,7 +54,7 @@ func areEqualAddressLists(current []common.Address, other []common.Address) bool } // Verify returns an error if there is an overlapping address between admin and enabled roles -func (c *AllowListConfig) Verify() error { +func (c *Config) Verify() error { // return early if either list is empty if len(c.EnabledAddresses) == 0 || len(c.AdminAddresses) == 0 { return nil diff --git a/precompile/allowlist/config_test.go b/precompile/allowlist/config_test.go index b991747162..eb489772f4 100644 --- a/precompile/allowlist/config_test.go +++ b/precompile/allowlist/config_test.go @@ -15,27 +15,27 @@ func TestVerifyAllowlistConfig(t *testing.T) { enableds := []common.Address{{2}} tests := []struct { name string - config AllowListConfig + config Config expectedError string }{ { name: "invalid allow list config in allowlist", - config: AllowListConfig{admins, admins}, + config: Config{admins, admins}, expectedError: "cannot set address", }, { name: "nil member allow list config in allowlist", - config: AllowListConfig{nil, nil}, + config: Config{nil, nil}, expectedError: "", }, { name: "empty member allow list config in allowlist", - config: AllowListConfig{[]common.Address{}, []common.Address{}}, + config: Config{[]common.Address{}, []common.Address{}}, expectedError: "", }, { name: "valid allow list config in allowlist", - config: AllowListConfig{admins, enableds}, + config: Config{admins, enableds}, expectedError: "", }, } @@ -58,32 +58,32 @@ func TestEqualAllowListConfig(t *testing.T) { enableds := []common.Address{{2}} tests := []struct { name string - config AllowListConfig - other *AllowListConfig + config Config + other *Config expected bool }{ { name: "non-nil config and nil other", - config: AllowListConfig{admins, enableds}, + config: Config{admins, enableds}, other: nil, expected: false, }, { name: "different admin", - config: AllowListConfig{admins, enableds}, - other: &AllowListConfig{[]common.Address{{3}}, enableds}, + config: Config{admins, enableds}, + other: &Config{[]common.Address{{3}}, enableds}, expected: false, }, { name: "different enabled", - config: AllowListConfig{admins, enableds}, - other: &AllowListConfig{admins, []common.Address{{3}}}, + config: Config{admins, enableds}, + other: &Config{admins, []common.Address{{3}}}, expected: false, }, { name: "same config", - config: AllowListConfig{admins, enableds}, - other: &AllowListConfig{admins, enableds}, + config: Config{admins, enableds}, + other: &Config{admins, enableds}, expected: true, }, } diff --git a/precompile/config/upgradeable.go b/precompile/config/upgradeable.go index 5d08091fb8..89fedecb98 100644 --- a/precompile/config/upgradeable.go +++ b/precompile/config/upgradeable.go @@ -9,28 +9,27 @@ import ( "github.com/ava-labs/subnet-evm/utils" ) -// UpgradeableConfig contains the timestamp for the upgrade along with +// Uprade contains the timestamp for the upgrade along with // a boolean [Disable]. If [Disable] is set, the upgrade deactivates // the precompile and resets its storage. -// TODO: convert to interface -type UpgradeableConfig struct { +type Uprade struct { BlockTimestamp *big.Int `json:"blockTimestamp"` Disable bool `json:"disable,omitempty"` } // Timestamp returns the timestamp this network upgrade goes into effect. -func (c *UpgradeableConfig) Timestamp() *big.Int { +func (c *Uprade) Timestamp() *big.Int { return c.BlockTimestamp } // IsDisabled returns true if the network upgrade deactivates the precompile. -func (c *UpgradeableConfig) IsDisabled() bool { +func (c *Uprade) IsDisabled() bool { return c.Disable } // Equal returns true iff [other] has the same blockTimestamp and has the // same on value for the Disable flag. -func (c *UpgradeableConfig) Equal(other *UpgradeableConfig) bool { +func (c *Uprade) Equal(other *Uprade) bool { if other == nil { return false } diff --git a/precompile/contracts/deployerallowlist/config.go b/precompile/contracts/deployerallowlist/config.go index 38e1f2d2be..d7634afe79 100644 --- a/precompile/contracts/deployerallowlist/config.go +++ b/precompile/contracts/deployerallowlist/config.go @@ -16,19 +16,19 @@ var _ config.Config = &ContractDeployerAllowListConfig{} // ContractDeployerAllowListConfig wraps [AllowListConfig] and uses it to implement the StatefulPrecompileConfig // interface while adding in the contract deployer specific precompile address. type ContractDeployerAllowListConfig struct { - allowlist.AllowListConfig - config.UpgradeableConfig + allowlist.Config + config.Uprade } // NewContractDeployerAllowListConfig returns a config for a network upgrade at [blockTimestamp] that enables // ContractDeployerAllowList with [admins] and [enableds] as members of the allowlist. func NewContractDeployerAllowListConfig(blockTimestamp *big.Int, admins []common.Address, enableds []common.Address) *ContractDeployerAllowListConfig { return &ContractDeployerAllowListConfig{ - AllowListConfig: allowlist.AllowListConfig{ + Config: allowlist.Config{ AdminAddresses: admins, EnabledAddresses: enableds, }, - UpgradeableConfig: config.UpgradeableConfig{BlockTimestamp: blockTimestamp}, + Uprade: config.Uprade{BlockTimestamp: blockTimestamp}, } } @@ -36,7 +36,7 @@ func NewContractDeployerAllowListConfig(blockTimestamp *big.Int, admins []common // that disables ContractDeployerAllowList. func NewDisableContractDeployerAllowListConfig(blockTimestamp *big.Int) *ContractDeployerAllowListConfig { return &ContractDeployerAllowListConfig{ - UpgradeableConfig: config.UpgradeableConfig{ + Uprade: config.Uprade{ BlockTimestamp: blockTimestamp, Disable: true, }, @@ -52,7 +52,7 @@ func (c *ContractDeployerAllowListConfig) Equal(cfg config.Config) bool { if !ok { return false } - return c.UpgradeableConfig.Equal(&other.UpgradeableConfig) && c.AllowListConfig.Equal(&other.AllowListConfig) + return c.Uprade.Equal(&other.Uprade) && c.Config.Equal(&other.Config) } -func (c *ContractDeployerAllowListConfig) Verify() error { return c.AllowListConfig.Verify() } +func (c *ContractDeployerAllowListConfig) Verify() error { return c.Config.Verify() } diff --git a/precompile/contracts/deployerallowlist/module.go b/precompile/contracts/deployerallowlist/module.go index c43a7cc4d8..bd4e27b6af 100644 --- a/precompile/contracts/deployerallowlist/module.go +++ b/precompile/contracts/deployerallowlist/module.go @@ -41,5 +41,5 @@ func (c *configuror) Configure(_ contract.ChainConfig, cfg config.Config, state if !ok { return fmt.Errorf("incorrect config %T: %v", config, config) } - return config.AllowListConfig.Configure(state, ContractAddress) + return config.Config.Configure(state, ContractAddress) } diff --git a/precompile/contracts/feemanager/config.go b/precompile/contracts/feemanager/config.go index 0623bcbd95..5a06df6a88 100644 --- a/precompile/contracts/feemanager/config.go +++ b/precompile/contracts/feemanager/config.go @@ -17,8 +17,8 @@ var _ config.Config = &FeeManagerConfig{} // FeeManagerConfig wraps [AllowListConfig] and uses it to implement the StatefulPrecompileConfig // interface while adding in the FeeManager specific precompile address. type FeeManagerConfig struct { - allowlist.AllowListConfig // Config for the fee config manager allow list - config.UpgradeableConfig + allowlist.Config // Config for the fee config manager allow list + config.Uprade InitialFeeConfig *commontype.FeeConfig `json:"initialFeeConfig,omitempty"` // initial fee config to be immediately activated } @@ -26,12 +26,12 @@ type FeeManagerConfig struct { // FeeManager with the given [admins] and [enableds] as members of the allowlist with [initialConfig] as initial fee config if specified. func NewFeeManagerConfig(blockTimestamp *big.Int, admins []common.Address, enableds []common.Address, initialConfig *commontype.FeeConfig) *FeeManagerConfig { return &FeeManagerConfig{ - AllowListConfig: allowlist.AllowListConfig{ + Config: allowlist.Config{ AdminAddresses: admins, EnabledAddresses: enableds, }, - UpgradeableConfig: config.UpgradeableConfig{BlockTimestamp: blockTimestamp}, - InitialFeeConfig: initialConfig, + Uprade: config.Uprade{BlockTimestamp: blockTimestamp}, + InitialFeeConfig: initialConfig, } } @@ -39,7 +39,7 @@ func NewFeeManagerConfig(blockTimestamp *big.Int, admins []common.Address, enabl // that disables FeeManager. func NewDisableFeeManagerConfig(blockTimestamp *big.Int) *FeeManagerConfig { return &FeeManagerConfig{ - UpgradeableConfig: config.UpgradeableConfig{ + Uprade: config.Uprade{ BlockTimestamp: blockTimestamp, Disable: true, }, @@ -55,7 +55,7 @@ func (c *FeeManagerConfig) Equal(cfg config.Config) bool { if !ok { return false } - eq := c.UpgradeableConfig.Equal(&other.UpgradeableConfig) && c.AllowListConfig.Equal(&other.AllowListConfig) + eq := c.Uprade.Equal(&other.Uprade) && c.Config.Equal(&other.Config) if !eq { return false } @@ -68,7 +68,7 @@ func (c *FeeManagerConfig) Equal(cfg config.Config) bool { } func (c *FeeManagerConfig) Verify() error { - if err := c.AllowListConfig.Verify(); err != nil { + if err := c.Config.Verify(); err != nil { return err } if c.InitialFeeConfig == nil { diff --git a/precompile/contracts/feemanager/module.go b/precompile/contracts/feemanager/module.go index b345793c8c..41b5f43793 100644 --- a/precompile/contracts/feemanager/module.go +++ b/precompile/contracts/feemanager/module.go @@ -53,5 +53,5 @@ func (*configuror) Configure(chainConfig contract.ChainConfig, cfg config.Config return fmt.Errorf("cannot configure fee config in chain config: %w", err) } } - return config.AllowListConfig.Configure(state, ContractAddress) + return config.Config.Configure(state, ContractAddress) } diff --git a/precompile/contracts/nativeminter/config.go b/precompile/contracts/nativeminter/config.go index 65da84f400..93625218fd 100644 --- a/precompile/contracts/nativeminter/config.go +++ b/precompile/contracts/nativeminter/config.go @@ -19,8 +19,8 @@ var _ config.Config = &ContractNativeMinterConfig{} // ContractNativeMinterConfig wraps [AllowListConfig] and uses it to implement the StatefulPrecompileConfig // interface while adding in the ContractNativeMinter specific precompile address. type ContractNativeMinterConfig struct { - allowlist.AllowListConfig - config.UpgradeableConfig + allowlist.Config + config.Uprade InitialMint map[common.Address]*math.HexOrDecimal256 `json:"initialMint,omitempty"` // initial mint config to be immediately minted } @@ -28,12 +28,12 @@ type ContractNativeMinterConfig struct { // ContractNativeMinter with the given [admins] and [enableds] as members of the allowlist. Also mints balances according to [initialMint] when the upgrade activates. func NewContractNativeMinterConfig(blockTimestamp *big.Int, admins []common.Address, enableds []common.Address, initialMint map[common.Address]*math.HexOrDecimal256) *ContractNativeMinterConfig { return &ContractNativeMinterConfig{ - AllowListConfig: allowlist.AllowListConfig{ + Config: allowlist.Config{ AdminAddresses: admins, EnabledAddresses: enableds, }, - UpgradeableConfig: config.UpgradeableConfig{BlockTimestamp: blockTimestamp}, - InitialMint: initialMint, + Uprade: config.Uprade{BlockTimestamp: blockTimestamp}, + InitialMint: initialMint, } } @@ -41,7 +41,7 @@ func NewContractNativeMinterConfig(blockTimestamp *big.Int, admins []common.Addr // that disables ContractNativeMinter. func NewDisableContractNativeMinterConfig(blockTimestamp *big.Int) *ContractNativeMinterConfig { return &ContractNativeMinterConfig{ - UpgradeableConfig: config.UpgradeableConfig{ + Uprade: config.Uprade{ BlockTimestamp: blockTimestamp, Disable: true, }, @@ -56,7 +56,7 @@ func (c *ContractNativeMinterConfig) Equal(cfg config.Config) bool { if !ok { return false } - eq := c.UpgradeableConfig.Equal(&other.UpgradeableConfig) && c.AllowListConfig.Equal(&other.AllowListConfig) + eq := c.Uprade.Equal(&other.Uprade) && c.Config.Equal(&other.Config) if !eq { return false } @@ -81,7 +81,7 @@ func (c *ContractNativeMinterConfig) Equal(cfg config.Config) bool { } func (c *ContractNativeMinterConfig) Verify() error { - if err := c.AllowListConfig.Verify(); err != nil { + if err := c.Config.Verify(); err != nil { return err } // ensure that all of the initial mint values in the map are non-nil positive values diff --git a/precompile/contracts/nativeminter/module.go b/precompile/contracts/nativeminter/module.go index 5fa7dbbf7f..3b86e4f95d 100644 --- a/precompile/contracts/nativeminter/module.go +++ b/precompile/contracts/nativeminter/module.go @@ -49,5 +49,5 @@ func (*configuror) Configure(_ contract.ChainConfig, cfg config.Config, state co } } - return config.AllowListConfig.Configure(state, ContractAddress) + return config.Config.Configure(state, ContractAddress) } diff --git a/precompile/contracts/rewardmanager/config.go b/precompile/contracts/rewardmanager/config.go index 5495f7d602..4f3e3aa4d2 100644 --- a/precompile/contracts/rewardmanager/config.go +++ b/precompile/contracts/rewardmanager/config.go @@ -57,8 +57,8 @@ func (i *InitialRewardConfig) Configure(state contract.StateDB) error { // RewardManagerConfig implements the StatefulPrecompileConfig // interface while adding in the RewardManager specific precompile config. type RewardManagerConfig struct { - allowlist.AllowListConfig - config.UpgradeableConfig + allowlist.Config + config.Uprade InitialRewardConfig *InitialRewardConfig `json:"initialRewardConfig,omitempty"` } @@ -66,11 +66,11 @@ type RewardManagerConfig struct { // RewardManager with the given [admins] and [enableds] as members of the allowlist with [initialConfig] as initial rewards config if specified. func NewRewardManagerConfig(blockTimestamp *big.Int, admins []common.Address, enableds []common.Address, initialConfig *InitialRewardConfig) *RewardManagerConfig { return &RewardManagerConfig{ - AllowListConfig: allowlist.AllowListConfig{ + Config: allowlist.Config{ AdminAddresses: admins, EnabledAddresses: enableds, }, - UpgradeableConfig: config.UpgradeableConfig{BlockTimestamp: blockTimestamp}, + Uprade: config.Uprade{BlockTimestamp: blockTimestamp}, InitialRewardConfig: initialConfig, } } @@ -79,7 +79,7 @@ func NewRewardManagerConfig(blockTimestamp *big.Int, admins []common.Address, en // that disables RewardManager. func NewDisableRewardManagerConfig(blockTimestamp *big.Int) *RewardManagerConfig { return &RewardManagerConfig{ - UpgradeableConfig: config.UpgradeableConfig{ + Uprade: config.Uprade{ BlockTimestamp: blockTimestamp, Disable: true, }, @@ -89,7 +89,7 @@ func NewDisableRewardManagerConfig(blockTimestamp *big.Int) *RewardManagerConfig func (RewardManagerConfig) Key() string { return ConfigKey } func (c *RewardManagerConfig) Verify() error { - if err := c.AllowListConfig.Verify(); err != nil { + if err := c.Config.Verify(); err != nil { return err } if c.InitialRewardConfig != nil { @@ -107,7 +107,7 @@ func (c *RewardManagerConfig) Equal(cfg config.Config) bool { } // modify this boolean accordingly with your custom RewardManagerConfig, to check if [other] and the current [c] are equal // if RewardManagerConfig contains only UpgradeableConfig and precompile.AllowListConfig you can skip modifying it. - equals := c.UpgradeableConfig.Equal(&other.UpgradeableConfig) && c.AllowListConfig.Equal(&other.AllowListConfig) + equals := c.Uprade.Equal(&other.Uprade) && c.Config.Equal(&other.Config) if !equals { return false } diff --git a/precompile/contracts/rewardmanager/module.go b/precompile/contracts/rewardmanager/module.go index 7559f5ec1a..b3efe3cbf0 100644 --- a/precompile/contracts/rewardmanager/module.go +++ b/precompile/contracts/rewardmanager/module.go @@ -42,7 +42,7 @@ func (*configuror) Configure(chainConfig contract.ChainConfig, cfg config.Config return fmt.Errorf("incorrect config %T: %v", config, config) } // TODO: should we move this to the end and return it for consistency with other precompiles? - if err := config.AllowListConfig.Configure(state, ContractAddress); err != nil { + if err := config.Config.Configure(state, ContractAddress); err != nil { return err } // configure the RewardManager with the given initial configuration diff --git a/precompile/contracts/txallowlist/config.go b/precompile/contracts/txallowlist/config.go index 8f7bfddf42..778f2ee03e 100644 --- a/precompile/contracts/txallowlist/config.go +++ b/precompile/contracts/txallowlist/config.go @@ -16,19 +16,19 @@ var _ config.Config = &TxAllowListConfig{} // TxAllowListConfig wraps [AllowListConfig] and uses it to implement the StatefulPrecompileConfig // interface while adding in the TxAllowList specific precompile address. type TxAllowListConfig struct { - allowlist.AllowListConfig - config.UpgradeableConfig + allowlist.Config + config.Uprade } // NewTxAllowListConfig returns a config for a network upgrade at [blockTimestamp] that enables // TxAllowList with the given [admins] and [enableds] as members of the allowlist. func NewTxAllowListConfig(blockTimestamp *big.Int, admins []common.Address, enableds []common.Address) *TxAllowListConfig { return &TxAllowListConfig{ - AllowListConfig: allowlist.AllowListConfig{ + Config: allowlist.Config{ AdminAddresses: admins, EnabledAddresses: enableds, }, - UpgradeableConfig: config.UpgradeableConfig{BlockTimestamp: blockTimestamp}, + Uprade: config.Uprade{BlockTimestamp: blockTimestamp}, } } @@ -36,7 +36,7 @@ func NewTxAllowListConfig(blockTimestamp *big.Int, admins []common.Address, enab // that disables TxAllowList. func NewDisableTxAllowListConfig(blockTimestamp *big.Int) *TxAllowListConfig { return &TxAllowListConfig{ - UpgradeableConfig: config.UpgradeableConfig{ + Uprade: config.Uprade{ BlockTimestamp: blockTimestamp, Disable: true, }, @@ -52,5 +52,5 @@ func (c *TxAllowListConfig) Equal(cfg config.Config) bool { if !ok { return false } - return c.UpgradeableConfig.Equal(&other.UpgradeableConfig) && c.AllowListConfig.Equal(&other.AllowListConfig) + return c.Uprade.Equal(&other.Uprade) && c.Config.Equal(&other.Config) } diff --git a/precompile/contracts/txallowlist/module.go b/precompile/contracts/txallowlist/module.go index fe5314d04d..0c73040bd9 100644 --- a/precompile/contracts/txallowlist/module.go +++ b/precompile/contracts/txallowlist/module.go @@ -41,5 +41,5 @@ func (*configuror) Configure(chainConfig contract.ChainConfig, cfg config.Config if !ok { return fmt.Errorf("incorrect config %T: %v", config, config) } - return config.AllowListConfig.Configure(state, ContractAddress) + return config.Config.Configure(state, ContractAddress) } From 19f54c9b359cd2b538774d28524bc80beb9259e4 Mon Sep 17 00:00:00 2001 From: Ceyhun Onur Date: Tue, 14 Feb 2023 13:50:01 +0300 Subject: [PATCH 5/5] moar reviews --- core/genesis_test.go | 4 +- core/state_processor_test.go | 2 +- core/test_blockchain.go | 4 +- eth/gasprice/gasprice_test.go | 2 +- params/config_test.go | 4 +- params/precompile_config_test.go | 50 ++++++++-------- params/precompile_upgrade_test.go | 60 +++++++++---------- plugin/evm/vm_test.go | 12 ++-- plugin/evm/vm_upgrade_bytes_test.go | 4 +- .../contracts/deployerallowlist/config.go | 26 ++++---- .../deployerallowlist/config_test.go | 22 +++---- .../contracts/deployerallowlist/module.go | 8 ++- precompile/contracts/feemanager/config.go | 26 ++++---- .../contracts/feemanager/config_test.go | 28 ++++----- .../contracts/feemanager/contract_test.go | 4 +- precompile/contracts/feemanager/module.go | 8 ++- precompile/contracts/nativeminter/config.go | 26 ++++---- .../contracts/nativeminter/config_test.go | 34 +++++------ .../contracts/nativeminter/contract_test.go | 2 +- precompile/contracts/nativeminter/module.go | 8 ++- precompile/contracts/rewardmanager/config.go | 26 ++++---- .../contracts/rewardmanager/config_test.go | 28 ++++----- .../contracts/rewardmanager/contract_test.go | 4 +- precompile/contracts/rewardmanager/module.go | 8 ++- precompile/contracts/txallowlist/config.go | 24 ++++---- .../contracts/txallowlist/config_test.go | 26 ++++---- precompile/contracts/txallowlist/module.go | 8 ++- precompile/registry/registry.go | 20 +++++++ 28 files changed, 254 insertions(+), 224 deletions(-) diff --git a/core/genesis_test.go b/core/genesis_test.go index da89e9699f..3c2b57d1c0 100644 --- a/core/genesis_test.go +++ b/core/genesis_test.go @@ -192,7 +192,7 @@ func TestStatefulPrecompilesConfigure(t *testing.T) { getConfig: func() *params.ChainConfig { config := *params.TestChainConfig config.GenesisPrecompiles = params.ChainConfigPrecompiles{ - deployerallowlist.ConfigKey: deployerallowlist.NewContractDeployerAllowListConfig(big.NewInt(0), []common.Address{addr}, nil), + deployerallowlist.ConfigKey: deployerallowlist.NewConfig(big.NewInt(0), []common.Address{addr}, nil), } return &config }, @@ -268,7 +268,7 @@ func TestPrecompileActivationAfterHeaderBlock(t *testing.T) { require.Greater(block.Time(), bc.lastAccepted.Time()) activatedGenesis := customg - contractDeployerConfig := deployerallowlist.NewContractDeployerAllowListConfig(big.NewInt(51), nil, nil) + contractDeployerConfig := deployerallowlist.NewConfig(big.NewInt(51), nil, nil) activatedGenesis.Config.UpgradeConfig.PrecompileUpgrades = []params.PrecompileUpgrade{ { Config: contractDeployerConfig, diff --git a/core/state_processor_test.go b/core/state_processor_test.go index 44f11035d2..3a11ac5b89 100644 --- a/core/state_processor_test.go +++ b/core/state_processor_test.go @@ -316,7 +316,7 @@ func TestBadTxAllowListBlock(t *testing.T) { SubnetEVMTimestamp: big.NewInt(0), }, GenesisPrecompiles: params.ChainConfigPrecompiles{ - txallowlist.ConfigKey: txallowlist.NewTxAllowListConfig(big.NewInt(0), nil, nil), + txallowlist.ConfigKey: txallowlist.NewConfig(big.NewInt(0), nil, nil), }, } signer = types.LatestSigner(config) diff --git a/core/test_blockchain.go b/core/test_blockchain.go index a69e98d568..2acbf65eae 100644 --- a/core/test_blockchain.go +++ b/core/test_blockchain.go @@ -1549,8 +1549,8 @@ func TestStatefulPrecompiles(t *testing.T, create func(db ethdb.Database, chainC config := *params.TestChainConfig // Set all of the required config parameters config.GenesisPrecompiles = params.ChainConfigPrecompiles{ - deployerallowlist.ConfigKey: deployerallowlist.NewContractDeployerAllowListConfig(big.NewInt(0), []common.Address{addr1}, nil), - feemanager.ConfigKey: feemanager.NewFeeManagerConfig(big.NewInt(0), []common.Address{addr1}, nil, nil), + deployerallowlist.ConfigKey: deployerallowlist.NewConfig(big.NewInt(0), []common.Address{addr1}, nil), + feemanager.ConfigKey: feemanager.NewConfig(big.NewInt(0), []common.Address{addr1}, nil, nil), } gspec := &Genesis{ Config: &config, diff --git a/eth/gasprice/gasprice_test.go b/eth/gasprice/gasprice_test.go index 67a19c9bf3..049c154127 100644 --- a/eth/gasprice/gasprice_test.go +++ b/eth/gasprice/gasprice_test.go @@ -435,7 +435,7 @@ func TestSuggestGasPriceAfterFeeConfigUpdate(t *testing.T) { // create a chain config with fee manager enabled at genesis with [addr] as the admin chainConfig := *params.TestChainConfig chainConfig.GenesisPrecompiles = params.ChainConfigPrecompiles{ - feemanager.ConfigKey: feemanager.NewFeeManagerConfig(big.NewInt(0), []common.Address{addr}, nil, nil), + feemanager.ConfigKey: feemanager.NewConfig(big.NewInt(0), []common.Address{addr}, nil, nil), } // create a fee config with higher MinBaseFee and prepare it for inclusion in a tx diff --git a/params/config_test.go b/params/config_test.go index b4f3b003bd..9032be1037 100644 --- a/params/config_test.go +++ b/params/config_test.go @@ -146,7 +146,7 @@ func TestCheckCompatible(t *testing.T) { func TestConfigUnmarshalJSON(t *testing.T) { require := require.New(t) - testRewardManagerConfig := rewardmanager.NewRewardManagerConfig( + testRewardManagerConfig := rewardmanager.NewConfig( big.NewInt(1671542573), []common.Address{common.HexToAddress("0x8db97C7cEcE249c2b98bDC0226Cc4C2A57BF52FC")}, nil, @@ -154,7 +154,7 @@ func TestConfigUnmarshalJSON(t *testing.T) { AllowFeeRecipients: true, }) - testContractNativeMinterConfig := nativeminter.NewContractNativeMinterConfig(big.NewInt(0), + testContractNativeMinterConfig := nativeminter.NewConfig(big.NewInt(0), []common.Address{common.HexToAddress("0x8db97C7cEcE249c2b98bDC0226Cc4C2A57BF52FC")}, nil, nil, diff --git a/params/precompile_config_test.go b/params/precompile_config_test.go index 8087ac5b65..a395f1e367 100644 --- a/params/precompile_config_test.go +++ b/params/precompile_config_test.go @@ -24,16 +24,16 @@ func TestVerifyWithChainConfig(t *testing.T) { baseConfig := *SubnetEVMDefaultChainConfig config := &baseConfig config.GenesisPrecompiles = ChainConfigPrecompiles{ - txallowlist.ConfigKey: txallowlist.NewTxAllowListConfig(big.NewInt(2), nil, nil), + txallowlist.ConfigKey: txallowlist.NewConfig(big.NewInt(2), nil, nil), } config.PrecompileUpgrades = []PrecompileUpgrade{ { // disable TxAllowList at timestamp 4 - txallowlist.NewDisableTxAllowListConfig(big.NewInt(4)), + txallowlist.NewDisableConfig(big.NewInt(4)), }, { // re-enable TxAllowList at timestamp 5 - txallowlist.NewTxAllowListConfig(big.NewInt(5), admins, nil), + txallowlist.NewConfig(big.NewInt(5), admins, nil), }, } @@ -46,7 +46,7 @@ func TestVerifyWithChainConfig(t *testing.T) { badConfig.PrecompileUpgrades = append( badConfig.PrecompileUpgrades, PrecompileUpgrade{ - Config: txallowlist.NewDisableTxAllowListConfig(big.NewInt(5)), + Config: txallowlist.NewDisableConfig(big.NewInt(5)), }, ) err = badConfig.Verify() @@ -57,7 +57,7 @@ func TestVerifyWithChainConfig(t *testing.T) { badConfig.PrecompileUpgrades = append( badConfig.PrecompileUpgrades, PrecompileUpgrade{ - Config: txallowlist.NewTxAllowListConfig(big.NewInt(5), admins, nil), + Config: txallowlist.NewConfig(big.NewInt(5), admins, nil), }, ) err = badConfig.Verify() @@ -75,10 +75,10 @@ func TestVerifyPrecompileUpgrades(t *testing.T) { name: "enable and disable tx allow list", upgrades: []PrecompileUpgrade{ { - Config: txallowlist.NewTxAllowListConfig(big.NewInt(1), admins, nil), + Config: txallowlist.NewConfig(big.NewInt(1), admins, nil), }, { - Config: txallowlist.NewDisableTxAllowListConfig(big.NewInt(2)), + Config: txallowlist.NewDisableConfig(big.NewInt(2)), }, }, expectedError: "", @@ -87,13 +87,13 @@ func TestVerifyPrecompileUpgrades(t *testing.T) { name: "invalid allow list config in tx allowlist", upgrades: []PrecompileUpgrade{ { - Config: txallowlist.NewTxAllowListConfig(big.NewInt(1), admins, nil), + Config: txallowlist.NewConfig(big.NewInt(1), admins, nil), }, { - Config: txallowlist.NewDisableTxAllowListConfig(big.NewInt(2)), + Config: txallowlist.NewDisableConfig(big.NewInt(2)), }, { - Config: txallowlist.NewTxAllowListConfig(big.NewInt(3), admins, admins), + Config: txallowlist.NewConfig(big.NewInt(3), admins, admins), }, }, expectedError: "cannot set address", @@ -102,7 +102,7 @@ func TestVerifyPrecompileUpgrades(t *testing.T) { name: "invalid initial fee manager config", upgrades: []PrecompileUpgrade{ { - Config: feemanager.NewFeeManagerConfig(big.NewInt(3), admins, nil, + Config: feemanager.NewConfig(big.NewInt(3), admins, nil, &commontype.FeeConfig{ GasLimit: big.NewInt(-1), }), @@ -114,7 +114,7 @@ func TestVerifyPrecompileUpgrades(t *testing.T) { name: "invalid initial fee manager config gas limit 0", upgrades: []PrecompileUpgrade{ { - Config: feemanager.NewFeeManagerConfig(big.NewInt(3), admins, nil, + Config: feemanager.NewConfig(big.NewInt(3), admins, nil, &commontype.FeeConfig{ GasLimit: big.NewInt(0), }), @@ -126,10 +126,10 @@ func TestVerifyPrecompileUpgrades(t *testing.T) { name: "different upgrades are allowed to configure same timestamp for different precompiles", upgrades: []PrecompileUpgrade{ { - Config: txallowlist.NewTxAllowListConfig(big.NewInt(1), admins, nil), + Config: txallowlist.NewConfig(big.NewInt(1), admins, nil), }, { - Config: feemanager.NewFeeManagerConfig(big.NewInt(1), admins, nil, nil), + Config: feemanager.NewConfig(big.NewInt(1), admins, nil, nil), }, }, expectedError: "", @@ -138,10 +138,10 @@ func TestVerifyPrecompileUpgrades(t *testing.T) { name: "different upgrades must be monotonically increasing", upgrades: []PrecompileUpgrade{ { - Config: txallowlist.NewTxAllowListConfig(big.NewInt(2), admins, nil), + Config: txallowlist.NewConfig(big.NewInt(2), admins, nil), }, { - Config: feemanager.NewFeeManagerConfig(big.NewInt(1), admins, nil, nil), + Config: feemanager.NewConfig(big.NewInt(1), admins, nil, nil), }, }, expectedError: "config block timestamp (1) < previous timestamp (2)", @@ -150,10 +150,10 @@ func TestVerifyPrecompileUpgrades(t *testing.T) { name: "upgrades with same keys are not allowed to configure same timestamp for same precompiles", upgrades: []PrecompileUpgrade{ { - Config: txallowlist.NewTxAllowListConfig(big.NewInt(1), admins, nil), + Config: txallowlist.NewConfig(big.NewInt(1), admins, nil), }, { - Config: txallowlist.NewDisableTxAllowListConfig(big.NewInt(1)), + Config: txallowlist.NewDisableConfig(big.NewInt(1)), }, }, expectedError: " config block timestamp (1) <= previous timestamp (1) of same key", @@ -186,14 +186,14 @@ func TestVerifyPrecompiles(t *testing.T) { { name: "invalid allow list config in tx allowlist", upgrade: ChainConfigPrecompiles{ - txallowlist.ConfigKey: txallowlist.NewTxAllowListConfig(big.NewInt(3), admins, admins), + txallowlist.ConfigKey: txallowlist.NewConfig(big.NewInt(3), admins, admins), }, expectedError: "cannot set address", }, { name: "invalid initial fee manager config", upgrade: ChainConfigPrecompiles{ - feemanager.ConfigKey: feemanager.NewFeeManagerConfig(big.NewInt(3), admins, nil, + feemanager.ConfigKey: feemanager.NewConfig(big.NewInt(3), admins, nil, &commontype.FeeConfig{ GasLimit: big.NewInt(-1), }), @@ -224,10 +224,10 @@ func TestVerifyRequiresSortedTimestamps(t *testing.T) { config := &baseConfig config.PrecompileUpgrades = []PrecompileUpgrade{ { - Config: txallowlist.NewTxAllowListConfig(big.NewInt(2), admins, nil), + Config: txallowlist.NewConfig(big.NewInt(2), admins, nil), }, { - Config: deployerallowlist.NewContractDeployerAllowListConfig(big.NewInt(1), admins, nil), + Config: deployerallowlist.NewConfig(big.NewInt(1), admins, nil), }, } @@ -241,7 +241,7 @@ func TestGetPrecompileConfig(t *testing.T) { baseConfig := *SubnetEVMDefaultChainConfig config := &baseConfig config.GenesisPrecompiles = ChainConfigPrecompiles{ - deployerallowlist.ConfigKey: deployerallowlist.NewContractDeployerAllowListConfig(big.NewInt(10), nil, nil), + deployerallowlist.ConfigKey: deployerallowlist.NewConfig(big.NewInt(10), nil, nil), } deployerConfig := config.GetActivePrecompileConfig(deployerallowlist.ContractAddress, big.NewInt(0)) @@ -292,7 +292,7 @@ func TestPrecompileUpgradeUnmarshalJSON(t *testing.T) { rewardManagerConf := upgradeConfig.PrecompileUpgrades[0] require.Equal(rewardManagerConf.Key(), rewardmanager.ConfigKey) - testRewardManagerConfig := rewardmanager.NewRewardManagerConfig( + testRewardManagerConfig := rewardmanager.NewConfig( big.NewInt(1671542573), []common.Address{common.HexToAddress("0x8db97C7cEcE249c2b98bDC0226Cc4C2A57BF52FC")}, nil, @@ -303,7 +303,7 @@ func TestPrecompileUpgradeUnmarshalJSON(t *testing.T) { contractNativeMinterConf := upgradeConfig.PrecompileUpgrades[1] require.Equal(contractNativeMinterConf.Key(), nativeminter.ConfigKey) - testContractNativeMinterConfig := nativeminter.NewContractNativeMinterConfig(big.NewInt(1671543172), nil, nil, nil) + testContractNativeMinterConfig := nativeminter.NewConfig(big.NewInt(1671543172), nil, nil, nil) require.True(contractNativeMinterConf.Equal(testContractNativeMinterConfig)) // Marshal and unmarshal again and check that the result is the same diff --git a/params/precompile_upgrade_test.go b/params/precompile_upgrade_test.go index a8a667cb87..3048693f65 100644 --- a/params/precompile_upgrade_test.go +++ b/params/precompile_upgrade_test.go @@ -17,7 +17,7 @@ func TestVerifyUpgradeConfig(t *testing.T) { admins := []common.Address{{1}} chainConfig := *TestChainConfig chainConfig.GenesisPrecompiles = ChainConfigPrecompiles{ - txallowlist.ConfigKey: txallowlist.NewTxAllowListConfig(big.NewInt(1), admins, nil), + txallowlist.ConfigKey: txallowlist.NewConfig(big.NewInt(1), admins, nil), } type test struct { @@ -30,7 +30,7 @@ func TestVerifyUpgradeConfig(t *testing.T) { expectedErrorString: "disable should be [true]", upgrades: []PrecompileUpgrade{ { - Config: txallowlist.NewTxAllowListConfig(big.NewInt(2), admins, nil), + Config: txallowlist.NewConfig(big.NewInt(2), admins, nil), }, }, }, @@ -38,7 +38,7 @@ func TestVerifyUpgradeConfig(t *testing.T) { expectedErrorString: "config block timestamp (0) <= previous timestamp (1) of same key", upgrades: []PrecompileUpgrade{ { - Config: txallowlist.NewDisableTxAllowListConfig(big.NewInt(0)), + Config: txallowlist.NewDisableConfig(big.NewInt(0)), }, }, }, @@ -46,7 +46,7 @@ func TestVerifyUpgradeConfig(t *testing.T) { expectedErrorString: "config block timestamp (1) <= previous timestamp (1) of same key", upgrades: []PrecompileUpgrade{ { - Config: txallowlist.NewDisableTxAllowListConfig(big.NewInt(1)), + Config: txallowlist.NewDisableConfig(big.NewInt(1)), }, }, }, @@ -74,8 +74,8 @@ func TestCheckCompatibleUpgradeConfigs(t *testing.T) { admins := []common.Address{{1}} chainConfig := *TestChainConfig chainConfig.GenesisPrecompiles = ChainConfigPrecompiles{ - txallowlist.ConfigKey: txallowlist.NewTxAllowListConfig(big.NewInt(1), admins, nil), - deployerallowlist.ConfigKey: deployerallowlist.NewContractDeployerAllowListConfig(big.NewInt(10), admins, nil), + txallowlist.ConfigKey: txallowlist.NewConfig(big.NewInt(1), admins, nil), + deployerallowlist.ConfigKey: deployerallowlist.NewConfig(big.NewInt(10), admins, nil), } type test struct { @@ -91,10 +91,10 @@ func TestCheckCompatibleUpgradeConfigs(t *testing.T) { { PrecompileUpgrades: []PrecompileUpgrade{ { - Config: txallowlist.NewDisableTxAllowListConfig(big.NewInt(6)), + Config: txallowlist.NewDisableConfig(big.NewInt(6)), }, { - Config: txallowlist.NewTxAllowListConfig(big.NewInt(7), admins, nil), + Config: txallowlist.NewConfig(big.NewInt(7), admins, nil), }, }, }, @@ -106,20 +106,20 @@ func TestCheckCompatibleUpgradeConfigs(t *testing.T) { { PrecompileUpgrades: []PrecompileUpgrade{ { - Config: txallowlist.NewDisableTxAllowListConfig(big.NewInt(6)), + Config: txallowlist.NewDisableConfig(big.NewInt(6)), }, { - Config: txallowlist.NewTxAllowListConfig(big.NewInt(7), admins, nil), + Config: txallowlist.NewConfig(big.NewInt(7), admins, nil), }, }, }, { PrecompileUpgrades: []PrecompileUpgrade{ { - Config: txallowlist.NewDisableTxAllowListConfig(big.NewInt(6)), + Config: txallowlist.NewDisableConfig(big.NewInt(6)), }, { - Config: txallowlist.NewTxAllowListConfig(big.NewInt(8), admins, nil), + Config: txallowlist.NewConfig(big.NewInt(8), admins, nil), }, }, }, @@ -132,20 +132,20 @@ func TestCheckCompatibleUpgradeConfigs(t *testing.T) { { PrecompileUpgrades: []PrecompileUpgrade{ { - Config: txallowlist.NewDisableTxAllowListConfig(big.NewInt(6)), + Config: txallowlist.NewDisableConfig(big.NewInt(6)), }, { - Config: txallowlist.NewTxAllowListConfig(big.NewInt(7), admins, nil), + Config: txallowlist.NewConfig(big.NewInt(7), admins, nil), }, }, }, { PrecompileUpgrades: []PrecompileUpgrade{ { - Config: txallowlist.NewDisableTxAllowListConfig(big.NewInt(6)), + Config: txallowlist.NewDisableConfig(big.NewInt(6)), }, { - Config: txallowlist.NewTxAllowListConfig(big.NewInt(8), admins, nil), + Config: txallowlist.NewConfig(big.NewInt(8), admins, nil), }, }, }, @@ -157,17 +157,17 @@ func TestCheckCompatibleUpgradeConfigs(t *testing.T) { { PrecompileUpgrades: []PrecompileUpgrade{ { - Config: txallowlist.NewDisableTxAllowListConfig(big.NewInt(6)), + Config: txallowlist.NewDisableConfig(big.NewInt(6)), }, { - Config: txallowlist.NewTxAllowListConfig(big.NewInt(7), admins, nil), + Config: txallowlist.NewConfig(big.NewInt(7), admins, nil), }, }, }, { PrecompileUpgrades: []PrecompileUpgrade{ { - Config: txallowlist.NewDisableTxAllowListConfig(big.NewInt(6)), + Config: txallowlist.NewDisableConfig(big.NewInt(6)), }, }, }, @@ -180,17 +180,17 @@ func TestCheckCompatibleUpgradeConfigs(t *testing.T) { { PrecompileUpgrades: []PrecompileUpgrade{ { - Config: txallowlist.NewDisableTxAllowListConfig(big.NewInt(6)), + Config: txallowlist.NewDisableConfig(big.NewInt(6)), }, { - Config: txallowlist.NewTxAllowListConfig(big.NewInt(7), admins, nil), + Config: txallowlist.NewConfig(big.NewInt(7), admins, nil), }, }, }, { PrecompileUpgrades: []PrecompileUpgrade{ { - Config: txallowlist.NewDisableTxAllowListConfig(big.NewInt(6)), + Config: txallowlist.NewDisableConfig(big.NewInt(6)), }, }, }, @@ -203,21 +203,21 @@ func TestCheckCompatibleUpgradeConfigs(t *testing.T) { { PrecompileUpgrades: []PrecompileUpgrade{ { - Config: txallowlist.NewDisableTxAllowListConfig(big.NewInt(6)), + Config: txallowlist.NewDisableConfig(big.NewInt(6)), }, { - Config: txallowlist.NewTxAllowListConfig(big.NewInt(7), admins, nil), + Config: txallowlist.NewConfig(big.NewInt(7), admins, nil), }, }, }, { PrecompileUpgrades: []PrecompileUpgrade{ { - Config: txallowlist.NewDisableTxAllowListConfig(big.NewInt(6)), + Config: txallowlist.NewDisableConfig(big.NewInt(6)), }, { // uses a different (empty) admin list, not allowed - Config: txallowlist.NewTxAllowListConfig(big.NewInt(7), []common.Address{}, nil), + Config: txallowlist.NewConfig(big.NewInt(7), []common.Address{}, nil), }, }, }, @@ -229,20 +229,20 @@ func TestCheckCompatibleUpgradeConfigs(t *testing.T) { { PrecompileUpgrades: []PrecompileUpgrade{ { - Config: txallowlist.NewDisableTxAllowListConfig(big.NewInt(6)), + Config: txallowlist.NewDisableConfig(big.NewInt(6)), }, { - Config: txallowlist.NewTxAllowListConfig(big.NewInt(7), admins, nil), + Config: txallowlist.NewConfig(big.NewInt(7), admins, nil), }, }, }, { PrecompileUpgrades: []PrecompileUpgrade{ { - Config: txallowlist.NewDisableTxAllowListConfig(big.NewInt(6)), + Config: txallowlist.NewDisableConfig(big.NewInt(6)), }, { - Config: txallowlist.NewTxAllowListConfig(big.NewInt(7), admins, nil), + Config: txallowlist.NewConfig(big.NewInt(7), admins, nil), }, }, }, diff --git a/plugin/evm/vm_test.go b/plugin/evm/vm_test.go index c7ddf0f3bf..dbbf7b8f10 100644 --- a/plugin/evm/vm_test.go +++ b/plugin/evm/vm_test.go @@ -2121,7 +2121,7 @@ func TestBuildAllowListActivationBlock(t *testing.T) { t.Fatal(err) } genesis.Config.GenesisPrecompiles = params.ChainConfigPrecompiles{ - deployerallowlist.ConfigKey: deployerallowlist.NewContractDeployerAllowListConfig(big.NewInt(time.Now().Unix()), testEthAddrs, nil), + deployerallowlist.ConfigKey: deployerallowlist.NewConfig(big.NewInt(time.Now().Unix()), testEthAddrs, nil), } genesisJSON, err := genesis.MarshalJSON() @@ -2187,7 +2187,7 @@ func TestTxAllowListSuccessfulTx(t *testing.T) { t.Fatal(err) } genesis.Config.GenesisPrecompiles = params.ChainConfigPrecompiles{ - txallowlist.ConfigKey: txallowlist.NewTxAllowListConfig(big.NewInt(0), testEthAddrs[0:1], nil), + txallowlist.ConfigKey: txallowlist.NewConfig(big.NewInt(0), testEthAddrs[0:1], nil), } genesisJSON, err := genesis.MarshalJSON() if err != nil { @@ -2265,7 +2265,7 @@ func TestTxAllowListDisablePrecompile(t *testing.T) { } enableAllowListTimestamp := time.Unix(0, 0) // enable at genesis genesis.Config.GenesisPrecompiles = params.ChainConfigPrecompiles{ - txallowlist.ConfigKey: txallowlist.NewTxAllowListConfig(big.NewInt(enableAllowListTimestamp.Unix()), testEthAddrs[0:1], nil), + txallowlist.ConfigKey: txallowlist.NewConfig(big.NewInt(enableAllowListTimestamp.Unix()), testEthAddrs[0:1], nil), } genesisJSON, err := genesis.MarshalJSON() if err != nil { @@ -2379,7 +2379,7 @@ func TestFeeManagerChangeFee(t *testing.T) { t.Fatal(err) } genesis.Config.GenesisPrecompiles = params.ChainConfigPrecompiles{ - feemanager.ConfigKey: feemanager.NewFeeManagerConfig(big.NewInt(0), testEthAddrs[0:1], nil, nil), + feemanager.ConfigKey: feemanager.NewConfig(big.NewInt(0), testEthAddrs[0:1], nil, nil), } // set a lower fee config now @@ -2621,7 +2621,7 @@ func TestRewardManagerPrecompileSetRewardAddress(t *testing.T) { require.NoError(t, genesis.UnmarshalJSON([]byte(genesisJSONSubnetEVM))) genesis.Config.GenesisPrecompiles = params.ChainConfigPrecompiles{ - rewardmanager.ConfigKey: rewardmanager.NewRewardManagerConfig(common.Big0, testEthAddrs[0:1], nil, nil), + rewardmanager.ConfigKey: rewardmanager.NewConfig(common.Big0, testEthAddrs[0:1], nil, nil), } genesis.Config.AllowFeeRecipients = true // enable this in genesis to test if this is recognized by the reward manager genesisJSON, err := genesis.MarshalJSON() @@ -2763,7 +2763,7 @@ func TestRewardManagerPrecompileAllowFeeRecipients(t *testing.T) { require.NoError(t, genesis.UnmarshalJSON([]byte(genesisJSONSubnetEVM))) genesis.Config.GenesisPrecompiles = params.ChainConfigPrecompiles{ - rewardmanager.ConfigKey: rewardmanager.NewRewardManagerConfig(common.Big0, testEthAddrs[0:1], nil, nil), + rewardmanager.ConfigKey: rewardmanager.NewConfig(common.Big0, testEthAddrs[0:1], nil, nil), } genesis.Config.AllowFeeRecipients = false // disable this in genesis genesisJSON, err := genesis.MarshalJSON() diff --git a/plugin/evm/vm_upgrade_bytes_test.go b/plugin/evm/vm_upgrade_bytes_test.go index 8218e8f625..85e8ba540e 100644 --- a/plugin/evm/vm_upgrade_bytes_test.go +++ b/plugin/evm/vm_upgrade_bytes_test.go @@ -28,7 +28,7 @@ func TestVMUpgradeBytesPrecompile(t *testing.T) { upgradeConfig := ¶ms.UpgradeConfig{ PrecompileUpgrades: []params.PrecompileUpgrade{ { - Config: txallowlist.NewTxAllowListConfig(big.NewInt(enableAllowListTimestamp.Unix()), testEthAddrs[0:1], nil), + Config: txallowlist.NewConfig(big.NewInt(enableAllowListTimestamp.Unix()), testEthAddrs[0:1], nil), }, }, } @@ -71,7 +71,7 @@ func TestVMUpgradeBytesPrecompile(t *testing.T) { upgradeConfig.PrecompileUpgrades = append( upgradeConfig.PrecompileUpgrades, params.PrecompileUpgrade{ - Config: txallowlist.NewDisableTxAllowListConfig(big.NewInt(disableAllowListTimestamp.Unix())), + Config: txallowlist.NewDisableConfig(big.NewInt(disableAllowListTimestamp.Unix())), }, ) upgradeBytesJSON, err = json.Marshal(upgradeConfig) diff --git a/precompile/contracts/deployerallowlist/config.go b/precompile/contracts/deployerallowlist/config.go index d7634afe79..beef49c635 100644 --- a/precompile/contracts/deployerallowlist/config.go +++ b/precompile/contracts/deployerallowlist/config.go @@ -11,19 +11,19 @@ import ( "github.com/ethereum/go-ethereum/common" ) -var _ config.Config = &ContractDeployerAllowListConfig{} +var _ config.Config = &Config{} -// ContractDeployerAllowListConfig wraps [AllowListConfig] and uses it to implement the StatefulPrecompileConfig +// Config wraps [AllowListConfig] and uses it to implement the StatefulPrecompileConfig // interface while adding in the contract deployer specific precompile address. -type ContractDeployerAllowListConfig struct { +type Config struct { allowlist.Config config.Uprade } -// NewContractDeployerAllowListConfig returns a config for a network upgrade at [blockTimestamp] that enables +// NewConfig returns a config for a network upgrade at [blockTimestamp] that enables // ContractDeployerAllowList with [admins] and [enableds] as members of the allowlist. -func NewContractDeployerAllowListConfig(blockTimestamp *big.Int, admins []common.Address, enableds []common.Address) *ContractDeployerAllowListConfig { - return &ContractDeployerAllowListConfig{ +func NewConfig(blockTimestamp *big.Int, admins []common.Address, enableds []common.Address) *Config { + return &Config{ Config: allowlist.Config{ AdminAddresses: admins, EnabledAddresses: enableds, @@ -32,10 +32,10 @@ func NewContractDeployerAllowListConfig(blockTimestamp *big.Int, admins []common } } -// NewDisableContractDeployerAllowListConfig returns config for a network upgrade at [blockTimestamp] +// NewDisableConfig returns config for a network upgrade at [blockTimestamp] // that disables ContractDeployerAllowList. -func NewDisableContractDeployerAllowListConfig(blockTimestamp *big.Int) *ContractDeployerAllowListConfig { - return &ContractDeployerAllowListConfig{ +func NewDisableConfig(blockTimestamp *big.Int) *Config { + return &Config{ Uprade: config.Uprade{ BlockTimestamp: blockTimestamp, Disable: true, @@ -43,16 +43,16 @@ func NewDisableContractDeployerAllowListConfig(blockTimestamp *big.Int) *Contrac } } -func (ContractDeployerAllowListConfig) Key() string { return ConfigKey } +func (Config) Key() string { return ConfigKey } // Equal returns true if [cfg] is a [*ContractDeployerAllowListConfig] and it has been configured identical to [c]. -func (c *ContractDeployerAllowListConfig) Equal(cfg config.Config) bool { +func (c *Config) Equal(cfg config.Config) bool { // typecast before comparison - other, ok := (cfg).(*ContractDeployerAllowListConfig) + other, ok := (cfg).(*Config) if !ok { return false } return c.Uprade.Equal(&other.Uprade) && c.Config.Equal(&other.Config) } -func (c *ContractDeployerAllowListConfig) Verify() error { return c.Config.Verify() } +func (c *Config) Verify() error { return c.Config.Verify() } diff --git a/precompile/contracts/deployerallowlist/config_test.go b/precompile/contracts/deployerallowlist/config_test.go index 047ab85182..c1245b0b09 100644 --- a/precompile/contracts/deployerallowlist/config_test.go +++ b/precompile/contracts/deployerallowlist/config_test.go @@ -21,7 +21,7 @@ func TestVerifyContractDeployerConfig(t *testing.T) { }{ { name: "invalid allow list config in deployer allowlist", - config: NewContractDeployerAllowListConfig(big.NewInt(3), admins, admins), + config: NewConfig(big.NewInt(3), admins, admins), expectedError: "cannot set address", }, } @@ -50,38 +50,38 @@ func TestEqualContractDeployerAllowListConfig(t *testing.T) { }{ { name: "non-nil config and nil other", - config: NewContractDeployerAllowListConfig(big.NewInt(3), admins, enableds), + config: NewConfig(big.NewInt(3), admins, enableds), other: nil, expected: false, }, { name: "different type", - config: NewContractDeployerAllowListConfig(big.NewInt(3), admins, enableds), + config: NewConfig(big.NewInt(3), admins, enableds), other: config.NewNoopStatefulPrecompileConfig(), expected: false, }, { name: "different admin", - config: NewContractDeployerAllowListConfig(big.NewInt(3), admins, enableds), - other: NewContractDeployerAllowListConfig(big.NewInt(3), []common.Address{{3}}, enableds), + config: NewConfig(big.NewInt(3), admins, enableds), + other: NewConfig(big.NewInt(3), []common.Address{{3}}, enableds), expected: false, }, { name: "different enabled", - config: NewContractDeployerAllowListConfig(big.NewInt(3), admins, enableds), - other: NewContractDeployerAllowListConfig(big.NewInt(3), admins, []common.Address{{3}}), + config: NewConfig(big.NewInt(3), admins, enableds), + other: NewConfig(big.NewInt(3), admins, []common.Address{{3}}), expected: false, }, { name: "different timestamp", - config: NewContractDeployerAllowListConfig(big.NewInt(3), admins, enableds), - other: NewContractDeployerAllowListConfig(big.NewInt(4), admins, enableds), + config: NewConfig(big.NewInt(3), admins, enableds), + other: NewConfig(big.NewInt(4), admins, enableds), expected: false, }, { name: "same config", - config: NewContractDeployerAllowListConfig(big.NewInt(3), admins, enableds), - other: NewContractDeployerAllowListConfig(big.NewInt(3), admins, enableds), + config: NewConfig(big.NewInt(3), admins, enableds), + other: NewConfig(big.NewInt(3), admins, enableds), expected: true, }, } diff --git a/precompile/contracts/deployerallowlist/module.go b/precompile/contracts/deployerallowlist/module.go index bd4e27b6af..3bdd2bb7ba 100644 --- a/precompile/contracts/deployerallowlist/module.go +++ b/precompile/contracts/deployerallowlist/module.go @@ -28,16 +28,18 @@ var Module = modules.Module{ type configuror struct{} func init() { - modules.RegisterModule(Module) + if err := modules.RegisterModule(Module); err != nil { + panic(err) + } } func (*configuror) NewConfig() config.Config { - return &ContractDeployerAllowListConfig{} + return &Config{} } // Configure configures [state] with the desired admins based on [cfg]. func (c *configuror) Configure(_ contract.ChainConfig, cfg config.Config, state contract.StateDB, _ contract.BlockContext) error { - config, ok := cfg.(*ContractDeployerAllowListConfig) + config, ok := cfg.(*Config) if !ok { return fmt.Errorf("incorrect config %T: %v", config, config) } diff --git a/precompile/contracts/feemanager/config.go b/precompile/contracts/feemanager/config.go index 5a06df6a88..6d9a890e6a 100644 --- a/precompile/contracts/feemanager/config.go +++ b/precompile/contracts/feemanager/config.go @@ -12,20 +12,20 @@ import ( "github.com/ethereum/go-ethereum/common" ) -var _ config.Config = &FeeManagerConfig{} +var _ config.Config = &Config{} -// FeeManagerConfig wraps [AllowListConfig] and uses it to implement the StatefulPrecompileConfig +// Config wraps [AllowListConfig] and uses it to implement the StatefulPrecompileConfig // interface while adding in the FeeManager specific precompile address. -type FeeManagerConfig struct { +type Config struct { allowlist.Config // Config for the fee config manager allow list config.Uprade InitialFeeConfig *commontype.FeeConfig `json:"initialFeeConfig,omitempty"` // initial fee config to be immediately activated } -// NewFeeManagerConfig returns a config for a network upgrade at [blockTimestamp] that enables +// NewConfig returns a config for a network upgrade at [blockTimestamp] that enables // FeeManager with the given [admins] and [enableds] as members of the allowlist with [initialConfig] as initial fee config if specified. -func NewFeeManagerConfig(blockTimestamp *big.Int, admins []common.Address, enableds []common.Address, initialConfig *commontype.FeeConfig) *FeeManagerConfig { - return &FeeManagerConfig{ +func NewConfig(blockTimestamp *big.Int, admins []common.Address, enableds []common.Address, initialConfig *commontype.FeeConfig) *Config { + return &Config{ Config: allowlist.Config{ AdminAddresses: admins, EnabledAddresses: enableds, @@ -35,10 +35,10 @@ func NewFeeManagerConfig(blockTimestamp *big.Int, admins []common.Address, enabl } } -// NewDisableFeeManagerConfig returns config for a network upgrade at [blockTimestamp] +// NewDisableConfig returns config for a network upgrade at [blockTimestamp] // that disables FeeManager. -func NewDisableFeeManagerConfig(blockTimestamp *big.Int) *FeeManagerConfig { - return &FeeManagerConfig{ +func NewDisableConfig(blockTimestamp *big.Int) *Config { + return &Config{ Uprade: config.Uprade{ BlockTimestamp: blockTimestamp, Disable: true, @@ -46,12 +46,12 @@ func NewDisableFeeManagerConfig(blockTimestamp *big.Int) *FeeManagerConfig { } } -func (FeeManagerConfig) Key() string { return ConfigKey } +func (Config) Key() string { return ConfigKey } // Equal returns true if [cfg] is a [*FeeManagerConfig] and it has been configured identical to [c]. -func (c *FeeManagerConfig) Equal(cfg config.Config) bool { +func (c *Config) Equal(cfg config.Config) bool { // typecast before comparison - other, ok := (cfg).(*FeeManagerConfig) + other, ok := (cfg).(*Config) if !ok { return false } @@ -67,7 +67,7 @@ func (c *FeeManagerConfig) Equal(cfg config.Config) bool { return c.InitialFeeConfig.Equal(other.InitialFeeConfig) } -func (c *FeeManagerConfig) Verify() error { +func (c *Config) Verify() error { if err := c.Config.Verify(); err != nil { return err } diff --git a/precompile/contracts/feemanager/config_test.go b/precompile/contracts/feemanager/config_test.go index eaafd50de6..861c713023 100644 --- a/precompile/contracts/feemanager/config_test.go +++ b/precompile/contracts/feemanager/config_test.go @@ -35,12 +35,12 @@ func TestVerifyFeeManagerConfig(t *testing.T) { }{ { name: "invalid allow list config in fee manager allowlist", - config: NewFeeManagerConfig(big.NewInt(3), admins, admins, nil), + config: NewConfig(big.NewInt(3), admins, admins, nil), expectedError: "cannot set address", }, { name: "invalid initial fee manager config", - config: NewFeeManagerConfig(big.NewInt(3), admins, nil, + config: NewConfig(big.NewInt(3), admins, nil, &commontype.FeeConfig{ GasLimit: big.NewInt(0), }), @@ -72,38 +72,38 @@ func TestEqualFeeManagerConfig(t *testing.T) { }{ { name: "non-nil config and nil other", - config: NewFeeManagerConfig(big.NewInt(3), admins, enableds, nil), + config: NewConfig(big.NewInt(3), admins, enableds, nil), other: nil, expected: false, }, { name: "different type", - config: NewFeeManagerConfig(big.NewInt(3), admins, enableds, nil), + config: NewConfig(big.NewInt(3), admins, enableds, nil), other: config.NewNoopStatefulPrecompileConfig(), expected: false, }, { name: "different timestamp", - config: NewFeeManagerConfig(big.NewInt(3), admins, nil, nil), - other: NewFeeManagerConfig(big.NewInt(4), admins, nil, nil), + config: NewConfig(big.NewInt(3), admins, nil, nil), + other: NewConfig(big.NewInt(4), admins, nil, nil), expected: false, }, { name: "different enabled", - config: NewFeeManagerConfig(big.NewInt(3), admins, nil, nil), - other: NewFeeManagerConfig(big.NewInt(3), admins, enableds, nil), + config: NewConfig(big.NewInt(3), admins, nil, nil), + other: NewConfig(big.NewInt(3), admins, enableds, nil), expected: false, }, { name: "non-nil initial config and nil initial config", - config: NewFeeManagerConfig(big.NewInt(3), admins, nil, &validFeeConfig), - other: NewFeeManagerConfig(big.NewInt(3), admins, nil, nil), + config: NewConfig(big.NewInt(3), admins, nil, &validFeeConfig), + other: NewConfig(big.NewInt(3), admins, nil, nil), expected: false, }, { name: "different initial config", - config: NewFeeManagerConfig(big.NewInt(3), admins, nil, &validFeeConfig), - other: NewFeeManagerConfig(big.NewInt(3), admins, nil, + config: NewConfig(big.NewInt(3), admins, nil, &validFeeConfig), + other: NewConfig(big.NewInt(3), admins, nil, func() *commontype.FeeConfig { c := validFeeConfig c.GasLimit = big.NewInt(123) @@ -113,8 +113,8 @@ func TestEqualFeeManagerConfig(t *testing.T) { }, { name: "same config", - config: NewFeeManagerConfig(big.NewInt(3), admins, nil, &validFeeConfig), - other: NewFeeManagerConfig(big.NewInt(3), admins, nil, &validFeeConfig), + config: NewConfig(big.NewInt(3), admins, nil, &validFeeConfig), + other: NewConfig(big.NewInt(3), admins, nil, &validFeeConfig), expected: true, }, } diff --git a/precompile/contracts/feemanager/contract_test.go b/precompile/contracts/feemanager/contract_test.go index d28e3cb8c8..698fce802d 100644 --- a/precompile/contracts/feemanager/contract_test.go +++ b/precompile/contracts/feemanager/contract_test.go @@ -96,7 +96,7 @@ func TestFeeManagerRun(t *testing.T) { suppliedGas: SetFeeConfigGasCost, readOnly: false, expectedRes: nil, - config: &FeeManagerConfig{ + config: &Config{ InitialFeeConfig: &testFeeConfig, }, expectedErr: "cannot be greater than maxBlockGasCost", @@ -152,7 +152,7 @@ func TestFeeManagerRun(t *testing.T) { return PackGetFeeConfigInput() }, suppliedGas: GetFeeConfigGasCost, - config: &FeeManagerConfig{ + config: &Config{ InitialFeeConfig: &testFeeConfig, }, readOnly: true, diff --git a/precompile/contracts/feemanager/module.go b/precompile/contracts/feemanager/module.go index 41b5f43793..d8f9fe60f5 100644 --- a/precompile/contracts/feemanager/module.go +++ b/precompile/contracts/feemanager/module.go @@ -28,16 +28,18 @@ var Module = modules.Module{ type configuror struct{} func init() { - modules.RegisterModule(Module) + if err := modules.RegisterModule(Module); err != nil { + panic(err) + } } func (*configuror) NewConfig() config.Config { - return &FeeManagerConfig{} + return &Config{} } // Configure configures [state] with the desired admins based on [configIface]. func (*configuror) Configure(chainConfig contract.ChainConfig, cfg config.Config, state contract.StateDB, blockContext contract.BlockContext) error { - config, ok := cfg.(*FeeManagerConfig) + config, ok := cfg.(*Config) if !ok { return fmt.Errorf("incorrect config %T: %v", config, config) } diff --git a/precompile/contracts/nativeminter/config.go b/precompile/contracts/nativeminter/config.go index 93625218fd..6c5b3fcf0e 100644 --- a/precompile/contracts/nativeminter/config.go +++ b/precompile/contracts/nativeminter/config.go @@ -14,20 +14,20 @@ import ( "github.com/ethereum/go-ethereum/common/math" ) -var _ config.Config = &ContractNativeMinterConfig{} +var _ config.Config = &Config{} -// ContractNativeMinterConfig wraps [AllowListConfig] and uses it to implement the StatefulPrecompileConfig +// Config wraps [AllowListConfig] and uses it to implement the StatefulPrecompileConfig // interface while adding in the ContractNativeMinter specific precompile address. -type ContractNativeMinterConfig struct { +type Config struct { allowlist.Config config.Uprade InitialMint map[common.Address]*math.HexOrDecimal256 `json:"initialMint,omitempty"` // initial mint config to be immediately minted } -// NewContractNativeMinterConfig returns a config for a network upgrade at [blockTimestamp] that enables +// NewConfig returns a config for a network upgrade at [blockTimestamp] that enables // ContractNativeMinter with the given [admins] and [enableds] as members of the allowlist. Also mints balances according to [initialMint] when the upgrade activates. -func NewContractNativeMinterConfig(blockTimestamp *big.Int, admins []common.Address, enableds []common.Address, initialMint map[common.Address]*math.HexOrDecimal256) *ContractNativeMinterConfig { - return &ContractNativeMinterConfig{ +func NewConfig(blockTimestamp *big.Int, admins []common.Address, enableds []common.Address, initialMint map[common.Address]*math.HexOrDecimal256) *Config { + return &Config{ Config: allowlist.Config{ AdminAddresses: admins, EnabledAddresses: enableds, @@ -37,22 +37,22 @@ func NewContractNativeMinterConfig(blockTimestamp *big.Int, admins []common.Addr } } -// NewDisableContractNativeMinterConfig returns config for a network upgrade at [blockTimestamp] +// NewDisableConfig returns config for a network upgrade at [blockTimestamp] // that disables ContractNativeMinter. -func NewDisableContractNativeMinterConfig(blockTimestamp *big.Int) *ContractNativeMinterConfig { - return &ContractNativeMinterConfig{ +func NewDisableConfig(blockTimestamp *big.Int) *Config { + return &Config{ Uprade: config.Uprade{ BlockTimestamp: blockTimestamp, Disable: true, }, } } -func (ContractNativeMinterConfig) Key() string { return ConfigKey } +func (Config) Key() string { return ConfigKey } // Equal returns true if [cfg] is a [*ContractNativeMinterConfig] and it has been configured identical to [c]. -func (c *ContractNativeMinterConfig) Equal(cfg config.Config) bool { +func (c *Config) Equal(cfg config.Config) bool { // typecast before comparison - other, ok := (cfg).(*ContractNativeMinterConfig) + other, ok := (cfg).(*Config) if !ok { return false } @@ -80,7 +80,7 @@ func (c *ContractNativeMinterConfig) Equal(cfg config.Config) bool { return true } -func (c *ContractNativeMinterConfig) Verify() error { +func (c *Config) Verify() error { if err := c.Config.Verify(); err != nil { return err } diff --git a/precompile/contracts/nativeminter/config_test.go b/precompile/contracts/nativeminter/config_test.go index e9058e30ce..d1232b9cc3 100644 --- a/precompile/contracts/nativeminter/config_test.go +++ b/precompile/contracts/nativeminter/config_test.go @@ -23,22 +23,22 @@ func TestVerifyContractNativeMinterConfig(t *testing.T) { }{ { name: "invalid allow list config in native minter allowlist", - config: NewContractNativeMinterConfig(big.NewInt(3), admins, admins, nil), + config: NewConfig(big.NewInt(3), admins, admins, nil), expectedError: "cannot set address", }, { name: "duplicate admins in config in native minter allowlist", - config: NewContractNativeMinterConfig(big.NewInt(3), append(admins, admins[0]), enableds, nil), + config: NewConfig(big.NewInt(3), append(admins, admins[0]), enableds, nil), expectedError: "duplicate address", }, { name: "duplicate enableds in config in native minter allowlist", - config: NewContractNativeMinterConfig(big.NewInt(3), admins, append(enableds, enableds[0]), nil), + config: NewConfig(big.NewInt(3), admins, append(enableds, enableds[0]), nil), expectedError: "duplicate address", }, { name: "nil amount in native minter config", - config: NewContractNativeMinterConfig(big.NewInt(3), admins, nil, + config: NewConfig(big.NewInt(3), admins, nil, map[common.Address]*math.HexOrDecimal256{ common.HexToAddress("0x01"): math.NewHexOrDecimal256(123), common.HexToAddress("0x02"): nil, @@ -47,7 +47,7 @@ func TestVerifyContractNativeMinterConfig(t *testing.T) { }, { name: "negative amount in native minter config", - config: NewContractNativeMinterConfig(big.NewInt(3), admins, nil, + config: NewConfig(big.NewInt(3), admins, nil, map[common.Address]*math.HexOrDecimal256{ common.HexToAddress("0x01"): math.NewHexOrDecimal256(123), common.HexToAddress("0x02"): math.NewHexOrDecimal256(-1), @@ -80,35 +80,35 @@ func TestEqualContractNativeMinterConfig(t *testing.T) { }{ { name: "non-nil config and nil other", - config: NewContractNativeMinterConfig(big.NewInt(3), admins, enableds, nil), + config: NewConfig(big.NewInt(3), admins, enableds, nil), other: nil, expected: false, }, { name: "different type", - config: NewContractNativeMinterConfig(big.NewInt(3), admins, enableds, nil), + config: NewConfig(big.NewInt(3), admins, enableds, nil), other: config.NewNoopStatefulPrecompileConfig(), expected: false, }, { name: "different timestamps", - config: NewContractNativeMinterConfig(big.NewInt(3), admins, nil, nil), - other: NewContractNativeMinterConfig(big.NewInt(4), admins, nil, nil), + config: NewConfig(big.NewInt(3), admins, nil, nil), + other: NewConfig(big.NewInt(4), admins, nil, nil), expected: false, }, { name: "different enabled", - config: NewContractNativeMinterConfig(big.NewInt(3), admins, nil, nil), - other: NewContractNativeMinterConfig(big.NewInt(3), admins, enableds, nil), + config: NewConfig(big.NewInt(3), admins, nil, nil), + other: NewConfig(big.NewInt(3), admins, enableds, nil), expected: false, }, { name: "different initial mint amounts", - config: NewContractNativeMinterConfig(big.NewInt(3), admins, nil, + config: NewConfig(big.NewInt(3), admins, nil, map[common.Address]*math.HexOrDecimal256{ common.HexToAddress("0x01"): math.NewHexOrDecimal256(1), }), - other: NewContractNativeMinterConfig(big.NewInt(3), admins, nil, + other: NewConfig(big.NewInt(3), admins, nil, map[common.Address]*math.HexOrDecimal256{ common.HexToAddress("0x01"): math.NewHexOrDecimal256(2), }), @@ -116,11 +116,11 @@ func TestEqualContractNativeMinterConfig(t *testing.T) { }, { name: "different initial mint addresses", - config: NewContractNativeMinterConfig(big.NewInt(3), admins, nil, + config: NewConfig(big.NewInt(3), admins, nil, map[common.Address]*math.HexOrDecimal256{ common.HexToAddress("0x01"): math.NewHexOrDecimal256(1), }), - other: NewContractNativeMinterConfig(big.NewInt(3), admins, nil, + other: NewConfig(big.NewInt(3), admins, nil, map[common.Address]*math.HexOrDecimal256{ common.HexToAddress("0x02"): math.NewHexOrDecimal256(1), }), @@ -128,11 +128,11 @@ func TestEqualContractNativeMinterConfig(t *testing.T) { }, { name: "same config", - config: NewContractNativeMinterConfig(big.NewInt(3), admins, nil, + config: NewConfig(big.NewInt(3), admins, nil, map[common.Address]*math.HexOrDecimal256{ common.HexToAddress("0x01"): math.NewHexOrDecimal256(1), }), - other: NewContractNativeMinterConfig(big.NewInt(3), admins, nil, + other: NewConfig(big.NewInt(3), admins, nil, map[common.Address]*math.HexOrDecimal256{ common.HexToAddress("0x01"): math.NewHexOrDecimal256(1), }), diff --git a/precompile/contracts/nativeminter/contract_test.go b/precompile/contracts/nativeminter/contract_test.go index f1cdfeb881..4eb3202495 100644 --- a/precompile/contracts/nativeminter/contract_test.go +++ b/precompile/contracts/nativeminter/contract_test.go @@ -69,7 +69,7 @@ func TestContractNativeMinterRun(t *testing.T) { }, "initial mint funds": { caller: enabledAddr, - config: &ContractNativeMinterConfig{ + config: &Config{ InitialMint: map[common.Address]*math.HexOrDecimal256{ enabledAddr: math.NewHexOrDecimal256(2), }, diff --git a/precompile/contracts/nativeminter/module.go b/precompile/contracts/nativeminter/module.go index 3b86e4f95d..0f4ac2e411 100644 --- a/precompile/contracts/nativeminter/module.go +++ b/precompile/contracts/nativeminter/module.go @@ -29,16 +29,18 @@ var Module = modules.Module{ type configuror struct{} func init() { - modules.RegisterModule(Module) + if err := modules.RegisterModule(Module); err != nil { + panic(err) + } } func (*configuror) NewConfig() config.Config { - return &ContractNativeMinterConfig{} + return &Config{} } // Configure configures [state] with the desired admins based on [cfg]. func (*configuror) Configure(_ contract.ChainConfig, cfg config.Config, state contract.StateDB, _ contract.BlockContext) error { - config, ok := cfg.(*ContractNativeMinterConfig) + config, ok := cfg.(*Config) if !ok { return fmt.Errorf("incorrect config %T: %v", config, config) } diff --git a/precompile/contracts/rewardmanager/config.go b/precompile/contracts/rewardmanager/config.go index 4f3e3aa4d2..32a27bc7ec 100644 --- a/precompile/contracts/rewardmanager/config.go +++ b/precompile/contracts/rewardmanager/config.go @@ -15,7 +15,7 @@ import ( "github.com/ethereum/go-ethereum/common" ) -var _ config.Config = &RewardManagerConfig{} +var _ config.Config = &Config{} type InitialRewardConfig struct { AllowFeeRecipients bool `json:"allowFeeRecipients"` @@ -54,18 +54,18 @@ func (i *InitialRewardConfig) Configure(state contract.StateDB) error { return nil } -// RewardManagerConfig implements the StatefulPrecompileConfig +// Config implements the StatefulPrecompileConfig // interface while adding in the RewardManager specific precompile config. -type RewardManagerConfig struct { +type Config struct { allowlist.Config config.Uprade InitialRewardConfig *InitialRewardConfig `json:"initialRewardConfig,omitempty"` } -// NewRewardManagerConfig returns a config for a network upgrade at [blockTimestamp] that enables +// NewConfig returns a config for a network upgrade at [blockTimestamp] that enables // RewardManager with the given [admins] and [enableds] as members of the allowlist with [initialConfig] as initial rewards config if specified. -func NewRewardManagerConfig(blockTimestamp *big.Int, admins []common.Address, enableds []common.Address, initialConfig *InitialRewardConfig) *RewardManagerConfig { - return &RewardManagerConfig{ +func NewConfig(blockTimestamp *big.Int, admins []common.Address, enableds []common.Address, initialConfig *InitialRewardConfig) *Config { + return &Config{ Config: allowlist.Config{ AdminAddresses: admins, EnabledAddresses: enableds, @@ -75,10 +75,10 @@ func NewRewardManagerConfig(blockTimestamp *big.Int, admins []common.Address, en } } -// NewDisableRewardManagerConfig returns config for a network upgrade at [blockTimestamp] +// NewDisableConfig returns config for a network upgrade at [blockTimestamp] // that disables RewardManager. -func NewDisableRewardManagerConfig(blockTimestamp *big.Int) *RewardManagerConfig { - return &RewardManagerConfig{ +func NewDisableConfig(blockTimestamp *big.Int) *Config { + return &Config{ Uprade: config.Uprade{ BlockTimestamp: blockTimestamp, Disable: true, @@ -86,9 +86,9 @@ func NewDisableRewardManagerConfig(blockTimestamp *big.Int) *RewardManagerConfig } } -func (RewardManagerConfig) Key() string { return ConfigKey } +func (Config) Key() string { return ConfigKey } -func (c *RewardManagerConfig) Verify() error { +func (c *Config) Verify() error { if err := c.Config.Verify(); err != nil { return err } @@ -99,9 +99,9 @@ func (c *RewardManagerConfig) Verify() error { } // Equal returns true if [cfg] is a [*RewardManagerConfig] and it has been configured identical to [c]. -func (c *RewardManagerConfig) Equal(cfg config.Config) bool { +func (c *Config) Equal(cfg config.Config) bool { // typecast before comparison - other, ok := (cfg).(*RewardManagerConfig) + other, ok := (cfg).(*Config) if !ok { return false } diff --git a/precompile/contracts/rewardmanager/config_test.go b/precompile/contracts/rewardmanager/config_test.go index f22ba9b4df..669ec1cb64 100644 --- a/precompile/contracts/rewardmanager/config_test.go +++ b/precompile/contracts/rewardmanager/config_test.go @@ -22,12 +22,12 @@ func TestVerifyRewardManagerConfig(t *testing.T) { }{ { name: "duplicate enableds in config in reward manager allowlist", - config: NewRewardManagerConfig(big.NewInt(3), admins, append(enableds, enableds[0]), nil), + config: NewConfig(big.NewInt(3), admins, append(enableds, enableds[0]), nil), expectedError: "duplicate address", }, { name: "both reward mechanisms should not be activated at the same time in reward manager", - config: NewRewardManagerConfig(big.NewInt(3), admins, enableds, &InitialRewardConfig{ + config: NewConfig(big.NewInt(3), admins, enableds, &InitialRewardConfig{ AllowFeeRecipients: true, RewardAddress: common.HexToAddress("0x01"), }), @@ -59,42 +59,42 @@ func TestEqualRewardManagerConfig(t *testing.T) { }{ { name: "non-nil config and nil other", - config: NewRewardManagerConfig(big.NewInt(3), admins, enableds, nil), + config: NewConfig(big.NewInt(3), admins, enableds, nil), other: nil, expected: false, }, { name: "different type", - config: NewRewardManagerConfig(big.NewInt(3), admins, enableds, nil), + config: NewConfig(big.NewInt(3), admins, enableds, nil), other: config.NewNoopStatefulPrecompileConfig(), expected: false, }, { name: "different timestamp", - config: NewRewardManagerConfig(big.NewInt(3), admins, nil, nil), - other: NewRewardManagerConfig(big.NewInt(4), admins, nil, nil), + config: NewConfig(big.NewInt(3), admins, nil, nil), + other: NewConfig(big.NewInt(4), admins, nil, nil), expected: false, }, { name: "different enabled", - config: NewRewardManagerConfig(big.NewInt(3), admins, nil, nil), - other: NewRewardManagerConfig(big.NewInt(3), admins, enableds, nil), + config: NewConfig(big.NewInt(3), admins, nil, nil), + other: NewConfig(big.NewInt(3), admins, enableds, nil), expected: false, }, { name: "non-nil initial config and nil initial config", - config: NewRewardManagerConfig(big.NewInt(3), admins, nil, &InitialRewardConfig{ + config: NewConfig(big.NewInt(3), admins, nil, &InitialRewardConfig{ AllowFeeRecipients: true, }), - other: NewRewardManagerConfig(big.NewInt(3), admins, nil, nil), + other: NewConfig(big.NewInt(3), admins, nil, nil), expected: false, }, { name: "different initial config", - config: NewRewardManagerConfig(big.NewInt(3), admins, nil, &InitialRewardConfig{ + config: NewConfig(big.NewInt(3), admins, nil, &InitialRewardConfig{ RewardAddress: common.HexToAddress("0x01"), }), - other: NewRewardManagerConfig(big.NewInt(3), admins, nil, + other: NewConfig(big.NewInt(3), admins, nil, &InitialRewardConfig{ RewardAddress: common.HexToAddress("0x02"), }), @@ -102,10 +102,10 @@ func TestEqualRewardManagerConfig(t *testing.T) { }, { name: "same config", - config: NewRewardManagerConfig(big.NewInt(3), admins, nil, &InitialRewardConfig{ + config: NewConfig(big.NewInt(3), admins, nil, &InitialRewardConfig{ RewardAddress: common.HexToAddress("0x01"), }), - other: NewRewardManagerConfig(big.NewInt(3), admins, nil, &InitialRewardConfig{ + other: NewConfig(big.NewInt(3), admins, nil, &InitialRewardConfig{ RewardAddress: common.HexToAddress("0x01"), }), expected: true, diff --git a/precompile/contracts/rewardmanager/contract_test.go b/precompile/contracts/rewardmanager/contract_test.go index b511bbd79f..e2db6b5d5e 100644 --- a/precompile/contracts/rewardmanager/contract_test.go +++ b/precompile/contracts/rewardmanager/contract_test.go @@ -174,7 +174,7 @@ func TestRewardManagerRun(t *testing.T) { return input }, suppliedGas: CurrentRewardAddressGasCost, - config: &RewardManagerConfig{ + config: &Config{ InitialRewardConfig: &InitialRewardConfig{ RewardAddress: testAddr, }, @@ -194,7 +194,7 @@ func TestRewardManagerRun(t *testing.T) { return input }, suppliedGas: AreFeeRecipientsAllowedGasCost, - config: &RewardManagerConfig{ + config: &Config{ InitialRewardConfig: &InitialRewardConfig{ AllowFeeRecipients: true, }, diff --git a/precompile/contracts/rewardmanager/module.go b/precompile/contracts/rewardmanager/module.go index b3efe3cbf0..3566b37f11 100644 --- a/precompile/contracts/rewardmanager/module.go +++ b/precompile/contracts/rewardmanager/module.go @@ -28,16 +28,18 @@ var Module = modules.Module{ type configuror struct{} func init() { - modules.RegisterModule(Module) + if err := modules.RegisterModule(Module); err != nil { + panic(err) + } } func (*configuror) NewConfig() config.Config { - return &RewardManagerConfig{} + return &Config{} } // Configure configures [state] with the desired admins based on [cfg]. func (*configuror) Configure(chainConfig contract.ChainConfig, cfg config.Config, state contract.StateDB, _ contract.BlockContext) error { - config, ok := cfg.(*RewardManagerConfig) + config, ok := cfg.(*Config) if !ok { return fmt.Errorf("incorrect config %T: %v", config, config) } diff --git a/precompile/contracts/txallowlist/config.go b/precompile/contracts/txallowlist/config.go index 778f2ee03e..36d4c5b214 100644 --- a/precompile/contracts/txallowlist/config.go +++ b/precompile/contracts/txallowlist/config.go @@ -11,19 +11,19 @@ import ( "github.com/ethereum/go-ethereum/common" ) -var _ config.Config = &TxAllowListConfig{} +var _ config.Config = &Config{} -// TxAllowListConfig wraps [AllowListConfig] and uses it to implement the StatefulPrecompileConfig +// Config wraps [AllowListConfig] and uses it to implement the StatefulPrecompileConfig // interface while adding in the TxAllowList specific precompile address. -type TxAllowListConfig struct { +type Config struct { allowlist.Config config.Uprade } -// NewTxAllowListConfig returns a config for a network upgrade at [blockTimestamp] that enables +// NewConfig returns a config for a network upgrade at [blockTimestamp] that enables // TxAllowList with the given [admins] and [enableds] as members of the allowlist. -func NewTxAllowListConfig(blockTimestamp *big.Int, admins []common.Address, enableds []common.Address) *TxAllowListConfig { - return &TxAllowListConfig{ +func NewConfig(blockTimestamp *big.Int, admins []common.Address, enableds []common.Address) *Config { + return &Config{ Config: allowlist.Config{ AdminAddresses: admins, EnabledAddresses: enableds, @@ -32,10 +32,10 @@ func NewTxAllowListConfig(blockTimestamp *big.Int, admins []common.Address, enab } } -// NewDisableTxAllowListConfig returns config for a network upgrade at [blockTimestamp] +// NewDisableConfig returns config for a network upgrade at [blockTimestamp] // that disables TxAllowList. -func NewDisableTxAllowListConfig(blockTimestamp *big.Int) *TxAllowListConfig { - return &TxAllowListConfig{ +func NewDisableConfig(blockTimestamp *big.Int) *Config { + return &Config{ Uprade: config.Uprade{ BlockTimestamp: blockTimestamp, Disable: true, @@ -43,12 +43,12 @@ func NewDisableTxAllowListConfig(blockTimestamp *big.Int) *TxAllowListConfig { } } -func (c *TxAllowListConfig) Key() string { return ConfigKey } +func (c *Config) Key() string { return ConfigKey } // Equal returns true if [cfg] is a [*TxAllowListConfig] and it has been configured identical to [c]. -func (c *TxAllowListConfig) Equal(cfg config.Config) bool { +func (c *Config) Equal(cfg config.Config) bool { // typecast before comparison - other, ok := (cfg).(*TxAllowListConfig) + other, ok := (cfg).(*Config) if !ok { return false } diff --git a/precompile/contracts/txallowlist/config_test.go b/precompile/contracts/txallowlist/config_test.go index add29ec037..51817d8959 100644 --- a/precompile/contracts/txallowlist/config_test.go +++ b/precompile/contracts/txallowlist/config_test.go @@ -22,22 +22,22 @@ func TestVerifyTxAllowlistConfig(t *testing.T) { }{ { name: "invalid allow list config in tx allowlist", - config: NewTxAllowListConfig(big.NewInt(3), admins, admins), + config: NewConfig(big.NewInt(3), admins, admins), expectedError: "cannot set address", }, { name: "nil member allow list config in tx allowlist", - config: NewTxAllowListConfig(big.NewInt(3), nil, nil), + config: NewConfig(big.NewInt(3), nil, nil), expectedError: "", }, { name: "empty member allow list config in tx allowlist", - config: NewTxAllowListConfig(big.NewInt(3), []common.Address{}, []common.Address{}), + config: NewConfig(big.NewInt(3), []common.Address{}, []common.Address{}), expectedError: "", }, { name: "valid allow list config in tx allowlist", - config: NewTxAllowListConfig(big.NewInt(3), admins, enableds), + config: NewConfig(big.NewInt(3), admins, enableds), expectedError: "", }, } @@ -66,32 +66,32 @@ func TestEqualTxAllowListConfig(t *testing.T) { }{ { name: "non-nil config and nil other", - config: NewTxAllowListConfig(big.NewInt(3), admins, enableds), + config: NewConfig(big.NewInt(3), admins, enableds), other: nil, expected: false, }, { name: "different admin", - config: NewTxAllowListConfig(big.NewInt(3), admins, enableds), - other: NewTxAllowListConfig(big.NewInt(3), []common.Address{{3}}, enableds), + config: NewConfig(big.NewInt(3), admins, enableds), + other: NewConfig(big.NewInt(3), []common.Address{{3}}, enableds), expected: false, }, { name: "different enabled", - config: NewTxAllowListConfig(big.NewInt(3), admins, enableds), - other: NewTxAllowListConfig(big.NewInt(3), admins, []common.Address{{3}}), + config: NewConfig(big.NewInt(3), admins, enableds), + other: NewConfig(big.NewInt(3), admins, []common.Address{{3}}), expected: false, }, { name: "different timestamp", - config: NewTxAllowListConfig(big.NewInt(3), admins, enableds), - other: NewTxAllowListConfig(big.NewInt(4), admins, enableds), + config: NewConfig(big.NewInt(3), admins, enableds), + other: NewConfig(big.NewInt(4), admins, enableds), expected: false, }, { name: "same config", - config: NewTxAllowListConfig(big.NewInt(3), admins, enableds), - other: NewTxAllowListConfig(big.NewInt(3), admins, enableds), + config: NewConfig(big.NewInt(3), admins, enableds), + other: NewConfig(big.NewInt(3), admins, enableds), expected: true, }, } diff --git a/precompile/contracts/txallowlist/module.go b/precompile/contracts/txallowlist/module.go index 0c73040bd9..7db6a7f6d8 100644 --- a/precompile/contracts/txallowlist/module.go +++ b/precompile/contracts/txallowlist/module.go @@ -28,16 +28,18 @@ var Module = modules.Module{ type configuror struct{} func init() { - modules.RegisterModule(Module) + if err := modules.RegisterModule(Module); err != nil { + panic(err) + } } func (*configuror) NewConfig() config.Config { - return &TxAllowListConfig{} + return &Config{} } // Configure configures [state] with the desired admins based on [cfg]. func (*configuror) Configure(chainConfig contract.ChainConfig, cfg config.Config, state contract.StateDB, _ contract.BlockContext) error { - config, ok := cfg.(*TxAllowListConfig) + config, ok := cfg.(*Config) if !ok { return fmt.Errorf("incorrect config %T: %v", config, config) } diff --git a/precompile/registry/registry.go b/precompile/registry/registry.go index 16d93a4531..16d2a8d1fb 100644 --- a/precompile/registry/registry.go +++ b/precompile/registry/registry.go @@ -16,3 +16,23 @@ import ( // ADD YOUR PRECOMPILE HERE // _ "github.com/ava-labs/subnet-evm/precompile/contracts/yourprecompile" ) + +// This list is kept just for reference. The actual addresses defined in respective packages of precompiles. +// Note: it is important that none of these addresses conflict with each other or any other precompiles +// in core/vm/contracts.go. +// The first stateful precompiles were added in coreth to support nativeAssetCall and nativeAssetBalance. New stateful precompiles +// originating in coreth will continue at this prefix, so we reserve this range in subnet-evm so that they can be migrated into +// subnet-evm without issue. +// These start at the address: 0x0100000000000000000000000000000000000000 and will increment by 1. +// Optional precompiles implemented in subnet-evm start at 0x0200000000000000000000000000000000000000 and will increment by 1 +// from here to reduce the risk of conflicts. +// For forks of subnet-evm, users should start at 0x0300000000000000000000000000000000000000 to ensure +// that their own modifications do not conflict with stateful precompiles that may be added to subnet-evm +// in the future. +// ContractDeployerAllowListAddress = common.HexToAddress("0x0200000000000000000000000000000000000000") +// ContractNativeMinterAddress = common.HexToAddress("0x0200000000000000000000000000000000000001") +// TxAllowListAddress = common.HexToAddress("0x0200000000000000000000000000000000000002") +// FeeManagerAddress = common.HexToAddress("0x0200000000000000000000000000000000000003") +// RewardManagerAddress = common.HexToAddress("0x0200000000000000000000000000000000000004") +// ADD YOUR PRECOMPILE HERE +// {YourPrecompile}Address = common.HexToAddress("0x03000000000000000000000000000000000000??")