-
Notifications
You must be signed in to change notification settings - Fork 12
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
* Add skeleton of consensus executor * Cleanup * Weight vote by its validators voting power * Add unit test for `ValidatorSet` * Split common lib into modules * WIP: Unit tests for state machine * Cleanup * Create new round state machine on NewRound * Propose checks, id in prevote and precommit (#7) * Propose checks, id in prevote and precommit * Disallow `unwrap` and `panic` * Add proper checks without unwraps * Add executor test with steps up to precommit * Formatting and clippy * Enable more lints * Finish the happy path test --------- Co-authored-by: Anca Zamfir <zamfiranca@gmail.com> --------- Co-authored-by: Anca Zamfir <zamfiranca@gmail.com>
- Loading branch information
1 parent
e4059de
commit ccc12e6
Showing
24 changed files
with
1,087 additions
and
267 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -2,5 +2,6 @@ | |
name = "malachite-common" | ||
version = "0.1.0" | ||
edition = "2021" | ||
publish = false | ||
|
||
[dependencies] |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
// TODO: Abstract over Height | ||
|
||
/// A blockchain height | ||
#[derive(Copy, Clone, Debug, Default, PartialEq, Eq, PartialOrd, Ord)] | ||
pub struct Height(u64); | ||
|
||
impl Height { | ||
pub fn new(height: u64) -> Self { | ||
Self(height) | ||
} | ||
|
||
pub fn as_u64(&self) -> u64 { | ||
self.0 | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,159 +1,27 @@ | ||
/// A blockchain height | ||
#[derive(Copy, Clone, Debug, Default, PartialEq, Eq, PartialOrd, Ord)] | ||
pub struct Height(u64); | ||
|
||
impl Height { | ||
pub fn new(height: u64) -> Self { | ||
Self(height) | ||
} | ||
|
||
pub fn as_u64(&self) -> u64 { | ||
self.0 | ||
} | ||
} | ||
|
||
/// A round number, ie. a natural number | ||
#[derive(Copy, Clone, Debug, PartialEq, Eq)] | ||
pub enum Round { | ||
/// No round | ||
None, | ||
|
||
/// Some round | ||
Some(i64), | ||
} | ||
|
||
impl Round { | ||
pub const INITIAL: Round = Round::new(0); | ||
|
||
pub const fn new(round: i64) -> Self { | ||
if round < 0 { | ||
Self::None | ||
} else { | ||
Self::Some(round) | ||
} | ||
} | ||
|
||
pub fn as_i64(&self) -> i64 { | ||
match self { | ||
Round::None => -1, | ||
Round::Some(r) => *r, | ||
} | ||
} | ||
|
||
pub fn is_defined(&self) -> bool { | ||
matches!(self, Round::Some(_)) | ||
} | ||
|
||
pub fn increment(&self) -> Round { | ||
match self { | ||
Round::None => Round::new(0), | ||
Round::Some(r) => Round::new(r + 1), | ||
} | ||
} | ||
} | ||
|
||
impl PartialOrd for Round { | ||
fn partial_cmp(&self, other: &Self) -> Option<std::cmp::Ordering> { | ||
Some(self.cmp(other)) | ||
} | ||
} | ||
|
||
impl Ord for Round { | ||
fn cmp(&self, other: &Self) -> std::cmp::Ordering { | ||
self.as_i64().cmp(&other.as_i64()) | ||
} | ||
} | ||
|
||
/// The value to decide on | ||
#[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord)] | ||
pub struct Value(u64); | ||
|
||
impl Value { | ||
pub fn new(value: u64) -> Self { | ||
Self(value) | ||
} | ||
|
||
pub fn as_u64(&self) -> u64 { | ||
self.0 | ||
} | ||
} | ||
|
||
/// A proposal for a value in a round | ||
#[derive(Clone, Debug, PartialEq, Eq)] | ||
pub struct Proposal { | ||
pub round: Round, | ||
pub value: Value, | ||
pub pol_round: Round, | ||
} | ||
|
||
#[derive(Copy, Clone, Debug, PartialEq, Eq)] | ||
pub enum VoteType { | ||
Prevote, | ||
Precommit, | ||
} | ||
|
||
/// A vote for a value in a round | ||
#[derive(Clone, Debug, PartialEq, Eq)] | ||
pub struct Vote { | ||
pub typ: VoteType, | ||
pub round: Round, | ||
pub value: Option<Value>, | ||
} | ||
|
||
impl Vote { | ||
pub fn new_prevote(round: Round, value: Option<Value>) -> Self { | ||
Self { | ||
typ: VoteType::Prevote, | ||
round, | ||
value, | ||
} | ||
} | ||
|
||
pub fn new_precommit(round: Round, value: Option<Value>) -> Self { | ||
Self { | ||
typ: VoteType::Precommit, | ||
round, | ||
value, | ||
} | ||
} | ||
} | ||
|
||
#[derive(Copy, Clone, Debug, PartialEq, Eq)] | ||
pub enum TimeoutStep { | ||
Propose, | ||
Prevote, | ||
Precommit, | ||
} | ||
|
||
#[derive(Clone, Debug, PartialEq, Eq)] | ||
pub struct Timeout { | ||
pub round: Round, | ||
pub step: TimeoutStep, | ||
} | ||
|
||
#[cfg(test)] | ||
mod tests { | ||
use super::*; | ||
|
||
#[test] | ||
fn test_round() { | ||
// Test Round::new() | ||
assert_eq!(Round::new(-42), Round::None); | ||
assert_eq!(Round::new(-1), Round::None); | ||
assert_eq!(Round::new(0), Round::Some(0)); | ||
assert_eq!(Round::new(1), Round::Some(1)); | ||
assert_eq!(Round::new(2), Round::Some(2)); | ||
|
||
// Test Round::as_i64() | ||
assert_eq!(Round::None.as_i64(), -1); | ||
assert_eq!(Round::Some(0).as_i64(), 0); | ||
assert_eq!(Round::Some(1).as_i64(), 1); | ||
assert_eq!(Round::Some(2).as_i64(), 2); | ||
|
||
// Test Round::is_defined() | ||
assert!(!Round::None.is_defined()); | ||
assert!(Round::Some(0).is_defined()); | ||
assert!(Round::Some(1).is_defined()); | ||
assert!(Round::Some(2).is_defined()); | ||
} | ||
} | ||
//! Common data types and abstractions | ||
#![forbid(unsafe_code)] | ||
#![deny(unused_crate_dependencies, trivial_casts, trivial_numeric_casts)] | ||
#![warn( | ||
// missing_docs, | ||
broken_intra_doc_links, | ||
private_intra_doc_links, | ||
variant_size_differences | ||
)] | ||
#![cfg_attr(not(test), deny(clippy::unwrap_used, clippy::panic))] | ||
|
||
mod height; | ||
mod proposal; | ||
mod round; | ||
mod timeout; | ||
mod validator_set; | ||
mod value; | ||
mod vote; | ||
|
||
pub use height::*; | ||
pub use proposal::*; | ||
pub use round::*; | ||
pub use timeout::*; | ||
pub use validator_set::*; | ||
pub use value::*; | ||
pub use vote::*; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
use crate::{Height, Round, Value}; | ||
|
||
/// A proposal for a value in a round | ||
#[derive(Clone, Debug, PartialEq, Eq)] | ||
pub struct Proposal { | ||
pub height: Height, | ||
pub round: Round, | ||
pub value: Value, | ||
pub pol_round: Round, | ||
} | ||
|
||
impl Proposal { | ||
pub fn new(height: Height, round: Round, value: Value, pol_round: Round) -> Self { | ||
Self { | ||
height, | ||
round, | ||
value, | ||
pol_round, | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,89 @@ | ||
/// A round number, ie. a natural number | ||
#[derive(Copy, Clone, Debug, PartialEq, Eq)] | ||
pub enum Round { | ||
/// No round | ||
None, | ||
|
||
/// Some round | ||
Some(i64), | ||
} | ||
|
||
impl Round { | ||
pub const INITIAL: Round = Round::new(0); | ||
|
||
pub const fn new(round: i64) -> Self { | ||
if round < 0 { | ||
Self::None | ||
} else { | ||
Self::Some(round) | ||
} | ||
} | ||
|
||
pub fn as_i64(&self) -> i64 { | ||
match self { | ||
Round::None => -1, | ||
Round::Some(r) => *r, | ||
} | ||
} | ||
|
||
pub fn is_defined(&self) -> bool { | ||
matches!(self, Round::Some(r) if *r >= 0) | ||
} | ||
|
||
pub fn is_nil(&self) -> bool { | ||
matches!(self, Round::None) | ||
} | ||
|
||
pub fn is_valid(&self) -> bool { | ||
match self { | ||
Round::None => true, | ||
Round::Some(r) => *r >= 0, | ||
} | ||
} | ||
|
||
pub fn increment(&self) -> Round { | ||
match self { | ||
Round::None => Round::new(0), | ||
Round::Some(r) => Round::new(r + 1), | ||
} | ||
} | ||
} | ||
|
||
impl PartialOrd for Round { | ||
fn partial_cmp(&self, other: &Self) -> Option<std::cmp::Ordering> { | ||
Some(self.cmp(other)) | ||
} | ||
} | ||
|
||
impl Ord for Round { | ||
fn cmp(&self, other: &Self) -> std::cmp::Ordering { | ||
self.as_i64().cmp(&other.as_i64()) | ||
} | ||
} | ||
|
||
#[cfg(test)] | ||
mod tests { | ||
use super::*; | ||
|
||
#[test] | ||
fn test_round() { | ||
// Test Round::new() | ||
assert_eq!(Round::new(-42), Round::None); | ||
assert_eq!(Round::new(-1), Round::None); | ||
assert_eq!(Round::new(0), Round::Some(0)); | ||
assert_eq!(Round::new(1), Round::Some(1)); | ||
assert_eq!(Round::new(2), Round::Some(2)); | ||
|
||
// Test Round::as_i64() | ||
assert_eq!(Round::None.as_i64(), -1); | ||
assert_eq!(Round::Some(0).as_i64(), 0); | ||
assert_eq!(Round::Some(1).as_i64(), 1); | ||
assert_eq!(Round::Some(2).as_i64(), 2); | ||
|
||
// Test Round::is_defined() | ||
assert!(!Round::None.is_defined()); | ||
assert!(Round::Some(0).is_defined()); | ||
assert!(Round::Some(1).is_defined()); | ||
assert!(Round::Some(2).is_defined()); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,14 @@ | ||
use crate::Round; | ||
|
||
#[derive(Copy, Clone, Debug, PartialEq, Eq)] | ||
pub enum TimeoutStep { | ||
Propose, | ||
Prevote, | ||
Precommit, | ||
} | ||
|
||
#[derive(Clone, Debug, PartialEq, Eq)] | ||
pub struct Timeout { | ||
pub round: Round, | ||
pub step: TimeoutStep, | ||
} |
Oops, something went wrong.