Skip to content

Commit

Permalink
Add propose+precommit timeout test
Browse files Browse the repository at this point in the history
  • Loading branch information
romac committed Oct 24, 2023
1 parent e28625f commit 5909cf1
Show file tree
Hide file tree
Showing 3 changed files with 437 additions and 10 deletions.
18 changes: 18 additions & 0 deletions Code/common/src/timeout.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,3 +14,21 @@ pub struct Timeout {
pub round: Round,
pub step: TimeoutStep,
}

impl Timeout {
pub fn new(round: Round, step: TimeoutStep) -> Self {
Self { round, step }
}

pub fn propose(round: Round) -> Self {
Self::new(round, TimeoutStep::Propose)
}

pub fn prevote(round: Round) -> Self {
Self::new(round, TimeoutStep::Prevote)
}

pub fn precommit(round: Round) -> Self {
Self::new(round, TimeoutStep::Precommit)
}
}
13 changes: 12 additions & 1 deletion Code/consensus/src/executor.rs
Original file line number Diff line number Diff line change
Expand Up @@ -72,12 +72,15 @@ where

self.round_states
.insert(round, RoundState::new(self.height.clone()).new_round(round));

None
}

RoundMessage::Proposal(p) => {
// sign the proposal
Some(Message::Proposal(p))
}

RoundMessage::Vote(mut v) => {
// sign the vote

Expand All @@ -92,10 +95,12 @@ where

Some(Message::Vote(v))
}

RoundMessage::Timeout(_) => {
// schedule the timeout
None
}

RoundMessage::Decision(_) => {
// update the state
None
Expand All @@ -114,39 +119,45 @@ where

fn apply_new_round(&mut self, round: Round) -> Option<RoundMessage<C>> {
let proposer = self.validator_set.get_proposer();

let event = if proposer.public_key() == &self.key {
let value = self.get_value();
RoundEvent::NewRoundProposer(value)
} else {
RoundEvent::NewRound
};

self.apply_event(round, event)
}

fn apply_proposal(&mut self, proposal: C::Proposal) -> Option<RoundMessage<C>> {
// TODO: Check for invalid proposal
let event = RoundEvent::Proposal(proposal.clone());

// Check that there is an ongoing round
let Some(round_state) = self.round_states.get(&self.round) else {
// TODO: Add logging
return None;
};

// Only process the proposal if there is no other proposal
if round_state.proposal.is_some() {
return None;
}

// Check that the proposal is for the current height and round
if round_state.height != proposal.height() || proposal.round() != self.round {
return None;
}

// TODO: Document
if !proposal.pol_round().is_valid()
|| proposal.pol_round().is_defined() && proposal.pol_round() >= round_state.round
{
return None;
}

// TODO verify proposal signature (make some of these checks part of message validation)
// TODO: Verify proposal signature (make some of these checks part of message validation)
match proposal.pol_round() {
Round::Nil => {
// Is it possible to get +2/3 prevotes before the proposal?
Expand Down
Loading

0 comments on commit 5909cf1

Please sign in to comment.