From 010570d3b7aa20889fb5ad0e5b23800aa33f5634 Mon Sep 17 00:00:00 2001 From: Vineeth Kashyap Date: Mon, 25 Nov 2024 20:33:27 -0500 Subject: [PATCH] Fix units in timed feature flags (#15391) (cherry picked from commit 4d4c200f854db1c223714e49a531b8606e3b73f5) --- .../aptos-vm-environment/src/environment.rs | 6 +- crates/aptos/src/node/mod.rs | 2 +- types/src/on_chain_config/mod.rs | 4 +- types/src/on_chain_config/timed_features.rs | 116 +++++++++++++++--- 4 files changed, 106 insertions(+), 22 deletions(-) diff --git a/aptos-move/aptos-vm-environment/src/environment.rs b/aptos-move/aptos-vm-environment/src/environment.rs index debdd654c92ac..0d3474ab64e96 100644 --- a/aptos-move/aptos-vm-environment/src/environment.rs +++ b/aptos-move/aptos-vm-environment/src/environment.rs @@ -181,12 +181,12 @@ impl Environment { // If no chain ID is in storage, we assume we are in a testing environment. let chain_id = fetch_config_and_update_hash::(&mut sha3_256, state_view) .unwrap_or_else(ChainId::test); - let timestamp = + let timestamp_micros = fetch_config_and_update_hash::(&mut sha3_256, state_view) - .map(|config| config.last_reconfiguration_time()) + .map(|config| config.last_reconfiguration_time_micros()) .unwrap_or(0); - let mut timed_features_builder = TimedFeaturesBuilder::new(chain_id, timestamp); + let mut timed_features_builder = TimedFeaturesBuilder::new(chain_id, timestamp_micros); if let Some(profile) = get_timed_feature_override() { // We need to ensure the override is taken into account for the hash. let profile_bytes = bcs::to_bytes(&profile) diff --git a/crates/aptos/src/node/mod.rs b/crates/aptos/src/node/mod.rs index c9fe8c9a1bacf..e062e721cc94a 100644 --- a/crates/aptos/src/node/mod.rs +++ b/crates/aptos/src/node/mod.rs @@ -1443,7 +1443,7 @@ async fn get_epoch_info(client: &Client) -> CliTypedResult { let epoch_interval = block_resource.epoch_interval(); let epoch_interval_secs = epoch_interval / SECS_TO_MICROSECS; - let last_reconfig = reconfig_resource.last_reconfiguration_time(); + let last_reconfig = reconfig_resource.last_reconfiguration_time_micros(); Ok(EpochInfo { epoch: reconfig_resource.epoch(), epoch_interval_secs, diff --git a/types/src/on_chain_config/mod.rs b/types/src/on_chain_config/mod.rs index 03b5c5f2a409a..4a1bd1d9c023f 100644 --- a/types/src/on_chain_config/mod.rs +++ b/types/src/on_chain_config/mod.rs @@ -238,6 +238,7 @@ pub fn struct_tag_for_config(config_id: ConfigID) -> StructTag { #[derive(Debug, Deserialize, Serialize)] pub struct ConfigurationResource { epoch: u64, + /// Unix epoch timestamp (in microseconds) of the last reconfiguration time. last_reconfiguration_time: u64, events: EventHandle, } @@ -247,7 +248,8 @@ impl ConfigurationResource { self.epoch } - pub fn last_reconfiguration_time(&self) -> u64 { + /// Return the last Unix epoch timestamp (in microseconds) of the last reconfiguration time. + pub fn last_reconfiguration_time_micros(&self) -> u64 { self.last_reconfiguration_time } diff --git a/types/src/on_chain_config/timed_features.rs b/types/src/on_chain_config/timed_features.rs index ea7cafa68a7b9..aa590a7026db8 100644 --- a/types/src/on_chain_config/timed_features.rs +++ b/types/src/on_chain_config/timed_features.rs @@ -6,10 +6,6 @@ use serde::Serialize; use strum::{EnumCount, IntoEnumIterator}; use strum_macros::{EnumCount as EnumCountMacro, EnumIter}; -// A placeholder that can be used to represent activation times that have not been determined. -const NOT_YET_SPECIFIED: u64 = END_OF_TIME; /* Thursday, December 31, 2099 11:59:59 PM */ - -pub const END_OF_TIME: u64 = 4102444799000; /* Thursday, December 31, 2099 11:59:59 PM */ #[derive(Debug, EnumCountMacro, EnumIter, Clone, Copy, Eq, PartialEq)] pub enum TimedFeatureFlag { DisableInvariantViolationCheckInSwapLoc, @@ -23,7 +19,8 @@ pub enum TimedFeatureFlag { enum TimedFeaturesImpl { OnNamedChain { named_chain: NamedChain, - timestamp: u64, + // Unix Epoch timestamp in microseconds. + timestamp_micros: u64, }, EnableAll, } @@ -44,7 +41,6 @@ impl TimedFeatureOverride { Replay => match flag { LimitTypeTagSize => true, ModuleComplexityCheck => true, - EntryCompatibility => true, // Add overrides for replay here. _ => return None, }, @@ -57,19 +53,22 @@ impl TimedFeatureOverride { } impl TimedFeatureFlag { - pub const fn activation_time_on(&self, chain_id: &NamedChain) -> u64 { + /// Returns the activation time of the feature on the given chain. + /// The time is specified as a Unix Epoch timestamp in microseconds. + pub const fn activation_time_micros_on(&self, chain_id: &NamedChain) -> u64 { use NamedChain::*; use TimedFeatureFlag::*; match (self, chain_id) { - (DisableInvariantViolationCheckInSwapLoc, TESTNET) => NOT_YET_SPECIFIED, - (DisableInvariantViolationCheckInSwapLoc, MAINNET) => NOT_YET_SPECIFIED, + // Enabled from the beginning of time. + (DisableInvariantViolationCheckInSwapLoc, TESTNET) => 0, + (DisableInvariantViolationCheckInSwapLoc, MAINNET) => 0, - (ModuleComplexityCheck, TESTNET) => 1719356400000, /* Tuesday, June 21, 2024 16:00:00 AM GMT-07:00 */ - (ModuleComplexityCheck, MAINNET) => 1720033200000, /* Wednesday, July 3, 2024 12:00:00 AM GMT-07:00 */ + (ModuleComplexityCheck, TESTNET) => 1_719_356_400_000_000, /* Tuesday, June 21, 2024 16:00:00 AM GMT-07:00 */ + (ModuleComplexityCheck, MAINNET) => 1_720_033_200_000_000, /* Wednesday, July 3, 2024 12:00:00 AM GMT-07:00 */ - (EntryCompatibility, TESTNET) => 1730923200000, /* Wednesday, Nov 6, 2024 12:00:00 AM GMT-07:00 */ - (EntryCompatibility, MAINNET) => 1731441600000, /* Tuesday, Nov 12, 2024 12:00:00 AM GMT-07:00 */ + (EntryCompatibility, TESTNET) => 1_730_923_200_000_000, /* Wednesday, Nov 6, 2024 12:00:00 AM GMT-07:00 */ + (EntryCompatibility, MAINNET) => 1_731_441_600_000_000, /* Tuesday, Nov 12, 2024 12:00:00 AM GMT-07:00 */ // If unspecified, a timed feature is considered enabled from the very beginning of time. _ => 0, @@ -84,11 +83,12 @@ pub struct TimedFeaturesBuilder { } impl TimedFeaturesBuilder { - pub fn new(chain_id: ChainId, timestamp: u64) -> Self { + /// `timestamp_micros` is a Unix Epoch timestamp in microseconds. + pub fn new(chain_id: ChainId, timestamp_micros: u64) -> Self { let inner = match NamedChain::from_chain_id(&chain_id) { Ok(named_chain) => TimedFeaturesImpl::OnNamedChain { named_chain, - timestamp, + timestamp_micros, }, Err(_) => TimedFeaturesImpl::EnableAll, // Unknown chain => enable all features by default. }; @@ -125,8 +125,8 @@ impl TimedFeaturesBuilder { match &self.inner { OnNamedChain { named_chain, - timestamp, - } => *timestamp >= flag.activation_time_on(named_chain), + timestamp_micros, + } => *timestamp_micros >= flag.activation_time_micros_on(named_chain), EnableAll => true, } } @@ -161,4 +161,86 @@ mod test { let testing = assert_ok!(bcs::to_bytes(&TimedFeatureOverride::Testing)); assert_ne!(replay, testing); } + + #[test] + fn test_timed_features_activation() { + use TimedFeatureFlag::*; + // Monday, Jan 01, 2024 12:00:00.000 AM GMT + let jan_1_2024_micros: u64 = 1_704_067_200_000_000; + // Friday, November 15, 2024 12:00:00 AM GMT + let nov_15_2024_micros: u64 = 1_731_628_800_000_000; + + // Check testnet on Jan 1, 2024. + let testnet_jan_1_2024 = TimedFeaturesBuilder::new(ChainId::testnet(), jan_1_2024_micros); + assert!( + testnet_jan_1_2024.is_enabled(DisableInvariantViolationCheckInSwapLoc), + "DisableInvariantViolationCheckInSwapLoc should always be enabled" + ); + assert!( + testnet_jan_1_2024.is_enabled(LimitTypeTagSize), + "LimitTypeTagSize should always be enabled" + ); + assert!( + !testnet_jan_1_2024.is_enabled(ModuleComplexityCheck), + "ModuleComplexityCheck should be disabled on Jan 1, 2024 on testnet" + ); + assert!( + !testnet_jan_1_2024.is_enabled(EntryCompatibility), + "EntryCompatibility should be disabled on Jan 1, 2024 on testnet" + ); + // Check testnet on Nov 15, 2024. + let testnet_nov_15_2024 = TimedFeaturesBuilder::new(ChainId::testnet(), nov_15_2024_micros); + assert!( + testnet_nov_15_2024.is_enabled(DisableInvariantViolationCheckInSwapLoc), + "DisableInvariantViolationCheckInSwapLoc should always be enabled" + ); + assert!( + testnet_nov_15_2024.is_enabled(LimitTypeTagSize), + "LimitTypeTagSize should always be enabled" + ); + assert!( + testnet_nov_15_2024.is_enabled(ModuleComplexityCheck), + "ModuleComplexityCheck should be enabled on Nov 15, 2024 on testnet" + ); + assert!( + testnet_nov_15_2024.is_enabled(EntryCompatibility), + "EntryCompatibility should be enabled on Nov 15, 2024 on testnet" + ); + // Check mainnet on Jan 1, 2024. + let mainnet_jan_1_2024 = TimedFeaturesBuilder::new(ChainId::mainnet(), jan_1_2024_micros); + assert!( + mainnet_jan_1_2024.is_enabled(DisableInvariantViolationCheckInSwapLoc), + "DisableInvariantViolationCheckInSwapLoc should always be enabled" + ); + assert!( + mainnet_jan_1_2024.is_enabled(LimitTypeTagSize), + "LimitTypeTagSize should always be enabled" + ); + assert!( + !mainnet_jan_1_2024.is_enabled(ModuleComplexityCheck), + "ModuleComplexityCheck should be disabled on Jan 1, 2024 on mainnet" + ); + assert!( + !mainnet_jan_1_2024.is_enabled(EntryCompatibility), + "EntryCompatibility should be disabled on Jan 1, 2024 on mainnet" + ); + // Check mainnet on Nov 15, 2024. + let mainnet_nov_15_2024 = TimedFeaturesBuilder::new(ChainId::mainnet(), nov_15_2024_micros); + assert!( + mainnet_nov_15_2024.is_enabled(DisableInvariantViolationCheckInSwapLoc), + "DisableInvariantViolationCheckInSwapLoc should always be enabled" + ); + assert!( + mainnet_nov_15_2024.is_enabled(LimitTypeTagSize), + "LimitTypeTagSize should always be enabled" + ); + assert!( + mainnet_nov_15_2024.is_enabled(ModuleComplexityCheck), + "ModuleComplexityCheck should be enabled on Nov 15, 2024 on mainnet" + ); + assert!( + mainnet_nov_15_2024.is_enabled(EntryCompatibility), + "EntryCompatibility should be enabled on Nov 15, 2024 on mainnet" + ); + } }