Skip to content

Commit

Permalink
Temporary commit
Browse files Browse the repository at this point in the history
  • Loading branch information
fjarri committed Oct 25, 2024
1 parent 21deb86 commit 0933c50
Show file tree
Hide file tree
Showing 14 changed files with 278 additions and 189 deletions.
26 changes: 13 additions & 13 deletions examples/src/simple.rs
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ impl ProtocolError for SimpleProtocolError {

fn verify_messages_constitute_error(
&self,
_echo_broadcast: &Option<EchoBroadcast>,
_echo_broadcast: &EchoBroadcast,
direct_message: &DirectMessage,
_echo_broadcasts: &BTreeMap<RoundId, EchoBroadcast>,
_direct_messages: &BTreeMap<RoundId, DirectMessage>,
Expand Down Expand Up @@ -171,41 +171,41 @@ impl<Id: 'static + Debug + Clone + Ord + Send + Sync> Round<Id> for Round1<Id> {
&self.context.other_ids
}

fn make_echo_broadcast(&self, _rng: &mut impl CryptoRngCore) -> Option<Result<EchoBroadcast, LocalError>> {
fn make_echo_broadcast(&self, _rng: &mut impl CryptoRngCore) -> Result<EchoBroadcast, LocalError> {
debug!("{:?}: making echo broadcast", self.context.id);

let message = Round1Echo {
my_position: self.context.ids_to_positions[&self.context.id],
};

Some(Self::serialize_echo_broadcast(message))
Self::serialize_echo_broadcast(message)
}

fn make_direct_message(
&self,
_rng: &mut impl CryptoRngCore,
destination: &Id,
) -> Result<(DirectMessage, Artifact), LocalError> {
) -> Result<DirectMessage, LocalError> {
debug!("{:?}: making direct message for {:?}", self.context.id, destination);

let message = Round1Message {
my_position: self.context.ids_to_positions[&self.context.id],
your_position: self.context.ids_to_positions[destination],
};
let dm = Self::serialize_direct_message(message)?;
let artifact = Artifact::empty();
Ok((dm, artifact))
Ok(dm)
}

fn receive_message(
&self,
_rng: &mut impl CryptoRngCore,
from: &Id,
_echo_broadcast: Option<EchoBroadcast>,
echo_broadcast: EchoBroadcast,
direct_message: DirectMessage,
) -> Result<Payload, ReceiveError<Id, Self::Protocol>> {
debug!("{:?}: receiving message from {:?}", self.context.id, from);

let _echo = echo_broadcast.deserialize::<SimpleProtocol, Round1Echo>()?;
let message = direct_message.deserialize::<SimpleProtocol, Round1Message>()?;

debug!("{:?}: received message: {:?}", self.context.id, message);
Expand Down Expand Up @@ -275,41 +275,41 @@ impl<Id: 'static + Debug + Clone + Ord + Send + Sync> Round<Id> for Round2<Id> {
&self.context.other_ids
}

fn make_echo_broadcast(&self, _rng: &mut impl CryptoRngCore) -> Option<Result<EchoBroadcast, LocalError>> {
fn make_echo_broadcast(&self, _rng: &mut impl CryptoRngCore) -> Result<EchoBroadcast, LocalError> {
debug!("{:?}: making echo broadcast", self.context.id);

let message = Round1Echo {
my_position: self.context.ids_to_positions[&self.context.id],
};

Some(Self::serialize_echo_broadcast(message))
Self::serialize_echo_broadcast(message)
}

fn make_direct_message(
&self,
_rng: &mut impl CryptoRngCore,
destination: &Id,
) -> Result<(DirectMessage, Artifact), LocalError> {
) -> Result<DirectMessage, LocalError> {
debug!("{:?}: making direct message for {:?}", self.context.id, destination);

let message = Round1Message {
my_position: self.context.ids_to_positions[&self.context.id],
your_position: self.context.ids_to_positions[destination],
};
let dm = Self::serialize_direct_message(message)?;
let artifact = Artifact::empty();
Ok((dm, artifact))
Ok(dm)
}

fn receive_message(
&self,
_rng: &mut impl CryptoRngCore,
from: &Id,
_echo_broadcast: Option<EchoBroadcast>,
echo_broadcast: EchoBroadcast,
direct_message: DirectMessage,
) -> Result<Payload, ReceiveError<Id, Self::Protocol>> {
debug!("{:?}: receiving message from {:?}", self.context.id, from);

let _echo = echo_broadcast.deserialize::<SimpleProtocol, Round1Echo>()?;
let message = direct_message.deserialize::<SimpleProtocol, Round1Message>()?;

debug!("{:?}: received message: {:?}", self.context.id, message);
Expand Down
18 changes: 5 additions & 13 deletions examples/src/simple_malicious.rs
Original file line number Diff line number Diff line change
Expand Up @@ -57,21 +57,17 @@ impl<Id: 'static + Debug + Clone + Ord + Send + Sync> FirstRound<Id> for Malicio
}

impl<Id: 'static + Debug + Clone + Ord + Send + Sync> RoundOverride<Id> for MaliciousRound1<Id> {
fn make_direct_message(
&self,
rng: &mut impl CryptoRngCore,
destination: &Id,
) -> Result<(DirectMessage, Artifact), LocalError> {
fn make_direct_message(&self, rng: &mut impl CryptoRngCore, destination: &Id) -> Result<DirectMessage, LocalError> {
if matches!(self.behavior, Behavior::SerializedGarbage) {
let dm = DirectMessage::new::<<Self::InnerRound as Round<Id>>::Protocol, _>(&[99u8]).unwrap();
Ok((dm, Artifact::empty()))
Ok(dm)
} else if matches!(self.behavior, Behavior::AttributableFailure) {
let message = Round1Message {
my_position: self.round.context.ids_to_positions[&self.round.context.id],
your_position: self.round.context.ids_to_positions[&self.round.context.id],
};
let dm = DirectMessage::new::<<Self::InnerRound as Round<Id>>::Protocol, _>(&message)?;
Ok((dm, Artifact::empty()))
Ok(dm)
} else {
self.inner_round_ref().make_direct_message(rng, destination)
}
Expand Down Expand Up @@ -121,18 +117,14 @@ impl<Id: 'static + Debug + Clone + Ord + Send + Sync> RoundWrapper<Id> for Malic
}

impl<Id: 'static + Debug + Clone + Ord + Send + Sync> RoundOverride<Id> for MaliciousRound2<Id> {
fn make_direct_message(
&self,
rng: &mut impl CryptoRngCore,
destination: &Id,
) -> Result<(DirectMessage, Artifact), LocalError> {
fn make_direct_message(&self, rng: &mut impl CryptoRngCore, destination: &Id) -> Result<DirectMessage, LocalError> {
if matches!(self.behavior, Behavior::AttributableFailureRound2) {
let message = Round2Message {
my_position: self.round.context.ids_to_positions[&self.round.context.id],
your_position: self.round.context.ids_to_positions[&self.round.context.id],
};
let dm = DirectMessage::new::<<Self::InnerRound as Round<Id>>::Protocol, _>(&message)?;
Ok((dm, Artifact::empty()))
Ok(dm)
} else {
self.inner_round_ref().make_direct_message(rng, destination)
}
Expand Down
24 changes: 13 additions & 11 deletions manul/benches/empty_rounds.rs
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ pub struct EmptyProtocolError;
impl ProtocolError for EmptyProtocolError {
fn verify_messages_constitute_error(
&self,
_echo_broadcast: &Option<EchoBroadcast>,
_echo_broadcast: &EchoBroadcast,
_direct_message: &DirectMessage,
_echo_broadcasts: &BTreeMap<RoundId, EchoBroadcast>,
_direct_messages: &BTreeMap<RoundId, DirectMessage>,
Expand Down Expand Up @@ -108,34 +108,36 @@ impl<Id: 'static + Debug + Clone + Ord + Send + Sync> Round<Id> for EmptyRound<I
&self.inputs.other_ids
}

fn make_echo_broadcast(&self, _rng: &mut impl CryptoRngCore) -> Option<Result<EchoBroadcast, LocalError>> {
fn make_echo_broadcast(&self, _rng: &mut impl CryptoRngCore) -> Result<EchoBroadcast, LocalError> {
if self.inputs.echo {
Some(Self::serialize_echo_broadcast(Round1EchoBroadcast))
Self::serialize_echo_broadcast(Round1EchoBroadcast)
} else {
None
Ok(EchoBroadcast::none())
}
}

fn make_direct_message(
fn make_direct_message_with_artifact(
&self,
_rng: &mut impl CryptoRngCore,
_destination: &Id,
) -> Result<(DirectMessage, Artifact), LocalError> {
) -> Result<(DirectMessage, Option<Artifact>), LocalError> {
let dm = Self::serialize_direct_message(Round1DirectMessage)?;
let artifact = Artifact::new(Round1Artifact);
Ok((dm, artifact))
Ok((dm, Some(artifact)))
}

fn receive_message(
&self,
_rng: &mut impl CryptoRngCore,
_from: &Id,
echo_broadcast: Option<EchoBroadcast>,
echo_broadcast: EchoBroadcast,
direct_message: DirectMessage,
) -> Result<Payload, ReceiveError<Id, Self::Protocol>> {
let _echo_broadcast = echo_broadcast
.map(|echo| echo.deserialize::<EmptyProtocol, Round1EchoBroadcast>())
.transpose()?;
if self.inputs.echo {
let _echo_broadcast = echo_broadcast.deserialize::<EmptyProtocol, Round1EchoBroadcast>()?;
} else {
echo_broadcast.assert_is_none()?;
}
let _direct_message = direct_message.deserialize::<EmptyProtocol, Round1DirectMessage>()?;
Ok(Payload::new(Round1Payload))
}
Expand Down
2 changes: 1 addition & 1 deletion manul/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
clippy::mod_module_files,
clippy::unwrap_used,
clippy::indexing_slicing,
missing_docs,
//missing_docs,
missing_copy_implementations,
rust_2018_idioms,
trivial_casts,
Expand Down
5 changes: 3 additions & 2 deletions manul/src/protocol.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,16 +12,17 @@ For more details, see the documentation of the mentioned traits.
*/

mod errors;
mod message;
mod object_safe;
mod round;

pub use errors::{
DeserializationError, DirectMessageError, EchoBroadcastError, FinalizeError, LocalError, MessageValidationError,
ProtocolValidationError, ReceiveError, RemoteError,
};
pub use message::{DirectMessage, EchoBroadcast};
pub use round::{
AnotherRound, Artifact, DirectMessage, EchoBroadcast, FinalizeOutcome, FirstRound, Payload, Protocol,
ProtocolError, Round, RoundId,
AnotherRound, Artifact, FinalizeOutcome, FirstRound, Payload, Protocol, ProtocolError, Round, RoundId,
};

pub(crate) use errors::ReceiveErrorType;
Expand Down
16 changes: 14 additions & 2 deletions manul/src/protocol/errors.rs
Original file line number Diff line number Diff line change
Expand Up @@ -193,7 +193,13 @@ impl From<LocalError> for ProtocolValidationError {
pub struct DirectMessageError(DeserializationError);

impl DirectMessageError {
pub(crate) fn new(error: DeserializationError) -> Self {
pub(crate) fn new(message: impl Into<String>) -> Self {
Self(DeserializationError::new(message))
}
}

impl From<DeserializationError> for DirectMessageError {
fn from(error: DeserializationError) -> Self {
Self(error)
}
}
Expand All @@ -204,7 +210,13 @@ impl DirectMessageError {
pub struct EchoBroadcastError(DeserializationError);

impl EchoBroadcastError {
pub(crate) fn new(error: DeserializationError) -> Self {
pub(crate) fn new(message: impl Into<String>) -> Self {
Self(DeserializationError::new(message))
}
}

impl From<DeserializationError> for EchoBroadcastError {
fn from(error: DeserializationError) -> Self {
Self(error)
}
}
113 changes: 113 additions & 0 deletions manul/src/protocol/message.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,113 @@
use alloc::boxed::Box;

use serde::{Deserialize, Serialize};
use serde_encoded_bytes::{Base64, SliceLike};

use super::{
errors::{DirectMessageError, EchoBroadcastError, LocalError, MessageValidationError},
round::Protocol,
};

/// A serialized direct message.
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct DirectMessagePayload(#[serde(with = "SliceLike::<Base64>")] Box<[u8]>);

#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct DirectMessage(Option<DirectMessagePayload>);

impl DirectMessage {
pub fn none() -> Self {
Self(None)
}

/// Creates a new serialized direct message.
pub fn new<P: Protocol, T: Serialize>(message: T) -> Result<Self, LocalError> {
Ok(Self(Some(DirectMessagePayload(P::serialize(message)?))))
}

pub(crate) fn is_none(&self) -> bool {
self.0.is_none()
}

pub fn assert_is_none(&self) -> Result<(), DirectMessageError> {
if self.is_none() {
Ok(())
} else {
Err(DirectMessageError::new("The expected direct message is missing"))
}
}

/// Returns `Ok(())` if the message cannot be deserialized into `T`.
///
/// This is intended to be used in the implementations of [`Protocol::verify_direct_message_is_invalid`].
pub fn verify_is_invalid<P: Protocol, T: for<'de> Deserialize<'de>>(&self) -> Result<(), MessageValidationError> {
if self.deserialize::<P, T>().is_err() {
Ok(())
} else {
Err(MessageValidationError::InvalidEvidence(
"Message deserialized successfully".into(),
))
}
}

/// Deserializes the direct message.
pub fn deserialize<P: Protocol, T: for<'de> Deserialize<'de>>(&self) -> Result<T, DirectMessageError> {
let payload = self
.0
.as_ref()
.ok_or_else(|| DirectMessageError::new("The direct message is missing in the payload"))?;
P::deserialize(&payload.0).map_err(DirectMessageError::from)
}
}

/// A serialized echo broadcast.
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
pub struct EchoBroadcastPayload(#[serde(with = "SliceLike::<Base64>")] Box<[u8]>);

#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
pub struct EchoBroadcast(Option<EchoBroadcastPayload>);

impl EchoBroadcast {
pub fn none() -> Self {
Self(None)
}

/// Creates a new serialized echo broadcast.
pub fn new<P: Protocol, T: Serialize>(message: T) -> Result<Self, LocalError> {
Ok(Self(Some(EchoBroadcastPayload(P::serialize(message)?))))
}

pub(crate) fn is_none(&self) -> bool {
self.0.is_none()
}

pub fn assert_is_none(&self) -> Result<(), EchoBroadcastError> {
if self.is_none() {
Ok(())
} else {
Err(EchoBroadcastError::new("The expected echo broadcast is missing"))
}
}

/// Returns `Ok(())` if the message cannot be deserialized into `T`.
///
/// This is intended to be used in the implementations of [`Protocol::verify_direct_message_is_invalid`].
pub fn verify_is_invalid<P: Protocol, T: for<'de> Deserialize<'de>>(&self) -> Result<(), MessageValidationError> {
if self.deserialize::<P, T>().is_err() {
Ok(())
} else {
Err(MessageValidationError::InvalidEvidence(
"Message deserialized successfully".into(),
))
}
}

/// Deserializes the echo broadcast.
pub fn deserialize<P: Protocol, T: for<'de> Deserialize<'de>>(&self) -> Result<T, EchoBroadcastError> {
let payload = self
.0
.as_ref()
.ok_or_else(|| EchoBroadcastError::new("The direct message is missing in the payload"))?;
P::deserialize(&payload.0).map_err(EchoBroadcastError::from)
}
}
Loading

0 comments on commit 0933c50

Please sign in to comment.