Skip to content

Commit 0c5a67f

Browse files
insumityromac
andauthored
fix(code/core): Remove Ord constraint from Vote trait (#1148)
* remove unnecessary has_vote * remove unnecessary restore_votes * remove Ord trait from Vote and use Vec instead of BTreeSet * set an initial capacity to avoid re-allocations * Post-merge commit * Restore check for seen votes --------- Co-authored-by: Romain Ruetschi <[email protected]>
1 parent 325b4f7 commit 0c5a67f

File tree

4 files changed

+23
-54
lines changed

4 files changed

+23
-54
lines changed

code/crates/core-consensus/src/handle/vote.rs

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -76,19 +76,18 @@ where
7676

7777
debug_assert_eq!(consensus_height, vote_height);
7878

79-
// Only append to WAL and store the non-nil precommit if we have not yet seen this vote.
79+
// Only process this vote if we have not yet seen it.
8080
if !state.driver.votes().has_vote(&signed_vote) {
81-
// Append the vote to the Write-ahead Log
8281
perform!(
8382
co,
8483
Effect::WalAppend(
8584
WalEntry::ConsensusMsg(SignedConsensusMsg::Vote(signed_vote.clone())),
8685
Default::default()
8786
)
8887
);
89-
}
9088

91-
apply_driver_input(co, state, metrics, DriverInput::Vote(signed_vote)).await?;
89+
apply_driver_input(co, state, metrics, DriverInput::Vote(signed_vote)).await?;
90+
}
9291

9392
Ok(())
9493
}

code/crates/core-consensus/src/state.rs

Lines changed: 0 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -111,38 +111,6 @@ where
111111
}
112112
}
113113

114-
#[allow(clippy::type_complexity)]
115-
pub fn restore_votes(
116-
&mut self,
117-
height: Ctx::Height,
118-
round: Round,
119-
) -> Option<(Vec<SignedVote<Ctx>>, Vec<PolkaCertificate<Ctx>>)> {
120-
assert!(round.is_defined());
121-
122-
if height != self.driver.height() {
123-
return None;
124-
}
125-
126-
let mut votes = Vec::new();
127-
128-
let upper_round = self.driver.votes().max_round();
129-
for r in round_range_inclusive(round, upper_round) {
130-
let per_round = self.driver.votes().per_round(r)?;
131-
votes.extend(per_round.received_votes().iter().cloned());
132-
}
133-
134-
// Gather polka certificates for all rounds up to `round` included
135-
let certificates = self
136-
.driver
137-
.polka_certificates()
138-
.iter()
139-
.filter(|c| c.round <= round && c.height == height)
140-
.cloned()
141-
.collect::<Vec<_>>();
142-
143-
Some((votes, certificates))
144-
}
145-
146114
pub fn polka_certificate_at_round(&self, round: Round) -> Option<PolkaCertificate<Ctx>> {
147115
// Get the polka certificate for the specified round if it exists
148116
self.driver
@@ -274,15 +242,3 @@ where
274242
self.driver.round_certificate.as_ref()
275243
}
276244
}
277-
278-
fn round_range_inclusive(from: Round, to: Round) -> Box<dyn Iterator<Item = Round>> {
279-
if !from.is_defined() || !to.is_defined() || from > to {
280-
return Box::new(std::iter::empty());
281-
}
282-
283-
if from == to {
284-
return Box::new(std::iter::once(from));
285-
}
286-
287-
Box::new((from.as_u32().unwrap_or(0)..=to.as_u32().unwrap_or(0)).map(Round::new))
288-
}

code/crates/core-types/src/vote.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ pub enum VoteType {
2323
/// include information about the validator signing it.
2424
pub trait Vote<Ctx>
2525
where
26-
Self: Clone + Debug + Eq + Ord + Send + Sync + 'static,
26+
Self: Clone + Debug + Eq + Send + Sync + 'static,
2727
Ctx: Context,
2828
{
2929
/// The height for which the vote is for.

code/crates/core-votekeeper/src/keeper.rs

Lines changed: 19 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ use derive_where::derive_where;
44
use thiserror::Error;
55

66
use alloc::collections::{BTreeMap, BTreeSet};
7-
7+
use alloc::vec::Vec;
88
use malachitebft_core_types::{
99
Context, NilOrVal, Round, SignedVote, Validator, ValidatorSet, ValueId, Vote, VoteType,
1010
};
@@ -49,7 +49,7 @@ where
4949
addresses_weights: RoundWeights<Ctx::Address>,
5050

5151
/// All the votes received for this round.
52-
received_votes: BTreeSet<SignedVote<Ctx>>,
52+
received_votes: Vec<SignedVote<Ctx>>,
5353

5454
/// The emitted outputs for this round.
5555
emitted_outputs: BTreeSet<Output<ValueId<Ctx>>>,
@@ -80,6 +80,15 @@ where
8080
Self::default()
8181
}
8282

83+
/// Create a new `PerRound` instance with pre-allocated capacity for the expected number of votes.
84+
pub fn with_expected_number_of_votes(num_votes: usize) -> Self {
85+
Self {
86+
// pre-allocate capacity to avoid re-allocations during the addition of votes
87+
received_votes: Vec::with_capacity(num_votes),
88+
..Self::default()
89+
}
90+
}
91+
8392
/// Add a vote to the round, checking for conflicts.
8493
pub fn add(
8594
&mut self,
@@ -104,7 +113,7 @@ where
104113
.set_once(vote.validator_address(), weight);
105114

106115
// Add the vote to the received votes
107-
self.received_votes.insert(vote);
116+
self.received_votes.push(vote);
108117

109118
Ok(())
110119
}
@@ -126,7 +135,7 @@ where
126135
}
127136

128137
/// Return the votes for this round.
129-
pub fn received_votes(&self) -> &BTreeSet<SignedVote<Ctx>> {
138+
pub fn received_votes(&self) -> &Vec<SignedVote<Ctx>> {
130139
&self.received_votes
131140
}
132141

@@ -219,7 +228,12 @@ where
219228
round: Round,
220229
) -> Option<Output<ValueId<Ctx>>> {
221230
let total_weight = self.total_weight();
222-
let per_round = self.per_round.entry(vote.round()).or_default();
231+
let per_round =
232+
self.per_round
233+
.entry(vote.round())
234+
.or_insert(PerRound::with_expected_number_of_votes(
235+
self.validator_set.count(),
236+
));
223237

224238
let Some(validator) = self.validator_set.get_by_address(vote.validator_address()) else {
225239
// Vote from unknown validator, let's discard it.

0 commit comments

Comments
 (0)