Skip to content

Commit

Permalink
Add Chain combinator
Browse files Browse the repository at this point in the history
  • Loading branch information
fjarri committed Nov 4, 2024
1 parent c835832 commit b9c3fcd
Show file tree
Hide file tree
Showing 10 changed files with 674 additions and 13 deletions.
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- An impl of `ProtocolError` for `()` for protocols that don't use errors. ([#60])
- A dummy `CorrectnessProof` trait. ([#60])
- A `misbehave` combinator, intended primarily for testing. ([#60])
- A `chain` combinator for chaining two protocols. ([#60])
- `EntryPoint::ENTRY_ROUND` constant. ([#60])


[#32]: https://github.com/entropyxyz/manul/pull/32
Expand Down
1 change: 1 addition & 0 deletions examples/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
extern crate alloc;

pub mod simple;
pub mod simple_chain;

#[cfg(test)]
mod simple_malicious;
85 changes: 85 additions & 0 deletions examples/src/simple_chain.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
use core::fmt::Debug;

use manul::{
combinators::{Chained, ChainedEntryPoint},
protocol::PartyId,
};

use super::simple::{Inputs, Round1};

pub struct ChainedSimple;

#[derive(Debug)]
pub struct NewInputs<Id>(Inputs<Id>);

impl<'a, Id: PartyId> From<&'a NewInputs<Id>> for Inputs<Id> {
fn from(source: &'a NewInputs<Id>) -> Self {
source.0.clone()
}
}

impl<Id: PartyId> From<(NewInputs<Id>, u8)> for Inputs<Id> {
fn from(source: (NewInputs<Id>, u8)) -> Self {
let (inputs, _result) = source;
inputs.0
}
}

impl<Id: PartyId> Chained<Id> for ChainedSimple {
type Inputs = NewInputs<Id>;
type EntryPoint1 = Round1<Id>;
type EntryPoint2 = Round1<Id>;
}

pub type DoubleSimpleEntryPoint<Id> = ChainedEntryPoint<Id, ChainedSimple>;

#[cfg(test)]
mod tests {
use alloc::collections::BTreeSet;

use manul::{
session::{signature::Keypair, SessionOutcome},
testing::{run_sync, BinaryFormat, TestSessionParams, TestSigner, TestVerifier},
};
use rand_core::OsRng;
use tracing_subscriber::EnvFilter;

use super::{DoubleSimpleEntryPoint, NewInputs};
use crate::simple::Inputs;

#[test]
fn round() {
let signers = (0..3).map(TestSigner::new).collect::<Vec<_>>();
let all_ids = signers
.iter()
.map(|signer| signer.verifying_key())
.collect::<BTreeSet<_>>();
let inputs = signers
.into_iter()
.map(|signer| {
(
signer,
NewInputs(Inputs {
all_ids: all_ids.clone(),
}),
)
})
.collect::<Vec<_>>();

let my_subscriber = tracing_subscriber::fmt()
.with_env_filter(EnvFilter::from_default_env())
.finish();
let reports = tracing::subscriber::with_default(my_subscriber, || {
run_sync::<DoubleSimpleEntryPoint<TestVerifier>, TestSessionParams<BinaryFormat>>(&mut OsRng, inputs)
.unwrap()
});

for (_id, report) in reports {
if let SessionOutcome::Result(result) = report.outcome {
assert_eq!(result, 3); // 0 + 1 + 2
} else {
panic!("Session did not finish successfully");
}
}
}
}
1 change: 1 addition & 0 deletions manul/benches/empty_rounds.rs
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@ struct Round1Artifact;
impl<Id: PartyId> EntryPoint<Id> for EmptyRound<Id> {
type Inputs = Inputs<Id>;
type Protocol = EmptyProtocol;

fn new(
_rng: &mut impl CryptoRngCore,
_shared_randomness: &[u8],
Expand Down
2 changes: 2 additions & 0 deletions manul/src/combinators.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
//! Combinators operating on protocols.

mod chain;
mod misbehave;

pub use chain::{Chained, ChainedEntryPoint, ChainedProtocol};
pub use misbehave::{Behavior, Misbehaving, MisbehavingEntryPoint, MisbehavingInputs};
Loading

0 comments on commit b9c3fcd

Please sign in to comment.