caches vote-state de-serialized from vote accounts (#13795)

Gossip and other places repeatedly de-serialize vote-state stored in
vote accounts. Ideally the first de-serialization should cache the
result.

This commit adds new VoteAccount type which lazily de-serializes
VoteState from Account data and caches the result internally.

Serialize and Deserialize traits are manually implemented to match
existing code. So, despite changes to frozen_abi, this commit should be
backward compatible.
This commit is contained in:
behzad nouri
2020-11-30 17:18:33 +00:00
committed by GitHub
parent 6203d1c94c
commit e1793e5a13
18 changed files with 433 additions and 198 deletions

View File

@ -299,6 +299,7 @@ fn graph_forks(bank_forks: &BankForks, include_all_votes: bool) -> String {
// Search all forks and collect the last vote made by each validator
let mut last_votes = HashMap::new();
let default_vote_state = VoteState::default();
for fork_slot in &fork_slots {
let bank = &bank_forks[*fork_slot];
@ -308,7 +309,8 @@ fn graph_forks(bank_forks: &BankForks, include_all_votes: bool) -> String {
.map(|(_, (stake, _))| stake)
.sum();
for (_, (stake, vote_account)) in bank.vote_accounts() {
let vote_state = VoteState::from(&vote_account).unwrap_or_default();
let vote_state = vote_account.vote_state();
let vote_state = vote_state.as_ref().unwrap_or(&default_vote_state);
if let Some(last_vote) = vote_state.votes.iter().last() {
let entry = last_votes.entry(vote_state.node_pubkey).or_insert((
last_vote.slot,
@ -317,7 +319,7 @@ fn graph_forks(bank_forks: &BankForks, include_all_votes: bool) -> String {
total_stake,
));
if entry.0 < last_vote.slot {
*entry = (last_vote.slot, vote_state, stake, total_stake);
*entry = (last_vote.slot, vote_state.clone(), stake, total_stake);
}
}
}
@ -348,7 +350,8 @@ fn graph_forks(bank_forks: &BankForks, include_all_votes: bool) -> String {
let mut first = true;
loop {
for (_, (_, vote_account)) in bank.vote_accounts() {
let vote_state = VoteState::from(&vote_account).unwrap_or_default();
let vote_state = vote_account.vote_state();
let vote_state = vote_state.as_ref().unwrap_or(&default_vote_state);
if let Some(last_vote) = vote_state.votes.iter().last() {
let validator_votes = all_votes.entry(vote_state.node_pubkey).or_default();
validator_votes