Skip to content

Commit

Permalink
Merge branch 'main' into anca/one_round_state
Browse files Browse the repository at this point in the history
  • Loading branch information
romac committed Nov 14, 2023
2 parents 6486834 + d39e933 commit 176eca9
Show file tree
Hide file tree
Showing 9 changed files with 62 additions and 58 deletions.
3 changes: 0 additions & 3 deletions Code/common/src/context.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,9 +18,6 @@ where
type Vote: Vote<Self>;
type SigningScheme: SigningScheme; // TODO: Do we need to support multiple signing schemes?

// FIXME: Remove altogether
const DUMMY_VALUE: Self::Value;

/// Sign the given vote our private key.
fn sign_vote(&self, vote: Self::Vote) -> SignedVote<Self>;

Expand Down
21 changes: 11 additions & 10 deletions Code/driver/src/driver.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ use crate::event::Event;
use crate::message::Message;
use crate::Error;
use crate::ProposerSelector;
use crate::Validity;

/// Driver for the state machine of the Malachite consensus engine at a given height.
#[derive(Clone, Debug)]
Expand Down Expand Up @@ -68,10 +69,6 @@ where
.await
}

async fn validate_proposal(&self, proposal: &Ctx::Proposal) -> bool {
self.env.validate_proposal(proposal).await
}

