Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

code: Initial implementation of the state machine, vote keeper and driver #1

Merged
merged 35 commits into from
Nov 8, 2023

Conversation

romac
Copy link
Member

@romac romac commented Oct 19, 2023

Closes: #49

@romac romac marked this pull request as ready for review October 19, 2023 08:55
@romac romac force-pushed the romac/rust-state-machine branch 7 times, most recently from a394f81 to 176217e Compare October 19, 2023 09:49
@romac romac force-pushed the romac/rust-state-machine branch from c5c2977 to 98b1203 Compare October 19, 2023 15:22
* Add vote counting facility, with multi-value support

* Show coverage summary in job output

* Formatting

* Comment out unused code

* Fix code coverage workflow
@codecov
Copy link

codecov bot commented Oct 19, 2023

Codecov Report

❗ No coverage uploaded for pull request base (main@b91ade7). Click here to learn what that means.
The diff coverage is n/a.

@@           Coverage Diff           @@
##             main       #1   +/-   ##
=======================================
  Coverage        ?   85.28%           
=======================================
  Files           ?       26           
  Lines           ?     1230           
  Branches        ?        0           
=======================================
  Hits            ?     1049           
  Misses          ?      181           
  Partials        ?        0           

📣 Codecov offers a browser extension for seamless coverage viewing on GitHub. Try it in Chrome or Firefox today!

romac and others added 10 commits October 21, 2023 11:40
* Add a vote keeper

* Rename `polka_round` to `pol_round` (Proof-Of-Lock)

* Add unit tests to VoteKeeper

* Add codecov settings

* Add tests for precommit
* 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>
Closes: #11

This gist of this PR is that it adds a `Consensus` trait which defines the various datatypes that the consensus engine operates over, as well as a trait per such datatype that defines the requirement for said datatype.

```rust
pub trait Consensus
where
    Self: Sized,
{
    type Address: Address;
    type Height: Height;
    type Proposal: Proposal<Self>;
    type PublicKey: PublicKey;
    type Validator: Validator<Self>;
    type ValidatorSet: ValidatorSet<Self>;
    type Value: Value;
    type Vote: Vote<Self>;
```

```rust
pub trait Height
where
    Self: Clone + Debug + PartialEq + Eq + PartialOrd + Ord,
{
}
```

etc.

In test code, we define our own simple versions of these datatypes as well as a `TestConsensus` struct, for which we implement the `Consensus` trait.


```rust
#[derive(Copy, Clone, Debug, PartialEq, Eq, PartialOrd, Ord)]
pub struct Address(u64);

impl Address {
    pub const fn new(value: u64) -> Self {
        Self(value)
    }
}

impl malachite_common::Address for Address {}
```

```rust
pub struct TestConsensus;

impl Consensus for TestConsensus {
    type Address = Address;
    type Height = Height;
    type Proposal = Proposal;
    type PublicKey = PublicKey;
    type ValidatorSet = ValidatorSet;
    type Validator = Validator;
    type Value = Value;
    type Vote = Vote;
}
```

---

* Attempt to abstract over the various data types needed by the consensus engine

* Fix tests

* Fix lints names

* Move tests and associated data types into their own crate (#10)

* Move tests and associated data types into their own crate

* Add small threshold to codecov

* Small cleanup

* Move tests into `tests` folder

* Adjust base when computing coverage in the presence of removed code

See: https://docs.codecov.com/docs/commit-status#removed_code_behavior

* Document the `Round` type and rename `Round::None` to `Round::Nil`

* More doc comments

* Remove `PublicKey::hash` requirement

* Few more comments

* Add propose+precommit timeout test
* Rename `check_threshold` to `is_threshold_met`

* Track nil as a regular value in the vote count

* Add unit test for `ValuesWeights`

* Remove dependency on `Consensus` trait in `VoteCount`

* Do not fail PRs on unexpected coverage changes not visible in diff
* Introduce `SignedVote` type and remove address from round `Vote`

* Add facility for signing votes

* Verify votes signatures

* Better name for the module

* Doc comments

* Refactor signing facility into a `SigningScheme`
@adizere adizere changed the title Rust state machine code: State machine implementation Oct 28, 2023
romac and others added 11 commits October 30, 2023 13:20
* executor: Rename input and outputs to `Event` and `Message`

* votekeeper: Rename outputs to `Message`
* Move address from SignedVote into Vote

* Rename a few fields for better clarity

* Supply validator address to the state machine

* Move `Transition` struct into its own module

* Extract immutable data required to run the round state machine into a `RoundData` struct (#37)
* Event name changes and other small fixes

* Add event multiplexing in executor and fix tests

* Fix formatting

* Fix executor handling of new round

* Fix executor initialization

* Add test step for NewRound, fix precommit for nil quorum to emit PrecommitAny

* Review comments

* Remove dead code

---------

Co-authored-by: Anca Zamfir <zamfiranca@gmail.com>
* Rename `Threshold::Init` to `Unreached`

* WIP: Pass votes directly to `VoteCount`

* Cleanup

* Split `compute_threshold` out of `add_vote`

* Only count a single vote per validator address

* Emit `PrecommitAny` message when we reach `Nil` threshold for precommits

* Doc comment

* Refactor `VoteCount` implementation

* Fix tests

* Split `vote` crate into more modules

* Add Skip threshold

* Refactor data kept by the `VoteKeeper` per-round

* Move dealing with skip threshold into `VoteKeeper`

* Rename `Event::RoundSkip` to `Event::SkipRound`

* Cleanup

* Include number of round to skip to in `SkipRound` message

* Parametrize over thresholds
@romac romac changed the title code: State machine implementation code: Initial implementation of the state machine, vote keeper and driver Nov 7, 2023
@romac romac merged commit c236fad into main Nov 8, 2023
7 checks passed
@romac romac deleted the romac/rust-state-machine branch November 8, 2023 07:36
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

code: Initial implementation of the state machine, vote keeper, and driver
2 participants