From e404da0cf28aad4546c843ce9b186ee60a204150 Mon Sep 17 00:00:00 2001 From: Arran Schlosberg Date: Thu, 8 Aug 2024 11:10:07 +0100 Subject: [PATCH 1/3] refactor: allow `types` to be imported by `precompile/contract` --- precompile/contract/contract.go | 18 ++++++++++++++++++ precompile/modules/module.go | 6 +++--- .../interfaces.go | 12 +++++------- 3 files changed, 26 insertions(+), 10 deletions(-) rename precompile/{contract => precompileconfig}/interfaces.go (85%) diff --git a/precompile/contract/contract.go b/precompile/contract/contract.go index 0be76a8955..327b03a31c 100644 --- a/precompile/contract/contract.go +++ b/precompile/contract/contract.go @@ -6,9 +6,27 @@ package contract import ( "fmt" + "github.com/ava-labs/subnet-evm/core/types" + "github.com/ava-labs/subnet-evm/precompile/precompileconfig" "github.com/ethereum/go-ethereum/common" ) +// Guarantee that we don't have a circular dependency if importing types here. +var _ *types.Transaction = nil + +// Temporary type aliases for proof-of-concept only. This allows all other code +// to work as expected, requiring only the `modules` package to change to a +// direct dependency on `precompileconfig`. As seen above, this allows importing +// of `types`. +type ( + StatefulPrecompiledContract = precompileconfig.StatefulPrecompiledContract + StateDB = precompileconfig.StateDB + AccessibleState = precompileconfig.AccessibleState + ConfigurationBlockContext = precompileconfig.ConfigurationBlockContext + Configurator = precompileconfig.Configurator + BlockContext = precompileconfig.BlockContext +) + const ( SelectorLen = 4 ) diff --git a/precompile/modules/module.go b/precompile/modules/module.go index d0a047c94d..6fad6a76c6 100644 --- a/precompile/modules/module.go +++ b/precompile/modules/module.go @@ -6,7 +6,7 @@ package modules import ( "bytes" - "github.com/ava-labs/subnet-evm/precompile/contract" + "github.com/ava-labs/subnet-evm/precompile/precompileconfig" "github.com/ethereum/go-ethereum/common" ) @@ -17,9 +17,9 @@ type Module struct { 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 precompileconfig.StatefulPrecompiledContract // Configurator is used to configure the stateful precompile when the config is enabled. - contract.Configurator + precompileconfig.Configurator } type moduleArray []Module diff --git a/precompile/contract/interfaces.go b/precompile/precompileconfig/interfaces.go similarity index 85% rename from precompile/contract/interfaces.go rename to precompile/precompileconfig/interfaces.go index 5ac6baa486..9ce6d787c4 100644 --- a/precompile/contract/interfaces.go +++ b/precompile/precompileconfig/interfaces.go @@ -1,14 +1,12 @@ // (c) 2023, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. -// Defines the interface for the configuration and execution of a precompile contract -package contract +package precompileconfig import ( "math/big" "github.com/ava-labs/avalanchego/snow" - "github.com/ava-labs/subnet-evm/precompile/precompileconfig" "github.com/ethereum/go-ethereum/common" ) @@ -48,7 +46,7 @@ type AccessibleState interface { GetStateDB() StateDB GetBlockContext() BlockContext GetSnowContext() *snow.Context - GetChainConfig() precompileconfig.ChainConfig + GetChainConfig() ChainConfig } // ConfigurationBlockContext defines the interface required to configure a precompile. @@ -65,10 +63,10 @@ type BlockContext interface { } type Configurator interface { - MakeConfig() precompileconfig.Config + MakeConfig() Config Configure( - chainConfig precompileconfig.ChainConfig, - precompileconfig precompileconfig.Config, + chainConfig ChainConfig, + precompileconfig Config, state StateDB, blockContext ConfigurationBlockContext, ) error From af9842e619d5b5222ddb1390d19fb756dd5b5077 Mon Sep 17 00:00:00 2001 From: Arran Schlosberg Date: Thu, 8 Aug 2024 12:01:03 +0100 Subject: [PATCH 2/3] fix: move `params` tests into `package params_test` There are tests of specific precompile configs being unmarshalled, which reintroduces the circular dependency. The `_test` idiom overcomes this instead of an otherwise major refactor. --- params/config_test.go | 4 +++- params/precompile_config_test.go | 22 +++++++++++++--------- params/precompile_upgrade_test.go | 6 ++++-- params/state_upgrade_test.go | 4 +++- 4 files changed, 23 insertions(+), 13 deletions(-) diff --git a/params/config_test.go b/params/config_test.go index 707cf89f9d..b5998ebab8 100644 --- a/params/config_test.go +++ b/params/config_test.go @@ -24,7 +24,7 @@ // You should have received a copy of the GNU Lesser General Public License // along with the go-ethereum library. If not, see . -package params +package params_test import ( "encoding/json" @@ -40,6 +40,8 @@ import ( "github.com/ava-labs/subnet-evm/utils" "github.com/ethereum/go-ethereum/common" "github.com/stretchr/testify/require" + + . "github.com/ava-labs/subnet-evm/params" ) func TestCheckCompatible(t *testing.T) { diff --git a/params/precompile_config_test.go b/params/precompile_config_test.go index 4e2c287241..f66a40742c 100644 --- a/params/precompile_config_test.go +++ b/params/precompile_config_test.go @@ -1,7 +1,7 @@ // (c) 2022 Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. -package params +package params_test import ( "encoding/json" @@ -17,6 +17,8 @@ import ( "github.com/ava-labs/subnet-evm/utils" "github.com/ethereum/go-ethereum/common" "github.com/stretchr/testify/require" + + . "github.com/ava-labs/subnet-evm/params" ) func TestVerifyWithChainConfig(t *testing.T) { @@ -270,17 +272,19 @@ func TestGetPrecompileConfig(t *testing.T) { deployerallowlist.ConfigKey: deployerallowlist.NewConfig(utils.NewUint64(10), nil, nil, nil), } - deployerConfig := config.getActivePrecompileConfig(deployerallowlist.ContractAddress, 0) - require.Nil(deployerConfig) + configs := config.GetActivatingPrecompileConfigs(deployerallowlist.ContractAddress, nil, 0, config.PrecompileUpgrades) + require.Len(configs, 0) - deployerConfig = config.getActivePrecompileConfig(deployerallowlist.ContractAddress, 10) - require.NotNil(deployerConfig) + configs = config.GetActivatingPrecompileConfigs(deployerallowlist.ContractAddress, nil, 10, config.PrecompileUpgrades) + require.GreaterOrEqual(len(configs), 1) + require.NotNil(configs[len(configs)-1]) - deployerConfig = config.getActivePrecompileConfig(deployerallowlist.ContractAddress, 11) - require.NotNil(deployerConfig) + configs = config.GetActivatingPrecompileConfigs(deployerallowlist.ContractAddress, nil, 11, config.PrecompileUpgrades) + require.GreaterOrEqual(len(configs), 1) + require.NotNil(configs[len(configs)-1]) - txAllowListConfig := config.getActivePrecompileConfig(txallowlist.ContractAddress, 0) - require.Nil(txAllowListConfig) + txAllowListConfig := config.GetActivatingPrecompileConfigs(txallowlist.ContractAddress, nil, 0, config.PrecompileUpgrades) + require.Len(txAllowListConfig, 0) } func TestPrecompileUpgradeUnmarshalJSON(t *testing.T) { diff --git a/params/precompile_upgrade_test.go b/params/precompile_upgrade_test.go index 8384ef4279..5c21b08534 100644 --- a/params/precompile_upgrade_test.go +++ b/params/precompile_upgrade_test.go @@ -1,7 +1,7 @@ // (c) 2022, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. -package params +package params_test import ( "testing" @@ -11,6 +11,8 @@ import ( "github.com/ava-labs/subnet-evm/utils" "github.com/ethereum/go-ethereum/common" "github.com/stretchr/testify/require" + + . "github.com/ava-labs/subnet-evm/params" ) func TestVerifyUpgradeConfig(t *testing.T) { @@ -279,7 +281,7 @@ func (tt *upgradeCompatibilityTest) run(t *testing.T, chainConfig ChainConfig) { newCfg := chainConfig newCfg.UpgradeConfig = *upgrade - err := chainConfig.checkCompatible(&newCfg, nil, tt.startTimestamps[i]) + err := chainConfig.CheckCompatible(&newCfg, 0, tt.startTimestamps[i]) // if this is not the final upgradeBytes, continue applying // the next upgradeBytes. (only check the result on the last apply) diff --git a/params/state_upgrade_test.go b/params/state_upgrade_test.go index 6ee4094fc0..da4361d3cb 100644 --- a/params/state_upgrade_test.go +++ b/params/state_upgrade_test.go @@ -1,7 +1,7 @@ // (c) 2022, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. -package params +package params_test import ( "encoding/json" @@ -12,6 +12,8 @@ import ( "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/common/math" "github.com/stretchr/testify/require" + + . "github.com/ava-labs/subnet-evm/params" ) func TestVerifyStateUpgrades(t *testing.T) { From 12febd10524eac0bec79b2fa0e54694e9baf2514 Mon Sep 17 00:00:00 2001 From: Arran Schlosberg Date: Thu, 8 Aug 2024 12:14:19 +0100 Subject: [PATCH 3/3] refactor: introduce `precompile/interfaces` package --- precompile/contract/contract.go | 16 ++++++++-------- .../interfaces.go | 15 +++++++++------ precompile/modules/module.go | 6 +++--- 3 files changed, 20 insertions(+), 17 deletions(-) rename precompile/{precompileconfig => interfaces}/interfaces.go (83%) diff --git a/precompile/contract/contract.go b/precompile/contract/contract.go index 327b03a31c..bab3a943a0 100644 --- a/precompile/contract/contract.go +++ b/precompile/contract/contract.go @@ -7,7 +7,7 @@ import ( "fmt" "github.com/ava-labs/subnet-evm/core/types" - "github.com/ava-labs/subnet-evm/precompile/precompileconfig" + "github.com/ava-labs/subnet-evm/precompile/interfaces" "github.com/ethereum/go-ethereum/common" ) @@ -16,15 +16,15 @@ var _ *types.Transaction = nil // Temporary type aliases for proof-of-concept only. This allows all other code // to work as expected, requiring only the `modules` package to change to a -// direct dependency on `precompileconfig`. As seen above, this allows importing +// direct dependency on `interfaces`. As seen above, this allows importing // of `types`. type ( - StatefulPrecompiledContract = precompileconfig.StatefulPrecompiledContract - StateDB = precompileconfig.StateDB - AccessibleState = precompileconfig.AccessibleState - ConfigurationBlockContext = precompileconfig.ConfigurationBlockContext - Configurator = precompileconfig.Configurator - BlockContext = precompileconfig.BlockContext + StatefulPrecompiledContract = interfaces.StatefulPrecompiledContract + StateDB = interfaces.StateDB + AccessibleState = interfaces.AccessibleState + ConfigurationBlockContext = interfaces.ConfigurationBlockContext + Configurator = interfaces.Configurator + BlockContext = interfaces.BlockContext ) const ( diff --git a/precompile/precompileconfig/interfaces.go b/precompile/interfaces/interfaces.go similarity index 83% rename from precompile/precompileconfig/interfaces.go rename to precompile/interfaces/interfaces.go index 9ce6d787c4..54310aa006 100644 --- a/precompile/precompileconfig/interfaces.go +++ b/precompile/interfaces/interfaces.go @@ -1,12 +1,15 @@ -// (c) 2023, Ava Labs, Inc. All rights reserved. +// (c) 2023-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. -package precompileconfig +// Package interfaces defines the interfaces used in building and running +// stateful precompiles. +package interfaces import ( "math/big" "github.com/ava-labs/avalanchego/snow" + "github.com/ava-labs/subnet-evm/precompile/precompileconfig" "github.com/ethereum/go-ethereum/common" ) @@ -46,7 +49,7 @@ type AccessibleState interface { GetStateDB() StateDB GetBlockContext() BlockContext GetSnowContext() *snow.Context - GetChainConfig() ChainConfig + GetChainConfig() precompileconfig.ChainConfig } // ConfigurationBlockContext defines the interface required to configure a precompile. @@ -63,10 +66,10 @@ type BlockContext interface { } type Configurator interface { - MakeConfig() Config + MakeConfig() precompileconfig.Config Configure( - chainConfig ChainConfig, - precompileconfig Config, + chainConfig precompileconfig.ChainConfig, + precompileconfig precompileconfig.Config, state StateDB, blockContext ConfigurationBlockContext, ) error diff --git a/precompile/modules/module.go b/precompile/modules/module.go index 6fad6a76c6..445b61707f 100644 --- a/precompile/modules/module.go +++ b/precompile/modules/module.go @@ -6,7 +6,7 @@ package modules import ( "bytes" - "github.com/ava-labs/subnet-evm/precompile/precompileconfig" + "github.com/ava-labs/subnet-evm/precompile/interfaces" "github.com/ethereum/go-ethereum/common" ) @@ -17,9 +17,9 @@ type Module struct { Address common.Address // Contract returns a thread-safe singleton that can be used as the StatefulPrecompiledContract when // this config is enabled. - Contract precompileconfig.StatefulPrecompiledContract + Contract interfaces.StatefulPrecompiledContract // Configurator is used to configure the stateful precompile when the config is enabled. - precompileconfig.Configurator + interfaces.Configurator } type moduleArray []Module