Skip to content

Commit 28a0c3a

Browse files
ancazamfirromac
andauthored
chore(code/blocksync): Include synced certificate in decision if one exists, otherwise derive (#598)
* Include synced certificate in decision if one exists, otherwise derive from seen commits. * Add `get_certificate` method on `Driver` --------- Co-authored-by: Romain Ruetschi <[email protected]>
1 parent 6c16dd1 commit 28a0c3a

File tree

3 files changed

+38
-15
lines changed

3 files changed

+38
-15
lines changed

code/crates/consensus/src/handle/decide.rs

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -14,8 +14,8 @@ where
1414
let proposal_round = proposal.round();
1515
let value = proposal.value();
1616

17-
// Restore the commits. Note that they will be removed from `state`
18-
let commits = state.restore_precommits(height, proposal_round, value);
17+
// We only decide proposals for the current height
18+
assert_eq!(height, state.driver.height());
1919

2020
// Clean proposals and values
2121
state.remove_full_proposals(height);
@@ -46,7 +46,17 @@ where
4646
}
4747
}
4848

49-
let certificate = CommitCertificate::new(height, proposal_round, value.id(), commits);
49+
// Look for an existing certificate
50+
let certificate = state
51+
.driver
52+
.get_certificate(proposal_round, value.id())
53+
.cloned()
54+
.unwrap_or_else(|| {
55+
// Restore the commits. Note that they will be removed from `state`
56+
let commits = state.restore_precommits(height, proposal_round, value);
57+
// TODO: should we verify we have 2/3rd commits?
58+
CommitCertificate::new(height, proposal_round, value.id(), commits)
59+
});
5060

5161
perform!(co, Effect::Decide { certificate });
5262

code/crates/driver/src/driver.rs

Lines changed: 15 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ use core::fmt;
44

55
use malachite_common::{
66
CommitCertificate, Context, Proposal, Round, SignedProposal, SignedVote, Timeout, TimeoutStep,
7-
Validator, ValidatorSet, Validity, Vote,
7+
Validator, ValidatorSet, Validity, ValueId, Vote,
88
};
99
use malachite_round::input::Input as RoundInput;
1010
use malachite_round::output::Output as RoundOutput;
@@ -38,6 +38,9 @@ where
3838
/// The validator set at the current height
3939
validator_set: Ctx::ValidatorSet,
4040

41+
/// The proposer for the current round, None for round nil.
42+
proposer: Option<Ctx::Address>,
43+
4144
/// The proposals to decide on.
4245
pub(crate) proposal_keeper: ProposalKeeper<Ctx>,
4346

@@ -50,9 +53,6 @@ where
5053
/// The state of the round state machine.
5154
pub(crate) round_state: RoundState<Ctx>,
5255

53-
/// The proposer for the current round, None for round nil.
54-
proposer: Option<Ctx::Address>,
55-
5656
/// The pending inputs to be processed next, if any.
5757
/// The first element of the tuple is the round at which that input has been emitted.
5858
pending_inputs: Vec<(Round, RoundInput<Ctx>)>,
@@ -176,6 +176,17 @@ where
176176
}
177177
}
178178

179+
/// Get a commit certificate for the given round and value id.
180+
pub fn get_certificate(
181+
&self,
182+
round: Round,
183+
value_id: ValueId<Ctx>,
184+
) -> Option<&CommitCertificate<Ctx>> {
185+
self.certificates
186+
.iter()
187+
.find(|c| c.round == round && c.value_id == value_id)
188+
}
189+
179190
/// Process the given input, returning the outputs to be broadcast to the network.
180191
pub fn process(&mut self, msg: Input<Ctx>) -> Result<Vec<Output<Ctx>>, Error<Ctx>> {
181192
let round_output = match self.apply(msg)? {

code/crates/driver/src/mux.rs

Lines changed: 10 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -119,11 +119,10 @@ where
119119

120120
// We have a valid proposal. Check if there is already a certificate for it.
121121
// L49
122-
if self
123-
.certificates
124-
.iter()
125-
.any(|c| c.value_id == proposal.value().id() && proposal.round() == c.round)
126-
&& self.round_state.decision.is_none()
122+
if self.round_state.decision.is_none()
123+
&& self
124+
.get_certificate(proposal.round(), proposal.value().id())
125+
.is_some()
127126
{
128127
return Some(RoundInput::ProposalAndPrecommitValue(proposal));
129128
}
@@ -189,15 +188,18 @@ where
189188
// Should only receive proposals for our height.
190189
assert_eq!(self.height(), certificate.height);
191190

191+
let certificate_round = certificate.round;
192+
let certificate_value_id = certificate.value_id.clone();
193+
192194
// Store the certificate
193-
self.certificates.push(certificate.clone());
195+
self.certificates.push(certificate);
194196

195197
if let Some((signed_proposal, validity)) = self
196198
.proposal_keeper
197-
.get_proposal_and_validity_for_round(certificate.round)
199+
.get_proposal_and_validity_for_round(certificate_round)
198200
{
199201
let proposal = &signed_proposal.message;
200-
if proposal.value().id() == certificate.value_id && validity.is_valid() {
202+
if proposal.value().id() == certificate_value_id && validity.is_valid() {
201203
return Some(RoundInput::ProposalAndPrecommitValue(proposal.clone()));
202204
}
203205
}

0 commit comments

Comments
 (0)