compute_bank_stats needs to return newly computed ForkStats (#8608)
* Fix broken confirmation, add test
This commit is contained in:
parent
09a0325534
commit
f23dc11a86
|
@ -852,7 +852,7 @@ impl ReplayStage {
|
||||||
progress: &mut ProgressMap,
|
progress: &mut ProgressMap,
|
||||||
) -> Vec<Slot> {
|
) -> Vec<Slot> {
|
||||||
frozen_banks.sort_by_key(|bank| bank.slot());
|
frozen_banks.sort_by_key(|bank| bank.slot());
|
||||||
let new_stats = vec![];
|
let mut new_stats = vec![];
|
||||||
for bank in frozen_banks {
|
for bank in frozen_banks {
|
||||||
// Only time progress map should be missing a bank slot
|
// Only time progress map should be missing a bank slot
|
||||||
// is if this node was the leader for this slot as those banks
|
// is if this node was the leader for this slot as those banks
|
||||||
|
@ -895,6 +895,7 @@ impl ReplayStage {
|
||||||
stats.stake_lockouts = stake_lockouts;
|
stats.stake_lockouts = stake_lockouts;
|
||||||
stats.block_height = bank.block_height();
|
stats.block_height = bank.block_height();
|
||||||
stats.computed = true;
|
stats.computed = true;
|
||||||
|
new_stats.push(stats.slot);
|
||||||
}
|
}
|
||||||
stats.vote_threshold = tower.check_vote_stake_threshold(
|
stats.vote_threshold = tower.check_vote_stake_threshold(
|
||||||
bank.slot(),
|
bank.slot(),
|
||||||
|
@ -1171,6 +1172,7 @@ impl ReplayStage {
|
||||||
bank: Arc<Bank>,
|
bank: Arc<Bank>,
|
||||||
slot_full_senders: &[Sender<(u64, Pubkey)>],
|
slot_full_senders: &[Sender<(u64, Pubkey)>],
|
||||||
) {
|
) {
|
||||||
|
info!("bank frozen: {}", bank.slot());
|
||||||
bank.freeze();
|
bank.freeze();
|
||||||
slot_full_senders.iter().for_each(|sender| {
|
slot_full_senders.iter().for_each(|sender| {
|
||||||
if let Err(e) = sender.send((bank.slot(), *bank.collector_id())) {
|
if let Err(e) = sender.send((bank.slot(), *bank.collector_id())) {
|
||||||
|
@ -1306,7 +1308,10 @@ pub(crate) mod tests {
|
||||||
transaction::TransactionError,
|
transaction::TransactionError,
|
||||||
};
|
};
|
||||||
use solana_stake_program::stake_state;
|
use solana_stake_program::stake_state;
|
||||||
use solana_vote_program::vote_state::{self, Vote, VoteState, VoteStateVersions};
|
use solana_vote_program::{
|
||||||
|
vote_state::{self, Vote, VoteState, VoteStateVersions},
|
||||||
|
vote_transaction,
|
||||||
|
};
|
||||||
use std::{
|
use std::{
|
||||||
fs::remove_dir_all,
|
fs::remove_dir_all,
|
||||||
iter,
|
iter,
|
||||||
|
@ -2157,6 +2162,119 @@ pub(crate) mod tests {
|
||||||
Blockstore::destroy(&ledger_path).unwrap();
|
Blockstore::destroy(&ledger_path).unwrap();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_compute_bank_stats_confirmed() {
|
||||||
|
let node_keypair = Keypair::new();
|
||||||
|
let vote_keypair = Keypair::new();
|
||||||
|
let stake_keypair = Keypair::new();
|
||||||
|
let node_pubkey = node_keypair.pubkey();
|
||||||
|
let mut keypairs = HashMap::new();
|
||||||
|
keypairs.insert(
|
||||||
|
node_pubkey,
|
||||||
|
ValidatorVoteKeypairs::new(node_keypair, vote_keypair, stake_keypair),
|
||||||
|
);
|
||||||
|
|
||||||
|
let (bank_forks, mut progress) = initialize_state(&keypairs);
|
||||||
|
let bank0 = bank_forks.get(0).unwrap().clone();
|
||||||
|
let my_keypairs = keypairs.get(&node_pubkey).unwrap();
|
||||||
|
let vote_tx = vote_transaction::new_vote_transaction(
|
||||||
|
vec![0],
|
||||||
|
bank0.hash(),
|
||||||
|
bank0.last_blockhash(),
|
||||||
|
&my_keypairs.node_keypair,
|
||||||
|
&my_keypairs.vote_keypair,
|
||||||
|
&my_keypairs.vote_keypair,
|
||||||
|
);
|
||||||
|
|
||||||
|
let bank_forks = RwLock::new(bank_forks);
|
||||||
|
let bank1 = Bank::new_from_parent(&bank0, &node_pubkey, 1);
|
||||||
|
bank1.process_transaction(&vote_tx).unwrap();
|
||||||
|
bank1.freeze();
|
||||||
|
|
||||||
|
// Test confirmations
|
||||||
|
let ancestors = bank_forks.read().unwrap().ancestors();
|
||||||
|
let mut frozen_banks: Vec<_> = bank_forks
|
||||||
|
.read()
|
||||||
|
.unwrap()
|
||||||
|
.frozen_banks()
|
||||||
|
.values()
|
||||||
|
.cloned()
|
||||||
|
.collect();
|
||||||
|
let tower = Tower::new_for_tests(0, 0.67);
|
||||||
|
let newly_computed = ReplayStage::compute_bank_stats(
|
||||||
|
&node_pubkey,
|
||||||
|
&ancestors,
|
||||||
|
&mut frozen_banks,
|
||||||
|
&tower,
|
||||||
|
&mut progress,
|
||||||
|
);
|
||||||
|
assert_eq!(newly_computed, vec![0]);
|
||||||
|
// The only vote is in bank 1, and bank_forks does not currently contain
|
||||||
|
// bank 1, so no slot should be confirmed.
|
||||||
|
{
|
||||||
|
let fork_progress = progress.get(&0).unwrap();
|
||||||
|
let confirmed_forks = ReplayStage::confirm_forks(
|
||||||
|
&tower,
|
||||||
|
&fork_progress.fork_stats.stake_lockouts,
|
||||||
|
fork_progress.fork_stats.total_staked,
|
||||||
|
&progress,
|
||||||
|
&bank_forks,
|
||||||
|
);
|
||||||
|
|
||||||
|
assert!(confirmed_forks.is_empty())
|
||||||
|
}
|
||||||
|
|
||||||
|
// Insert the bank that contains a vote for slot 0, which confirms slot 0
|
||||||
|
bank_forks.write().unwrap().insert(bank1);
|
||||||
|
progress.insert(1, ForkProgress::new(bank0.last_blockhash()));
|
||||||
|
let ancestors = bank_forks.read().unwrap().ancestors();
|
||||||
|
let mut frozen_banks: Vec<_> = bank_forks
|
||||||
|
.read()
|
||||||
|
.unwrap()
|
||||||
|
.frozen_banks()
|
||||||
|
.values()
|
||||||
|
.cloned()
|
||||||
|
.collect();
|
||||||
|
let newly_computed = ReplayStage::compute_bank_stats(
|
||||||
|
&node_pubkey,
|
||||||
|
&ancestors,
|
||||||
|
&mut frozen_banks,
|
||||||
|
&tower,
|
||||||
|
&mut progress,
|
||||||
|
);
|
||||||
|
|
||||||
|
assert_eq!(newly_computed, vec![1]);
|
||||||
|
{
|
||||||
|
let fork_progress = progress.get(&1).unwrap();
|
||||||
|
let confirmed_forks = ReplayStage::confirm_forks(
|
||||||
|
&tower,
|
||||||
|
&fork_progress.fork_stats.stake_lockouts,
|
||||||
|
fork_progress.fork_stats.total_staked,
|
||||||
|
&progress,
|
||||||
|
&bank_forks,
|
||||||
|
);
|
||||||
|
assert_eq!(confirmed_forks, vec![0]);
|
||||||
|
}
|
||||||
|
|
||||||
|
let ancestors = bank_forks.read().unwrap().ancestors();
|
||||||
|
let mut frozen_banks: Vec<_> = bank_forks
|
||||||
|
.read()
|
||||||
|
.unwrap()
|
||||||
|
.frozen_banks()
|
||||||
|
.values()
|
||||||
|
.cloned()
|
||||||
|
.collect();
|
||||||
|
let newly_computed = ReplayStage::compute_bank_stats(
|
||||||
|
&node_pubkey,
|
||||||
|
&ancestors,
|
||||||
|
&mut frozen_banks,
|
||||||
|
&tower,
|
||||||
|
&mut progress,
|
||||||
|
);
|
||||||
|
// No new stats should have been computed
|
||||||
|
assert!(newly_computed.is_empty());
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_child_bank_heavier() {
|
fn test_child_bank_heavier() {
|
||||||
let node_keypair = Keypair::new();
|
let node_keypair = Keypair::new();
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
pub mod authorized_voters;
|
pub mod authorized_voters;
|
||||||
pub mod vote_instruction;
|
pub mod vote_instruction;
|
||||||
pub mod vote_state;
|
pub mod vote_state;
|
||||||
|
pub mod vote_transaction;
|
||||||
|
|
||||||
#[macro_use]
|
#[macro_use]
|
||||||
extern crate solana_metrics;
|
extern crate solana_metrics;
|
||||||
|
|
|
@ -0,0 +1,30 @@
|
||||||
|
use solana_sdk::{
|
||||||
|
clock::Slot,
|
||||||
|
hash::Hash,
|
||||||
|
signature::{Keypair, Signer},
|
||||||
|
transaction::Transaction,
|
||||||
|
};
|
||||||
|
|
||||||
|
use crate::{vote_instruction, vote_state::Vote};
|
||||||
|
|
||||||
|
pub fn new_vote_transaction(
|
||||||
|
slots: Vec<Slot>,
|
||||||
|
bank_hash: Hash,
|
||||||
|
blockhash: Hash,
|
||||||
|
node_keypair: &Keypair,
|
||||||
|
vote_keypair: &Keypair,
|
||||||
|
authorized_voter_keypair: &Keypair,
|
||||||
|
) -> Transaction {
|
||||||
|
let votes = Vote::new(slots, bank_hash);
|
||||||
|
let vote_ix = vote_instruction::vote(
|
||||||
|
&vote_keypair.pubkey(),
|
||||||
|
&authorized_voter_keypair.pubkey(),
|
||||||
|
votes,
|
||||||
|
);
|
||||||
|
|
||||||
|
let mut vote_tx = Transaction::new_with_payer(vec![vote_ix], Some(&node_keypair.pubkey()));
|
||||||
|
|
||||||
|
vote_tx.partial_sign(&[node_keypair], blockhash);
|
||||||
|
vote_tx.partial_sign(&[authorized_voter_keypair], blockhash);
|
||||||
|
vote_tx
|
||||||
|
}
|
Loading…
Reference in New Issue