Add feature to increase timestamp bounding on the slow side to 150% of poh estimate (1s/slot) (#25666)

This commit is contained in:
Tyera Eulberg 2022-05-31 16:53:06 -06:00 committed by GitHub
parent 897e97a305
commit 8584a3a331
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 92 additions and 30 deletions

View File

@ -61,6 +61,7 @@ use {
stake_weighted_timestamp::{
calculate_stake_weighted_timestamp, MaxAllowableDrift, MAX_ALLOWABLE_DRIFT_PERCENTAGE,
MAX_ALLOWABLE_DRIFT_PERCENTAGE_FAST, MAX_ALLOWABLE_DRIFT_PERCENTAGE_SLOW,
MAX_ALLOWABLE_DRIFT_PERCENTAGE_SLOW_V2,
},
stakes::{InvalidCacheEntryReason, Stakes, StakesCache, StakesEnum},
status_cache::{SlotDelta, StatusCache},
@ -2418,10 +2419,15 @@ impl Bank {
fn update_clock(&self, parent_epoch: Option<Epoch>) {
let mut unix_timestamp = self.clock().unix_timestamp;
let warp_timestamp_again = self
let warp_timestamp = self
.feature_set
.activated_slot(&feature_set::warp_timestamp_again::id());
let epoch_start_timestamp = if warp_timestamp_again == Some(self.slot()) {
.activated_slot(&feature_set::warp_timestamp_again::id())
== Some(self.slot())
|| self
.feature_set
.activated_slot(&feature_set::warp_timestamp_with_a_vengeance::id())
== Some(self.slot());
let epoch_start_timestamp = if warp_timestamp {
None
} else {
let epoch = if let Some(epoch) = parent_epoch {
@ -2433,6 +2439,14 @@ impl Bank {
Some((first_slot_in_epoch, self.clock().epoch_start_timestamp))
};
let max_allowable_drift = if self
.feature_set
.is_active(&feature_set::warp_timestamp_with_a_vengeance::id())
{
MaxAllowableDrift {
fast: MAX_ALLOWABLE_DRIFT_PERCENTAGE_FAST,
slow: MAX_ALLOWABLE_DRIFT_PERCENTAGE_SLOW_V2,
}
} else if self
.feature_set
.is_active(&feature_set::warp_timestamp_again::id())
{
@ -14950,30 +14964,27 @@ pub(crate) mod tests {
* Duration::from_nanos(bank.ns_per_slot as u64)
}
#[test]
fn test_warp_timestamp_again_feature_slow() {
fn test_warp_timestamp_activation(
mut genesis_config: GenesisConfig,
voting_keypair: Keypair,
feature_id: &Pubkey,
max_allowable_drift_slow_before: u32,
max_allowable_drift_slow_after: u32,
) {
fn max_allowable_delta_since_epoch(bank: &Bank, max_allowable_drift: u32) -> i64 {
let poh_estimate_offset = poh_estimate_offset(bank);
(poh_estimate_offset.as_secs()
+ (poh_estimate_offset * max_allowable_drift / 100).as_secs()) as i64
}
let leader_pubkey = solana_sdk::pubkey::new_rand();
let GenesisConfigInfo {
mut genesis_config,
voting_keypair,
..
} = create_genesis_config_with_leader(5, &leader_pubkey, 3);
let slots_in_epoch = 32;
genesis_config
.accounts
.remove(&feature_set::warp_timestamp_again::id())
.unwrap();
genesis_config.epoch_schedule = EpochSchedule::new(slots_in_epoch);
let mut bank = Bank::new_for_tests(&genesis_config);
let slot_duration = Duration::from_nanos(bank.ns_per_slot as u64);
let recent_timestamp: UnixTimestamp = bank.unix_timestamp_from_genesis();
let additional_secs = 8; // Greater than MAX_ALLOWABLE_DRIFT_PERCENTAGE for full epoch
let additional_secs =
((slot_duration * max_allowable_drift_slow_before * 32) / 100).as_secs() as i64 + 1; // Greater than max_allowable_drift_slow_before for full epoch
update_vote_account_timestamp(
BlockTimestamp {
slot: bank.slot(),
@ -14983,24 +14994,21 @@ pub(crate) mod tests {
&voting_keypair.pubkey(),
);
// additional_secs greater than MAX_ALLOWABLE_DRIFT_PERCENTAGE for an epoch
// timestamp bounded to 50% deviation
// additional_secs greater than max_allowable_drift_slow_after for an epoch
// timestamp bounded to max_allowable_drift_slow_before deviation
for _ in 0..31 {
bank = new_from_parent(&Arc::new(bank));
assert_eq!(
bank.clock().unix_timestamp,
bank.clock().epoch_start_timestamp
+ max_allowable_delta_since_epoch(&bank, MAX_ALLOWABLE_DRIFT_PERCENTAGE),
+ max_allowable_delta_since_epoch(&bank, max_allowable_drift_slow_before),
);
assert_eq!(bank.clock().epoch_start_timestamp, recent_timestamp);
}
// Request `warp_timestamp_again` activation
let feature = Feature { activated_at: None };
bank.store_account(
&feature_set::warp_timestamp_again::id(),
&feature::create_account(&feature, 42),
);
bank.store_account(feature_id, &feature::create_account(&feature, 42));
let previous_epoch_timestamp = bank.clock().epoch_start_timestamp;
let previous_timestamp = bank.clock().unix_timestamp;
@ -15010,12 +15018,13 @@ pub(crate) mod tests {
assert!(
bank.clock().epoch_start_timestamp
> previous_epoch_timestamp
+ max_allowable_delta_since_epoch(&bank, MAX_ALLOWABLE_DRIFT_PERCENTAGE)
+ max_allowable_delta_since_epoch(&bank, max_allowable_drift_slow_before)
);
// Refresh vote timestamp
let recent_timestamp: UnixTimestamp = bank.clock().unix_timestamp;
let additional_secs = 8;
let additional_secs =
((slot_duration * max_allowable_drift_slow_after * 24) / 100).as_secs() as i64 + 1; // Greater than max_allowable_drift_slow_before for full epoch
update_vote_account_timestamp(
BlockTimestamp {
slot: bank.slot(),
@ -15025,14 +15034,13 @@ pub(crate) mod tests {
&voting_keypair.pubkey(),
);
// additional_secs greater than MAX_ALLOWABLE_DRIFT_PERCENTAGE for 22 slots
// timestamp bounded to 80% deviation
// additional_secs greater than max_allowable_drift_slow_after for 24 slots timestamp bounded
for _ in 0..23 {
bank = new_from_parent(&Arc::new(bank));
assert_eq!(
bank.clock().unix_timestamp,
bank.clock().epoch_start_timestamp
+ max_allowable_delta_since_epoch(&bank, MAX_ALLOWABLE_DRIFT_PERCENTAGE_SLOW),
+ max_allowable_delta_since_epoch(&bank, max_allowable_drift_slow_after),
);
assert_eq!(bank.clock().epoch_start_timestamp, recent_timestamp);
}
@ -15048,6 +15056,54 @@ pub(crate) mod tests {
}
}
#[test]
fn test_warp_timestamp_again_feature_slow() {
let leader_pubkey = solana_sdk::pubkey::new_rand();
let GenesisConfigInfo {
mut genesis_config,
voting_keypair,
..
} = create_genesis_config_with_leader(5, &leader_pubkey, 3);
genesis_config
.accounts
.remove(&feature_set::warp_timestamp_again::id())
.unwrap();
genesis_config
.accounts
.remove(&feature_set::warp_timestamp_with_a_vengeance::id())
.unwrap();
test_warp_timestamp_activation(
genesis_config,
voting_keypair,
&feature_set::warp_timestamp_again::id(),
MAX_ALLOWABLE_DRIFT_PERCENTAGE,
MAX_ALLOWABLE_DRIFT_PERCENTAGE_SLOW,
);
}
#[test]
fn test_warp_timestamp_with_a_vengeance() {
let leader_pubkey = solana_sdk::pubkey::new_rand();
let GenesisConfigInfo {
mut genesis_config,
voting_keypair,
..
} = create_genesis_config_with_leader(5, &leader_pubkey, 3);
genesis_config
.accounts
.remove(&feature_set::warp_timestamp_with_a_vengeance::id())
.unwrap();
test_warp_timestamp_activation(
genesis_config,
voting_keypair,
&feature_set::warp_timestamp_with_a_vengeance::id(),
MAX_ALLOWABLE_DRIFT_PERCENTAGE_SLOW,
MAX_ALLOWABLE_DRIFT_PERCENTAGE_SLOW_V2,
);
}
#[test]
fn test_timestamp_fast() {
fn max_allowable_delta_since_epoch(bank: &Bank, max_allowable_drift: u32) -> i64 {

View File

@ -13,6 +13,7 @@ use std::{
pub(crate) const MAX_ALLOWABLE_DRIFT_PERCENTAGE: u32 = 50;
pub(crate) const MAX_ALLOWABLE_DRIFT_PERCENTAGE_FAST: u32 = 25;
pub(crate) const MAX_ALLOWABLE_DRIFT_PERCENTAGE_SLOW: u32 = 80;
pub(crate) const MAX_ALLOWABLE_DRIFT_PERCENTAGE_SLOW_V2: u32 = 150;
#[derive(Copy, Clone)]
pub(crate) struct MaxAllowableDrift {
@ -80,7 +81,7 @@ where
&& estimate_offset.saturating_sub(poh_estimate_offset) > max_allowable_drift_slow
{
// estimate offset since the start of the epoch is higher than
// `MAX_ALLOWABLE_DRIFT_PERCENTAGE_SLOW`
// `max_allowable_drift_slow`
estimate = epoch_start_timestamp
.saturating_add(poh_estimate_offset.as_secs() as i64)
.saturating_add(max_allowable_drift_slow.as_secs() as i64);
@ -88,7 +89,7 @@ where
&& poh_estimate_offset.saturating_sub(estimate_offset) > max_allowable_drift_fast
{
// estimate offset since the start of the epoch is lower than
// `MAX_ALLOWABLE_DRIFT_PERCENTAGE_FAST`
// `max_allowable_drift_fast`
estimate = epoch_start_timestamp
.saturating_add(poh_estimate_offset.as_secs() as i64)
.saturating_sub(max_allowable_drift_fast.as_secs() as i64);

View File

@ -412,6 +412,10 @@ pub mod add_shred_type_to_shred_seed {
solana_sdk::declare_id!("Ds87KVeqhbv7Jw8W6avsS1mqz3Mw5J3pRTpPoDQ2QdiJ");
}
pub mod warp_timestamp_with_a_vengeance {
solana_sdk::declare_id!("3BX6SBeEBibHaVQXywdkcgyUk6evfYZkHdztXiDtEpFS");
}
lazy_static! {
/// Map of feature identifiers to user-visible description
pub static ref FEATURE_NAMES: HashMap<Pubkey, &'static str> = [
@ -508,6 +512,7 @@ lazy_static! {
(disable_deploy_of_alloc_free_syscall::id(), "disable new deployments of deprecated sol_alloc_free_ syscall"),
(include_account_index_in_rent_error::id(), "include account index in rent tx error #25190"),
(add_shred_type_to_shred_seed::id(), "add shred-type to shred seed #25556"),
(warp_timestamp_with_a_vengeance::id(), "warp timestamp again, adjust bounding to 150% slow #25666"),
/*************** ADD NEW FEATURES HERE ***************/
]
.iter()