-
Notifications
You must be signed in to change notification settings - Fork 4.5k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Stabilize some banking stage tests #6251
Changes from 3 commits
2262ee1
9df5ba3
b9a248a
cf6d0b0
a9138d1
b07bf58
5a39891
cef4770
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -928,14 +928,15 @@ impl Service for BankingStage { | |
pub fn create_test_recorder( | ||
bank: &Arc<Bank>, | ||
blocktree: &Arc<Blocktree>, | ||
poh_config: Option<PohConfig>, | ||
) -> ( | ||
Arc<AtomicBool>, | ||
Arc<Mutex<PohRecorder>>, | ||
PohService, | ||
Receiver<WorkingBankEntry>, | ||
) { | ||
let exit = Arc::new(AtomicBool::new(false)); | ||
let poh_config = Arc::new(PohConfig::default()); | ||
let poh_config = Arc::new(poh_config.unwrap_or_default()); | ||
let (mut poh_recorder, entry_receiver) = PohRecorder::new( | ||
bank.tick_height(), | ||
bank.last_blockhash(), | ||
|
@@ -986,7 +987,7 @@ mod tests { | |
Blocktree::open(&ledger_path).expect("Expected to be able to open database ledger"), | ||
); | ||
let (exit, poh_recorder, poh_service, _entry_receiever) = | ||
create_test_recorder(&bank, &blocktree); | ||
create_test_recorder(&bank, &blocktree, None); | ||
let cluster_info = ClusterInfo::new_with_invalid_keypair(Node::new_localhost().info); | ||
let cluster_info = Arc::new(RwLock::new(cluster_info)); | ||
let banking_stage = BankingStage::new( | ||
|
@@ -1020,8 +1021,10 @@ mod tests { | |
let blocktree = Arc::new( | ||
Blocktree::open(&ledger_path).expect("Expected to be able to open database ledger"), | ||
); | ||
let mut poh_config = PohConfig::default(); | ||
poh_config.target_tick_count = Some(6); | ||
let (exit, poh_recorder, poh_service, entry_receiver) = | ||
create_test_recorder(&bank, &blocktree); | ||
create_test_recorder(&bank, &blocktree, Some(poh_config)); | ||
let cluster_info = ClusterInfo::new_with_invalid_keypair(Node::new_localhost().info); | ||
let cluster_info = Arc::new(RwLock::new(cluster_info)); | ||
let banking_stage = BankingStage::new( | ||
|
@@ -1031,7 +1034,6 @@ mod tests { | |
vote_receiver, | ||
); | ||
trace!("sending bank"); | ||
sleep(Duration::from_millis(600)); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Because |
||
drop(verified_sender); | ||
drop(vote_sender); | ||
exit.store(true, Ordering::Relaxed); | ||
|
@@ -1069,8 +1071,11 @@ mod tests { | |
let blocktree = Arc::new( | ||
Blocktree::open(&ledger_path).expect("Expected to be able to open database ledger"), | ||
); | ||
let mut poh_config = PohConfig::default(); | ||
// limit the tick to 1 to prevent clearing working_bank at PohRecord then PohRecorderError(MaxHeightReached) at BankingStage | ||
poh_config.target_tick_count = Some(1); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Instead of the magic number 1, can we use something like genesis_block.ticks_per_slot - 1, to make it clear that there's nothing special about this number, it just needs to be < genesis_block.ticks_per_slot There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. sure thing! done at a9138d1 There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Well, I couldn't directly use genesis_block.ticks_per_slot because subtracting -1 from it still causes the race condition, so I chose different one: b07bf58 |
||
let (exit, poh_recorder, poh_service, entry_receiver) = | ||
create_test_recorder(&bank, &blocktree); | ||
create_test_recorder(&bank, &blocktree, Some(poh_config)); | ||
let cluster_info = ClusterInfo::new_with_invalid_keypair(Node::new_localhost().info); | ||
let cluster_info = Arc::new(RwLock::new(cluster_info)); | ||
let banking_stage = BankingStage::new( | ||
|
@@ -1120,6 +1125,9 @@ mod tests { | |
|
||
drop(verified_sender); | ||
drop(vote_sender); | ||
// wait until banking_stage to finish up all packets | ||
banking_stage.join().unwrap(); | ||
|
||
exit.store(true, Ordering::Relaxed); | ||
poh_service.join().unwrap(); | ||
drop(poh_recorder); | ||
|
@@ -1128,18 +1136,20 @@ mod tests { | |
let bank = Bank::new(&genesis_block); | ||
bank.process_transaction(&fund_tx).unwrap(); | ||
//receive entries + ticks | ||
for _ in 0..10 { | ||
loop { | ||
let entries: Vec<Entry> = entry_receiver | ||
.iter() | ||
.map(|(_bank, (entry, _tick_height))| entry) | ||
.collect(); | ||
|
||
assert!(entries.verify(&blockhash)); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. this assertion should be moved inside the newly-added empty guard if clause. |
||
blockhash = entries.last().unwrap().hash; | ||
for entry in entries { | ||
bank.process_transactions(&entry.transactions) | ||
.iter() | ||
.for_each(|x| assert_eq!(*x, Ok(()))); | ||
if !entries.is_empty() { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Under high load, I observed empty entries are returned. |
||
blockhash = entries.last().unwrap().hash; | ||
for entry in entries { | ||
bank.process_transactions(&entry.transactions) | ||
.iter() | ||
.for_each(|x| assert_eq!(*x, Ok(()))); | ||
} | ||
} | ||
|
||
if bank.get_balance(&to) == 1 { | ||
|
@@ -1153,13 +1163,11 @@ mod tests { | |
assert_eq!(bank.get_balance(&to2), 0); | ||
|
||
drop(entry_receiver); | ||
banking_stage.join().unwrap(); | ||
} | ||
Blocktree::destroy(&ledger_path).unwrap(); | ||
} | ||
|
||
#[test] | ||
#[ignore] | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yay! |
||
fn test_banking_stage_entryfication() { | ||
solana_logger::setup(); | ||
// In this attack we'll demonstrate that a verifier can interpret the ledger | ||
|
@@ -1212,8 +1220,11 @@ mod tests { | |
Blocktree::open(&ledger_path) | ||
.expect("Expected to be able to open database ledger"), | ||
); | ||
let mut poh_config = PohConfig::default(); | ||
// limit the tick to 1 to prevent clearing working_bank at PohRecord then PohRecorderError(MaxHeightReached) at BankingStage | ||
poh_config.target_tick_count = Some(1); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Good catch, quite a subtle bug, especially for your first time through the code base :) Instead of the magic number 1, can we use something like There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. sure thing! done at a9138d1 There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Well, I couldn't directly use genesis_block.ticks_per_slot because subtracting -1 from it still causes the race condition, so I chose different one: b07bf58 There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @ryoqun, ah yes, it's because of a special case where slot 0 generates one less tick than all the other slots. For instance, if This open PR here actually will address this issue: #6263, if you are curious and want to take a look :D There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Thanks for very detailed explanation! I'll look at it. :D |
||
let (exit, poh_recorder, poh_service, entry_receiver) = | ||
create_test_recorder(&bank, &blocktree); | ||
create_test_recorder(&bank, &blocktree, Some(poh_config)); | ||
let cluster_info = | ||
ClusterInfo::new_with_invalid_keypair(Node::new_localhost().info); | ||
let cluster_info = Arc::new(RwLock::new(cluster_info)); | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The purpose of this test is to check that the number of ticks output is
genesis_block.ticks_per_slot
, no matter how many extra ticks are sent by the PohService. For clarity, instead of the magic number 6, can we write this asgenesis_block.ticks_per_slot + num_extra_ticks
for some numbernum_extra_ticks
?There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
sure thing! done at a9138d1
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You were right 😄 for the same reasons as you found in the other cases listed below, this should also use
bank.max_tick_height()
instead ofgenesis_block.ticks_per_slot
for clarity and consistencyThere was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nice catch! done cef4770