Cleanup - filter_votes_outside_slot_hashes (#31760)

filter_votes_outside_slot_hashes
This commit is contained in:
Alexander Meißner 2023-06-14 01:31:27 +02:00 committed by GitHub
parent 67a434fc5b
commit 3b0b0ba07d
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
1 changed files with 50 additions and 108 deletions

View File

@ -10,7 +10,7 @@ use {
account::{AccountSharedData, ReadableAccount, WritableAccount},
clock::{Epoch, Slot, UnixTimestamp},
epoch_schedule::EpochSchedule,
feature_set::{self, filter_votes_outside_slot_hashes, FeatureSet},
feature_set::{self, FeatureSet},
hash::Hash,
instruction::InstructionError,
pubkey::Pubkey,
@ -722,54 +722,54 @@ pub fn process_new_vote_state(
Ok(())
}
pub fn process_vote(
fn process_vote_unfiltered(
vote_state: &mut VoteState,
vote_slots: &[Slot],
vote: &Vote,
slot_hashes: &[SlotHash],
epoch: Epoch,
feature_set: Option<&FeatureSet>,
) -> Result<(), VoteError> {
if vote.slots.is_empty() {
return Err(VoteError::EmptySlots);
}
let filtered_vote_slots = feature_set.and_then(|feature_set| {
if feature_set.is_active(&filter_votes_outside_slot_hashes::id()) {
let earliest_slot_in_history =
slot_hashes.last().map(|(slot, _hash)| *slot).unwrap_or(0);
Some(
vote.slots
.iter()
.filter(|slot| **slot >= earliest_slot_in_history)
.cloned()
.collect::<Vec<Slot>>(),
)
} else {
None
}
});
let vote_slots = filtered_vote_slots.as_ref().unwrap_or(&vote.slots);
if vote_slots.is_empty() {
return Err(VoteError::VotesTooOldAllFiltered);
}
check_slots_are_valid(vote_state, vote_slots, &vote.hash, slot_hashes)?;
vote_slots
.iter()
.for_each(|s| vote_state.process_next_vote_slot(*s, epoch));
Ok(())
}
pub fn process_vote(
vote_state: &mut VoteState,
vote: &Vote,
slot_hashes: &[SlotHash],
epoch: Epoch,
) -> Result<(), VoteError> {
if vote.slots.is_empty() {
return Err(VoteError::EmptySlots);
}
let earliest_slot_in_history = slot_hashes.last().map(|(slot, _hash)| *slot).unwrap_or(0);
let vote_slots = vote
.slots
.iter()
.filter(|slot| **slot >= earliest_slot_in_history)
.cloned()
.collect::<Vec<Slot>>();
if vote_slots.is_empty() {
return Err(VoteError::VotesTooOldAllFiltered);
}
process_vote_unfiltered(vote_state, &vote_slots, vote, slot_hashes, epoch)
}
/// "unchecked" functions used by tests and Tower
pub fn process_vote_unchecked(vote_state: &mut VoteState, vote: Vote) {
if vote.slots.is_empty() {
return;
}
let slot_hashes: Vec<_> = vote.slots.iter().rev().map(|x| (*x, vote.hash)).collect();
let _ignored = process_vote(
let _ignored = process_vote_unfiltered(
vote_state,
&vote.slots,
&vote,
&slot_hashes,
vote_state.current_epoch(),
None,
);
}
@ -1017,13 +1017,7 @@ pub fn process_vote_with_account<S: std::hash::BuildHasher>(
) -> Result<(), InstructionError> {
let mut vote_state = verify_and_get_vote_state(vote_account, clock, signers)?;
process_vote(
&mut vote_state,
vote,
slot_hashes,
clock.epoch,
Some(feature_set),
)?;
process_vote(&mut vote_state, vote, slot_hashes, clock.epoch)?;
if let Some(timestamp) = vote.timestamp {
vote.slots
.iter()
@ -1180,19 +1174,19 @@ mod tests {
vote_state.increment_credits(0, 100);
assert_eq!(
vote_state
.set_new_authorized_voter(&solana_sdk::pubkey::new_rand(), 0, 1, |_pubkey| Ok(()),),
.set_new_authorized_voter(&solana_sdk::pubkey::new_rand(), 0, 1, |_pubkey| Ok(())),
Ok(())
);
vote_state.increment_credits(1, 200);
assert_eq!(
vote_state
.set_new_authorized_voter(&solana_sdk::pubkey::new_rand(), 1, 2, |_pubkey| Ok(()),),
.set_new_authorized_voter(&solana_sdk::pubkey::new_rand(), 1, 2, |_pubkey| Ok(())),
Ok(())
);
vote_state.increment_credits(2, 300);
assert_eq!(
vote_state
.set_new_authorized_voter(&solana_sdk::pubkey::new_rand(), 2, 3, |_pubkey| Ok(()),),
.set_new_authorized_voter(&solana_sdk::pubkey::new_rand(), 2, 3, |_pubkey| Ok(())),
Ok(())
);
// Simulate votes having occurred
@ -1494,23 +1488,11 @@ mod tests {
let slot_hashes: Vec<_> = vote.slots.iter().rev().map(|x| (*x, vote.hash)).collect();
assert_eq!(
process_vote(
&mut vote_state_a,
&vote,
&slot_hashes,
0,
Some(&FeatureSet::default())
),
process_vote(&mut vote_state_a, &vote, &slot_hashes, 0),
Ok(())
);
assert_eq!(
process_vote(
&mut vote_state_b,
&vote,
&slot_hashes,
0,
Some(&FeatureSet::default())
),
process_vote(&mut vote_state_b, &vote, &slot_hashes, 0),
Ok(())
);
assert_eq!(recent_votes(&vote_state_a), recent_votes(&vote_state_b));
@ -1523,24 +1505,12 @@ mod tests {
let vote = Vote::new(vec![0], Hash::default());
let slot_hashes: Vec<_> = vec![(0, vote.hash)];
assert_eq!(
process_vote(
&mut vote_state,
&vote,
&slot_hashes,
0,
Some(&FeatureSet::default())
),
process_vote(&mut vote_state, &vote, &slot_hashes, 0),
Ok(())
);
let recent = recent_votes(&vote_state);
assert_eq!(
process_vote(
&mut vote_state,
&vote,
&slot_hashes,
0,
Some(&FeatureSet::default())
),
process_vote(&mut vote_state, &vote, &slot_hashes, 0),
Err(VoteError::VoteTooOld)
);
assert_eq!(recent, recent_votes(&vote_state));
@ -1600,13 +1570,7 @@ mod tests {
let vote = Vote::new(vec![0], Hash::default());
let slot_hashes: Vec<_> = vec![(*vote.slots.last().unwrap(), vote.hash)];
assert_eq!(
process_vote(
&mut vote_state,
&vote,
&slot_hashes,
0,
Some(&FeatureSet::default())
),
process_vote(&mut vote_state, &vote, &slot_hashes, 0),
Ok(())
);
assert_eq!(
@ -1622,13 +1586,7 @@ mod tests {
let vote = Vote::new(vec![0], Hash::default());
let slot_hashes: Vec<_> = vec![(*vote.slots.last().unwrap(), vote.hash)];
assert_eq!(
process_vote(
&mut vote_state,
&vote,
&slot_hashes,
0,
Some(&FeatureSet::default())
),
process_vote(&mut vote_state, &vote, &slot_hashes, 0),
Ok(())
);
@ -1647,13 +1605,7 @@ mod tests {
let vote = Vote::new(vec![0], Hash::default());
let slot_hashes: Vec<_> = vec![(*vote.slots.last().unwrap(), vote.hash)];
assert_eq!(
process_vote(
&mut vote_state,
&vote,
&slot_hashes,
0,
Some(&FeatureSet::default())
),
process_vote(&mut vote_state, &vote, &slot_hashes, 0),
Ok(())
);
@ -1670,7 +1622,7 @@ mod tests {
let vote = Vote::new(vec![], Hash::default());
assert_eq!(
process_vote(&mut vote_state, &vote, &[], 0, Some(&FeatureSet::default())),
process_vote(&mut vote_state, &vote, &[], 0),
Err(VoteError::EmptySlots)
);
}
@ -1788,7 +1740,7 @@ mod tests {
let current_epoch = vote_state1.current_epoch();
assert_eq!(
process_new_vote_state(&mut vote_state1, bad_votes, None, None, current_epoch, None,),
process_new_vote_state(&mut vote_state1, bad_votes, None, None, current_epoch, None),
Err(VoteError::TooManyVotes)
);
}
@ -1849,7 +1801,7 @@ mod tests {
.into_iter()
.collect();
assert_eq!(
process_new_vote_state(&mut vote_state1, bad_votes, None, None, current_epoch, None,),
process_new_vote_state(&mut vote_state1, bad_votes, None, None, current_epoch, None),
Err(VoteError::ZeroConfirmations)
);
@ -1860,7 +1812,7 @@ mod tests {
.into_iter()
.collect();
assert_eq!(
process_new_vote_state(&mut vote_state1, bad_votes, None, None, current_epoch, None,),
process_new_vote_state(&mut vote_state1, bad_votes, None, None, current_epoch, None),
Err(VoteError::ZeroConfirmations)
);
}
@ -2013,7 +1965,7 @@ mod tests {
// Slot 7 should have expired slot 0
assert_eq!(
process_new_vote_state(&mut vote_state1, bad_votes, None, None, current_epoch, None,),
process_new_vote_state(&mut vote_state1, bad_votes, None, None, current_epoch, None),
Err(VoteError::NewVoteStateLockoutMismatch)
);
}
@ -2316,10 +2268,6 @@ mod tests {
#[test]
fn test_filter_old_votes() {
// Enable feature
let mut feature_set = FeatureSet::default();
feature_set.activate(&filter_votes_outside_slot_hashes::id(), 0);
let mut vote_state = VoteState::default();
let old_vote_slot = 1;
let vote = Vote::new(vec![old_vote_slot], Hash::default());
@ -2328,7 +2276,7 @@ mod tests {
// error with `VotesTooOldAllFiltered`
let slot_hashes = vec![(3, Hash::new_unique()), (2, Hash::new_unique())];
assert_eq!(
process_vote(&mut vote_state, &vote, &slot_hashes, 0, Some(&feature_set),),
process_vote(&mut vote_state, &vote, &slot_hashes, 0),
Err(VoteError::VotesTooOldAllFiltered)
);
@ -2342,7 +2290,7 @@ mod tests {
.1;
let vote = Vote::new(vec![old_vote_slot, vote_slot], vote_slot_hash);
process_vote(&mut vote_state, &vote, &slot_hashes, 0, Some(&feature_set)).unwrap();
process_vote(&mut vote_state, &vote, &slot_hashes, 0).unwrap();
assert_eq!(
vote_state
.votes
@ -2370,14 +2318,8 @@ mod tests {
.find(|(slot, _hash)| slot == vote_slots.last().unwrap())
.unwrap()
.1;
process_vote(
&mut vote_state,
&Vote::new(vote_slots, vote_hash),
slot_hashes,
0,
None,
)
.unwrap();
let vote = Vote::new(vote_slots, vote_hash);
process_vote_unfiltered(&mut vote_state, &vote.slots, &vote, slot_hashes, 0).unwrap();
}
vote_state