flag end-of-slot when poh bank is gone (backport #23069) (#23174)

* flag end-of-slot when poh bank is gone

(cherry picked from commit 03bf66a51b)

# Conflicts:
#	core/src/banking_stage.rs

* merge fix

Co-authored-by: Tao Zhu <tao@solana.com>
This commit is contained in:
mergify[bot]
2022-02-16 18:08:03 +00:00
committed by GitHub
parent 68934353f2
commit 41bbc11a46

View File

@ -316,6 +316,12 @@ pub struct BatchedTransactionCostDetails {
pub batched_execute_cost: u64, pub batched_execute_cost: u64,
} }
#[derive(Debug, Default)]
struct EndOfSlot {
next_slot_leader: Option<Pubkey>,
working_bank: Option<Arc<Bank>>,
}
/// Stores the stage's thread handle and output receiver. /// Stores the stage's thread handle and output receiver.
pub struct BankingStage { pub struct BankingStage {
bank_thread_hdls: Vec<JoinHandle<()>>, bank_thread_hdls: Vec<JoinHandle<()>>,
@ -510,22 +516,25 @@ impl BankingStage {
let mut consumed_buffered_packets_count = 0; let mut consumed_buffered_packets_count = 0;
let buffered_packet_batches_len = buffered_packet_batches.len(); let buffered_packet_batches_len = buffered_packet_batches.len();
let mut proc_start = Measure::start("consume_buffered_process"); let mut proc_start = Measure::start("consume_buffered_process");
let mut reached_end_of_slot = None; let mut reached_end_of_slot: Option<EndOfSlot> = None;
buffered_packet_batches.retain_mut(|buffered_packet_batch_and_offsets| { buffered_packet_batches.retain_mut(|buffered_packet_batch_and_offsets| {
let (packet_batch, ref mut original_unprocessed_indexes, _forwarded) = let (packet_batch, ref mut original_unprocessed_indexes, _forwarded) =
buffered_packet_batch_and_offsets; buffered_packet_batch_and_offsets;
if let Some((next_leader, bank)) = &reached_end_of_slot { if let Some(end_of_slot) = &reached_end_of_slot {
// We've hit the end of this slot, no need to perform more processing, // We've hit the end of this slot, no need to perform more processing,
// just filter the remaining packets for the invalid (e.g. too old) ones // just filter the remaining packets for the invalid (e.g. too old) ones
// if the working_bank is available
if let Some(bank) = &end_of_slot.working_bank {
let new_unprocessed_indexes = Self::filter_unprocessed_packets_at_end_of_slot( let new_unprocessed_indexes = Self::filter_unprocessed_packets_at_end_of_slot(
bank, bank,
packet_batch, packet_batch,
original_unprocessed_indexes, original_unprocessed_indexes,
my_pubkey, my_pubkey,
*next_leader, end_of_slot.next_slot_leader,
banking_stage_stats, banking_stage_stats,
); );
let end_of_slot_filtered_invalid_count = original_unprocessed_indexes let end_of_slot_filtered_invalid_count = original_unprocessed_indexes
.len() .len()
.saturating_sub(new_unprocessed_indexes.len()); .saturating_sub(new_unprocessed_indexes.len());
@ -542,6 +551,9 @@ impl BankingStage {
original_unprocessed_indexes, original_unprocessed_indexes,
new_unprocessed_indexes, new_unprocessed_indexes,
) )
} else {
true
}
} else { } else {
let bank_start = poh_recorder.lock().unwrap().bank_start(); let bank_start = poh_recorder.lock().unwrap().bank_start();
if let Some(BankStart { if let Some(BankStart {
@ -573,10 +585,10 @@ impl BankingStage {
max_tx_ingestion_ns, max_tx_ingestion_ns,
) )
{ {
reached_end_of_slot = Some(( reached_end_of_slot = Some(EndOfSlot {
poh_recorder.lock().unwrap().next_slot_leader(), next_slot_leader: poh_recorder.lock().unwrap().next_slot_leader(),
working_bank, working_bank: Some(working_bank),
)); });
} }
// The difference between all transactions passed to execution and the ones that // The difference between all transactions passed to execution and the ones that
@ -603,6 +615,13 @@ impl BankingStage {
} }
has_more_unprocessed_transactions has_more_unprocessed_transactions
} else { } else {
// mark as end-of-slot to avoid aggressively lock poh for the remaining for
// packet batches in buffer
reached_end_of_slot = Some(EndOfSlot {
next_slot_leader: poh_recorder.lock().unwrap().next_slot_leader(),
working_bank: None,
});
// `original_unprocessed_indexes` must have remaining packets to process // `original_unprocessed_indexes` must have remaining packets to process
// if not yet processed. // if not yet processed.
assert!(Self::packet_has_more_unprocessed_transactions( assert!(Self::packet_has_more_unprocessed_transactions(