diff --git a/examples/src/simple.rs b/examples/src/simple.rs index 103e782..b85638c 100644 --- a/examples/src/simple.rs +++ b/examples/src/simple.rs @@ -23,7 +23,7 @@ pub enum SimpleProtocolError { Round2InvalidPosition, } -impl ProtocolError for SimpleProtocolError { +impl ProtocolError for SimpleProtocolError { fn description(&self) -> String { format!("{:?}", self) } @@ -53,6 +53,7 @@ impl ProtocolError for SimpleProtocolError { fn verify_messages_constitute_error( &self, deserializer: &Deserializer, + _guilty_party: &Id, _shared_randomness: &[u8], _echo_broadcast: &EchoBroadcast, _normal_broadcast: &NormalBroadcast, @@ -87,7 +88,7 @@ impl ProtocolError for SimpleProtocolError { } } -impl Protocol for SimpleProtocol { +impl Protocol for SimpleProtocol { type Result = u8; type ProtocolError = SimpleProtocolError; diff --git a/examples/src/simple_chain.rs b/examples/src/simple_chain.rs index 8d0fb7b..d38857d 100644 --- a/examples/src/simple_chain.rs +++ b/examples/src/simple_chain.rs @@ -2,10 +2,7 @@ use alloc::collections::BTreeSet; use core::fmt::Debug; use manul::{ - combinators::{ - chain::{Chain, ChainedJoin, ChainedProtocol, ChainedSplit}, - CombinatorEntryPoint, - }, + combinators::chain::{ChainedJoin, ChainedMarker, ChainedProtocol, ChainedSplit}, protocol::{PartyId, Protocol}, }; @@ -16,7 +13,9 @@ use super::simple::{SimpleProtocol, SimpleProtocolEntryPoint}; #[derive(Debug)] pub struct DoubleSimpleProtocol; -impl ChainedProtocol for DoubleSimpleProtocol { +impl ChainedMarker for DoubleSimpleProtocol {} + +impl ChainedProtocol for DoubleSimpleProtocol { type Protocol1 = SimpleProtocol; type Protocol2 = SimpleProtocol; } @@ -25,16 +24,14 @@ pub struct DoubleSimpleEntryPoint { all_ids: BTreeSet, } +impl ChainedMarker for DoubleSimpleEntryPoint {} + impl DoubleSimpleEntryPoint { pub fn new(all_ids: BTreeSet) -> Self { Self { all_ids } } } -impl CombinatorEntryPoint for DoubleSimpleEntryPoint { - type Combinator = Chain; -} - impl ChainedSplit for DoubleSimpleEntryPoint where Id: PartyId, @@ -60,7 +57,7 @@ where { type Protocol = DoubleSimpleProtocol; type EntryPoint = SimpleProtocolEntryPoint; - fn make_entry_point2(self, _result: ::Result) -> Self::EntryPoint { + fn make_entry_point2(self, _result: >::Result) -> Self::EntryPoint { SimpleProtocolEntryPoint::new(self.all_ids) } } diff --git a/examples/tests/async_runner.rs b/examples/tests/async_runner.rs index 504dec8..f7c937b 100644 --- a/examples/tests/async_runner.rs +++ b/examples/tests/async_runner.rs @@ -35,7 +35,7 @@ async fn run_session( session: Session, ) -> Result, LocalError> where - P: Protocol, + P: Protocol, SP: SessionParameters, { let rng = &mut OsRng; @@ -194,7 +194,7 @@ async fn message_dispatcher( async fn run_nodes(sessions: Vec>) -> Vec> where - P: Protocol + Send, + P: Protocol + Send, SP: SessionParameters, P::Result: Send, SP::Signer: Send, diff --git a/manul/benches/empty_rounds.rs b/manul/benches/empty_rounds.rs index 3f1140d..fae2539 100644 --- a/manul/benches/empty_rounds.rs +++ b/manul/benches/empty_rounds.rs @@ -18,7 +18,7 @@ use serde::{Deserialize, Serialize}; #[derive(Debug)] pub struct EmptyProtocol; -impl Protocol for EmptyProtocol { +impl Protocol for EmptyProtocol { type Result = (); type ProtocolError = (); } diff --git a/manul/src/combinators.rs b/manul/src/combinators.rs index 812b9d6..48f012b 100644 --- a/manul/src/combinators.rs +++ b/manul/src/combinators.rs @@ -1,7 +1,4 @@ //! Combinators operating on protocols. pub mod chain; -mod markers; pub mod misbehave; - -pub use markers::{Combinator, CombinatorEntryPoint}; diff --git a/manul/src/combinators/chain.rs b/manul/src/combinators/chain.rs index cb6fb72..3654f95 100644 --- a/manul/src/combinators/chain.rs +++ b/manul/src/combinators/chain.rs @@ -31,15 +31,19 @@ Usage: 1. Implement [`ChainedProtocol`] for a type of your choice. Usually it will be a ZST. You will have to specify the two protocol types you want to chain. - This type will then automatically implement [`Protocol`](`crate::protocol::Protocol`). -2. Define an entry point type for the new joined protocol. +2. Implement the marker trait [`ChainedMarker`] for this type. This will activate the blanket implementation + of [`Protocol`](`crate::protocol::Protocol`) for it. + The marker trait is needed to disambiguate different generic blanket implementations. + +3. Define an entry point type for the new joined protocol. Most likely it will contain a union between the required data for the entry point of the first and the second protocol. -3. Implement [`ChainedSplit`] and [`ChainedJoin`] for the new entry point. +4. Implement [`ChainedSplit`] and [`ChainedJoin`] for the new entry point. -4. Mark the new entry point with the [`CombinatorEntryPoint`] trait using [`Chain`] for `Type`. +5. Implement the marker trait [`ChainedMarker`] for this type. + Same as with the protocol, this is needed to disambiguate different generic blanket implementations. */ use alloc::{ @@ -54,65 +58,61 @@ use core::fmt::Debug; use rand_core::CryptoRngCore; use serde::{Deserialize, Serialize}; -use super::markers::{Combinator, CombinatorEntryPoint}; use crate::protocol::{ Artifact, BoxedRng, BoxedRound, Deserializer, DirectMessage, EchoBroadcast, EchoRoundParticipation, EntryPoint, FinalizeOutcome, LocalError, NormalBroadcast, ObjectSafeRound, PartyId, Payload, Protocol, ProtocolError, ProtocolValidationError, ReceiveError, RoundId, Serializer, }; -/// A marker for the `chain` combinator. -#[derive(Debug, Clone, Copy)] -pub struct Chain; - -impl Combinator for Chain {} +/// A marker trait that is used to disambiguate blanket trait implementations for [`Protocol`] and [`EntryPoint`]. +pub trait ChainedMarker {} /// A trait defining two protocols executed sequentially. -pub trait ChainedProtocol: 'static + Debug { +pub trait ChainedProtocol: 'static + Debug { /// The protcol that is executed first. - type Protocol1: Protocol; + type Protocol1: Protocol; /// The protcol that is executed second. - type Protocol2: Protocol; + type Protocol2: Protocol; } /// The protocol error type for the chained protocol. #[derive_where::derive_where(Debug, Clone)] #[derive(Serialize, Deserialize)] #[serde(bound(serialize = " - ::ProtocolError: Serialize, - ::ProtocolError: Serialize, + >::ProtocolError: Serialize, + >::ProtocolError: Serialize, "))] #[serde(bound(deserialize = " - ::ProtocolError: for<'x> Deserialize<'x>, - ::ProtocolError: for<'x> Deserialize<'x>, + >::ProtocolError: for<'x> Deserialize<'x>, + >::ProtocolError: for<'x> Deserialize<'x>, "))] -pub enum ChainedProtocolError +pub enum ChainedProtocolError where - C: ChainedProtocol, + C: ChainedProtocol, { /// A protocol error from the first protocol. - Protocol1(::ProtocolError), + Protocol1(>::ProtocolError), /// A protocol error from the second protocol. - Protocol2(::ProtocolError), + Protocol2(>::ProtocolError), } -impl ChainedProtocolError +impl ChainedProtocolError where - C: ChainedProtocol, + C: ChainedProtocol, { - fn from_protocol1(err: ::ProtocolError) -> Self { + fn from_protocol1(err: >::ProtocolError) -> Self { Self::Protocol1(err) } - fn from_protocol2(err: ::ProtocolError) -> Self { + fn from_protocol2(err: >::ProtocolError) -> Self { Self::Protocol2(err) } } -impl ProtocolError for ChainedProtocolError +impl ProtocolError for ChainedProtocolError where - C: ChainedProtocol, + C: ChainedProtocol, { fn description(&self) -> String { match self { @@ -169,6 +169,7 @@ where fn verify_messages_constitute_error( &self, deserializer: &Deserializer, + guilty_party: &Id, shared_randomness: &[u8], echo_broadcast: &EchoBroadcast, normal_broadcast: &NormalBroadcast, @@ -204,6 +205,7 @@ where match self { Self::Protocol1(err) => err.verify_messages_constitute_error( deserializer, + guilty_party, shared_randomness, echo_broadcast, normal_broadcast, @@ -215,6 +217,7 @@ where ), Self::Protocol2(err) => err.verify_messages_constitute_error( deserializer, + guilty_party, shared_randomness, echo_broadcast, normal_broadcast, @@ -228,12 +231,13 @@ where } } -impl Protocol for C +impl Protocol for C where - C: ChainedProtocol, + Id: 'static, + C: ChainedProtocol + ChainedMarker, { - type Result = ::Result; - type ProtocolError = ChainedProtocolError; + type Result = >::Result; + type ProtocolError = ChainedProtocolError; } /// A trait defining how the entry point for the whole chained protocol @@ -241,10 +245,10 @@ where /// that, along with the first protocol's result, will be used to create the entry point for the second protocol. pub trait ChainedSplit { /// The chained protocol this trait belongs to. - type Protocol: ChainedProtocol; + type Protocol: ChainedProtocol + ChainedMarker; /// The first protocol's entry point. - type EntryPoint: EntryPoint::Protocol1>; + type EntryPoint: EntryPoint>::Protocol1>; /// Creates the first protocol's entry point and the data for creating the second entry point. fn make_entry_point1(self) -> (Self::EntryPoint, impl ChainedJoin); @@ -254,22 +258,22 @@ pub trait ChainedSplit { /// will be joined with the result of the first protocol to create an entry point for the second protocol. pub trait ChainedJoin: 'static + Debug + Send + Sync { /// The chained protocol this trait belongs to. - type Protocol: ChainedProtocol; + type Protocol: ChainedProtocol + ChainedMarker; /// The second protocol's entry point. - type EntryPoint: EntryPoint::Protocol2>; + type EntryPoint: EntryPoint>::Protocol2>; /// Creates the second protocol's entry point using the first protocol's result. fn make_entry_point2( self, - result: <::Protocol1 as Protocol>::Result, + result: <>::Protocol1 as Protocol>::Result, ) -> Self::EntryPoint; } impl EntryPoint for T where Id: PartyId, - T: ChainedSplit + CombinatorEntryPoint, + T: ChainedSplit + ChainedMarker, { type Protocol = T::Protocol; @@ -314,11 +318,11 @@ where { Protocol1 { id: Id, - round: BoxedRound::Protocol1>, + round: BoxedRound>::Protocol1>, shared_randomness: Box<[u8]>, transition: T, }, - Protocol2(BoxedRound::Protocol2>), + Protocol2(BoxedRound>::Protocol2>), } impl ObjectSafeRound for ChainedRound diff --git a/manul/src/combinators/markers.rs b/manul/src/combinators/markers.rs deleted file mode 100644 index de297fc..0000000 --- a/manul/src/combinators/markers.rs +++ /dev/null @@ -1,9 +0,0 @@ -/// A marker trait for protocol combinators. -pub trait Combinator {} - -/// Marks an entry point for a protocol combinator result, so that [`EntryPoint`](`crate::protocol::EntryPoint`) -/// can be derived automatically for it. -pub trait CombinatorEntryPoint { - /// The type of the combinator. - type Combinator: Combinator; -} diff --git a/manul/src/dev/run_sync.rs b/manul/src/dev/run_sync.rs index 05a483d..73e222b 100644 --- a/manul/src/dev/run_sync.rs +++ b/manul/src/dev/run_sync.rs @@ -13,7 +13,7 @@ use crate::{ }, }; -enum State { +enum State, SP: SessionParameters> { InProgress { session: Session, accum: RoundAccumulator, @@ -34,7 +34,7 @@ fn propagate( accum: RoundAccumulator, ) -> Result<(State, Vec>), LocalError> where - P: Protocol, + P: Protocol, SP: SessionParameters, { let mut messages = Vec::new(); @@ -168,12 +168,12 @@ where /// The result of a protocol execution on a set of nodes. #[derive(Debug)] -pub struct ExecutionResult { +pub struct ExecutionResult, SP: SessionParameters> { pub reports: BTreeMap>, } impl ExecutionResult where - P: Protocol, + P: Protocol, SP: SessionParameters, { pub fn results(self) -> Result, String> { diff --git a/manul/src/protocol/errors.rs b/manul/src/protocol/errors.rs index 329948e..42d9cab 100644 --- a/manul/src/protocol/errors.rs +++ b/manul/src/protocol/errors.rs @@ -30,10 +30,10 @@ impl RemoteError { /// An error that can be returned from [`Round::receive_message`](`super::Round::receive_message`). #[derive(Debug)] -pub struct ReceiveError(pub(crate) ReceiveErrorType); +pub struct ReceiveError>(pub(crate) ReceiveErrorType); #[derive(Debug)] -pub(crate) enum ReceiveErrorType { +pub(crate) enum ReceiveErrorType> { /// A local error, indicating an implemenation bug or a misuse by the upper layer. Local(LocalError), /// The given direct message cannot be deserialized. @@ -53,7 +53,7 @@ pub(crate) enum ReceiveErrorType { Echo(Box>), } -impl ReceiveError { +impl> ReceiveError { /// A local error, indicating an implemenation bug or a misuse by the upper layer. pub fn local(message: impl Into) -> Self { Self(ReceiveErrorType::Local(LocalError::new(message.into()))) @@ -73,17 +73,17 @@ impl ReceiveError { pub(crate) fn map(self, f: F) -> ReceiveError where F: Fn(P::ProtocolError) -> T::ProtocolError, - T: Protocol, + T: Protocol, { ReceiveError(self.0.map::(f)) } } -impl ReceiveErrorType { +impl> ReceiveErrorType { pub(crate) fn map(self, f: F) -> ReceiveErrorType where F: Fn(P::ProtocolError) -> T::ProtocolError, - T: Protocol, + T: Protocol, { match self { Self::Local(err) => ReceiveErrorType::Local(err), @@ -99,7 +99,7 @@ impl ReceiveErrorType { impl From for ReceiveError where - P: Protocol, + P: Protocol, { fn from(error: LocalError) -> Self { Self(ReceiveErrorType::Local(error)) @@ -108,7 +108,7 @@ where impl From for ReceiveError where - P: Protocol, + P: Protocol, { fn from(error: RemoteError) -> Self { Self(ReceiveErrorType::Unprovable(error)) @@ -117,7 +117,7 @@ where impl From> for ReceiveError where - P: Protocol, + P: Protocol, { fn from(error: EchoRoundError) -> Self { Self(ReceiveErrorType::Echo(Box::new(error))) @@ -126,7 +126,7 @@ where impl From for ReceiveError where - P: Protocol, + P: Protocol, { fn from(error: DirectMessageError) -> Self { Self(ReceiveErrorType::InvalidDirectMessage(error)) @@ -135,7 +135,7 @@ where impl From for ReceiveError where - P: Protocol, + P: Protocol, { fn from(error: EchoBroadcastError) -> Self { Self(ReceiveErrorType::InvalidEchoBroadcast(error)) @@ -144,7 +144,7 @@ where impl From for ReceiveError where - P: Protocol, + P: Protocol, { fn from(error: NormalBroadcastError) -> Self { Self(ReceiveErrorType::InvalidNormalBroadcast(error)) diff --git a/manul/src/protocol/object_safe.rs b/manul/src/protocol/object_safe.rs index 00bcb6e..b66d96a 100644 --- a/manul/src/protocol/object_safe.rs +++ b/manul/src/protocol/object_safe.rs @@ -40,7 +40,7 @@ impl RngCore for BoxedRng<'_> { // (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 { - type Protocol: Protocol; + type Protocol: Protocol; fn id(&self) -> RoundId; @@ -217,12 +217,12 @@ where /// A wrapped new round that may be returned by [`Round::finalize`] /// or [`EntryPoint::make_round`](`crate::protocol::EntryPoint::make_round`). #[derive_where::derive_where(Debug)] -pub struct BoxedRound { +pub struct BoxedRound> { wrapped: bool, round: Box>, } -impl BoxedRound { +impl> BoxedRound { /// Wraps an object implementing the dynamic round trait ([`Round`](`crate::protocol::Round`)). pub fn new_dynamic>(round: R) -> Self { Self { diff --git a/manul/src/protocol/round.rs b/manul/src/protocol/round.rs index 651a130..800eab3 100644 --- a/manul/src/protocol/round.rs +++ b/manul/src/protocol/round.rs @@ -23,7 +23,7 @@ use super::{ /// Possible successful outcomes of [`Round::finalize`]. #[derive(Debug)] -pub enum FinalizeOutcome { +pub enum FinalizeOutcome> { /// Transition to a new round. AnotherRound(BoxedRound), /// The protocol reached a result. @@ -127,12 +127,12 @@ impl RoundId { } /// A distributed protocol. -pub trait Protocol: 'static { +pub trait Protocol: 'static { /// The successful result of an execution of this protocol. type Result: Debug; /// An object of this type will be returned when a provable error happens during [`Round::receive_message`]. - type ProtocolError: ProtocolError; + type ProtocolError: ProtocolError; /// Returns `Ok(())` if the given direct message cannot be deserialized /// assuming it is a direct message from the round `round_id`. @@ -181,7 +181,7 @@ pub trait Protocol: 'static { /// /// Provable here means that we can create an evidence object entirely of messages signed by some party, /// which, in combination, prove the party's malicious actions. -pub trait ProtocolError: Debug + Clone + Send + Serialize + for<'de> Deserialize<'de> { +pub trait ProtocolError: Debug + Clone + Send + Serialize + for<'de> Deserialize<'de> { /// A description of the error that will be included in the generated evidence. /// /// Make it short and informative. @@ -234,6 +234,7 @@ pub trait ProtocolError: Debug + Clone + Send + Serialize + for<'de> Deserialize fn verify_messages_constitute_error( &self, deserializer: &Deserializer, + guilty_party: &Id, shared_randomness: &[u8], echo_broadcast: &EchoBroadcast, normal_broadcast: &NormalBroadcast, @@ -247,7 +248,7 @@ pub trait ProtocolError: Debug + Clone + Send + Serialize + for<'de> Deserialize // A convenience implementation for protocols that don't define any errors. // Have to do it for `()`, since `!` is unstable. -impl ProtocolError for () { +impl ProtocolError for () { fn description(&self) -> String { panic!("Attempt to use an empty error type in an evidence. This is a bug in the protocol implementation.") } @@ -255,6 +256,7 @@ impl ProtocolError for () { fn verify_messages_constitute_error( &self, _deserializer: &Deserializer, + _guilty_party: &Id, _shared_randomness: &[u8], _echo_broadcast: &EchoBroadcast, _normal_broadcast: &NormalBroadcast, @@ -327,7 +329,7 @@ impl Artifact { /// all the others are only reachable throud [`Round::finalize`] by the execution layer. pub trait EntryPoint { /// The protocol implemented by the round this entry points returns. - type Protocol: Protocol; + type Protocol: Protocol; /// Returns the ID of the round returned by [`Self::make_round`]. fn entry_round() -> RoundId { @@ -381,7 +383,7 @@ The way a round will be used by an external caller: */ pub trait Round: 'static + Debug + Send + Sync { /// The protocol this round is a part of. - type Protocol: Protocol; + type Protocol: Protocol; /// The round ID. /// diff --git a/manul/src/session/echo.rs b/manul/src/session/echo.rs index de90251..69601e4 100644 --- a/manul/src/session/echo.rs +++ b/manul/src/session/echo.rs @@ -73,7 +73,7 @@ pub(crate) struct EchoRoundMessage { /// participants. The execution layer of the protocol guarantees that all participants have received /// the messages. #[derive_where::derive_where(Debug)] -pub struct EchoRound { +pub struct EchoRound, SP: SessionParameters> { verifier: SP::Verifier, echo_broadcasts: BTreeMap>, echo_round_info: EchoRoundInfo, @@ -84,7 +84,7 @@ pub struct EchoRound { impl EchoRound where - P: Protocol, + P: Protocol, SP: SessionParameters, { pub fn new( @@ -132,7 +132,7 @@ where impl Round for EchoRound where - P: Protocol, + P: Protocol, SP: SessionParameters, { type Protocol = P; diff --git a/manul/src/session/evidence.rs b/manul/src/session/evidence.rs index 36e411e..5315868 100644 --- a/manul/src/session/evidence.rs +++ b/manul/src/session/evidence.rs @@ -76,7 +76,7 @@ impl From for EvidenceError { /// A self-contained evidence of malicious behavior by a node. #[derive_where::derive_where(Debug)] #[derive(Clone, Serialize, Deserialize)] -pub struct Evidence { +pub struct Evidence, SP: SessionParameters> { guilty_party: SP::Verifier, description: String, evidence: EvidenceEnum, @@ -84,7 +84,7 @@ pub struct Evidence { impl Evidence where - P: Protocol, + P: Protocol, SP: SessionParameters, { pub(crate) fn new_protocol_error( @@ -193,10 +193,7 @@ where Self { guilty_party: verifier.clone(), description: error.to_string(), - evidence: EvidenceEnum::InvalidDirectMessage(InvalidDirectMessageEvidence { - direct_message, - phantom: core::marker::PhantomData, - }), + evidence: EvidenceEnum::InvalidDirectMessage(InvalidDirectMessageEvidence(direct_message)), } } @@ -208,10 +205,7 @@ where Self { guilty_party: verifier.clone(), description: error.to_string(), - evidence: EvidenceEnum::InvalidEchoBroadcast(InvalidEchoBroadcastEvidence { - echo_broadcast, - phantom: core::marker::PhantomData, - }), + evidence: EvidenceEnum::InvalidEchoBroadcast(InvalidEchoBroadcastEvidence(echo_broadcast)), } } @@ -223,10 +217,7 @@ where Self { guilty_party: verifier.clone(), description: error.to_string(), - evidence: EvidenceEnum::InvalidNormalBroadcast(InvalidNormalBroadcastEvidence { - normal_broadcast, - phantom: core::marker::PhantomData, - }), + evidence: EvidenceEnum::InvalidNormalBroadcast(InvalidNormalBroadcastEvidence(normal_broadcast)), } } @@ -248,9 +239,11 @@ where let deserializer = Deserializer::new::(); match &self.evidence { EvidenceEnum::Protocol(evidence) => evidence.verify::(&self.guilty_party, &deserializer), - EvidenceEnum::InvalidDirectMessage(evidence) => evidence.verify::(&self.guilty_party, &deserializer), - EvidenceEnum::InvalidEchoBroadcast(evidence) => evidence.verify::(&self.guilty_party, &deserializer), - EvidenceEnum::InvalidNormalBroadcast(evidence) => evidence.verify::(&self.guilty_party, &deserializer), + EvidenceEnum::InvalidDirectMessage(evidence) => evidence.verify::(&self.guilty_party, &deserializer), + EvidenceEnum::InvalidEchoBroadcast(evidence) => evidence.verify::(&self.guilty_party, &deserializer), + EvidenceEnum::InvalidNormalBroadcast(evidence) => { + evidence.verify::(&self.guilty_party, &deserializer) + } EvidenceEnum::InvalidEchoPack(evidence) => evidence.verify(&self.guilty_party, &deserializer), EvidenceEnum::MismatchedBroadcasts(evidence) => evidence.verify::(&self.guilty_party), } @@ -259,11 +252,11 @@ where #[derive_where::derive_where(Debug)] #[derive(Clone, Serialize, Deserialize)] -enum EvidenceEnum { - Protocol(ProtocolEvidence

), - InvalidDirectMessage(InvalidDirectMessageEvidence

), - InvalidEchoBroadcast(InvalidEchoBroadcastEvidence

), - InvalidNormalBroadcast(InvalidNormalBroadcastEvidence

), +enum EvidenceEnum, SP: SessionParameters> { + Protocol(ProtocolEvidence), + InvalidDirectMessage(InvalidDirectMessageEvidence), + InvalidEchoBroadcast(InvalidEchoBroadcastEvidence), + InvalidNormalBroadcast(InvalidNormalBroadcastEvidence), InvalidEchoPack(InvalidEchoPackEvidence), MismatchedBroadcasts(MismatchedBroadcastsEvidence), } @@ -348,85 +341,67 @@ impl MismatchedBroadcastsEvidence { } } -#[derive_where::derive_where(Debug)] -#[derive(Clone, Serialize, Deserialize)] -pub struct InvalidDirectMessageEvidence { - direct_message: SignedMessagePart, - phantom: core::marker::PhantomData

, -} +#[derive(Debug, Clone, Serialize, Deserialize)] +pub struct InvalidDirectMessageEvidence(SignedMessagePart); -impl

InvalidDirectMessageEvidence

-where - P: Protocol, -{ - fn verify(&self, verifier: &SP::Verifier, deserializer: &Deserializer) -> Result<(), EvidenceError> +impl InvalidDirectMessageEvidence { + fn verify(&self, verifier: &SP::Verifier, deserializer: &Deserializer) -> Result<(), EvidenceError> where + P: Protocol, SP: SessionParameters, { - let verified_direct_message = self.direct_message.clone().verify::(verifier)?; + let verified_direct_message = self.0.clone().verify::(verifier)?; let payload = verified_direct_message.payload(); - if self.direct_message.metadata().round_id().is_echo() { + if self.0.metadata().round_id().is_echo() { Ok(EchoRound::::verify_direct_message_is_invalid(payload)?) } else { Ok(P::verify_direct_message_is_invalid( deserializer, - self.direct_message.metadata().round_id(), + self.0.metadata().round_id(), payload, )?) } } } -#[derive_where::derive_where(Debug)] -#[derive(Clone, Serialize, Deserialize)] -pub struct InvalidEchoBroadcastEvidence { - echo_broadcast: SignedMessagePart, - phantom: core::marker::PhantomData

, -} +#[derive(Debug, Clone, Serialize, Deserialize)] +pub struct InvalidEchoBroadcastEvidence(SignedMessagePart); -impl

InvalidEchoBroadcastEvidence

-where - P: Protocol, -{ - fn verify(&self, verifier: &SP::Verifier, deserializer: &Deserializer) -> Result<(), EvidenceError> +impl InvalidEchoBroadcastEvidence { + fn verify(&self, verifier: &SP::Verifier, deserializer: &Deserializer) -> Result<(), EvidenceError> where + P: Protocol, SP: SessionParameters, { - let verified_echo_broadcast = self.echo_broadcast.clone().verify::(verifier)?; + let verified_echo_broadcast = self.0.clone().verify::(verifier)?; let payload = verified_echo_broadcast.payload(); - if self.echo_broadcast.metadata().round_id().is_echo() { + if self.0.metadata().round_id().is_echo() { Ok(EchoRound::::verify_echo_broadcast_is_invalid(payload)?) } else { Ok(P::verify_echo_broadcast_is_invalid( deserializer, - self.echo_broadcast.metadata().round_id(), + self.0.metadata().round_id(), payload, )?) } } } -#[derive_where::derive_where(Debug)] -#[derive(Clone, Serialize, Deserialize)] -pub struct InvalidNormalBroadcastEvidence { - normal_broadcast: SignedMessagePart, - phantom: core::marker::PhantomData

, -} +#[derive(Debug, Clone, Serialize, Deserialize)] +pub struct InvalidNormalBroadcastEvidence(SignedMessagePart); -impl

InvalidNormalBroadcastEvidence

-where - P: Protocol, -{ - fn verify(&self, verifier: &SP::Verifier, deserializer: &Deserializer) -> Result<(), EvidenceError> +impl InvalidNormalBroadcastEvidence { + fn verify(&self, verifier: &SP::Verifier, deserializer: &Deserializer) -> Result<(), EvidenceError> where + P: Protocol, SP: SessionParameters, { - let verified_normal_broadcast = self.normal_broadcast.clone().verify::(verifier)?; + let verified_normal_broadcast = self.0.clone().verify::(verifier)?; let payload = verified_normal_broadcast.payload(); - if self.normal_broadcast.metadata().round_id().is_echo() { + if self.0.metadata().round_id().is_echo() { Ok(EchoRound::::verify_normal_broadcast_is_invalid( deserializer, payload, @@ -434,7 +409,7 @@ where } else { Ok(P::verify_normal_broadcast_is_invalid( deserializer, - self.normal_broadcast.metadata().round_id(), + self.0.metadata().round_id(), payload, )?) } @@ -443,7 +418,7 @@ where #[derive_where::derive_where(Debug)] #[derive(Clone, Serialize, Deserialize)] -struct ProtocolEvidence { +struct ProtocolEvidence> { error: P::ProtocolError, direct_message: SignedMessagePart, echo_broadcast: SignedMessagePart, @@ -454,13 +429,13 @@ struct ProtocolEvidence { combined_echos: SerializableMap>, } -impl

ProtocolEvidence

+impl ProtocolEvidence where - P: Protocol, + P: Protocol, { fn verify(&self, verifier: &SP::Verifier, deserializer: &Deserializer) -> Result<(), EvidenceError> where - SP: SessionParameters, + SP: SessionParameters, { let session_id = self.direct_message.metadata().session_id(); @@ -549,6 +524,7 @@ where Ok(self.error.verify_messages_constitute_error( deserializer, + verifier, session_id.as_ref(), &verified_echo_broadcast, &verified_normal_broadcast, diff --git a/manul/src/session/session.rs b/manul/src/session/session.rs index 9123fca..02b1c3c 100644 --- a/manul/src/session/session.rs +++ b/manul/src/session/session.rs @@ -107,7 +107,7 @@ pub(crate) struct EchoRoundInfo { /// An object encapsulating the currently active round, transport protocol, /// and the database of messages and errors from the previous rounds. #[derive(Debug)] -pub struct Session { +pub struct Session, SP: SessionParameters> { session_id: SessionId, signer: SP::Signer, verifier: SP::Verifier, @@ -124,7 +124,7 @@ pub struct Session { /// Possible non-erroneous results of finalizing a round. #[derive(Debug)] -pub enum RoundOutcome { +pub enum RoundOutcome, SP: SessionParameters> { /// The execution is finished. Finished(SessionReport), /// Transitioned to another round. @@ -138,7 +138,7 @@ pub enum RoundOutcome { impl Session where - P: Protocol, + P: Protocol, SP: SessionParameters, { /// Initializes a new session. @@ -572,7 +572,7 @@ pub enum CanFinalize { /// A mutable accumulator for collecting the results and errors from processing messages for a single round. #[derive_where::derive_where(Debug)] -pub struct RoundAccumulator { +pub struct RoundAccumulator, SP: SessionParameters> { still_have_not_sent_messages: BTreeSet, expecting_messages_from: BTreeSet, processing: BTreeSet, @@ -588,7 +588,7 @@ pub struct RoundAccumulator { impl RoundAccumulator where - P: Protocol, + P: Protocol, SP: SessionParameters, { fn new(expecting_messages_from: &BTreeSet) -> Self { @@ -787,7 +787,7 @@ pub struct ProcessedArtifact { } #[derive(Debug)] -pub struct ProcessedMessage { +pub struct ProcessedMessage, SP: SessionParameters> { message: VerifiedMessage, processed: Result>, } @@ -840,7 +840,7 @@ fn filter_messages( mod tests { use impls::impls; - use super::{Message, ProcessedArtifact, ProcessedMessage, Session, VerifiedMessage}; + use super::{Message, ProcessedArtifact, ProcessedMessage, Session, SessionParameters, VerifiedMessage}; use crate::{ dev::{BinaryFormat, TestSessionParams, TestVerifier}, protocol::Protocol, @@ -856,15 +856,15 @@ mod tests { // Send/Sync. But we want to make sure that if the generic parameters are // Send/Sync, our types are too. + type SP = TestSessionParams; + struct DummyProtocol; - impl Protocol for DummyProtocol { + impl Protocol<::Verifier> for DummyProtocol { type Result = (); type ProtocolError = (); } - type SP = TestSessionParams; - // We need `Session` to be `Send` so that we send a `Session` object to a task // to run the loop there. assert!(impls!(Session: Send)); diff --git a/manul/src/session/transcript.rs b/manul/src/session/transcript.rs index dcd5749..a32971a 100644 --- a/manul/src/session/transcript.rs +++ b/manul/src/session/transcript.rs @@ -10,7 +10,7 @@ use super::{evidence::Evidence, message::SignedMessagePart, session::SessionPara use crate::protocol::{DirectMessage, EchoBroadcast, NormalBroadcast, Protocol, RoundId}; #[derive(Debug)] -pub(crate) struct Transcript { +pub(crate) struct Transcript, SP: SessionParameters> { echo_broadcasts: BTreeMap>>, normal_broadcasts: BTreeMap>>, direct_messages: BTreeMap>>, @@ -21,7 +21,7 @@ pub(crate) struct Transcript { impl Transcript where - P: Protocol, + P: Protocol, SP: SessionParameters, { pub fn new() -> Self { @@ -170,7 +170,7 @@ where /// Possible outcomes of running a session. #[derive(Debug)] -pub enum SessionOutcome { +pub enum SessionOutcome> { /// The protocol successfully produced a result. Result(P::Result), /// The execution stalled because not enough messages were received to finalize the round. @@ -179,9 +179,9 @@ pub enum SessionOutcome { Terminated, } -impl

SessionOutcome

+impl SessionOutcome where - P: Protocol, + P: Protocol, { /// Returns a brief description of the outcome. pub fn brief(&self) -> String { @@ -195,9 +195,9 @@ where /// The report of a session execution. #[derive(Debug)] -pub struct SessionReport { +pub struct SessionReport, SP: SessionParameters> { /// The session outcome. - pub outcome: SessionOutcome

, + pub outcome: SessionOutcome, /// The provable errors collected during the execution, as the evidences that can be published to prove them. pub provable_errors: BTreeMap>, /// The unprovable errors collected during the execution. @@ -208,10 +208,10 @@ pub struct SessionReport { impl SessionReport where - P: Protocol, + P: Protocol, SP: SessionParameters, { - pub(crate) fn new(outcome: SessionOutcome

, transcript: Transcript) -> Self { + pub(crate) fn new(outcome: SessionOutcome, transcript: Transcript) -> Self { Self { outcome, provable_errors: transcript.provable_errors, diff --git a/manul/src/tests/partial_echo.rs b/manul/src/tests/partial_echo.rs index 8dc3af2..53d1560 100644 --- a/manul/src/tests/partial_echo.rs +++ b/manul/src/tests/partial_echo.rs @@ -5,7 +5,7 @@ use alloc::{ vec, vec::Vec, }; -use core::fmt::Debug; +use core::{fmt::Debug, marker::PhantomData}; use rand_core::{CryptoRngCore, OsRng}; use serde::{Deserialize, Serialize}; @@ -21,17 +21,17 @@ use crate::{ }; #[derive(Debug)] -struct PartialEchoProtocol; +struct PartialEchoProtocol(PhantomData); -impl Protocol for PartialEchoProtocol { +impl Protocol for PartialEchoProtocol { type Result = (); - type ProtocolError = PartialEchoProtocolError; + type ProtocolError = PartialEchoProtocolError; } #[derive(Debug, Clone, Serialize, Deserialize)] -struct PartialEchoProtocolError; +struct PartialEchoProtocolError(PhantomData); -impl ProtocolError for PartialEchoProtocolError { +impl ProtocolError for PartialEchoProtocolError { fn description(&self) -> String { format!("{:?}", self) } @@ -39,6 +39,7 @@ impl ProtocolError for PartialEchoProtocolError { fn verify_messages_constitute_error( &self, _deserializer: &Deserializer, + _guilty_party: &Id, _shared_randomness: &[u8], _echo_broadcast: &EchoBroadcast, _normal_broadcast: &NormalBroadcast, @@ -71,7 +72,7 @@ struct Round1Echo { } impl Deserialize<'de>> EntryPoint for Inputs { - type Protocol = PartialEchoProtocol; + type Protocol = PartialEchoProtocol; fn make_round( self, _rng: &mut impl CryptoRngCore, @@ -83,7 +84,7 @@ impl Deserialize<'de>> EntryPoint for Inp } impl Deserialize<'de>> Round for Round1 { - type Protocol = PartialEchoProtocol; + type Protocol = PartialEchoProtocol; fn id(&self) -> RoundId { RoundId::new(1)