diff --git a/params/config.go b/params/config.go index a00e885c49..2503e41ffc 100644 --- a/params/config.go +++ b/params/config.go @@ -166,7 +166,7 @@ type UpgradeConfig struct { // Config for optional timestamps that enable network upgrades. // Note: if OptionalUpgrades is specified in the JSON all previously activated // forks must be present or upgradeBytes will be rejected. - OptionalNetworkUpgrades *OptionalNetworkUpgrades `json:"networkUpgrades,omitempty"` + OptionalNetworkUpgrades *OptionalNetworkUpgrades // Config for modifying state as a network upgrade. StateUpgrades []StateUpgrade `json:"stateUpgrades,omitempty"` @@ -444,17 +444,17 @@ func (c *ChainConfig) Verify() error { return nil } -type Fork struct { - name string `serialize:"true"` - block *big.Int `serialize:"true"` // some go-ethereum forks use block numbers - timestamp *uint64 `serialize:"true"` // Avalanche forks use timestamps - optional bool `serialize:"true"` // if true, the fork may be nil and next fork is still allowed +type fork struct { + name string + block *big.Int // some go-ethereum forks use block numbers + timestamp *uint64 // Avalanche forks use timestamps + optional bool // if true, the fork may be nil and next fork is still allowed } // CheckConfigForkOrder checks that we don't "skip" any forks, geth isn't pluggable enough // to guarantee that forks can be implemented in a different order than on official networks func (c *ChainConfig) CheckConfigForkOrder() error { - ethForks := []Fork{ + ethForks := []fork{ {name: "homesteadBlock", block: c.HomesteadBlock}, {name: "eip150Block", block: c.EIP150Block}, {name: "eip155Block", block: c.EIP155Block}, @@ -493,8 +493,8 @@ func (c *ChainConfig) CheckConfigForkOrder() error { // checkForks checks that forks are enabled in order and returns an error if not // [blockFork] is true if the fork is a block number fork, false if it is a timestamp fork -func checkForks(forks []Fork, blockFork bool) error { - lastFork := Fork{} +func checkForks(forks []fork, blockFork bool) error { + lastFork := fork{} for _, cur := range forks { if blockFork && cur.block != nil && common.Big0.Cmp(cur.block) != 0 { return errNonGenesisForkByHeight diff --git a/params/network_upgrades.go b/params/network_upgrades.go index 916762d8d9..9cec00ba33 100644 --- a/params/network_upgrades.go +++ b/params/network_upgrades.go @@ -4,6 +4,8 @@ package params import ( + "math/big" + "github.com/ava-labs/subnet-evm/utils" ) @@ -50,21 +52,44 @@ func (m *MandatoryNetworkUpgrades) CheckMandatoryCompatible(newcfg *MandatoryNet return nil } -func (m *MandatoryNetworkUpgrades) mandatoryForkOrder() []Fork { - return []Fork{ +func (m *MandatoryNetworkUpgrades) mandatoryForkOrder() []fork { + return []fork{ {name: "subnetEVMTimestamp", timestamp: m.SubnetEVMTimestamp}, {name: "dUpgradeTimestamp", timestamp: m.DUpgradeTimestamp}, } } +type OptionalFork struct { + Name string `json:"name" serialize:"true"` + Block big.Int `json:"block" serialize:"true"` + Timestamp uint64 `json:"timestamp" serialize:"true"` +} + type OptionalNetworkUpgrades struct { - Updates []Fork `json:"serialize,omitempty" serialize:"true"` + OptionalNetworkUpgrades []OptionalFork `json:"networkUpgrades,omitempty" serialize:"true"` } func (n *OptionalNetworkUpgrades) CheckOptionalCompatible(newcfg *OptionalNetworkUpgrades, time uint64) *ConfigCompatError { return nil } -func (n *OptionalNetworkUpgrades) optionalForkOrder() []Fork { - return n.Updates +func (n *OptionalNetworkUpgrades) optionalForkOrder() []fork { + forks := make([]fork, len(n.OptionalNetworkUpgrades)) + for i, n := range n.OptionalNetworkUpgrades { + var block *big.Int + var timestamp *uint64 + if n.Block.BitLen() > 0 { + block = &n.Block + } + if n.Timestamp != 0 { + timestamp = &n.Timestamp + } + forks[i] = fork{ + name: n.Name, + block: block, + timestamp: timestamp, + optional: true, + } + } + return []fork{} } diff --git a/plugin/evm/message/handshake/upgrade_config.go b/plugin/evm/message/handshake/upgrade_config.go index 9ee72d9525..6599d4e054 100644 --- a/plugin/evm/message/handshake/upgrade_config.go +++ b/plugin/evm/message/handshake/upgrade_config.go @@ -15,7 +15,7 @@ type rawPrecompileUpgrade struct { } type networkUpgradeConfigMessage struct { - OptionalNetworkUpgrades []params.Fork `serialize:"true"` + OptionalNetworkUpgrades params.OptionalNetworkUpgrades `serialize:"true"` // Config for modifying state as a network upgrade. StateUpgrades []params.StateUpgrade `serialize:"true"` @@ -64,7 +64,7 @@ func ParseUpgradeConfigMessage(bytes []byte) (*params.UpgradeConfig, error) { } return ¶ms.UpgradeConfig{ - OptionalNetworkUpgrades: ¶ms.OptionalNetworkUpgrades{Updates: config.OptionalNetworkUpgrades}, + OptionalNetworkUpgrades: &config.OptionalNetworkUpgrades, StateUpgrades: config.StateUpgrades, PrecompileUpgrades: PrecompileUpgrades, }, nil @@ -92,16 +92,17 @@ func UpgradeConfigToNetworkMessage(config *params.UpgradeConfig) (*UpgradeConfig }) } - optionalNetworkUpgrades := make([]params.Fork, 0) - if config.OptionalNetworkUpgrades != nil { - optionalNetworkUpgrades = config.OptionalNetworkUpgrades.Updates + optionalNetworkUpgrades := config.OptionalNetworkUpgrades + if optionalNetworkUpgrades == nil { + optionalNetworkUpgrades = ¶ms.OptionalNetworkUpgrades{} } wrappedConfig := networkUpgradeConfigMessage{ - OptionalNetworkUpgrades: optionalNetworkUpgrades, + OptionalNetworkUpgrades: *optionalNetworkUpgrades, StateUpgrades: config.StateUpgrades, PrecompileUpgrades: PrecompileUpgrades, } + bytes, err := Codec.Marshal(Version, wrappedConfig) if err != nil { return nil, err diff --git a/plugin/evm/message/handshake/upgrade_config_test.go b/plugin/evm/message/handshake/upgrade_config_test.go index 17bb449078..cc289a3880 100644 --- a/plugin/evm/message/handshake/upgrade_config_test.go +++ b/plugin/evm/message/handshake/upgrade_config_test.go @@ -35,6 +35,10 @@ func TestSerialize(t *testing.T) { config3, err := ParseUpgradeConfigMessage(message2.Bytes) require.NoError(t, err) + message3, err := UpgradeConfigToNetworkMessage(config3) + require.NoError(t, err) + require.Equal(t, config, config3) require.Equal(t, message.Hash, message2.Hash) + require.Equal(t, message2.Hash, message3.Hash) }