ff cleanup: allow_votes_to_directly_update_vote_state and compact_vot… (#32967)
ff cleanup: allow_votes_to_directly_update_vote_state and compact_vote_state_updates
This commit is contained in:
parent
1b9c9a313c
commit
025651e0d4
|
@ -28,7 +28,7 @@ use {
|
|||
bank_forks::BankForks, prioritization_fee_cache::PrioritizationFeeCache,
|
||||
vote_sender_types::ReplayVoteSender,
|
||||
},
|
||||
solana_sdk::{feature_set::allow_votes_to_directly_update_vote_state, timing::AtomicInterval},
|
||||
solana_sdk::timing::AtomicInterval,
|
||||
std::{
|
||||
cmp, env,
|
||||
sync::{
|
||||
|
@ -359,41 +359,18 @@ impl BankingStage {
|
|||
TOTAL_BUFFERED_PACKETS / ((num_threads - NUM_VOTE_PROCESSING_THREADS) as usize);
|
||||
// Keeps track of extraneous vote transactions for the vote threads
|
||||
let latest_unprocessed_votes = Arc::new(LatestUnprocessedVotes::new());
|
||||
let should_split_voting_threads = bank_forks
|
||||
.read()
|
||||
.map(|bank_forks| {
|
||||
let bank = bank_forks.root_bank();
|
||||
bank.feature_set
|
||||
.is_active(&allow_votes_to_directly_update_vote_state::id())
|
||||
})
|
||||
.unwrap_or(false);
|
||||
// Many banks that process transactions in parallel.
|
||||
let bank_thread_hdls: Vec<JoinHandle<()>> = (0..num_threads)
|
||||
.map(|id| {
|
||||
let (packet_receiver, unprocessed_transaction_storage) =
|
||||
match (id, should_split_voting_threads) {
|
||||
(0, false) => (
|
||||
gossip_vote_receiver.clone(),
|
||||
UnprocessedTransactionStorage::new_transaction_storage(
|
||||
UnprocessedPacketBatches::with_capacity(batch_limit),
|
||||
ThreadType::Voting(VoteSource::Gossip),
|
||||
),
|
||||
),
|
||||
(0, true) => (
|
||||
let (packet_receiver, unprocessed_transaction_storage) = match id {
|
||||
0 => (
|
||||
gossip_vote_receiver.clone(),
|
||||
UnprocessedTransactionStorage::new_vote_storage(
|
||||
latest_unprocessed_votes.clone(),
|
||||
VoteSource::Gossip,
|
||||
),
|
||||
),
|
||||
(1, false) => (
|
||||
tpu_vote_receiver.clone(),
|
||||
UnprocessedTransactionStorage::new_transaction_storage(
|
||||
UnprocessedPacketBatches::with_capacity(batch_limit),
|
||||
ThreadType::Voting(VoteSource::Tpu),
|
||||
),
|
||||
),
|
||||
(1, true) => (
|
||||
1 => (
|
||||
tpu_vote_receiver.clone(),
|
||||
UnprocessedTransactionStorage::new_vote_storage(
|
||||
latest_unprocessed_votes.clone(),
|
||||
|
@ -609,9 +586,7 @@ mod tests {
|
|||
poh_service::PohService,
|
||||
},
|
||||
solana_runtime::{
|
||||
bank::Bank,
|
||||
bank_forks::BankForks,
|
||||
genesis_utils::{activate_feature, bootstrap_validator_stake_lamports},
|
||||
bank::Bank, bank_forks::BankForks, genesis_utils::bootstrap_validator_stake_lamports,
|
||||
},
|
||||
solana_sdk::{
|
||||
hash::Hash,
|
||||
|
@ -1126,14 +1101,10 @@ mod tests {
|
|||
fn test_unprocessed_transaction_storage_full_send() {
|
||||
solana_logger::setup();
|
||||
let GenesisConfigInfo {
|
||||
mut genesis_config,
|
||||
genesis_config,
|
||||
mint_keypair,
|
||||
..
|
||||
} = create_slow_genesis_config(10000);
|
||||
activate_feature(
|
||||
&mut genesis_config,
|
||||
allow_votes_to_directly_update_vote_state::id(),
|
||||
);
|
||||
let bank = Bank::new_no_wallclock_throttle_for_tests(&genesis_config);
|
||||
let bank_forks = Arc::new(RwLock::new(BankForks::new(bank)));
|
||||
let bank = bank_forks.read().unwrap().get(0).unwrap();
|
||||
|
|
|
@ -36,7 +36,6 @@ use {
|
|||
},
|
||||
solana_sdk::{
|
||||
clock::{Slot, DEFAULT_MS_PER_SLOT, DEFAULT_TICKS_PER_SLOT},
|
||||
feature_set::allow_votes_to_directly_update_vote_state,
|
||||
hash::Hash,
|
||||
pubkey::Pubkey,
|
||||
signature::Signature,
|
||||
|
@ -265,7 +264,6 @@ impl ClusterInfoVoteListener {
|
|||
})
|
||||
.unwrap()
|
||||
};
|
||||
let bank_forks_clone = bank_forks.clone();
|
||||
let bank_send_thread = {
|
||||
let exit = exit.clone();
|
||||
Builder::new()
|
||||
|
@ -276,7 +274,6 @@ impl ClusterInfoVoteListener {
|
|||
verified_vote_label_packets_receiver,
|
||||
poh_recorder,
|
||||
&verified_packets_sender,
|
||||
bank_forks_clone,
|
||||
);
|
||||
})
|
||||
.unwrap()
|
||||
|
@ -382,17 +379,10 @@ impl ClusterInfoVoteListener {
|
|||
verified_vote_label_packets_receiver: VerifiedLabelVotePacketsReceiver,
|
||||
poh_recorder: Arc<RwLock<PohRecorder>>,
|
||||
verified_packets_sender: &BankingPacketSender,
|
||||
bank_forks: Arc<RwLock<BankForks>>,
|
||||
) -> Result<()> {
|
||||
let mut verified_vote_packets = VerifiedVotePackets::default();
|
||||
let mut time_since_lock = Instant::now();
|
||||
let mut bank_vote_sender_state_option: Option<BankVoteSenderState> = None;
|
||||
let mut is_tower_full_vote_enabled = bank_forks
|
||||
.read()
|
||||
.unwrap()
|
||||
.root_bank()
|
||||
.feature_set
|
||||
.is_active(&allow_votes_to_directly_update_vote_state::id());
|
||||
|
||||
loop {
|
||||
if exit.load(Ordering::Relaxed) {
|
||||
|
@ -407,7 +397,6 @@ impl ClusterInfoVoteListener {
|
|||
if let Err(e) = verified_vote_packets.receive_and_process_vote_packets(
|
||||
&verified_vote_label_packets_receiver,
|
||||
would_be_leader,
|
||||
is_tower_full_vote_enabled,
|
||||
) {
|
||||
match e {
|
||||
Error::RecvTimeout(RecvTimeoutError::Disconnected)
|
||||
|
@ -428,15 +417,6 @@ impl ClusterInfoVoteListener {
|
|||
verified_packets_sender,
|
||||
&verified_vote_packets,
|
||||
)?;
|
||||
// Check if we've crossed the feature boundary
|
||||
if !is_tower_full_vote_enabled {
|
||||
is_tower_full_vote_enabled = bank_forks
|
||||
.read()
|
||||
.unwrap()
|
||||
.root_bank()
|
||||
.feature_set
|
||||
.is_active(&allow_votes_to_directly_update_vote_state::id());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -25,7 +25,6 @@ use {
|
|||
},
|
||||
solana_sdk::{
|
||||
clock::{Slot, UnixTimestamp},
|
||||
feature_set,
|
||||
hash::Hash,
|
||||
instruction::Instruction,
|
||||
pubkey::Pubkey,
|
||||
|
@ -508,50 +507,16 @@ impl Tower {
|
|||
self.last_vote_tx_blockhash = Some(new_vote_tx_blockhash);
|
||||
}
|
||||
|
||||
// Returns true if we have switched the new vote instruction that directly sets vote state
|
||||
pub(crate) fn is_direct_vote_state_update_enabled(bank: &Bank) -> bool {
|
||||
bank.feature_set
|
||||
.is_active(&feature_set::allow_votes_to_directly_update_vote_state::id())
|
||||
}
|
||||
|
||||
fn apply_vote_and_generate_vote_diff(
|
||||
local_vote_state: &mut VoteState,
|
||||
slot: Slot,
|
||||
hash: Hash,
|
||||
last_voted_slot_in_bank: Option<Slot>,
|
||||
) -> VoteTransaction {
|
||||
let vote = Vote::new(vec![slot], hash);
|
||||
let _ignored = process_vote_unchecked(local_vote_state, vote);
|
||||
let slots = if let Some(last_voted_slot) = last_voted_slot_in_bank {
|
||||
local_vote_state
|
||||
.votes
|
||||
.iter()
|
||||
.map(|v| v.slot())
|
||||
.skip_while(|s| *s <= last_voted_slot)
|
||||
.collect()
|
||||
} else {
|
||||
local_vote_state.votes.iter().map(|v| v.slot()).collect()
|
||||
};
|
||||
VoteTransaction::from(Vote::new(slots, hash))
|
||||
}
|
||||
|
||||
pub fn last_voted_slot_in_bank(bank: &Bank, vote_account_pubkey: &Pubkey) -> Option<Slot> {
|
||||
let vote_account = bank.get_vote_account(vote_account_pubkey)?;
|
||||
let vote_state = vote_account.vote_state();
|
||||
vote_state.as_ref().ok()?.last_voted_slot()
|
||||
}
|
||||
|
||||
pub fn record_bank_vote(&mut self, bank: &Bank, vote_account_pubkey: &Pubkey) -> Option<Slot> {
|
||||
let last_voted_slot_in_bank = Self::last_voted_slot_in_bank(bank, vote_account_pubkey);
|
||||
|
||||
pub fn record_bank_vote(&mut self, bank: &Bank) -> Option<Slot> {
|
||||
// Returns the new root if one is made after applying a vote for the given bank to
|
||||
// `self.vote_state`
|
||||
self.record_bank_vote_and_update_lockouts(
|
||||
bank.slot(),
|
||||
bank.hash(),
|
||||
last_voted_slot_in_bank,
|
||||
Self::is_direct_vote_state_update_enabled(bank),
|
||||
)
|
||||
self.record_bank_vote_and_update_lockouts(bank.slot(), bank.hash())
|
||||
}
|
||||
|
||||
/// If we've recently updated the vote state by applying a new vote
|
||||
|
@ -575,13 +540,10 @@ impl Tower {
|
|||
&mut self,
|
||||
vote_slot: Slot,
|
||||
vote_hash: Hash,
|
||||
last_voted_slot_in_bank: Option<Slot>,
|
||||
is_direct_vote_state_update_enabled: bool,
|
||||
) -> Option<Slot> {
|
||||
trace!("{} record_vote for {}", self.node_pubkey, vote_slot);
|
||||
let old_root = self.root();
|
||||
|
||||
if is_direct_vote_state_update_enabled {
|
||||
let vote = Vote::new(vec![vote_slot], vote_hash);
|
||||
let result = process_vote_unchecked(&mut self.vote_state, vote);
|
||||
if result.is_err() {
|
||||
|
@ -591,18 +553,6 @@ impl Tower {
|
|||
);
|
||||
}
|
||||
self.update_last_vote_from_vote_state(vote_hash);
|
||||
} else {
|
||||
let mut new_vote = Self::apply_vote_and_generate_vote_diff(
|
||||
&mut self.vote_state,
|
||||
vote_slot,
|
||||
vote_hash,
|
||||
last_voted_slot_in_bank,
|
||||
);
|
||||
|
||||
new_vote
|
||||
.set_timestamp(self.maybe_timestamp(self.last_voted_slot().unwrap_or_default()));
|
||||
self.last_vote = new_vote;
|
||||
};
|
||||
|
||||
let new_root = self.root();
|
||||
|
||||
|
@ -620,7 +570,7 @@ impl Tower {
|
|||
|
||||
#[cfg(test)]
|
||||
pub fn record_vote(&mut self, slot: Slot, hash: Hash) -> Option<Slot> {
|
||||
self.record_bank_vote_and_update_lockouts(slot, hash, self.last_voted_slot(), true)
|
||||
self.record_bank_vote_and_update_lockouts(slot, hash)
|
||||
}
|
||||
|
||||
/// Used for tests
|
||||
|
@ -1579,7 +1529,7 @@ pub mod test {
|
|||
signature::Signer,
|
||||
slot_history::SlotHistory,
|
||||
},
|
||||
solana_vote_program::vote_state::{self, Vote, VoteStateVersions, MAX_LOCKOUT_HISTORY},
|
||||
solana_vote_program::vote_state::{Vote, VoteStateVersions, MAX_LOCKOUT_HISTORY},
|
||||
std::{
|
||||
collections::{HashMap, VecDeque},
|
||||
fs::{remove_file, OpenOptions},
|
||||
|
@ -2530,61 +2480,6 @@ pub mod test {
|
|||
assert_eq!(voted_stakes[&2], 1);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_apply_vote_and_generate_vote_diff() {
|
||||
let mut local = VoteState::default();
|
||||
let vote = Tower::apply_vote_and_generate_vote_diff(&mut local, 0, Hash::default(), None);
|
||||
assert_eq!(local.votes.len(), 1);
|
||||
assert_eq!(vote.slots(), vec![0]);
|
||||
assert_eq!(local.tower(), vec![0]);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_apply_vote_and_generate_vote_diff_dup_vote() {
|
||||
let mut local = VoteState::default();
|
||||
// If `latest_voted_slot_in_bank == Some(0)`, then we already have a vote for 0. Adding
|
||||
// another vote for slot 0 should return an empty vote as the diff.
|
||||
let vote =
|
||||
Tower::apply_vote_and_generate_vote_diff(&mut local, 0, Hash::default(), Some(0));
|
||||
assert!(vote.is_empty());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_apply_vote_and_generate_vote_diff_next_vote() {
|
||||
let mut local = VoteState::default();
|
||||
let vote = Vote {
|
||||
slots: vec![0],
|
||||
hash: Hash::default(),
|
||||
timestamp: None,
|
||||
};
|
||||
let _ = vote_state::process_vote_unchecked(&mut local, vote);
|
||||
assert_eq!(local.votes.len(), 1);
|
||||
let vote =
|
||||
Tower::apply_vote_and_generate_vote_diff(&mut local, 1, Hash::default(), Some(0));
|
||||
assert_eq!(vote.slots(), vec![1]);
|
||||
assert_eq!(local.tower(), vec![0, 1]);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_apply_vote_and_generate_vote_diff_next_after_expired_vote() {
|
||||
let mut local = VoteState::default();
|
||||
let vote = Vote {
|
||||
slots: vec![0],
|
||||
hash: Hash::default(),
|
||||
timestamp: None,
|
||||
};
|
||||
let _ = vote_state::process_vote_unchecked(&mut local, vote);
|
||||
assert_eq!(local.votes.len(), 1);
|
||||
|
||||
// First vote expired, so should be evicted from tower. Thus even with
|
||||
// `latest_voted_slot_in_bank == Some(0)`, the first vote slot won't be
|
||||
// observable in any of the results.
|
||||
let vote =
|
||||
Tower::apply_vote_and_generate_vote_diff(&mut local, 3, Hash::default(), Some(0));
|
||||
assert_eq!(vote.slots(), vec![3]);
|
||||
assert_eq!(local.tower(), vec![3]);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_check_vote_threshold_forks() {
|
||||
// Create the ancestor relationships
|
||||
|
|
|
@ -67,7 +67,6 @@ use {
|
|||
},
|
||||
solana_sdk::{
|
||||
clock::{BankId, Slot, MAX_PROCESSING_AGE, NUM_CONSECUTIVE_LEADER_SLOTS},
|
||||
feature_set,
|
||||
genesis_config::ClusterType,
|
||||
hash::Hash,
|
||||
pubkey::Pubkey,
|
||||
|
@ -2123,7 +2122,7 @@ impl ReplayStage {
|
|||
datapoint_info!("replay_stage-voted_empty_bank", ("slot", bank.slot(), i64));
|
||||
}
|
||||
trace!("handle votable bank {}", bank.slot());
|
||||
let new_root = tower.record_bank_vote(bank, vote_account_pubkey);
|
||||
let new_root = tower.record_bank_vote(bank);
|
||||
|
||||
if let Some(new_root) = new_root {
|
||||
// get the root bank before squash
|
||||
|
@ -2303,14 +2302,11 @@ impl ReplayStage {
|
|||
|
||||
// Send our last few votes along with the new one
|
||||
// Compact the vote state update before sending
|
||||
let should_compact = bank
|
||||
.feature_set
|
||||
.is_active(&feature_set::compact_vote_state_updates::id());
|
||||
let vote = match (should_compact, vote) {
|
||||
(true, VoteTransaction::VoteStateUpdate(vote_state_update)) => {
|
||||
let vote = match vote {
|
||||
VoteTransaction::VoteStateUpdate(vote_state_update) => {
|
||||
VoteTransaction::CompactVoteStateUpdate(vote_state_update)
|
||||
}
|
||||
(_, vote) => vote,
|
||||
vote => vote,
|
||||
};
|
||||
let vote_ix = switch_fork_decision
|
||||
.to_vote_instruction(
|
||||
|
@ -3024,10 +3020,7 @@ impl ReplayStage {
|
|||
if !is_computed {
|
||||
// Check if our tower is behind, if so (and the feature migration flag is in use)
|
||||
// overwrite with the newer bank.
|
||||
if let (true, Some(vote_account)) = (
|
||||
Tower::is_direct_vote_state_update_enabled(bank),
|
||||
bank.get_vote_account(my_vote_pubkey),
|
||||
) {
|
||||
if let Some(vote_account) = bank.get_vote_account(my_vote_pubkey) {
|
||||
if let Ok(mut bank_vote_state) = vote_account.vote_state().cloned() {
|
||||
if bank_vote_state.last_voted_slot()
|
||||
> tower.vote_state.last_voted_slot()
|
||||
|
@ -6297,10 +6290,7 @@ pub(crate) mod tests {
|
|||
assert_eq!(reset_fork.unwrap(), 4);
|
||||
|
||||
// Record the vote for 5 which is not on the heaviest fork.
|
||||
tower.record_bank_vote(
|
||||
&bank_forks.read().unwrap().get(5).unwrap(),
|
||||
&Pubkey::default(),
|
||||
);
|
||||
tower.record_bank_vote(&bank_forks.read().unwrap().get(5).unwrap());
|
||||
|
||||
// 4 should be the heaviest slot, but should not be votable
|
||||
// because of lockout. 5 is the heaviest slot on the same fork as the last vote.
|
||||
|
@ -6447,10 +6437,7 @@ pub(crate) mod tests {
|
|||
assert_eq!(reset_fork.unwrap(), 4);
|
||||
|
||||
// Record the vote for 4
|
||||
tower.record_bank_vote(
|
||||
&bank_forks.read().unwrap().get(4).unwrap(),
|
||||
&Pubkey::default(),
|
||||
);
|
||||
tower.record_bank_vote(&bank_forks.read().unwrap().get(4).unwrap());
|
||||
|
||||
// Mark 4 as duplicate, 3 should be the heaviest slot, but should not be votable
|
||||
// because of lockout
|
||||
|
@ -6684,10 +6671,7 @@ pub(crate) mod tests {
|
|||
..
|
||||
} = vote_simulator;
|
||||
|
||||
tower.record_bank_vote(
|
||||
&bank_forks.read().unwrap().get(first_vote).unwrap(),
|
||||
&Pubkey::default(),
|
||||
);
|
||||
tower.record_bank_vote(&bank_forks.read().unwrap().get(first_vote).unwrap());
|
||||
|
||||
// Simulate another version of slot 2 was duplicate confirmed
|
||||
let our_bank2_hash = bank_forks.read().unwrap().bank_hash(2).unwrap();
|
||||
|
@ -7079,7 +7063,7 @@ pub(crate) mod tests {
|
|||
// Simulate landing a vote for slot 0 landing in slot 1
|
||||
let bank1 = Arc::new(Bank::new_from_parent(bank0.clone(), &Pubkey::default(), 1));
|
||||
bank1.fill_bank_with_ticks_for_tests();
|
||||
tower.record_bank_vote(&bank0, &my_vote_pubkey);
|
||||
tower.record_bank_vote(&bank0);
|
||||
ReplayStage::push_vote(
|
||||
&bank0,
|
||||
&my_vote_pubkey,
|
||||
|
@ -7149,7 +7133,7 @@ pub(crate) mod tests {
|
|||
|
||||
// Simulate submitting a new vote for bank 1 to the network, but the vote
|
||||
// not landing
|
||||
tower.record_bank_vote(&bank1, &my_vote_pubkey);
|
||||
tower.record_bank_vote(&bank1);
|
||||
ReplayStage::push_vote(
|
||||
&bank1,
|
||||
&my_vote_pubkey,
|
||||
|
@ -7344,7 +7328,7 @@ pub(crate) mod tests {
|
|||
progress: &mut ProgressMap,
|
||||
) -> Arc<Bank> {
|
||||
let my_vote_pubkey = &my_vote_keypair[0].pubkey();
|
||||
tower.record_bank_vote(&parent_bank, my_vote_pubkey);
|
||||
tower.record_bank_vote(&parent_bank);
|
||||
ReplayStage::push_vote(
|
||||
&parent_bank,
|
||||
my_vote_pubkey,
|
||||
|
|
|
@ -209,7 +209,6 @@ impl VerifiedVotePackets {
|
|||
&mut self,
|
||||
vote_packets_receiver: &VerifiedLabelVotePacketsReceiver,
|
||||
would_be_leader: bool,
|
||||
is_full_tower_vote_enabled: bool,
|
||||
) -> Result<()> {
|
||||
use SingleValidatorVotes::*;
|
||||
const RECV_TIMEOUT: Duration = Duration::from_millis(200);
|
||||
|
@ -233,8 +232,8 @@ impl VerifiedVotePackets {
|
|||
let hash = vote.hash();
|
||||
let timestamp = vote.timestamp();
|
||||
|
||||
match (vote, is_full_tower_vote_enabled) {
|
||||
(VoteStateUpdate(_), true) => {
|
||||
match vote {
|
||||
VoteStateUpdate(_) => {
|
||||
let (latest_gossip_slot, latest_timestamp) =
|
||||
self.0.get(&vote_account_key).map_or((0, None), |vote| {
|
||||
(vote.get_latest_gossip_slot(), vote.get_latest_timestamp())
|
||||
|
@ -265,7 +264,7 @@ impl VerifiedVotePackets {
|
|||
if let Some(FullTowerVote(gossip_vote)) =
|
||||
self.0.get_mut(&vote_account_key)
|
||||
{
|
||||
if slot > gossip_vote.slot && is_full_tower_vote_enabled {
|
||||
if slot > gossip_vote.slot {
|
||||
warn!(
|
||||
"Originally {} submitted full tower votes, but now has reverted to incremental votes. Converting back to old format.",
|
||||
vote_account_key
|
||||
|
@ -341,7 +340,7 @@ mod tests {
|
|||
}])
|
||||
.unwrap();
|
||||
verified_vote_packets
|
||||
.receive_and_process_vote_packets(&r, true, false)
|
||||
.receive_and_process_vote_packets(&r, true)
|
||||
.unwrap();
|
||||
assert_eq!(
|
||||
verified_vote_packets
|
||||
|
@ -361,7 +360,7 @@ mod tests {
|
|||
}])
|
||||
.unwrap();
|
||||
verified_vote_packets
|
||||
.receive_and_process_vote_packets(&r, true, false)
|
||||
.receive_and_process_vote_packets(&r, true)
|
||||
.unwrap();
|
||||
assert_eq!(
|
||||
verified_vote_packets
|
||||
|
@ -383,7 +382,7 @@ mod tests {
|
|||
}])
|
||||
.unwrap();
|
||||
verified_vote_packets
|
||||
.receive_and_process_vote_packets(&r, true, false)
|
||||
.receive_and_process_vote_packets(&r, true)
|
||||
.unwrap();
|
||||
assert_eq!(
|
||||
verified_vote_packets
|
||||
|
@ -406,7 +405,7 @@ mod tests {
|
|||
}])
|
||||
.unwrap();
|
||||
verified_vote_packets
|
||||
.receive_and_process_vote_packets(&r, true, false)
|
||||
.receive_and_process_vote_packets(&r, true)
|
||||
.unwrap();
|
||||
assert_eq!(
|
||||
verified_vote_packets
|
||||
|
@ -419,7 +418,7 @@ mod tests {
|
|||
|
||||
// No new messages, should time out
|
||||
assert_matches!(
|
||||
verified_vote_packets.receive_and_process_vote_packets(&r, true, false),
|
||||
verified_vote_packets.receive_and_process_vote_packets(&r, true),
|
||||
Err(Error::RecvTimeout(_))
|
||||
);
|
||||
}
|
||||
|
@ -448,7 +447,7 @@ mod tests {
|
|||
|
||||
// At most `MAX_VOTES_PER_VALIDATOR` should be stored per validator
|
||||
verified_vote_packets
|
||||
.receive_and_process_vote_packets(&r, true, false)
|
||||
.receive_and_process_vote_packets(&r, true)
|
||||
.unwrap();
|
||||
assert_eq!(
|
||||
verified_vote_packets
|
||||
|
@ -486,7 +485,7 @@ mod tests {
|
|||
// Ingest the votes into the buffer
|
||||
let mut verified_vote_packets = VerifiedVotePackets(HashMap::new());
|
||||
verified_vote_packets
|
||||
.receive_and_process_vote_packets(&r, true, false)
|
||||
.receive_and_process_vote_packets(&r, true)
|
||||
.unwrap();
|
||||
|
||||
// Create tracker for previously sent bank votes
|
||||
|
@ -542,7 +541,7 @@ mod tests {
|
|||
// Ingest the votes into the buffer
|
||||
let mut verified_vote_packets = VerifiedVotePackets(HashMap::new());
|
||||
verified_vote_packets
|
||||
.receive_and_process_vote_packets(&r, true, false)
|
||||
.receive_and_process_vote_packets(&r, true)
|
||||
.unwrap();
|
||||
|
||||
// One batch of vote packets per validator
|
||||
|
@ -603,7 +602,7 @@ mod tests {
|
|||
.unwrap();
|
||||
// Ingest the votes into the buffer
|
||||
verified_vote_packets
|
||||
.receive_and_process_vote_packets(&r, true, false)
|
||||
.receive_and_process_vote_packets(&r, true)
|
||||
.unwrap();
|
||||
let mut gossip_votes_iterator = ValidatorGossipVotesIterator::new(
|
||||
my_leader_bank,
|
||||
|
@ -624,7 +623,7 @@ mod tests {
|
|||
let second_vote = VoteStateUpdate::from(vec![(2, 4), (4, 3), (11, 1)]);
|
||||
let third_vote = VoteStateUpdate::from(vec![(2, 5), (4, 4), (11, 3), (12, 2), (13, 1)]);
|
||||
|
||||
for vote in [second_vote.clone(), first_vote.clone()] {
|
||||
for vote in [second_vote, first_vote] {
|
||||
s.send(vec![VerifiedVoteMetadata {
|
||||
vote_account_key,
|
||||
vote: VoteTransaction::from(vote),
|
||||
|
@ -636,7 +635,7 @@ mod tests {
|
|||
|
||||
let mut verified_vote_packets = VerifiedVotePackets(HashMap::new());
|
||||
verified_vote_packets
|
||||
.receive_and_process_vote_packets(&r, true, true)
|
||||
.receive_and_process_vote_packets(&r, true)
|
||||
.unwrap();
|
||||
|
||||
// second_vote should be kept and first_vote ignored
|
||||
|
@ -650,14 +649,14 @@ mod tests {
|
|||
// Now send the third_vote, it should overwrite second_vote
|
||||
s.send(vec![VerifiedVoteMetadata {
|
||||
vote_account_key,
|
||||
vote: VoteTransaction::from(third_vote.clone()),
|
||||
vote: VoteTransaction::from(third_vote),
|
||||
packet_batch: PacketBatch::default(),
|
||||
signature: Signature::from([1u8; 64]),
|
||||
}])
|
||||
.unwrap();
|
||||
|
||||
verified_vote_packets
|
||||
.receive_and_process_vote_packets(&r, true, true)
|
||||
.receive_and_process_vote_packets(&r, true)
|
||||
.unwrap();
|
||||
let slot = verified_vote_packets
|
||||
.0
|
||||
|
@ -665,30 +664,6 @@ mod tests {
|
|||
.unwrap()
|
||||
.get_latest_gossip_slot();
|
||||
assert_eq!(13, slot);
|
||||
|
||||
// Now send all three, but keep the feature off
|
||||
for vote in vec![second_vote, first_vote, third_vote] {
|
||||
s.send(vec![VerifiedVoteMetadata {
|
||||
vote_account_key,
|
||||
vote: VoteTransaction::from(vote),
|
||||
packet_batch: PacketBatch::default(),
|
||||
signature: Signature::from([1u8; 64]),
|
||||
}])
|
||||
.unwrap();
|
||||
}
|
||||
let mut verified_vote_packets = VerifiedVotePackets(HashMap::new());
|
||||
verified_vote_packets
|
||||
.receive_and_process_vote_packets(&r, true, false)
|
||||
.unwrap();
|
||||
|
||||
assert_eq!(
|
||||
3,
|
||||
verified_vote_packets
|
||||
.0
|
||||
.get(&vote_account_key)
|
||||
.unwrap()
|
||||
.len()
|
||||
);
|
||||
}
|
||||
|
||||
fn send_vote_state_update_and_process(
|
||||
|
@ -696,7 +671,6 @@ mod tests {
|
|||
r: &Receiver<Vec<VerifiedVoteMetadata>>,
|
||||
vote: VoteStateUpdate,
|
||||
vote_account_key: Pubkey,
|
||||
is_tower_full_vote_enabled: bool,
|
||||
verified_vote_packets: &mut VerifiedVotePackets,
|
||||
) -> GossipVote {
|
||||
s.send(vec![VerifiedVoteMetadata {
|
||||
|
@ -707,7 +681,7 @@ mod tests {
|
|||
}])
|
||||
.unwrap();
|
||||
verified_vote_packets
|
||||
.receive_and_process_vote_packets(r, true, is_tower_full_vote_enabled)
|
||||
.receive_and_process_vote_packets(r, true)
|
||||
.unwrap();
|
||||
match verified_vote_packets.0.get(&vote_account_key).unwrap() {
|
||||
SingleValidatorVotes::FullTowerVote(gossip_vote) => gossip_vote.clone(),
|
||||
|
@ -743,7 +717,6 @@ mod tests {
|
|||
&r,
|
||||
vote.clone(),
|
||||
vote_account_key,
|
||||
true,
|
||||
&mut verified_vote_packets,
|
||||
);
|
||||
assert_eq!(slot, vote.last_voted_slot().unwrap());
|
||||
|
@ -757,7 +730,6 @@ mod tests {
|
|||
&r,
|
||||
vote_later_ts.clone(),
|
||||
vote_account_key,
|
||||
true,
|
||||
&mut verified_vote_packets,
|
||||
);
|
||||
assert_eq!(slot, vote_later_ts.last_voted_slot().unwrap());
|
||||
|
@ -771,7 +743,6 @@ mod tests {
|
|||
&r,
|
||||
vote_earlier_ts,
|
||||
vote_account_key,
|
||||
true,
|
||||
&mut verified_vote_packets,
|
||||
);
|
||||
assert_eq!(slot, vote_later_ts.last_voted_slot().unwrap());
|
||||
|
@ -785,7 +756,6 @@ mod tests {
|
|||
&r,
|
||||
vote_no_ts,
|
||||
vote_account_key,
|
||||
true,
|
||||
&mut verified_vote_packets,
|
||||
);
|
||||
assert_eq!(slot, vote_later_ts.last_voted_slot().unwrap());
|
||||
|
@ -812,7 +782,7 @@ mod tests {
|
|||
let mut verified_vote_packets = VerifiedVotePackets(HashMap::new());
|
||||
// Receive votes without the feature active
|
||||
verified_vote_packets
|
||||
.receive_and_process_vote_packets(&r, true, false)
|
||||
.receive_and_process_vote_packets(&r, true)
|
||||
.unwrap();
|
||||
assert_eq!(
|
||||
100,
|
||||
|
@ -846,7 +816,7 @@ mod tests {
|
|||
|
||||
// Receive votes with the feature active
|
||||
verified_vote_packets
|
||||
.receive_and_process_vote_packets(&r, true, true)
|
||||
.receive_and_process_vote_packets(&r, true)
|
||||
.unwrap();
|
||||
if let FullTowerVote(vote) = verified_vote_packets.0.get(&vote_account_key).unwrap() {
|
||||
assert_eq!(200, vote.slot);
|
||||
|
@ -873,7 +843,7 @@ mod tests {
|
|||
|
||||
// Receive incremental votes with the feature active
|
||||
verified_vote_packets
|
||||
.receive_and_process_vote_packets(&r, true, true)
|
||||
.receive_and_process_vote_packets(&r, true)
|
||||
.unwrap();
|
||||
|
||||
// Should still store as incremental votes
|
||||
|
@ -902,7 +872,7 @@ mod tests {
|
|||
|
||||
// Receive full votes
|
||||
verified_vote_packets
|
||||
.receive_and_process_vote_packets(&r, true, true)
|
||||
.receive_and_process_vote_packets(&r, true)
|
||||
.unwrap();
|
||||
assert_eq!(
|
||||
42,
|
||||
|
@ -925,7 +895,7 @@ mod tests {
|
|||
|
||||
// Try to receive nothing should happen
|
||||
verified_vote_packets
|
||||
.receive_and_process_vote_packets(&r, true, true)
|
||||
.receive_and_process_vote_packets(&r, true)
|
||||
.unwrap();
|
||||
if let FullTowerVote(vote) = verified_vote_packets.0.get(&vote_account_key).unwrap() {
|
||||
assert_eq!(42, vote.slot);
|
||||
|
@ -946,7 +916,7 @@ mod tests {
|
|||
|
||||
// Try to receive and vote lands as well as the conversion back to incremental votes
|
||||
verified_vote_packets
|
||||
.receive_and_process_vote_packets(&r, true, true)
|
||||
.receive_and_process_vote_packets(&r, true)
|
||||
.unwrap();
|
||||
if let IncrementalVotes(votes) = verified_vote_packets.0.get(&vote_account_key).unwrap() {
|
||||
assert!(votes.contains_key(&(42, hash_42)));
|
||||
|
|
|
@ -143,8 +143,6 @@ impl VoteSimulator {
|
|||
tower: &mut Tower,
|
||||
) -> Vec<HeaviestForkFailures> {
|
||||
// Try to simulate the vote
|
||||
let my_keypairs = self.validator_keypairs.get(my_pubkey).unwrap();
|
||||
let my_vote_pubkey = my_keypairs.vote_keypair.pubkey();
|
||||
let ancestors = self.bank_forks.read().unwrap().ancestors();
|
||||
let mut frozen_banks: Vec<_> = self
|
||||
.bank_forks
|
||||
|
@ -197,7 +195,7 @@ impl VoteSimulator {
|
|||
return heaviest_fork_failures;
|
||||
}
|
||||
|
||||
let new_root = tower.record_bank_vote(&vote_bank, &my_vote_pubkey);
|
||||
let new_root = tower.record_bank_vote(&vote_bank);
|
||||
if let Some(new_root) = new_root {
|
||||
self.set_root(new_root);
|
||||
}
|
||||
|
|
|
@ -180,10 +180,6 @@ declare_process_instruction!(
|
|||
}
|
||||
VoteInstruction::UpdateVoteState(vote_state_update)
|
||||
| VoteInstruction::UpdateVoteStateSwitch(vote_state_update, _) => {
|
||||
if invoke_context
|
||||
.feature_set
|
||||
.is_active(&feature_set::allow_votes_to_directly_update_vote_state::id())
|
||||
{
|
||||
let sysvar_cache = invoke_context.get_sysvar_cache();
|
||||
let slot_hashes = sysvar_cache.get_slot_hashes()?;
|
||||
let clock = sysvar_cache.get_clock()?;
|
||||
|
@ -195,19 +191,9 @@ declare_process_instruction!(
|
|||
&signers,
|
||||
&invoke_context.feature_set,
|
||||
)
|
||||
} else {
|
||||
Err(InstructionError::InvalidInstructionData)
|
||||
}
|
||||
}
|
||||
VoteInstruction::CompactUpdateVoteState(vote_state_update)
|
||||
| VoteInstruction::CompactUpdateVoteStateSwitch(vote_state_update, _) => {
|
||||
if invoke_context
|
||||
.feature_set
|
||||
.is_active(&feature_set::allow_votes_to_directly_update_vote_state::id())
|
||||
&& invoke_context
|
||||
.feature_set
|
||||
.is_active(&feature_set::compact_vote_state_updates::id())
|
||||
{
|
||||
let sysvar_cache = invoke_context.get_sysvar_cache();
|
||||
let slot_hashes = sysvar_cache.get_slot_hashes()?;
|
||||
let clock = sysvar_cache.get_clock()?;
|
||||
|
@ -219,9 +205,6 @@ declare_process_instruction!(
|
|||
&signers,
|
||||
&invoke_context.feature_set,
|
||||
)
|
||||
} else {
|
||||
Err(InstructionError::InvalidInstructionData)
|
||||
}
|
||||
}
|
||||
|
||||
VoteInstruction::Withdraw(lamports) => {
|
||||
|
|
Loading…
Reference in New Issue