Better dupe detection (#13992)

This commit is contained in:
sakridge
2020-12-09 23:14:31 -08:00
committed by GitHub
parent 8d1651c8ad
commit c5fe076432
6 changed files with 380 additions and 114 deletions

View File

@ -989,29 +989,43 @@ impl ReplayStage {
// errors related to the slot being purged
let slot = bank.slot();
warn!("Fatal replay error in slot: {}, err: {:?}", slot, err);
if let BlockstoreProcessorError::InvalidBlock(BlockError::InvalidTickCount) = err {
datapoint_info!(
"replay-stage-mark_dead_slot",
("error", format!("error: {:?}", err), String),
("slot", slot, i64)
);
} else {
datapoint_error!(
"replay-stage-mark_dead_slot",
("error", format!("error: {:?}", err), String),
("slot", slot, i64)
);
}
bank_progress.is_dead = true;
blockstore
.set_dead_slot(slot)
.expect("Failed to mark slot as dead in blockstore");
let is_serious = matches!(
err,
BlockstoreProcessorError::InvalidBlock(BlockError::InvalidTickCount)
);
Self::mark_dead_slot(blockstore, bank_progress, slot, &err, is_serious);
err
})?;
Ok(tx_count)
}
fn mark_dead_slot(
blockstore: &Blockstore,
bank_progress: &mut ForkProgress,
slot: Slot,
err: &BlockstoreProcessorError,
is_serious: bool,
) {
if is_serious {
datapoint_error!(
"replay-stage-mark_dead_slot",
("error", format!("error: {:?}", err), String),
("slot", slot, i64)
);
} else {
datapoint_info!(
"replay-stage-mark_dead_slot",
("error", format!("error: {:?}", err), String),
("slot", slot, i64)
);
}
bank_progress.is_dead = true;
blockstore
.set_dead_slot(slot)
.expect("Failed to mark slot as dead in blockstore");
}
#[allow(clippy::too_many_arguments)]
fn handle_votable_bank(
bank: &Arc<Bank>,
@ -1323,23 +1337,40 @@ impl ReplayStage {
}
assert_eq!(*bank_slot, bank.slot());
if bank.is_complete() {
bank_progress.replay_stats.report_stats(
bank.slot(),
bank_progress.replay_progress.num_entries,
bank_progress.replay_progress.num_shreds,
);
did_complete_bank = true;
info!("bank frozen: {}", bank.slot());
bank.freeze();
heaviest_subtree_fork_choice
.add_new_leaf_slot(bank.slot(), Some(bank.parent_slot()));
if let Some(sender) = bank_notification_sender {
sender
.send(BankNotification::Frozen(bank.clone()))
.unwrap_or_else(|err| warn!("bank_notification_sender failed: {:?}", err));
}
if !blockstore.has_duplicate_shreds_in_slot(bank.slot()) {
bank_progress.replay_stats.report_stats(
bank.slot(),
bank_progress.replay_progress.num_entries,
bank_progress.replay_progress.num_shreds,
);
did_complete_bank = true;
info!("bank frozen: {}", bank.slot());
bank.freeze();
heaviest_subtree_fork_choice
.add_new_leaf_slot(bank.slot(), Some(bank.parent_slot()));
if let Some(sender) = bank_notification_sender {
sender
.send(BankNotification::Frozen(bank.clone()))
.unwrap_or_else(|err| {
warn!("bank_notification_sender failed: {:?}", err)
});
}
Self::record_rewards(&bank, &rewards_recorder_sender);
Self::record_rewards(&bank, &rewards_recorder_sender);
} else {
Self::mark_dead_slot(
blockstore,
bank_progress,
bank.slot(),
&BlockstoreProcessorError::InvalidBlock(BlockError::DuplicateBlock),
true,
);
warn!(
"{} duplicate shreds detected, not freezing bank {}",
my_pubkey,
bank.slot()
);
}
} else {
trace!(
"bank {} not completed tick_height: {}, max_tick_height: {}",

View File

@ -305,7 +305,7 @@ mod tests {
assert!(!packet.meta.discard);
let coding =
solana_ledger::shred::Shredder::generate_coding_shreds(slot, 1.0f32, &[shred], 10);
solana_ledger::shred::Shredder::generate_coding_shreds(slot, 1.0f32, &[shred], 10, 1);
coding[0].copy_to_packet(&mut packet);
ShredFetchStage::process_packet(
&mut packet,