pub async fn execute(&mut self, msg: Event<Ctx>) -> Result<Option<Message<Ctx>>, Error<Ctx>> {
let round_msg = match self.apply(msg).await? {
Some(msg) => msg,
Expand Down Expand Up @@ -107,7 +104,9 @@ where
async fn apply(&mut self, event: Event<Ctx>) -> Result<Option<RoundMessage<Ctx>>, Error<Ctx>> {
match event {
Event::NewRound(height, round) => self.apply_new_round(height, round).await,
Event::Proposal(proposal) => Ok(self.apply_proposal(proposal).await),
Event::Proposal(proposal, validity) => {
Ok(self.apply_proposal(proposal, validity).await)
}
Event::Vote(signed_vote) => self.apply_vote(signed_vote),
Event::TimeoutElapsed(timeout) => Ok(self.apply_timeout(timeout)),
}
Expand Down Expand Up @@ -145,7 +144,11 @@ where
Ok(self.apply_event(round, event))
}

async fn apply_proposal(&mut self, proposal: Ctx::Proposal) -> Option<RoundMessage<Ctx>> {
async fn apply_proposal(
&mut self,
proposal: Ctx::Proposal,
validity: Validity,
) -> Option<RoundMessage<Ctx>> {
// Check that there is an ongoing round
if self.round_state.round == Round::NIL {
return None;
Expand All @@ -170,14 +173,12 @@ where

// TODO: Verify proposal signature (make some of these checks part of message validation)

let is_valid = self.validate_proposal(&proposal).await;

match proposal.pol_round() {
Round::Nil => {
// Is it possible to get +2/3 prevotes before the proposal?
// Do we wait for our own prevote to check the threshold?
let round = proposal.round();
let event = if is_valid {
let event = if validity.is_valid() {
RoundEvent::Proposal(proposal)
} else {
RoundEvent::ProposalInvalid
Expand All @@ -193,7 +194,7 @@ where
) =>
{
let round = proposal.round();
let event = if is_valid {
let event = if validity.is_valid() {
RoundEvent::Proposal(proposal)
} else {
RoundEvent::ProposalInvalid
Expand Down
3 changes: 0 additions & 3 deletions Code/driver/src/env.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,4 @@ where
/// If `None` is returned, the driver will understand this
/// as an error and will not propose a value.
async fn get_value(&self, height: Ctx::Height, round: Round) -> Option<Ctx::Value>;

/// Validate a proposal.
async fn validate_proposal(&self, proposal: &Ctx::Proposal) -> bool;
}
4 changes: 3 additions & 1 deletion Code/driver/src/event.rs
Original file line number Diff line number Diff line change
@@ -1,13 +1,15 @@
use malachite_common::{Context, Round, SignedVote, Timeout};

use crate::Validity;

/// Events that can be received by the [`Driver`](crate::Driver).
#[derive(Clone, Debug, PartialEq, Eq)]
pub enum Event<Ctx>
where
Ctx: Context,
{
NewRound(Ctx::Height, Round),
Proposal(Ctx::Proposal),
Proposal(Ctx::Proposal, Validity),
Vote(SignedVote<Ctx>),
TimeoutElapsed(Timeout),
}
2 changes: 2 additions & 0 deletions Code/driver/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,13 +20,15 @@ mod error;
mod event;
mod message;
mod proposer;
mod util;

pub use driver::Driver;
pub use env::Env;
pub use error::Error;
pub use event::Event;
pub use message::Message;
pub use proposer::ProposerSelector;
pub use util::Validity;

// Re-export `#[async_trait]` macro for convenience.
pub use async_trait::async_trait;
15 changes: 15 additions & 0 deletions Code/driver/src/util.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
/// Wether or not a proposal is valid.
#[derive(Copy, Clone, Debug, PartialEq, Eq)]
pub enum Validity {
/// The proposal is valid.
Valid,
/// The proposal is invalid.
Invalid,
}

impl Validity {
/// Returns `true` if the proposal is valid.
pub fn is_valid(self) -> bool {
self == Validity::Valid
}
}
2 changes: 0 additions & 2 deletions Code/test/src/context.rs
Original file line number Diff line number Diff line change
Expand Up @@ -30,8 +30,6 @@ impl Context for TestContext {
type Vote = Vote;
type SigningScheme = Ed25519;

const DUMMY_VALUE: Self::Value = Value::new(9999);

fn sign_vote(&self, vote: Self::Vote) -> SignedVote<Self> {
use signature::Signer;
let signature = self.private_key.sign(&vote.to_bytes());
Expand Down
13 changes: 2 additions & 11 deletions Code/test/src/env.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,21 +3,16 @@ use async_trait::async_trait;
use malachite_common::Round;
use malachite_driver::Env;

use crate::{Height, Proposal, TestContext, Value};
use crate::{Height, TestContext, Value};

pub struct TestEnv {
get_value: Box<dyn Fn(Height, Round) -> Option<Value> + Send + Sync>,
is_valid: Box<dyn Fn(&Proposal) -> bool + Send + Sync>,
}

impl TestEnv {
pub fn new(
get_value: impl Fn(Height, Round) -> Option<Value> + Send + Sync + 'static,
is_valid: impl Fn(&Proposal) -> bool + Send + Sync + 'static,
) -> Self {
pub fn new(get_value: impl Fn(Height, Round) -> Option<Value> + Send + Sync + 'static) -> Self {
Self {
get_value: Box::new(get_value),
is_valid: Box::new(is_valid),
}
}
}
Expand All @@ -27,8 +22,4 @@ impl Env<TestContext> for TestEnv {
async fn get_value(&self, height: Height, round: Round) -> Option<Value> {
(self.get_value)(height, round)
}

async fn validate_proposal(&self, proposal: &Proposal) -> bool {
(self.is_valid)(proposal)
}
}
57 changes: 29 additions & 28 deletions Code/test/tests/driver.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,12 @@ use futures::executor::block_on;
use rand::rngs::StdRng;
use rand::SeedableRng;

use malachite_common::{Context, Round, Timeout};
use malachite_driver::{Driver, Error, Event, Message, ProposerSelector};
use malachite_common::{Round, Timeout};
use malachite_driver::{Driver, Error, Event, Message, ProposerSelector, Validity};
use malachite_round::state::{RoundValue, State, Step};
use malachite_test::{
Address, Height, PrivateKey, Proposal, TestContext, TestEnv, Validator, ValidatorSet, Vote,
Address, Height, PrivateKey, Proposal, TestContext, TestEnv, Validator, ValidatorSet, Value,
Vote,
};

struct TestStep {
Expand All @@ -19,7 +20,8 @@ struct TestStep {

fn to_input_msg(output: Message<TestContext>) -> Option<Event<TestContext>> {
match output {
Message::Propose(p) => Some(Event::Proposal(p)),
// Let's consider our own proposal to always be valid
Message::Propose(p) => Some(Event::Proposal(p, Validity::Valid)),
Message::Vote(v) => Some(Event::Vote(v)),
Message::Decide(_, _) => None,
Message::ScheduleTimeout(_) => None,
Expand Down Expand Up @@ -59,11 +61,10 @@ impl ProposerSelector<TestContext> for FixedProposer {

#[test]
fn driver_steps_proposer() {
let value = TestContext::DUMMY_VALUE;
let value_id = value.id();
let value = Value::new(9999);

let sel = RotateProposer::default();
let env = TestEnv::new(move |_, _| Some(value), |_| true);
let env = TestEnv::new(move |_, _| Some(value));

let mut rng = StdRng::seed_from_u64(0x42);

Expand Down Expand Up @@ -107,7 +108,7 @@ fn driver_steps_proposer() {
desc: "Receive our own proposal, prevote for it (v1)",
input_event: None,
expected_output: Some(Message::Vote(
Vote::new_prevote(Height::new(1), Round::new(0), Some(value_id), my_addr)
Vote::new_prevote(Height::new(1), Round::new(0), Some(value.id()), my_addr)
.signed(&my_sk),
)),
expected_round: Round::new(0),
Expand Down Expand Up @@ -137,7 +138,7 @@ fn driver_steps_proposer() {
TestStep {
desc: "v2 prevotes for our proposal",
input_event: Some(Event::Vote(
Vote::new_prevote(Height::new(1), Round::new(0), Some(value_id), addr2)
Vote::new_prevote(Height::new(1), Round::new(0), Some(value.id()), addr2)
.signed(&sk2),
)),
expected_output: None,
Expand All @@ -154,11 +155,11 @@ fn driver_steps_proposer() {
TestStep {
desc: "v3 prevotes for our proposal, we get +2/3 prevotes, precommit for it (v1)",
input_event: Some(Event::Vote(
Vote::new_prevote(Height::new(1), Round::new(0), Some(value_id), addr3)
Vote::new_prevote(Height::new(1), Round::new(0), Some(value.id()), addr3)
.signed(&sk3),
)),
expected_output: Some(Message::Vote(
Vote::new_precommit(Height::new(1), Round::new(0), Some(value_id), my_addr)
Vote::new_precommit(Height::new(1), Round::new(0), Some(value.id()), my_addr)
.signed(&my_sk),
)),
expected_round: Round::new(0),
Expand Down Expand Up @@ -200,7 +201,7 @@ fn driver_steps_proposer() {
TestStep {
desc: "v2 precommits for our proposal",
input_event: Some(Event::Vote(
Vote::new_precommit(Height::new(1), Round::new(0), Some(value_id), addr2)
Vote::new_precommit(Height::new(1), Round::new(0), Some(value.id()), addr2)
.signed(&sk2),
)),
expected_output: None,
Expand All @@ -223,7 +224,7 @@ fn driver_steps_proposer() {
TestStep {
desc: "v3 precommits for our proposal, we get +2/3 precommits, decide it (v1)",
input_event: Some(Event::Vote(
Vote::new_precommit(Height::new(1), Round::new(0), Some(value_id), addr3)
Vote::new_precommit(Height::new(1), Round::new(0), Some(value.id()), addr3)
.signed(&sk3),
)),
expected_output: Some(Message::Decide(Round::new(0), value)),
Expand Down Expand Up @@ -270,11 +271,11 @@ fn driver_steps_proposer() {

#[test]
fn driver_steps_not_proposer_valid() {
let value = TestContext::DUMMY_VALUE;
let value = Value::new(9999);
let value_id = value.id();

let sel = RotateProposer::default();
let env = TestEnv::new(move |_, _| Some(value), |_| true);
let env = TestEnv::new(move |_, _| Some(value));

let mut rng = StdRng::seed_from_u64(0x42);

Expand Down Expand Up @@ -317,7 +318,7 @@ fn driver_steps_not_proposer_valid() {
},
TestStep {
desc: "Receive a proposal, prevote for it (v2)",
input_event: Some(Event::Proposal(proposal.clone())),
input_event: Some(Event::Proposal(proposal.clone(), Validity::Valid)),
expected_output: Some(Message::Vote(
Vote::new_prevote(Height::new(1), Round::new(0), Some(value_id), my_addr)
.signed(&my_sk),
Expand Down Expand Up @@ -482,11 +483,11 @@ fn driver_steps_not_proposer_valid() {

#[test]
fn driver_steps_not_proposer_invalid() {
let value = TestContext::DUMMY_VALUE;
let value = Value::new(9999);
let value_id = value.id();

let sel = RotateProposer::default();
let env = TestEnv::new(move |_, _| Some(value), |_| false);
let env = TestEnv::new(move |_, _| Some(value));

let mut rng = StdRng::seed_from_u64(0x42);

Expand Down Expand Up @@ -529,7 +530,7 @@ fn driver_steps_not_proposer_invalid() {
},
TestStep {
desc: "Receive an invalid proposal, prevote for nil (v2)",
input_event: Some(Event::Proposal(proposal.clone())),
input_event: Some(Event::Proposal(proposal.clone(), Validity::Invalid)),
expected_output: Some(Message::Vote(
Vote::new_prevote(Height::new(1),Round::new(0), None, my_addr).signed(&my_sk),
)),
Expand Down Expand Up @@ -632,11 +633,11 @@ fn driver_steps_not_proposer_invalid() {

#[test]
fn driver_steps_not_proposer_timeout_multiple_rounds() {
let value = TestContext::DUMMY_VALUE;
let value = Value::new(9999);
let value_id = value.id();

let sel = RotateProposer::default();
let env = TestEnv::new(move |_, _| Some(value), |_| true);
let env = TestEnv::new(move |_, _| Some(value));

let mut rng = StdRng::seed_from_u64(0x42);

Expand Down Expand Up @@ -847,7 +848,7 @@ fn driver_steps_not_proposer_timeout_multiple_rounds() {
#[test]
fn driver_steps_no_value_to_propose() {
// No value to propose
let env = TestEnv::new(|_, _| None, |_| true);
let env = TestEnv::new(|_, _| None);

let mut rng = StdRng::seed_from_u64(0x42);

Expand All @@ -874,9 +875,9 @@ fn driver_steps_no_value_to_propose() {

#[test]
fn driver_steps_proposer_not_found() {
let value = TestContext::DUMMY_VALUE;
let value = Value::new(9999);

let env = TestEnv::new(move |_, _| Some(value), |_| true);
let env = TestEnv::new(move |_, _| Some(value));

let mut rng = StdRng::seed_from_u64(0x42);

Expand Down Expand Up @@ -905,9 +906,9 @@ fn driver_steps_proposer_not_found() {

#[test]
fn driver_steps_validator_not_found() {
let value = TestContext::DUMMY_VALUE;
let value = Value::new(9999);

let env = TestEnv::new(move |_, _| Some(value), |_| true);
let env = TestEnv::new(move |_, _| Some(value));

let mut rng = StdRng::seed_from_u64(0x42);

Expand Down Expand Up @@ -943,9 +944,9 @@ fn driver_steps_validator_not_found() {

#[test]
fn driver_steps_invalid_signature() {
let value = TestContext::DUMMY_VALUE;
let value = Value::new(9999);

let env = TestEnv::new(move |_, _| Some(value), |_| true);
let env = TestEnv::new(move |_, _| Some(value));

let mut rng = StdRng::seed_from_u64(0x42);

Expand Down

0 comments on commit 176eca9

Please sign in to comment.