uses enum instead of trait for VoteTransaction (#22019)
Box<dyn Trait> involves runtime dispatch, has significant overhead and is slow. It also requires hacky boilerplate code for implementing Clone or other basic traits: https://github.com/solana-labs/solana/blob/e92a81b74/programs/vote/src/vote_state/mod.rs#L70-L102 Only limited known types can be VoteTransaction and they are all defined in the same crate. So using a trait here only adds overhead. https://github.com/solana-labs/solana/blob/e92a81b74/programs/vote/src/vote_state/mod.rs#L125-L165 https://github.com/solana-labs/solana/blob/e92a81b74/programs/vote/src/vote_state/mod.rs#L221-L264
This commit is contained in:
@ -677,7 +677,7 @@ impl ClusterInfoVoteListener {
|
||||
|
||||
#[allow(clippy::too_many_arguments)]
|
||||
fn track_new_votes_and_notify_confirmations(
|
||||
vote: Box<dyn VoteTransaction>,
|
||||
vote: VoteTransaction,
|
||||
vote_pubkey: &Pubkey,
|
||||
vote_tracker: &VoteTracker,
|
||||
root_bank: &Bank,
|
||||
@ -792,7 +792,7 @@ impl ClusterInfoVoteListener {
|
||||
fn filter_gossip_votes(
|
||||
vote_tracker: &VoteTracker,
|
||||
vote_pubkey: &Pubkey,
|
||||
vote: &dyn VoteTransaction,
|
||||
vote: &VoteTransaction,
|
||||
gossip_tx: &Transaction,
|
||||
) -> bool {
|
||||
if vote.is_empty() {
|
||||
@ -842,7 +842,7 @@ impl ClusterInfoVoteListener {
|
||||
.filter_map(|gossip_tx| {
|
||||
vote_transaction::parse_vote_transaction(gossip_tx)
|
||||
.filter(|(vote_pubkey, vote, _)| {
|
||||
Self::filter_gossip_votes(vote_tracker, vote_pubkey, &**vote, gossip_tx)
|
||||
Self::filter_gossip_votes(vote_tracker, vote_pubkey, vote, gossip_tx)
|
||||
})
|
||||
.map(|v| (true, v))
|
||||
})
|
||||
@ -1249,7 +1249,7 @@ mod tests {
|
||||
replay_votes_sender
|
||||
.send((
|
||||
vote_keypair.pubkey(),
|
||||
Box::new(replay_vote.clone()),
|
||||
VoteTransaction::from(replay_vote.clone()),
|
||||
switch_proof_hash,
|
||||
))
|
||||
.unwrap();
|
||||
@ -1537,7 +1537,7 @@ mod tests {
|
||||
replay_votes_sender
|
||||
.send((
|
||||
vote_keypair.pubkey(),
|
||||
Box::new(Vote::new(vec![vote_slot], Hash::default())),
|
||||
VoteTransaction::from(Vote::new(vec![vote_slot], Hash::default())),
|
||||
switch_proof_hash,
|
||||
))
|
||||
.unwrap();
|
||||
@ -1685,7 +1685,7 @@ mod tests {
|
||||
// Add gossip vote for same slot, should not affect outcome
|
||||
vec![(
|
||||
validator0_keypairs.vote_keypair.pubkey(),
|
||||
Box::new(Vote::new(vec![voted_slot], Hash::default())),
|
||||
VoteTransaction::from(Vote::new(vec![voted_slot], Hash::default())),
|
||||
None,
|
||||
)],
|
||||
&bank,
|
||||
@ -1741,7 +1741,7 @@ mod tests {
|
||||
vote_txs,
|
||||
vec![(
|
||||
validator_keypairs[1].vote_keypair.pubkey(),
|
||||
Box::new(Vote::new(vec![first_slot_in_new_epoch], Hash::default())),
|
||||
VoteTransaction::from(Vote::new(vec![first_slot_in_new_epoch], Hash::default())),
|
||||
None,
|
||||
)],
|
||||
&new_root_bank,
|
||||
|
@ -21,9 +21,7 @@ use {
|
||||
},
|
||||
solana_vote_program::{
|
||||
vote_instruction,
|
||||
vote_state::{
|
||||
BlockTimestamp, Lockout, Vote, VoteState, VoteTransaction, MAX_LOCKOUT_HISTORY,
|
||||
},
|
||||
vote_state::{BlockTimestamp, Lockout, Vote, VoteState, MAX_LOCKOUT_HISTORY},
|
||||
},
|
||||
std::{
|
||||
cmp::Ordering,
|
||||
@ -411,7 +409,8 @@ impl Tower {
|
||||
last_voted_slot_in_bank,
|
||||
);
|
||||
|
||||
new_vote.set_timestamp(self.maybe_timestamp(self.last_vote.last_voted_slot().unwrap_or(0)));
|
||||
new_vote.timestamp =
|
||||
self.maybe_timestamp(self.last_vote.slots.last().copied().unwrap_or_default());
|
||||
self.last_vote = new_vote;
|
||||
|
||||
let new_root = self.root();
|
||||
@ -434,11 +433,11 @@ impl Tower {
|
||||
}
|
||||
|
||||
pub fn last_voted_slot(&self) -> Option<Slot> {
|
||||
self.last_vote.last_voted_slot()
|
||||
self.last_vote.slots.last().copied()
|
||||
}
|
||||
|
||||
pub fn last_voted_slot_hash(&self) -> Option<(Slot, Hash)> {
|
||||
self.last_vote.last_voted_slot_hash()
|
||||
Some((*self.last_vote.slots.last()?, self.last_vote.hash))
|
||||
}
|
||||
|
||||
pub fn stray_restored_slot(&self) -> Option<Slot> {
|
||||
@ -1120,10 +1119,10 @@ impl Tower {
|
||||
);
|
||||
|
||||
assert_eq!(
|
||||
self.last_vote.last_voted_slot().unwrap(),
|
||||
*self.voted_slots().last().unwrap()
|
||||
self.last_vote.slots.last().unwrap(),
|
||||
self.voted_slots().last().unwrap()
|
||||
);
|
||||
self.stray_restored_slot = Some(self.last_vote.last_voted_slot().unwrap());
|
||||
self.stray_restored_slot = Some(*self.last_vote.slots.last().unwrap());
|
||||
}
|
||||
|
||||
Ok(())
|
||||
@ -2248,7 +2247,7 @@ pub mod test {
|
||||
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!(vote.slots, vec![0]);
|
||||
assert_eq!(local.tower(), vec![0]);
|
||||
}
|
||||
|
||||
@ -2259,7 +2258,7 @@ pub mod test {
|
||||
// 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());
|
||||
assert!(vote.slots.is_empty());
|
||||
}
|
||||
|
||||
#[test]
|
||||
@ -2274,7 +2273,7 @@ pub mod test {
|
||||
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!(vote.slots, vec![1]);
|
||||
assert_eq!(local.tower(), vec![0, 1]);
|
||||
}
|
||||
|
||||
@ -2294,7 +2293,7 @@ pub mod test {
|
||||
// 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!(vote.slots, vec![3]);
|
||||
assert_eq!(local.tower(), vec![3]);
|
||||
}
|
||||
|
||||
@ -2376,7 +2375,7 @@ pub mod test {
|
||||
tower.record_vote(i as u64, Hash::default());
|
||||
}
|
||||
|
||||
expected.timestamp = tower.last_vote.timestamp();
|
||||
expected.timestamp = tower.last_vote.timestamp;
|
||||
assert_eq!(expected, tower.last_vote)
|
||||
}
|
||||
|
||||
|
@ -18,7 +18,7 @@ const MAX_VOTES_PER_VALIDATOR: usize = 1000;
|
||||
|
||||
pub struct VerifiedVoteMetadata {
|
||||
pub vote_account_key: Pubkey,
|
||||
pub vote: Box<dyn VoteTransaction>,
|
||||
pub vote: VoteTransaction,
|
||||
pub packet_batch: PacketBatch,
|
||||
pub signature: Signature,
|
||||
}
|
||||
@ -198,7 +198,7 @@ mod tests {
|
||||
let vote = Vote::new(vec![vote_slot], vote_hash);
|
||||
s.send(vec![VerifiedVoteMetadata {
|
||||
vote_account_key,
|
||||
vote: Box::new(vote.clone()),
|
||||
vote: VoteTransaction::from(vote.clone()),
|
||||
packet_batch: PacketBatch::default(),
|
||||
signature: Signature::new(&[1u8; 64]),
|
||||
}])
|
||||
@ -218,7 +218,7 @@ mod tests {
|
||||
// Same slot, same hash, should not be inserted
|
||||
s.send(vec![VerifiedVoteMetadata {
|
||||
vote_account_key,
|
||||
vote: Box::new(vote),
|
||||
vote: VoteTransaction::from(vote),
|
||||
packet_batch: PacketBatch::default(),
|
||||
signature: Signature::new(&[1u8; 64]),
|
||||
}])
|
||||
@ -240,7 +240,7 @@ mod tests {
|
||||
let vote = Vote::new(vec![vote_slot], new_vote_hash);
|
||||
s.send(vec![VerifiedVoteMetadata {
|
||||
vote_account_key,
|
||||
vote: Box::new(vote),
|
||||
vote: VoteTransaction::from(vote),
|
||||
packet_batch: PacketBatch::default(),
|
||||
signature: Signature::new(&[1u8; 64]),
|
||||
}])
|
||||
@ -263,7 +263,7 @@ mod tests {
|
||||
let vote = Vote::new(vec![vote_slot], vote_hash);
|
||||
s.send(vec![VerifiedVoteMetadata {
|
||||
vote_account_key,
|
||||
vote: Box::new(vote),
|
||||
vote: VoteTransaction::from(vote),
|
||||
packet_batch: PacketBatch::default(),
|
||||
signature: Signature::new(&[2u8; 64]),
|
||||
}])
|
||||
@ -302,7 +302,7 @@ mod tests {
|
||||
let vote = Vote::new(vec![vote_slot], vote_hash);
|
||||
s.send(vec![VerifiedVoteMetadata {
|
||||
vote_account_key,
|
||||
vote: Box::new(vote),
|
||||
vote: VoteTransaction::from(vote),
|
||||
packet_batch: PacketBatch::default(),
|
||||
signature: Signature::new(&[1u8; 64]),
|
||||
}])
|
||||
@ -339,7 +339,7 @@ mod tests {
|
||||
let vote = Vote::new(vec![vote_slot], vote_hash);
|
||||
s.send(vec![VerifiedVoteMetadata {
|
||||
vote_account_key,
|
||||
vote: Box::new(vote),
|
||||
vote: VoteTransaction::from(vote),
|
||||
packet_batch: PacketBatch::default(),
|
||||
signature: Signature::new_unique(),
|
||||
}])
|
||||
@ -393,7 +393,7 @@ mod tests {
|
||||
let vote = Vote::new(vec![*vote_slot], *vote_hash);
|
||||
s.send(vec![VerifiedVoteMetadata {
|
||||
vote_account_key,
|
||||
vote: Box::new(vote),
|
||||
vote: VoteTransaction::from(vote),
|
||||
packet_batch: PacketBatch::new(vec![Packet::default(); num_packets]),
|
||||
signature: Signature::new_unique(),
|
||||
}])
|
||||
@ -457,7 +457,7 @@ mod tests {
|
||||
my_leader_bank.slot() + 1,
|
||||
));
|
||||
let vote_account_key = vote_simulator.vote_pubkeys[1];
|
||||
let vote = Box::new(Vote::new(vec![vote_slot], vote_hash));
|
||||
let vote = VoteTransaction::from(Vote::new(vec![vote_slot], vote_hash));
|
||||
s.send(vec![VerifiedVoteMetadata {
|
||||
vote_account_key,
|
||||
vote,
|
||||
|
Reference in New Issue
Block a user