Refactor bank get vote accounts (#3052)
This commit is contained in:
committed by
Michael Vines
parent
f4c5b9ccb0
commit
d22a13257e
@ -13,7 +13,6 @@ use crate::sigverify_stage::VerifiedPackets;
|
||||
use bincode::deserialize;
|
||||
use solana_metrics::counter::Counter;
|
||||
use solana_runtime::bank::{self, Bank, BankError};
|
||||
use solana_sdk::pubkey::Pubkey;
|
||||
use solana_sdk::timing::{self, duration_as_us, MAX_RECENT_TICK_HASHES};
|
||||
use solana_sdk::transaction::Transaction;
|
||||
use std::sync::atomic::{AtomicBool, Ordering};
|
||||
@ -44,7 +43,6 @@ impl BankingStage {
|
||||
poh_recorder: &Arc<Mutex<PohRecorder>>,
|
||||
verified_receiver: Receiver<VerifiedPackets>,
|
||||
max_tick_height: u64,
|
||||
leader_id: Pubkey,
|
||||
) -> (Self, Receiver<Vec<(Entry, u64)>>) {
|
||||
let (entry_sender, entry_receiver) = channel();
|
||||
let working_bank = WorkingBank {
|
||||
@ -70,8 +68,7 @@ impl BankingStage {
|
||||
let exit = Arc::new(AtomicBool::new(false));
|
||||
|
||||
// Single thread to compute confirmation
|
||||
let leader_confirmation_service =
|
||||
LeaderConfirmationService::new(&bank, leader_id, exit.clone());
|
||||
let leader_confirmation_service = LeaderConfirmationService::new(&bank, exit.clone());
|
||||
|
||||
// Many banks that process transactions in parallel.
|
||||
let bank_thread_hdls: Vec<JoinHandle<UnprocessedPackets>> = (0..Self::num_threads())
|
||||
@ -382,7 +379,6 @@ mod tests {
|
||||
&poh_recorder,
|
||||
verified_receiver,
|
||||
DEFAULT_TICKS_PER_SLOT,
|
||||
genesis_block.bootstrap_leader_id,
|
||||
);
|
||||
drop(verified_sender);
|
||||
banking_stage.join().unwrap();
|
||||
@ -402,7 +398,6 @@ mod tests {
|
||||
&poh_recorder,
|
||||
verified_receiver,
|
||||
genesis_block.ticks_per_slot - 1,
|
||||
genesis_block.bootstrap_leader_id,
|
||||
);
|
||||
sleep(Duration::from_millis(600));
|
||||
drop(verified_sender);
|
||||
@ -430,7 +425,6 @@ mod tests {
|
||||
&poh_recorder,
|
||||
verified_receiver,
|
||||
DEFAULT_TICKS_PER_SLOT,
|
||||
genesis_block.bootstrap_leader_id,
|
||||
);
|
||||
|
||||
// good tx
|
||||
@ -489,7 +483,6 @@ mod tests {
|
||||
&poh_recorder,
|
||||
verified_receiver,
|
||||
DEFAULT_TICKS_PER_SLOT,
|
||||
genesis_block.bootstrap_leader_id,
|
||||
);
|
||||
|
||||
// Process a batch that includes a transaction that receives two tokens.
|
||||
@ -552,13 +545,8 @@ mod tests {
|
||||
let (verified_sender, verified_receiver) = channel();
|
||||
let max_tick_height = 10;
|
||||
let (poh_recorder, poh_service) = create_test_recorder(&bank);
|
||||
let (banking_stage, _entry_receiver) = BankingStage::new(
|
||||
&bank,
|
||||
&poh_recorder,
|
||||
verified_receiver,
|
||||
max_tick_height,
|
||||
genesis_block.bootstrap_leader_id,
|
||||
);
|
||||
let (banking_stage, _entry_receiver) =
|
||||
BankingStage::new(&bank, &poh_recorder, verified_receiver, max_tick_height);
|
||||
|
||||
loop {
|
||||
let bank_tick_height = bank.tick_height();
|
||||
@ -581,13 +569,8 @@ mod tests {
|
||||
let ticks_per_slot = 1;
|
||||
let (verified_sender, verified_receiver) = channel();
|
||||
let (poh_recorder, poh_service) = create_test_recorder(&bank);
|
||||
let (mut banking_stage, _entry_receiver) = BankingStage::new(
|
||||
&bank,
|
||||
&poh_recorder,
|
||||
verified_receiver,
|
||||
ticks_per_slot,
|
||||
genesis_block.bootstrap_leader_id,
|
||||
);
|
||||
let (mut banking_stage, _entry_receiver) =
|
||||
BankingStage::new(&bank, &poh_recorder, verified_receiver, ticks_per_slot);
|
||||
|
||||
// Wait for Poh recorder to hit max height
|
||||
loop {
|
||||
|
@ -5,8 +5,8 @@
|
||||
use crate::service::Service;
|
||||
use solana_metrics::{influxdb, submit};
|
||||
use solana_runtime::bank::Bank;
|
||||
use solana_sdk::pubkey::Pubkey;
|
||||
use solana_sdk::timing;
|
||||
use solana_sdk::vote_program::VoteState;
|
||||
use std::result;
|
||||
use std::sync::atomic::{AtomicBool, Ordering};
|
||||
use std::sync::Arc;
|
||||
@ -28,26 +28,23 @@ pub struct LeaderConfirmationService {
|
||||
impl LeaderConfirmationService {
|
||||
fn get_last_supermajority_timestamp(
|
||||
bank: &Arc<Bank>,
|
||||
leader_id: Pubkey,
|
||||
last_valid_validator_timestamp: u64,
|
||||
) -> result::Result<u64, ConfirmationError> {
|
||||
let mut total_stake = 0;
|
||||
|
||||
let mut slots_and_stakes: Vec<(u64, u64)> = vec![];
|
||||
// Hold an accounts_db read lock as briefly as possible, just long enough to collect all
|
||||
// the vote states
|
||||
let vote_states = bank.vote_states(|_, vote_state| leader_id != vote_state.delegate_id);
|
||||
|
||||
let slots_and_stakes: Vec<(u64, u64)> = vote_states
|
||||
.iter()
|
||||
.filter_map(|(_, vote_state)| {
|
||||
let validator_stake = bank.get_balance(&vote_state.delegate_id);
|
||||
total_stake += validator_stake;
|
||||
vote_state
|
||||
.votes
|
||||
.back()
|
||||
.map(|vote| (vote.slot_height, validator_stake))
|
||||
})
|
||||
.collect();
|
||||
bank.vote_accounts().for_each(|(_, account)| {
|
||||
total_stake += account.tokens;
|
||||
let vote_state = VoteState::deserialize(&account.userdata).unwrap();
|
||||
if let Some(stake_and_state) = vote_state
|
||||
.votes
|
||||
.back()
|
||||
.map(|vote| (vote.slot_height, account.tokens))
|
||||
{
|
||||
slots_and_stakes.push(stake_and_state);
|
||||
}
|
||||
});
|
||||
|
||||
let super_majority_stake = (2 * total_stake) / 3;
|
||||
|
||||
@ -72,13 +69,9 @@ impl LeaderConfirmationService {
|
||||
Err(ConfirmationError::NoValidSupermajority)
|
||||
}
|
||||
|
||||
pub fn compute_confirmation(
|
||||
bank: &Arc<Bank>,
|
||||
leader_id: Pubkey,
|
||||
last_valid_validator_timestamp: &mut u64,
|
||||
) {
|
||||
pub fn compute_confirmation(bank: &Arc<Bank>, last_valid_validator_timestamp: &mut u64) {
|
||||
if let Ok(super_majority_timestamp) =
|
||||
Self::get_last_supermajority_timestamp(bank, leader_id, *last_valid_validator_timestamp)
|
||||
Self::get_last_supermajority_timestamp(bank, *last_valid_validator_timestamp)
|
||||
{
|
||||
let now = timing::timestamp();
|
||||
let confirmation_ms = now - super_majority_timestamp;
|
||||
@ -97,7 +90,7 @@ impl LeaderConfirmationService {
|
||||
}
|
||||
|
||||
/// Create a new LeaderConfirmationService for computing confirmation.
|
||||
pub fn new(bank: &Arc<Bank>, leader_id: Pubkey, exit: Arc<AtomicBool>) -> Self {
|
||||
pub fn new(bank: &Arc<Bank>, exit: Arc<AtomicBool>) -> Self {
|
||||
let bank = bank.clone();
|
||||
let thread_hdl = Builder::new()
|
||||
.name("solana-leader-confirmation-service".to_string())
|
||||
@ -107,11 +100,7 @@ impl LeaderConfirmationService {
|
||||
if exit.load(Ordering::Relaxed) {
|
||||
break;
|
||||
}
|
||||
Self::compute_confirmation(
|
||||
&bank,
|
||||
leader_id,
|
||||
&mut last_valid_validator_timestamp,
|
||||
);
|
||||
Self::compute_confirmation(&bank, &mut last_valid_validator_timestamp);
|
||||
sleep(Duration::from_millis(COMPUTE_CONFIRMATION_MS));
|
||||
}
|
||||
})
|
||||
@ -179,11 +168,7 @@ mod tests {
|
||||
|
||||
// There isn't 2/3 consensus, so the bank's confirmation value should be the default
|
||||
let mut last_confirmation_time = 0;
|
||||
LeaderConfirmationService::compute_confirmation(
|
||||
&bank,
|
||||
genesis_block.bootstrap_leader_id,
|
||||
&mut last_confirmation_time,
|
||||
);
|
||||
LeaderConfirmationService::compute_confirmation(&bank, &mut last_confirmation_time);
|
||||
assert_eq!(last_confirmation_time, 0);
|
||||
|
||||
// Get another validator to vote, so we now have 2/3 consensus
|
||||
@ -191,11 +176,7 @@ mod tests {
|
||||
let vote_tx = VoteTransaction::new_vote(voting_keypair, 7, blockhash, 0);
|
||||
bank.process_transaction(&vote_tx).unwrap();
|
||||
|
||||
LeaderConfirmationService::compute_confirmation(
|
||||
&bank,
|
||||
genesis_block.bootstrap_leader_id,
|
||||
&mut last_confirmation_time,
|
||||
);
|
||||
LeaderConfirmationService::compute_confirmation(&bank, &mut last_confirmation_time);
|
||||
assert!(last_confirmation_time > 0);
|
||||
}
|
||||
}
|
||||
|
@ -226,13 +226,8 @@ impl Tpu {
|
||||
.map(|meta| meta.consumed)
|
||||
.unwrap_or(0);
|
||||
|
||||
let (banking_stage, entry_receiver) = BankingStage::new(
|
||||
&bank,
|
||||
poh_recorder,
|
||||
verified_receiver,
|
||||
max_tick_height,
|
||||
self.id,
|
||||
);
|
||||
let (banking_stage, entry_receiver) =
|
||||
BankingStage::new(&bank, poh_recorder, verified_receiver, max_tick_height);
|
||||
|
||||
let broadcast_stage = BroadcastStage::new(
|
||||
slot,
|
||||
|
Reference in New Issue
Block a user