Initailize locktower with heaviest bank (#3489)
This commit is contained in:
parent
4d34102d9c
commit
615472b52c
|
@ -7,6 +7,7 @@ use solana_sdk::account::Account;
|
||||||
use solana_sdk::pubkey::Pubkey;
|
use solana_sdk::pubkey::Pubkey;
|
||||||
use solana_vote_api::vote_instruction::Vote;
|
use solana_vote_api::vote_instruction::Vote;
|
||||||
use solana_vote_api::vote_state::{Lockout, VoteState, MAX_LOCKOUT_HISTORY};
|
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_DEPTH: usize = 8;
|
||||||
pub const VOTE_THRESHOLD_SIZE: f64 = 2f64 / 3f64;
|
pub const VOTE_THRESHOLD_SIZE: f64 = 2f64 / 3f64;
|
||||||
|
@ -65,30 +66,32 @@ impl EpochStakes {
|
||||||
|
|
||||||
impl Locktower {
|
impl Locktower {
|
||||||
pub fn new_from_forks(bank_forks: &BankForks) -> Self {
|
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();
|
let mut frozen_banks: Vec<_> = bank_forks.frozen_banks().values().cloned().collect();
|
||||||
frozen_banks.sort_by_key(|b| (b.parents().len(), b.slot()));
|
frozen_banks.sort_by_key(|b| (b.parents().len(), b.slot()));
|
||||||
if let Some(bank) = frozen_banks.last() {
|
let epoch_stakes = {
|
||||||
Self::new_from_bank(bank)
|
if let Some(bank) = frozen_banks.last() {
|
||||||
} else {
|
EpochStakes::new_from_bank(bank)
|
||||||
Self::default()
|
} 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 {
|
pub fn new_from_bank(bank: &Bank) -> Self {
|
||||||
let current_epoch = bank.get_epoch_and_slot_index(bank.slot()).0;
|
let current_epoch = bank.get_epoch_and_slot_index(bank.slot()).0;
|
||||||
let mut lockouts = VoteState::default();
|
let lockouts = Self::initialize_lockouts_from_bank(&bank, current_epoch);
|
||||||
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 epoch_stakes = EpochStakes::new_from_bank(bank);
|
let epoch_stakes = EpochStakes::new_from_bank(bank);
|
||||||
Self {
|
Self {
|
||||||
epoch_stakes,
|
epoch_stakes,
|
||||||
|
@ -299,6 +302,44 @@ impl Locktower {
|
||||||
entry.stake += lamports;
|
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)]
|
#[cfg(test)]
|
||||||
|
|
Loading…
Reference in New Issue