Skip to content

Commit

Permalink
Merge branch 'main' into josef/addStepInput
Browse files Browse the repository at this point in the history
  • Loading branch information
josef-widder authored Dec 12, 2023
2 parents d16f046 + 265d3fe commit f95304f
Show file tree
Hide file tree
Showing 53 changed files with 2,232 additions and 1,269 deletions.
6 changes: 3 additions & 3 deletions .github/workflows/coverage.yml
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ jobs:
- name: Install cargo-llvm-cov
uses: taiki-e/install-action@cargo-llvm-cov
- name: Generate code coverage
run: cargo llvm-cov nextest --workspace --exclude malachite-itf --all-features --lcov --output-path lcov.info
run: cargo llvm-cov nextest --workspace --exclude malachite-itf --all-features --ignore-run-fail --lcov --output-path lcov.info
- name: Generate text report
run: cargo llvm-cov report
- name: Upload coverage to Codecov
Expand All @@ -48,7 +48,7 @@ jobs:
token: ${{ secrets.CODECOV_TOKEN }}
files: Code/lcov.info
flags: integration
fail_ci_if_error: true
fail_ci_if_error: false

mbt-coverage:
name: MBT
Expand Down Expand Up @@ -84,4 +84,4 @@ jobs:
token: ${{ secrets.CODECOV_TOKEN }}
files: Code/lcov.info
flags: mbt
fail_ci_if_error: true
fail_ci_if_error: false
4 changes: 2 additions & 2 deletions Code/.cargo/config.toml
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
[alias]
mbt = "nextest run -p malachite-itf --all-features"
integration = "nextest run --workspace --exclude malachite-itf"
mbt = "nextest run -p malachite-itf --all-features --no-fail-fast"
integration = "nextest run --workspace --exclude malachite-itf --no-fail-fast"
3 changes: 2 additions & 1 deletion Code/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -22,10 +22,11 @@ async-trait = "0.1"
ed25519-consensus = "2.1.0"
futures = "0.3"
glob = "0.3.0"
itf = "0.2.1"
itf = "0.2.2"
num-bigint = "0.4.4"
rand = { version = "0.8.5", features = ["std_rng"] }
serde = "1.0"
serde_json = "1.0"
serde_with = "3.4"
sha2 = "0.10.8"
signature = "2.1.0"
25 changes: 20 additions & 5 deletions Code/common/src/context.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
use crate::{
Address, Height, Proposal, PublicKey, Round, SignedVote, SigningScheme, Validator,
Address, Height, NilOrVal, Proposal, PublicKey, Round, SignedVote, SigningScheme, Validator,
ValidatorSet, Value, ValueId, Vote,
};

