diff --git a/chains/manager.go b/chains/manager.go index f3418a48cefd..5cb75c79bc94 100644 --- a/chains/manager.go +++ b/chains/manager.go @@ -43,6 +43,7 @@ import ( "github.com/ava-labs/avalanchego/staking" "github.com/ava-labs/avalanchego/subnets" "github.com/ava-labs/avalanchego/trace" + "github.com/ava-labs/avalanchego/upgrade" "github.com/ava-labs/avalanchego/utils/buffer" "github.com/ava-labs/avalanchego/utils/constants" "github.com/ava-labs/avalanchego/utils/crypto/bls" @@ -50,7 +51,6 @@ import ( "github.com/ava-labs/avalanchego/utils/metric" "github.com/ava-labs/avalanchego/utils/perms" "github.com/ava-labs/avalanchego/utils/set" - "github.com/ava-labs/avalanchego/version" "github.com/ava-labs/avalanchego/vms" "github.com/ava-labs/avalanchego/vms/fx" "github.com/ava-labs/avalanchego/vms/metervm" @@ -233,8 +233,7 @@ type ManagerConfig struct { // containers in an ancestors message it receives. BootstrapAncestorsMaxContainersReceived int - ApricotPhase4Time time.Time - ApricotPhase4MinPChainHeight uint64 + Upgrades upgrade.Config // Tracks CPU/disk usage caused by each peer. ResourceTracker timetracker.ResourceTracker @@ -726,11 +725,10 @@ func (m *manager) createAvalancheChain( // persistence of vertices vtxManager := state.NewSerializer( state.SerializerConfig{ - ChainID: ctx.ChainID, - VM: dagVM, - DB: vertexDB, - Log: ctx.Log, - CortinaTime: version.GetCortinaTime(ctx.NetworkID), + ChainID: ctx.ChainID, + VM: dagVM, + DB: vertexDB, + Log: ctx.Log, }, ) @@ -767,8 +765,8 @@ func (m *manager) createAvalancheChain( numHistoricalBlocks = subnetCfg.ProposerNumHistoricalBlocks } m.Log.Info("creating proposervm wrapper", - zap.Time("activationTime", m.ApricotPhase4Time), - zap.Uint64("minPChainHeight", m.ApricotPhase4MinPChainHeight), + zap.Time("activationTime", m.Upgrades.ApricotPhase4Time), + zap.Uint64("minPChainHeight", m.Upgrades.ApricotPhase4MinPChainHeight), zap.Duration("minBlockDelay", minBlockDelay), zap.Uint64("numHistoricalBlocks", numHistoricalBlocks), ) @@ -792,9 +790,7 @@ func (m *manager) createAvalancheChain( proposerVM := proposervm.New( vmWrappedInsideProposerVM, proposervm.Config{ - ActivationTime: m.ApricotPhase4Time, - DurangoTime: version.GetDurangoTime(m.NetworkID), - MinimumPChainHeight: m.ApricotPhase4MinPChainHeight, + Upgrades: m.Upgrades, MinBlkDelay: minBlockDelay, NumHistoricalBlocks: numHistoricalBlocks, StakingLeafSigner: m.StakingTLSSigner, @@ -1013,7 +1009,7 @@ func (m *manager) createAvalancheChain( VM: linearizableVM, } if ctx.ChainID == m.XChainID { - avalancheBootstrapperConfig.StopVertexID = version.CortinaXChainStopVertexID[ctx.NetworkID] + avalancheBootstrapperConfig.StopVertexID = m.Upgrades.CortinaXChainStopVertexID } avalancheBootstrapper, err := avbootstrap.New( @@ -1173,8 +1169,8 @@ func (m *manager) createSnowmanChain( numHistoricalBlocks = subnetCfg.ProposerNumHistoricalBlocks } m.Log.Info("creating proposervm wrapper", - zap.Time("activationTime", m.ApricotPhase4Time), - zap.Uint64("minPChainHeight", m.ApricotPhase4MinPChainHeight), + zap.Time("activationTime", m.Upgrades.ApricotPhase4Time), + zap.Uint64("minPChainHeight", m.Upgrades.ApricotPhase4MinPChainHeight), zap.Duration("minBlockDelay", minBlockDelay), zap.Uint64("numHistoricalBlocks", numHistoricalBlocks), ) @@ -1194,9 +1190,7 @@ func (m *manager) createSnowmanChain( proposerVM := proposervm.New( vm, proposervm.Config{ - ActivationTime: m.ApricotPhase4Time, - DurangoTime: version.GetDurangoTime(m.NetworkID), - MinimumPChainHeight: m.ApricotPhase4MinPChainHeight, + Upgrades: m.Upgrades, MinBlkDelay: minBlockDelay, NumHistoricalBlocks: numHistoricalBlocks, StakingLeafSigner: m.StakingTLSSigner, diff --git a/config/config.go b/config/config.go index e9506e33723f..4c98b6a47fda 100644 --- a/config/config.go +++ b/config/config.go @@ -33,6 +33,7 @@ import ( "github.com/ava-labs/avalanchego/staking" "github.com/ava-labs/avalanchego/subnets" "github.com/ava-labs/avalanchego/trace" + "github.com/ava-labs/avalanchego/upgrade" "github.com/ava-labs/avalanchego/utils/compression" "github.com/ava-labs/avalanchego/utils/constants" "github.com/ava-labs/avalanchego/utils/crypto/bls" @@ -796,6 +797,44 @@ func getTxFeeConfig(v *viper.Viper, networkID uint32) genesis.TxFeeConfig { return genesis.GetTxFeeConfig(networkID) } +func getUpgradeConfig(v *viper.Viper, networkID uint32) (upgrade.Config, error) { + if !v.IsSet(UpgradeFileKey) && !v.IsSet(UpgradeFileContentKey) { + return upgrade.GetConfig(networkID), nil + } + + switch networkID { + case constants.MainnetID, constants.TestnetID, constants.LocalID: + return upgrade.Config{}, fmt.Errorf("cannot configure upgrades for networkID: %s", + constants.NetworkName(networkID), + ) + } + + var ( + upgradeBytes []byte + err error + ) + switch { + case v.IsSet(UpgradeFileKey): + upgradeFileName := GetExpandedArg(v, UpgradeFileKey) + upgradeBytes, err = os.ReadFile(upgradeFileName) + if err != nil { + return upgrade.Config{}, fmt.Errorf("unable to read upgrade file: %w", err) + } + case v.IsSet(UpgradeFileContentKey): + upgradeContent := v.GetString(UpgradeFileContentKey) + upgradeBytes, err = base64.StdEncoding.DecodeString(upgradeContent) + if err != nil { + return upgrade.Config{}, fmt.Errorf("unable to decode upgrade base64 content: %w", err) + } + } + + var upgradeConfig upgrade.Config + if err := json.Unmarshal(upgradeBytes, &upgradeConfig); err != nil { + return upgrade.Config{}, fmt.Errorf("unable to unmarshal upgrade bytes: %w", err) + } + return upgradeConfig, nil +} + func getGenesisData(v *viper.Viper, networkID uint32, stakingCfg *genesis.StakingConfig) ([]byte, ids.ID, error) { // try first loading genesis content directly from flag/env-var if v.IsSet(GenesisFileContentKey) { @@ -1311,6 +1350,12 @@ func GetNodeConfig(v *viper.Viper) (node.Config, error) { return node.Config{}, err } + // Upgrade config + nodeConfig.UpgradeConfig, err = getUpgradeConfig(v, nodeConfig.NetworkID) + if err != nil { + return node.Config{}, err + } + // Network Config nodeConfig.NetworkConfig, err = getNetworkConfig( v, diff --git a/config/flags.go b/config/flags.go index 78fe2b87c2a6..6351161e69a2 100644 --- a/config/flags.go +++ b/config/flags.go @@ -92,6 +92,11 @@ func addNodeFlags(fs *pflag.FlagSet) { GenesisFileContentKey)) fs.String(GenesisFileContentKey, "", "Specifies base64 encoded genesis content") + // Upgrade + fs.String(UpgradeFileKey, "", fmt.Sprintf("Specifies an upgrade config file path. Ignored when running standard networks or if %s is specified", + UpgradeFileContentKey)) + fs.String(UpgradeFileContentKey, "", "Specifies base64 encoded upgrade content") + // Network ID fs.String(NetworkNameKey, constants.MainnetName, "Network ID this node will connect to") diff --git a/config/keys.go b/config/keys.go index 827f6bd7a99f..714136a74073 100644 --- a/config/keys.go +++ b/config/keys.go @@ -16,6 +16,8 @@ const ( VersionJSONKey = "version-json" GenesisFileKey = "genesis-file" GenesisFileContentKey = "genesis-file-content" + UpgradeFileKey = "upgrade-file" + UpgradeFileContentKey = "upgrade-file-content" NetworkNameKey = "network-id" ACPSupportKey = "acp-support" ACPObjectKey = "acp-object" diff --git a/network/network.go b/network/network.go index 2aee13a910d9..5d2fa1ec344b 100644 --- a/network/network.go +++ b/network/network.go @@ -172,6 +172,7 @@ type network struct { // NewNetwork returns a new Network implementation with the provided parameters. func NewNetwork( config *Config, + minCompatibleTime time.Time, msgCreator message.Creator, metricsRegisterer prometheus.Registerer, log logging.Logger, @@ -261,7 +262,7 @@ func NewNetwork( InboundMsgThrottler: inboundMsgThrottler, Network: nil, // This is set below. Router: router, - VersionCompatibility: version.GetCompatibility(config.NetworkID), + VersionCompatibility: version.GetCompatibility(minCompatibleTime), MySubnets: config.TrackedSubnets, Beacons: config.Beacons, Validators: config.Validators, diff --git a/network/network_test.go b/network/network_test.go index 85390da90dff..a79d5d0cf717 100644 --- a/network/network_test.go +++ b/network/network_test.go @@ -26,6 +26,7 @@ import ( "github.com/ava-labs/avalanchego/snow/validators" "github.com/ava-labs/avalanchego/staking" "github.com/ava-labs/avalanchego/subnets" + "github.com/ava-labs/avalanchego/upgrade" "github.com/ava-labs/avalanchego/utils" "github.com/ava-labs/avalanchego/utils/constants" "github.com/ava-labs/avalanchego/utils/crypto/bls" @@ -237,6 +238,7 @@ func newFullyConnectedTestNetwork(t *testing.T, handlers []router.InboundHandler var connected set.Set[ids.NodeID] net, err := NewNetwork( config, + upgrade.InitiallyActiveTime, msgCreator, registry, logging.NoLog{}, @@ -466,6 +468,7 @@ func TestTrackDoesNotDialPrivateIPs(t *testing.T) { net, err := NewNetwork( config, + upgrade.InitiallyActiveTime, msgCreator, registry, logging.NoLog{}, @@ -545,6 +548,7 @@ func TestDialDeletesNonValidators(t *testing.T) { net, err := NewNetwork( config, + upgrade.InitiallyActiveTime, msgCreator, registry, logging.NoLog{}, @@ -699,6 +703,7 @@ func TestAllowConnectionAsAValidator(t *testing.T) { net, err := NewNetwork( config, + upgrade.InitiallyActiveTime, msgCreator, registry, logging.NoLog{}, diff --git a/network/peer/peer_test.go b/network/peer/peer_test.go index e29edbe17ba6..316b491180af 100644 --- a/network/peer/peer_test.go +++ b/network/peer/peer_test.go @@ -23,6 +23,7 @@ import ( "github.com/ava-labs/avalanchego/snow/uptime" "github.com/ava-labs/avalanchego/snow/validators" "github.com/ava-labs/avalanchego/staking" + "github.com/ava-labs/avalanchego/upgrade" "github.com/ava-labs/avalanchego/utils" "github.com/ava-labs/avalanchego/utils/constants" "github.com/ava-labs/avalanchego/utils/crypto/bls" @@ -83,7 +84,7 @@ func newConfig(t *testing.T) Config { InboundMsgThrottler: throttling.NewNoInboundThrottler(), Network: TestNetwork, Router: nil, - VersionCompatibility: version.GetCompatibility(constants.LocalID), + VersionCompatibility: version.GetCompatibility(upgrade.InitiallyActiveTime), MySubnets: nil, Beacons: validators.NewManager(), Validators: validators.NewManager(), @@ -451,7 +452,7 @@ func TestShouldDisconnect(t *testing.T) { initialPeer: &peer{ Config: &Config{ Log: logging.NoLog{}, - VersionCompatibility: version.GetCompatibility(constants.UnitTestID), + VersionCompatibility: version.GetCompatibility(upgrade.InitiallyActiveTime), }, version: &version.Application{ Name: version.Client, @@ -463,7 +464,7 @@ func TestShouldDisconnect(t *testing.T) { expectedPeer: &peer{ Config: &Config{ Log: logging.NoLog{}, - VersionCompatibility: version.GetCompatibility(constants.UnitTestID), + VersionCompatibility: version.GetCompatibility(upgrade.InitiallyActiveTime), }, version: &version.Application{ Name: version.Client, @@ -479,7 +480,7 @@ func TestShouldDisconnect(t *testing.T) { initialPeer: &peer{ Config: &Config{ Log: logging.NoLog{}, - VersionCompatibility: version.GetCompatibility(constants.UnitTestID), + VersionCompatibility: version.GetCompatibility(upgrade.InitiallyActiveTime), Validators: validators.NewManager(), }, version: version.CurrentApp, @@ -487,7 +488,7 @@ func TestShouldDisconnect(t *testing.T) { expectedPeer: &peer{ Config: &Config{ Log: logging.NoLog{}, - VersionCompatibility: version.GetCompatibility(constants.UnitTestID), + VersionCompatibility: version.GetCompatibility(upgrade.InitiallyActiveTime), Validators: validators.NewManager(), }, version: version.CurrentApp, @@ -499,7 +500,7 @@ func TestShouldDisconnect(t *testing.T) { initialPeer: &peer{ Config: &Config{ Log: logging.NoLog{}, - VersionCompatibility: version.GetCompatibility(constants.UnitTestID), + VersionCompatibility: version.GetCompatibility(upgrade.InitiallyActiveTime), Validators: func() validators.Manager { vdrs := validators.NewManager() require.NoError(t, vdrs.AddStaker( @@ -518,7 +519,7 @@ func TestShouldDisconnect(t *testing.T) { expectedPeer: &peer{ Config: &Config{ Log: logging.NoLog{}, - VersionCompatibility: version.GetCompatibility(constants.UnitTestID), + VersionCompatibility: version.GetCompatibility(upgrade.InitiallyActiveTime), Validators: func() validators.Manager { vdrs := validators.NewManager() require.NoError(t, vdrs.AddStaker( @@ -541,7 +542,7 @@ func TestShouldDisconnect(t *testing.T) { initialPeer: &peer{ Config: &Config{ Log: logging.NoLog{}, - VersionCompatibility: version.GetCompatibility(constants.UnitTestID), + VersionCompatibility: version.GetCompatibility(upgrade.InitiallyActiveTime), Validators: func() validators.Manager { vdrs := validators.NewManager() require.NoError(t, vdrs.AddStaker( @@ -561,7 +562,7 @@ func TestShouldDisconnect(t *testing.T) { expectedPeer: &peer{ Config: &Config{ Log: logging.NoLog{}, - VersionCompatibility: version.GetCompatibility(constants.UnitTestID), + VersionCompatibility: version.GetCompatibility(upgrade.InitiallyActiveTime), Validators: func() validators.Manager { vdrs := validators.NewManager() require.NoError(t, vdrs.AddStaker( @@ -585,7 +586,7 @@ func TestShouldDisconnect(t *testing.T) { initialPeer: &peer{ Config: &Config{ Log: logging.NoLog{}, - VersionCompatibility: version.GetCompatibility(constants.UnitTestID), + VersionCompatibility: version.GetCompatibility(upgrade.InitiallyActiveTime), Validators: func() validators.Manager { vdrs := validators.NewManager() require.NoError(t, vdrs.AddStaker( @@ -605,7 +606,7 @@ func TestShouldDisconnect(t *testing.T) { expectedPeer: &peer{ Config: &Config{ Log: logging.NoLog{}, - VersionCompatibility: version.GetCompatibility(constants.UnitTestID), + VersionCompatibility: version.GetCompatibility(upgrade.InitiallyActiveTime), Validators: func() validators.Manager { vdrs := validators.NewManager() require.NoError(t, vdrs.AddStaker( @@ -629,7 +630,7 @@ func TestShouldDisconnect(t *testing.T) { initialPeer: &peer{ Config: &Config{ Log: logging.NoLog{}, - VersionCompatibility: version.GetCompatibility(constants.UnitTestID), + VersionCompatibility: version.GetCompatibility(upgrade.InitiallyActiveTime), Validators: func() validators.Manager { vdrs := validators.NewManager() require.NoError(t, vdrs.AddStaker( @@ -651,7 +652,7 @@ func TestShouldDisconnect(t *testing.T) { expectedPeer: &peer{ Config: &Config{ Log: logging.NoLog{}, - VersionCompatibility: version.GetCompatibility(constants.UnitTestID), + VersionCompatibility: version.GetCompatibility(upgrade.InitiallyActiveTime), Validators: func() validators.Manager { vdrs := validators.NewManager() require.NoError(t, vdrs.AddStaker( @@ -677,7 +678,7 @@ func TestShouldDisconnect(t *testing.T) { initialPeer: &peer{ Config: &Config{ Log: logging.NoLog{}, - VersionCompatibility: version.GetCompatibility(constants.UnitTestID), + VersionCompatibility: version.GetCompatibility(upgrade.InitiallyActiveTime), Validators: func() validators.Manager { vdrs := validators.NewManager() require.NoError(t, vdrs.AddStaker( @@ -699,7 +700,7 @@ func TestShouldDisconnect(t *testing.T) { expectedPeer: &peer{ Config: &Config{ Log: logging.NoLog{}, - VersionCompatibility: version.GetCompatibility(constants.UnitTestID), + VersionCompatibility: version.GetCompatibility(upgrade.InitiallyActiveTime), Validators: func() validators.Manager { vdrs := validators.NewManager() require.NoError(t, vdrs.AddStaker( diff --git a/network/peer/test_peer.go b/network/peer/test_peer.go index ae03594f8e67..bb1022982635 100644 --- a/network/peer/test_peer.go +++ b/network/peer/test_peer.go @@ -20,6 +20,7 @@ import ( "github.com/ava-labs/avalanchego/snow/uptime" "github.com/ava-labs/avalanchego/snow/validators" "github.com/ava-labs/avalanchego/staking" + "github.com/ava-labs/avalanchego/upgrade" "github.com/ava-labs/avalanchego/utils" "github.com/ava-labs/avalanchego/utils/constants" "github.com/ava-labs/avalanchego/utils/crypto/bls" @@ -113,7 +114,7 @@ func StartTestPeer( InboundMsgThrottler: throttling.NewNoInboundThrottler(), Network: TestNetwork, Router: router, - VersionCompatibility: version.GetCompatibility(networkID), + VersionCompatibility: version.GetCompatibility(upgrade.InitiallyActiveTime), MySubnets: set.Set[ids.ID]{}, Beacons: validators.NewManager(), Validators: validators.NewManager(), diff --git a/network/test_network.go b/network/test_network.go index 8644eb359ae1..e0647210ee5a 100644 --- a/network/test_network.go +++ b/network/test_network.go @@ -25,6 +25,7 @@ import ( "github.com/ava-labs/avalanchego/snow/validators" "github.com/ava-labs/avalanchego/staking" "github.com/ava-labs/avalanchego/subnets" + "github.com/ava-labs/avalanchego/upgrade" "github.com/ava-labs/avalanchego/utils" "github.com/ava-labs/avalanchego/utils/constants" "github.com/ava-labs/avalanchego/utils/crypto/bls" @@ -216,6 +217,7 @@ func NewTestNetwork( resourceTracker.DiskTracker(), ), }, + upgrade.InitiallyActiveTime, msgCreator, metrics, log, diff --git a/node/config.go b/node/config.go index 7ca0cadee9e1..1c99b2de8a83 100644 --- a/node/config.go +++ b/node/config.go @@ -18,6 +18,7 @@ import ( "github.com/ava-labs/avalanchego/snow/networking/tracker" "github.com/ava-labs/avalanchego/subnets" "github.com/ava-labs/avalanchego/trace" + "github.com/ava-labs/avalanchego/upgrade" "github.com/ava-labs/avalanchego/utils/crypto/bls" "github.com/ava-labs/avalanchego/utils/logging" "github.com/ava-labs/avalanchego/utils/profiler" @@ -130,6 +131,8 @@ type Config struct { BootstrapConfig `json:"bootstrapConfig"` DatabaseConfig `json:"databaseConfig"` + UpgradeConfig upgrade.Config `json:"upgradeConfig"` + // Genesis information GenesisBytes []byte `json:"-"` AvaxAssetID ids.ID `json:"avaxAssetID"` diff --git a/node/node.go b/node/node.go index e63f92e82bcd..ca804b815cdd 100644 --- a/node/node.go +++ b/node/node.go @@ -77,7 +77,6 @@ import ( "github.com/ava-labs/avalanchego/vms/avm" "github.com/ava-labs/avalanchego/vms/platformvm" "github.com/ava-labs/avalanchego/vms/platformvm/signer" - "github.com/ava-labs/avalanchego/vms/platformvm/upgrade" "github.com/ava-labs/avalanchego/vms/registry" "github.com/ava-labs/avalanchego/vms/rpcchainvm/runtime" @@ -633,6 +632,7 @@ func (n *Node) initNetworking(reg prometheus.Registerer) error { n.Net, err = network.NewNetwork( &n.Config.NetworkConfig, + n.Config.UpgradeConfig.DurangoTime, n.msgCreator, reg, n.Log, @@ -1184,8 +1184,7 @@ func (n *Node) initChainManager(avaxAssetID ids.ID) error { BootstrapMaxTimeGetAncestors: n.Config.BootstrapMaxTimeGetAncestors, BootstrapAncestorsMaxContainersSent: n.Config.BootstrapAncestorsMaxContainersSent, BootstrapAncestorsMaxContainersReceived: n.Config.BootstrapAncestorsMaxContainersReceived, - ApricotPhase4Time: version.GetApricotPhase4Time(n.Config.NetworkID), - ApricotPhase4MinPChainHeight: version.ApricotPhase4MinPChainHeight[n.Config.NetworkID], + Upgrades: n.Config.UpgradeConfig, ResourceTracker: n.resourceTracker, StateSyncBeacons: n.Config.StateSyncIDs, TracingEnabled: n.Config.TraceConfig.Enabled, @@ -1217,7 +1216,6 @@ func (n *Node) initVMs() error { } // Register the VMs that Avalanche supports - eUpgradeTime := version.GetEUpgradeTime(n.Config.NetworkID) err := errors.Join( n.VMManager.RegisterFactory(context.TODO(), constants.PlatformVMID, &platformvm.Factory{ Config: platformconfig.Config{ @@ -1238,22 +1236,15 @@ func (n *Node) initVMs() error { MinStakeDuration: n.Config.MinStakeDuration, MaxStakeDuration: n.Config.MaxStakeDuration, RewardConfig: n.Config.RewardConfig, - UpgradeConfig: upgrade.Config{ - ApricotPhase3Time: version.GetApricotPhase3Time(n.Config.NetworkID), - ApricotPhase5Time: version.GetApricotPhase5Time(n.Config.NetworkID), - BanffTime: version.GetBanffTime(n.Config.NetworkID), - CortinaTime: version.GetCortinaTime(n.Config.NetworkID), - DurangoTime: version.GetDurangoTime(n.Config.NetworkID), - EUpgradeTime: eUpgradeTime, - }, - UseCurrentHeight: n.Config.UseCurrentHeight, + UpgradeConfig: n.Config.UpgradeConfig, + UseCurrentHeight: n.Config.UseCurrentHeight, }, }), n.VMManager.RegisterFactory(context.TODO(), constants.AVMID, &avm.Factory{ Config: avmconfig.Config{ + Upgrades: n.Config.UpgradeConfig, TxFee: n.Config.StaticFeeConfig.TxFee, CreateAssetTxFee: n.Config.CreateAssetTxFee, - EUpgradeTime: eUpgradeTime, }, }), n.VMManager.RegisterFactory(context.TODO(), constants.EVMID, &coreth.Factory{}), diff --git a/snow/engine/avalanche/state/serializer.go b/snow/engine/avalanche/state/serializer.go index d88fa79ae240..1b0051bb6664 100644 --- a/snow/engine/avalanche/state/serializer.go +++ b/snow/engine/avalanche/state/serializer.go @@ -8,7 +8,6 @@ package state import ( "context" "errors" - "time" "github.com/ava-labs/avalanchego/cache" "github.com/ava-labs/avalanchego/database" @@ -43,11 +42,10 @@ type Serializer struct { } type SerializerConfig struct { - ChainID ids.ID - VM vertex.DAGVM - DB database.Database - Log logging.Logger - CortinaTime time.Time + ChainID ids.ID + VM vertex.DAGVM + DB database.Database + Log logging.Logger } func NewSerializer(config SerializerConfig) vertex.Manager { diff --git a/upgrade/upgrade.go b/upgrade/upgrade.go new file mode 100644 index 000000000000..f17ecfede88c --- /dev/null +++ b/upgrade/upgrade.go @@ -0,0 +1,182 @@ +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. +// See the file LICENSE for licensing terms. + +package upgrade + +import ( + "errors" + "fmt" + "time" + + "github.com/ava-labs/avalanchego/ids" + "github.com/ava-labs/avalanchego/utils/constants" +) + +var ( + InitiallyActiveTime = time.Date(2020, time.December, 5, 5, 0, 0, 0, time.UTC) + UnscheduledActivationTime = time.Date(10000, time.December, 1, 0, 0, 0, 0, time.UTC) + + Mainnet = Config{ + ApricotPhase1Time: time.Date(2021, time.March, 31, 14, 0, 0, 0, time.UTC), + ApricotPhase2Time: time.Date(2021, time.May, 10, 11, 0, 0, 0, time.UTC), + ApricotPhase3Time: time.Date(2021, time.August, 24, 14, 0, 0, 0, time.UTC), + ApricotPhase4Time: time.Date(2021, time.September, 22, 21, 0, 0, 0, time.UTC), + ApricotPhase4MinPChainHeight: 793005, + ApricotPhase5Time: time.Date(2021, time.December, 2, 18, 0, 0, 0, time.UTC), + ApricotPhasePre6Time: time.Date(2022, time.September, 5, 1, 30, 0, 0, time.UTC), + ApricotPhase6Time: time.Date(2022, time.September, 6, 20, 0, 0, 0, time.UTC), + ApricotPhasePost6Time: time.Date(2022, time.September, 7, 3, 0, 0, 0, time.UTC), + BanffTime: time.Date(2022, time.October, 18, 16, 0, 0, 0, time.UTC), + CortinaTime: time.Date(2023, time.April, 25, 15, 0, 0, 0, time.UTC), + // The mainnet stop vertex is well known. It can be verified on any + // fully synced node by looking at the parentID of the genesis block. + // + // Ref: https://subnets.avax.network/x-chain/block/0 + CortinaXChainStopVertexID: ids.FromStringOrPanic("jrGWDh5Po9FMj54depyunNixpia5PN4aAYxfmNzU8n752Rjga"), + DurangoTime: time.Date(2024, time.March, 6, 16, 0, 0, 0, time.UTC), + EtnaTime: UnscheduledActivationTime, + } + Fuji = Config{ + ApricotPhase1Time: time.Date(2021, time.March, 26, 14, 0, 0, 0, time.UTC), + ApricotPhase2Time: time.Date(2021, time.May, 5, 14, 0, 0, 0, time.UTC), + ApricotPhase3Time: time.Date(2021, time.August, 16, 19, 0, 0, 0, time.UTC), + ApricotPhase4Time: time.Date(2021, time.September, 16, 21, 0, 0, 0, time.UTC), + ApricotPhase4MinPChainHeight: 47437, + ApricotPhase5Time: time.Date(2021, time.November, 24, 15, 0, 0, 0, time.UTC), + ApricotPhasePre6Time: time.Date(2022, time.September, 6, 20, 0, 0, 0, time.UTC), + ApricotPhase6Time: time.Date(2022, time.September, 6, 20, 0, 0, 0, time.UTC), + ApricotPhasePost6Time: time.Date(2022, time.September, 7, 6, 0, 0, 0, time.UTC), + BanffTime: time.Date(2022, time.October, 3, 14, 0, 0, 0, time.UTC), + CortinaTime: time.Date(2023, time.April, 6, 15, 0, 0, 0, time.UTC), + // The fuji stop vertex is well known. It can be verified on any fully + // synced node by looking at the parentID of the genesis block. + // + // Ref: https://subnets-test.avax.network/x-chain/block/0 + CortinaXChainStopVertexID: ids.FromStringOrPanic("2D1cmbiG36BqQMRyHt4kFhWarmatA1ighSpND3FeFgz3vFVtCZ"), + DurangoTime: time.Date(2024, time.February, 13, 16, 0, 0, 0, time.UTC), + EtnaTime: UnscheduledActivationTime, + } + Default = Config{ + ApricotPhase1Time: InitiallyActiveTime, + ApricotPhase2Time: InitiallyActiveTime, + ApricotPhase3Time: InitiallyActiveTime, + ApricotPhase4Time: InitiallyActiveTime, + ApricotPhase4MinPChainHeight: 0, + ApricotPhase5Time: InitiallyActiveTime, + ApricotPhasePre6Time: InitiallyActiveTime, + ApricotPhase6Time: InitiallyActiveTime, + ApricotPhasePost6Time: InitiallyActiveTime, + BanffTime: InitiallyActiveTime, + CortinaTime: InitiallyActiveTime, + CortinaXChainStopVertexID: ids.Empty, + DurangoTime: InitiallyActiveTime, + EtnaTime: InitiallyActiveTime, + } + + ErrInvalidUpgradeTimes = errors.New("invalid upgrade configuration") +) + +type Config struct { + ApricotPhase1Time time.Time `json:"apricotPhase1Time"` + ApricotPhase2Time time.Time `json:"apricotPhase2Time"` + ApricotPhase3Time time.Time `json:"apricotPhase3Time"` + ApricotPhase4Time time.Time `json:"apricotPhase4Time"` + ApricotPhase4MinPChainHeight uint64 `json:"apricotPhase4MinPChainHeight"` + ApricotPhase5Time time.Time `json:"apricotPhase5Time"` + ApricotPhasePre6Time time.Time `json:"apricotPhasePre6Time"` + ApricotPhase6Time time.Time `json:"apricotPhase6Time"` + ApricotPhasePost6Time time.Time `json:"apricotPhasePost6Time"` + BanffTime time.Time `json:"banffTime"` + CortinaTime time.Time `json:"cortinaTime"` + CortinaXChainStopVertexID ids.ID `json:"cortinaXChainStopVertexID"` + DurangoTime time.Time `json:"durangoTime"` + EtnaTime time.Time `json:"etnaTime"` +} + +func (c *Config) Validate() error { + upgrades := []time.Time{ + c.ApricotPhase1Time, + c.ApricotPhase2Time, + c.ApricotPhase3Time, + c.ApricotPhase4Time, + c.ApricotPhase5Time, + c.ApricotPhasePre6Time, + c.ApricotPhase6Time, + c.ApricotPhasePost6Time, + c.BanffTime, + c.CortinaTime, + c.DurangoTime, + c.EtnaTime, + } + for i := 0; i < len(upgrades)-1; i++ { + if upgrades[i].After(upgrades[i+1]) { + return fmt.Errorf("%w: upgrade %d (%s) is after upgrade %d (%s)", + ErrInvalidUpgradeTimes, + i, + upgrades[i], + i+1, + upgrades[i+1], + ) + } + } + return nil +} + +func (c *Config) IsApricotPhase1Activated(t time.Time) bool { + return !t.Before(c.ApricotPhase1Time) +} + +func (c *Config) IsApricotPhase2Activated(t time.Time) bool { + return !t.Before(c.ApricotPhase2Time) +} + +func (c *Config) IsApricotPhase3Activated(t time.Time) bool { + return !t.Before(c.ApricotPhase3Time) +} + +func (c *Config) IsApricotPhase4Activated(t time.Time) bool { + return !t.Before(c.ApricotPhase4Time) +} + +func (c *Config) IsApricotPhase5Activated(t time.Time) bool { + return !t.Before(c.ApricotPhase5Time) +} + +func (c *Config) IsApricotPhasePre6Activated(t time.Time) bool { + return !t.Before(c.ApricotPhasePre6Time) +} + +func (c *Config) IsApricotPhase6Activated(t time.Time) bool { + return !t.Before(c.ApricotPhase6Time) +} + +func (c *Config) IsApricotPhasePost6Activated(t time.Time) bool { + return !t.Before(c.ApricotPhasePost6Time) +} + +func (c *Config) IsBanffActivated(t time.Time) bool { + return !t.Before(c.BanffTime) +} + +func (c *Config) IsCortinaActivated(t time.Time) bool { + return !t.Before(c.CortinaTime) +} + +func (c *Config) IsDurangoActivated(t time.Time) bool { + return !t.Before(c.DurangoTime) +} + +func (c *Config) IsEtnaActivated(t time.Time) bool { + return !t.Before(c.EtnaTime) +} + +func GetConfig(networkID uint32) Config { + switch networkID { + case constants.MainnetID: + return Mainnet + case constants.FujiID: + return Fuji + default: + return Default + } +} diff --git a/upgrade/upgrade_test.go b/upgrade/upgrade_test.go new file mode 100644 index 000000000000..eb9cdb38bd34 --- /dev/null +++ b/upgrade/upgrade_test.go @@ -0,0 +1,48 @@ +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. +// See the file LICENSE for licensing terms. + +package upgrade + +import ( + "testing" + "time" + + "github.com/stretchr/testify/require" +) + +func TestValidDefaultUpgrades(t *testing.T) { + for _, upgradeTest := range []struct { + name string + upgrade Config + }{ + { + name: "Default", + upgrade: Default, + }, + { + name: "Fuji", + upgrade: Fuji, + }, + { + name: "Mainnet", + upgrade: Mainnet, + }, + } { + t.Run(upgradeTest.name, func(t *testing.T) { + require := require.New(t) + require.NoError(upgradeTest.upgrade.Validate()) + }) + } +} + +func TestInvalidUpgrade(t *testing.T) { + require := require.New(t) + firstUpgradeTime := time.Now() + invalidSecondUpgradeTime := firstUpgradeTime.Add(-1 * time.Second) + upgrade := Config{ + ApricotPhase1Time: firstUpgradeTime, + ApricotPhase2Time: invalidSecondUpgradeTime, + } + err := upgrade.Validate() + require.ErrorIs(err, ErrInvalidUpgradeTimes) +} diff --git a/version/constants.go b/version/constants.go index 9e294b981694..3742f7ffe61f 100644 --- a/version/constants.go +++ b/version/constants.go @@ -9,7 +9,7 @@ import ( _ "embed" - "github.com/ava-labs/avalanchego/ids" + "github.com/ava-labs/avalanchego/upgrade" "github.com/ava-labs/avalanchego/utils/constants" ) @@ -68,82 +68,76 @@ var ( // by avalanchego, but is useful for downstream libraries. RPCChainVMProtocolCompatibility map[uint][]*Semantic - DefaultUpgradeTime = time.Date(2020, time.December, 5, 5, 0, 0, 0, time.UTC) - + // Deprecated: This will be removed once coreth no longer uses it. ApricotPhase1Times = map[uint32]time.Time{ - constants.MainnetID: time.Date(2021, time.March, 31, 14, 0, 0, 0, time.UTC), - constants.FujiID: time.Date(2021, time.March, 26, 14, 0, 0, 0, time.UTC), + constants.MainnetID: upgrade.Mainnet.ApricotPhase1Time, + constants.FujiID: upgrade.Fuji.ApricotPhase1Time, } + // Deprecated: This will be removed once coreth no longer uses it. ApricotPhase2Times = map[uint32]time.Time{ - constants.MainnetID: time.Date(2021, time.May, 10, 11, 0, 0, 0, time.UTC), - constants.FujiID: time.Date(2021, time.May, 5, 14, 0, 0, 0, time.UTC), + constants.MainnetID: upgrade.Mainnet.ApricotPhase2Time, + constants.FujiID: upgrade.Fuji.ApricotPhase2Time, } + // Deprecated: This will be removed once coreth no longer uses it. ApricotPhase3Times = map[uint32]time.Time{ - constants.MainnetID: time.Date(2021, time.August, 24, 14, 0, 0, 0, time.UTC), - constants.FujiID: time.Date(2021, time.August, 16, 19, 0, 0, 0, time.UTC), + constants.MainnetID: upgrade.Mainnet.ApricotPhase3Time, + constants.FujiID: upgrade.Fuji.ApricotPhase3Time, } + // Deprecated: This will be removed once coreth no longer uses it. ApricotPhase4Times = map[uint32]time.Time{ - constants.MainnetID: time.Date(2021, time.September, 22, 21, 0, 0, 0, time.UTC), - constants.FujiID: time.Date(2021, time.September, 16, 21, 0, 0, 0, time.UTC), - } - ApricotPhase4MinPChainHeight = map[uint32]uint64{ - constants.MainnetID: 793005, - constants.FujiID: 47437, + constants.MainnetID: upgrade.Mainnet.ApricotPhase4Time, + constants.FujiID: upgrade.Fuji.ApricotPhase4Time, } + // Deprecated: This will be removed once coreth no longer uses it. ApricotPhase5Times = map[uint32]time.Time{ - constants.MainnetID: time.Date(2021, time.December, 2, 18, 0, 0, 0, time.UTC), - constants.FujiID: time.Date(2021, time.November, 24, 15, 0, 0, 0, time.UTC), + constants.MainnetID: upgrade.Mainnet.ApricotPhase5Time, + constants.FujiID: upgrade.Fuji.ApricotPhase5Time, } + // Deprecated: This will be removed once coreth no longer uses it. ApricotPhasePre6Times = map[uint32]time.Time{ - constants.MainnetID: time.Date(2022, time.September, 5, 1, 30, 0, 0, time.UTC), - constants.FujiID: time.Date(2022, time.September, 6, 20, 0, 0, 0, time.UTC), + constants.MainnetID: upgrade.Mainnet.ApricotPhasePre6Time, + constants.FujiID: upgrade.Fuji.ApricotPhasePre6Time, } + // Deprecated: This will be removed once coreth no longer uses it. ApricotPhase6Times = map[uint32]time.Time{ - constants.MainnetID: time.Date(2022, time.September, 6, 20, 0, 0, 0, time.UTC), - constants.FujiID: time.Date(2022, time.September, 6, 20, 0, 0, 0, time.UTC), + constants.MainnetID: upgrade.Mainnet.ApricotPhase6Time, + constants.FujiID: upgrade.Fuji.ApricotPhase6Time, } + // Deprecated: This will be removed once coreth no longer uses it. ApricotPhasePost6Times = map[uint32]time.Time{ - constants.MainnetID: time.Date(2022, time.September, 7, 3, 0, 0, 0, time.UTC), - constants.FujiID: time.Date(2022, time.September, 7, 6, 0, 0, 0, time.UTC), + constants.MainnetID: upgrade.Mainnet.ApricotPhasePost6Time, + constants.FujiID: upgrade.Fuji.ApricotPhasePost6Time, } + // Deprecated: This will be removed once coreth no longer uses it. BanffTimes = map[uint32]time.Time{ - constants.MainnetID: time.Date(2022, time.October, 18, 16, 0, 0, 0, time.UTC), - constants.FujiID: time.Date(2022, time.October, 3, 14, 0, 0, 0, time.UTC), + constants.MainnetID: upgrade.Mainnet.BanffTime, + constants.FujiID: upgrade.Fuji.BanffTime, } + // Deprecated: This will be removed once coreth no longer uses it. CortinaTimes = map[uint32]time.Time{ - constants.MainnetID: time.Date(2023, time.April, 25, 15, 0, 0, 0, time.UTC), - constants.FujiID: time.Date(2023, time.April, 6, 15, 0, 0, 0, time.UTC), - } - CortinaXChainStopVertexID = map[uint32]ids.ID{ - // The mainnet stop vertex is well known. It can be verified on any - // fully synced node by looking at the parentID of the genesis block. - // - // Ref: https://subnets.avax.network/x-chain/block/0 - constants.MainnetID: ids.FromStringOrPanic("jrGWDh5Po9FMj54depyunNixpia5PN4aAYxfmNzU8n752Rjga"), - // The fuji stop vertex is well known. It can be verified on any fully - // synced node by looking at the parentID of the genesis block. - // - // Ref: https://subnets-test.avax.network/x-chain/block/0 - constants.FujiID: ids.FromStringOrPanic("2D1cmbiG36BqQMRyHt4kFhWarmatA1ighSpND3FeFgz3vFVtCZ"), + constants.MainnetID: upgrade.Mainnet.CortinaTime, + constants.FujiID: upgrade.Fuji.CortinaTime, } + // Deprecated: This will be removed once coreth no longer uses it. DurangoTimes = map[uint32]time.Time{ - constants.MainnetID: time.Date(2024, time.March, 6, 16, 0, 0, 0, time.UTC), - constants.FujiID: time.Date(2024, time.February, 13, 16, 0, 0, 0, time.UTC), + constants.MainnetID: upgrade.Mainnet.DurangoTime, + constants.FujiID: upgrade.Fuji.DurangoTime, } + // Deprecated: This will be removed once coreth no longer uses it. EUpgradeTimes = map[uint32]time.Time{ - constants.MainnetID: time.Date(10000, time.December, 1, 0, 0, 0, 0, time.UTC), - constants.FujiID: time.Date(10000, time.December, 1, 0, 0, 0, 0, time.UTC), + constants.MainnetID: upgrade.Mainnet.EtnaTime, + constants.FujiID: upgrade.Fuji.EtnaTime, } ) @@ -168,95 +162,11 @@ func init() { } } -func GetApricotPhase1Time(networkID uint32) time.Time { - if upgradeTime, exists := ApricotPhase1Times[networkID]; exists { - return upgradeTime - } - return DefaultUpgradeTime -} - -func GetApricotPhase2Time(networkID uint32) time.Time { - if upgradeTime, exists := ApricotPhase2Times[networkID]; exists { - return upgradeTime - } - return DefaultUpgradeTime -} - -func GetApricotPhase3Time(networkID uint32) time.Time { - if upgradeTime, exists := ApricotPhase3Times[networkID]; exists { - return upgradeTime - } - return DefaultUpgradeTime -} - -func GetApricotPhase4Time(networkID uint32) time.Time { - if upgradeTime, exists := ApricotPhase4Times[networkID]; exists { - return upgradeTime - } - return DefaultUpgradeTime -} - -func GetApricotPhase5Time(networkID uint32) time.Time { - if upgradeTime, exists := ApricotPhase5Times[networkID]; exists { - return upgradeTime - } - return DefaultUpgradeTime -} - -func GetApricotPhasePre6Time(networkID uint32) time.Time { - if upgradeTime, exists := ApricotPhasePre6Times[networkID]; exists { - return upgradeTime - } - return DefaultUpgradeTime -} - -func GetApricotPhase6Time(networkID uint32) time.Time { - if upgradeTime, exists := ApricotPhase6Times[networkID]; exists { - return upgradeTime - } - return DefaultUpgradeTime -} - -func GetApricotPhasePost6Time(networkID uint32) time.Time { - if upgradeTime, exists := ApricotPhasePost6Times[networkID]; exists { - return upgradeTime - } - return DefaultUpgradeTime -} - -func GetBanffTime(networkID uint32) time.Time { - if upgradeTime, exists := BanffTimes[networkID]; exists { - return upgradeTime - } - return DefaultUpgradeTime -} - -func GetCortinaTime(networkID uint32) time.Time { - if upgradeTime, exists := CortinaTimes[networkID]; exists { - return upgradeTime - } - return DefaultUpgradeTime -} - -func GetDurangoTime(networkID uint32) time.Time { - if upgradeTime, exists := DurangoTimes[networkID]; exists { - return upgradeTime - } - return DefaultUpgradeTime -} - -func GetEUpgradeTime(networkID uint32) time.Time { - if upgradeTime, exists := EUpgradeTimes[networkID]; exists { - return upgradeTime - } - return DefaultUpgradeTime -} - -func GetCompatibility(networkID uint32) Compatibility { +func GetCompatibility(minCompatibleTime time.Time) Compatibility { return NewCompatibility( CurrentApp, MinimumCompatibleVersion, - GetDurangoTime(networkID), + minCompatibleTime, PrevMinimumCompatibleVersion, ) } diff --git a/vms/avm/block/executor/block_test.go b/vms/avm/block/executor/block_test.go index 3f6c0a81b977..c95796da638f 100644 --- a/vms/avm/block/executor/block_test.go +++ b/vms/avm/block/executor/block_test.go @@ -15,6 +15,7 @@ import ( "github.com/ava-labs/avalanchego/chains/atomic" "github.com/ava-labs/avalanchego/ids" "github.com/ava-labs/avalanchego/snow" + "github.com/ava-labs/avalanchego/upgrade" "github.com/ava-labs/avalanchego/utils" "github.com/ava-labs/avalanchego/utils/logging" "github.com/ava-labs/avalanchego/utils/set" @@ -939,7 +940,9 @@ func defaultTestBackend(bootstrapped bool, sharedMemory atomic.SharedMemory) *ex Log: logging.NoLog{}, }, Config: &config.Config{ - EUpgradeTime: mockable.MaxTime, + Upgrades: upgrade.Config{ + EtnaTime: mockable.MaxTime, + }, TxFee: 0, CreateAssetTxFee: 0, }, diff --git a/vms/avm/config/config.go b/vms/avm/config/config.go index 0d026eb05dbb..9fddc7427c61 100644 --- a/vms/avm/config/config.go +++ b/vms/avm/config/config.go @@ -3,20 +3,15 @@ package config -import "time" +import "github.com/ava-labs/avalanchego/upgrade" // Struct collecting all the foundational parameters of the AVM type Config struct { + Upgrades upgrade.Config + // Fee that is burned by every non-asset creating transaction TxFee uint64 // Fee that must be burned by every asset creating transaction CreateAssetTxFee uint64 - - // Time of the E network upgrade - EUpgradeTime time.Time -} - -func (c *Config) IsEActivated(timestamp time.Time) bool { - return !timestamp.Before(c.EUpgradeTime) } diff --git a/vms/avm/environment_test.go b/vms/avm/environment_test.go index d4375aa092d1..ad4eff1aa1ba 100644 --- a/vms/avm/environment_test.go +++ b/vms/avm/environment_test.go @@ -20,6 +20,7 @@ import ( "github.com/ava-labs/avalanchego/snow" "github.com/ava-labs/avalanchego/snow/engine/common" "github.com/ava-labs/avalanchego/snow/snowtest" + "github.com/ava-labs/avalanchego/upgrade" "github.com/ava-labs/avalanchego/utils/constants" "github.com/ava-labs/avalanchego/utils/crypto/secp256k1" "github.com/ava-labs/avalanchego/utils/formatting" @@ -44,7 +45,7 @@ type fork uint8 const ( durango fork = iota - eUpgrade + etna latest = durango @@ -230,14 +231,16 @@ func setup(tb testing.TB, c *envConfig) *environment { func staticConfig(tb testing.TB, f fork) config.Config { c := config.Config{ + Upgrades: upgrade.Config{ + EtnaTime: mockable.MaxTime, + }, TxFee: testTxFee, CreateAssetTxFee: testTxFee, - EUpgradeTime: mockable.MaxTime, } switch f { - case eUpgrade: - c.EUpgradeTime = time.Time{} + case etna: + c.Upgrades.EtnaTime = time.Time{} case durango: default: require.FailNow(tb, "unhandled fork", f) diff --git a/vms/avm/service_test.go b/vms/avm/service_test.go index 4648506b2a5b..534424c63b0e 100644 --- a/vms/avm/service_test.go +++ b/vms/avm/service_test.go @@ -22,6 +22,7 @@ import ( "github.com/ava-labs/avalanchego/snow" "github.com/ava-labs/avalanchego/snow/choices" "github.com/ava-labs/avalanchego/snow/engine/common" + "github.com/ava-labs/avalanchego/upgrade" "github.com/ava-labs/avalanchego/utils/constants" "github.com/ava-labs/avalanchego/utils/crypto/secp256k1" "github.com/ava-labs/avalanchego/utils/formatting" @@ -2720,7 +2721,9 @@ func TestSendMultiple(t *testing.T) { initialKeys: keys, }}, vmStaticConfig: &config.Config{ - EUpgradeTime: mockable.MaxTime, + Upgrades: upgrade.Config{ + EtnaTime: mockable.MaxTime, + }, }, }) service := &Service{vm: env.vm} diff --git a/vms/avm/state/state_test.go b/vms/avm/state/state_test.go index a6170c62c405..b2d8f4f40845 100644 --- a/vms/avm/state/state_test.go +++ b/vms/avm/state/state_test.go @@ -14,7 +14,7 @@ import ( "github.com/ava-labs/avalanchego/database/memdb" "github.com/ava-labs/avalanchego/database/versiondb" "github.com/ava-labs/avalanchego/ids" - "github.com/ava-labs/avalanchego/version" + "github.com/ava-labs/avalanchego/upgrade" "github.com/ava-labs/avalanchego/vms/avm/block" "github.com/ava-labs/avalanchego/vms/avm/fxs" "github.com/ava-labs/avalanchego/vms/avm/txs" @@ -287,7 +287,7 @@ func TestInitializeChainState(t *testing.T) { require.NoError(err) stopVertexID := ids.GenerateTestID() - genesisTimestamp := version.DefaultUpgradeTime + genesisTimestamp := upgrade.InitiallyActiveTime require.NoError(s.InitializeChainState(stopVertexID, genesisTimestamp)) lastAcceptedID := s.GetLastAccepted() diff --git a/vms/avm/txs/executor/syntactic_verifier_test.go b/vms/avm/txs/executor/syntactic_verifier_test.go index c5762a81c74b..a5811163bad1 100644 --- a/vms/avm/txs/executor/syntactic_verifier_test.go +++ b/vms/avm/txs/executor/syntactic_verifier_test.go @@ -12,6 +12,7 @@ import ( "github.com/ava-labs/avalanchego/ids" "github.com/ava-labs/avalanchego/snow/snowtest" + "github.com/ava-labs/avalanchego/upgrade" "github.com/ava-labs/avalanchego/utils/constants" "github.com/ava-labs/avalanchego/utils/crypto/secp256k1" "github.com/ava-labs/avalanchego/utils/timer/mockable" @@ -28,9 +29,11 @@ import ( var ( keys = secp256k1.TestKeys() feeConfig = config.Config{ + Upgrades: upgrade.Config{ + EtnaTime: mockable.MaxTime, + }, TxFee: 2, CreateAssetTxFee: 3, - EUpgradeTime: mockable.MaxTime, } ) diff --git a/vms/avm/vm.go b/vms/avm/vm.go index e83e7cd9ea7a..c9170ba882f7 100644 --- a/vms/avm/vm.go +++ b/vms/avm/vm.go @@ -395,7 +395,7 @@ func (vm *VM) GetBlockIDAtHeight(_ context.Context, height uint64) (ids.ID, erro */ func (vm *VM) Linearize(ctx context.Context, stopVertexID ids.ID, toEngine chan<- common.Message) error { - time := version.GetCortinaTime(vm.ctx.NetworkID) + time := vm.Config.Upgrades.CortinaTime err := vm.state.InitializeChainState(stopVertexID, time) if err != nil { return err diff --git a/vms/platformvm/block/builder/helpers_test.go b/vms/platformvm/block/builder/helpers_test.go index d197cf9a1831..9b1954ebefea 100644 --- a/vms/platformvm/block/builder/helpers_test.go +++ b/vms/platformvm/block/builder/helpers_test.go @@ -25,6 +25,7 @@ import ( "github.com/ava-labs/avalanchego/snow/snowtest" "github.com/ava-labs/avalanchego/snow/uptime" "github.com/ava-labs/avalanchego/snow/validators" + "github.com/ava-labs/avalanchego/upgrade" "github.com/ava-labs/avalanchego/utils" "github.com/ava-labs/avalanchego/utils/constants" "github.com/ava-labs/avalanchego/utils/crypto/secp256k1" @@ -46,7 +47,6 @@ import ( "github.com/ava-labs/avalanchego/vms/platformvm/txs/fee" "github.com/ava-labs/avalanchego/vms/platformvm/txs/mempool" "github.com/ava-labs/avalanchego/vms/platformvm/txs/txstest" - "github.com/ava-labs/avalanchego/vms/platformvm/upgrade" "github.com/ava-labs/avalanchego/vms/platformvm/utxo" "github.com/ava-labs/avalanchego/vms/secp256k1fx" @@ -66,7 +66,7 @@ const ( banff cortina durango - eUpgrade + etna latestFork = durango ) @@ -329,13 +329,13 @@ func defaultConfig(t *testing.T, f fork) *config.Config { BanffTime: mockable.MaxTime, CortinaTime: mockable.MaxTime, DurangoTime: mockable.MaxTime, - EUpgradeTime: mockable.MaxTime, + EtnaTime: mockable.MaxTime, }, } switch f { - case eUpgrade: - c.UpgradeConfig.EUpgradeTime = time.Time{} // neglecting fork ordering this for package tests + case etna: + c.UpgradeConfig.EtnaTime = time.Time{} // neglecting fork ordering this for package tests fallthrough case durango: c.UpgradeConfig.DurangoTime = time.Time{} // neglecting fork ordering for this package's tests diff --git a/vms/platformvm/block/executor/helpers_test.go b/vms/platformvm/block/executor/helpers_test.go index e06031eb2bce..33470fecf9fc 100644 --- a/vms/platformvm/block/executor/helpers_test.go +++ b/vms/platformvm/block/executor/helpers_test.go @@ -27,6 +27,7 @@ import ( "github.com/ava-labs/avalanchego/snow/snowtest" "github.com/ava-labs/avalanchego/snow/uptime" "github.com/ava-labs/avalanchego/snow/validators" + "github.com/ava-labs/avalanchego/upgrade" "github.com/ava-labs/avalanchego/utils" "github.com/ava-labs/avalanchego/utils/constants" "github.com/ava-labs/avalanchego/utils/crypto/secp256k1" @@ -48,7 +49,6 @@ import ( "github.com/ava-labs/avalanchego/vms/platformvm/txs/fee" "github.com/ava-labs/avalanchego/vms/platformvm/txs/mempool" "github.com/ava-labs/avalanchego/vms/platformvm/txs/txstest" - "github.com/ava-labs/avalanchego/vms/platformvm/upgrade" "github.com/ava-labs/avalanchego/vms/platformvm/utxo" "github.com/ava-labs/avalanchego/vms/secp256k1fx" @@ -69,7 +69,7 @@ const ( banff cortina durango - eUpgrade + etna ) var ( @@ -359,13 +359,13 @@ func defaultConfig(t *testing.T, f fork) *config.Config { BanffTime: mockable.MaxTime, CortinaTime: mockable.MaxTime, DurangoTime: mockable.MaxTime, - EUpgradeTime: mockable.MaxTime, + EtnaTime: mockable.MaxTime, }, } switch f { - case eUpgrade: - c.UpgradeConfig.EUpgradeTime = time.Time{} // neglecting fork ordering this for package tests + case etna: + c.UpgradeConfig.EtnaTime = time.Time{} // neglecting fork ordering this for package tests fallthrough case durango: c.UpgradeConfig.DurangoTime = time.Time{} // neglecting fork ordering for this package's tests diff --git a/vms/platformvm/block/executor/verifier_test.go b/vms/platformvm/block/executor/verifier_test.go index bbb6dd36e336..5c058e7c69ee 100644 --- a/vms/platformvm/block/executor/verifier_test.go +++ b/vms/platformvm/block/executor/verifier_test.go @@ -15,6 +15,7 @@ import ( "github.com/ava-labs/avalanchego/database" "github.com/ava-labs/avalanchego/ids" "github.com/ava-labs/avalanchego/snow" + "github.com/ava-labs/avalanchego/upgrade" "github.com/ava-labs/avalanchego/utils/logging" "github.com/ava-labs/avalanchego/utils/set" "github.com/ava-labs/avalanchego/utils/timer/mockable" @@ -27,7 +28,6 @@ import ( "github.com/ava-labs/avalanchego/vms/platformvm/txs" "github.com/ava-labs/avalanchego/vms/platformvm/txs/executor" "github.com/ava-labs/avalanchego/vms/platformvm/txs/mempool" - "github.com/ava-labs/avalanchego/vms/platformvm/upgrade" ) func TestVerifierVisitProposalBlock(t *testing.T) { diff --git a/vms/platformvm/config/config.go b/vms/platformvm/config/config.go index 61dedea3ff28..4cb6c981feac 100644 --- a/vms/platformvm/config/config.go +++ b/vms/platformvm/config/config.go @@ -10,11 +10,11 @@ import ( "github.com/ava-labs/avalanchego/ids" "github.com/ava-labs/avalanchego/snow/uptime" "github.com/ava-labs/avalanchego/snow/validators" + "github.com/ava-labs/avalanchego/upgrade" "github.com/ava-labs/avalanchego/utils/constants" "github.com/ava-labs/avalanchego/utils/set" "github.com/ava-labs/avalanchego/vms/platformvm/reward" "github.com/ava-labs/avalanchego/vms/platformvm/txs" - "github.com/ava-labs/avalanchego/vms/platformvm/upgrade" feecomponent "github.com/ava-labs/avalanchego/vms/components/fee" txfee "github.com/ava-labs/avalanchego/vms/platformvm/txs/fee" diff --git a/vms/platformvm/txs/executor/helpers_test.go b/vms/platformvm/txs/executor/helpers_test.go index 1485f1802555..8aea45ee3317 100644 --- a/vms/platformvm/txs/executor/helpers_test.go +++ b/vms/platformvm/txs/executor/helpers_test.go @@ -25,6 +25,7 @@ import ( "github.com/ava-labs/avalanchego/snow/snowtest" "github.com/ava-labs/avalanchego/snow/uptime" "github.com/ava-labs/avalanchego/snow/validators" + "github.com/ava-labs/avalanchego/upgrade" "github.com/ava-labs/avalanchego/utils" "github.com/ava-labs/avalanchego/utils/constants" "github.com/ava-labs/avalanchego/utils/crypto/secp256k1" @@ -44,7 +45,6 @@ import ( "github.com/ava-labs/avalanchego/vms/platformvm/txs" "github.com/ava-labs/avalanchego/vms/platformvm/txs/fee" "github.com/ava-labs/avalanchego/vms/platformvm/txs/txstest" - "github.com/ava-labs/avalanchego/vms/platformvm/upgrade" "github.com/ava-labs/avalanchego/vms/platformvm/utxo" "github.com/ava-labs/avalanchego/vms/secp256k1fx" "github.com/ava-labs/avalanchego/wallet/subnet/primary/common" @@ -61,7 +61,7 @@ const ( banff cortina durango - eUpgrade + etna ) var ( @@ -302,13 +302,13 @@ func defaultConfig(t *testing.T, f fork) *config.Config { BanffTime: mockable.MaxTime, CortinaTime: mockable.MaxTime, DurangoTime: mockable.MaxTime, - EUpgradeTime: mockable.MaxTime, + EtnaTime: mockable.MaxTime, }, } switch f { - case eUpgrade: - c.UpgradeConfig.EUpgradeTime = defaultValidateStartTime.Add(-2 * time.Second) + case etna: + c.UpgradeConfig.EtnaTime = defaultValidateStartTime.Add(-2 * time.Second) fallthrough case durango: c.UpgradeConfig.DurangoTime = defaultValidateStartTime.Add(-2 * time.Second) diff --git a/vms/platformvm/txs/executor/standard_tx_executor_test.go b/vms/platformvm/txs/executor/standard_tx_executor_test.go index 9e610bb71dcf..f6bd40f7aae3 100644 --- a/vms/platformvm/txs/executor/standard_tx_executor_test.go +++ b/vms/platformvm/txs/executor/standard_tx_executor_test.go @@ -17,6 +17,7 @@ import ( "github.com/ava-labs/avalanchego/database" "github.com/ava-labs/avalanchego/ids" "github.com/ava-labs/avalanchego/snow" + "github.com/ava-labs/avalanchego/upgrade" "github.com/ava-labs/avalanchego/utils" "github.com/ava-labs/avalanchego/utils/constants" "github.com/ava-labs/avalanchego/utils/crypto/bls" @@ -33,7 +34,6 @@ import ( "github.com/ava-labs/avalanchego/vms/platformvm/state" "github.com/ava-labs/avalanchego/vms/platformvm/status" "github.com/ava-labs/avalanchego/vms/platformvm/txs" - "github.com/ava-labs/avalanchego/vms/platformvm/upgrade" "github.com/ava-labs/avalanchego/vms/platformvm/utxo" "github.com/ava-labs/avalanchego/vms/secp256k1fx" "github.com/ava-labs/avalanchego/wallet/subnet/primary/common" @@ -2257,13 +2257,13 @@ func defaultTestConfig(t *testing.T, f fork, tm time.Time) *config.Config { BanffTime: mockable.MaxTime, CortinaTime: mockable.MaxTime, DurangoTime: mockable.MaxTime, - EUpgradeTime: mockable.MaxTime, + EtnaTime: mockable.MaxTime, }, } switch f { - case eUpgrade: - c.UpgradeConfig.EUpgradeTime = tm + case etna: + c.UpgradeConfig.EtnaTime = tm fallthrough case durango: c.UpgradeConfig.DurangoTime = tm diff --git a/vms/platformvm/upgrade/config.go b/vms/platformvm/upgrade/config.go deleted file mode 100644 index 1d92736a2ee3..000000000000 --- a/vms/platformvm/upgrade/config.go +++ /dev/null @@ -1,50 +0,0 @@ -// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. -// See the file LICENSE for licensing terms. - -package upgrade - -import "time" - -type Config struct { - // Time of the AP3 network upgrade - ApricotPhase3Time time.Time - - // Time of the AP5 network upgrade - ApricotPhase5Time time.Time - - // Time of the Banff network upgrade - BanffTime time.Time - - // Time of the Cortina network upgrade - CortinaTime time.Time - - // Time of the Durango network upgrade - DurangoTime time.Time - - // Time of the E network upgrade - EUpgradeTime time.Time -} - -func (c *Config) IsApricotPhase3Activated(timestamp time.Time) bool { - return !timestamp.Before(c.ApricotPhase3Time) -} - -func (c *Config) IsApricotPhase5Activated(timestamp time.Time) bool { - return !timestamp.Before(c.ApricotPhase5Time) -} - -func (c *Config) IsBanffActivated(timestamp time.Time) bool { - return !timestamp.Before(c.BanffTime) -} - -func (c *Config) IsCortinaActivated(timestamp time.Time) bool { - return !timestamp.Before(c.CortinaTime) -} - -func (c *Config) IsDurangoActivated(timestamp time.Time) bool { - return !timestamp.Before(c.DurangoTime) -} - -func (c *Config) IsEActivated(timestamp time.Time) bool { - return !timestamp.Before(c.EUpgradeTime) -} diff --git a/vms/platformvm/validator_set_property_test.go b/vms/platformvm/validator_set_property_test.go index 9ed3dc7cbd4d..e55bca434180 100644 --- a/vms/platformvm/validator_set_property_test.go +++ b/vms/platformvm/validator_set_property_test.go @@ -28,6 +28,7 @@ import ( "github.com/ava-labs/avalanchego/snow/snowtest" "github.com/ava-labs/avalanchego/snow/uptime" "github.com/ava-labs/avalanchego/snow/validators" + "github.com/ava-labs/avalanchego/upgrade" "github.com/ava-labs/avalanchego/utils/constants" "github.com/ava-labs/avalanchego/utils/crypto/bls" "github.com/ava-labs/avalanchego/utils/formatting" @@ -44,7 +45,6 @@ import ( "github.com/ava-labs/avalanchego/vms/platformvm/txs" "github.com/ava-labs/avalanchego/vms/platformvm/txs/fee" "github.com/ava-labs/avalanchego/vms/platformvm/txs/txstest" - "github.com/ava-labs/avalanchego/vms/platformvm/upgrade" "github.com/ava-labs/avalanchego/vms/secp256k1fx" blockexecutor "github.com/ava-labs/avalanchego/vms/platformvm/block/executor" @@ -667,7 +667,7 @@ func buildVM(t *testing.T) (*VM, ids.ID, error) { ApricotPhase5Time: forkTime, BanffTime: forkTime, CortinaTime: forkTime, - EUpgradeTime: mockable.MaxTime, + EtnaTime: mockable.MaxTime, }, }} vm.clock.Set(forkTime.Add(time.Second)) diff --git a/vms/platformvm/vm_regression_test.go b/vms/platformvm/vm_regression_test.go index 035573fd8ae8..b967dfd6632f 100644 --- a/vms/platformvm/vm_regression_test.go +++ b/vms/platformvm/vm_regression_test.go @@ -27,6 +27,7 @@ import ( "github.com/ava-labs/avalanchego/snow/snowtest" "github.com/ava-labs/avalanchego/snow/uptime" "github.com/ava-labs/avalanchego/snow/validators" + "github.com/ava-labs/avalanchego/upgrade" "github.com/ava-labs/avalanchego/utils/bloom" "github.com/ava-labs/avalanchego/utils/constants" "github.com/ava-labs/avalanchego/utils/crypto/bls" @@ -43,7 +44,6 @@ import ( "github.com/ava-labs/avalanchego/vms/platformvm/txs" "github.com/ava-labs/avalanchego/vms/platformvm/txs/executor" "github.com/ava-labs/avalanchego/vms/platformvm/txs/txstest" - "github.com/ava-labs/avalanchego/vms/platformvm/upgrade" "github.com/ava-labs/avalanchego/vms/secp256k1fx" blockexecutor "github.com/ava-labs/avalanchego/vms/platformvm/block/executor" @@ -457,10 +457,10 @@ func TestUnverifiedParentPanicRegression(t *testing.T) { MaxStakeDuration: defaultMaxStakingDuration, RewardConfig: defaultRewardConfig, UpgradeConfig: upgrade.Config{ - BanffTime: latestForkTime, - CortinaTime: mockable.MaxTime, - DurangoTime: mockable.MaxTime, - EUpgradeTime: mockable.MaxTime, + BanffTime: latestForkTime, + CortinaTime: mockable.MaxTime, + DurangoTime: mockable.MaxTime, + EtnaTime: mockable.MaxTime, }, }} diff --git a/vms/platformvm/vm_test.go b/vms/platformvm/vm_test.go index 7c44e18c72ff..ab2bcb430463 100644 --- a/vms/platformvm/vm_test.go +++ b/vms/platformvm/vm_test.go @@ -34,6 +34,7 @@ import ( "github.com/ava-labs/avalanchego/snow/uptime" "github.com/ava-labs/avalanchego/snow/validators" "github.com/ava-labs/avalanchego/subnets" + "github.com/ava-labs/avalanchego/upgrade" "github.com/ava-labs/avalanchego/utils/constants" "github.com/ava-labs/avalanchego/utils/crypto/bls" "github.com/ava-labs/avalanchego/utils/crypto/secp256k1" @@ -58,7 +59,6 @@ import ( "github.com/ava-labs/avalanchego/vms/platformvm/txs" "github.com/ava-labs/avalanchego/vms/platformvm/txs/fee" "github.com/ava-labs/avalanchego/vms/platformvm/txs/txstest" - "github.com/ava-labs/avalanchego/vms/platformvm/upgrade" "github.com/ava-labs/avalanchego/vms/secp256k1fx" p2ppb "github.com/ava-labs/avalanchego/proto/pb/p2p" @@ -80,7 +80,7 @@ const ( banff cortina durango - eUpgrade + etna latestFork = durango @@ -213,15 +213,15 @@ func defaultVM(t *testing.T, f fork) (*VM, *txstest.WalletFactory, database.Data banffTime = mockable.MaxTime cortinaTime = mockable.MaxTime durangoTime = mockable.MaxTime - eUpgradeTime = mockable.MaxTime + etnaTime = mockable.MaxTime ) // always reset latestForkTime (a package level variable) // to ensure test independence latestForkTime = defaultGenesisTime.Add(time.Second) switch f { - case eUpgrade: - eUpgradeTime = latestForkTime + case etna: + etnaTime = latestForkTime fallthrough case durango: durangoTime = latestForkTime @@ -264,7 +264,7 @@ func defaultVM(t *testing.T, f fork) (*VM, *txstest.WalletFactory, database.Data BanffTime: banffTime, CortinaTime: cortinaTime, DurangoTime: durangoTime, - EUpgradeTime: eUpgradeTime, + EtnaTime: etnaTime, }, }} @@ -1203,10 +1203,10 @@ func TestRestartFullyAccepted(t *testing.T) { MaxStakeDuration: defaultMaxStakingDuration, RewardConfig: defaultRewardConfig, UpgradeConfig: upgrade.Config{ - BanffTime: latestForkTime, - CortinaTime: latestForkTime, - DurangoTime: latestForkTime, - EUpgradeTime: mockable.MaxTime, + BanffTime: latestForkTime, + CortinaTime: latestForkTime, + DurangoTime: latestForkTime, + EtnaTime: mockable.MaxTime, }, }} @@ -1293,10 +1293,10 @@ func TestRestartFullyAccepted(t *testing.T) { MaxStakeDuration: defaultMaxStakingDuration, RewardConfig: defaultRewardConfig, UpgradeConfig: upgrade.Config{ - BanffTime: latestForkTime, - CortinaTime: latestForkTime, - DurangoTime: latestForkTime, - EUpgradeTime: mockable.MaxTime, + BanffTime: latestForkTime, + CortinaTime: latestForkTime, + DurangoTime: latestForkTime, + EtnaTime: mockable.MaxTime, }, }} @@ -1344,10 +1344,10 @@ func TestBootstrapPartiallyAccepted(t *testing.T) { MaxStakeDuration: defaultMaxStakingDuration, RewardConfig: defaultRewardConfig, UpgradeConfig: upgrade.Config{ - BanffTime: latestForkTime, - CortinaTime: latestForkTime, - DurangoTime: latestForkTime, - EUpgradeTime: mockable.MaxTime, + BanffTime: latestForkTime, + CortinaTime: latestForkTime, + DurangoTime: latestForkTime, + EtnaTime: mockable.MaxTime, }, }} @@ -1695,10 +1695,10 @@ func TestUnverifiedParent(t *testing.T) { MaxStakeDuration: defaultMaxStakingDuration, RewardConfig: defaultRewardConfig, UpgradeConfig: upgrade.Config{ - BanffTime: latestForkTime, - CortinaTime: latestForkTime, - DurangoTime: latestForkTime, - EUpgradeTime: mockable.MaxTime, + BanffTime: latestForkTime, + CortinaTime: latestForkTime, + DurangoTime: latestForkTime, + EtnaTime: mockable.MaxTime, }, }} @@ -1858,10 +1858,10 @@ func TestUptimeDisallowedWithRestart(t *testing.T) { Validators: validators.NewManager(), UptimeLockedCalculator: uptime.NewLockedCalculator(), UpgradeConfig: upgrade.Config{ - BanffTime: latestForkTime, - CortinaTime: latestForkTime, - DurangoTime: latestForkTime, - EUpgradeTime: mockable.MaxTime, + BanffTime: latestForkTime, + CortinaTime: latestForkTime, + DurangoTime: latestForkTime, + EtnaTime: mockable.MaxTime, }, }} @@ -1909,10 +1909,10 @@ func TestUptimeDisallowedWithRestart(t *testing.T) { Validators: validators.NewManager(), UptimeLockedCalculator: uptime.NewLockedCalculator(), UpgradeConfig: upgrade.Config{ - BanffTime: latestForkTime, - CortinaTime: latestForkTime, - DurangoTime: latestForkTime, - EUpgradeTime: mockable.MaxTime, + BanffTime: latestForkTime, + CortinaTime: latestForkTime, + DurangoTime: latestForkTime, + EtnaTime: mockable.MaxTime, }, }} @@ -2011,10 +2011,10 @@ func TestUptimeDisallowedAfterNeverConnecting(t *testing.T) { Validators: validators.NewManager(), UptimeLockedCalculator: uptime.NewLockedCalculator(), UpgradeConfig: upgrade.Config{ - BanffTime: latestForkTime, - CortinaTime: latestForkTime, - DurangoTime: latestForkTime, - EUpgradeTime: mockable.MaxTime, + BanffTime: latestForkTime, + CortinaTime: latestForkTime, + DurangoTime: latestForkTime, + EtnaTime: mockable.MaxTime, }, }} diff --git a/vms/proposervm/batched_vm_test.go b/vms/proposervm/batched_vm_test.go index d3588cb7334f..dc4d8d3ac616 100644 --- a/vms/proposervm/batched_vm_test.go +++ b/vms/proposervm/batched_vm_test.go @@ -26,6 +26,7 @@ import ( "github.com/ava-labs/avalanchego/snow/snowtest" "github.com/ava-labs/avalanchego/snow/validators" "github.com/ava-labs/avalanchego/staking" + "github.com/ava-labs/avalanchego/upgrade" "github.com/ava-labs/avalanchego/utils/timer/mockable" blockbuilder "github.com/ava-labs/avalanchego/vms/proposervm/block" @@ -964,9 +965,11 @@ func initTestRemoteProposerVM( proVM := New( coreVM, Config{ - ActivationTime: activationTime, - DurangoTime: durangoTime, - MinimumPChainHeight: 0, + Upgrades: upgrade.Config{ + ApricotPhase4Time: activationTime, + ApricotPhase4MinPChainHeight: 0, + DurangoTime: durangoTime, + }, MinBlkDelay: DefaultMinBlockDelay, NumHistoricalBlocks: DefaultNumHistoricalBlocks, StakingLeafSigner: pTestSigner, diff --git a/vms/proposervm/block.go b/vms/proposervm/block.go index 6c0c2c7e14e7..8136e428e111 100644 --- a/vms/proposervm/block.go +++ b/vms/proposervm/block.go @@ -141,7 +141,7 @@ func (p *postForkCommonComponents) Verify( } var shouldHaveProposer bool - if p.vm.IsDurangoActivated(parentTimestamp) { + if p.vm.Upgrades.IsDurangoActivated(parentTimestamp) { shouldHaveProposer, err = p.verifyPostDurangoBlockDelay(ctx, parentTimestamp, parentPChainHeight, child) } else { shouldHaveProposer, err = p.verifyPreDurangoBlockDelay(ctx, parentTimestamp, parentPChainHeight, child) @@ -197,7 +197,7 @@ func (p *postForkCommonComponents) buildChild( } var shouldBuildSignedBlock bool - if p.vm.IsDurangoActivated(parentTimestamp) { + if p.vm.Upgrades.IsDurangoActivated(parentTimestamp) { shouldBuildSignedBlock, err = p.shouldBuildSignedBlockPostDurango( ctx, parentID, diff --git a/vms/proposervm/block_test.go b/vms/proposervm/block_test.go index d55a615537d0..6c04c5d13948 100644 --- a/vms/proposervm/block_test.go +++ b/vms/proposervm/block_test.go @@ -23,6 +23,7 @@ import ( "github.com/ava-labs/avalanchego/snow/engine/snowman/block" "github.com/ava-labs/avalanchego/snow/validators" "github.com/ava-labs/avalanchego/staking" + "github.com/ava-labs/avalanchego/upgrade" "github.com/ava-labs/avalanchego/utils/logging" "github.com/ava-labs/avalanchego/utils/timer/mockable" "github.com/ava-labs/avalanchego/vms/proposervm/proposer" @@ -71,8 +72,11 @@ func TestPostForkCommonComponents_buildChild(t *testing.T) { require.NoError(err) vm := &VM{ Config: Config{ - ActivationTime: time.Unix(0, 0), - DurangoTime: time.Unix(0, 0), + Upgrades: upgrade.Config{ + ApricotPhase4Time: time.Unix(0, 0), + ApricotPhase4MinPChainHeight: 0, + DurangoTime: time.Unix(0, 0), + }, StakingCertLeaf: &staking.Certificate{}, StakingLeafSigner: pk, Registerer: prometheus.NewRegistry(), @@ -384,8 +388,11 @@ func TestPostDurangoBuildChildResetScheduler(t *testing.T) { require.NoError(err) vm := &VM{ Config: Config{ - ActivationTime: time.Unix(0, 0), - DurangoTime: time.Unix(0, 0), + Upgrades: upgrade.Config{ + ApricotPhase4Time: time.Unix(0, 0), + ApricotPhase4MinPChainHeight: 0, + DurangoTime: time.Unix(0, 0), + }, StakingCertLeaf: &staking.Certificate{}, StakingLeafSigner: pk, Registerer: prometheus.NewRegistry(), diff --git a/vms/proposervm/config.go b/vms/proposervm/config.go index 296f6a60520c..ac357d568239 100644 --- a/vms/proposervm/config.go +++ b/vms/proposervm/config.go @@ -10,17 +10,11 @@ import ( "github.com/prometheus/client_golang/prometheus" "github.com/ava-labs/avalanchego/staking" + "github.com/ava-labs/avalanchego/upgrade" ) type Config struct { - // Time at which proposerVM activates its congestion control mechanism - ActivationTime time.Time - - // Durango fork activation time - DurangoTime time.Time - - // Minimal P-chain height referenced upon block building - MinimumPChainHeight uint64 + Upgrades upgrade.Config // Configurable minimal delay among blocks issued consecutively MinBlkDelay time.Duration @@ -38,7 +32,3 @@ type Config struct { // Registerer for prometheus metrics Registerer prometheus.Registerer } - -func (c *Config) IsDurangoActivated(timestamp time.Time) bool { - return !timestamp.Before(c.DurangoTime) -} diff --git a/vms/proposervm/post_fork_option_test.go b/vms/proposervm/post_fork_option_test.go index 0055fa3f50e2..3a76bc9faa06 100644 --- a/vms/proposervm/post_fork_option_test.go +++ b/vms/proposervm/post_fork_option_test.go @@ -19,6 +19,7 @@ import ( "github.com/ava-labs/avalanchego/snow/consensus/snowman/snowmantest" "github.com/ava-labs/avalanchego/snow/engine/common" "github.com/ava-labs/avalanchego/snow/snowtest" + "github.com/ava-labs/avalanchego/upgrade" "github.com/ava-labs/avalanchego/vms/proposervm/block" ) @@ -527,9 +528,11 @@ func TestOptionTimestampValidity(t *testing.T) { proVM = New( coreVM, Config{ - ActivationTime: time.Unix(0, 0), - DurangoTime: time.Unix(0, 0), - MinimumPChainHeight: 0, + Upgrades: upgrade.Config{ + ApricotPhase4Time: time.Unix(0, 0), + ApricotPhase4MinPChainHeight: 0, + DurangoTime: time.Unix(0, 0), + }, MinBlkDelay: DefaultMinBlockDelay, NumHistoricalBlocks: DefaultNumHistoricalBlocks, StakingLeafSigner: pTestSigner, diff --git a/vms/proposervm/pre_fork_block.go b/vms/proposervm/pre_fork_block.go index 6610a9f4d823..72f2a5a46a26 100644 --- a/vms/proposervm/pre_fork_block.go +++ b/vms/proposervm/pre_fork_block.go @@ -79,7 +79,7 @@ func (b *preForkBlock) getInnerBlk() snowman.Block { func (b *preForkBlock) verifyPreForkChild(ctx context.Context, child *preForkBlock) error { parentTimestamp := b.Timestamp() - if !parentTimestamp.Before(b.vm.ActivationTime) { + if b.vm.Upgrades.IsApricotPhase4Activated(parentTimestamp) { if err := verifyIsOracleBlock(ctx, b.Block); err != nil { return err } @@ -117,7 +117,7 @@ func (b *preForkBlock) verifyPostForkChild(ctx context.Context, child *postForkB currentPChainHeight, ) } - if childPChainHeight < b.vm.MinimumPChainHeight { + if childPChainHeight < b.vm.Upgrades.ApricotPhase4MinPChainHeight { return errPChainHeightTooLow } @@ -132,7 +132,7 @@ func (b *preForkBlock) verifyPostForkChild(ctx context.Context, child *postForkB // if the *preForkBlock is the last *preForkBlock before activation takes effect // (its timestamp is at or after the activation time) parentTimestamp := b.Timestamp() - if parentTimestamp.Before(b.vm.ActivationTime) { + if !b.vm.Upgrades.IsApricotPhase4Activated(parentTimestamp) { return errProposersNotActivated } @@ -163,7 +163,7 @@ func (*preForkBlock) verifyPostForkOption(context.Context, *postForkOption) erro func (b *preForkBlock) buildChild(ctx context.Context) (Block, error) { parentTimestamp := b.Timestamp() - if parentTimestamp.Before(b.vm.ActivationTime) { + if !b.vm.Upgrades.IsApricotPhase4Activated(parentTimestamp) { // The chain hasn't forked yet innerBlock, err := b.vm.ChainVM.BuildBlock(ctx) if err != nil { @@ -192,7 +192,7 @@ func (b *preForkBlock) buildChild(ctx context.Context) (Block, error) { // The child's P-Chain height is proposed as the optimal P-Chain height that // is at least the minimum height - pChainHeight, err := b.vm.optimalPChainHeight(ctx, b.vm.MinimumPChainHeight) + pChainHeight, err := b.vm.optimalPChainHeight(ctx, b.vm.Upgrades.ApricotPhase4MinPChainHeight) if err != nil { b.vm.ctx.Log.Error("unexpected build block failure", zap.String("reason", "failed to calculate optimal P-chain height"), diff --git a/vms/proposervm/pre_fork_block_test.go b/vms/proposervm/pre_fork_block_test.go index 2153a62f9e3b..b69ddd5a0d3b 100644 --- a/vms/proposervm/pre_fork_block_test.go +++ b/vms/proposervm/pre_fork_block_test.go @@ -667,7 +667,7 @@ func TestPreForkBlock_BuildBlockWithContext(t *testing.T) { // Should call BuildBlock since proposervm is not activated innerBlk.EXPECT().Timestamp().Return(time.Time{}) - vm.ActivationTime = mockable.MaxTime + vm.Upgrades.ApricotPhase4Time = mockable.MaxTime gotChild, err = blk.buildChild(context.Background()) require.NoError(err) diff --git a/vms/proposervm/state_syncable_vm_test.go b/vms/proposervm/state_syncable_vm_test.go index 2327384fc04f..5c4810f9d144 100644 --- a/vms/proposervm/state_syncable_vm_test.go +++ b/vms/proposervm/state_syncable_vm_test.go @@ -21,6 +21,7 @@ import ( "github.com/ava-labs/avalanchego/snow/engine/common" "github.com/ava-labs/avalanchego/snow/engine/snowman/block" "github.com/ava-labs/avalanchego/snow/snowtest" + "github.com/ava-labs/avalanchego/upgrade" "github.com/ava-labs/avalanchego/vms/proposervm/summary" statelessblock "github.com/ava-labs/avalanchego/vms/proposervm/block" @@ -58,9 +59,11 @@ func helperBuildStateSyncTestObjects(t *testing.T) (*fullVM, *VM) { vm := New( innerVM, Config{ - ActivationTime: time.Unix(0, 0), - DurangoTime: time.Unix(0, 0), - MinimumPChainHeight: 0, + Upgrades: upgrade.Config{ + ApricotPhase4Time: time.Unix(0, 0), + ApricotPhase4MinPChainHeight: 0, + DurangoTime: time.Unix(0, 0), + }, MinBlkDelay: DefaultMinBlockDelay, NumHistoricalBlocks: DefaultNumHistoricalBlocks, StakingLeafSigner: pTestSigner, diff --git a/vms/proposervm/vm.go b/vms/proposervm/vm.go index 8e5a45d1afcc..d0c21971c80d 100644 --- a/vms/proposervm/vm.go +++ b/vms/proposervm/vm.go @@ -328,7 +328,7 @@ func (vm *VM) SetPreference(ctx context.Context, preferred ids.ID) error { parentTimestamp = blk.Timestamp() nextStartTime time.Time ) - if vm.IsDurangoActivated(parentTimestamp) { + if vm.Upgrades.IsDurangoActivated(parentTimestamp) { currentTime := vm.Clock.Time().Truncate(time.Second) if nextStartTime, err = vm.getPostDurangoSlotTime( ctx, diff --git a/vms/proposervm/vm_test.go b/vms/proposervm/vm_test.go index 1fe2c225a5e1..c6c10056eb56 100644 --- a/vms/proposervm/vm_test.go +++ b/vms/proposervm/vm_test.go @@ -28,6 +28,7 @@ import ( "github.com/ava-labs/avalanchego/snow/snowtest" "github.com/ava-labs/avalanchego/snow/validators" "github.com/ava-labs/avalanchego/staking" + "github.com/ava-labs/avalanchego/upgrade" "github.com/ava-labs/avalanchego/utils" "github.com/ava-labs/avalanchego/utils/logging" "github.com/ava-labs/avalanchego/utils/timer/mockable" @@ -125,9 +126,11 @@ func initTestProposerVM( proVM := New( coreVM, Config{ - ActivationTime: proBlkStartTime, - DurangoTime: durangoTime, - MinimumPChainHeight: minPChainHeight, + Upgrades: upgrade.Config{ + ApricotPhase4Time: proBlkStartTime, + ApricotPhase4MinPChainHeight: minPChainHeight, + DurangoTime: durangoTime, + }, MinBlkDelay: DefaultMinBlockDelay, NumHistoricalBlocks: DefaultNumHistoricalBlocks, StakingLeafSigner: pTestSigner, @@ -802,9 +805,11 @@ func TestExpiredBuildBlock(t *testing.T) { proVM := New( coreVM, Config{ - ActivationTime: time.Time{}, - DurangoTime: mockable.MaxTime, - MinimumPChainHeight: 0, + Upgrades: upgrade.Config{ + ApricotPhase4Time: time.Time{}, + ApricotPhase4MinPChainHeight: 0, + DurangoTime: mockable.MaxTime, + }, MinBlkDelay: DefaultMinBlockDelay, NumHistoricalBlocks: DefaultNumHistoricalBlocks, StakingLeafSigner: pTestSigner, @@ -1120,9 +1125,11 @@ func TestInnerVMRollback(t *testing.T) { proVM := New( coreVM, Config{ - ActivationTime: time.Time{}, - DurangoTime: mockable.MaxTime, - MinimumPChainHeight: 0, + Upgrades: upgrade.Config{ + ApricotPhase4Time: time.Time{}, + ApricotPhase4MinPChainHeight: 0, + DurangoTime: mockable.MaxTime, + }, MinBlkDelay: DefaultMinBlockDelay, NumHistoricalBlocks: DefaultNumHistoricalBlocks, StakingLeafSigner: pTestSigner, @@ -1200,9 +1207,11 @@ func TestInnerVMRollback(t *testing.T) { proVM = New( coreVM, Config{ - ActivationTime: time.Time{}, - DurangoTime: mockable.MaxTime, - MinimumPChainHeight: 0, + Upgrades: upgrade.Config{ + ApricotPhase4Time: time.Time{}, + ApricotPhase4MinPChainHeight: 0, + DurangoTime: mockable.MaxTime, + }, MinBlkDelay: DefaultMinBlockDelay, NumHistoricalBlocks: DefaultNumHistoricalBlocks, StakingLeafSigner: pTestSigner, @@ -1588,9 +1597,11 @@ func TestRejectedHeightNotIndexed(t *testing.T) { proVM := New( coreVM, Config{ - ActivationTime: time.Unix(0, 0), - DurangoTime: time.Unix(0, 0), - MinimumPChainHeight: 0, + Upgrades: upgrade.Config{ + ApricotPhase4Time: time.Unix(0, 0), + ApricotPhase4MinPChainHeight: 0, + DurangoTime: time.Unix(0, 0), + }, MinBlkDelay: DefaultMinBlockDelay, NumHistoricalBlocks: DefaultNumHistoricalBlocks, StakingLeafSigner: pTestSigner, @@ -1759,9 +1770,11 @@ func TestRejectedOptionHeightNotIndexed(t *testing.T) { proVM := New( coreVM, Config{ - ActivationTime: time.Unix(0, 0), - DurangoTime: time.Unix(0, 0), - MinimumPChainHeight: 0, + Upgrades: upgrade.Config{ + ApricotPhase4Time: time.Unix(0, 0), + ApricotPhase4MinPChainHeight: 0, + DurangoTime: time.Unix(0, 0), + }, MinBlkDelay: DefaultMinBlockDelay, NumHistoricalBlocks: DefaultNumHistoricalBlocks, StakingLeafSigner: pTestSigner, @@ -1894,9 +1907,11 @@ func TestVMInnerBlkCache(t *testing.T) { vm := New( innerVM, Config{ - ActivationTime: time.Unix(0, 0), - DurangoTime: time.Unix(0, 0), - MinimumPChainHeight: 0, + Upgrades: upgrade.Config{ + ApricotPhase4Time: time.Unix(0, 0), + ApricotPhase4MinPChainHeight: 0, + DurangoTime: time.Unix(0, 0), + }, MinBlkDelay: DefaultMinBlockDelay, NumHistoricalBlocks: DefaultNumHistoricalBlocks, StakingLeafSigner: pTestSigner, @@ -2004,9 +2019,11 @@ func TestVM_VerifyBlockWithContext(t *testing.T) { vm := New( innerVM, Config{ - ActivationTime: time.Unix(0, 0), - DurangoTime: time.Unix(0, 0), - MinimumPChainHeight: 0, + Upgrades: upgrade.Config{ + ApricotPhase4Time: time.Unix(0, 0), + ApricotPhase4MinPChainHeight: 0, + DurangoTime: time.Unix(0, 0), + }, MinBlkDelay: DefaultMinBlockDelay, NumHistoricalBlocks: DefaultNumHistoricalBlocks, StakingLeafSigner: pTestSigner, @@ -2206,9 +2223,11 @@ func TestHistoricalBlockDeletion(t *testing.T) { proVM := New( coreVM, Config{ - ActivationTime: time.Unix(0, 0), - DurangoTime: mockable.MaxTime, - MinimumPChainHeight: 0, + Upgrades: upgrade.Config{ + ApricotPhase4Time: time.Unix(0, 0), + ApricotPhase4MinPChainHeight: 0, + DurangoTime: mockable.MaxTime, + }, MinBlkDelay: DefaultMinBlockDelay, NumHistoricalBlocks: DefaultNumHistoricalBlocks, StakingLeafSigner: pTestSigner, @@ -2298,9 +2317,11 @@ func TestHistoricalBlockDeletion(t *testing.T) { proVM = New( coreVM, Config{ - ActivationTime: time.Time{}, - DurangoTime: mockable.MaxTime, - MinimumPChainHeight: 0, + Upgrades: upgrade.Config{ + ApricotPhase4Time: time.Time{}, + ApricotPhase4MinPChainHeight: 0, + DurangoTime: mockable.MaxTime, + }, MinBlkDelay: DefaultMinBlockDelay, NumHistoricalBlocks: numHistoricalBlocks, StakingLeafSigner: pTestSigner, @@ -2343,9 +2364,11 @@ func TestHistoricalBlockDeletion(t *testing.T) { proVM = New( coreVM, Config{ - ActivationTime: time.Time{}, - DurangoTime: mockable.MaxTime, - MinimumPChainHeight: 0, + Upgrades: upgrade.Config{ + ApricotPhase4Time: time.Time{}, + ApricotPhase4MinPChainHeight: 0, + DurangoTime: mockable.MaxTime, + }, MinBlkDelay: DefaultMinBlockDelay, NumHistoricalBlocks: newNumHistoricalBlocks, StakingLeafSigner: pTestSigner,