Initailize locktower with heaviest bank (#3489)

This commit is contained in:
carllin 2019-03-25 20:00:11 -07:00 committed by GitHub
parent 4d34102d9c
commit 615472b52c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
1 changed files with 59 additions and 18 deletions

View File

@ -7,6 +7,7 @@ use solana_sdk::account::Account;
use solana_sdk::pubkey::Pubkey;
use solana_vote_api::vote_instruction::Vote;
use solana_vote_api::vote_state::{Lockout, VoteState, MAX_LOCKOUT_HISTORY};
use std::sync::Arc;
pub const VOTE_THRESHOLD_DEPTH: usize = 8;
pub const VOTE_THRESHOLD_SIZE: f64 = 2f64 / 3f64;
@ -65,30 +66,32 @@ impl EpochStakes {
impl Locktower {
pub fn new_from_forks(bank_forks: &BankForks) -> Self {
//TODO: which bank to start with?
let mut frozen_banks: Vec<_> = bank_forks.frozen_banks().values().cloned().collect();
frozen_banks.sort_by_key(|b| (b.parents().len(), b.slot()));
if let Some(bank) = frozen_banks.last() {
Self::new_from_bank(bank)
} else {
Self::default()
}
let epoch_stakes = {
if let Some(bank) = frozen_banks.last() {
EpochStakes::new_from_bank(bank)
} else {
return Self::default();
}
};
let mut locktower = Self {
epoch_stakes,
threshold_depth: VOTE_THRESHOLD_DEPTH,
threshold_size: VOTE_THRESHOLD_SIZE,
lockouts: VoteState::default(),
};
let bank = locktower.find_heaviest_bank(bank_forks).unwrap();
locktower.lockouts =
Self::initialize_lockouts_from_bank(&bank, locktower.epoch_stakes.slot);
locktower
}
pub fn new_from_bank(bank: &Bank) -> Self {
let current_epoch = bank.get_epoch_and_slot_index(bank.slot()).0;
let mut lockouts = VoteState::default();
if let Some(iter) = staking_utils::node_staked_accounts_at_epoch(bank, current_epoch) {
for (delegate_id, _, account) in iter {
if *delegate_id == bank.collector_id() {
let state = VoteState::deserialize(&account.data).expect("votes");
if lockouts.votes.len() < state.votes.len() {
//TODO: which state to init with?
lockouts = state;
}
}
}
}
let lockouts = Self::initialize_lockouts_from_bank(&bank, current_epoch);
let epoch_stakes = EpochStakes::new_from_bank(bank);
Self {
epoch_stakes,
@ -299,6 +302,44 @@ impl Locktower {
entry.stake += lamports;
}
}
fn bank_weight(&self, bank: &Bank, ancestors: &HashMap<u64, HashSet<u64>>) -> u128 {
let stake_lockouts =
self.collect_vote_lockouts(bank.slot(), bank.vote_accounts(), ancestors);
self.calculate_weight(&stake_lockouts)
}
fn find_heaviest_bank(&self, bank_forks: &BankForks) -> Option<Arc<Bank>> {
let ancestors = bank_forks.ancestors();
let mut bank_weights: Vec<_> = bank_forks
.frozen_banks()
.values()
.map(|b| {
(
self.bank_weight(b, &ancestors),
b.parents().len(),
b.clone(),
)
})
.collect();
bank_weights.sort_by_key(|b| (b.0, b.1));
bank_weights.pop().map(|b| b.2)
}
fn initialize_lockouts_from_bank(bank: &Bank, current_epoch: u64) -> VoteState {
let mut lockouts = VoteState::default();
if let Some(iter) = staking_utils::node_staked_accounts_at_epoch(&bank, current_epoch) {
for (delegate_id, _, account) in iter {
if *delegate_id == bank.collector_id() {
let state = VoteState::deserialize(&account.data).expect("votes");
if lockouts.votes.len() < state.votes.len() {
lockouts = state;
}
}
}
};
lockouts
}
}
#[cfg(test)]