Hold an accounts_db read lock as briefly as possible to avoid deadlocking

This commit is contained in:
Michael Vines
2019-01-13 10:47:29 -08:00
parent d28b643c84
commit 74e503da92

View File

@ -36,38 +36,40 @@ impl ComputeLeaderConfirmationService {
) -> result::Result<u64, ConfirmationError> { ) -> result::Result<u64, ConfirmationError> {
let mut total_stake = 0; let mut total_stake = 0;
let mut ticks_and_stakes: Vec<(u64, u64)> = { // Hold an accounts_db read lock as briefly as possible, just long enough to collect all
let bank_accounts = bank.accounts.accounts_db.read().unwrap(); // the vote states
// TODO: Doesn't account for duplicates since a single validator could potentially register let vote_states: Vec<VoteProgram> = bank
// multiple vote accounts. Once that is no longer possible (see the TODO in vote_program.rs, .accounts
// process_transaction(), case VoteInstruction::RegisterAccount), this will be more accurate. .accounts_db
// See github issue 1654. .read()
bank_accounts .unwrap()
.accounts .accounts
.values() .values()
.filter_map(|account| { .filter_map(|account| {
// Filter out any accounts that don't belong to the VoteProgram
// by returning None
if vote_program::check_id(&account.owner) { if vote_program::check_id(&account.owner) {
if let Ok(vote_state) = VoteProgram::deserialize(&account.userdata) { if let Ok(vote_state) = VoteProgram::deserialize(&account.userdata) {
if leader_id == vote_state.node_id { if leader_id != vote_state.node_id {
return None; return Some(vote_state);
} }
}
}
None
})
.collect();
let mut ticks_and_stakes: Vec<(u64, u64)> = vote_states
.iter()
.filter_map(|vote_state| {
let validator_stake = bank.get_stake(&vote_state.node_id); let validator_stake = bank.get_stake(&vote_state.node_id);
total_stake += validator_stake; total_stake += validator_stake;
// Filter out any validators that don't have at least one vote // Filter out any validators that don't have at least one vote
// by returning None // by returning None
return vote_state vote_state
.votes .votes
.back() .back()
.map(|vote| (vote.tick_height, validator_stake)); .map(|vote| (vote.tick_height, validator_stake))
}
}
None
}) })
.collect() .collect();
};
let super_majority_stake = (2 * total_stake) / 3; let super_majority_stake = (2 * total_stake) / 3;