Fix freeze and register_tick race (#6799)

* Fix freeze and register_tick race

* Add test
This commit is contained in:
carllin 2019-11-08 17:21:17 -08:00 committed by GitHub
parent d1daeb44e6
commit 91be35731c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 46 additions and 4 deletions

View File

@ -795,12 +795,13 @@ impl Bank {
// TODO: put this assert back in
// assert!(!self.is_frozen());
inc_new_counter_debug!("bank-register_tick-registered", 1);
// Grab blockhash lock before incrementing tick height so that replay stage does
// not attempt to freeze after observing the last tick and before blockhash is
// updated
let mut w_blockhash_queue = self.blockhash_queue.write().unwrap();
let current_tick_height = self.tick_height.fetch_add(1, Ordering::Relaxed) as u64;
if self.is_block_boundary(current_tick_height + 1) {
self.blockhash_queue
.write()
.unwrap()
.register_hash(hash, &self.fee_calculator);
w_blockhash_queue.register_hash(hash, &self.fee_calculator);
}
}

41
runtime/tests/bank.rs Normal file
View File

@ -0,0 +1,41 @@
use solana_runtime::bank::Bank;
use solana_sdk::genesis_block::create_genesis_block;
use solana_sdk::hash::hash;
use solana_sdk::pubkey::Pubkey;
use std::sync::Arc;
use std::thread::Builder;
#[test]
fn test_race_register_tick_freeze() {
solana_logger::setup();
let (mut genesis_block, _) = create_genesis_block(50);
genesis_block.ticks_per_slot = 1;
let p = Pubkey::new_rand();
let hash = hash(p.as_ref());
for _ in 0..1000 {
let bank0 = Arc::new(Bank::new(&genesis_block));
let bank0_ = bank0.clone();
let freeze_thread = Builder::new()
.name("freeze".to_string())
.spawn(move || loop {
if bank0_.tick_height() == bank0_.max_tick_height() {
assert_eq!(bank0_.last_blockhash(), hash);
break;
}
})
.unwrap();
let bank0_ = bank0.clone();
let register_tick_thread = Builder::new()
.name("register_tick".to_string())
.spawn(move || {
bank0_.register_tick(&hash);
})
.unwrap();
register_tick_thread.join().unwrap();
freeze_thread.join().unwrap();
}
}