Move block-time caching earlier (#17109)
* Require that blockstore block-time only be recognized slot, instead of root * Move cache_block_time to after Bank freeze * Single use statement * Pass transaction_status_sender by reference * Remove unnecessary slot-existence check before caching block time altogether * Move block-time existence check into Blockstore::cache_block_time, Blockstore no longer needed in blockstore_processor helper
This commit is contained in:
parent
f39dda00e0
commit
6e9deaf1bd
|
@ -1,18 +1,20 @@
|
||||||
use crossbeam_channel::{Receiver, RecvTimeoutError, Sender};
|
pub use solana_ledger::blockstore_processor::CacheBlockTimeSender;
|
||||||
use solana_ledger::blockstore::Blockstore;
|
use {
|
||||||
use solana_measure::measure::Measure;
|
crossbeam_channel::{Receiver, RecvTimeoutError},
|
||||||
use solana_runtime::bank::Bank;
|
solana_ledger::blockstore::Blockstore,
|
||||||
use std::{
|
solana_measure::measure::Measure,
|
||||||
sync::{
|
solana_runtime::bank::Bank,
|
||||||
atomic::{AtomicBool, Ordering},
|
std::{
|
||||||
Arc,
|
sync::{
|
||||||
|
atomic::{AtomicBool, Ordering},
|
||||||
|
Arc,
|
||||||
|
},
|
||||||
|
thread::{self, Builder, JoinHandle},
|
||||||
|
time::Duration,
|
||||||
},
|
},
|
||||||
thread::{self, Builder, JoinHandle},
|
|
||||||
time::Duration,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
pub type CacheBlockTimeReceiver = Receiver<Arc<Bank>>;
|
pub type CacheBlockTimeReceiver = Receiver<Arc<Bank>>;
|
||||||
pub type CacheBlockTimeSender = Sender<Arc<Bank>>;
|
|
||||||
|
|
||||||
pub struct CacheBlockTimeService {
|
pub struct CacheBlockTimeService {
|
||||||
thread_hdl: JoinHandle<()>,
|
thread_hdl: JoinHandle<()>,
|
||||||
|
|
|
@ -372,7 +372,8 @@ impl ReplayStage {
|
||||||
&my_pubkey,
|
&my_pubkey,
|
||||||
&vote_account,
|
&vote_account,
|
||||||
&mut progress,
|
&mut progress,
|
||||||
transaction_status_sender.clone(),
|
transaction_status_sender.as_ref(),
|
||||||
|
cache_block_time_sender.as_ref(),
|
||||||
&verify_recyclers,
|
&verify_recyclers,
|
||||||
&mut heaviest_subtree_fork_choice,
|
&mut heaviest_subtree_fork_choice,
|
||||||
&replay_vote_sender,
|
&replay_vote_sender,
|
||||||
|
@ -565,7 +566,6 @@ impl ReplayStage {
|
||||||
&subscriptions,
|
&subscriptions,
|
||||||
&block_commitment_cache,
|
&block_commitment_cache,
|
||||||
&mut heaviest_subtree_fork_choice,
|
&mut heaviest_subtree_fork_choice,
|
||||||
&cache_block_time_sender,
|
|
||||||
&bank_notification_sender,
|
&bank_notification_sender,
|
||||||
&mut gossip_duplicate_confirmed_slots,
|
&mut gossip_duplicate_confirmed_slots,
|
||||||
&mut unfrozen_gossip_verified_vote_hashes,
|
&mut unfrozen_gossip_verified_vote_hashes,
|
||||||
|
@ -1187,7 +1187,7 @@ impl ReplayStage {
|
||||||
bank: &Arc<Bank>,
|
bank: &Arc<Bank>,
|
||||||
blockstore: &Blockstore,
|
blockstore: &Blockstore,
|
||||||
bank_progress: &mut ForkProgress,
|
bank_progress: &mut ForkProgress,
|
||||||
transaction_status_sender: Option<TransactionStatusSender>,
|
transaction_status_sender: Option<&TransactionStatusSender>,
|
||||||
replay_vote_sender: &ReplayVoteSender,
|
replay_vote_sender: &ReplayVoteSender,
|
||||||
verify_recyclers: &VerifyRecyclers,
|
verify_recyclers: &VerifyRecyclers,
|
||||||
) -> result::Result<usize, BlockstoreProcessorError> {
|
) -> result::Result<usize, BlockstoreProcessorError> {
|
||||||
|
@ -1294,7 +1294,6 @@ impl ReplayStage {
|
||||||
subscriptions: &Arc<RpcSubscriptions>,
|
subscriptions: &Arc<RpcSubscriptions>,
|
||||||
block_commitment_cache: &Arc<RwLock<BlockCommitmentCache>>,
|
block_commitment_cache: &Arc<RwLock<BlockCommitmentCache>>,
|
||||||
heaviest_subtree_fork_choice: &mut HeaviestSubtreeForkChoice,
|
heaviest_subtree_fork_choice: &mut HeaviestSubtreeForkChoice,
|
||||||
cache_block_time_sender: &Option<CacheBlockTimeSender>,
|
|
||||||
bank_notification_sender: &Option<BankNotificationSender>,
|
bank_notification_sender: &Option<BankNotificationSender>,
|
||||||
gossip_duplicate_confirmed_slots: &mut GossipDuplicateConfirmedSlots,
|
gossip_duplicate_confirmed_slots: &mut GossipDuplicateConfirmedSlots,
|
||||||
unfrozen_gossip_verified_vote_hashes: &mut UnfrozenGossipVerifiedVoteHashes,
|
unfrozen_gossip_verified_vote_hashes: &mut UnfrozenGossipVerifiedVoteHashes,
|
||||||
|
@ -1331,12 +1330,6 @@ impl ReplayStage {
|
||||||
blockstore
|
blockstore
|
||||||
.set_roots(&rooted_slots)
|
.set_roots(&rooted_slots)
|
||||||
.expect("Ledger set roots failed");
|
.expect("Ledger set roots failed");
|
||||||
Self::cache_block_times(
|
|
||||||
blockstore,
|
|
||||||
bank_forks,
|
|
||||||
&rooted_slots,
|
|
||||||
cache_block_time_sender,
|
|
||||||
);
|
|
||||||
let highest_confirmed_root = Some(
|
let highest_confirmed_root = Some(
|
||||||
block_commitment_cache
|
block_commitment_cache
|
||||||
.read()
|
.read()
|
||||||
|
@ -1630,7 +1623,8 @@ impl ReplayStage {
|
||||||
my_pubkey: &Pubkey,
|
my_pubkey: &Pubkey,
|
||||||
vote_account: &Pubkey,
|
vote_account: &Pubkey,
|
||||||
progress: &mut ProgressMap,
|
progress: &mut ProgressMap,
|
||||||
transaction_status_sender: Option<TransactionStatusSender>,
|
transaction_status_sender: Option<&TransactionStatusSender>,
|
||||||
|
cache_block_time_sender: Option<&CacheBlockTimeSender>,
|
||||||
verify_recyclers: &VerifyRecyclers,
|
verify_recyclers: &VerifyRecyclers,
|
||||||
heaviest_subtree_fork_choice: &mut HeaviestSubtreeForkChoice,
|
heaviest_subtree_fork_choice: &mut HeaviestSubtreeForkChoice,
|
||||||
replay_vote_sender: &ReplayVoteSender,
|
replay_vote_sender: &ReplayVoteSender,
|
||||||
|
@ -1694,7 +1688,7 @@ impl ReplayStage {
|
||||||
&bank,
|
&bank,
|
||||||
&blockstore,
|
&blockstore,
|
||||||
bank_progress,
|
bank_progress,
|
||||||
transaction_status_sender.clone(),
|
transaction_status_sender,
|
||||||
replay_vote_sender,
|
replay_vote_sender,
|
||||||
verify_recyclers,
|
verify_recyclers,
|
||||||
);
|
);
|
||||||
|
@ -1729,7 +1723,7 @@ impl ReplayStage {
|
||||||
);
|
);
|
||||||
did_complete_bank = true;
|
did_complete_bank = true;
|
||||||
info!("bank frozen: {}", bank.slot());
|
info!("bank frozen: {}", bank.slot());
|
||||||
if let Some(transaction_status_sender) = transaction_status_sender.clone() {
|
if let Some(transaction_status_sender) = transaction_status_sender {
|
||||||
transaction_status_sender.send_transaction_status_freeze_message(&bank);
|
transaction_status_sender.send_transaction_status_freeze_message(&bank);
|
||||||
}
|
}
|
||||||
bank.freeze();
|
bank.freeze();
|
||||||
|
@ -1755,6 +1749,7 @@ impl ReplayStage {
|
||||||
.send(BankNotification::Frozen(bank.clone()))
|
.send(BankNotification::Frozen(bank.clone()))
|
||||||
.unwrap_or_else(|err| warn!("bank_notification_sender failed: {:?}", err));
|
.unwrap_or_else(|err| warn!("bank_notification_sender failed: {:?}", err));
|
||||||
}
|
}
|
||||||
|
blockstore_processor::cache_block_time(&bank, cache_block_time_sender);
|
||||||
|
|
||||||
let bank_hash = bank.hash();
|
let bank_hash = bank.hash();
|
||||||
if let Some(new_frozen_voters) =
|
if let Some(new_frozen_voters) =
|
||||||
|
@ -2455,36 +2450,6 @@ impl ReplayStage {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn cache_block_times(
|
|
||||||
blockstore: &Arc<Blockstore>,
|
|
||||||
bank_forks: &Arc<RwLock<BankForks>>,
|
|
||||||
rooted_slots: &[Slot],
|
|
||||||
cache_block_time_sender: &Option<CacheBlockTimeSender>,
|
|
||||||
) {
|
|
||||||
if let Some(cache_block_time_sender) = cache_block_time_sender {
|
|
||||||
for slot in rooted_slots {
|
|
||||||
if blockstore
|
|
||||||
.get_block_time(*slot)
|
|
||||||
.unwrap_or_default()
|
|
||||||
.is_none()
|
|
||||||
{
|
|
||||||
if let Some(rooted_bank) = bank_forks.read().unwrap().get(*slot) {
|
|
||||||
cache_block_time_sender
|
|
||||||
.send(rooted_bank.clone())
|
|
||||||
.unwrap_or_else(|err| {
|
|
||||||
warn!("cache_block_time_sender failed: {:?}", err)
|
|
||||||
});
|
|
||||||
} else {
|
|
||||||
error!(
|
|
||||||
"rooted_bank {:?} not available in BankForks; block time not cached",
|
|
||||||
slot
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn get_unlock_switch_vote_slot(cluster_type: ClusterType) -> Slot {
|
pub fn get_unlock_switch_vote_slot(cluster_type: ClusterType) -> Slot {
|
||||||
match cluster_type {
|
match cluster_type {
|
||||||
ClusterType::Development => 0,
|
ClusterType::Development => 0,
|
||||||
|
@ -3381,7 +3346,7 @@ pub(crate) mod tests {
|
||||||
&bank,
|
&bank,
|
||||||
&mut entries,
|
&mut entries,
|
||||||
true,
|
true,
|
||||||
Some(TransactionStatusSender {
|
Some(&TransactionStatusSender {
|
||||||
sender: transaction_status_sender,
|
sender: transaction_status_sender,
|
||||||
enable_cpi_and_log_storage: false,
|
enable_cpi_and_log_storage: false,
|
||||||
}),
|
}),
|
||||||
|
|
|
@ -693,7 +693,7 @@ mod tests {
|
||||||
..ProcessOptions::default()
|
..ProcessOptions::default()
|
||||||
};
|
};
|
||||||
let (bank_forks, cached_leader_schedule) =
|
let (bank_forks, cached_leader_schedule) =
|
||||||
process_blockstore(&genesis_config, &blockstore, Vec::new(), opts).unwrap();
|
process_blockstore(&genesis_config, &blockstore, Vec::new(), opts, None).unwrap();
|
||||||
let leader_schedule_cache = Arc::new(cached_leader_schedule);
|
let leader_schedule_cache = Arc::new(cached_leader_schedule);
|
||||||
let bank_forks = Arc::new(RwLock::new(bank_forks));
|
let bank_forks = Arc::new(RwLock::new(bank_forks));
|
||||||
|
|
||||||
|
|
|
@ -1119,7 +1119,10 @@ fn new_banks_from_ledger(
|
||||||
process_options,
|
process_options,
|
||||||
transaction_history_services
|
transaction_history_services
|
||||||
.transaction_status_sender
|
.transaction_status_sender
|
||||||
.clone(),
|
.as_ref(),
|
||||||
|
transaction_history_services
|
||||||
|
.cache_block_time_sender
|
||||||
|
.as_ref(),
|
||||||
)
|
)
|
||||||
.unwrap_or_else(|err| {
|
.unwrap_or_else(|err| {
|
||||||
error!("Failed to load ledger: {:?}", err);
|
error!("Failed to load ledger: {:?}", err);
|
||||||
|
|
|
@ -703,6 +703,7 @@ fn load_bank_forks(
|
||||||
snapshot_config.as_ref(),
|
snapshot_config.as_ref(),
|
||||||
process_options,
|
process_options,
|
||||||
None,
|
None,
|
||||||
|
None,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
use crate::{
|
use crate::{
|
||||||
blockstore::Blockstore,
|
blockstore::Blockstore,
|
||||||
blockstore_processor::{
|
blockstore_processor::{
|
||||||
self, BlockstoreProcessorError, BlockstoreProcessorResult, ProcessOptions,
|
self, BlockstoreProcessorError, BlockstoreProcessorResult, CacheBlockTimeSender,
|
||||||
TransactionStatusSender,
|
ProcessOptions, TransactionStatusSender,
|
||||||
},
|
},
|
||||||
entry::VerifyRecyclers,
|
entry::VerifyRecyclers,
|
||||||
leader_schedule_cache::LeaderScheduleCache,
|
leader_schedule_cache::LeaderScheduleCache,
|
||||||
|
@ -36,7 +36,8 @@ pub fn load(
|
||||||
shrink_paths: Option<Vec<PathBuf>>,
|
shrink_paths: Option<Vec<PathBuf>>,
|
||||||
snapshot_config: Option<&SnapshotConfig>,
|
snapshot_config: Option<&SnapshotConfig>,
|
||||||
process_options: ProcessOptions,
|
process_options: ProcessOptions,
|
||||||
transaction_status_sender: Option<TransactionStatusSender>,
|
transaction_status_sender: Option<&TransactionStatusSender>,
|
||||||
|
cache_block_time_sender: Option<&CacheBlockTimeSender>,
|
||||||
) -> LoadResult {
|
) -> LoadResult {
|
||||||
if let Some(snapshot_config) = snapshot_config.as_ref() {
|
if let Some(snapshot_config) = snapshot_config.as_ref() {
|
||||||
info!(
|
info!(
|
||||||
|
@ -96,6 +97,7 @@ pub fn load(
|
||||||
&process_options,
|
&process_options,
|
||||||
&VerifyRecyclers::default(),
|
&VerifyRecyclers::default(),
|
||||||
transaction_status_sender,
|
transaction_status_sender,
|
||||||
|
cache_block_time_sender,
|
||||||
),
|
),
|
||||||
Some(deserialized_snapshot_hash),
|
Some(deserialized_snapshot_hash),
|
||||||
);
|
);
|
||||||
|
@ -113,6 +115,7 @@ pub fn load(
|
||||||
&blockstore,
|
&blockstore,
|
||||||
account_paths,
|
account_paths,
|
||||||
process_options,
|
process_options,
|
||||||
|
cache_block_time_sender,
|
||||||
),
|
),
|
||||||
None,
|
None,
|
||||||
)
|
)
|
||||||
|
|
|
@ -1755,10 +1755,11 @@ impl Blockstore {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn cache_block_time(&self, slot: Slot, timestamp: UnixTimestamp) -> Result<()> {
|
pub fn cache_block_time(&self, slot: Slot, timestamp: UnixTimestamp) -> Result<()> {
|
||||||
if !self.is_root(slot) {
|
if self.get_block_time(slot).unwrap_or_default().is_none() {
|
||||||
return Err(BlockstoreError::SlotNotRooted);
|
self.blocktime_cf.put(slot, ×tamp)
|
||||||
|
} else {
|
||||||
|
Ok(())
|
||||||
}
|
}
|
||||||
self.blocktime_cf.put(slot, ×tamp)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_first_available_block(&self) -> Result<Slot> {
|
pub fn get_first_available_block(&self) -> Result<Slot> {
|
||||||
|
|
|
@ -101,7 +101,7 @@ fn get_first_error(
|
||||||
fn execute_batch(
|
fn execute_batch(
|
||||||
batch: &TransactionBatch,
|
batch: &TransactionBatch,
|
||||||
bank: &Arc<Bank>,
|
bank: &Arc<Bank>,
|
||||||
transaction_status_sender: Option<TransactionStatusSender>,
|
transaction_status_sender: Option<&TransactionStatusSender>,
|
||||||
replay_vote_sender: Option<&ReplayVoteSender>,
|
replay_vote_sender: Option<&ReplayVoteSender>,
|
||||||
timings: &mut ExecuteTimings,
|
timings: &mut ExecuteTimings,
|
||||||
) -> Result<()> {
|
) -> Result<()> {
|
||||||
|
@ -163,7 +163,7 @@ fn execute_batches(
|
||||||
bank: &Arc<Bank>,
|
bank: &Arc<Bank>,
|
||||||
batches: &[TransactionBatch],
|
batches: &[TransactionBatch],
|
||||||
entry_callback: Option<&ProcessCallback>,
|
entry_callback: Option<&ProcessCallback>,
|
||||||
transaction_status_sender: Option<TransactionStatusSender>,
|
transaction_status_sender: Option<&TransactionStatusSender>,
|
||||||
replay_vote_sender: Option<&ReplayVoteSender>,
|
replay_vote_sender: Option<&ReplayVoteSender>,
|
||||||
timings: &mut ExecuteTimings,
|
timings: &mut ExecuteTimings,
|
||||||
) -> Result<()> {
|
) -> Result<()> {
|
||||||
|
@ -173,12 +173,12 @@ fn execute_batches(
|
||||||
thread_pool.borrow().install(|| {
|
thread_pool.borrow().install(|| {
|
||||||
batches
|
batches
|
||||||
.into_par_iter()
|
.into_par_iter()
|
||||||
.map_with(transaction_status_sender, |sender, batch| {
|
.map(|batch| {
|
||||||
let mut timings = ExecuteTimings::default();
|
let mut timings = ExecuteTimings::default();
|
||||||
let result = execute_batch(
|
let result = execute_batch(
|
||||||
batch,
|
batch,
|
||||||
bank,
|
bank,
|
||||||
sender.clone(),
|
transaction_status_sender,
|
||||||
replay_vote_sender,
|
replay_vote_sender,
|
||||||
&mut timings,
|
&mut timings,
|
||||||
);
|
);
|
||||||
|
@ -207,7 +207,7 @@ pub fn process_entries(
|
||||||
bank: &Arc<Bank>,
|
bank: &Arc<Bank>,
|
||||||
entries: &mut [Entry],
|
entries: &mut [Entry],
|
||||||
randomize: bool,
|
randomize: bool,
|
||||||
transaction_status_sender: Option<TransactionStatusSender>,
|
transaction_status_sender: Option<&TransactionStatusSender>,
|
||||||
replay_vote_sender: Option<&ReplayVoteSender>,
|
replay_vote_sender: Option<&ReplayVoteSender>,
|
||||||
) -> Result<()> {
|
) -> Result<()> {
|
||||||
let mut timings = ExecuteTimings::default();
|
let mut timings = ExecuteTimings::default();
|
||||||
|
@ -232,7 +232,7 @@ fn process_entries_with_callback(
|
||||||
entries: &mut [EntryType],
|
entries: &mut [EntryType],
|
||||||
randomize: bool,
|
randomize: bool,
|
||||||
entry_callback: Option<&ProcessCallback>,
|
entry_callback: Option<&ProcessCallback>,
|
||||||
transaction_status_sender: Option<TransactionStatusSender>,
|
transaction_status_sender: Option<&TransactionStatusSender>,
|
||||||
replay_vote_sender: Option<&ReplayVoteSender>,
|
replay_vote_sender: Option<&ReplayVoteSender>,
|
||||||
timings: &mut ExecuteTimings,
|
timings: &mut ExecuteTimings,
|
||||||
) -> Result<()> {
|
) -> Result<()> {
|
||||||
|
@ -253,7 +253,7 @@ fn process_entries_with_callback(
|
||||||
bank,
|
bank,
|
||||||
&batches,
|
&batches,
|
||||||
entry_callback,
|
entry_callback,
|
||||||
transaction_status_sender.clone(),
|
transaction_status_sender,
|
||||||
replay_vote_sender,
|
replay_vote_sender,
|
||||||
timings,
|
timings,
|
||||||
)?;
|
)?;
|
||||||
|
@ -304,7 +304,7 @@ fn process_entries_with_callback(
|
||||||
bank,
|
bank,
|
||||||
&batches,
|
&batches,
|
||||||
entry_callback,
|
entry_callback,
|
||||||
transaction_status_sender.clone(),
|
transaction_status_sender,
|
||||||
replay_vote_sender,
|
replay_vote_sender,
|
||||||
timings,
|
timings,
|
||||||
)?;
|
)?;
|
||||||
|
@ -376,6 +376,7 @@ pub fn process_blockstore(
|
||||||
blockstore: &Blockstore,
|
blockstore: &Blockstore,
|
||||||
account_paths: Vec<PathBuf>,
|
account_paths: Vec<PathBuf>,
|
||||||
opts: ProcessOptions,
|
opts: ProcessOptions,
|
||||||
|
cache_block_time_sender: Option<&CacheBlockTimeSender>,
|
||||||
) -> BlockstoreProcessorResult {
|
) -> BlockstoreProcessorResult {
|
||||||
if let Some(num_threads) = opts.override_num_threads {
|
if let Some(num_threads) = opts.override_num_threads {
|
||||||
PAR_THREAD_POOL.with(|pool| {
|
PAR_THREAD_POOL.with(|pool| {
|
||||||
|
@ -399,8 +400,21 @@ pub fn process_blockstore(
|
||||||
let bank0 = Arc::new(bank0);
|
let bank0 = Arc::new(bank0);
|
||||||
info!("processing ledger for slot 0...");
|
info!("processing ledger for slot 0...");
|
||||||
let recyclers = VerifyRecyclers::default();
|
let recyclers = VerifyRecyclers::default();
|
||||||
process_bank_0(&bank0, blockstore, &opts, &recyclers);
|
process_bank_0(
|
||||||
do_process_blockstore_from_root(blockstore, bank0, &opts, &recyclers, None)
|
&bank0,
|
||||||
|
blockstore,
|
||||||
|
&opts,
|
||||||
|
&recyclers,
|
||||||
|
cache_block_time_sender,
|
||||||
|
);
|
||||||
|
do_process_blockstore_from_root(
|
||||||
|
blockstore,
|
||||||
|
bank0,
|
||||||
|
&opts,
|
||||||
|
&recyclers,
|
||||||
|
None,
|
||||||
|
cache_block_time_sender,
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Process blockstore from a known root bank
|
// Process blockstore from a known root bank
|
||||||
|
@ -409,7 +423,8 @@ pub(crate) fn process_blockstore_from_root(
|
||||||
bank: Bank,
|
bank: Bank,
|
||||||
opts: &ProcessOptions,
|
opts: &ProcessOptions,
|
||||||
recyclers: &VerifyRecyclers,
|
recyclers: &VerifyRecyclers,
|
||||||
transaction_status_sender: Option<TransactionStatusSender>,
|
transaction_status_sender: Option<&TransactionStatusSender>,
|
||||||
|
cache_block_time_sender: Option<&CacheBlockTimeSender>,
|
||||||
) -> BlockstoreProcessorResult {
|
) -> BlockstoreProcessorResult {
|
||||||
do_process_blockstore_from_root(
|
do_process_blockstore_from_root(
|
||||||
blockstore,
|
blockstore,
|
||||||
|
@ -417,6 +432,7 @@ pub(crate) fn process_blockstore_from_root(
|
||||||
opts,
|
opts,
|
||||||
recyclers,
|
recyclers,
|
||||||
transaction_status_sender,
|
transaction_status_sender,
|
||||||
|
cache_block_time_sender,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -425,7 +441,8 @@ fn do_process_blockstore_from_root(
|
||||||
bank: Arc<Bank>,
|
bank: Arc<Bank>,
|
||||||
opts: &ProcessOptions,
|
opts: &ProcessOptions,
|
||||||
recyclers: &VerifyRecyclers,
|
recyclers: &VerifyRecyclers,
|
||||||
transaction_status_sender: Option<TransactionStatusSender>,
|
transaction_status_sender: Option<&TransactionStatusSender>,
|
||||||
|
cache_block_time_sender: Option<&CacheBlockTimeSender>,
|
||||||
) -> BlockstoreProcessorResult {
|
) -> BlockstoreProcessorResult {
|
||||||
info!("processing ledger from slot {}...", bank.slot());
|
info!("processing ledger from slot {}...", bank.slot());
|
||||||
|
|
||||||
|
@ -486,6 +503,7 @@ fn do_process_blockstore_from_root(
|
||||||
opts,
|
opts,
|
||||||
recyclers,
|
recyclers,
|
||||||
transaction_status_sender,
|
transaction_status_sender,
|
||||||
|
cache_block_time_sender,
|
||||||
&mut timing,
|
&mut timing,
|
||||||
)?;
|
)?;
|
||||||
initial_forks.sort_by_key(|bank| bank.slot());
|
initial_forks.sort_by_key(|bank| bank.slot());
|
||||||
|
@ -586,7 +604,7 @@ fn confirm_full_slot(
|
||||||
opts: &ProcessOptions,
|
opts: &ProcessOptions,
|
||||||
recyclers: &VerifyRecyclers,
|
recyclers: &VerifyRecyclers,
|
||||||
progress: &mut ConfirmationProgress,
|
progress: &mut ConfirmationProgress,
|
||||||
transaction_status_sender: Option<TransactionStatusSender>,
|
transaction_status_sender: Option<&TransactionStatusSender>,
|
||||||
replay_vote_sender: Option<&ReplayVoteSender>,
|
replay_vote_sender: Option<&ReplayVoteSender>,
|
||||||
timing: &mut ExecuteTimings,
|
timing: &mut ExecuteTimings,
|
||||||
) -> result::Result<(), BlockstoreProcessorError> {
|
) -> result::Result<(), BlockstoreProcessorError> {
|
||||||
|
@ -665,7 +683,7 @@ pub fn confirm_slot(
|
||||||
timing: &mut ConfirmationTiming,
|
timing: &mut ConfirmationTiming,
|
||||||
progress: &mut ConfirmationProgress,
|
progress: &mut ConfirmationProgress,
|
||||||
skip_verification: bool,
|
skip_verification: bool,
|
||||||
transaction_status_sender: Option<TransactionStatusSender>,
|
transaction_status_sender: Option<&TransactionStatusSender>,
|
||||||
replay_vote_sender: Option<&ReplayVoteSender>,
|
replay_vote_sender: Option<&ReplayVoteSender>,
|
||||||
entry_callback: Option<&ProcessCallback>,
|
entry_callback: Option<&ProcessCallback>,
|
||||||
recyclers: &VerifyRecyclers,
|
recyclers: &VerifyRecyclers,
|
||||||
|
@ -785,6 +803,7 @@ fn process_bank_0(
|
||||||
blockstore: &Blockstore,
|
blockstore: &Blockstore,
|
||||||
opts: &ProcessOptions,
|
opts: &ProcessOptions,
|
||||||
recyclers: &VerifyRecyclers,
|
recyclers: &VerifyRecyclers,
|
||||||
|
cache_block_time_sender: Option<&CacheBlockTimeSender>,
|
||||||
) {
|
) {
|
||||||
assert_eq!(bank0.slot(), 0);
|
assert_eq!(bank0.slot(), 0);
|
||||||
let mut progress = ConfirmationProgress::new(bank0.last_blockhash());
|
let mut progress = ConfirmationProgress::new(bank0.last_blockhash());
|
||||||
|
@ -800,6 +819,7 @@ fn process_bank_0(
|
||||||
)
|
)
|
||||||
.expect("processing for bank 0 must succeed");
|
.expect("processing for bank 0 must succeed");
|
||||||
bank0.freeze();
|
bank0.freeze();
|
||||||
|
cache_block_time(bank0, cache_block_time_sender);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Given a bank, add its children to the pending slots queue if those children slots are
|
// Given a bank, add its children to the pending slots queue if those children slots are
|
||||||
|
@ -857,6 +877,7 @@ fn process_next_slots(
|
||||||
|
|
||||||
// Iterate through blockstore processing slots starting from the root slot pointed to by the
|
// Iterate through blockstore processing slots starting from the root slot pointed to by the
|
||||||
// given `meta` and return a vector of frozen bank forks
|
// given `meta` and return a vector of frozen bank forks
|
||||||
|
#[allow(clippy::too_many_arguments)]
|
||||||
fn load_frozen_forks(
|
fn load_frozen_forks(
|
||||||
root_bank: &Arc<Bank>,
|
root_bank: &Arc<Bank>,
|
||||||
root_meta: &SlotMeta,
|
root_meta: &SlotMeta,
|
||||||
|
@ -865,7 +886,8 @@ fn load_frozen_forks(
|
||||||
root: &mut Slot,
|
root: &mut Slot,
|
||||||
opts: &ProcessOptions,
|
opts: &ProcessOptions,
|
||||||
recyclers: &VerifyRecyclers,
|
recyclers: &VerifyRecyclers,
|
||||||
transaction_status_sender: Option<TransactionStatusSender>,
|
transaction_status_sender: Option<&TransactionStatusSender>,
|
||||||
|
cache_block_time_sender: Option<&CacheBlockTimeSender>,
|
||||||
timing: &mut ExecuteTimings,
|
timing: &mut ExecuteTimings,
|
||||||
) -> result::Result<Vec<Arc<Bank>>, BlockstoreProcessorError> {
|
) -> result::Result<Vec<Arc<Bank>>, BlockstoreProcessorError> {
|
||||||
let mut initial_forks = HashMap::new();
|
let mut initial_forks = HashMap::new();
|
||||||
|
@ -919,7 +941,8 @@ fn load_frozen_forks(
|
||||||
opts,
|
opts,
|
||||||
recyclers,
|
recyclers,
|
||||||
&mut progress,
|
&mut progress,
|
||||||
transaction_status_sender.clone(),
|
transaction_status_sender,
|
||||||
|
cache_block_time_sender,
|
||||||
None,
|
None,
|
||||||
timing,
|
timing,
|
||||||
)
|
)
|
||||||
|
@ -1077,7 +1100,8 @@ fn process_single_slot(
|
||||||
opts: &ProcessOptions,
|
opts: &ProcessOptions,
|
||||||
recyclers: &VerifyRecyclers,
|
recyclers: &VerifyRecyclers,
|
||||||
progress: &mut ConfirmationProgress,
|
progress: &mut ConfirmationProgress,
|
||||||
transaction_status_sender: Option<TransactionStatusSender>,
|
transaction_status_sender: Option<&TransactionStatusSender>,
|
||||||
|
cache_block_time_sender: Option<&CacheBlockTimeSender>,
|
||||||
replay_vote_sender: Option<&ReplayVoteSender>,
|
replay_vote_sender: Option<&ReplayVoteSender>,
|
||||||
timing: &mut ExecuteTimings,
|
timing: &mut ExecuteTimings,
|
||||||
) -> result::Result<(), BlockstoreProcessorError> {
|
) -> result::Result<(), BlockstoreProcessorError> {
|
||||||
|
@ -1097,6 +1121,7 @@ fn process_single_slot(
|
||||||
})?;
|
})?;
|
||||||
|
|
||||||
bank.freeze(); // all banks handled by this routine are created from complete slots
|
bank.freeze(); // all banks handled by this routine are created from complete slots
|
||||||
|
cache_block_time(bank, cache_block_time_sender);
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
@ -1171,6 +1196,16 @@ impl TransactionStatusSender {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub type CacheBlockTimeSender = Sender<Arc<Bank>>;
|
||||||
|
|
||||||
|
pub fn cache_block_time(bank: &Arc<Bank>, cache_block_time_sender: Option<&CacheBlockTimeSender>) {
|
||||||
|
if let Some(cache_block_time_sender) = cache_block_time_sender {
|
||||||
|
cache_block_time_sender
|
||||||
|
.send(bank.clone())
|
||||||
|
.unwrap_or_else(|err| warn!("cache_block_time_sender failed: {:?}", err));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// used for tests only
|
// used for tests only
|
||||||
pub fn fill_blockstore_slot_with_ticks(
|
pub fn fill_blockstore_slot_with_ticks(
|
||||||
blockstore: &Blockstore,
|
blockstore: &Blockstore,
|
||||||
|
@ -1276,6 +1311,7 @@ pub mod tests {
|
||||||
poh_verify: true,
|
poh_verify: true,
|
||||||
..ProcessOptions::default()
|
..ProcessOptions::default()
|
||||||
},
|
},
|
||||||
|
None,
|
||||||
)
|
)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
assert_eq!(frozen_bank_slots(&bank_forks), vec![0]);
|
assert_eq!(frozen_bank_slots(&bank_forks), vec![0]);
|
||||||
|
@ -1320,6 +1356,7 @@ pub mod tests {
|
||||||
poh_verify: true,
|
poh_verify: true,
|
||||||
..ProcessOptions::default()
|
..ProcessOptions::default()
|
||||||
},
|
},
|
||||||
|
None,
|
||||||
)
|
)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
assert_eq!(frozen_bank_slots(&bank_forks), vec![0]);
|
assert_eq!(frozen_bank_slots(&bank_forks), vec![0]);
|
||||||
|
@ -1336,6 +1373,7 @@ pub mod tests {
|
||||||
poh_verify: true,
|
poh_verify: true,
|
||||||
..ProcessOptions::default()
|
..ProcessOptions::default()
|
||||||
},
|
},
|
||||||
|
None,
|
||||||
)
|
)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
|
||||||
|
@ -1391,7 +1429,7 @@ pub mod tests {
|
||||||
..ProcessOptions::default()
|
..ProcessOptions::default()
|
||||||
};
|
};
|
||||||
let (bank_forks, _leader_schedule) =
|
let (bank_forks, _leader_schedule) =
|
||||||
process_blockstore(&genesis_config, &blockstore, Vec::new(), opts).unwrap();
|
process_blockstore(&genesis_config, &blockstore, Vec::new(), opts, None).unwrap();
|
||||||
assert_eq!(frozen_bank_slots(&bank_forks), vec![0]);
|
assert_eq!(frozen_bank_slots(&bank_forks), vec![0]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1456,7 +1494,7 @@ pub mod tests {
|
||||||
..ProcessOptions::default()
|
..ProcessOptions::default()
|
||||||
};
|
};
|
||||||
let (bank_forks, _leader_schedule) =
|
let (bank_forks, _leader_schedule) =
|
||||||
process_blockstore(&genesis_config, &blockstore, Vec::new(), opts).unwrap();
|
process_blockstore(&genesis_config, &blockstore, Vec::new(), opts, None).unwrap();
|
||||||
|
|
||||||
assert_eq!(frozen_bank_slots(&bank_forks), vec![0]); // slot 1 isn't "full", we stop at slot zero
|
assert_eq!(frozen_bank_slots(&bank_forks), vec![0]); // slot 1 isn't "full", we stop at slot zero
|
||||||
|
|
||||||
|
@ -1475,7 +1513,7 @@ pub mod tests {
|
||||||
fill_blockstore_slot_with_ticks(&blockstore, ticks_per_slot, 3, 0, blockhash);
|
fill_blockstore_slot_with_ticks(&blockstore, ticks_per_slot, 3, 0, blockhash);
|
||||||
// Slot 0 should not show up in the ending bank_forks_info
|
// Slot 0 should not show up in the ending bank_forks_info
|
||||||
let (bank_forks, _leader_schedule) =
|
let (bank_forks, _leader_schedule) =
|
||||||
process_blockstore(&genesis_config, &blockstore, Vec::new(), opts).unwrap();
|
process_blockstore(&genesis_config, &blockstore, Vec::new(), opts, None).unwrap();
|
||||||
|
|
||||||
// slot 1 isn't "full", we stop at slot zero
|
// slot 1 isn't "full", we stop at slot zero
|
||||||
assert_eq!(frozen_bank_slots(&bank_forks), vec![0, 3]);
|
assert_eq!(frozen_bank_slots(&bank_forks), vec![0, 3]);
|
||||||
|
@ -1542,7 +1580,7 @@ pub mod tests {
|
||||||
..ProcessOptions::default()
|
..ProcessOptions::default()
|
||||||
};
|
};
|
||||||
let (bank_forks, _leader_schedule) =
|
let (bank_forks, _leader_schedule) =
|
||||||
process_blockstore(&genesis_config, &blockstore, Vec::new(), opts).unwrap();
|
process_blockstore(&genesis_config, &blockstore, Vec::new(), opts, None).unwrap();
|
||||||
|
|
||||||
// One fork, other one is ignored b/c not a descendant of the root
|
// One fork, other one is ignored b/c not a descendant of the root
|
||||||
assert_eq!(frozen_bank_slots(&bank_forks), vec![4]);
|
assert_eq!(frozen_bank_slots(&bank_forks), vec![4]);
|
||||||
|
@ -1621,7 +1659,7 @@ pub mod tests {
|
||||||
..ProcessOptions::default()
|
..ProcessOptions::default()
|
||||||
};
|
};
|
||||||
let (bank_forks, _leader_schedule) =
|
let (bank_forks, _leader_schedule) =
|
||||||
process_blockstore(&genesis_config, &blockstore, Vec::new(), opts).unwrap();
|
process_blockstore(&genesis_config, &blockstore, Vec::new(), opts, None).unwrap();
|
||||||
|
|
||||||
assert_eq!(frozen_bank_slots(&bank_forks), vec![1, 2, 3, 4]);
|
assert_eq!(frozen_bank_slots(&bank_forks), vec![1, 2, 3, 4]);
|
||||||
assert_eq!(bank_forks.working_bank().slot(), 4);
|
assert_eq!(bank_forks.working_bank().slot(), 4);
|
||||||
|
@ -1681,6 +1719,7 @@ pub mod tests {
|
||||||
&blockstore,
|
&blockstore,
|
||||||
Vec::new(),
|
Vec::new(),
|
||||||
ProcessOptions::default(),
|
ProcessOptions::default(),
|
||||||
|
None,
|
||||||
)
|
)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
|
||||||
|
@ -1730,6 +1769,7 @@ pub mod tests {
|
||||||
&blockstore,
|
&blockstore,
|
||||||
Vec::new(),
|
Vec::new(),
|
||||||
ProcessOptions::default(),
|
ProcessOptions::default(),
|
||||||
|
None,
|
||||||
)
|
)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
|
||||||
|
@ -1782,6 +1822,7 @@ pub mod tests {
|
||||||
&blockstore,
|
&blockstore,
|
||||||
Vec::new(),
|
Vec::new(),
|
||||||
ProcessOptions::default(),
|
ProcessOptions::default(),
|
||||||
|
None,
|
||||||
)
|
)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
|
||||||
|
@ -1832,7 +1873,7 @@ pub mod tests {
|
||||||
..ProcessOptions::default()
|
..ProcessOptions::default()
|
||||||
};
|
};
|
||||||
let (bank_forks, _leader_schedule) =
|
let (bank_forks, _leader_schedule) =
|
||||||
process_blockstore(&genesis_config, &blockstore, Vec::new(), opts).unwrap();
|
process_blockstore(&genesis_config, &blockstore, Vec::new(), opts, None).unwrap();
|
||||||
|
|
||||||
// There is one fork, head is last_slot + 1
|
// There is one fork, head is last_slot + 1
|
||||||
assert_eq!(frozen_bank_slots(&bank_forks), vec![last_slot + 1]);
|
assert_eq!(frozen_bank_slots(&bank_forks), vec![last_slot + 1]);
|
||||||
|
@ -1976,7 +2017,7 @@ pub mod tests {
|
||||||
..ProcessOptions::default()
|
..ProcessOptions::default()
|
||||||
};
|
};
|
||||||
let (bank_forks, _leader_schedule) =
|
let (bank_forks, _leader_schedule) =
|
||||||
process_blockstore(&genesis_config, &blockstore, Vec::new(), opts).unwrap();
|
process_blockstore(&genesis_config, &blockstore, Vec::new(), opts, None).unwrap();
|
||||||
|
|
||||||
assert_eq!(frozen_bank_slots(&bank_forks), vec![0, 1]);
|
assert_eq!(frozen_bank_slots(&bank_forks), vec![0, 1]);
|
||||||
assert_eq!(bank_forks.root(), 0);
|
assert_eq!(bank_forks.root(), 0);
|
||||||
|
@ -2005,7 +2046,7 @@ pub mod tests {
|
||||||
..ProcessOptions::default()
|
..ProcessOptions::default()
|
||||||
};
|
};
|
||||||
let (bank_forks, _leader_schedule) =
|
let (bank_forks, _leader_schedule) =
|
||||||
process_blockstore(&genesis_config, &blockstore, Vec::new(), opts).unwrap();
|
process_blockstore(&genesis_config, &blockstore, Vec::new(), opts, None).unwrap();
|
||||||
|
|
||||||
assert_eq!(frozen_bank_slots(&bank_forks), vec![0]);
|
assert_eq!(frozen_bank_slots(&bank_forks), vec![0]);
|
||||||
let bank = bank_forks[0].clone();
|
let bank = bank_forks[0].clone();
|
||||||
|
@ -2022,7 +2063,7 @@ pub mod tests {
|
||||||
override_num_threads: Some(1),
|
override_num_threads: Some(1),
|
||||||
..ProcessOptions::default()
|
..ProcessOptions::default()
|
||||||
};
|
};
|
||||||
process_blockstore(&genesis_config, &blockstore, Vec::new(), opts).unwrap();
|
process_blockstore(&genesis_config, &blockstore, Vec::new(), opts, None).unwrap();
|
||||||
PAR_THREAD_POOL.with(|pool| {
|
PAR_THREAD_POOL.with(|pool| {
|
||||||
assert_eq!(pool.borrow().current_num_threads(), 1);
|
assert_eq!(pool.borrow().current_num_threads(), 1);
|
||||||
});
|
});
|
||||||
|
@ -2039,7 +2080,7 @@ pub mod tests {
|
||||||
..ProcessOptions::default()
|
..ProcessOptions::default()
|
||||||
};
|
};
|
||||||
let (_bank_forks, leader_schedule) =
|
let (_bank_forks, leader_schedule) =
|
||||||
process_blockstore(&genesis_config, &blockstore, Vec::new(), opts).unwrap();
|
process_blockstore(&genesis_config, &blockstore, Vec::new(), opts, None).unwrap();
|
||||||
assert_eq!(leader_schedule.max_schedules(), std::usize::MAX);
|
assert_eq!(leader_schedule.max_schedules(), std::usize::MAX);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2099,7 +2140,7 @@ pub mod tests {
|
||||||
entry_callback: Some(entry_callback),
|
entry_callback: Some(entry_callback),
|
||||||
..ProcessOptions::default()
|
..ProcessOptions::default()
|
||||||
};
|
};
|
||||||
process_blockstore(&genesis_config, &blockstore, Vec::new(), opts).unwrap();
|
process_blockstore(&genesis_config, &blockstore, Vec::new(), opts, None).unwrap();
|
||||||
assert_eq!(*callback_counter.write().unwrap(), 2);
|
assert_eq!(*callback_counter.write().unwrap(), 2);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2753,7 +2794,7 @@ pub mod tests {
|
||||||
..ProcessOptions::default()
|
..ProcessOptions::default()
|
||||||
};
|
};
|
||||||
let (bank_forks, _leader_schedule) =
|
let (bank_forks, _leader_schedule) =
|
||||||
process_blockstore(&genesis_config, &blockstore, Vec::new(), opts).unwrap();
|
process_blockstore(&genesis_config, &blockstore, Vec::new(), opts, None).unwrap();
|
||||||
|
|
||||||
// Should be able to fetch slot 0 because we specified halting at slot 0, even
|
// Should be able to fetch slot 0 because we specified halting at slot 0, even
|
||||||
// if there is a greater root at slot 1.
|
// if there is a greater root at slot 1.
|
||||||
|
@ -2803,7 +2844,7 @@ pub mod tests {
|
||||||
..ProcessOptions::default()
|
..ProcessOptions::default()
|
||||||
};
|
};
|
||||||
let recyclers = VerifyRecyclers::default();
|
let recyclers = VerifyRecyclers::default();
|
||||||
process_bank_0(&bank0, &blockstore, &opts, &recyclers);
|
process_bank_0(&bank0, &blockstore, &opts, &recyclers, None);
|
||||||
let bank1 = Arc::new(Bank::new_from_parent(&bank0, &Pubkey::default(), 1));
|
let bank1 = Arc::new(Bank::new_from_parent(&bank0, &Pubkey::default(), 1));
|
||||||
confirm_full_slot(
|
confirm_full_slot(
|
||||||
&blockstore,
|
&blockstore,
|
||||||
|
@ -2820,7 +2861,8 @@ pub mod tests {
|
||||||
|
|
||||||
// Test process_blockstore_from_root() from slot 1 onwards
|
// Test process_blockstore_from_root() from slot 1 onwards
|
||||||
let (bank_forks, _leader_schedule) =
|
let (bank_forks, _leader_schedule) =
|
||||||
do_process_blockstore_from_root(&blockstore, bank1, &opts, &recyclers, None).unwrap();
|
do_process_blockstore_from_root(&blockstore, bank1, &opts, &recyclers, None, None)
|
||||||
|
.unwrap();
|
||||||
|
|
||||||
assert_eq!(frozen_bank_slots(&bank_forks), vec![5, 6]);
|
assert_eq!(frozen_bank_slots(&bank_forks), vec![5, 6]);
|
||||||
assert_eq!(bank_forks.working_bank().slot(), 6);
|
assert_eq!(bank_forks.working_bank().slot(), 6);
|
||||||
|
@ -3247,7 +3289,8 @@ pub mod tests {
|
||||||
..ProcessOptions::default()
|
..ProcessOptions::default()
|
||||||
};
|
};
|
||||||
let (bank_forks, _leader_schedule) =
|
let (bank_forks, _leader_schedule) =
|
||||||
process_blockstore(&genesis_config, &blockstore, Vec::new(), opts.clone()).unwrap();
|
process_blockstore(&genesis_config, &blockstore, Vec::new(), opts.clone(), None)
|
||||||
|
.unwrap();
|
||||||
|
|
||||||
// prepare to add votes
|
// prepare to add votes
|
||||||
let last_vote_bank_hash = bank_forks.get(last_main_fork_slot - 1).unwrap().hash();
|
let last_vote_bank_hash = bank_forks.get(last_main_fork_slot - 1).unwrap().hash();
|
||||||
|
@ -3279,7 +3322,8 @@ pub mod tests {
|
||||||
);
|
);
|
||||||
|
|
||||||
let (bank_forks, _leader_schedule) =
|
let (bank_forks, _leader_schedule) =
|
||||||
process_blockstore(&genesis_config, &blockstore, Vec::new(), opts.clone()).unwrap();
|
process_blockstore(&genesis_config, &blockstore, Vec::new(), opts.clone(), None)
|
||||||
|
.unwrap();
|
||||||
|
|
||||||
assert_eq!(bank_forks.root(), expected_root_slot);
|
assert_eq!(bank_forks.root(), expected_root_slot);
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
|
@ -3334,7 +3378,7 @@ pub mod tests {
|
||||||
);
|
);
|
||||||
|
|
||||||
let (bank_forks, _leader_schedule) =
|
let (bank_forks, _leader_schedule) =
|
||||||
process_blockstore(&genesis_config, &blockstore, Vec::new(), opts).unwrap();
|
process_blockstore(&genesis_config, &blockstore, Vec::new(), opts, None).unwrap();
|
||||||
|
|
||||||
assert_eq!(bank_forks.root(), really_expected_root_slot);
|
assert_eq!(bank_forks.root(), really_expected_root_slot);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue