Skip to content

Commit f516a89

Browse files
mergify[bot]steviezOliverNChalk
authored
v3.0: core: Adjust vote-storage handling (backport of #9898) (#9901)
Co-authored-by: steviez <[email protected]> Co-authored-by: OliverNChalk <[email protected]>
1 parent f4ac43d commit f516a89

File tree

2 files changed

+46
-30
lines changed

2 files changed

+46
-30
lines changed

core/src/banking_stage/latest_validator_vote_packet.rs

Lines changed: 29 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ pub struct LatestValidatorVotePacket {
2323
vote_source: VoteSource,
2424
vote_pubkey: Pubkey,
2525
vote: Option<Arc<ImmutableDeserializedPacket>>,
26+
authorized_voter_pubkey: Pubkey,
2627
slot: Slot,
2728
hash: Hash,
2829
timestamp: Option<UnixTimestamp>,
@@ -55,17 +56,29 @@ impl LatestValidatorVotePacket {
5556
Ok(vote_state_update_instruction)
5657
if instruction_filter(&vote_state_update_instruction) =>
5758
{
58-
let vote_account_index = instruction
59-
.accounts
60-
.first()
61-
.copied()
62-
.ok_or(DeserializedPacketError::VoteTransactionError)?;
63-
let vote_pubkey = message
64-
.message
65-
.static_account_keys()
66-
.get(vote_account_index as usize)
67-
.copied()
68-
.ok_or(DeserializedPacketError::VoteTransactionError)?;
59+
let ix_key = |offset: usize| {
60+
let index = instruction
61+
.accounts
62+
.get(offset)
63+
.copied()
64+
.ok_or(DeserializedPacketError::VoteTransactionError)?;
65+
let pubkey = message
66+
.message
67+
.static_account_keys()
68+
.get(index as usize)
69+
.copied()
70+
.ok_or(DeserializedPacketError::VoteTransactionError)?;
71+
let signed = message.message.is_signer(index as usize);
72+
73+
Ok::<(Pubkey, bool), DeserializedPacketError>((pubkey, signed))
74+
};
75+
76+
let (vote_pubkey, _) = ix_key(0)?;
77+
let (authorized_voter_pubkey, authorized_voter_signed) = ix_key(1)?;
78+
if !authorized_voter_signed {
79+
return Err(DeserializedPacketError::VoteTransactionError);
80+
}
81+
6982
let slot = vote_state_update_instruction.last_voted_slot().unwrap_or(0);
7083
let hash = vote_state_update_instruction.hash();
7184
let timestamp = vote_state_update_instruction.timestamp();
@@ -75,6 +88,7 @@ impl LatestValidatorVotePacket {
7588
slot,
7689
hash,
7790
vote_pubkey,
91+
authorized_voter_pubkey,
7892
vote_source,
7993
timestamp,
8094
})
@@ -101,6 +115,10 @@ impl LatestValidatorVotePacket {
101115
self.vote_pubkey
102116
}
103117

118+
pub fn authorized_voter_pubkey(&self) -> Pubkey {
119+
self.authorized_voter_pubkey
120+
}
121+
104122
pub fn slot(&self) -> Slot {
105123
self.slot
106124
}

core/src/banking_stage/vote_storage.rs

Lines changed: 17 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -214,6 +214,16 @@ impl VoteStorage {
214214
{
215215
continue;
216216
}
217+
218+
if self
219+
.cached_epoch_stakes
220+
.epoch_authorized_voters()
221+
.get(&vote.vote_pubkey())
222+
.is_none_or(|authorized| authorized != &vote.authorized_voter_pubkey())
223+
{
224+
continue;
225+
}
226+
217227
if let Some(vote) = self.update_latest_vote(vote, should_replenish_taken_votes) {
218228
match vote.source() {
219229
VoteSource::Gossip => num_dropped_gossip += 1,
@@ -344,13 +354,12 @@ mod tests {
344354
solana_epoch_schedule::MINIMUM_SLOTS_PER_EPOCH,
345355
solana_genesis_config::GenesisConfig,
346356
solana_hash::Hash,
347-
solana_keypair::Keypair,
348357
solana_perf::packet::{BytesPacket, PacketFlags},
349358
solana_runtime::genesis_utils::{self, ValidatorVoteKeypairs},
350359
solana_signer::Signer,
351360
solana_vote::vote_transaction::new_tower_sync_transaction,
352361
solana_vote_program::vote_state::TowerSync,
353-
std::error::Error,
362+
std::{error::Error, sync::Arc},
354363
};
355364

356365
fn packet_from_slots(
@@ -389,26 +398,14 @@ mod tests {
389398

390399
#[test]
391400
fn test_reinsert_packets() -> Result<(), Box<dyn Error>> {
392-
let node_keypair = Keypair::new();
401+
let keypair = ValidatorVoteKeypairs::new_rand();
393402
let genesis_config =
394-
genesis_utils::create_genesis_config_with_leader(100, &node_keypair.pubkey(), 200)
403+
genesis_utils::create_genesis_config_with_vote_accounts(100, &[&keypair], vec![200])
395404
.genesis_config;
396405
let (bank, _bank_forks) = Bank::new_with_bank_forks_for_tests(&genesis_config);
397-
let vote_keypair = Keypair::new();
398-
let mut vote = BytesPacket::from_data(
399-
None,
400-
new_tower_sync_transaction(
401-
TowerSync::default(),
402-
Hash::new_unique(),
403-
&node_keypair,
404-
&vote_keypair,
405-
&vote_keypair,
406-
None,
407-
),
408-
)?;
409-
vote.meta_mut().flags.set(PacketFlags::SIMPLE_VOTE_TX, true);
410-
411-
let mut vote_storage = VoteStorage::new_for_tests(&[vote_keypair.pubkey()]);
406+
407+
let vote = packet_from_slots(vec![(0, 1)], &keypair, None);
408+
let mut vote_storage = VoteStorage::new(&bank);
412409
vote_storage.insert_batch(
413410
VoteSource::Tpu,
414411
std::iter::once(ImmutableDeserializedPacket::new(vote.as_ref())?),
@@ -421,6 +418,7 @@ mod tests {
421418

422419
// All packets should remain in the transaction storage
423420
assert_eq!(1, vote_storage.len());
421+
424422
Ok(())
425423
}
426424

0 commit comments

Comments
 (0)