Skip to content
This repository has been archived by the owner on Jan 22, 2025. It is now read-only.

Deleted #29296

Closed
Closed

Deleted #29296

Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion entry/src/poh.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ use {
pub struct Poh {
pub hash: Hash,
num_hashes: u64,
hashes_per_tick: u64,
pub hashes_per_tick: u64,
remaining_hashes: u64,
tick_number: u64,
slot_start_time: Instant,
Expand Down
29 changes: 22 additions & 7 deletions poh/src/poh_recorder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -225,7 +225,6 @@ pub struct PohRecorder {
id: Pubkey,
blockstore: Arc<Blockstore>,
leader_schedule_cache: Arc<LeaderScheduleCache>,
poh_config: PohConfig,
ticks_per_slot: u64,
target_ns_per_tick: u64,
record_lock_contention_us: u64,
Expand Down Expand Up @@ -460,13 +459,11 @@ impl PohRecorder {
))
}

// synchronize PoH with a bank
pub fn reset(&mut self, reset_bank: Arc<Bank>, next_leader_slot: Option<(Slot, Slot)>) {
self.clear_bank();
fn reset_poh(&mut self, reset_bank: Arc<Bank>, reset_start_bank: bool) {
let blockhash = reset_bank.last_blockhash();
let poh_hash = {
let mut poh = self.poh.lock().unwrap();
poh.reset(blockhash, self.poh_config.hashes_per_tick);
poh.reset(blockhash, *reset_bank.hashes_per_tick());
poh.hash
};
info!(
Expand All @@ -479,9 +476,17 @@ impl PohRecorder {
);

self.tick_cache = vec![];
self.start_bank = reset_bank;
if reset_start_bank {
self.start_bank = reset_bank;
}
self.tick_height = (self.start_slot() + 1) * self.ticks_per_slot;
self.start_tick_height = self.tick_height + 1;
}

// synchronize PoH with a bank
pub fn reset(&mut self, reset_bank: Arc<Bank>, next_leader_slot: Option<(Slot, Slot)>) {
self.clear_bank();
self.reset_poh(reset_bank, true);

if let Some(ref sender) = self.poh_timing_point_sender {
// start_slot() is the parent slot. current slot is start_slot() + 1.
Expand Down Expand Up @@ -513,6 +518,17 @@ impl PohRecorder {
};
trace!("new working bank");
assert_eq!(working_bank.bank.ticks_per_slot(), self.ticks_per_slot());
if let Some(hashes_per_tick) = *working_bank.bank.hashes_per_tick() {
if self.poh.lock().unwrap().hashes_per_tick != hashes_per_tick {
// Reset poh when changing hashes per tick so that we ensure all ticks
// for this slot are created with the proper hashes per tick
info!(
"resetting poh due to hashes per tick change detected at {}",
working_bank.bank.slot()
);
self.reset_poh(working_bank.clone().bank, false);
}
}
self.working_bank = Some(working_bank);

// send poh slot start timing point
Expand Down Expand Up @@ -865,7 +881,6 @@ impl PohRecorder {
leader_schedule_cache: leader_schedule_cache.clone(),
ticks_per_slot,
target_ns_per_tick,
poh_config: poh_config.clone(),
record_lock_contention_us: 0,
flush_cache_tick_us: 0,
flush_cache_no_tick_us: 0,
Expand Down
92 changes: 81 additions & 11 deletions runtime/src/bank.rs
Original file line number Diff line number Diff line change
Expand Up @@ -108,9 +108,10 @@ use {
account_utils::StateMut,
bpf_loader_upgradeable::{self, UpgradeableLoaderState},
clock::{
BankId, Epoch, Slot, SlotCount, SlotIndex, UnixTimestamp, DEFAULT_TICKS_PER_SECOND,
INITIAL_RENT_EPOCH, MAX_PROCESSING_AGE, MAX_TRANSACTION_FORWARDING_DELAY,
MAX_TRANSACTION_FORWARDING_DELAY_GPU, SECONDS_PER_DAY,
BankId, Epoch, Slot, SlotCount, SlotIndex, UnixTimestamp, DEFAULT_HASHES_PER_TICK,
DEFAULT_TICKS_PER_SECOND, INITIAL_RENT_EPOCH, MAX_PROCESSING_AGE,
MAX_TRANSACTION_FORWARDING_DELAY, MAX_TRANSACTION_FORWARDING_DELAY_GPU,
SECONDS_PER_DAY,
},
ed25519_program,
epoch_info::EpochInfo,
Expand Down Expand Up @@ -1661,7 +1662,8 @@ impl Bank {
let (_, apply_feature_activations_time) = measure!(
new.apply_feature_activations(
ApplyFeatureActivationsCaller::NewFromParent,
false
false,
vec![false; FeatureActivation::NumVariants as usize],
),
"apply_feature_activation",
);
Expand Down Expand Up @@ -1888,7 +1890,11 @@ impl Bank {

let parent_timestamp = parent.clock().unix_timestamp;
let mut new = Bank::new_from_parent(parent, collector_id, slot);
new.apply_feature_activations(ApplyFeatureActivationsCaller::WarpFromParent, false);
new.apply_feature_activations(
ApplyFeatureActivationsCaller::WarpFromParent,
false,
vec![false; FeatureActivation::NumVariants as usize],
);
new.update_epoch_stakes(new.epoch_schedule().get_epoch(slot));
new.tick_height.store(new.max_tick_height(), Relaxed);

Expand Down Expand Up @@ -2015,10 +2021,6 @@ impl Bank {
"Bank snapshot genesis creation time does not match genesis.bin creation time.\
The snapshot and genesis.bin might pertain to different clusters"
);
assert_eq!(
bank.hashes_per_tick,
genesis_config.poh_config.hashes_per_tick
);
assert_eq!(bank.ticks_per_slot, genesis_config.ticks_per_slot);
assert_eq!(
bank.ns_per_slot,
Expand Down Expand Up @@ -6426,6 +6428,7 @@ impl Bank {
self.apply_feature_activations(
ApplyFeatureActivationsCaller::FinishInit,
debug_do_not_add_builtins,
vec![false; FeatureActivation::NumVariants as usize],
);

if self
Expand Down Expand Up @@ -7452,10 +7455,12 @@ impl Bank {

// This is called from snapshot restore AND for each epoch boundary
// The entire code path herein must be idempotent
fn apply_feature_activations(
pub fn apply_feature_activations(
&mut self,
caller: ApplyFeatureActivationsCaller,
debug_do_not_add_builtins: bool,
// This vector is for forcing a feature to get activated for testing purposes
features_activated_test: Vec<bool>,
) {
use ApplyFeatureActivationsCaller::*;
let allow_new_activations = match caller {
Expand Down Expand Up @@ -7507,6 +7512,21 @@ impl Bank {
const ACCOUNTS_DATA_LEN: u64 = 50_000_000_000;
self.accounts_data_size_initial = ACCOUNTS_DATA_LEN;
}

if new_feature_activations.contains(&feature_set::configurable_hashes_per_tick::id())
|| features_activated_test[FeatureActivation::ConfigurablePohTicksPerSecond as usize]
{
self.apply_updated_hashes_per_tick(DEFAULT_HASHES_PER_TICK);
}
}

fn apply_updated_hashes_per_tick(&mut self, hashes_per_tick: u64) {
info!(
"Activating configurable_hashes_per_tick {} at slot {}",
hashes_per_tick,
self.slot(),
);
self.hashes_per_tick = Some(hashes_per_tick);
}

fn adjust_sysvar_balance_for_rent(&self, account: &mut AccountSharedData) {
Expand Down Expand Up @@ -7797,12 +7817,19 @@ fn calculate_data_size_delta(old_data_size: usize, new_data_size: usize) -> i64
/// Since `apply_feature_activations()` has different behavior depending on its caller, enumerate
/// those callers explicitly.
#[derive(Debug, Copy, Clone, Eq, PartialEq)]
enum ApplyFeatureActivationsCaller {
pub enum ApplyFeatureActivationsCaller {
FinishInit,
NewFromParent,
WarpFromParent,
}

/// Allows for force enabling feature activations for testing.
pub enum FeatureActivation {
ConfigurablePohTicksPerSecond,
// Add new feature activation enums here
NumVariants,
}

/// Return the computed values from `collect_rent_from_accounts()`
///
/// Since `collect_rent_from_accounts()` is running in parallel, instead of updating the
Expand Down Expand Up @@ -20157,4 +20184,47 @@ pub(crate) mod tests {
)),
);
}

#[test]
fn test_feature_activation_idempotent() {
let GenesisConfigInfo {
mut genesis_config, ..
} = genesis_utils::create_genesis_config_with_leader(
1_000_000 * LAMPORTS_PER_SOL,
&Pubkey::new_unique(),
100 * LAMPORTS_PER_SOL,
);
genesis_config.rent = Rent::default();
const HASHES_PER_TICK_START: u64 = 3;
genesis_config.poh_config.hashes_per_tick = Some(HASHES_PER_TICK_START);

let mut bank = Bank::new_for_tests(&genesis_config);
assert_eq!(bank.hashes_per_tick, Some(HASHES_PER_TICK_START));

// Don't activate feature
let mut test_activation = vec![false; FeatureActivation::NumVariants as usize];
bank.apply_feature_activations(
ApplyFeatureActivationsCaller::NewFromParent,
false,
test_activation.clone(),
);
assert_eq!(bank.hashes_per_tick, Some(HASHES_PER_TICK_START));

// Activate feature
test_activation[FeatureActivation::ConfigurablePohTicksPerSecond as usize] = true;
bank.apply_feature_activations(
ApplyFeatureActivationsCaller::NewFromParent,
false,
test_activation.clone(),
);
assert_eq!(bank.hashes_per_tick, Some(DEFAULT_HASHES_PER_TICK));

// Activate feature "again"
bank.apply_feature_activations(
ApplyFeatureActivationsCaller::NewFromParent,
false,
test_activation,
);
assert_eq!(bank.hashes_per_tick, Some(DEFAULT_HASHES_PER_TICK));
}
}
5 changes: 5 additions & 0 deletions sdk/src/feature_set.rs
Original file line number Diff line number Diff line change
Expand Up @@ -554,6 +554,10 @@ pub mod enable_program_redeployment_cooldown {
solana_sdk::declare_id!("J4HFT8usBxpcF63y46t1upYobJgChmKyZPm5uTBRg25Z");
}

pub mod configurable_hashes_per_tick {
solana_sdk::declare_id!("3uFHb9oKdGfgZGJK9EHaAXN4USvnQtAFC13Fh5gGFS5B");
}

lazy_static! {
/// Map of feature identifiers to user-visible description
pub static ref FEATURE_NAMES: HashMap<Pubkey, &'static str> = [
Expand Down Expand Up @@ -687,6 +691,7 @@ lazy_static! {
(cap_transaction_accounts_data_size::id(), "cap transaction accounts data size up to its compute unit limits #27839"),
(enable_alt_bn128_syscall::id(), "add alt_bn128 syscalls #27961"),
(enable_program_redeployment_cooldown::id(), "enable program redeployment cooldown #29135"),
(configurable_hashes_per_tick::id(), "Configure desired hashes per tick to update on epoch boundary"),
/*************** ADD NEW FEATURES HERE ***************/
]
.iter()
Expand Down