Hold an accounts_db read lock as briefly as possible to avoid deadlocking
This commit is contained in:
@ -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;
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user