From 14b4988fd35e3f4f1d1d945ca32d93d51391c99b Mon Sep 17 00:00:00 2001 From: Bogdan Opanchuk Date: Tue, 24 Sep 2024 00:08:51 -0700 Subject: [PATCH 1/7] Initial commit --- .gitignore | 1 + Cargo.toml | 6 +++ README.md | 23 +++++++++++ src/error.rs | 32 +++++++++++++++ src/lib.rs | 13 +++++++ src/message.rs | 40 +++++++++++++++++++ src/round.rs | 70 +++++++++++++++++++++++++++++++++ src/session.rs | 103 +++++++++++++++++++++++++++++++++++++++++++++++++ 8 files changed, 288 insertions(+) create mode 100644 .gitignore create mode 100644 Cargo.toml create mode 100644 README.md create mode 100644 src/error.rs create mode 100644 src/lib.rs create mode 100644 src/message.rs create mode 100644 src/round.rs create mode 100644 src/session.rs diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..ea8c4bf --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +/target diff --git a/Cargo.toml b/Cargo.toml new file mode 100644 index 0000000..cf3dd90 --- /dev/null +++ b/Cargo.toml @@ -0,0 +1,6 @@ +[package] +name = "manul" +version = "0.1.0" +edition = "2021" + +[dependencies] diff --git a/README.md b/README.md new file mode 100644 index 0000000..ebd15c3 --- /dev/null +++ b/README.md @@ -0,0 +1,23 @@ +# Round-based distributed protocols + +*The body is round* + +## Goals + +- Sans-I/O API. That is, bring your own async libraries, or don't. +- Generic over signer/verifier/signature types, so you can use whatever your blockchain uses. +- Support parallelization where possible, to offload expensive cryptographic operations into spawned tasks (but since it's Sans-I/O, it's up to you to make use of that functionality). +- Provide tools for unit and integration testing of the protocols. +- Support generating malicious behavior proofs and correctness proofs with bundled signed messages. +- Support caching messages intended for the next round and then applying them when it starts (since some nodes can finalize a round before others and send out a new batch of messages). + + +## Assumptions + +We try to find the balance between supporting the majority of protocols and keeping the API simple. Currently we operate under the following assumptions: + +- A protocol consists of several rounds. +- A round generates messages to send out without any additional external input, then waits for messages from other parties. When it receives enough messages, it can be finalized. +- On finalization, a round can return the result, halt with an error, or continue to another round. +- A round can generate several direct messages (each going to a specific party). +- Additionally, a round can generate one echo-broadcasted message, for which it will be ensured that each party received the same message. diff --git a/src/error.rs b/src/error.rs new file mode 100644 index 0000000..86fbe7b --- /dev/null +++ b/src/error.rs @@ -0,0 +1,32 @@ +use alloc::collections::BTreeMap; + +use crate::message::SignedDirectMessage; +use crate::round::{Protocol, ProtocolError, RoundId}; + +pub struct LocalError; + +pub enum Error { + Local, + Remote, + Protocol(Evidence), +} + +pub struct Evidence { + pub party: I, + pub error: P::ProtocolError, + pub message: SignedDirectMessage, + pub previous_messages: BTreeMap>, +} + +impl Evidence { + pub fn verify(&self) -> bool { + let verified_messages = self + .previous_messages + .iter() + .map(|(round, message)| (*round, message.clone().verify(&self.party).unwrap())) + .collect::>(); + let message = self.message.clone().verify(&self.party).unwrap(); + + self.error.verify(&message, &verified_messages) + } +} diff --git a/src/lib.rs b/src/lib.rs new file mode 100644 index 0000000..d5f1588 --- /dev/null +++ b/src/lib.rs @@ -0,0 +1,13 @@ +#![allow(dead_code)] +#![allow(unused_variables)] + +extern crate alloc; + +mod error; +mod message; +mod round; +mod session; + +pub use error::Error; +pub use round::{DirectMessage, Protocol, ProtocolError, Round, RoundId}; +pub use session::Session; diff --git a/src/message.rs b/src/message.rs new file mode 100644 index 0000000..9622696 --- /dev/null +++ b/src/message.rs @@ -0,0 +1,40 @@ +use crate::round::{DirectMessage, EchoBroadcast, RoundId}; + +#[derive(Debug, Clone)] +pub struct SignedDirectMessage { + pub signature: I, + pub message: DirectMessage, +} + +impl SignedDirectMessage { + pub fn verify(self, id: &I) -> Option { + if &self.signature == id { + Some(self.message) + } else { + None + } + } +} + +#[derive(Debug, Clone)] +pub struct SignedEchoBroadcast { + pub signature: I, + pub message: EchoBroadcast, +} + +impl SignedEchoBroadcast { + pub fn verify(self, id: &I) -> Option { + if &self.signature == id { + Some(self.message) + } else { + None + } + } +} + +#[derive(Clone, Debug)] +pub struct MessageBundle { + pub round_id: RoundId, + pub direct_message: SignedDirectMessage, + pub echo_broadcast: Option>, +} diff --git a/src/round.rs b/src/round.rs new file mode 100644 index 0000000..c53bf6d --- /dev/null +++ b/src/round.rs @@ -0,0 +1,70 @@ +use alloc::collections::{BTreeMap, BTreeSet}; +use core::any::Any; + +use crate::error::LocalError; + +pub enum VerificationError { + InvalidMessage, + Protocol(P::ProtocolError), +} + +pub enum FinalizeOutcome { + Round(Box>), + Result(P::Success), +} + +pub enum FinalizeError {} + +pub type RoundId = u8; + +pub trait Protocol { + type Success; + type ProtocolError: ProtocolError; + type CorrectnessProof; +} + +pub trait ProtocolError { + fn required_rounds(&self) -> BTreeSet { + BTreeSet::new() + } + fn verify(&self, message: &DirectMessage, messages: &BTreeMap) -> bool; +} + +#[derive(Debug, Clone)] +pub struct DirectMessage(pub Box<[u8]>); + +#[derive(Debug, Clone)] +pub struct EchoBroadcast(pub Box<[u8]>); + +pub struct Payload(pub Box); + +pub struct Artifact(pub Box); + +pub trait Round { + type Protocol: Protocol; + + fn id(&self) -> RoundId; + fn possible_next_rounds(&self) -> BTreeSet { + BTreeSet::new() + } + + fn message_destinations(&self) -> BTreeSet; + fn make_direct_message(&self, destination: &I) + -> Result<(DirectMessage, Artifact), LocalError>; + fn make_echo_broadcast(&self) -> Result, LocalError> { + Ok(None) + } + + fn verify_message( + &self, + from: &I, + echo_broadcast: &Option, + direct_message: &DirectMessage, + ) -> Result>; + + fn finalize( + self: Box, + payloads: BTreeMap, + artifacts: BTreeMap, + ) -> Result, FinalizeError>; +} diff --git a/src/session.rs b/src/session.rs new file mode 100644 index 0000000..af87abe --- /dev/null +++ b/src/session.rs @@ -0,0 +1,103 @@ +use alloc::collections::{BTreeMap, BTreeSet}; + +use crate::error::{Evidence, LocalError}; +use crate::message::{MessageBundle, SignedDirectMessage, SignedEchoBroadcast}; +use crate::round::{Artifact, Payload, ProtocolError, RoundId, VerificationError}; +use crate::{Error, Protocol, Round}; + +pub struct Session { + my_id: I, + round: Box>, + messages: BTreeMap>>, +} + +impl Session { + pub fn new(my_id: I, round: R) -> Self + where + R: Round + 'static, + { + Self { + my_id, + round: Box::new(round), + messages: BTreeMap::new(), + } + } + + pub fn message_destinations(&self) -> BTreeSet { + self.round.message_destinations() + } + + pub fn make_message( + &self, + destination: &I, + ) -> Result<(MessageBundle, Artifact), LocalError> { + let (message, artifact) = self.round.make_direct_message(destination)?; + let signed_direct_message = SignedDirectMessage { + signature: self.my_id.clone(), + message, + }; + + let signed_echo_broadcast = + self.round + .make_echo_broadcast()? + .map(|echo| SignedEchoBroadcast { + signature: self.my_id.clone(), + message: echo, + }); + + let bundle = MessageBundle { + round_id: self.round.id(), + direct_message: signed_direct_message, + echo_broadcast: signed_echo_broadcast, + }; + + Ok((bundle, artifact)) + } + + pub fn verify_message( + &self, + from: &I, + message: &MessageBundle, + ) -> Result> { + let verified_direct_message = message.direct_message.clone().verify(from).unwrap(); + let verified_echo_broadcast = message + .echo_broadcast + .as_ref() + .map(|echo| echo.clone().verify(from).unwrap()); + match self + .round + .verify_message(from, &verified_echo_broadcast, &verified_direct_message) + { + Ok(payload) => Ok(payload), + Err(error) => { + match error { + VerificationError::InvalidMessage => unimplemented!(), + VerificationError::Protocol(error) => Err(Error::Protocol( + self.prepare_evidence(from, &message.direct_message, error), + )), + } + } + } + } + + fn prepare_evidence( + &self, + from: &I, + message: &SignedDirectMessage, + error: P::ProtocolError, + ) -> Evidence { + let rounds = error.required_rounds(); + + let messages = rounds + .iter() + .map(|round| (*round, self.messages[round][from].clone())) + .collect(); + + Evidence { + party: from.clone(), + error, + message: message.clone(), + previous_messages: messages, + } + } +} From 394e4375046bf3e363e7604b2dc620a5e0e20c3e Mon Sep 17 00:00:00 2001 From: Bogdan Opanchuk Date: Wed, 25 Sep 2024 12:02:16 -0700 Subject: [PATCH 2/7] In progress --- src/error.rs | 6 +++ src/lib.rs | 5 +- src/message.rs | 135 +++++++++++++++++++++++++++++++++++++++------- src/round.rs | 18 ++++--- src/session.rs | 124 ++++++++++++++++++++++++++---------------- src/test_utils.rs | 79 +++++++++++++++++++++++++++ tests/example.rs | 69 ++++++++++++++++++++++++ 7 files changed, 363 insertions(+), 73 deletions(-) create mode 100644 src/test_utils.rs create mode 100644 tests/example.rs diff --git a/src/error.rs b/src/error.rs index 86fbe7b..22e76c6 100644 --- a/src/error.rs +++ b/src/error.rs @@ -3,14 +3,20 @@ use alloc::collections::BTreeMap; use crate::message::SignedDirectMessage; use crate::round::{Protocol, ProtocolError, RoundId}; +#[derive(Debug, Clone)] pub struct LocalError; +#[derive(Debug, Clone)] +pub struct RemoteError; + +#[derive(Debug, Clone)] pub enum Error { Local, Remote, Protocol(Evidence), } +#[derive(Debug, Clone)] pub struct Evidence { pub party: I, pub error: P::ProtocolError, diff --git a/src/lib.rs b/src/lib.rs index d5f1588..ab784dc 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -7,7 +7,8 @@ mod error; mod message; mod round; mod session; +mod test_utils; pub use error::Error; -pub use round::{DirectMessage, Protocol, ProtocolError, Round, RoundId}; -pub use session::Session; +pub use round::{DirectMessage, FirstRound, Protocol, ProtocolError, Round, RoundId}; +pub use session::{FinalizeOutcome, Session}; diff --git a/src/message.rs b/src/message.rs index 9622696..dd2e959 100644 --- a/src/message.rs +++ b/src/message.rs @@ -1,40 +1,137 @@ +use crate::error::RemoteError; use crate::round::{DirectMessage, EchoBroadcast, RoundId}; #[derive(Debug, Clone)] -pub struct SignedDirectMessage { - pub signature: I, - pub message: DirectMessage, +pub struct SignedMessage { + signature: I, + message: MessageWithMetadata, } -impl SignedDirectMessage { - pub fn verify(self, id: &I) -> Option { - if &self.signature == id { - Some(self.message) - } else { - None +impl SignedMessage { + pub fn new(signer: &I, round_id: RoundId, message: M) -> Self { + Self { + signature: signer.clone(), + message: MessageWithMetadata { round_id, message }, } } } #[derive(Debug, Clone)] -pub struct SignedEchoBroadcast { - pub signature: I, - pub message: EchoBroadcast, +pub struct MessageWithMetadata { + round_id: RoundId, + message: M, } -impl SignedEchoBroadcast { - pub fn verify(self, id: &I) -> Option { +impl SignedMessage { + pub fn verify(self, id: &I) -> Result, RemoteError> { if &self.signature == id { - Some(self.message) + Ok(VerifiedMessage { + signature: self.signature, + message: self.message, + }) } else { - None + Err(RemoteError) + } + } +} + +#[derive(Debug, Clone)] +pub struct VerifiedMessage { + signature: I, + message: MessageWithMetadata, +} + +impl VerifiedMessage { + pub fn round_id(&self) -> RoundId { + self.message.round_id + } + + pub fn payload(&self) -> &M { + &self.message.message + } + + pub fn into_unverified(self) -> SignedMessage { + SignedMessage { + signature: self.signature, + message: self.message, } } } #[derive(Clone, Debug)] pub struct MessageBundle { - pub round_id: RoundId, - pub direct_message: SignedDirectMessage, - pub echo_broadcast: Option>, + direct_message: SignedMessage, + echo_broadcast: Option>, +} + +impl MessageBundle { + pub fn new( + signer: &I, + round_id: RoundId, + direct_message: DirectMessage, + echo_broadcast: Option, + ) -> Self { + let direct_message = SignedMessage::new(signer, round_id, direct_message); + let echo_broadcast = echo_broadcast.map(|echo| SignedMessage::new(signer, round_id, echo)); + Self { + direct_message, + echo_broadcast, + } + } + + pub fn verify(self, id: &I) -> Result, RemoteError> { + let direct_message = self.direct_message.verify(id)?; + let echo_broadcast = self + .echo_broadcast + .map(|echo| echo.verify(id)) + .transpose()?; + if !echo_broadcast + .as_ref() + .map(|echo| echo.round_id() == direct_message.round_id()) + .unwrap_or(true) + { + return Err(RemoteError); + } + Ok(VerifiedMessageBundle { + from: id.clone(), + direct_message, + echo_broadcast, + }) + } +} + +#[derive(Clone, Debug)] +pub struct VerifiedMessageBundle { + from: I, + direct_message: VerifiedMessage, + echo_broadcast: Option>, +} + +impl VerifiedMessageBundle { + pub fn round_id(&self) -> RoundId { + self.direct_message.round_id() + } + + pub fn from(&self) -> &I { + &self.from + } + + pub fn direct_message(&self) -> &DirectMessage { + &self.direct_message.payload() + } + + pub fn into_unverified( + self, + ) -> ( + Option>, + SignedMessage, + ) { + let direct_message = self.direct_message.into_unverified(); + let echo_broadcast = self.echo_broadcast.map(|echo| echo.into_unverified()); + (echo_broadcast, direct_message) + } + + pub fn echo_broadcast(&self) -> Option<&EchoBroadcast> { + self.echo_broadcast.as_ref().map(|echo| echo.payload()) + } } diff --git a/src/round.rs b/src/round.rs index c53bf6d..aa253a2 100644 --- a/src/round.rs +++ b/src/round.rs @@ -1,5 +1,6 @@ use alloc::collections::{BTreeMap, BTreeSet}; use core::any::Any; +use core::fmt::Debug; use crate::error::LocalError; @@ -10,20 +11,20 @@ pub enum VerificationError { pub enum FinalizeOutcome { Round(Box>), - Result(P::Success), + Result(P::Result), } pub enum FinalizeError {} pub type RoundId = u8; -pub trait Protocol { - type Success; +pub trait Protocol: Debug { + type Result; type ProtocolError: ProtocolError; type CorrectnessProof; } -pub trait ProtocolError { +pub trait ProtocolError: Debug + Clone { fn required_rounds(&self) -> BTreeSet { BTreeSet::new() } @@ -40,6 +41,11 @@ pub struct Payload(pub Box); pub struct Artifact(pub Box); +pub trait FirstRound: Round + Sized { + type Inputs; + fn new(inputs: Self::Inputs) -> Result; +} + pub trait Round { type Protocol: Protocol; @@ -55,10 +61,10 @@ pub trait Round { Ok(None) } - fn verify_message( + fn receive_message( &self, from: &I, - echo_broadcast: &Option, + echo_broadcast: Option<&EchoBroadcast>, direct_message: &DirectMessage, ) -> Result>; diff --git a/src/session.rs b/src/session.rs index af87abe..f8b64ec 100644 --- a/src/session.rs +++ b/src/session.rs @@ -1,21 +1,29 @@ use alloc::collections::{BTreeMap, BTreeSet}; -use crate::error::{Evidence, LocalError}; -use crate::message::{MessageBundle, SignedDirectMessage, SignedEchoBroadcast}; -use crate::round::{Artifact, Payload, ProtocolError, RoundId, VerificationError}; +use crate::error::{Evidence, LocalError, RemoteError}; +use crate::message::{MessageBundle, SignedMessage, VerifiedMessageBundle}; +use crate::round::{ + Artifact, DirectMessage, FirstRound, Payload, ProtocolError, RoundId, VerificationError, +}; use crate::{Error, Protocol, Round}; pub struct Session { my_id: I, round: Box>, - messages: BTreeMap>>, + messages: BTreeMap>>, } -impl Session { - pub fn new(my_id: I, round: R) -> Self +pub enum FinalizeOutcome { + Result(P::Result), + AnotherRound { session: Session }, +} + +impl Session { + pub fn new(my_id: I, inputs: R::Inputs) -> Self where - R: Round + 'static, + R: FirstRound + Round + 'static, { + let round = R::new(inputs).unwrap(); Self { my_id, round: Box::new(round), @@ -23,6 +31,10 @@ impl Session { } } + pub fn party_id(&self) -> I { + unimplemented!() + } + pub fn message_destinations(&self) -> BTreeSet { self.round.message_destinations() } @@ -31,25 +43,11 @@ impl Session { &self, destination: &I, ) -> Result<(MessageBundle, Artifact), LocalError> { - let (message, artifact) = self.round.make_direct_message(destination)?; - let signed_direct_message = SignedDirectMessage { - signature: self.my_id.clone(), - message, - }; - - let signed_echo_broadcast = - self.round - .make_echo_broadcast()? - .map(|echo| SignedEchoBroadcast { - signature: self.my_id.clone(), - message: echo, - }); - - let bundle = MessageBundle { - round_id: self.round.id(), - direct_message: signed_direct_message, - echo_broadcast: signed_echo_broadcast, - }; + let (direct_message, artifact) = self.round.make_direct_message(destination)?; + let echo_broadcast = self.round.make_echo_broadcast()?; + + let bundle = + MessageBundle::new(&self.my_id, self.round.id(), direct_message, echo_broadcast); Ok((bundle, artifact)) } @@ -57,33 +55,47 @@ impl Session { pub fn verify_message( &self, from: &I, - message: &MessageBundle, - ) -> Result> { - let verified_direct_message = message.direct_message.clone().verify(from).unwrap(); - let verified_echo_broadcast = message - .echo_broadcast - .as_ref() - .map(|echo| echo.clone().verify(from).unwrap()); - match self - .round - .verify_message(from, &verified_echo_broadcast, &verified_direct_message) - { - Ok(payload) => Ok(payload), - Err(error) => { - match error { - VerificationError::InvalidMessage => unimplemented!(), - VerificationError::Protocol(error) => Err(Error::Protocol( - self.prepare_evidence(from, &message.direct_message, error), - )), + message: MessageBundle, + ) -> Result, RemoteError> { + message.verify(from) + } + + pub fn process_message( + &self, + message: VerifiedMessageBundle, + ) -> Result> { + match self.round.receive_message( + message.from(), + message.echo_broadcast(), + message.direct_message(), + ) { + Ok(payload) => Ok(ProcessedMessage { payload }), + Err(error) => match error { + VerificationError::InvalidMessage => unimplemented!(), + VerificationError::Protocol(error) => { + let from = message.from().clone(); + let (echo, dm) = message.into_unverified(); + Err(Error::Protocol(self.prepare_evidence(&from, &dm, error))) } - } + }, } } + pub fn make_accumulator(&self) -> RoundAccumulator { + unimplemented!() + } + + pub fn finalize_round( + self, + accum: RoundAccumulator, + ) -> Result, Error> { + unimplemented!() + } + fn prepare_evidence( &self, from: &I, - message: &SignedDirectMessage, + message: &SignedMessage, error: P::ProtocolError, ) -> Evidence { let rounds = error.required_rounds(); @@ -101,3 +113,23 @@ impl Session { } } } + +pub struct RoundAccumulator; + +impl RoundAccumulator { + pub fn add_artifact(&mut self, artifact: Artifact) { + unimplemented!() + } + + pub fn add_processed_message(&mut self, processed: ProcessedMessage) { + unimplemented!() + } +} + +pub struct VerifiedMessage { + from: I, +} + +pub struct ProcessedMessage { + payload: Payload, +} diff --git a/src/test_utils.rs b/src/test_utils.rs new file mode 100644 index 0000000..68ff4ed --- /dev/null +++ b/src/test_utils.rs @@ -0,0 +1,79 @@ +use alloc::collections::BTreeMap; +use core::fmt::Debug; + +use crate::{Error, FinalizeOutcome, FirstRound, Protocol, Round, Session}; + +pub fn run_sync( + inputs: BTreeMap, +) -> BTreeMap>> +where + I: Debug + Clone + Eq + Ord, + R: FirstRound + Round + 'static, + P: Protocol, +{ + let mut sessions = inputs + .into_iter() + .map(|(id, inputs)| (id.clone(), Session::::new::(id, inputs))) + .collect::>(); + + let mut results = BTreeMap::new(); + + loop { + let mut accums = sessions + .iter() + .map(|(id, session)| (id.clone(), session.make_accumulator())) + .collect::>(); + + // Generate messages + let mut messages = sessions + .keys() + .map(|id| (id.clone(), BTreeMap::new())) + .collect::>(); + for (id, session) in sessions.iter() { + let destinations = session.message_destinations(); + for destination in destinations.iter() { + let (message, artifact) = session.make_message(destination).unwrap(); + messages + .get_mut(&destination) + .unwrap() + .insert(id.clone(), message); + accums.get_mut(id).unwrap().add_artifact(artifact); + } + } + + // Send out messages + for (id, session) in sessions.iter() { + for (from, message) in messages[id].iter() { + let verified = session.verify_message(from, message.clone()).unwrap(); + let processed = session.process_message(verified).unwrap(); + accums.get_mut(id).unwrap().add_processed_message(processed); + } + } + + // Finalize + let ids = sessions.keys().cloned().collect::>(); + for id in ids { + let accum = accums.remove(&id).unwrap(); + let session = sessions.remove(&id).unwrap(); + let result = session.finalize_round(accum); + + match result { + Ok(result) => match result { + FinalizeOutcome::Result(result) => { + results.insert(id.clone(), Ok(result)); + } + FinalizeOutcome::AnotherRound { session } => { + sessions.insert(id.clone(), session); + } + }, + Err(result) => { + results.insert(id.clone(), Err(result)); + } + } + } + + if sessions.is_empty() { + return results; + } + } +} diff --git a/tests/example.rs b/tests/example.rs new file mode 100644 index 0000000..40cc8e7 --- /dev/null +++ b/tests/example.rs @@ -0,0 +1,69 @@ +extern crate alloc; + +use alloc::collections::BTreeMap; + +use manul::*; + +struct Id(u8); + +struct Round1; + +struct MyProto; + +struct MyProtoError; + +impl ProtocolError for MyProtoError { + fn verify( + &self, + _message: &DirectMessage, + _messages: &BTreeMap, + ) -> bool { + true + } +} + +impl Protocol for MyProto { + type Success = u8; + type ProtocolError = MyProtoError; + type CorrectnessProof = (); +} + +impl Round for Round1 { + type Protocol = MyProto; + + fn id(&self) -> RoundId { + 1 + } + + fn message_destinations(&self) -> Vec { + vec![Id(2)] + } + + fn make_direct_message(&self, destination: &Id) -> DirectMessage { + DirectMessage(vec![1, 2, 3].into()) + } + + fn verify_message( + &self, + from: &Id, + message: &DirectMessage, + ) -> Result> { + Ok(Payload(Box::new(1))) + } + + fn round_num(&self) -> u8 { + 1 + } + + fn finalize(self: Box) -> Result, FinalizeError> { + Ok(FinalizeOutcome::Result(1)) + } +} + +#[test] +fn round() { + let r1 = Round1; + + let boxed_r1: Box> = Box::new(r1); + let _result = boxed_r1.finalize(); +} From 10d6be5b708b9dcc15ffc37bebfd7def47d7841d Mon Sep 17 00:00:00 2001 From: Bogdan Opanchuk Date: Wed, 25 Sep 2024 14:17:06 -0700 Subject: [PATCH 3/7] Create a separate example crate --- Cargo.toml | 12 ++--- example/Cargo.toml | 7 +++ example/src/lib.rs | 3 ++ example/src/rounds.rs | 76 ++++++++++++++++++++++++++++++++ manul/Cargo.toml | 6 +++ manul/src/error.rs | 54 +++++++++++++++++++++++ manul/src/lib.rs | 17 +++++++ {src => manul/src}/message.rs | 0 {src => manul/src}/round.rs | 20 ++++++--- {src => manul/src}/session.rs | 14 +++--- {src => manul/src}/test_utils.rs | 6 +-- src/error.rs | 38 ---------------- src/lib.rs | 14 ------ tests/example.rs | 69 ----------------------------- 14 files changed, 194 insertions(+), 142 deletions(-) create mode 100644 example/Cargo.toml create mode 100644 example/src/lib.rs create mode 100644 example/src/rounds.rs create mode 100644 manul/Cargo.toml create mode 100644 manul/src/error.rs create mode 100644 manul/src/lib.rs rename {src => manul/src}/message.rs (100%) rename {src => manul/src}/round.rs (80%) rename {src => manul/src}/session.rs (91%) rename {src => manul/src}/test_utils.rs (92%) delete mode 100644 src/error.rs delete mode 100644 src/lib.rs delete mode 100644 tests/example.rs diff --git a/Cargo.toml b/Cargo.toml index cf3dd90..1a43d60 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ -[package] -name = "manul" -version = "0.1.0" -edition = "2021" - -[dependencies] +[workspace] +members = [ + "example", + "manul", +] +resolver = "2" diff --git a/example/Cargo.toml b/example/Cargo.toml new file mode 100644 index 0000000..eeb8969 --- /dev/null +++ b/example/Cargo.toml @@ -0,0 +1,7 @@ +[package] +name = "manul-example" +version = "0.1.0" +edition = "2021" + +[dependencies] +manul = { path = "../manul" } diff --git a/example/src/lib.rs b/example/src/lib.rs new file mode 100644 index 0000000..8e2a071 --- /dev/null +++ b/example/src/lib.rs @@ -0,0 +1,3 @@ +extern crate alloc; + +mod rounds; diff --git a/example/src/rounds.rs b/example/src/rounds.rs new file mode 100644 index 0000000..e08b5ce --- /dev/null +++ b/example/src/rounds.rs @@ -0,0 +1,76 @@ +use alloc::collections::{BTreeMap, BTreeSet}; + +use manul::*; + +#[derive(Debug, Clone, PartialOrd, Ord, PartialEq, Eq)] +struct Id(u8); + +struct Round1; + +#[derive(Debug)] +struct MyProto; + +#[derive(Debug, Clone)] +struct MyProtoError; + +impl ProtocolError for MyProtoError { + fn verify( + &self, + _message: &DirectMessage, + _messages: &BTreeMap, + ) -> bool { + true + } +} + +impl Protocol for MyProto { + type Result = u8; + type ProtocolError = MyProtoError; + type CorrectnessProof = (); +} + +impl Round for Round1 { + type Protocol = MyProto; + + fn id(&self) -> RoundId { + 1 + } + + fn message_destinations(&self) -> BTreeSet { + BTreeSet::from([Id(2)]) + } + + fn make_direct_message( + &self, + _destination: &Id, + ) -> Result<(DirectMessage, Artifact), LocalError> { + let dm = DirectMessage(vec![1, 2, 3].into()); + let artifact = Artifact::empty(); + Ok((dm, artifact)) + } + + fn receive_message( + &self, + _from: &Id, + _echo_broadcast: Option, + _direct_message: DirectMessage, + ) -> Result> { + Ok(Payload(Box::new(1))) + } + + fn finalize( + self: Box, + _payloads: BTreeMap, + _artifacts: BTreeMap, + ) -> Result, FinalizeError> { + Ok(FinalizeOutcome::Result(1)) + } +} + +#[test] +fn round() { + let r1 = Round1; + + let boxed_r1: Box> = Box::new(r1); + let _result = boxed_r1.finalize(BTreeMap::new(), BTreeMap::new()); +} diff --git a/manul/Cargo.toml b/manul/Cargo.toml new file mode 100644 index 0000000..cf3dd90 --- /dev/null +++ b/manul/Cargo.toml @@ -0,0 +1,6 @@ +[package] +name = "manul" +version = "0.1.0" +edition = "2021" + +[dependencies] diff --git a/manul/src/error.rs b/manul/src/error.rs new file mode 100644 index 0000000..c713e93 --- /dev/null +++ b/manul/src/error.rs @@ -0,0 +1,54 @@ +use alloc::collections::BTreeMap; + +use crate::message::SignedMessage; +use crate::round::{DirectMessage, Protocol, ProtocolError, RoundId}; + +#[derive(Debug, Clone)] +pub struct LocalError; + +#[derive(Debug, Clone)] +pub struct RemoteError; + +#[derive(Debug, Clone)] +pub enum Error { + Local, + Remote, + Protocol(Evidence), +} + +#[derive(Debug, Clone)] +pub struct Evidence { + pub party: I, + pub error: P::ProtocolError, + pub message: SignedMessage, + pub previous_messages: BTreeMap>, +} + +impl Evidence { + pub fn verify(&self) -> bool { + let verified_messages = self + .previous_messages + .iter() + .map(|(round, message)| { + ( + *round, + message + .clone() + .verify(&self.party) + .unwrap() + .payload() + .clone(), + ) + }) + .collect::>(); + let message = self + .message + .clone() + .verify(&self.party) + .unwrap() + .payload() + .clone(); + + self.error.verify(&message, &verified_messages) + } +} diff --git a/manul/src/lib.rs b/manul/src/lib.rs new file mode 100644 index 0000000..666d6b9 --- /dev/null +++ b/manul/src/lib.rs @@ -0,0 +1,17 @@ +#![allow(dead_code)] +#![allow(unused_variables)] + +extern crate alloc; + +mod error; +mod message; +mod round; +mod session; +mod test_utils; + +pub use error::{Error, LocalError}; +pub use round::{ + Artifact, DirectMessage, EchoBroadcast, FinalizeError, FinalizeOutcome, FirstRound, Payload, + Protocol, ProtocolError, ReceiveError, Round, RoundId, +}; +pub use session::{RoundOutcome, Session}; diff --git a/src/message.rs b/manul/src/message.rs similarity index 100% rename from src/message.rs rename to manul/src/message.rs diff --git a/src/round.rs b/manul/src/round.rs similarity index 80% rename from src/round.rs rename to manul/src/round.rs index aa253a2..480e28b 100644 --- a/src/round.rs +++ b/manul/src/round.rs @@ -4,13 +4,13 @@ use core::fmt::Debug; use crate::error::LocalError; -pub enum VerificationError { +pub enum ReceiveError { InvalidMessage, Protocol(P::ProtocolError), } pub enum FinalizeOutcome { - Round(Box>), + AnotherRound(Box>), Result(P::Result), } @@ -41,6 +41,16 @@ pub struct Payload(pub Box); pub struct Artifact(pub Box); +impl Artifact { + pub fn new(artifact: T) -> Self { + Self(Box::new(artifact)) + } + + pub fn empty() -> Self { + Self::new(()) + } +} + pub trait FirstRound: Round + Sized { type Inputs; fn new(inputs: Self::Inputs) -> Result; @@ -64,9 +74,9 @@ pub trait Round { fn receive_message( &self, from: &I, - echo_broadcast: Option<&EchoBroadcast>, - direct_message: &DirectMessage, - ) -> Result>; + echo_broadcast: Option, + direct_message: DirectMessage, + ) -> Result>; fn finalize( self: Box, diff --git a/src/session.rs b/manul/src/session.rs similarity index 91% rename from src/session.rs rename to manul/src/session.rs index f8b64ec..c6b8465 100644 --- a/src/session.rs +++ b/manul/src/session.rs @@ -3,7 +3,7 @@ use alloc::collections::{BTreeMap, BTreeSet}; use crate::error::{Evidence, LocalError, RemoteError}; use crate::message::{MessageBundle, SignedMessage, VerifiedMessageBundle}; use crate::round::{ - Artifact, DirectMessage, FirstRound, Payload, ProtocolError, RoundId, VerificationError, + Artifact, DirectMessage, FirstRound, Payload, ProtocolError, ReceiveError, RoundId, }; use crate::{Error, Protocol, Round}; @@ -13,7 +13,7 @@ pub struct Session { messages: BTreeMap>>, } -pub enum FinalizeOutcome { +pub enum RoundOutcome { Result(P::Result), AnotherRound { session: Session }, } @@ -66,13 +66,13 @@ impl Session { ) -> Result> { match self.round.receive_message( message.from(), - message.echo_broadcast(), - message.direct_message(), + message.echo_broadcast().cloned(), + message.direct_message().clone(), ) { Ok(payload) => Ok(ProcessedMessage { payload }), Err(error) => match error { - VerificationError::InvalidMessage => unimplemented!(), - VerificationError::Protocol(error) => { + ReceiveError::InvalidMessage => unimplemented!(), + ReceiveError::Protocol(error) => { let from = message.from().clone(); let (echo, dm) = message.into_unverified(); Err(Error::Protocol(self.prepare_evidence(&from, &dm, error))) @@ -88,7 +88,7 @@ impl Session { pub fn finalize_round( self, accum: RoundAccumulator, - ) -> Result, Error> { + ) -> Result, Error> { unimplemented!() } diff --git a/src/test_utils.rs b/manul/src/test_utils.rs similarity index 92% rename from src/test_utils.rs rename to manul/src/test_utils.rs index 68ff4ed..2c0e317 100644 --- a/src/test_utils.rs +++ b/manul/src/test_utils.rs @@ -1,7 +1,7 @@ use alloc::collections::BTreeMap; use core::fmt::Debug; -use crate::{Error, FinalizeOutcome, FirstRound, Protocol, Round, Session}; +use crate::{Error, FirstRound, Protocol, Round, RoundOutcome, Session}; pub fn run_sync( inputs: BTreeMap, @@ -59,10 +59,10 @@ where match result { Ok(result) => match result { - FinalizeOutcome::Result(result) => { + RoundOutcome::Result(result) => { results.insert(id.clone(), Ok(result)); } - FinalizeOutcome::AnotherRound { session } => { + RoundOutcome::AnotherRound { session } => { sessions.insert(id.clone(), session); } }, diff --git a/src/error.rs b/src/error.rs deleted file mode 100644 index 22e76c6..0000000 --- a/src/error.rs +++ /dev/null @@ -1,38 +0,0 @@ -use alloc::collections::BTreeMap; - -use crate::message::SignedDirectMessage; -use crate::round::{Protocol, ProtocolError, RoundId}; - -#[derive(Debug, Clone)] -pub struct LocalError; - -#[derive(Debug, Clone)] -pub struct RemoteError; - -#[derive(Debug, Clone)] -pub enum Error { - Local, - Remote, - Protocol(Evidence), -} - -#[derive(Debug, Clone)] -pub struct Evidence { - pub party: I, - pub error: P::ProtocolError, - pub message: SignedDirectMessage, - pub previous_messages: BTreeMap>, -} - -impl Evidence { - pub fn verify(&self) -> bool { - let verified_messages = self - .previous_messages - .iter() - .map(|(round, message)| (*round, message.clone().verify(&self.party).unwrap())) - .collect::>(); - let message = self.message.clone().verify(&self.party).unwrap(); - - self.error.verify(&message, &verified_messages) - } -} diff --git a/src/lib.rs b/src/lib.rs deleted file mode 100644 index ab784dc..0000000 --- a/src/lib.rs +++ /dev/null @@ -1,14 +0,0 @@ -#![allow(dead_code)] -#![allow(unused_variables)] - -extern crate alloc; - -mod error; -mod message; -mod round; -mod session; -mod test_utils; - -pub use error::Error; -pub use round::{DirectMessage, FirstRound, Protocol, ProtocolError, Round, RoundId}; -pub use session::{FinalizeOutcome, Session}; diff --git a/tests/example.rs b/tests/example.rs deleted file mode 100644 index 40cc8e7..0000000 --- a/tests/example.rs +++ /dev/null @@ -1,69 +0,0 @@ -extern crate alloc; - -use alloc::collections::BTreeMap; - -use manul::*; - -struct Id(u8); - -struct Round1; - -struct MyProto; - -struct MyProtoError; - -impl ProtocolError for MyProtoError { - fn verify( - &self, - _message: &DirectMessage, - _messages: &BTreeMap, - ) -> bool { - true - } -} - -impl Protocol for MyProto { - type Success = u8; - type ProtocolError = MyProtoError; - type CorrectnessProof = (); -} - -impl Round for Round1 { - type Protocol = MyProto; - - fn id(&self) -> RoundId { - 1 - } - - fn message_destinations(&self) -> Vec { - vec![Id(2)] - } - - fn make_direct_message(&self, destination: &Id) -> DirectMessage { - DirectMessage(vec![1, 2, 3].into()) - } - - fn verify_message( - &self, - from: &Id, - message: &DirectMessage, - ) -> Result> { - Ok(Payload(Box::new(1))) - } - - fn round_num(&self) -> u8 { - 1 - } - - fn finalize(self: Box) -> Result, FinalizeError> { - Ok(FinalizeOutcome::Result(1)) - } -} - -#[test] -fn round() { - let r1 = Round1; - - let boxed_r1: Box> = Box::new(r1); - let _result = boxed_r1.finalize(); -} From ada1fccd50c3a18bd4ebec6edd95e033967d0b02 Mon Sep 17 00:00:00 2001 From: Bogdan Opanchuk Date: Wed, 25 Sep 2024 14:49:18 -0700 Subject: [PATCH 4/7] Basic test running --- example/src/rounds.rs | 25 +++++++++++--- manul/src/lib.rs | 2 +- manul/src/session.rs | 73 +++++++++++++++++++++++++++++++---------- manul/src/test_utils.rs | 22 ++++++++----- 4 files changed, 90 insertions(+), 32 deletions(-) diff --git a/example/src/rounds.rs b/example/src/rounds.rs index e08b5ce..f038a1a 100644 --- a/example/src/rounds.rs +++ b/example/src/rounds.rs @@ -29,6 +29,13 @@ impl Protocol for MyProto { type CorrectnessProof = (); } +impl FirstRound for Round1 { + type Inputs = (); + fn new(_inputs: Self::Inputs) -> Result { + Ok(Self) + } +} + impl Round for Round1 { type Protocol = MyProto; @@ -67,10 +74,18 @@ impl Round for Round1 { } } -#[test] -fn round() { - let r1 = Round1; +#[cfg(test)] +mod tests { + use alloc::collections::BTreeMap; + use manul::test_utils::{run_sync, RunOutcome}; - let boxed_r1: Box> = Box::new(r1); - let _result = boxed_r1.finalize(BTreeMap::new(), BTreeMap::new()); + use super::{Id, Round1}; + + #[test] + fn round() { + let results = run_sync::(BTreeMap::from([(Id(1), ()), (Id(2), ())])).unwrap(); + for (_id, result) in results { + assert!(matches!(result, RunOutcome::Result(_))); + } + } } diff --git a/manul/src/lib.rs b/manul/src/lib.rs index 666d6b9..3d3420a 100644 --- a/manul/src/lib.rs +++ b/manul/src/lib.rs @@ -7,7 +7,7 @@ mod error; mod message; mod round; mod session; -mod test_utils; +pub mod test_utils; pub use error::{Error, LocalError}; pub use round::{ diff --git a/manul/src/session.rs b/manul/src/session.rs index c6b8465..1b04daa 100644 --- a/manul/src/session.rs +++ b/manul/src/session.rs @@ -3,7 +3,8 @@ use alloc::collections::{BTreeMap, BTreeSet}; use crate::error::{Evidence, LocalError, RemoteError}; use crate::message::{MessageBundle, SignedMessage, VerifiedMessageBundle}; use crate::round::{ - Artifact, DirectMessage, FirstRound, Payload, ProtocolError, ReceiveError, RoundId, + Artifact, DirectMessage, FinalizeOutcome, FirstRound, Payload, ProtocolError, ReceiveError, + RoundId, }; use crate::{Error, Protocol, Round}; @@ -32,7 +33,7 @@ impl Session { } pub fn party_id(&self) -> I { - unimplemented!() + self.my_id.clone() } pub fn message_destinations(&self) -> BTreeSet { @@ -42,14 +43,20 @@ impl Session { pub fn make_message( &self, destination: &I, - ) -> Result<(MessageBundle, Artifact), LocalError> { + ) -> Result<(MessageBundle, ProcessedArtifact), LocalError> { let (direct_message, artifact) = self.round.make_direct_message(destination)?; let echo_broadcast = self.round.make_echo_broadcast()?; let bundle = MessageBundle::new(&self.my_id, self.round.id(), direct_message, echo_broadcast); - Ok((bundle, artifact)) + Ok(( + bundle, + ProcessedArtifact { + destination: destination.clone(), + artifact, + }, + )) } pub fn verify_message( @@ -63,13 +70,16 @@ impl Session { pub fn process_message( &self, message: VerifiedMessageBundle, - ) -> Result> { + ) -> Result, Error> { match self.round.receive_message( message.from(), message.echo_broadcast().cloned(), message.direct_message().clone(), ) { - Ok(payload) => Ok(ProcessedMessage { payload }), + Ok(payload) => Ok(ProcessedMessage { + from: message.from().clone(), + payload, + }), Err(error) => match error { ReceiveError::InvalidMessage => unimplemented!(), ReceiveError::Protocol(error) => { @@ -81,15 +91,27 @@ impl Session { } } - pub fn make_accumulator(&self) -> RoundAccumulator { - unimplemented!() + pub fn make_accumulator(&self) -> RoundAccumulator { + RoundAccumulator::new() } pub fn finalize_round( self, - accum: RoundAccumulator, + accum: RoundAccumulator, ) -> Result, Error> { - unimplemented!() + match self.round.finalize(accum.payloads, accum.artifacts) { + Ok(result) => Ok(match result { + FinalizeOutcome::Result(result) => RoundOutcome::Result(result), + FinalizeOutcome::AnotherRound(round) => RoundOutcome::AnotherRound { + session: Session { + my_id: self.my_id, + round, + messages: BTreeMap::new(), + }, + }, + }), + Err(error) => unimplemented!(), + } } fn prepare_evidence( @@ -114,15 +136,26 @@ impl Session { } } -pub struct RoundAccumulator; +pub struct RoundAccumulator { + payloads: BTreeMap, + artifacts: BTreeMap, +} + +impl RoundAccumulator { + pub fn new() -> Self { + Self { + payloads: BTreeMap::new(), + artifacts: BTreeMap::new(), + } + } -impl RoundAccumulator { - pub fn add_artifact(&mut self, artifact: Artifact) { - unimplemented!() + pub fn add_artifact(&mut self, processed: ProcessedArtifact) { + self.artifacts + .insert(processed.destination, processed.artifact); } - pub fn add_processed_message(&mut self, processed: ProcessedMessage) { - unimplemented!() + pub fn add_processed_message(&mut self, processed: ProcessedMessage) { + self.payloads.insert(processed.from, processed.payload); } } @@ -130,6 +163,12 @@ pub struct VerifiedMessage { from: I, } -pub struct ProcessedMessage { +pub struct ProcessedArtifact { + destination: I, + artifact: Artifact, +} + +pub struct ProcessedMessage { + from: I, payload: Payload, } diff --git a/manul/src/test_utils.rs b/manul/src/test_utils.rs index 2c0e317..ff2579f 100644 --- a/manul/src/test_utils.rs +++ b/manul/src/test_utils.rs @@ -1,19 +1,23 @@ use alloc::collections::BTreeMap; use core::fmt::Debug; -use crate::{Error, FirstRound, Protocol, Round, RoundOutcome, Session}; +use crate::{Error, FirstRound, Protocol, RoundOutcome, Session}; -pub fn run_sync( +pub enum RunOutcome { + Result(P::Result), + Error(Error), +} + +pub fn run_sync( inputs: BTreeMap, -) -> BTreeMap>> +) -> Result>, String> where I: Debug + Clone + Eq + Ord, - R: FirstRound + Round + 'static, - P: Protocol, + R: FirstRound + 'static, { let mut sessions = inputs .into_iter() - .map(|(id, inputs)| (id.clone(), Session::::new::(id, inputs))) + .map(|(id, inputs)| (id.clone(), Session::::new::(id, inputs))) .collect::>(); let mut results = BTreeMap::new(); @@ -60,20 +64,20 @@ where match result { Ok(result) => match result { RoundOutcome::Result(result) => { - results.insert(id.clone(), Ok(result)); + results.insert(id.clone(), RunOutcome::Result(result)); } RoundOutcome::AnotherRound { session } => { sessions.insert(id.clone(), session); } }, Err(result) => { - results.insert(id.clone(), Err(result)); + results.insert(id.clone(), RunOutcome::Error(result)); } } } if sessions.is_empty() { - return results; + return Ok(results); } } } From bbca2004158205c66f03187586cf4b9eebf8203d Mon Sep 17 00:00:00 2001 From: Bogdan Opanchuk Date: Wed, 25 Sep 2024 22:17:28 -0700 Subject: [PATCH 5/7] Add protocol-wide serialization --- example/Cargo.toml | 2 ++ example/README.md | 5 +++++ example/src/lib.rs | 2 +- example/src/{rounds.rs => simple.rs} | 26 +++++++++++++++++++------- manul/Cargo.toml | 1 + manul/src/round.rs | 20 +++++++++++++++++++- 6 files changed, 47 insertions(+), 9 deletions(-) create mode 100644 example/README.md rename example/src/{rounds.rs => simple.rs} (68%) diff --git a/example/Cargo.toml b/example/Cargo.toml index eeb8969..352dc15 100644 --- a/example/Cargo.toml +++ b/example/Cargo.toml @@ -5,3 +5,5 @@ edition = "2021" [dependencies] manul = { path = "../manul" } +bincode = { version = "2.0.0-rc.3", default-features = false, features = ["alloc", "serde"] } +serde = "1" diff --git a/example/README.md b/example/README.md new file mode 100644 index 0000000..253d83f --- /dev/null +++ b/example/README.md @@ -0,0 +1,5 @@ +This crate illustrates the usage of `manul` for implementing distributed protocols. + +The library itself is the perspective of the protocol implementor, where they create a set of `Round` impls and write unit-tests for them. + +The integration tests are the perspective of the protocol user, emulating an asynchronous execution of the protocol on multiple nodes. diff --git a/example/src/lib.rs b/example/src/lib.rs index 8e2a071..433dfee 100644 --- a/example/src/lib.rs +++ b/example/src/lib.rs @@ -1,3 +1,3 @@ extern crate alloc; -mod rounds; +mod simple; diff --git a/example/src/rounds.rs b/example/src/simple.rs similarity index 68% rename from example/src/rounds.rs rename to example/src/simple.rs index f038a1a..1adf198 100644 --- a/example/src/rounds.rs +++ b/example/src/simple.rs @@ -1,5 +1,6 @@ use alloc::collections::{BTreeMap, BTreeSet}; +use serde::{Deserialize, Serialize}; use manul::*; #[derive(Debug, Clone, PartialOrd, Ord, PartialEq, Eq)] @@ -8,12 +9,12 @@ struct Id(u8); struct Round1; #[derive(Debug)] -struct MyProto; +struct SimpleProtocol; #[derive(Debug, Clone)] -struct MyProtoError; +struct SimpleProtocolError; -impl ProtocolError for MyProtoError { +impl ProtocolError for SimpleProtocolError { fn verify( &self, _message: &DirectMessage, @@ -23,10 +24,21 @@ impl ProtocolError for MyProtoError { } } -impl Protocol for MyProto { +impl Protocol for SimpleProtocol { type Result = u8; - type ProtocolError = MyProtoError; + type ProtocolError = SimpleProtocolError; type CorrectnessProof = (); + + type SerializationError = bincode::error::EncodeError; + type DeserializationError = bincode::error::DecodeError; + + fn serialize(value: &T) -> Result, Self::SerializationError> { + bincode::serde::encode_to_vec(value, bincode::config::standard()).map(|vec| vec.into()) + } + + fn deserialize Deserialize<'de>>(bytes: &[u8]) -> Result { + bincode::serde::decode_borrowed_from_slice(bytes, bincode::config::standard()) + } } impl FirstRound for Round1 { @@ -37,7 +49,7 @@ impl FirstRound for Round1 { } impl Round for Round1 { - type Protocol = MyProto; + type Protocol = SimpleProtocol; fn id(&self) -> RoundId { 1 @@ -51,7 +63,7 @@ impl Round for Round1 { &self, _destination: &Id, ) -> Result<(DirectMessage, Artifact), LocalError> { - let dm = DirectMessage(vec![1, 2, 3].into()); + let dm = DirectMessage::new::(&[1u8, 2, 3]).unwrap(); let artifact = Artifact::empty(); Ok((dm, artifact)) } diff --git a/manul/Cargo.toml b/manul/Cargo.toml index cf3dd90..90a1f20 100644 --- a/manul/Cargo.toml +++ b/manul/Cargo.toml @@ -4,3 +4,4 @@ version = "0.1.0" edition = "2021" [dependencies] +serde = { version = "1", default-features = false } diff --git a/manul/src/round.rs b/manul/src/round.rs index 480e28b..7658d15 100644 --- a/manul/src/round.rs +++ b/manul/src/round.rs @@ -2,6 +2,8 @@ use alloc::collections::{BTreeMap, BTreeSet}; use core::any::Any; use core::fmt::Debug; +use serde::{Deserialize, Serialize}; + use crate::error::LocalError; pub enum ReceiveError { @@ -22,6 +24,12 @@ pub trait Protocol: Debug { type Result; type ProtocolError: ProtocolError; type CorrectnessProof; + type SerializationError: serde::ser::Error; + type DeserializationError: serde::de::Error; + + // TODO: should we take inputs by value? + fn serialize(value: &T) -> Result, Self::SerializationError>; + fn deserialize Deserialize<'de>>(bytes: &[u8]) -> Result; } pub trait ProtocolError: Debug + Clone { @@ -32,7 +40,17 @@ pub trait ProtocolError: Debug + Clone { } #[derive(Debug, Clone)] -pub struct DirectMessage(pub Box<[u8]>); +pub struct DirectMessage(Box<[u8]>); + +impl DirectMessage { + pub fn new(message: &T) -> Result { + P::serialize(message).map(Self) + } + + pub fn try_deserialize Deserialize<'de>>(&self) -> Result { + P::deserialize(&self.0) + } +} #[derive(Debug, Clone)] pub struct EchoBroadcast(pub Box<[u8]>); From 43b04594b488a9869a18846f0527d4d479cddb6a Mon Sep 17 00:00:00 2001 From: David Palm Date: Tue, 4 Mar 2025 17:15:47 +0100 Subject: [PATCH 6/7] Update to latest rand* crates --- Cargo.lock | 106 ++++++++++++++++++++++------ examples/Cargo.toml | 6 +- examples/src/simple.rs | 20 +++--- examples/src/simple_chain.rs | 4 +- examples/src/simple_malicious.rs | 10 +-- examples/tests/async_runner.rs | 4 +- manul/Cargo.toml | 12 ++-- manul/benches/async_session.rs | 16 +++-- manul/benches/empty_rounds.rs | 24 ++++--- manul/src/combinators/chain.rs | 12 ++-- manul/src/combinators/misbehave.rs | 20 +++--- manul/src/dev/run_sync.rs | 12 ++-- manul/src/dev/session_parameters.rs | 12 ++-- manul/src/dev/tokio.rs | 8 +-- manul/src/protocol/object_safe.rs | 29 ++++---- manul/src/protocol/round.rs | 12 ++-- manul/src/session/echo.rs | 6 +- manul/src/session/message.rs | 12 ++-- manul/src/session/session.rs | 25 +++---- manul/src/session/tokio.rs | 6 +- manul/src/tests/partial_echo.rs | 11 ++- 21 files changed, 216 insertions(+), 151 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 6e68fae..599f66a 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -123,6 +123,12 @@ version = "0.21.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9d297deb1925b89f2ccc13d7635fa0714f12c87adce1c75356b39ca9b7178567" +[[package]] +name = "bitflags" +version = "2.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5c8214115b7bf84099f1309324e63141d4c5d7cc26862f97a0a857dbefe165bd" + [[package]] name = "block-buffer" version = "0.10.4" @@ -312,6 +318,15 @@ dependencies = [ "typenum", ] +[[package]] +name = "crypto-common" +version = "0.2.0-rc.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "170d71b5b14dec99db7739f6fc7d6ec2db80b78c3acb77db48392ccc3d8a9ea0" +dependencies = [ + "hybrid-array", +] + [[package]] name = "derive-where" version = "1.2.7" @@ -330,7 +345,16 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9ed9a281f7bc9b7576e61468ba615a66a5c8cfdff42420a70aa82701a3b1e292" dependencies = [ "block-buffer", - "crypto-common", + "crypto-common 0.1.6", +] + +[[package]] +name = "digest" +version = "0.11.0-pre.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cf2e3d6615d99707295a9673e889bf363a04b2a466bd320c65a72536f7577379" +dependencies = [ + "crypto-common 0.2.0-rc.2", ] [[package]] @@ -405,13 +429,14 @@ dependencies = [ [[package]] name = "getrandom" -version = "0.2.15" +version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c4567c8db10ae91089c99af84c68c38da3ec2f087c3f82960bcdbf3656b6f4d7" +checksum = "43a49c392881ce6d5c3b8cb70f98717b7c07aabbdff06687b9030dbfbe2725f8" dependencies = [ "cfg-if", "libc", "wasi", + "windows-targets", ] [[package]] @@ -465,6 +490,15 @@ version = "0.4.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70" +[[package]] +name = "hybrid-array" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4dab50e193aebe510fe0e40230145820e02f48dae0cf339ea4204e6e708ff7bd" +dependencies = [ + "typenum", +] + [[package]] name = "impls" version = "1.0.3" @@ -555,7 +589,7 @@ version = "0.2.0-dev" dependencies = [ "criterion", "derive-where", - "digest", + "digest 0.11.0-pre.9", "displaydoc", "erased-serde", "impls", @@ -577,7 +611,7 @@ dependencies = [ name = "manul-example" version = "0.0.0" dependencies = [ - "digest", + "digest 0.11.0-pre.9", "displaydoc", "manul", "postcard", @@ -713,7 +747,7 @@ version = "0.2.20" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "77957b295656769bb8ad2b6a6b09d897d94f05c41b069aede1fcdaa675eaea04" dependencies = [ - "zerocopy", + "zerocopy 0.7.35", ] [[package]] @@ -736,20 +770,20 @@ dependencies = [ [[package]] name = "rand" -version = "0.8.5" +version = "0.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404" +checksum = "3779b94aeb87e8bd4e834cee3650289ee9e0d5677f976ecdb6d219e5f4f6cd94" dependencies = [ - "libc", "rand_chacha", "rand_core", + "zerocopy 0.8.21", ] [[package]] name = "rand_chacha" -version = "0.3.1" +version = "0.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88" +checksum = "d3022b5f1df60f26e1ffddd6c66e8aa15de382ae63b3a0c1bfc0e4d3e3f325cb" dependencies = [ "ppv-lite86", "rand_core", @@ -757,9 +791,9 @@ dependencies = [ [[package]] name = "rand_core" -version = "0.6.4" +version = "0.9.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c" +checksum = "99d9a13982dcf210057a8a78572b2217b667c3beacbf3a0d8b454f6f82837d38" dependencies = [ "getrandom", ] @@ -938,7 +972,7 @@ version = "0.10.8" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "75872d278a8f37ef87fa0ddbda7802605cb18344497949862c0d4dcb291eba60" dependencies = [ - "digest", + "digest 0.10.7", "keccak", ] @@ -953,11 +987,11 @@ dependencies = [ [[package]] name = "signature" -version = "2.2.0" +version = "2.3.0-pre.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "77549399552de45a898a580c1b41d445bf730df867cc44e6c0233bbc4b8329de" +checksum = "4633ec5613e4218fbab07568ca79ee388e3c041af75f0f83a15f040f096f94cf" dependencies = [ - "digest", + "digest 0.11.0-pre.9", "rand_core", ] @@ -1175,9 +1209,12 @@ dependencies = [ [[package]] name = "wasi" -version = "0.11.0+wasi-snapshot-preview1" +version = "0.13.3+wasi-0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" +checksum = "26816d2e1a4a36a2940b96c5296ce403917633dff8f3440e9b236ed6f6bacad2" +dependencies = [ + "wit-bindgen-rt", +] [[package]] name = "wasm-bindgen" @@ -1357,6 +1394,15 @@ version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec" +[[package]] +name = "wit-bindgen-rt" +version = "0.33.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3268f3d866458b787f390cf61f4bbb563b922d091359f9608842999eaee3943c" +dependencies = [ + "bitflags", +] + [[package]] name = "zerocopy" version = "0.7.35" @@ -1364,7 +1410,16 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1b9b4fd18abc82b8136838da5d50bae7bdea537c574d8dc1a34ed098d6c166f0" dependencies = [ "byteorder", - "zerocopy-derive", + "zerocopy-derive 0.7.35", +] + +[[package]] +name = "zerocopy" +version = "0.8.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dcf01143b2dd5d134f11f545cf9f1431b13b749695cb33bcce051e7568f99478" +dependencies = [ + "zerocopy-derive 0.8.21", ] [[package]] @@ -1377,3 +1432,14 @@ dependencies = [ "quote", "syn", ] + +[[package]] +name = "zerocopy-derive" +version = "0.8.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "712c8386f4f4299382c9abee219bee7084f78fb939d88b6840fcc1320d5f6da2" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] diff --git a/examples/Cargo.toml b/examples/Cargo.toml index 4e1a2fc..5bb65b5 100644 --- a/examples/Cargo.toml +++ b/examples/Cargo.toml @@ -13,13 +13,13 @@ manul = { path = "../manul" } postcard = { version = "1", features = ["alloc"] } serde = "1" sha3 = "0.10" -rand_core = "0.6" +rand_core = "0.9" tracing = "0.1" displaydoc = "0.2" [dev-dependencies] tokio = { version = "1", features = ["rt", "sync", "time", "macros"] } -rand = "0.8" -digest = "0.10" +rand = "0.9" +digest = { version = "0.11.0-pre.9", default-features = false } manul = { path = "../manul", features = ["dev", "tokio"] } test-log = { version = "0.2", features = ["trace", "color"] } diff --git a/examples/src/simple.rs b/examples/src/simple.rs index ed52bfb..8d1e017 100644 --- a/examples/src/simple.rs +++ b/examples/src/simple.rs @@ -7,7 +7,7 @@ use manul::protocol::{ ProtocolMessagePart, ProtocolValidationError, ReceiveError, RequiredMessageParts, RequiredMessages, Round, RoundId, Serializer, TransitionInfo, }; -use rand_core::CryptoRngCore; +use rand_core::CryptoRng; use serde::{Deserialize, Serialize}; use tracing::debug; @@ -166,7 +166,7 @@ impl EntryPoint for SimpleProtocolEntryPoint { fn make_round( self, - _rng: &mut impl CryptoRngCore, + _rng: &mut impl CryptoRng, _shared_randomness: &[u8], id: &Id, ) -> Result, LocalError> { @@ -205,7 +205,7 @@ impl Round for Round1 { fn make_normal_broadcast( &self, - _rng: &mut impl CryptoRngCore, + _rng: &mut impl CryptoRng, serializer: &Serializer, ) -> Result { debug!("{:?}: making normal broadcast", self.context.id); @@ -220,7 +220,7 @@ impl Round for Round1 { fn make_echo_broadcast( &self, - _rng: &mut impl CryptoRngCore, + _rng: &mut impl CryptoRng, serializer: &Serializer, ) -> Result { debug!("{:?}: making echo broadcast", self.context.id); @@ -234,7 +234,7 @@ impl Round for Round1 { fn make_direct_message( &self, - _rng: &mut impl CryptoRngCore, + _rng: &mut impl CryptoRng, serializer: &Serializer, destination: &Id, ) -> Result<(DirectMessage, Option), LocalError> { @@ -271,7 +271,7 @@ impl Round for Round1 { fn finalize( self, - _rng: &mut impl CryptoRngCore, + _rng: &mut impl CryptoRng, payloads: BTreeMap, _artifacts: BTreeMap, ) -> Result, LocalError> { @@ -321,7 +321,7 @@ impl Round for Round2 { fn make_direct_message( &self, - _rng: &mut impl CryptoRngCore, + _rng: &mut impl CryptoRng, serializer: &Serializer, destination: &Id, ) -> Result<(DirectMessage, Option), LocalError> { @@ -359,7 +359,7 @@ impl Round for Round2 { fn finalize( self, - _rng: &mut impl CryptoRngCore, + _rng: &mut impl CryptoRng, payloads: BTreeMap, _artifacts: BTreeMap, ) -> Result, LocalError> { @@ -388,7 +388,7 @@ mod tests { dev::{run_sync, BinaryFormat, TestSessionParams, TestSigner}, signature::Keypair, }; - use rand_core::OsRng; + use rand_core::{OsRng, TryRngCore}; use test_log::test; use super::SimpleProtocolEntryPoint; @@ -405,7 +405,7 @@ mod tests { .map(|signer| (signer, SimpleProtocolEntryPoint::new(all_ids.clone()))) .collect::>(); - let results = run_sync::<_, TestSessionParams>(&mut OsRng, entry_points) + let results = run_sync::<_, TestSessionParams>(&mut OsRng.unwrap_err(), entry_points) .unwrap() .results() .unwrap(); diff --git a/examples/src/simple_chain.rs b/examples/src/simple_chain.rs index d38857d..352b8f0 100644 --- a/examples/src/simple_chain.rs +++ b/examples/src/simple_chain.rs @@ -70,7 +70,7 @@ mod tests { dev::{run_sync, BinaryFormat, TestSessionParams, TestSigner}, signature::Keypair, }; - use rand_core::OsRng; + use rand_core::{OsRng, TryRngCore}; use test_log::test; use super::DoubleSimpleEntryPoint; @@ -87,7 +87,7 @@ mod tests { .map(|signer| (signer, DoubleSimpleEntryPoint::new(all_ids.clone()))) .collect::>(); - let results = run_sync::<_, TestSessionParams>(&mut OsRng, entry_points) + let results = run_sync::<_, TestSessionParams>(&mut OsRng.unwrap_err(), entry_points) .unwrap() .results() .unwrap(); diff --git a/examples/src/simple_malicious.rs b/examples/src/simple_malicious.rs index a4bfbef..8f97559 100644 --- a/examples/src/simple_malicious.rs +++ b/examples/src/simple_malicious.rs @@ -10,7 +10,7 @@ use manul::{ }, signature::Keypair, }; -use rand_core::{CryptoRngCore, OsRng}; +use rand_core::{CryptoRng, OsRng, TryRngCore}; use test_log::test; use crate::simple::{Round1, Round1Message, Round2, Round2Message, SimpleProtocolEntryPoint}; @@ -28,7 +28,7 @@ impl Misbehaving for MaliciousLogic { type EntryPoint = SimpleProtocolEntryPoint; fn modify_direct_message( - _rng: &mut impl CryptoRngCore, + _rng: &mut impl CryptoRng, round: &BoxedRound>::Protocol>, behavior: &Behavior, serializer: &Serializer, @@ -94,7 +94,7 @@ fn serialized_garbage() { }) .collect::>(); - let mut reports = run_sync::<_, TestSessionParams>(&mut OsRng, entry_points) + let mut reports = run_sync::<_, TestSessionParams>(&mut OsRng.unwrap_err(), entry_points) .unwrap() .reports; @@ -133,7 +133,7 @@ fn attributable_failure() { }) .collect::>(); - let mut reports = run_sync::<_, TestSessionParams>(&mut OsRng, entry_points) + let mut reports = run_sync::<_, TestSessionParams>(&mut OsRng.unwrap_err(), entry_points) .unwrap() .reports; @@ -172,7 +172,7 @@ fn attributable_failure_round2() { }) .collect::>(); - let mut reports = run_sync::<_, TestSessionParams>(&mut OsRng, entry_points) + let mut reports = run_sync::<_, TestSessionParams>(&mut OsRng.unwrap_err(), entry_points) .unwrap() .reports; diff --git a/examples/tests/async_runner.rs b/examples/tests/async_runner.rs index 728669d..9609ef4 100644 --- a/examples/tests/async_runner.rs +++ b/examples/tests/async_runner.rs @@ -7,7 +7,7 @@ use manul::{ signature::Keypair, }; use manul_example::simple::SimpleProtocolEntryPoint; -use rand_core::OsRng; +use rand_core::{OsRng, TryRngCore}; async fn async_run(offload_processing: bool) { // Create 4 parties @@ -27,7 +27,7 @@ async fn async_run(offload_processing: bool) { .collect::>(); // Run the protocol - run_async::<_, TestSessionParams>(&mut OsRng, entry_points, offload_processing) + run_async::<_, TestSessionParams>(&mut OsRng.unwrap_err(), entry_points, offload_processing) .await .unwrap(); } diff --git a/manul/Cargo.toml b/manul/Cargo.toml index 39a4d9d..6119a28 100644 --- a/manul/Cargo.toml +++ b/manul/Cargo.toml @@ -14,29 +14,29 @@ categories = ["cryptography", "no-std"] serde = { version = "1", default-features = false, features = ["alloc", "serde_derive"] } erased-serde = { version = "0.4", default-features = false, features = ["alloc"] } serde-encoded-bytes = { version = "0.1", default-features = false, features = ["hex", "base64"] } -digest = { version = "0.10", default-features = false } -signature = { version = "2", default-features = false, features = ["digest", "rand_core"] } -rand_core = { version = "0.6.4", default-features = false } +digest = { version = "0.11.0-pre.9", default-features = false } +signature = { version = "2.3.0-pre.6", default-features = false, features = ["digest", "rand_core"] } +rand_core = { version = "0.9", default-features = false } tracing = { version = "0.1", default-features = false } displaydoc = { version = "0.2", default-features = false } derive-where = "1" tinyvec = { version = "1", default-features = false, features = ["alloc", "serde"] } # Optional dependencies -rand = { version = "0.8", default-features = false, optional = true } +rand = { version = "0.9", default-features = false, optional = true } serde-persistent-deserializer = { version = "0.3", optional = true } postcard = { version = "1", default-features = false, features = ["alloc"], optional = true } serde_json = { version = "1", default-features = false, features = ["alloc"], optional = true } tokio = { version = "1", default-features = false, features = ["sync", "rt", "macros", "time"], optional = true } [dev-dependencies] +rand_core = { version = "0.9", default-features = false, features = ["os_rng"] } impls = "1" -rand_core = { version = "0.6.4", default-features = false, features = ["getrandom"] } serde_asn1_der = "0.8" criterion = "0.5" # These mirror the versions from the optional dependencies above. -rand = { version = "0.8", default-features = false } +rand = { version = "0.9", default-features = false } serde-persistent-deserializer = "0.3" postcard = { version = "1", default-features = false, features = ["alloc"] } serde_json = { version = "1", default-features = false, features = ["alloc"] } diff --git a/manul/benches/async_session.rs b/manul/benches/async_session.rs index e6d39a6..cddfe0d 100644 --- a/manul/benches/async_session.rs +++ b/manul/benches/async_session.rs @@ -14,7 +14,7 @@ use manul::{ }, signature::Keypair, }; -use rand_core::{CryptoRngCore, OsRng}; +use rand_core::{CryptoRng, OsRng, TryRngCore}; use serde::{Deserialize, Serialize}; fn do_work(seed: u8) -> u128 { @@ -91,7 +91,7 @@ impl EntryPoint for Inputs { fn make_round( self, - _rng: &mut impl CryptoRngCore, + _rng: &mut impl CryptoRng, _shared_randomness: &[u8], _id: &Id, ) -> Result, LocalError> { @@ -119,7 +119,7 @@ impl Round for EmptyRound { fn make_echo_broadcast( &self, - _rng: &mut impl CryptoRngCore, + _rng: &mut impl CryptoRng, serializer: &Serializer, ) -> Result { if self.inputs.echo { @@ -131,7 +131,7 @@ impl Round for EmptyRound { fn make_direct_message( &self, - _rng: &mut impl CryptoRngCore, + _rng: &mut impl CryptoRng, serializer: &Serializer, _destination: &Id, ) -> Result<(DirectMessage, Option), LocalError> { @@ -164,7 +164,7 @@ impl Round for EmptyRound { fn finalize( self, - _rng: &mut impl CryptoRngCore, + _rng: &mut impl CryptoRng, payloads: BTreeMap, artifacts: BTreeMap, ) -> Result, LocalError> { @@ -226,7 +226,8 @@ fn bench_async_session(c: &mut Criterion) { group.bench_function("no offloading, 10 nodes, 5 rounds, no echo", |b| { b.iter(|| { rt.block_on(async { - run_async::<_, TestSessionParams>(&mut OsRng, entry_points.clone(), false).await + run_async::<_, TestSessionParams>(&mut OsRng.unwrap_err(), entry_points.clone(), false) + .await }) }) }); @@ -235,7 +236,8 @@ fn bench_async_session(c: &mut Criterion) { group.bench_function("with offloading, 10 nodes, 5 rounds, no echo", |b| { b.iter(|| { rt.block_on(async { - run_async::<_, TestSessionParams>(&mut OsRng, entry_points.clone(), true).await + run_async::<_, TestSessionParams>(&mut OsRng.unwrap_err(), entry_points.clone(), true) + .await }) }) }); diff --git a/manul/benches/empty_rounds.rs b/manul/benches/empty_rounds.rs index 0703c26..d81007a 100644 --- a/manul/benches/empty_rounds.rs +++ b/manul/benches/empty_rounds.rs @@ -2,6 +2,7 @@ extern crate alloc; use alloc::collections::{BTreeMap, BTreeSet}; use core::fmt::Debug; +use rand::TryRngCore; use criterion::{criterion_group, criterion_main, Criterion}; use manul::{ @@ -13,7 +14,7 @@ use manul::{ }, signature::Keypair, }; -use rand_core::{CryptoRngCore, OsRng}; +use rand_core::{CryptoRng, OsRng}; use serde::{Deserialize, Serialize}; #[derive(Debug)] @@ -80,7 +81,7 @@ impl EntryPoint for Inputs { fn make_round( self, - _rng: &mut impl CryptoRngCore, + _rng: &mut impl CryptoRng, _shared_randomness: &[u8], _id: &Id, ) -> Result, LocalError> { @@ -108,7 +109,7 @@ impl Round for EmptyRound { fn make_echo_broadcast( &self, - _rng: &mut impl CryptoRngCore, + _rng: &mut impl CryptoRng, serializer: &Serializer, ) -> Result { if self.inputs.echo { @@ -120,7 +121,7 @@ impl Round for EmptyRound { fn make_direct_message( &self, - _rng: &mut impl CryptoRngCore, + _rng: &mut impl CryptoRng, serializer: &Serializer, _destination: &Id, ) -> Result<(DirectMessage, Option), LocalError> { @@ -151,7 +152,7 @@ impl Round for EmptyRound { fn finalize( self, - _rng: &mut impl CryptoRngCore, + _rng: &mut impl CryptoRng, payloads: BTreeMap, artifacts: BTreeMap, ) -> Result, LocalError> { @@ -209,12 +210,13 @@ fn bench_empty_rounds(c: &mut Criterion) { group.bench_function("25 nodes, 5 rounds, no echo", |b| { b.iter(|| { - assert!( - run_sync::<_, TestSessionParams>(&mut OsRng, entry_points_no_echo.clone()) - .unwrap() - .results() - .is_ok() + assert!(run_sync::<_, TestSessionParams>( + &mut OsRng.unwrap_err(), + entry_points_no_echo.clone() ) + .unwrap() + .results() + .is_ok()) }) }); @@ -240,7 +242,7 @@ fn bench_empty_rounds(c: &mut Criterion) { group.bench_function("25 nodes, 5 rounds, echo each round", |b| { b.iter(|| { assert!( - run_sync::<_, TestSessionParams>(&mut OsRng, entry_points_echo.clone()) + run_sync::<_, TestSessionParams>(&mut OsRng.unwrap_err(), entry_points_echo.clone()) .unwrap() .results() .is_ok() diff --git a/manul/src/combinators/chain.rs b/manul/src/combinators/chain.rs index d3ee435..1e24082 100644 --- a/manul/src/combinators/chain.rs +++ b/manul/src/combinators/chain.rs @@ -52,7 +52,7 @@ Usage: use alloc::{boxed::Box, collections::BTreeMap}; use core::fmt::{self, Debug}; -use rand_core::CryptoRngCore; +use rand_core::CryptoRng; use serde::{Deserialize, Serialize}; use crate::protocol::{ @@ -299,7 +299,7 @@ where fn make_round( self, - rng: &mut impl CryptoRngCore, + rng: &mut impl CryptoRng, shared_randomness: &[u8], id: &Id, ) -> Result, LocalError> { @@ -371,7 +371,7 @@ where fn make_direct_message( &self, - rng: &mut dyn CryptoRngCore, + rng: &mut dyn CryptoRng, serializer: &Serializer, deserializer: &Deserializer, destination: &Id, @@ -392,7 +392,7 @@ where fn make_echo_broadcast( &self, - rng: &mut dyn CryptoRngCore, + rng: &mut dyn CryptoRng, serializer: &Serializer, deserializer: &Deserializer, ) -> Result { @@ -404,7 +404,7 @@ where fn make_normal_broadcast( &self, - rng: &mut dyn CryptoRngCore, + rng: &mut dyn CryptoRng, serializer: &Serializer, deserializer: &Deserializer, ) -> Result { @@ -434,7 +434,7 @@ where fn finalize( self: Box, - rng: &mut dyn CryptoRngCore, + rng: &mut dyn CryptoRng, payloads: BTreeMap, artifacts: BTreeMap, ) -> Result, LocalError> { diff --git a/manul/src/combinators/misbehave.rs b/manul/src/combinators/misbehave.rs index 5bfe276..c70c091 100644 --- a/manul/src/combinators/misbehave.rs +++ b/manul/src/combinators/misbehave.rs @@ -26,7 +26,7 @@ Usage: use alloc::{boxed::Box, collections::BTreeMap}; use core::fmt::Debug; -use rand_core::CryptoRngCore; +use rand_core::CryptoRng; use crate::protocol::{ Artifact, BoxedRng, BoxedRound, CommunicationInfo, Deserializer, DirectMessage, EchoBroadcast, EntryPoint, @@ -56,7 +56,7 @@ where /// The default implementation passes through the original message. #[allow(unused_variables)] fn modify_echo_broadcast( - rng: &mut impl CryptoRngCore, + rng: &mut impl CryptoRng, round: &BoxedRound>::Protocol>, behavior: &B, serializer: &Serializer, @@ -72,7 +72,7 @@ where /// The default implementation passes through the original message. #[allow(unused_variables)] fn modify_normal_broadcast( - rng: &mut impl CryptoRngCore, + rng: &mut impl CryptoRng, round: &BoxedRound>::Protocol>, behavior: &B, serializer: &Serializer, @@ -88,7 +88,7 @@ where /// The default implementation passes through the original message. #[allow(unused_variables, clippy::too_many_arguments)] fn modify_direct_message( - rng: &mut impl CryptoRngCore, + rng: &mut impl CryptoRng, round: &BoxedRound>::Protocol>, behavior: &B, serializer: &Serializer, @@ -109,7 +109,7 @@ where /// in which case the existing `finalize()` will not be called. #[allow(unused_variables)] fn override_finalize( - rng: &mut impl CryptoRngCore, + rng: &mut impl CryptoRng, round: BoxedRound>::Protocol>, behavior: &B, payloads: BTreeMap, @@ -179,7 +179,7 @@ where fn make_round( self, - rng: &mut impl CryptoRngCore, + rng: &mut impl CryptoRng, shared_randomness: &[u8], id: &Id, ) -> Result, LocalError> { @@ -240,7 +240,7 @@ where fn make_direct_message( &self, - rng: &mut dyn CryptoRngCore, + rng: &mut dyn CryptoRng, serializer: &Serializer, deserializer: &Deserializer, destination: &Id, @@ -268,7 +268,7 @@ where fn make_echo_broadcast( &self, - rng: &mut dyn CryptoRngCore, + rng: &mut dyn CryptoRng, serializer: &Serializer, deserializer: &Deserializer, ) -> Result { @@ -290,7 +290,7 @@ where fn make_normal_broadcast( &self, - rng: &mut dyn CryptoRngCore, + rng: &mut dyn CryptoRng, serializer: &Serializer, deserializer: &Deserializer, ) -> Result { @@ -324,7 +324,7 @@ where fn finalize( self: Box, - rng: &mut dyn CryptoRngCore, + rng: &mut dyn CryptoRng, payloads: BTreeMap, artifacts: BTreeMap, ) -> Result, LocalError> { diff --git a/manul/src/dev/run_sync.rs b/manul/src/dev/run_sync.rs index 45b7641..da7cea6 100644 --- a/manul/src/dev/run_sync.rs +++ b/manul/src/dev/run_sync.rs @@ -1,7 +1,7 @@ use alloc::{collections::BTreeMap, format, string::String, vec::Vec}; use rand::Rng; -use rand_core::CryptoRngCore; +use rand_core::CryptoRng; use signature::Keypair; use tracing::debug; @@ -62,11 +62,11 @@ where } /// Removes a random message from the queue and returns it. - fn pop(&mut self, rng: &mut impl CryptoRngCore) -> RoundMessage { + fn pop(&mut self, rng: &mut impl CryptoRng) -> RoundMessage { match self { Self::Ordered(m) => { let senders_num = m.len(); - let sender_idx = rng.gen_range(0..senders_num); + let sender_idx = rng.random_range(0..senders_num); let sender = m.keys().nth(sender_idx).expect("the entry exists").clone(); let (message, is_empty) = { @@ -80,7 +80,7 @@ where message } Self::Unordered(v) => { - let message_idx = rng.gen_range(0..v.len()); + let message_idx = rng.random_range(0..v.len()); v.swap_remove(message_idx) } } @@ -96,7 +96,7 @@ where #[allow(clippy::type_complexity)] fn propagate( - rng: &mut impl CryptoRngCore, + rng: &mut impl CryptoRng, session: Session, accum: RoundAccumulator, ) -> Result<(State, Vec>), LocalError> @@ -156,7 +156,7 @@ where /// Execute sessions for multiple nodes in a single thread, /// given a vector of the signer and the entry point as a tuple for each node. pub fn run_sync( - rng: &mut impl CryptoRngCore, + rng: &mut impl CryptoRng, entry_points: Vec<(SP::Signer, EP)>, ) -> Result, LocalError> where diff --git a/manul/src/dev/session_parameters.rs b/manul/src/dev/session_parameters.rs index a2e3a21..e8fc025 100644 --- a/manul/src/dev/session_parameters.rs +++ b/manul/src/dev/session_parameters.rs @@ -1,5 +1,5 @@ -use digest::generic_array::typenum; -use rand_core::CryptoRngCore; +use digest::array::typenum; +use rand_core::TryCryptoRng; use serde::{Deserialize, Serialize}; use crate::session::{SessionParameters, WireFormat}; @@ -27,14 +27,14 @@ impl TestSigner { } impl signature::RandomizedDigestSigner for TestSigner { - fn try_sign_digest_with_rng( + fn try_sign_digest_with_rng( &self, - rng: &mut impl CryptoRngCore, + rng: &mut R, _digest: D, ) -> Result { Ok(TestSignature { signed_by: self.0, - randomness: rng.next_u64(), + randomness: rng.try_next_u64().expect("The OsRng works"), }) } } @@ -79,7 +79,7 @@ impl digest::Update for TestHasher { impl digest::FixedOutput for TestHasher { fn finalize_into(self, out: &mut digest::Output) { - AsMut::<[u8]>::as_mut(out).copy_from_slice(&self.buffer) + AsMut::<[u8]>::as_mut(out).copy_from_slice(self.buffer.as_ref()) } } diff --git a/manul/src/dev/tokio.rs b/manul/src/dev/tokio.rs index 718b2b6..bdbd74c 100644 --- a/manul/src/dev/tokio.rs +++ b/manul/src/dev/tokio.rs @@ -3,7 +3,7 @@ use alloc::{collections::BTreeMap, format, vec::Vec}; use rand::Rng; -use rand_core::CryptoRngCore; +use rand_core::CryptoRng; use signature::Keypair; use tokio::sync::mpsc; @@ -17,7 +17,7 @@ use crate::{ }; async fn message_dispatcher( - rng: impl CryptoRngCore, + rng: impl CryptoRng, txs: BTreeMap>>, rx: mpsc::Receiver>, ) -> Result<(), LocalError> @@ -42,7 +42,7 @@ where while !messages.is_empty() { // Pull a random message from the list, // to increase the chances that they are delivered out of order. - let message_idx = rng.gen_range(0..messages.len()); + let message_idx = rng.random_range(0..messages.len()); let outgoing = messages.swap_remove(message_idx); txs.get(&outgoing.to) @@ -74,7 +74,7 @@ where /// /// If `offload_processing` is `true`, message creation and verification will be launched in separate tasks. pub async fn run_async( - rng: &mut (impl 'static + CryptoRngCore + Clone + Send), + rng: &mut (impl 'static + CryptoRng + Clone + Send), entry_points: Vec<(SP::Signer, EP)>, offload_processing: bool, ) -> Result, LocalError> diff --git a/manul/src/protocol/object_safe.rs b/manul/src/protocol/object_safe.rs index 9a7c384..a470031 100644 --- a/manul/src/protocol/object_safe.rs +++ b/manul/src/protocol/object_safe.rs @@ -1,7 +1,7 @@ use alloc::{boxed::Box, collections::BTreeMap, format}; use core::{fmt::Debug, marker::PhantomData}; -use rand_core::{CryptoRng, CryptoRngCore, RngCore}; +use rand_core::{CryptoRng, RngCore}; use super::{ errors::{LocalError, ReceiveError}, @@ -11,10 +11,10 @@ use super::{ serialization::{Deserializer, Serializer}, }; -/// Since object-safe trait methods cannot take `impl CryptoRngCore` arguments, -/// this structure wraps the dynamic object and exposes a `CryptoRngCore` interface, +/// Since object-safe trait methods cannot take `impl CryptoRng` arguments, +/// this structure wraps the dynamic object and exposes a `CryptoRng` interface, /// to be passed to statically typed round methods. -pub(crate) struct BoxedRng<'a>(pub(crate) &'a mut dyn CryptoRngCore); +pub(crate) struct BoxedRng<'a>(pub(crate) &'a mut dyn CryptoRng); impl CryptoRng for BoxedRng<'_> {} @@ -28,12 +28,9 @@ impl RngCore for BoxedRng<'_> { fn fill_bytes(&mut self, dest: &mut [u8]) { self.0.fill_bytes(dest) } - fn try_fill_bytes(&mut self, dest: &mut [u8]) -> Result<(), rand_core::Error> { - self.0.try_fill_bytes(dest) - } } -// Since we want `Round` methods to take `&mut impl CryptoRngCore` arguments +// Since we want `Round` methods to take `&mut impl CryptoRng` arguments // (which is what all cryptographic libraries generally take), it cannot be object-safe. // Thus we have to add this crate-private object-safe layer on top of `Round`. pub(crate) trait ObjectSafeRound: 'static + Debug + Send + Sync { @@ -45,7 +42,7 @@ pub(crate) trait ObjectSafeRound: 'static + Debug + Send + Sync { fn make_direct_message( &self, - rng: &mut dyn CryptoRngCore, + rng: &mut dyn CryptoRng, serializer: &Serializer, deserializer: &Deserializer, destination: &Id, @@ -53,14 +50,14 @@ pub(crate) trait ObjectSafeRound: 'static + Debug + Send + Sync { fn make_echo_broadcast( &self, - rng: &mut dyn CryptoRngCore, + rng: &mut dyn CryptoRng, serializer: &Serializer, deserializer: &Deserializer, ) -> Result; fn make_normal_broadcast( &self, - rng: &mut dyn CryptoRngCore, + rng: &mut dyn CryptoRng, serializer: &Serializer, deserializer: &Deserializer, ) -> Result; @@ -74,7 +71,7 @@ pub(crate) trait ObjectSafeRound: 'static + Debug + Send + Sync { fn finalize( self: Box, - rng: &mut dyn CryptoRngCore, + rng: &mut dyn CryptoRng, payloads: BTreeMap, artifacts: BTreeMap, ) -> Result, LocalError>; @@ -122,7 +119,7 @@ where fn make_direct_message( &self, - rng: &mut dyn CryptoRngCore, + rng: &mut dyn CryptoRng, serializer: &Serializer, #[allow(unused_variables)] deserializer: &Deserializer, destination: &Id, @@ -133,7 +130,7 @@ where fn make_echo_broadcast( &self, - rng: &mut dyn CryptoRngCore, + rng: &mut dyn CryptoRng, serializer: &Serializer, #[allow(unused_variables)] deserializer: &Deserializer, ) -> Result { @@ -143,7 +140,7 @@ where fn make_normal_broadcast( &self, - rng: &mut dyn CryptoRngCore, + rng: &mut dyn CryptoRng, serializer: &Serializer, #[allow(unused_variables)] deserializer: &Deserializer, ) -> Result { @@ -162,7 +159,7 @@ where fn finalize( self: Box, - rng: &mut dyn CryptoRngCore, + rng: &mut dyn CryptoRng, payloads: BTreeMap, artifacts: BTreeMap, ) -> Result, LocalError> { diff --git a/manul/src/protocol/round.rs b/manul/src/protocol/round.rs index e535136..85c0459 100644 --- a/manul/src/protocol/round.rs +++ b/manul/src/protocol/round.rs @@ -8,7 +8,7 @@ use core::{ fmt::{Debug, Display}, }; -use rand_core::CryptoRngCore; +use rand_core::CryptoRng; use serde::{Deserialize, Serialize}; use super::{ @@ -327,7 +327,7 @@ pub trait EntryPoint { /// `id` is the ID of this node. fn make_round( self, - rng: &mut impl CryptoRngCore, + rng: &mut impl CryptoRng, shared_randomness: &[u8], id: &Id, ) -> Result, LocalError>; @@ -389,7 +389,7 @@ pub trait Round: 'static + Debug + Send + Sync { /// These should be put in an [`Artifact`] and will be available at the time of [`finalize`](`Self::finalize`). fn make_direct_message( &self, - #[allow(unused_variables)] rng: &mut impl CryptoRngCore, + #[allow(unused_variables)] rng: &mut impl CryptoRng, #[allow(unused_variables)] serializer: &Serializer, #[allow(unused_variables)] destination: &Id, ) -> Result<(DirectMessage, Option), LocalError> { @@ -406,7 +406,7 @@ pub trait Round: 'static + Debug + Send + Sync { /// if an evidence of malicious behavior has to be constructed. fn make_echo_broadcast( &self, - #[allow(unused_variables)] rng: &mut impl CryptoRngCore, + #[allow(unused_variables)] rng: &mut impl CryptoRng, #[allow(unused_variables)] serializer: &Serializer, ) -> Result { Ok(EchoBroadcast::none()) @@ -421,7 +421,7 @@ pub trait Round: 'static + Debug + Send + Sync { /// without any confirmation required. fn make_normal_broadcast( &self, - #[allow(unused_variables)] rng: &mut impl CryptoRngCore, + #[allow(unused_variables)] rng: &mut impl CryptoRng, #[allow(unused_variables)] serializer: &Serializer, ) -> Result { Ok(NormalBroadcast::none()) @@ -445,7 +445,7 @@ pub trait Round: 'static + Debug + Send + Sync { /// [`make_direct_message`](`Self::make_direct_message`). fn finalize( self, - rng: &mut impl CryptoRngCore, + rng: &mut impl CryptoRng, payloads: BTreeMap, artifacts: BTreeMap, ) -> Result, LocalError>; diff --git a/manul/src/session/echo.rs b/manul/src/session/echo.rs index 568322d..a72432b 100644 --- a/manul/src/session/echo.rs +++ b/manul/src/session/echo.rs @@ -6,7 +6,7 @@ use alloc::{ }; use core::fmt::Debug; -use rand_core::CryptoRngCore; +use rand_core::CryptoRng; use serde::{Deserialize, Serialize}; use tracing::debug; @@ -153,7 +153,7 @@ where fn make_normal_broadcast( &self, - _rng: &mut impl CryptoRngCore, + _rng: &mut impl CryptoRng, serializer: &Serializer, ) -> Result { debug!("{:?}: making an echo round message", self.verifier); @@ -268,7 +268,7 @@ where fn finalize( self, - rng: &mut impl CryptoRngCore, + rng: &mut impl CryptoRng, _payloads: BTreeMap, _artifacts: BTreeMap, ) -> Result, LocalError> { diff --git a/manul/src/session/message.rs b/manul/src/session/message.rs index 5b15b54..1beafb6 100644 --- a/manul/src/session/message.rs +++ b/manul/src/session/message.rs @@ -1,7 +1,7 @@ use alloc::{boxed::Box, format}; use digest::Digest; -use rand_core::CryptoRngCore; +use rand_core::CryptoRng; use serde::{Deserialize, Serialize}; use serde_encoded_bytes::{Hex, SliceLike}; use signature::{DigestVerifier, RandomizedDigestSigner}; @@ -116,7 +116,7 @@ where M: ProtocolMessagePartHashable, { pub fn new( - rng: &mut impl CryptoRngCore, + rng: &mut impl CryptoRng, signer: &SP::Signer, session_id: &SessionId, round_id: &RoundId, @@ -142,10 +142,11 @@ where SP: SessionParameters, { let message_part_hash = self.message_with_metadata.message.hash::(); + let message_part_hash: &[u8] = message_part_hash.as_ref(); SignedMessageHash { signature: self.signature.clone(), metadata: self.message_with_metadata.metadata.clone(), - message_part_hash: message_part_hash.as_ref().into(), + message_part_hash: message_part_hash.into(), } } @@ -213,7 +214,7 @@ where { #[allow(clippy::too_many_arguments)] pub(crate) fn new( - rng: &mut impl CryptoRngCore, + rng: &mut impl CryptoRng, signer: &SP::Signer, session_id: &SessionId, round_id: &RoundId, @@ -390,6 +391,7 @@ impl VerifiedMessageHash { M: ProtocolMessagePartHashable, { let message_part_hash = message.message_with_metadata.message.hash::(); - message_part_hash.as_ref() == self.message_part_hash.as_ref() + let message_part_hash: &[u8] = message_part_hash.as_ref(); + message_part_hash == self.message_part_hash.as_ref() } } diff --git a/manul/src/session/session.rs b/manul/src/session/session.rs index eec696b..54153ab 100644 --- a/manul/src/session/session.rs +++ b/manul/src/session/session.rs @@ -8,7 +8,7 @@ use alloc::{ use core::fmt::Debug; use digest::Digest; -use rand_core::CryptoRngCore; +use rand_core::CryptoRng; use serde::{Deserialize, Serialize}; use serde_encoded_bytes::{Hex, SliceLike}; use signature::{DigestVerifier, Keypair, RandomizedDigestSigner}; @@ -64,10 +64,11 @@ impl SessionId { /// **Warning:** this should generally be used for testing; creating a random session ID in a centralized way /// usually defeats the purpose of having a distributed protocol. #[cfg(any(test, feature = "dev"))] - pub fn random(rng: &mut impl CryptoRngCore) -> Self { + pub fn random(rng: &mut impl CryptoRng) -> Self { let mut buffer = digest::Output::::default(); rng.fill_bytes(&mut buffer); - Self(buffer.as_ref().into()) + let buffer: &[u8] = buffer.as_ref(); + Self(buffer.into()) } /// Creates a session identifier deterministically from the given bytestring. @@ -81,13 +82,9 @@ impl SessionId { /// In a blockchain setting, it may be some combination of the current block hash with the public parameters /// (identities of the parties, hash of the inputs). pub fn from_seed(bytes: &[u8]) -> Self { - Self( - SP::Digest::new_with_prefix(b"SessionId") - .chain_update(bytes) - .finalize() - .as_ref() - .into(), - ) + let digest = SP::Digest::new_with_prefix(b"SessionId").chain_update(bytes).finalize(); + let digest: &[u8] = digest.as_ref(); + Self(digest.into()) } } @@ -143,7 +140,7 @@ where { /// Initializes a new session. pub fn new( - rng: &mut impl CryptoRngCore, + rng: &mut impl CryptoRng, session_id: SessionId, signer: SP::Signer, entry_point: EP, @@ -166,7 +163,7 @@ where } fn new_for_next_round( - rng: &mut impl CryptoRngCore, + rng: &mut impl CryptoRng, session_id: SessionId, signer: SP::Signer, serializer: Serializer, @@ -246,7 +243,7 @@ where /// The destination must be one of those returned by [`message_destinations`](`Self::message_destinations`). pub fn make_message( &self, - rng: &mut impl CryptoRngCore, + rng: &mut impl CryptoRng, destination: &SP::Verifier, ) -> Result<(Message, ProcessedArtifact), LocalError> { let (direct_message, artifact) = @@ -470,7 +467,7 @@ where /// Attempts to finalize the current round. pub fn finalize_round( self, - rng: &mut impl CryptoRngCore, + rng: &mut impl CryptoRng, accum: RoundAccumulator, ) -> Result, LocalError> { let verifier = self.verifier().clone(); diff --git a/manul/src/session/tokio.rs b/manul/src/session/tokio.rs index 748ac8a..ac04431 100644 --- a/manul/src/session/tokio.rs +++ b/manul/src/session/tokio.rs @@ -2,7 +2,7 @@ use alloc::{format, sync::Arc, vec::Vec}; -use rand_core::CryptoRngCore; +use rand_core::CryptoRng; use tokio::{sync::mpsc, task::JoinHandle}; use tracing::{debug, trace}; @@ -47,7 +47,7 @@ pub struct MessageIn { /// Executes the session waiting for the messages from the `rx` channel /// and pushing outgoing messages into the `tx` channel. pub async fn run_session( - rng: &mut impl CryptoRngCore, + rng: &mut impl CryptoRng, tx: &mpsc::Sender>, rx: &mut mpsc::Receiver>, session: Session, @@ -181,7 +181,7 @@ where /// to offset the parallelizing overhead. /// Use [`tokio::run_async`](`crate::dev::tokio::run_async`) to benchmark your specific protocol. pub async fn par_run_session( - rng: &mut (impl 'static + Clone + CryptoRngCore + Send), + rng: &mut (impl 'static + Clone + CryptoRng + Send), tx: &mpsc::Sender>, rx: &mut mpsc::Receiver>, session: Session, diff --git a/manul/src/tests/partial_echo.rs b/manul/src/tests/partial_echo.rs index b7e07f5..4891a97 100644 --- a/manul/src/tests/partial_echo.rs +++ b/manul/src/tests/partial_echo.rs @@ -4,8 +4,7 @@ use alloc::{ vec::Vec, }; use core::{fmt::Debug, marker::PhantomData}; - -use rand_core::{CryptoRngCore, OsRng}; +use rand_core::{CryptoRng, OsRng, TryRngCore}; use serde::{Deserialize, Serialize}; use crate::{ @@ -78,7 +77,7 @@ impl Deserialize<'de>> EntryPoint for Inp fn make_round( self, - _rng: &mut impl CryptoRngCore, + _rng: &mut impl CryptoRng, _shared_randomness: &[u8], _id: &Id, ) -> Result, LocalError> { @@ -103,7 +102,7 @@ impl Deserialize<'de>> Round for Round1 Result { if self.inputs.message_destinations.is_empty() { @@ -140,7 +139,7 @@ impl Deserialize<'de>> Round for Round1, _artifacts: BTreeMap, ) -> Result, LocalError> { @@ -210,7 +209,7 @@ fn partial_echo() { let entry_points = vec![node0, node1, node2, node3, node4]; - let _results = run_sync::<_, TestSessionParams>(&mut OsRng, entry_points) + let _results = run_sync::<_, TestSessionParams>(&mut OsRng.unwrap_err(), entry_points) .unwrap() .results() .unwrap(); From 60cb4e02f7b0ccc2e8f21ce3c5ce04502c51eb3e Mon Sep 17 00:00:00 2001 From: David Palm Date: Tue, 4 Mar 2025 17:20:27 +0100 Subject: [PATCH 7/7] Upgrade to rust 1.85 --- .github/workflows/ci.yml | 6 +++--- manul/Cargo.toml | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index a6ef5ad..4a83fd4 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -17,7 +17,7 @@ jobs: strategy: matrix: rust: - - 1.81.0 # MSRV + - 1.85.0 # MSRV - stable target: - wasm32-unknown-unknown @@ -58,7 +58,7 @@ jobs: matrix: include: - target: x86_64-unknown-linux-gnu - rust: 1.81.0 # MSRV + rust: 1.85.0 # MSRV steps: - uses: actions/checkout@v4 - uses: dtolnay/rust-toolchain@v1 @@ -76,7 +76,7 @@ jobs: - uses: actions/checkout@v4 - uses: actions-rs/toolchain@v1 with: - toolchain: 1.81.0 # MSRV + toolchain: 1.85.0 # MSRV components: clippy override: true profile: minimal diff --git a/manul/Cargo.toml b/manul/Cargo.toml index 6119a28..5eeb324 100644 --- a/manul/Cargo.toml +++ b/manul/Cargo.toml @@ -2,7 +2,7 @@ name = "manul" version = "0.2.0-dev" edition = "2021" -rust-version = "1.81" +rust-version = "1.85" authors = ['Entropy Cryptography '] license = "AGPL-3.0-or-later" description = "Generic library for round-based protocols"