-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat: primary implementation of the protocol (#6)
* adding structure for ballot * adding ballot logic * adding stop method * fixed party new method * removing stop, removing separate channel for receiving value * fixed comments, fixed warnings, removing stop event * chore: added README.md * chore: cargo fmt * chore: add rust ci * fix: resolve linter problems * chore: add docs ci * feat: implement leader election and error handling * feat: added tests * chore: cargo fmt * fix: resolve leader election issues * feat: added full coverage on update state * feat: added more tests on party * feat: computing leader in a randomized manner deterministically using config-based seed * fix: encapsulate message round state for 2av, 2b and improve event emit error handling * feat: messages with rkyv, value with bincode * fix: rename MessageWire to MessagePacket --------- Co-authored-by: Nikita Masych <[email protected]>
- Loading branch information
1 parent
90d2238
commit 5acf84a
Showing
14 changed files
with
1,369 additions
and
254 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 |
---|---|---|
@@ -0,0 +1,52 @@ | ||
name: Deploy Rust Docs to GitHub Pages | ||
|
||
on: | ||
push: | ||
branches: | ||
- main | ||
|
||
concurrency: | ||
group: "pages" | ||
cancel-in-progress: false | ||
|
||
jobs: | ||
build: | ||
runs-on: ubuntu-latest | ||
|
||
steps: | ||
- name: Checkout sources | ||
uses: actions/checkout@v4 | ||
|
||
- name: Install stable toolchain | ||
uses: actions-rs/toolchain@v1 | ||
with: | ||
profile: minimal | ||
toolchain: stable | ||
override: true | ||
|
||
- name: Build Rust Documentation | ||
run: | | ||
cargo doc --no-deps --document-private-items | ||
echo "<meta http-equiv=\"refresh\" content=\"0; url=\">" > target/doc/index.html | ||
- name: Upload artifact | ||
uses: actions/upload-pages-artifact@v3 | ||
with: | ||
path: ./target/doc | ||
|
||
deploy: | ||
runs-on: ubuntu-latest | ||
needs: build | ||
|
||
permissions: | ||
pages: write | ||
id-token: write | ||
|
||
environment: | ||
name: docs | ||
url: ${{ steps.deployment.outputs.page_url }} | ||
|
||
steps: | ||
- name: Deploy to GitHub Pages | ||
id: deployment | ||
uses: actions/deploy-pages@v4 |
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,135 @@ | ||
name: Rust CI | ||
|
||
on: | ||
pull_request: | ||
branches: | ||
- main | ||
push: | ||
branches: | ||
- main | ||
workflow_dispatch: | ||
|
||
permissions: | ||
contents: read | ||
|
||
jobs: | ||
check: | ||
name: Check | ||
runs-on: ubuntu-latest | ||
steps: | ||
- name: Checkout sources | ||
uses: actions/checkout@v4 | ||
|
||
- name: Cache Cargo registry | ||
uses: actions/cache@v4 | ||
with: | ||
path: ~/.cargo/registry | ||
key: ${{ runner.os }}-cargo-registry-${{ hashFiles('**/Cargo.lock') }} | ||
restore-keys: | | ||
${{ runner.os }}-cargo-registry- | ||
- name: Cache Cargo build | ||
uses: actions/cache@v4 | ||
with: | ||
path: target | ||
key: ${{ runner.os }}-cargo-build-${{ hashFiles('**/Cargo.lock') }} | ||
restore-keys: | | ||
${{ runner.os }}-cargo-build- | ||
- name: Install stable toolchain | ||
uses: actions-rs/toolchain@v1 | ||
with: | ||
profile: minimal | ||
toolchain: stable | ||
override: true | ||
|
||
- name: Run cargo check | ||
uses: actions-rs/cargo@v1 | ||
continue-on-error: false | ||
with: | ||
command: check | ||
|
||
test: | ||
name: Test Suite | ||
strategy: | ||
matrix: | ||
os: [ubuntu-latest, macos-latest, windows-latest] | ||
rust: [stable, beta, nightly] | ||
runs-on: ${{ matrix.os }} | ||
steps: | ||
- name: Checkout sources | ||
uses: actions/checkout@v4 | ||
|
||
- name: Cache Cargo registry | ||
uses: actions/cache@v4 | ||
with: | ||
path: ~/.cargo/registry | ||
key: ${{ runner.os }}-cargo-registry-${{ hashFiles('**/Cargo.lock') }} | ||
restore-keys: | | ||
${{ runner.os }}-cargo-registry- | ||
- name: Cache Cargo build | ||
uses: actions/cache@v4 | ||
with: | ||
path: target | ||
key: ${{ runner.os }}-cargo-build-${{ hashFiles('**/Cargo.lock') }} | ||
restore-keys: | | ||
${{ runner.os }}-cargo-build- | ||
- name: Install ${{ matrix.rust }} toolchain | ||
uses: actions-rs/toolchain@v1 | ||
with: | ||
profile: minimal | ||
toolchain: ${{ matrix.rust }} | ||
|
||
- name: Run cargo test | ||
uses: actions-rs/cargo@v1 | ||
continue-on-error: false | ||
with: | ||
command: test | ||
args: --all-features --verbose | ||
|
||
lints: | ||
name: Lints | ||
runs-on: ubuntu-latest | ||
steps: | ||
- name: Checkout sources | ||
uses: actions/checkout@v4 | ||
|
||
- name: Cache Cargo registry | ||
uses: actions/cache@v4 | ||
with: | ||
path: ~/.cargo/registry | ||
key: ${{ runner.os }}-cargo-registry-${{ hashFiles('**/Cargo.lock') }} | ||
restore-keys: | | ||
${{ runner.os }}-cargo-registry- | ||
- name: Cache Cargo build | ||
uses: actions/cache@v4 | ||
with: | ||
path: target | ||
key: ${{ runner.os }}-cargo-build-${{ hashFiles('**/Cargo.lock') }} | ||
restore-keys: | | ||
${{ runner.os }}-cargo-build- | ||
- name: Install stable toolchain | ||
uses: actions-rs/toolchain@v1 | ||
with: | ||
profile: minimal | ||
toolchain: stable | ||
override: true | ||
components: rustfmt, clippy | ||
|
||
- name: Run cargo fmt | ||
uses: actions-rs/cargo@v1 | ||
continue-on-error: false | ||
with: | ||
command: fmt | ||
args: --all -- --check | ||
|
||
- name: Run cargo clippy | ||
uses: actions-rs/cargo@v1 | ||
continue-on-error: false | ||
with: | ||
command: clippy | ||
args: --all-targets -- -D warnings |
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
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,27 @@ | ||
# BPCon Rust Library | ||
|
||
[![License: GPL v3](https://img.shields.io/badge/License-GPLv3-blue.svg)](https://www.gnu.org/licenses/gpl-3.0) | ||
|
||
This is a generic rust implementation of the `BPCon` consensus mechanism. | ||
|
||
## Library Structure | ||
|
||
### src/party.rs | ||
|
||
Main entity in this implementation is `Party` - it represents member of the consensus. | ||
|
||
External system shall create desired amount of parties. | ||
|
||
We have 2 communication channels - one for sending `MessageWire` - encoded in bytes message and routing information, | ||
and the other for pitching consensus events - this allows for external system to impose custom limitations and rules | ||
regarding runway. | ||
|
||
### src/message.rs | ||
|
||
Definitions of the general message struct, routing information and type-specific contents. | ||
|
||
### src/lib.rs | ||
|
||
Here we present a trait for the value on which consensus is being conducted. Additionally, there is a trait for | ||
defining custom value selection rules, called `ValueSelector`. | ||
|
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,4 +1,56 @@ | ||
//! Definition of the BPCon errors. | ||
use std::fmt; | ||
|
||
#[derive(Debug)] | ||
pub enum BallotError { | ||
// TODO: define errors. | ||
} | ||
MessageParsing(String), | ||
ValueParsing(String), | ||
InvalidState(String), | ||
Communication(String), | ||
LeaderElection(String), | ||
} | ||
|
||
impl fmt::Display for BallotError { | ||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { | ||
match *self { | ||
BallotError::MessageParsing(ref err) => write!(f, "Message parsing error: {}", err), | ||
BallotError::ValueParsing(ref err) => write!(f, "Value parsing error: {}", err), | ||
BallotError::InvalidState(ref err) => write!(f, "Invalid state error: {}", err), | ||
BallotError::Communication(ref err) => write!(f, "Communication error: {}", err), | ||
BallotError::LeaderElection(ref err) => write!(f, "Leader election error: {}", err), | ||
} | ||
} | ||
} | ||
|
||
impl std::error::Error for BallotError { | ||
fn source(&self) -> Option<&(dyn std::error::Error + 'static)> { | ||
// Since these are all simple String errors, there is no underlying source error. | ||
None | ||
} | ||
} | ||
|
||
#[cfg(test)] | ||
mod tests { | ||
use super::*; | ||
|
||
#[test] | ||
fn test_ballot_error_message_parsing() { | ||
let error = BallotError::MessageParsing("Parsing failed".into()); | ||
if let BallotError::MessageParsing(msg) = error { | ||
assert_eq!(msg, "Parsing failed"); | ||
} else { | ||
panic!("Expected MessageParsing error"); | ||
} | ||
} | ||
|
||
#[test] | ||
fn test_ballot_error_invalid_state() { | ||
let error = BallotError::InvalidState("Invalid state transition".into()); | ||
if let BallotError::InvalidState(msg) = error { | ||
assert_eq!(msg, "Invalid state transition"); | ||
} else { | ||
panic!("Expected InvalidState error"); | ||
} | ||
} | ||
} |
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,18 +1,23 @@ | ||
use serde::{Deserialize, Serialize}; | ||
use std::collections::HashMap; | ||
|
||
mod error; | ||
pub mod message; | ||
pub mod party; | ||
mod error; | ||
|
||
/// General trait for value itself. | ||
pub trait Value: Eq {} | ||
pub trait Value: Eq + Serialize + for<'a> Deserialize<'a> + Clone {} | ||
|
||
/// Trait for value selector and verificator. | ||
/// Value selection and verification may depend on different conditions for different values. | ||
/// Note that value selection should follow the rules of BPCon: only safe values can be selected. | ||
/// Party can not vote for different values, even in different ballots. | ||
pub trait ValueSelector<V: Value> { | ||
/// Verifies if a value is selected correctly. | ||
fn verify(v: V) -> bool; | ||
/// Verifies if a value is selected correctly. Accepts 2b messages from parties. | ||
fn verify(&self, v: &V, m: &HashMap<u64, Option<V>>) -> bool; | ||
|
||
/// Select value depending on inner conditions. | ||
fn select() -> V; | ||
/// Select value depending on inner conditions. Accepts 2b messages from parties. | ||
fn select(&self, m: &HashMap<u64, Option<V>>) -> V; | ||
|
||
// TODO: add other fields to update selector state. | ||
} |
Oops, something went wrong.