Send recent votes in Vote Transactions (#3734)
This commit is contained in:
@ -475,7 +475,7 @@ mod tests {
|
||||
|
||||
fn create_sample_vote(keypair: &Keypair, hash: Hash) -> Transaction {
|
||||
let pubkey = keypair.pubkey();
|
||||
let ix = vote_instruction::vote(&pubkey, Vote::new(1));
|
||||
let ix = vote_instruction::vote(&pubkey, vec![Vote::new(1)]);
|
||||
Transaction::new_signed_instructions(&[keypair], vec![ix], hash)
|
||||
}
|
||||
|
||||
|
@ -347,7 +347,8 @@ pub fn make_active_set_entries(
|
||||
let new_vote_account_entry = next_entry_mut(&mut last_entry_hash, 1, vec![new_vote_account_tx]);
|
||||
|
||||
// 3) Create vote entry
|
||||
let vote_ix = vote_instruction::vote(&voting_keypair.pubkey(), Vote::new(slot_to_vote_on));
|
||||
let vote_ix =
|
||||
vote_instruction::vote(&voting_keypair.pubkey(), vec![Vote::new(slot_to_vote_on)]);
|
||||
let vote_tx =
|
||||
Transaction::new_signed_instructions(&[&voting_keypair], vec![vote_ix], *blockhash);
|
||||
let vote_entry = next_entry_mut(&mut last_entry_hash, 1, vec![vote_tx]);
|
||||
|
@ -10,6 +10,7 @@ use std::sync::Arc;
|
||||
|
||||
pub const VOTE_THRESHOLD_DEPTH: usize = 8;
|
||||
pub const VOTE_THRESHOLD_SIZE: f64 = 2f64 / 3f64;
|
||||
const MAX_RECENT_VOTES: usize = 16;
|
||||
|
||||
#[derive(Default)]
|
||||
pub struct EpochStakes {
|
||||
@ -253,6 +254,13 @@ impl Locktower {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn recent_votes(&self) -> Vec<Vote> {
|
||||
let start = self.lockouts.votes.len().saturating_sub(MAX_RECENT_VOTES);
|
||||
(start..self.lockouts.votes.len())
|
||||
.map(|i| Vote::new(self.lockouts.votes[i].slot))
|
||||
.collect()
|
||||
}
|
||||
|
||||
pub fn root(&self) -> Option<u64> {
|
||||
self.lockouts.root_slot
|
||||
}
|
||||
@ -798,4 +806,29 @@ mod test {
|
||||
locktower.collect_vote_lockouts(vote_to_evaluate, accounts.into_iter(), &ancestors);
|
||||
assert!(!locktower.check_vote_stake_threshold(vote_to_evaluate, &stakes_lockouts));
|
||||
}
|
||||
|
||||
fn vote_and_check_recent(num_votes: usize) {
|
||||
let mut locktower = Locktower::new(EpochStakes::new_for_tests(2), 1, 0.67);
|
||||
let start = num_votes.saturating_sub(MAX_RECENT_VOTES);
|
||||
let expected: Vec<_> = (start..num_votes).map(|i| Vote::new(i as u64)).collect();
|
||||
for i in 0..num_votes {
|
||||
locktower.record_vote(i as u64);
|
||||
}
|
||||
assert_eq!(expected, locktower.recent_votes())
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_recent_votes_full() {
|
||||
vote_and_check_recent(MAX_LOCKOUT_HISTORY)
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_recent_votes_empty() {
|
||||
vote_and_check_recent(0)
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_recent_votes_exact() {
|
||||
vote_and_check_recent(MAX_RECENT_VOTES)
|
||||
}
|
||||
}
|
||||
|
@ -22,7 +22,6 @@ use solana_sdk::signature::KeypairUtil;
|
||||
use solana_sdk::timing::{self, duration_as_ms};
|
||||
use solana_sdk::transaction::Transaction;
|
||||
use solana_vote_api::vote_instruction;
|
||||
use solana_vote_api::vote_state::Vote;
|
||||
use std::sync::atomic::{AtomicBool, Ordering};
|
||||
use std::sync::mpsc::{channel, Receiver, RecvTimeoutError, Sender};
|
||||
use std::sync::{Arc, Mutex, RwLock};
|
||||
@ -294,24 +293,25 @@ impl ReplayStage {
|
||||
locktower: &mut Locktower,
|
||||
progress: &mut HashMap<u64, ForkProgress>,
|
||||
voting_keypair: &Option<Arc<T>>,
|
||||
vote_account: &Pubkey,
|
||||
vote_account_pubkey: &Pubkey,
|
||||
cluster_info: &Arc<RwLock<ClusterInfo>>,
|
||||
blocktree: &Arc<Blocktree>,
|
||||
) where
|
||||
T: 'static + KeypairUtil + Send + Sync,
|
||||
{
|
||||
if let Some(ref voting_keypair) = voting_keypair {
|
||||
let vote_ix = vote_instruction::vote(&vote_account, Vote::new(bank.slot()));
|
||||
let vote_tx = Transaction::new_signed_instructions(
|
||||
&[voting_keypair.as_ref()],
|
||||
vec![vote_ix],
|
||||
bank.last_blockhash(),
|
||||
);
|
||||
if let Some(new_root) = locktower.record_vote(bank.slot()) {
|
||||
bank_forks.write().unwrap().set_root(new_root);
|
||||
blocktree.set_root(new_root);
|
||||
Self::handle_new_root(&bank_forks, progress);
|
||||
}
|
||||
// Send our last few votes along with the new one
|
||||
let vote_ix = vote_instruction::vote(vote_account_pubkey, locktower.recent_votes());
|
||||
let vote_tx = Transaction::new_signed_instructions(
|
||||
&[voting_keypair.as_ref()],
|
||||
vec![vote_ix],
|
||||
bank.last_blockhash(),
|
||||
);
|
||||
locktower.update_epoch(&bank);
|
||||
cluster_info.write().unwrap().push_vote(vote_tx);
|
||||
}
|
||||
@ -604,6 +604,7 @@ mod test {
|
||||
use solana_sdk::genesis_block::GenesisBlock;
|
||||
use solana_sdk::hash::Hash;
|
||||
use solana_sdk::signature::{Keypair, KeypairUtil};
|
||||
use solana_vote_api::vote_state::Vote;
|
||||
use std::fs::remove_dir_all;
|
||||
use std::sync::mpsc::channel;
|
||||
use std::sync::{Arc, RwLock};
|
||||
@ -652,8 +653,7 @@ mod test {
|
||||
&poh_recorder,
|
||||
ledger_writer_sender,
|
||||
);
|
||||
|
||||
let vote_ix = vote_instruction::vote(&voting_keypair.pubkey(), Vote::new(0));
|
||||
let vote_ix = vote_instruction::vote(&voting_keypair.pubkey(), vec![Vote::new(0)]);
|
||||
let vote_tx = Transaction::new_signed_instructions(
|
||||
&[voting_keypair.as_ref()],
|
||||
vec![vote_ix],
|
||||
|
@ -138,7 +138,7 @@ pub mod tests {
|
||||
}
|
||||
|
||||
pub fn push_vote<T: KeypairUtil>(voting_keypair: &T, bank: &Bank, slot: u64) {
|
||||
let ix = vote_instruction::vote(&voting_keypair.pubkey(), Vote::new(slot));
|
||||
let ix = vote_instruction::vote(&voting_keypair.pubkey(), vec![Vote::new(slot)]);
|
||||
process_instructions(bank, &[voting_keypair], vec![ix]);
|
||||
}
|
||||
|
||||
@ -158,7 +158,10 @@ pub mod tests {
|
||||
0,
|
||||
lamports,
|
||||
);
|
||||
ixs.push(vote_instruction::vote(&voting_pubkey, Vote::new(slot)));
|
||||
ixs.push(vote_instruction::vote(
|
||||
&voting_pubkey,
|
||||
vec![Vote::new(slot)],
|
||||
));
|
||||
process_instructions(bank, &[from_keypair, voting_keypair], ixs);
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user