Skip to content

Commit 3a640b3

Browse files
carllinbw-solana
authored andcommitted
Add alpenglow poh (anza-xyz#43)
PohService needs to set `use_alpenglow_tick_producer` flag on startup (anza-xyz#59)
1 parent 0fd4e38 commit 3a640b3

File tree

9 files changed

+225
-32
lines changed

9 files changed

+225
-32
lines changed

Cargo.lock

Lines changed: 1 addition & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

core/src/banking_simulation.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -739,6 +739,7 @@ impl BankingSimulator {
739739
&genesis_config.poh_config,
740740
None,
741741
exit.clone(),
742+
false,
742743
);
743744
let poh_recorder = Arc::new(RwLock::new(poh_recorder));
744745
let poh_service = PohService::new(

core/src/validator.rs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -954,7 +954,11 @@ impl Validator {
954954
let startup_verification_complete;
955955
let (poh_recorder, entry_receiver, record_receiver) = {
956956
let bank = &bank_forks.read().unwrap().working_bank();
957+
let highest_frozen_bank = &bank_forks.read().unwrap().highest_frozen_bank();
957958
startup_verification_complete = Arc::clone(bank.get_startup_verification_complete());
959+
let first_alpenglow_slot = highest_frozen_bank
960+
.feature_set
961+
.activated_slot(&solana_feature_set::secp256k1_program_enabled::id());
958962
PohRecorder::new_with_clear_signal(
959963
bank.tick_height(),
960964
bank.last_blockhash(),
@@ -968,6 +972,7 @@ impl Validator {
968972
&genesis_config.poh_config,
969973
Some(poh_timing_point_sender),
970974
exit.clone(),
975+
highest_frozen_bank.slot() >= first_alpenglow_slot.unwrap_or(u64::MAX),
971976
)
972977
};
973978
let poh_recorder = Arc::new(RwLock::new(poh_recorder));

poh/Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ solana-metrics = { workspace = true }
2222
solana-poh-config = { workspace = true }
2323
solana-pubkey = { workspace = true }
2424
solana-runtime = { workspace = true }
25+
solana-sdk = { workspace = true }
2526
solana-time-utils = { workspace = true }
2627
solana-transaction = { workspace = true }
2728
thiserror = { workspace = true }

poh/src/poh_recorder.rs

Lines changed: 59 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,8 @@
1010
//! For Entries:
1111
//! * recorded entry must be >= WorkingBank::min_tick_height && entry must be < WorkingBank::max_tick_height
1212
//!
13+
#[cfg(feature = "dev-context-only-utils")]
14+
use std::sync::RwLock;
1315
use {
1416
crate::{leader_bank_notifier::LeaderBankNotifier, poh_service::PohService},
1517
crossbeam_channel::{
@@ -34,7 +36,7 @@ use {
3436
num::Saturating,
3537
sync::{
3638
atomic::{AtomicBool, Ordering},
37-
Arc, Mutex, RwLock,
39+
Arc, Mutex,
3840
},
3941
time::{Duration, Instant},
4042
},
@@ -334,13 +336,16 @@ pub struct PohRecorder {
334336
delay_leader_block_for_pending_fork: bool,
335337
last_reported_slot_for_pending_fork: Arc<Mutex<Slot>>,
336338
pub is_exited: Arc<AtomicBool>,
339+
pub is_alpenglow_enabled: bool,
340+
pub use_alpenglow_tick_producer: bool,
337341
}
338342

339343
impl PohRecorder {
340344
/// A recorder to synchronize PoH with the following data structures
341345
/// * bank - the LastId's queue is updated on `tick` and `record` events
342346
/// * sender - the Entry channel that outputs to the ledger
343347
#[allow(clippy::too_many_arguments)]
348+
#[cfg(feature = "dev-context-only-utils")]
344349
pub fn new(
345350
tick_height: u64,
346351
last_entry_hash: Hash,
@@ -366,6 +371,7 @@ impl PohRecorder {
366371
poh_config,
367372
None,
368373
is_exited,
374+
false,
369375
)
370376
}
371377

@@ -383,6 +389,7 @@ impl PohRecorder {
383389
poh_config: &PohConfig,
384390
poh_timing_point_sender: Option<PohTimingSender>,
385391
is_exited: Arc<AtomicBool>,
392+
is_alpenglow_enabled: bool,
386393
) -> (Self, Receiver<WorkingBankEntry>, Receiver<Record>) {
387394
let tick_number = 0;
388395
let poh = Arc::new(Mutex::new(Poh::new_with_slot_info(
@@ -424,6 +431,8 @@ impl PohRecorder {
424431
delay_leader_block_for_pending_fork,
425432
last_reported_slot_for_pending_fork: Arc::default(),
426433
is_exited,
434+
is_alpenglow_enabled,
435+
use_alpenglow_tick_producer: is_alpenglow_enabled,
427436
},
428437
working_bank_receiver,
429438
record_receiver,
@@ -658,9 +667,14 @@ impl PohRecorder {
658667

659668
fn reset_poh(&mut self, reset_bank: Arc<Bank>, reset_start_bank: bool) {
660669
let blockhash = reset_bank.last_blockhash();
670+
let hashes_per_tick = if self.use_alpenglow_tick_producer {
671+
None
672+
} else {
673+
*reset_bank.hashes_per_tick()
674+
};
661675
let poh_hash = {
662676
let mut poh = self.poh.lock().unwrap();
663-
poh.reset(blockhash, *reset_bank.hashes_per_tick());
677+
poh.reset(blockhash, hashes_per_tick);
664678
poh.hash
665679
};
666680
info!(
@@ -1112,8 +1126,48 @@ impl PohRecorder {
11121126
self.report_poh_timing_point_by_tick()
11131127
}
11141128
}
1129+
1130+
pub fn tick_alpenglow(&mut self, slot_max_tick_height: u64) {
1131+
let (poh_entry, tick_lock_contention_us) = measure_us!({
1132+
let mut poh_l = self.poh.lock().unwrap();
1133+
poh_l.tick()
1134+
});
1135+
self.metrics.tick_lock_contention_us += tick_lock_contention_us;
1136+
1137+
if let Some(poh_entry) = poh_entry {
1138+
self.tick_height = slot_max_tick_height;
1139+
self.report_poh_timing_point();
1140+
1141+
// Should be empty in most cases, but reset just to be safe
1142+
self.tick_cache = vec![];
1143+
self.tick_cache.push((
1144+
Entry {
1145+
num_hashes: poh_entry.num_hashes,
1146+
hash: poh_entry.hash,
1147+
transactions: vec![],
1148+
},
1149+
self.tick_height,
1150+
));
1151+
1152+
let (_flush_res, flush_cache_and_tick_us) = measure_us!(self.flush_cache(true));
1153+
self.metrics.flush_cache_tick_us += flush_cache_and_tick_us;
1154+
}
1155+
}
1156+
1157+
pub fn migrate_to_alpenglow_poh(&mut self) {
1158+
self.tick_cache = vec![];
1159+
{
1160+
let mut poh = self.poh.lock().unwrap();
1161+
// sets PoH to low power mode
1162+
let hashes_per_tick = None;
1163+
let current_hash = poh.hash;
1164+
info!("migrating poh to low power mode");
1165+
poh.reset(current_hash, hashes_per_tick);
1166+
}
1167+
}
11151168
}
11161169

1170+
#[cfg(feature = "dev-context-only-utils")]
11171171
fn do_create_test_recorder(
11181172
bank: Arc<Bank>,
11191173
blockstore: Arc<Blockstore>,
@@ -1163,6 +1217,7 @@ fn do_create_test_recorder(
11631217
(exit, poh_recorder, poh_service, entry_receiver)
11641218
}
11651219

1220+
#[cfg(feature = "dev-context-only-utils")]
11661221
pub fn create_test_recorder(
11671222
bank: Arc<Bank>,
11681223
blockstore: Arc<Blockstore>,
@@ -1177,6 +1232,7 @@ pub fn create_test_recorder(
11771232
do_create_test_recorder(bank, blockstore, poh_config, leader_schedule_cache, false)
11781233
}
11791234

1235+
#[cfg(feature = "dev-context-only-utils")]
11801236
pub fn create_test_recorder_with_index_tracking(
11811237
bank: Arc<Bank>,
11821238
blockstore: Arc<Blockstore>,
@@ -1829,6 +1885,7 @@ mod tests {
18291885
&PohConfig::default(),
18301886
None,
18311887
Arc::new(AtomicBool::default()),
1888+
false,
18321889
);
18331890
poh_recorder.set_bank_for_test(bank);
18341891
poh_recorder.clear_bank();

0 commit comments

Comments
 (0)