Skip to content

Commit

Permalink
chore(code/blocksync): Include synced certificate in decision if one …
Browse files Browse the repository at this point in the history
…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]>
  • Loading branch information
ancazamfir and romac authored Nov 22, 2024
1 parent 6c16dd1 commit 28a0c3a
Show file tree
Hide file tree
Showing 3 changed files with 38 additions and 15 deletions.
16 changes: 13 additions & 3 deletions code/crates/consensus/src/handle/decide.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,8 @@ where
let proposal_round = proposal.round();
let value = proposal.value();

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

// Clean proposals and values
state.remove_full_proposals(height);
Expand Down Expand Up @@ -46,7 +46,17 @@ where
}
}

let certificate = CommitCertificate::new(height, proposal_round, value.id(), commits);
// Look for an existing certificate
let certificate = state
.driver
.get_certificate(proposal_round, value.id())
.cloned()
.unwrap_or_else(|| {
// Restore the commits. Note that they will be removed from `state`
let commits = state.restore_precommits(height, proposal_round, value);
// TODO: should we verify we have 2/3rd commits?
CommitCertificate::new(height, proposal_round, value.id(), commits)
});

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

Expand Down
19 changes: 15 additions & 4 deletions code/crates/driver/src/driver.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ use core::fmt;

use malachite_common::{
CommitCertificate, Context, Proposal, Round, SignedProposal, SignedVote, Timeout, TimeoutStep,
Validator, ValidatorSet, Validity, Vote,
Validator, ValidatorSet, Validity, ValueId, Vote,
};
use malachite_round::input::Input as RoundInput;
use malachite_round::output::Output as RoundOutput;
Expand Down Expand Up @@ -38,6 +38,9 @@ where
/// The validator set at the current height
validator_set: Ctx::ValidatorSet,

/// The proposer for the current round, None for round nil.
proposer: Option<Ctx::Address>,

/// The proposals to decide on.
pub(crate) proposal_keeper: ProposalKeeper<Ctx>,

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

/// The proposer for the current round, None for round nil.
proposer: Option<Ctx::Address>,

/// The pending inputs to be processed next, if any.
/// The first element of the tuple is the round at which that input has been emitted.
pending_inputs: Vec<(Round, RoundInput<Ctx>)>,
Expand Down Expand Up @@ -176,6 +176,17 @@ where
}
}

/// Get a commit certificate for the given round and value id.
pub fn get_certificate(
&self,
round: Round,
value_id: ValueId<Ctx>,
) -> Option<&CommitCertificate<Ctx>> {
self.certificates
.iter()
.find(|c| c.round == round && c.value_id == value_id)
}

/// Process the given input, returning the outputs to be broadcast to the network.
pub fn process(&mut self, msg: Input<Ctx>) -> Result<Vec<Output<Ctx>>, Error<Ctx>> {
let round_output = match self.apply(msg)? {
Expand Down
18 changes: 10 additions & 8 deletions code/crates/driver/src/mux.rs
Original file line number Diff line number Diff line change
Expand Up @@ -119,11 +119,10 @@ where

// We have a valid proposal. Check if there is already a certificate for it.
// L49
if self
.certificates
.iter()
.any(|c| c.value_id == proposal.value().id() && proposal.round() == c.round)
&& self.round_state.decision.is_none()
if self.round_state.decision.is_none()
&& self
.get_certificate(proposal.round(), proposal.value().id())
.is_some()
{
return Some(RoundInput::ProposalAndPrecommitValue(proposal));
}
Expand Down Expand Up @@ -189,15 +188,18 @@ where
// Should only receive proposals for our height.
assert_eq!(self.height(), certificate.height);

let certificate_round = certificate.round;
let certificate_value_id = certificate.value_id.clone();

// Store the certificate
self.certificates.push(certificate.clone());
self.certificates.push(certificate);

if let Some((signed_proposal, validity)) = self
.proposal_keeper
.get_proposal_and_validity_for_round(certificate.round)
.get_proposal_and_validity_for_round(certificate_round)
{
let proposal = &signed_proposal.message;
if proposal.value().id() == certificate.value_id && validity.is_valid() {
if proposal.value().id() == certificate_value_id && validity.is_valid() {
return Some(RoundInput::ProposalAndPrecommitValue(proposal.clone()));
}
}
Expand Down

0 comments on commit 28a0c3a

Please sign in to comment.