Skip to content
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions core/genesis_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -240,11 +240,11 @@ func TestPrecompileActivationAfterHeaderBlock(t *testing.T) {
db := rawdb.NewMemoryDatabase()

customg := Genesis{
Config: params.SubnetEVMDefaultChainConfig,
Config: params.TestChainConfig,
Alloc: GenesisAlloc{
{1}: {Balance: big.NewInt(1), Storage: map[common.Hash]common.Hash{{1}: {1}}},
},
GasLimit: params.SubnetEVMDefaultChainConfig.FeeConfig.GasLimit.Uint64(),
GasLimit: params.TestChainConfig.FeeConfig.GasLimit.Uint64(),
}
genesis := customg.MustCommit(db)
bc, _ := NewBlockChain(db, DefaultCacheConfig, customg.Config, dummy.NewFullFaker(), vm.Config{}, common.Hash{})
Expand Down
34 changes: 6 additions & 28 deletions params/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,8 @@ var (
)

var (
// SubnetEVMDefaultChainConfig is the default configuration
// SubnetEVMDefaultConfig is the default configuration
// without any network upgrades.
SubnetEVMDefaultChainConfig = &ChainConfig{
ChainID: SubnetEVMChainID,
FeeConfig: DefaultFeeConfig,
Expand All @@ -87,9 +88,6 @@ var (
IstanbulBlock: big.NewInt(0),
MuirGlacierBlock: big.NewInt(0),
GenesisPrecompiles: Precompiles{},
NetworkUpgrades: NetworkUpgrades{
SubnetEVMTimestamp: big.NewInt(0),
},
}

TestChainConfig = &ChainConfig{
Expand All @@ -107,7 +105,7 @@ var (
PetersburgBlock: big.NewInt(0),
IstanbulBlock: big.NewInt(0),
MuirGlacierBlock: big.NewInt(0),
NetworkUpgrades: NetworkUpgrades{big.NewInt(0)},
NetworkUpgrades: NetworkUpgrades{big.NewInt(0), big.NewInt(0)},
GenesisPrecompiles: Precompiles{},
UpgradeConfig: UpgradeConfig{},
}
Expand Down Expand Up @@ -137,11 +135,6 @@ var (
// - Timestamps that enable avalanche network upgrades,
// - Enabling or disabling precompiles as network upgrades.
type UpgradeConfig struct {
// Config for blocks/timestamps that enable network upgrades.
// Note: if NetworkUpgrades is specified in the JSON all previously activated
// forks must be present or upgradeBytes will be rejected.
NetworkUpgrades *NetworkUpgrades `json:"networkUpgrades,omitempty"`

// Config for modifying state as a network upgrade.
StateUpgrades []StateUpgrade `json:"stateUpgrades,omitempty"`

Expand Down Expand Up @@ -323,7 +316,7 @@ func (c *ChainConfig) IsIstanbul(num *big.Int) bool {

// IsSubnetEVM returns whether [blockTimestamp] is either equal to the SubnetEVM fork block timestamp or greater.
func (c *ChainConfig) IsSubnetEVM(blockTimestamp *big.Int) bool {
return utils.IsForked(c.getNetworkUpgrades().SubnetEVMTimestamp, blockTimestamp)
return utils.IsForked(c.SubnetEVMTimestamp, blockTimestamp)
}

func (r *Rules) PredicatesExist() bool {
Expand Down Expand Up @@ -498,14 +491,8 @@ func (c *ChainConfig) checkCompatible(newcfg *ChainConfig, lastHeight *big.Int,
}

// Check subnet-evm specific activations
newNetworkUpgrades := newcfg.getNetworkUpgrades()
if c.UpgradeConfig.NetworkUpgrades != nil && newcfg.UpgradeConfig.NetworkUpgrades == nil {
// Note: if the current NetworkUpgrades are set via UpgradeConfig, then a new config
// without NetworkUpgrades will be treated as having specified an empty set of network
// upgrades (ie., treated as the user intends to cancel scheduled forks)
newNetworkUpgrades = &NetworkUpgrades{}
}
if err := c.getNetworkUpgrades().CheckCompatible(newNetworkUpgrades, lastTimestamp); err != nil {
newNetworkUpgrades := newcfg.NetworkUpgrades
if err := c.NetworkUpgrades.CheckCompatible(newNetworkUpgrades, lastTimestamp); err != nil {
return err
}

Expand All @@ -523,15 +510,6 @@ func (c *ChainConfig) checkCompatible(newcfg *ChainConfig, lastHeight *big.Int,
return nil
}

// getNetworkUpgrades returns NetworkUpgrades from upgrade config if set there,
// otherwise it falls back to the genesis chain config.
func (c *ChainConfig) getNetworkUpgrades() *NetworkUpgrades {
if upgradeConfigOverride := c.UpgradeConfig.NetworkUpgrades; upgradeConfigOverride != nil {
return upgradeConfigOverride
}
return &c.NetworkUpgrades
}

// isForkIncompatible returns true if a fork scheduled at s1 cannot be rescheduled to
// block s2 because head is already past the fork.
func isForkIncompatible(s1, s2, head *big.Int) bool {
Expand Down
2 changes: 1 addition & 1 deletion params/config_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -245,7 +245,7 @@ func TestChainConfigMarshalWithUpgrades(t *testing.T) {
PetersburgBlock: big.NewInt(0),
IstanbulBlock: big.NewInt(0),
MuirGlacierBlock: big.NewInt(0),
NetworkUpgrades: NetworkUpgrades{big.NewInt(0)},
NetworkUpgrades: NetworkUpgrades{big.NewInt(0), big.NewInt(0)},
GenesisPrecompiles: Precompiles{},
},
UpgradeConfig: UpgradeConfig{
Expand Down
38 changes: 36 additions & 2 deletions params/network_upgrades.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,18 +5,52 @@ package params

import (
"math/big"

"github.com/ava-labs/avalanchego/utils/constants"
)

var (
LocalNetworkUpgrades = NetworkUpgrades{
SubnetEVMTimestamp: big.NewInt(0),
DUpgradeTimestamp: big.NewInt(0),
}

FujiNetworkUpgrades = NetworkUpgrades{
SubnetEVMTimestamp: big.NewInt(0),
// DUpgradeTimestamp: big.NewInt(0), // TODO: Uncomment and set this to the correct value
}

MainnetNetworkUpgrades = NetworkUpgrades{
SubnetEVMTimestamp: big.NewInt(0),
// DUpgradeTimestamp: big.NewInt(0), // TODO: Uncomment and set this to the correct value
}
)

// NetworkUpgrades contains timestamps that enable avalanche network upgrades.
type NetworkUpgrades struct {
SubnetEVMTimestamp *big.Int `json:"subnetEVMTimestamp,omitempty"` // A placeholder for the latest avalanche forks (nil = no fork, 0 = already activated)
SubnetEVMTimestamp *big.Int `json:"subnetEVMTimestamp,omitempty"` // initial subnet-evm upgrade (nil = no fork, 0 = already activated)
DUpgradeTimestamp *big.Int `json:"dUpgradeTimestamp,omitempty"` // A placeholder for the latest avalanche forks (nil = no fork, 0 = already activated)
}

func (n *NetworkUpgrades) CheckCompatible(newcfg *NetworkUpgrades, headTimestamp *big.Int) *ConfigCompatError {
func (n *NetworkUpgrades) CheckCompatible(newcfg NetworkUpgrades, headTimestamp *big.Int) *ConfigCompatError {
// Check subnet-evm specific activations
if isForkIncompatible(n.SubnetEVMTimestamp, newcfg.SubnetEVMTimestamp, headTimestamp) {
return newCompatError("SubnetEVM fork block timestamp", n.SubnetEVMTimestamp, newcfg.SubnetEVMTimestamp)
}
if isForkIncompatible(n.DUpgradeTimestamp, newcfg.DUpgradeTimestamp, headTimestamp) {
return newCompatError("DUpgrade fork block timestamp", n.DUpgradeTimestamp, newcfg.DUpgradeTimestamp)
}

return nil
}

func GetNetworkUpgrades(networkID uint32) NetworkUpgrades {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If we needed to add a network upgrade where the timestamp was set by each instance of Subnet-EVM as opposed to being hardcoded in Subnet-EVM for official Avalanche network-wide upgrades, how would we do that?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There are 2 different options:
1- Allow these timestamps to be overriden by genesis/external upgrades
2- Allow separate optional network upgrades.

There could be some problems allowing overrides for avalanche network-wide upgrades. Like AvalancheGo versions, a critical bug etc etc.

I can revert changes that removes specifiable network upgrades, and convert them to "Optional" network upgrades. In any case we should keep this mandatory network upgrade notion in the code, without expecting to be activated by genesis/upgrade files.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Added optional network upgrades

switch networkID {
case constants.FujiID:
return FujiNetworkUpgrades
case constants.MainnetID:
return MainnetNetworkUpgrades
default:
return LocalNetworkUpgrades
}
}
12 changes: 6 additions & 6 deletions params/precompile_config_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ import (

func TestVerifyWithChainConfig(t *testing.T) {
admins := []common.Address{{1}}
baseConfig := *SubnetEVMDefaultChainConfig
baseConfig := *TestChainConfig
config := &baseConfig
config.GenesisPrecompiles = Precompiles{
txallowlist.ConfigKey: txallowlist.NewConfig(big.NewInt(2), nil, nil),
Expand Down Expand Up @@ -65,7 +65,7 @@ func TestVerifyWithChainConfig(t *testing.T) {

func TestVerifyWithChainConfigAtNilTimestamp(t *testing.T) {
admins := []common.Address{{0}}
baseConfig := *SubnetEVMDefaultChainConfig
baseConfig := *TestChainConfig
config := &baseConfig
config.PrecompileUpgrades = []PrecompileUpgrade{
// this does NOT enable the precompile, so it should be upgradeable.
Expand Down Expand Up @@ -185,7 +185,7 @@ func TestVerifyPrecompileUpgrades(t *testing.T) {
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
require := require.New(t)
baseConfig := *SubnetEVMDefaultChainConfig
baseConfig := *TestChainConfig
config := &baseConfig
config.PrecompileUpgrades = tt.upgrades

Expand Down Expand Up @@ -229,7 +229,7 @@ func TestVerifyPrecompiles(t *testing.T) {
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
require := require.New(t)
baseConfig := *SubnetEVMDefaultChainConfig
baseConfig := *TestChainConfig
config := &baseConfig
config.GenesisPrecompiles = tt.precompiles

Expand All @@ -245,7 +245,7 @@ func TestVerifyPrecompiles(t *testing.T) {

func TestVerifyRequiresSortedTimestamps(t *testing.T) {
admins := []common.Address{{1}}
baseConfig := *SubnetEVMDefaultChainConfig
baseConfig := *TestChainConfig
config := &baseConfig
config.PrecompileUpgrades = []PrecompileUpgrade{
{
Expand All @@ -263,7 +263,7 @@ func TestVerifyRequiresSortedTimestamps(t *testing.T) {

func TestGetPrecompileConfig(t *testing.T) {
require := require.New(t)
baseConfig := *SubnetEVMDefaultChainConfig
baseConfig := *TestChainConfig
config := &baseConfig
config.GenesisPrecompiles = Precompiles{
deployerallowlist.ConfigKey: deployerallowlist.NewConfig(big.NewInt(10), nil, nil),
Expand Down
2 changes: 1 addition & 1 deletion params/stateupgrade_config_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ func TestVerifyStateUpgrades(t *testing.T) {
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
require := require.New(t)
baseConfig := *SubnetEVMDefaultChainConfig
baseConfig := *TestChainConfig
config := &baseConfig
config.StateUpgrades = tt.upgrades

Expand Down
3 changes: 0 additions & 3 deletions plugin/evm/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -195,9 +195,6 @@ type Config struct {
// identical state with the pre-upgrade ruleset.
SkipUpgradeCheck bool `json:"skip-upgrade-check"`

// SkipSubnetEVMUpgradeCheck disables checking that SubnetEVM Upgrade is enabled at genesis
SkipSubnetEVMUpgradeCheck bool `json:"skip-subnet-evm-upgrade-check"`

// AcceptedCacheSize is the depth to keep in the accepted headers cache and the
// accepted logs cache at the accepted tip.
//
Expand Down
16 changes: 8 additions & 8 deletions plugin/evm/vm.go
Original file line number Diff line number Diff line change
Expand Up @@ -290,6 +290,10 @@ func (vm *VM) Initialize(
g.Config = params.SubnetEVMDefaultChainConfig
}

// We enforce network upgrades here, regardless of the chain config
// provided in the genesis file.
g.Config.NetworkUpgrades = params.GetNetworkUpgrades(chainCtx.NetworkID)

// Load airdrop file if provided
if vm.config.AirdropFile != "" {
g.AirdropData, err = os.ReadFile(vm.config.AirdropFile)
Expand All @@ -310,6 +314,10 @@ func (vm *VM) Initialize(

vm.ethConfig = ethconfig.NewDefaultConfig()
vm.ethConfig.Genesis = g
// NetworkID of EVM is equal to the ChainID
// But this is different than Avalanche's NetworkID
// which represents the Avalanche network the EVM is running on
// like Fuji, Mainnet, Local, etc.
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

what's the reason for this comment?

the networkID is not necessarily the same as the chainID in the EVM, but some tooling incorrectly assumes it is and adds incorrect checks to verify this which caused us to follow this convention so that the tooling would work correctly 😅

Could we either remove this comment or clarify this point?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

changed it

vm.ethConfig.NetworkId = g.Config.ChainID.Uint64()

// Set minimum price for mining and default gas price oracle value to the min
Expand Down Expand Up @@ -376,14 +384,6 @@ func (vm *VM) Initialize(
vm.chainConfig = g.Config
vm.networkID = vm.ethConfig.NetworkId

// TODO: remove SkipSubnetEVMUpgradeCheck after next network upgrade
if !vm.config.SkipSubnetEVMUpgradeCheck {
// check that subnetEVM upgrade is enabled from genesis before upgradeBytes
if !vm.chainConfig.IsSubnetEVM(common.Big0) {
return errSubnetEVMUpgradeNotEnabled
}
}

// Apply upgradeBytes (if any) by unmarshalling them into [chainConfig.UpgradeConfig].
// Initializing the chain will verify upgradeBytes are compatible with existing values.
if len(upgradeBytes) > 0 {
Expand Down
12 changes: 0 additions & 12 deletions plugin/evm/vm_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -405,18 +405,6 @@ func TestSubnetEVMUpgradeRequiredAtGenesis(t *testing.T) {
configJSON: "",
expectedErr: errSubnetEVMUpgradeNotEnabled,
},
{
// we do not expect an err when skip-subnet-evm-upgrade-check is set to true
genesisJSON: genesisJSONPreSubnetEVM,
configJSON: "{\"skip-subnet-evm-upgrade-check\": true}",
expectedErr: nil,
},
{
// we do not expect an err when skip-subnet-evm-upgrade-check is set to true
genesisJSON: genesisJSONSubnetEVMLateEnablement,
configJSON: "{\"skip-subnet-evm-upgrade-check\": true}",
expectedErr: nil,
},
}

for _, test := range genesisTests {
Expand Down
Loading