From 3ff05d1b570f8591767c70cf8f9361a61b343063 Mon Sep 17 00:00:00 2001 From: Bogdan Opanchuk Date: Sun, 3 Nov 2024 15:38:23 -0800 Subject: [PATCH] Add Misbehaving combinator --- examples/src/simple_malicious.rs | 196 +++++++-------------- manul/src/combinators.rs | 5 + manul/src/combinators/misbehave.rs | 266 +++++++++++++++++++++++++++++ manul/src/lib.rs | 1 + manul/src/protocol.rs | 1 + manul/src/protocol/object_safe.rs | 28 ++- manul/src/session/echo.rs | 2 +- manul/src/session/session.rs | 33 ++-- 8 files changed, 371 insertions(+), 161 deletions(-) create mode 100644 manul/src/combinators.rs create mode 100644 manul/src/combinators/misbehave.rs diff --git a/examples/src/simple_malicious.rs b/examples/src/simple_malicious.rs index 90a4aa9..4fd46cd 100644 --- a/examples/src/simple_malicious.rs +++ b/examples/src/simple_malicious.rs @@ -1,151 +1,75 @@ -use alloc::collections::{BTreeMap, BTreeSet}; +use alloc::collections::BTreeSet; use core::fmt::Debug; use manul::{ + combinators::{Misbehaving, MisbehavingEntryPoint, MisbehavingInputs}, protocol::{ - Artifact, BoxedRound, DirectMessage, EntryPoint, FinalizeError, FinalizeOutcome, LocalError, PartyId, Payload, - ProtocolMessagePart, Round, Serializer, + Artifact, BoxedRound, Deserializer, DirectMessage, EntryPoint, LocalError, PartyId, ProtocolMessagePart, + RoundId, Serializer, }, session::signature::Keypair, - testing::{ - round_override, run_sync, BinaryFormat, RoundOverride, RoundWrapper, TestSessionParams, TestSigner, - TestVerifier, - }, + testing::{run_sync, BinaryFormat, TestSessionParams, TestSigner, TestVerifier}, }; use rand_core::{CryptoRngCore, OsRng}; use tracing_subscriber::EnvFilter; -use crate::simple::{Inputs, Round1, Round1Message, Round2, Round2Message, SimpleProtocol}; +use crate::simple::{Inputs, Round1, Round1Message, Round2, Round2Message}; #[derive(Debug, Clone, Copy)] enum Behavior { - Lawful, SerializedGarbage, AttributableFailure, AttributableFailureRound2, } -struct MaliciousInputs { - inputs: Inputs, - behavior: Behavior, -} - -#[derive(Debug)] -struct MaliciousRound1 { - round: Round1, - behavior: Behavior, -} +struct SimpleMaliciousProtocol; -impl RoundWrapper for MaliciousRound1 { - type InnerRound = Round1; - fn inner_round_ref(&self) -> &Self::InnerRound { - &self.round - } - fn inner_round(self) -> Self::InnerRound { - self.round - } -} +impl Misbehaving for SimpleMaliciousProtocol { + type EntryPoint = Round1; -impl EntryPoint for MaliciousRound1 { - type Inputs = MaliciousInputs; - type Protocol = SimpleProtocol; - fn new( - rng: &mut impl CryptoRngCore, - shared_randomness: &[u8], - id: Id, - inputs: Self::Inputs, - ) -> Result, LocalError> { - let round = Round1::new(rng, shared_randomness, id, inputs.inputs)?.downcast::>()?; - Ok(BoxedRound::new_dynamic(Self { - round, - behavior: inputs.behavior, - })) - } -} - -impl RoundOverride for MaliciousRound1 { - fn make_direct_message( - &self, - rng: &mut impl CryptoRngCore, + fn amend_direct_message( + _rng: &mut impl CryptoRngCore, + round: &BoxedRound>::Protocol>, + behavior: &Behavior, serializer: &Serializer, - destination: &Id, + _deserializer: &Deserializer, + _destination: &Id, + direct_message: DirectMessage, + artifact: Option, ) -> Result<(DirectMessage, Option), LocalError> { - if matches!(self.behavior, Behavior::SerializedGarbage) { - Ok((DirectMessage::new(serializer, [99u8])?, None)) - } 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], - }; - Ok((DirectMessage::new(serializer, message)?, None)) - } else { - self.inner_round_ref().make_direct_message(rng, serializer, destination) - } - } - - fn finalize( - self, - rng: &mut impl CryptoRngCore, - payloads: BTreeMap, - artifacts: BTreeMap, - ) -> Result< - FinalizeOutcome>::InnerRound as Round>::Protocol>, - FinalizeError<<>::InnerRound as Round>::Protocol>, - > { - let behavior = self.behavior; - let outcome = self.inner_round().finalize(rng, payloads, artifacts)?; - - Ok(match outcome { - FinalizeOutcome::Result(res) => FinalizeOutcome::Result(res), - FinalizeOutcome::AnotherRound(boxed_round) => { - let round2 = boxed_round.downcast::>().map_err(FinalizeError::Local)?; - FinalizeOutcome::AnotherRound(BoxedRound::new_dynamic(MaliciousRound2 { - round: round2, - behavior, - })) + let dm = if round.id() == RoundId::new(1) { + match behavior { + Behavior::SerializedGarbage => DirectMessage::new(serializer, [99u8])?, + Behavior::AttributableFailure => { + let round1 = round.downcast_ref::>()?; + let message = Round1Message { + my_position: round1.context.ids_to_positions[&round1.context.id], + your_position: round1.context.ids_to_positions[&round1.context.id], + }; + DirectMessage::new(serializer, message)? + } + _ => direct_message, + } + } else if round.id() == RoundId::new(2) { + match behavior { + Behavior::AttributableFailureRound2 => { + let round2 = round.downcast_ref::>()?; + let message = Round2Message { + my_position: round2.context.ids_to_positions[&round2.context.id], + your_position: round2.context.ids_to_positions[&round2.context.id], + }; + DirectMessage::new(serializer, message)? + } + _ => direct_message, } - }) - } -} - -round_override!(MaliciousRound1); - -#[derive(Debug)] -struct MaliciousRound2 { - round: Round2, - behavior: Behavior, -} - -impl RoundWrapper for MaliciousRound2 { - type InnerRound = Round2; - fn inner_round_ref(&self) -> &Self::InnerRound { - &self.round - } - fn inner_round(self) -> Self::InnerRound { - self.round - } -} - -impl RoundOverride for MaliciousRound2 { - fn make_direct_message( - &self, - rng: &mut impl CryptoRngCore, - serializer: &Serializer, - destination: &Id, - ) -> Result<(DirectMessage, Option), 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], - }; - Ok((DirectMessage::new(serializer, message)?, None)) } else { - self.inner_round_ref().make_direct_message(rng, serializer, destination) - } + direct_message + }; + Ok((dm, artifact)) } } -round_override!(MaliciousRound2); +type MaliciousEntryPoint = MisbehavingEntryPoint; #[test] fn serialized_garbage() { @@ -161,13 +85,13 @@ fn serialized_garbage() { .enumerate() .map(|(idx, signer)| { let behavior = if idx == 0 { - Behavior::SerializedGarbage + Some(Behavior::SerializedGarbage) } else { - Behavior::Lawful + None }; - let malicious_inputs = MaliciousInputs { - inputs: inputs.clone(), + let malicious_inputs = MisbehavingInputs { + inner_inputs: inputs.clone(), behavior, }; (*signer, malicious_inputs) @@ -178,7 +102,7 @@ fn serialized_garbage() { .with_env_filter(EnvFilter::from_default_env()) .finish(); let mut reports = tracing::subscriber::with_default(my_subscriber, || { - run_sync::, TestSessionParams>(&mut OsRng, run_inputs).unwrap() + run_sync::, TestSessionParams>(&mut OsRng, run_inputs).unwrap() }); let v0 = signers[0].verifying_key(); @@ -207,13 +131,13 @@ fn attributable_failure() { .enumerate() .map(|(idx, signer)| { let behavior = if idx == 0 { - Behavior::AttributableFailure + Some(Behavior::AttributableFailure) } else { - Behavior::Lawful + None }; - let malicious_inputs = MaliciousInputs { - inputs: inputs.clone(), + let malicious_inputs = MisbehavingInputs { + inner_inputs: inputs.clone(), behavior, }; (*signer, malicious_inputs) @@ -224,7 +148,7 @@ fn attributable_failure() { .with_env_filter(EnvFilter::from_default_env()) .finish(); let mut reports = tracing::subscriber::with_default(my_subscriber, || { - run_sync::, TestSessionParams>(&mut OsRng, run_inputs).unwrap() + run_sync::, TestSessionParams>(&mut OsRng, run_inputs).unwrap() }); let v0 = signers[0].verifying_key(); @@ -253,13 +177,13 @@ fn attributable_failure_round2() { .enumerate() .map(|(idx, signer)| { let behavior = if idx == 0 { - Behavior::AttributableFailureRound2 + Some(Behavior::AttributableFailureRound2) } else { - Behavior::Lawful + None }; - let malicious_inputs = MaliciousInputs { - inputs: inputs.clone(), + let malicious_inputs = MisbehavingInputs { + inner_inputs: inputs.clone(), behavior, }; (*signer, malicious_inputs) @@ -270,7 +194,7 @@ fn attributable_failure_round2() { .with_env_filter(EnvFilter::from_default_env()) .finish(); let mut reports = tracing::subscriber::with_default(my_subscriber, || { - run_sync::, TestSessionParams>(&mut OsRng, run_inputs).unwrap() + run_sync::, TestSessionParams>(&mut OsRng, run_inputs).unwrap() }); let v0 = signers[0].verifying_key(); diff --git a/manul/src/combinators.rs b/manul/src/combinators.rs new file mode 100644 index 0000000..66d2aba --- /dev/null +++ b/manul/src/combinators.rs @@ -0,0 +1,5 @@ +//! Combinators operating on protocols. + +mod misbehave; + +pub use misbehave::{Behavior, Misbehaving, MisbehavingEntryPoint, MisbehavingInputs}; diff --git a/manul/src/combinators/misbehave.rs b/manul/src/combinators/misbehave.rs new file mode 100644 index 0000000..a298282 --- /dev/null +++ b/manul/src/combinators/misbehave.rs @@ -0,0 +1,266 @@ +use alloc::{ + boxed::Box, + collections::{BTreeMap, BTreeSet}, +}; +use core::fmt::Debug; + +use rand_core::CryptoRngCore; + +use crate::protocol::{ + Artifact, BoxedRng, BoxedRound, Deserializer, DirectMessage, EchoBroadcast, EntryPoint, FinalizeError, + FinalizeOutcome, LocalError, NormalBroadcast, ObjectSafeRound, PartyId, Payload, ReceiveError, RoundId, Serializer, +}; + +/// A trait describing required properties for a behavior type. +pub trait Behavior: 'static + Debug + Send + Sync {} + +impl Behavior for T {} + +/// The new entry point for the misbehaving rounds. +/// +/// Use as an entry point to run the session, with your ID, behavior `B` and the misbehavior definition `M` set. +#[derive_where::derive_where(Debug)] +pub struct MisbehavingEntryPoint +where + Id: PartyId, + B: Behavior, + M: Misbehaving, +{ + round: BoxedRound>::Protocol>, + behavior: Option, +} + +/// A trait defining a sequence of misbehaving rounds amending the messages sent by some existing ones. +/// +/// Override one or more optional methods to amend the specific messages. +pub trait Misbehaving: 'static +where + Id: PartyId, + B: Behavior, +{ + /// The entry point of the wrapped rounds. + type EntryPoint: EntryPoint; + + /// Called after [`Round::make_echo_broadcast`] and may amend its result. + /// + /// The default implementation passes through the original message. + #[allow(unused_variables)] + fn amend_echo_broadcast( + rng: &mut impl CryptoRngCore, + round: &BoxedRound>::Protocol>, + behavior: &B, + serializer: &Serializer, + deserializer: &Deserializer, + echo_broadcast: EchoBroadcast, + ) -> Result { + Ok(echo_broadcast) + } + + /// Called after [`Round::make_normal_broadcast`] and may amend its result. + /// + /// The default implementation passes through the original message. + #[allow(unused_variables)] + fn amend_normal_broadcast( + rng: &mut impl CryptoRngCore, + round: &BoxedRound>::Protocol>, + behavior: &B, + serializer: &Serializer, + deserializer: &Deserializer, + normal_broadcast: NormalBroadcast, + ) -> Result { + Ok(normal_broadcast) + } + + /// Called after [`Round::make_direct_message`] and may amend its result. + /// + /// The default implementation passes through the original message. + #[allow(unused_variables, clippy::too_many_arguments)] + fn amend_direct_message( + rng: &mut impl CryptoRngCore, + round: &BoxedRound>::Protocol>, + behavior: &B, + serializer: &Serializer, + deserializer: &Deserializer, + destination: &Id, + direct_message: DirectMessage, + artifact: Option, + ) -> Result<(DirectMessage, Option), LocalError> { + Ok((direct_message, artifact)) + } +} + +/// The inputs for the amended rounds. +#[derive_where::derive_where(Debug; >::Inputs)] +pub struct MisbehavingInputs +where + Id: PartyId, + B: Behavior, + M: Misbehaving, +{ + /// The behavior for the rounds starting with these inputs. + /// + /// If `None`, all the amended behavior will be skipped. + pub behavior: Option, + /// The inputs for the wrapped rounds. + pub inner_inputs: >::Inputs, +} + +impl EntryPoint for MisbehavingEntryPoint +where + Id: PartyId, + B: Behavior, + M: Misbehaving, +{ + type Inputs = MisbehavingInputs; + type Protocol = >::Protocol; + + fn new( + rng: &mut impl CryptoRngCore, + shared_randomness: &[u8], + id: Id, + inputs: Self::Inputs, + ) -> Result>::Protocol>, LocalError> { + let round = M::EntryPoint::new(rng, shared_randomness, id, inputs.inner_inputs)?; + Ok(BoxedRound::new_object_safe(Self { + round, + behavior: inputs.behavior, + })) + } +} + +impl ObjectSafeRound for MisbehavingEntryPoint +where + Id: PartyId, + B: Behavior, + M: Misbehaving, +{ + type Protocol = >::Protocol; + + fn id(&self) -> RoundId { + self.round.as_ref().id() + } + + fn possible_next_rounds(&self) -> BTreeSet { + self.round.as_ref().possible_next_rounds() + } + + fn message_destinations(&self) -> &BTreeSet { + self.round.as_ref().message_destinations() + } + + fn make_direct_message( + &self, + rng: &mut dyn CryptoRngCore, + serializer: &Serializer, + deserializer: &Deserializer, + destination: &Id, + ) -> Result<(DirectMessage, Option), LocalError> { + let (direct_message, artifact) = + self.round + .as_ref() + .make_direct_message(rng, serializer, deserializer, destination)?; + if let Some(behavior) = self.behavior.as_ref() { + let mut boxed_rng = BoxedRng(rng); + M::amend_direct_message( + &mut boxed_rng, + &self.round, + behavior, + serializer, + deserializer, + destination, + direct_message, + artifact, + ) + } else { + Ok((direct_message, artifact)) + } + } + + fn make_echo_broadcast( + &self, + rng: &mut dyn CryptoRngCore, + serializer: &Serializer, + deserializer: &Deserializer, + ) -> Result { + let echo_broadcast = self.round.as_ref().make_echo_broadcast(rng, serializer, deserializer)?; + if let Some(behavior) = self.behavior.as_ref() { + let mut boxed_rng = BoxedRng(rng); + M::amend_echo_broadcast( + &mut boxed_rng, + &self.round, + behavior, + serializer, + deserializer, + echo_broadcast, + ) + } else { + Ok(echo_broadcast) + } + } + + fn make_normal_broadcast( + &self, + rng: &mut dyn CryptoRngCore, + serializer: &Serializer, + deserializer: &Deserializer, + ) -> Result { + let normal_broadcast = self + .round + .as_ref() + .make_normal_broadcast(rng, serializer, deserializer)?; + if let Some(behavior) = self.behavior.as_ref() { + let mut boxed_rng = BoxedRng(rng); + M::amend_normal_broadcast( + &mut boxed_rng, + &self.round, + behavior, + serializer, + deserializer, + normal_broadcast, + ) + } else { + Ok(normal_broadcast) + } + } + + fn receive_message( + &self, + rng: &mut dyn CryptoRngCore, + deserializer: &Deserializer, + from: &Id, + echo_broadcast: EchoBroadcast, + normal_broadcast: NormalBroadcast, + direct_message: DirectMessage, + ) -> Result> { + self.round.as_ref().receive_message( + rng, + deserializer, + from, + echo_broadcast, + normal_broadcast, + direct_message, + ) + } + + fn finalize( + self: Box, + rng: &mut dyn CryptoRngCore, + payloads: BTreeMap, + artifacts: BTreeMap, + ) -> Result, FinalizeError> { + match self.round.into_boxed().finalize(rng, payloads, artifacts) { + Ok(FinalizeOutcome::Result(result)) => Ok(FinalizeOutcome::Result(result)), + Ok(FinalizeOutcome::AnotherRound(round)) => Ok(FinalizeOutcome::AnotherRound(BoxedRound::new_object_safe( + MisbehavingEntryPoint:: { + round, + behavior: self.behavior, + }, + ))), + Err(err) => Err(err), + } + } + + fn expecting_messages_from(&self) -> &BTreeSet { + self.round.as_ref().expecting_messages_from() + } +} diff --git a/manul/src/lib.rs b/manul/src/lib.rs index 8d3323f..ad55b47 100644 --- a/manul/src/lib.rs +++ b/manul/src/lib.rs @@ -16,6 +16,7 @@ extern crate alloc; +pub mod combinators; pub mod protocol; pub mod session; pub(crate) mod utils; diff --git a/manul/src/protocol.rs b/manul/src/protocol.rs index f1b063f..46b356f 100644 --- a/manul/src/protocol.rs +++ b/manul/src/protocol.rs @@ -29,5 +29,6 @@ pub use round::{ pub use serialization::{Deserializer, Serializer}; pub(crate) use errors::ReceiveErrorType; +pub(crate) use object_safe::{BoxedRng, ObjectSafeRound}; pub use digest; diff --git a/manul/src/protocol/object_safe.rs b/manul/src/protocol/object_safe.rs index af0c644..27e2785 100644 --- a/manul/src/protocol/object_safe.rs +++ b/manul/src/protocol/object_safe.rs @@ -17,7 +17,7 @@ use super::{ /// Since object-safe trait methods cannot take `impl CryptoRngCore` arguments, /// this structure wraps the dynamic object and exposes a `CryptoRngCore` interface, /// to be passed to statically typed round methods. -struct BoxedRng<'a>(&'a mut dyn CryptoRngCore); +pub(crate) struct BoxedRng<'a>(pub(crate) &'a mut dyn CryptoRngCore); impl CryptoRng for BoxedRng<'_> {} @@ -52,6 +52,7 @@ pub(crate) trait ObjectSafeRound: 'static + Debug + Send + Sync { &self, rng: &mut dyn CryptoRngCore, serializer: &Serializer, + deserializer: &Deserializer, destination: &Id, ) -> Result<(DirectMessage, Option), LocalError>; @@ -59,12 +60,14 @@ pub(crate) trait ObjectSafeRound: 'static + Debug + Send + Sync { &self, rng: &mut dyn CryptoRngCore, serializer: &Serializer, + deserializer: &Deserializer, ) -> Result; fn make_normal_broadcast( &self, rng: &mut dyn CryptoRngCore, serializer: &Serializer, + deserializer: &Deserializer, ) -> Result; fn receive_message( @@ -87,7 +90,9 @@ pub(crate) trait ObjectSafeRound: 'static + Debug + Send + Sync { fn expecting_messages_from(&self) -> &BTreeSet; /// Returns the type ID of the implementing type. - fn get_type_id(&self) -> core::any::TypeId; + fn get_type_id(&self) -> core::any::TypeId { + core::any::TypeId::of::() + } } // The `fn(Id) -> Id` bit is so that `ObjectSafeRoundWrapper` didn't require a bound on `Id` to be @@ -134,6 +139,7 @@ where &self, rng: &mut dyn CryptoRngCore, serializer: &Serializer, + #[allow(unused_variables)] deserializer: &Deserializer, destination: &Id, ) -> Result<(DirectMessage, Option), LocalError> { let mut boxed_rng = BoxedRng(rng); @@ -144,6 +150,7 @@ where &self, rng: &mut dyn CryptoRngCore, serializer: &Serializer, + #[allow(unused_variables)] deserializer: &Deserializer, ) -> Result { let mut boxed_rng = BoxedRng(rng); self.round.make_echo_broadcast(&mut boxed_rng, serializer) @@ -153,6 +160,7 @@ where &self, rng: &mut dyn CryptoRngCore, serializer: &Serializer, + #[allow(unused_variables)] deserializer: &Deserializer, ) -> Result { let mut boxed_rng = BoxedRng(rng); self.round.make_normal_broadcast(&mut boxed_rng, serializer) @@ -191,10 +199,6 @@ where fn expecting_messages_from(&self) -> &BTreeSet { self.round.expecting_messages_from() } - - fn get_type_id(&self) -> core::any::TypeId { - core::any::TypeId::of::() - } } // We do not want to expose `ObjectSafeRound` to the user, so it is hidden in a struct. @@ -215,6 +219,13 @@ impl BoxedRound { } } + pub(crate) fn new_object_safe>(round: R) -> Self { + Self { + wrapped: false, + round: Box::new(round), + } + } + pub(crate) fn as_ref(&self) -> &dyn ObjectSafeRound { self.round.as_ref() } @@ -265,4 +276,9 @@ impl BoxedRound { ))) } } + + /// Returns the round's ID. + pub fn id(&self) -> RoundId { + self.round.id() + } } diff --git a/manul/src/session/echo.rs b/manul/src/session/echo.rs index 936df48..c4fbcb9 100644 --- a/manul/src/session/echo.rs +++ b/manul/src/session/echo.rs @@ -146,7 +146,7 @@ where type Protocol = P; fn id(&self) -> RoundId { - self.main_round.as_ref().id().echo() + self.main_round.id().echo() } fn possible_next_rounds(&self) -> BTreeSet { diff --git a/manul/src/session/session.rs b/manul/src/session/session.rs index c556344..ad33fc3 100644 --- a/manul/src/session/session.rs +++ b/manul/src/session/session.rs @@ -169,18 +169,18 @@ where ) -> Result { let verifier = signer.verifying_key(); - let echo = round.as_ref().make_echo_broadcast(rng, &serializer)?; - let echo_broadcast = SignedMessagePart::new::(rng, &signer, &session_id, round.as_ref().id(), echo)?; + let echo = round.as_ref().make_echo_broadcast(rng, &serializer, &deserializer)?; + let echo_broadcast = SignedMessagePart::new::(rng, &signer, &session_id, round.id(), echo)?; - let normal = round.as_ref().make_normal_broadcast(rng, &serializer)?; - let normal_broadcast = SignedMessagePart::new::(rng, &signer, &session_id, round.as_ref().id(), normal)?; + let normal = round.as_ref().make_normal_broadcast(rng, &serializer, &deserializer)?; + let normal_broadcast = SignedMessagePart::new::(rng, &signer, &session_id, round.id(), normal)?; let message_destinations = round.as_ref().message_destinations().clone(); let possible_next_rounds = if echo_broadcast.payload().is_none() { round.as_ref().possible_next_rounds() } else { - BTreeSet::from([round.as_ref().id().echo()]) + BTreeSet::from([round.id().echo()]) }; Ok(Self { @@ -221,16 +221,16 @@ where rng: &mut impl CryptoRngCore, destination: &SP::Verifier, ) -> Result<(Message, ProcessedArtifact), LocalError> { - let (direct_message, artifact) = self - .round - .as_ref() - .make_direct_message(rng, &self.serializer, destination)?; + let (direct_message, artifact) = + self.round + .as_ref() + .make_direct_message(rng, &self.serializer, &self.deserializer, destination)?; let message = Message::new::( rng, &self.signer, &self.session_id, - self.round.as_ref().id(), + self.round.id(), destination, direct_message, self.echo_broadcast.clone(), @@ -256,7 +256,7 @@ where /// Returns the ID of the current round. pub fn round_id(&self) -> RoundId { - self.round.as_ref().id() + self.round.id() } /// Performs some preliminary checks on the message to verify its integrity. @@ -466,7 +466,7 @@ where accum.payloads, accum.artifacts, )); - let cached_messages = filter_messages(accum.cached, round.as_ref().id()); + let cached_messages = filter_messages(accum.cached, round.id()); let session = Session::new_for_next_round( rng, self.session_id, @@ -489,18 +489,15 @@ where } FinalizeOutcome::AnotherRound(round) => { // Protecting against common bugs - if !self.possible_next_rounds.contains(&round.as_ref().id()) { - return Err(LocalError::new(format!( - "Unexpected next round id: {:?}", - round.as_ref().id() - ))); + if !self.possible_next_rounds.contains(&round.id()) { + return Err(LocalError::new(format!("Unexpected next round id: {:?}", round.id()))); } // These messages could have been cached before // processing messages from the same node for the current round. // So there might have been some new errors, and we need to check again // if the sender is already banned. - let cached_messages = filter_messages(accum.cached, round.as_ref().id()) + let cached_messages = filter_messages(accum.cached, round.id()) .into_iter() .filter(|message| !transcript.is_banned(message.from())) .collect::>();