Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
38 changes: 28 additions & 10 deletions core/src/banking_stage/latest_validator_vote_packet.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ pub enum VoteSource {
pub struct LatestValidatorVote {
vote_source: VoteSource,
vote_pubkey: Pubkey,
authorized_voter_pubkey: Pubkey,
vote: Option<SanitizedTransactionView<SharedBytes>>,
slot: Slot,
hash: Hash,
Expand Down Expand Up @@ -55,16 +56,28 @@ impl LatestValidatorVote {
Ok(vote_state_update_instruction)
if instruction_filter(&vote_state_update_instruction) =>
{
let vote_account_index = instruction
.accounts
.first()
.copied()
.ok_or(DeserializedPacketError::VoteTransaction)?;
let vote_pubkey = vote
.static_account_keys()
.get(vote_account_index as usize)
.copied()
.ok_or(DeserializedPacketError::VoteTransaction)?;
let ix_key = |offset| {
let index = instruction
.accounts
.get(offset)
.copied()
.ok_or(DeserializedPacketError::VoteTransaction)?;
let pubkey = vote
.static_account_keys()
.get(index as usize)
.copied()
.ok_or(DeserializedPacketError::VoteTransaction)?;
let signed = index < vote.num_required_signatures();

Ok((pubkey, signed))
};

let (vote_pubkey, _) = ix_key(0)?;
let (authorized_voter_pubkey, authorized_voter_signed) = ix_key(1)?;
if !authorized_voter_signed {
return Err(DeserializedPacketError::VoteTransaction);
}

let slot = vote_state_update_instruction.last_voted_slot().unwrap_or(0);
let hash = vote_state_update_instruction.hash();
let timestamp = vote_state_update_instruction.timestamp();
Expand All @@ -74,6 +87,7 @@ impl LatestValidatorVote {
slot,
hash,
vote_pubkey,
authorized_voter_pubkey,
vote_source,
timestamp,
})
Expand Down Expand Up @@ -105,6 +119,10 @@ impl LatestValidatorVote {
self.vote_pubkey
}

pub fn authorized_voter_pubkey(&self) -> Pubkey {
self.authorized_voter_pubkey
}

pub fn slot(&self) -> Slot {
self.slot
}
Expand Down
38 changes: 17 additions & 21 deletions core/src/banking_stage/vote_storage.rs
Original file line number Diff line number Diff line change
Expand Up @@ -213,6 +213,16 @@ impl VoteStorage {
{
continue;
}

if self
.cached_epoch_stakes
.epoch_authorized_voters()
.get(&vote.vote_pubkey())
.is_none_or(|authorized| authorized != &vote.authorized_voter_pubkey())
{
continue;
}

if let Some(vote) = self.update_latest_vote(vote, should_replenish_taken_votes) {
match vote.source() {
VoteSource::Gossip => num_dropped_gossip += 1,
Expand Down Expand Up @@ -340,13 +350,12 @@ pub(crate) mod tests {
solana_epoch_schedule::MINIMUM_SLOTS_PER_EPOCH,
solana_genesis_config::GenesisConfig,
solana_hash::Hash,
solana_keypair::Keypair,
solana_perf::packet::{BytesPacket, PacketFlags},
solana_runtime::genesis_utils::{self, ValidatorVoteKeypairs},
solana_signer::Signer,
solana_vote::vote_transaction::new_tower_sync_transaction,
solana_vote_program::vote_state::TowerSync,
std::{error::Error, sync::Arc},
std::sync::Arc,
};

pub(crate) fn packet_from_slots(
Expand Down Expand Up @@ -389,27 +398,15 @@ pub(crate) mod tests {
}

#[test]
fn test_reinsert_packets() -> Result<(), Box<dyn Error>> {
let node_keypair = Keypair::new();
fn test_reinsert_packets() {
let keypair = ValidatorVoteKeypairs::new_rand();
let genesis_config =
genesis_utils::create_genesis_config_with_leader(100, &node_keypair.pubkey(), 200)
genesis_utils::create_genesis_config_with_vote_accounts(100, &[&keypair], vec![200])
.genesis_config;
let (bank, _bank_forks) = Bank::new_with_bank_forks_for_tests(&genesis_config);
let vote_keypair = Keypair::new();
let mut vote = BytesPacket::from_data(
None,
new_tower_sync_transaction(
TowerSync::default(),
Hash::new_unique(),
&node_keypair,
&vote_keypair,
&vote_keypair,
None,
),
)?;
vote.meta_mut().flags.set(PacketFlags::SIMPLE_VOTE_TX, true);

let mut vote_storage = VoteStorage::new_for_tests(&[vote_keypair.pubkey()]);

let vote = packet_from_slots(vec![(0, 1)], &keypair, None);
let mut vote_storage = VoteStorage::new(&bank);
vote_storage.insert_batch(VoteSource::Tpu, std::iter::once(to_sanitized_view(vote)));
assert_eq!(1, vote_storage.len());

Expand All @@ -419,7 +416,6 @@ pub(crate) mod tests {

// All packets should remain in the transaction storage
assert_eq!(1, vote_storage.len());
Ok(())
}

#[test]
Expand Down
Loading