Fix timestamp handling on ledger warp (#14210)
* Reset timestamp for slot and epoch-start on warp * Fix genesis timestamp metric source * Remove check that timestamp > unix_timestamp_from_genesis Default to previous timestamp, not genesis timestamp * Move timestamp metrics to report even on warp * Initialize slot 0 timestamps correctly * Add feature gate to warp testnet timestamp * Review suggestion: simplify warp-timestamp slot check
This commit is contained in:
@ -1075,10 +1075,22 @@ impl Bank {
|
|||||||
/// * Adjusts the new bank's tick height to avoid having to run PoH for millions of slots
|
/// * Adjusts the new bank's tick height to avoid having to run PoH for millions of slots
|
||||||
/// * Freezes the new bank, assuming that the user will `Bank::new_from_parent` from this bank
|
/// * Freezes the new bank, assuming that the user will `Bank::new_from_parent` from this bank
|
||||||
pub fn warp_from_parent(parent: &Arc<Bank>, collector_id: &Pubkey, slot: Slot) -> Self {
|
pub fn warp_from_parent(parent: &Arc<Bank>, collector_id: &Pubkey, slot: Slot) -> Self {
|
||||||
|
let parent_timestamp = parent.clock().unix_timestamp;
|
||||||
let mut new = Bank::new_from_parent(parent, collector_id, slot);
|
let mut new = Bank::new_from_parent(parent, collector_id, slot);
|
||||||
new.apply_feature_activations(true);
|
new.apply_feature_activations(true);
|
||||||
new.update_epoch_stakes(new.epoch_schedule().get_epoch(slot));
|
new.update_epoch_stakes(new.epoch_schedule().get_epoch(slot));
|
||||||
new.tick_height.store(new.max_tick_height(), Relaxed);
|
new.tick_height.store(new.max_tick_height(), Relaxed);
|
||||||
|
|
||||||
|
let mut clock = new.clock();
|
||||||
|
clock.epoch_start_timestamp = parent_timestamp;
|
||||||
|
clock.unix_timestamp = parent_timestamp;
|
||||||
|
new.update_sysvar_account(&sysvar::clock::id(), |account| {
|
||||||
|
create_account(
|
||||||
|
&clock,
|
||||||
|
new.inherit_specially_retained_account_balance(account),
|
||||||
|
)
|
||||||
|
});
|
||||||
|
|
||||||
new.freeze();
|
new.freeze();
|
||||||
new
|
new
|
||||||
}
|
}
|
||||||
@ -1310,6 +1322,7 @@ impl Bank {
|
|||||||
.feature_set
|
.feature_set
|
||||||
.is_active(&feature_set::timestamp_correction::id())
|
.is_active(&feature_set::timestamp_correction::id())
|
||||||
{
|
{
|
||||||
|
unix_timestamp = self.clock().unix_timestamp;
|
||||||
let (estimate_type, epoch_start_timestamp) =
|
let (estimate_type, epoch_start_timestamp) =
|
||||||
if let Some(timestamp_bounding_activation_slot) = self
|
if let Some(timestamp_bounding_activation_slot) = self
|
||||||
.feature_set
|
.feature_set
|
||||||
@ -1319,14 +1332,23 @@ impl Bank {
|
|||||||
// needed for timestamp bounding, but isn't yet corrected for the activation slot
|
// needed for timestamp bounding, but isn't yet corrected for the activation slot
|
||||||
let epoch_start_timestamp = if self.slot() > timestamp_bounding_activation_slot
|
let epoch_start_timestamp = if self.slot() > timestamp_bounding_activation_slot
|
||||||
{
|
{
|
||||||
let epoch = if let Some(epoch) = parent_epoch {
|
let warp_testnet_timestamp = self
|
||||||
epoch
|
.feature_set
|
||||||
|
.activated_slot(&feature_set::warp_testnet_timestamp::id());
|
||||||
|
if warp_testnet_timestamp == Some(self.slot())
|
||||||
|
&& self.cluster_type() == ClusterType::Testnet
|
||||||
|
{
|
||||||
|
None
|
||||||
} else {
|
} else {
|
||||||
self.epoch()
|
let epoch = if let Some(epoch) = parent_epoch {
|
||||||
};
|
epoch
|
||||||
let first_slot_in_epoch =
|
} else {
|
||||||
self.epoch_schedule.get_first_slot_in_epoch(epoch);
|
self.epoch()
|
||||||
Some((first_slot_in_epoch, self.clock().epoch_start_timestamp))
|
};
|
||||||
|
let first_slot_in_epoch =
|
||||||
|
self.epoch_schedule.get_first_slot_in_epoch(epoch);
|
||||||
|
Some((first_slot_in_epoch, self.clock().epoch_start_timestamp))
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
None
|
None
|
||||||
};
|
};
|
||||||
@ -1334,30 +1356,29 @@ impl Bank {
|
|||||||
} else {
|
} else {
|
||||||
(EstimateType::Unbounded, None)
|
(EstimateType::Unbounded, None)
|
||||||
};
|
};
|
||||||
|
|
||||||
|
let ancestor_timestamp = self.clock().unix_timestamp;
|
||||||
if let Some(timestamp_estimate) =
|
if let Some(timestamp_estimate) =
|
||||||
self.get_timestamp_estimate(estimate_type, epoch_start_timestamp)
|
self.get_timestamp_estimate(estimate_type, epoch_start_timestamp)
|
||||||
{
|
{
|
||||||
if timestamp_estimate > unix_timestamp {
|
unix_timestamp = timestamp_estimate;
|
||||||
unix_timestamp = timestamp_estimate;
|
if self
|
||||||
let ancestor_timestamp = self.clock().unix_timestamp;
|
.feature_set
|
||||||
if self
|
.is_active(&feature_set::timestamp_bounding::id())
|
||||||
.feature_set
|
&& timestamp_estimate < ancestor_timestamp
|
||||||
.is_active(&feature_set::timestamp_bounding::id())
|
{
|
||||||
&& timestamp_estimate < ancestor_timestamp
|
unix_timestamp = ancestor_timestamp;
|
||||||
{
|
|
||||||
unix_timestamp = ancestor_timestamp;
|
|
||||||
}
|
|
||||||
datapoint_info!(
|
|
||||||
"bank-timestamp-correction",
|
|
||||||
("slot", self.slot(), i64),
|
|
||||||
("from_genesis", unix_timestamp, i64),
|
|
||||||
("corrected", timestamp_estimate, i64),
|
|
||||||
("ancestor_timestamp", ancestor_timestamp, i64),
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
datapoint_info!(
|
||||||
|
"bank-timestamp-correction",
|
||||||
|
("slot", self.slot(), i64),
|
||||||
|
("from_genesis", self.unix_timestamp_from_genesis(), i64),
|
||||||
|
("corrected", unix_timestamp, i64),
|
||||||
|
("ancestor_timestamp", ancestor_timestamp, i64),
|
||||||
|
);
|
||||||
}
|
}
|
||||||
let epoch_start_timestamp = if self
|
let mut epoch_start_timestamp = if self
|
||||||
.feature_set
|
.feature_set
|
||||||
.is_active(&feature_set::timestamp_bounding::id())
|
.is_active(&feature_set::timestamp_bounding::id())
|
||||||
{
|
{
|
||||||
@ -1370,6 +1391,10 @@ impl Bank {
|
|||||||
} else {
|
} else {
|
||||||
Self::get_unused_from_slot(self.slot, self.unused) as i64
|
Self::get_unused_from_slot(self.slot, self.unused) as i64
|
||||||
};
|
};
|
||||||
|
if self.slot == 0 {
|
||||||
|
unix_timestamp = self.unix_timestamp_from_genesis();
|
||||||
|
epoch_start_timestamp = self.unix_timestamp_from_genesis();
|
||||||
|
}
|
||||||
let clock = sysvar::clock::Clock {
|
let clock = sysvar::clock::Clock {
|
||||||
slot: self.slot,
|
slot: self.slot,
|
||||||
epoch_start_timestamp,
|
epoch_start_timestamp,
|
||||||
@ -11146,6 +11171,9 @@ pub(crate) mod tests {
|
|||||||
..
|
..
|
||||||
} = create_genesis_config_with_leader(5, &leader_pubkey, 3);
|
} = create_genesis_config_with_leader(5, &leader_pubkey, 3);
|
||||||
let mut bank = Bank::new(&genesis_config);
|
let mut bank = Bank::new(&genesis_config);
|
||||||
|
// Advance past slot 0, which has special handling.
|
||||||
|
bank = new_from_parent(&Arc::new(bank));
|
||||||
|
bank = new_from_parent(&Arc::new(bank));
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
bank.clock().unix_timestamp,
|
bank.clock().unix_timestamp,
|
||||||
bank.unix_timestamp_from_genesis()
|
bank.unix_timestamp_from_genesis()
|
||||||
|
@ -110,6 +110,10 @@ pub mod try_find_program_address_syscall_enabled {
|
|||||||
solana_sdk::declare_id!("EMsMNadQNhCYDyGpYH5Tx6dGHxiUqKHk782PU5XaWfmi");
|
solana_sdk::declare_id!("EMsMNadQNhCYDyGpYH5Tx6dGHxiUqKHk782PU5XaWfmi");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub mod warp_testnet_timestamp {
|
||||||
|
solana_sdk::declare_id!("Bfqm7fGk5MBptqa2WHXWFLH7uJvq8hkJcAQPipy2bAMk");
|
||||||
|
}
|
||||||
|
|
||||||
lazy_static! {
|
lazy_static! {
|
||||||
/// Map of feature identifiers to user-visible description
|
/// Map of feature identifiers to user-visible description
|
||||||
pub static ref FEATURE_NAMES: HashMap<Pubkey, &'static str> = [
|
pub static ref FEATURE_NAMES: HashMap<Pubkey, &'static str> = [
|
||||||
@ -139,6 +143,7 @@ lazy_static! {
|
|||||||
(simple_capitalization::id(), "simple capitalization"),
|
(simple_capitalization::id(), "simple capitalization"),
|
||||||
(bpf_loader_upgradeable_program::id(), "upgradeable bpf loader"),
|
(bpf_loader_upgradeable_program::id(), "upgradeable bpf loader"),
|
||||||
(try_find_program_address_syscall_enabled::id(), "add try_find_program_address syscall"),
|
(try_find_program_address_syscall_enabled::id(), "add try_find_program_address syscall"),
|
||||||
|
(warp_testnet_timestamp::id(), "warp testnet timestamp to current #TODO"),
|
||||||
/*************** ADD NEW FEATURES HERE ***************/
|
/*************** ADD NEW FEATURES HERE ***************/
|
||||||
]
|
]
|
||||||
.iter()
|
.iter()
|
||||||
|
Reference in New Issue
Block a user