Expand All @@ -9,20 +9,35 @@ pub trait Context
where
Self: Sized,
{
/// The type of address of a validator.
type Address: Address;

/// The type of the height of a block.
type Height: Height;

/// The interface provided by the proposal type.
type Proposal: Proposal<Self>;

/// The interface provided by the validator type.
type Validator: Validator<Self>;

/// The interface provided by the validator set type.
type ValidatorSet: ValidatorSet<Self>;

/// The type of values that can be proposed.
type Value: Value;

/// The type of votes that can be cast.
type Vote: Vote<Self>;
type SigningScheme: SigningScheme; // TODO: Do we need to support multiple signing schemes?

// TODO: Do we need to support multiple signing schemes?
/// The signing scheme used to sign votes.
type SigningScheme: SigningScheme;

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

/// Verify the given vote's signature using the given public key.
/// TODO: Maybe move this as concrete methods in `SignedVote`?
fn verify_signed_vote(
&self,
signed_vote: &SignedVote<Self>,
Expand All @@ -42,7 +57,7 @@ where
fn new_prevote(
height: Self::Height,
round: Round,
value_id: Option<ValueId<Self>>,
value_id: NilOrVal<ValueId<Self>>,
address: Self::Address,
) -> Self::Vote;

Expand All @@ -51,7 +66,7 @@ where
fn new_precommit(
height: Self::Height,
round: Round,
value_id: Option<ValueId<Self>>,
value_id: NilOrVal<ValueId<Self>>,
address: Self::Address,
) -> Self::Vote;
}
10 changes: 8 additions & 2 deletions Code/common/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
#![forbid(unsafe_code)]
#![deny(unused_crate_dependencies, trivial_casts, trivial_numeric_casts)]
#![warn(
// missing_docs,
missing_docs,
rustdoc::broken_intra_doc_links,
rustdoc::private_intra_doc_links,
variant_size_differences
Expand All @@ -28,8 +28,14 @@ pub use ::signature;

/// Type alias to make it easier to refer the `ValueId` type of a given `Consensus` engine.
pub type ValueId<Ctx> = <<Ctx as Context>::Value as Value>::Id;

/// Type alias to make it easier to refer the `PublicKey` type of a given `Consensus` engine.
pub type PublicKey<Ctx> = <<Ctx as Context>::SigningScheme as SigningScheme>::PublicKey;

/// Type alias to make it easier to refer the `PrivateKey` type of a given `Consensus` engine.
pub type PrivateKey<Ctx> = <<Ctx as Context>::SigningScheme as SigningScheme>::PrivateKey;

/// Type alias to make it easier to refer the `Signature` type of a given `Consensus` engine.
pub type Signature<Ctx> = <<Ctx as Context>::SigningScheme as SigningScheme>::Signature;

pub use context::Context;
Expand All @@ -40,5 +46,5 @@ pub use signed_vote::SignedVote;
pub use signing::SigningScheme;
pub use timeout::{Timeout, TimeoutStep};
pub use validator_set::{Address, Validator, ValidatorSet, VotingPower};
pub use value::Value;
pub use value::{NilOrVal, Value};
pub use vote::{Vote, VoteType};
6 changes: 6 additions & 0 deletions Code/common/src/signed_vote.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,22 +4,28 @@ use crate::{Context, Signature, Vote};

// TODO: Do we need to abstract over `SignedVote` as well?

/// A signed vote, ie. a vote emitted by a validator and signed by its private key.
pub struct SignedVote<Ctx>
where
Ctx: Context,
{
/// The vote.
pub vote: Ctx::Vote,

/// The signature of the vote.
pub signature: Signature<Ctx>,
}

impl<Ctx> SignedVote<Ctx>
where
Ctx: Context,
{
/// Create a new signed vote from the given vote and signature.
pub fn new(vote: Ctx::Vote, signature: Signature<Ctx>) -> Self {
Self { vote, signature }
}

/// Return the address of the validator that emitted this vote.
pub fn validator_address(&self) -> &Ctx::Address {
self.vote.validator_address()
}
Expand Down
11 changes: 11 additions & 0 deletions Code/common/src/signing.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,24 @@ use core::fmt::Debug;

use signature::{Keypair, Signer, Verifier};

/// A signing scheme that can be used to sign votes and verify such signatures.
///
/// This trait is used to abstract over the signature scheme used by the consensus engine.
///
/// An example of a signing scheme is the Ed25519 signature scheme,
/// eg. as implemented in the [`ed25519-consensus`][ed25519-consensus] crate.
///
/// [ed25519-consensus]: https://crates.io/crates/ed25519-consensus
pub trait SigningScheme
where
Self: Clone + Debug + Eq,
{
/// The type of signatures produced by this signing scheme.
type Signature: Clone + Debug + Eq;

/// The type of public keys produced by this signing scheme.
type PublicKey: Clone + Debug + Eq + Verifier<Self::Signature>;

/// The type of private keys produced by this signing scheme.
type PrivateKey: Clone + Signer<Self::Signature> + Keypair<VerifyingKey = Self::PublicKey>;
}
12 changes: 12 additions & 0 deletions Code/common/src/timeout.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,31 +3,43 @@ use crate::Round;
/// The round step for which the timeout is for.
#[derive(Copy, Clone, Debug, PartialEq, Eq)]
pub enum TimeoutStep {
/// The timeout is for the propose step.
Propose,

/// The timeout is for the prevote step.
Prevote,

/// The timeout is for the precommit step.
Precommit,
}

/// A timeout for a round step.
#[derive(Copy, Clone, Debug, PartialEq, Eq)]
pub struct Timeout {
/// The round for which the timeout is for.
pub round: Round,

/// The round step for which the timeout is for.
pub step: TimeoutStep,
}

impl Timeout {
/// Create a new timeout for the given round and step.
pub fn new(round: Round, step: TimeoutStep) -> Self {
Self { round, step }
}

/// Create a new timeout for the propose step of the given round.
pub fn propose(round: Round) -> Self {
Self::new(round, TimeoutStep::Propose)
}

/// Create a new timeout for the prevote step of the given round.
pub fn prevote(round: Round) -> Self {
Self::new(round, TimeoutStep::Prevote)
}

/// Create a new timeout for the precommit step of the given round.
pub fn precommit(round: Round) -> Self {
Self::new(round, TimeoutStep::Precommit)
}
Expand Down
2 changes: 0 additions & 2 deletions Code/common/src/validator_set.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,6 @@ use core::fmt::{Debug, Display};
use crate::{Context, PublicKey};

/// Voting power held by a validator.
///
/// TODO: Do we need to abstract over this as well?
pub type VotingPower = u64;

/// Defines the requirements for an address.
Expand Down
53 changes: 53 additions & 0 deletions Code/common/src/value.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,58 @@
use core::fmt::Debug;

/// Represents either `Nil` or a value of type `Value`.
///
/// This type is isomorphic to `Option<Value>` but is more explicit about its intent.
#[derive(Copy, Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash, Default)]
pub enum NilOrVal<Value> {
/// The value is `nil`.
#[default]
Nil,

/// The value is a value of type `Value`.
Val(Value),
}

impl<Value> NilOrVal<Value> {
/// Whether this is `nil`.
pub fn is_nil(&self) -> bool {
matches!(self, Self::Nil)
}

/// Whether this is an actual value.
pub fn is_val(&self) -> bool {
matches!(self, Self::Val(_))
}

/// Apply the given function to the value if it is not `nil`.
pub fn map<NewValue, F: FnOnce(Value) -> NewValue>(self, f: F) -> NilOrVal<NewValue> {
match self {
NilOrVal::Nil => NilOrVal::Nil,
NilOrVal::Val(value) => NilOrVal::Val(f(value)),
}
}

/// Convert this into an `NilOrVal<&Value>`, allowing to borrow the value.
pub fn as_ref(&self) -> NilOrVal<&Value> {
match self {
NilOrVal::Nil => NilOrVal::Nil,
NilOrVal::Val(value) => NilOrVal::Val(value),
}
}

/// Consumes this and returns the value if it is not `nil`,
/// otherwise returns the default `Value`.
pub fn value_or_default(self) -> Value
where
Value: Default,
{
match self {
NilOrVal::Nil => Value::default(),
NilOrVal::Val(value) => value,
}
}
}

/// Defines the requirements for the type of value to decide on.
pub trait Value
where
Expand Down
6 changes: 3 additions & 3 deletions Code/common/src/vote.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
use core::fmt::Debug;

use crate::{Context, Round, Value};
use crate::{Context, NilOrVal, Round, Value};

/// A type of vote.
#[derive(Copy, Clone, Debug, PartialEq, Eq)]
Expand Down Expand Up @@ -28,10 +28,10 @@ where
fn round(&self) -> Round;

/// Get a reference to the value being voted for.
fn value(&self) -> &Option<<Ctx::Value as Value>::Id>;
fn value(&self) -> &NilOrVal<<Ctx::Value as Value>::Id>;

/// Take ownership of the value being voted for.
fn take_value(self) -> Option<<Ctx::Value as Value>::Id>;
fn take_value(self) -> NilOrVal<<Ctx::Value as Value>::Id>;

/// The type of vote.
fn vote_type(&self) -> VoteType;
Expand Down
Loading

0 comments on commit f95304f

Please sign in to comment.