Skip to content

Commit

Permalink
move network upgrade code to file (#1136)
Browse files Browse the repository at this point in the history
* move network upgrade code to file

* Update params/network_upgrades.go

Co-authored-by: Darioush Jalali <darioush.jalali@avalabs.org>
Signed-off-by: Ceyhun Onur <ceyhunonur54@gmail.com>

* rename setevmupgrades

---------

Signed-off-by: Ceyhun Onur <ceyhunonur54@gmail.com>
Co-authored-by: Darioush Jalali <darioush.jalali@avalabs.org>
  • Loading branch information
ceyonur and darioush authored Mar 29, 2024
1 parent 1f5b595 commit 8f9dbb6
Show file tree
Hide file tree
Showing 4 changed files with 118 additions and 90 deletions.
77 changes: 6 additions & 71 deletions params/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,6 @@ import (
"errors"
"fmt"
"math/big"
"time"

"github.com/ava-labs/avalanchego/utils/constants"
"github.com/ava-labs/subnet-evm/commontype"
Expand Down Expand Up @@ -105,12 +104,9 @@ var (
PetersburgBlock: big.NewInt(0),
IstanbulBlock: big.NewInt(0),
MuirGlacierBlock: big.NewInt(0),
NetworkUpgrades: NetworkUpgrades{
SubnetEVMTimestamp: utils.NewUint64(0),
DurangoTimestamp: utils.NewUint64(0),
},
GenesisPrecompiles: Precompiles{},
UpgradeConfig: UpgradeConfig{},
NetworkUpgrades: TestNetworkUpgrades,
GenesisPrecompiles: Precompiles{},
UpgradeConfig: UpgradeConfig{},
}

TestSubnetEVMConfig = &ChainConfig{
Expand Down Expand Up @@ -156,15 +152,6 @@ var (
TestRules = TestChainConfig.Rules(new(big.Int), 0)
)

func getUpgradeTime(networkID uint32, upgradeTimes map[uint32]time.Time) *uint64 {
if upgradeTime, ok := upgradeTimes[networkID]; ok {
return utils.TimeToNewUint64(upgradeTime)
}
// If the upgrade time isn't specified, default being enabled in the
// genesis.
return utils.NewUint64(0)
}

// ChainConfig is the core config which determines the blockchain settings.
//
// ChainConfig is stored in the database on a per block basis. This means
Expand Down Expand Up @@ -227,8 +214,7 @@ func (c *ChainConfig) Description() string {
banner += fmt.Sprintf(" - Cancun Timestamp: @%-10v (https://github.com/ava-labs/avalanchego/releases/tag/v1.12.0)\n", ptrToString(c.CancunTime))

banner += "Avalanche Upgrades (timestamp based):\n"
banner += fmt.Sprintf(" - SubnetEVM Timestamp: @%-10v (https://github.com/ava-labs/avalanchego/releases/tag/v1.10.0)\n", ptrToString(c.SubnetEVMTimestamp))
banner += fmt.Sprintf(" - Durango Timestamp: @%-10v (https://github.com/ava-labs/avalanchego/releases/tag/v1.11.0)\n", ptrToString(c.DurangoTimestamp))
banner += c.NetworkUpgrades.Description()
banner += "\n"

precompileUpgradeBytes, err := json.Marshal(c.GenesisPrecompiles)
Expand Down Expand Up @@ -257,42 +243,6 @@ func (c *ChainConfig) Description() string {
return banner
}

func (c *ChainConfig) SetNetworkUpgradeDefaults() {
if c.HomesteadBlock == nil {
c.HomesteadBlock = big.NewInt(0)
}
if c.EIP150Block == nil {
c.EIP150Block = big.NewInt(0)
}
if c.EIP155Block == nil {
c.EIP155Block = big.NewInt(0)
}
if c.EIP158Block == nil {
c.EIP158Block = big.NewInt(0)
}
if c.ByzantiumBlock == nil {
c.ByzantiumBlock = big.NewInt(0)
}
if c.ConstantinopleBlock == nil {
c.ConstantinopleBlock = big.NewInt(0)
}
if c.PetersburgBlock == nil {
c.PetersburgBlock = big.NewInt(0)
}
if c.IstanbulBlock == nil {
c.IstanbulBlock = big.NewInt(0)
}
if c.MuirGlacierBlock == nil {
c.MuirGlacierBlock = big.NewInt(0)
}

c.NetworkUpgrades.setDefaults(c.SnowCtx.NetworkID)

// if c.CancunTime == nil {
// c.CancunTime = c.EUpgrade
// }
}

// IsHomestead returns whether num is either equal to the homestead block or greater.
func (c *ChainConfig) IsHomestead(num *big.Int) bool {
return utils.IsBlockForked(c.HomesteadBlock, num)
Expand Down Expand Up @@ -340,19 +290,6 @@ func (c *ChainConfig) IsIstanbul(num *big.Int) bool {
return utils.IsBlockForked(c.IstanbulBlock, num)
}

// IsSubnetEVM returns whether [time] represents a block
// with a timestamp after the SubnetEVM upgrade time.
func (c *ChainConfig) IsSubnetEVM(time uint64) bool {
return utils.IsTimestampForked(c.SubnetEVMTimestamp, time)
}

// TODO: move avalanche hardforks to network_upgrades.go
// IsDurango returns whether [time] represents a block
// with a timestamp after the Durango upgrade time.
func (c *ChainConfig) IsDurango(time uint64) bool {
return utils.IsTimestampForked(c.DurangoTimestamp, time)
}

// IsCancun returns whether [time] represents a block
// with a timestamp after the Cancun upgrade time.
func (c *ChainConfig) IsCancun(num *big.Int, time uint64) bool {
Expand Down Expand Up @@ -676,8 +613,7 @@ type Rules struct {
IsCancun bool

// Rules for Avalanche releases
IsSubnetEVM bool
IsDurango bool
AvalancheRules

// ActivePrecompiles maps addresses to stateful precompiled contracts that are enabled
// for this rule set.
Expand Down Expand Up @@ -723,8 +659,7 @@ func (c *ChainConfig) rules(num *big.Int, timestamp uint64) Rules {
func (c *ChainConfig) Rules(blockNum *big.Int, timestamp uint64) Rules {
rules := c.rules(blockNum, timestamp)

rules.IsSubnetEVM = c.IsSubnetEVM(timestamp)
rules.IsDurango = c.IsDurango(timestamp)
rules.AvalancheRules = c.GetAvalancheRules(timestamp)

// Initialize the stateful precompiles that should be enabled at [blockTimestamp].
rules.ActivePrecompiles = make(map[common.Address]precompileconfig.Config)
Expand Down
48 changes: 48 additions & 0 deletions params/config_extra.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@ package params
import (
"encoding/json"
"errors"
"math/big"
"time"

"github.com/ava-labs/avalanchego/snow"
)
Expand Down Expand Up @@ -145,3 +147,49 @@ func (c *ChainConfig) ToWithUpgradesJSON() *ChainConfigWithUpgradesJSON {
UpgradeConfig: c.UpgradeConfig,
}
}

func (c *ChainConfig) SetNetworkUpgradeDefaults() {
if c.HomesteadBlock == nil {
c.HomesteadBlock = big.NewInt(0)
}
if c.EIP150Block == nil {
c.EIP150Block = big.NewInt(0)
}
if c.EIP155Block == nil {
c.EIP155Block = big.NewInt(0)
}
if c.EIP158Block == nil {
c.EIP158Block = big.NewInt(0)
}
if c.ByzantiumBlock == nil {
c.ByzantiumBlock = big.NewInt(0)
}
if c.ConstantinopleBlock == nil {
c.ConstantinopleBlock = big.NewInt(0)
}
if c.PetersburgBlock == nil {
c.PetersburgBlock = big.NewInt(0)
}
if c.IstanbulBlock == nil {
c.IstanbulBlock = big.NewInt(0)
}
if c.MuirGlacierBlock == nil {
c.MuirGlacierBlock = big.NewInt(0)
}

c.NetworkUpgrades.setDefaults(c.SnowCtx.NetworkID)
}

// SetMappedUpgrades sets the mapped upgrades (usually Avalanche > EVM upgrades) for the chain config.
func (c *ChainConfig) SetEVMUpgrades(avalancheUpgrades NetworkUpgrades) {
// c.CancunTime = utils.NewUint64(*avalancheUpgrades.EUpgradeTimestamp)
}

func getUpgradeTime(networkID uint32, upgradeTimes map[uint32]time.Time) uint64 {
if upgradeTime, ok := upgradeTimes[networkID]; ok {
return uint64(upgradeTime.Unix())
}
// If the upgrade time isn't specified, default being enabled in the
// genesis.
return 0
}
81 changes: 62 additions & 19 deletions params/network_upgrades.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,19 +6,27 @@ package params
import (
"fmt"
"reflect"
"strconv"

"github.com/ava-labs/avalanchego/version"
"github.com/ava-labs/subnet-evm/utils"
)

var (
errCannotBeNil = fmt.Errorf("timestamp cannot be nil")

TestNetworkUpgrades = NetworkUpgrades{
SubnetEVMTimestamp: utils.NewUint64(0),
DurangoTimestamp: utils.NewUint64(0),
}
)

// NetworkUpgrades contains timestamps that enable network upgrades.
// Avalanche specific network upgrades are also included here.
type NetworkUpgrades struct {
// SubnetEVMTimestamp is a placeholder that activates Avalanche Upgrades prior to ApricotPhase6 (nil = no fork, 0 = already activated)
// SubnetEVMTimestamp is a placeholder that activates Avalanche Upgrades prior to ApricotPhase6
SubnetEVMTimestamp *uint64 `json:"subnetEVMTimestamp,omitempty"`
// Durango activates the Shanghai Execution Spec Upgrade from Ethereum (https://github.com/ethereum/execution-specs/blob/master/network-upgrades/mainnet-upgrades/shanghai.md#included-eips)
// and Avalanche Warp Messaging. (nil = no fork, 0 = already activated)
// and Avalanche Warp Messaging.
// Note: EIP-4895 is excluded since withdrawals are not relevant to the Avalanche C-Chain or Subnets running the EVM.
DurangoTimestamp *uint64 `json:"durangoTimestamp,omitempty"`
}
Expand Down Expand Up @@ -48,22 +56,27 @@ func (n *NetworkUpgrades) forkOrder() []fork {
// This overrides deactivating the network upgrade by providing a timestamp of nil value.
func (n *NetworkUpgrades) setDefaults(networkID uint32) {
defaults := getDefaultNetworkUpgrades(networkID)
if n.SubnetEVMTimestamp == nil {
// If the network upgrade is not set, set it to the default value.
// If the network upgrade is set to 0, we also treat it as nil and set it default.
// This is because in prior versions, upgrades were not modifiable and were directly set to their default values.
// Most of the tools and configurations just provide these as 0, so it is safer to treat 0 as nil and set to default
// to prevent premature activations of the network upgrades for live networks.
if n.SubnetEVMTimestamp == nil || *n.SubnetEVMTimestamp == 0 {
n.SubnetEVMTimestamp = defaults.SubnetEVMTimestamp
}
if n.DurangoTimestamp == nil {
if n.DurangoTimestamp == nil || *n.DurangoTimestamp == 0 {
n.DurangoTimestamp = defaults.DurangoTimestamp
}
}

// VerifyNetworkUpgrades checks that the network upgrades are well formed.
func (n *NetworkUpgrades) VerifyNetworkUpgrades(networkID uint32) error {
defaults := getDefaultNetworkUpgrades(networkID)
if isNilOrSmaller(n.SubnetEVMTimestamp, *defaults.SubnetEVMTimestamp) {
return fmt.Errorf("SubnetEVM fork block timestamp (%v) must be greater than or equal to %v", nilOrValueStr(n.SubnetEVMTimestamp), *defaults.SubnetEVMTimestamp)
if err := verifyWithDefault(n.SubnetEVMTimestamp, defaults.SubnetEVMTimestamp); err != nil {
return fmt.Errorf("SubnetEVM fork block timestamp is invalid: %w", err)
}
if isNilOrSmaller(n.DurangoTimestamp, *defaults.DurangoTimestamp) {
return fmt.Errorf("Durango fork block timestamp (%v) must be greater than or equal to %v", nilOrValueStr(n.DurangoTimestamp), *defaults.DurangoTimestamp)
if err := verifyWithDefault(n.DurangoTimestamp, defaults.DurangoTimestamp); err != nil {
return fmt.Errorf("Durango fork block timestamp is invalid: %w", err)
}
return nil
}
Expand All @@ -77,25 +90,55 @@ func (n *NetworkUpgrades) Override(o *NetworkUpgrades) {
}
}

// IsSubnetEVM returns whether [time] represents a block
// with a timestamp after the SubnetEVM upgrade time.
func (n *NetworkUpgrades) IsSubnetEVM(time uint64) bool {
return utils.IsTimestampForked(n.SubnetEVMTimestamp, time)
}

// IsDurango returns whether [time] represents a block
// with a timestamp after the Durango upgrade time.
func (n *NetworkUpgrades) IsDurango(time uint64) bool {
return utils.IsTimestampForked(n.DurangoTimestamp, time)
}

func (n *NetworkUpgrades) Description() string {
var banner string
banner += fmt.Sprintf(" - SubnetEVM Timestamp: @%-10v (https://github.com/ava-labs/avalanchego/releases/tag/v1.10.0)\n", ptrToString(n.SubnetEVMTimestamp))
banner += fmt.Sprintf(" - Durango Timestamp: @%-10v (https://github.com/ava-labs/avalanchego/releases/tag/v1.11.0)\n", ptrToString(n.DurangoTimestamp))
return banner
}

type AvalancheRules struct {
IsSubnetEVM bool
IsDurango bool
IsEUpgrade bool
}

func (n *NetworkUpgrades) GetAvalancheRules(time uint64) AvalancheRules {
return AvalancheRules{
IsSubnetEVM: n.IsSubnetEVM(time),
IsDurango: n.IsDurango(time),
}
}

// getDefaultNetworkUpgrades returns the network upgrades for the specified network ID.
// These should not return nil values.
func getDefaultNetworkUpgrades(networkID uint32) NetworkUpgrades {
return NetworkUpgrades{
SubnetEVMTimestamp: utils.NewUint64(0),
DurangoTimestamp: getUpgradeTime(networkID, version.DurangoTimes),
DurangoTimestamp: utils.NewUint64(getUpgradeTime(networkID, version.DurangoTimes)),
}
}

func isNilOrSmaller(a *uint64, b uint64) bool {
if a == nil {
return true
// verifyWithDefault checks that the provided timestamp is greater than or equal to the default timestamp.
func verifyWithDefault(configTimestamp *uint64, defaultTimestamp *uint64) error {
if configTimestamp == nil {
return errCannotBeNil
}
return *a < b
}

func nilOrValueStr(a *uint64) string {
if a == nil {
return "nil"
if *configTimestamp < *defaultTimestamp {
return fmt.Errorf("provided timestamp (%d) must be greater than or equal to the default timestamp (%d)", *configTimestamp, defaultTimestamp)
}
return strconv.FormatUint(*a, 10)
return nil
}
2 changes: 2 additions & 0 deletions plugin/evm/vm.go
Original file line number Diff line number Diff line change
Expand Up @@ -369,6 +369,8 @@ func (vm *VM) Initialize(
g.Config.Override(overrides)
}

g.Config.SetEVMUpgrades(g.Config.NetworkUpgrades)

if err := g.Verify(); err != nil {
return fmt.Errorf("failed to verify genesis: %w", err)
}
Expand Down

0 comments on commit 8f9dbb6

Please sign in to comment.