diff --git a/src/net/agency.rs b/src/net/agency.rs index bfc85d8..37bc61c 100644 --- a/src/net/agency.rs +++ b/src/net/agency.rs @@ -28,7 +28,7 @@ use futures::Future; use itertools::Itertools; pub trait Broadcast { - type Error: Error + Send + 'static; + type BroadcastError: Error + Send + 'static; // type Error: Error + 'static; /// Broadcast a message to all other parties. @@ -38,7 +38,7 @@ pub trait Broadcast { fn broadcast( &mut self, msg: &(impl serde::Serialize + Sync), - ) -> impl std::future::Future>; + ) -> impl std::future::Future>; /// Broadcast a message to all parties and await their messages /// Messages are ordered by their index. @@ -50,7 +50,7 @@ pub trait Broadcast { fn symmetric_broadcast( &mut self, msg: T, - ) -> impl Future, Self::Error>> + ) -> impl Future, Self::BroadcastError>> where T: serde::Serialize + serde::de::DeserializeOwned + Sync; @@ -60,7 +60,7 @@ pub trait Broadcast { fn recv_from( &mut self, idx: usize, - ) -> impl Future>; + ) -> impl Future>; /// Size of the broadcasting network including yourself, /// as such there is n-1 outgoing connections @@ -68,19 +68,19 @@ pub trait Broadcast { } impl<'a, B: Broadcast> Broadcast for &'a mut B { - type Error = B::Error; + type BroadcastError = B::BroadcastError; fn broadcast( &mut self, msg: &(impl serde::Serialize + Sync), - ) -> impl std::future::Future> { + ) -> impl std::future::Future> { (**self).broadcast(msg) } fn symmetric_broadcast( &mut self, msg: T, - ) -> impl Future, Self::Error>> + ) -> impl Future, Self::BroadcastError>> where T: serde::Serialize + serde::de::DeserializeOwned + Sync { (**self).symmetric_broadcast(msg) @@ -89,7 +89,7 @@ impl<'a, B: Broadcast> Broadcast for &'a mut B { fn recv_from( &mut self, idx: usize, - ) -> impl Future> { + ) -> impl Future> { (**self).recv_from(idx) } @@ -100,7 +100,7 @@ impl<'a, B: Broadcast> Broadcast for &'a mut B { // TODO: Possible rename this trait as it's name is confusing. pub trait Unicast { - type Error: Error + Send + 'static; + type UnicastError: Error + Send + 'static; /// Unicast messages to each party /// @@ -113,7 +113,7 @@ pub trait Unicast { fn unicast( &mut self, msgs: &[impl serde::Serialize + Sync], - ) -> impl std::future::Future>; + ) -> impl std::future::Future>; /// Unicast a message to each party and await their messages /// Messages are supposed to be in order, meaning message `i` @@ -123,7 +123,7 @@ pub trait Unicast { fn symmetric_unicast( &mut self, msgs: Vec, - ) -> impl Future, Self::Error>> + ) -> impl Future, Self::UnicastError>> where T: serde::Serialize + serde::de::DeserializeOwned + Sync; @@ -134,7 +134,7 @@ pub trait Unicast { /// Returns: A list sorted by the connections (skipping yourself) fn receive_all( &mut self, - ) -> impl Future, Self::Error>>; + ) -> impl Future, Self::UnicastError>>; /// Size of the unicasting network including yourself, /// as such there is n-1 outgoing connections @@ -142,7 +142,7 @@ pub trait Unicast { } impl<'a, U: Unicast> Unicast for &'a mut U { - type Error = U::Error; + type UnicastError = U::UnicastError; fn size(&self) -> usize { (**self).size() @@ -150,21 +150,21 @@ impl<'a, U: Unicast> Unicast for &'a mut U { fn receive_all( &mut self, - ) -> impl Future, Self::Error>> { + ) -> impl Future, Self::UnicastError>> { (**self).receive_all() } fn unicast( &mut self, msgs: &[impl serde::Serialize + Sync], - ) -> impl std::future::Future> { + ) -> impl std::future::Future> { (**self).unicast(msgs) } fn symmetric_unicast( &mut self, msgs: Vec, - ) -> impl Future, Self::Error>> + ) -> impl Future, Self::UnicastError>> where T: serde::Serialize + serde::de::DeserializeOwned + Sync { (**self).symmetric_unicast(msgs) @@ -189,7 +189,7 @@ impl VerifiedBroadcast { pub async fn symmetric_broadcast( &mut self, msg: T, - ) -> Result, BroadcastVerificationError> + ) -> Result, BroadcastVerificationError> where T: serde::Serialize + serde::de::DeserializeOwned, { @@ -261,7 +261,7 @@ impl VerifiedBroadcast { pub async fn broadcast( &mut self, msg: &T, - ) -> Result<(), BroadcastVerificationError> + ) -> Result<(), BroadcastVerificationError> where T: serde::Serialize, { @@ -291,7 +291,7 @@ impl VerifiedBroadcast { pub async fn recv_from( &mut self, party: usize, - ) -> Result> + ) -> Result> where T: serde::de::DeserializeOwned, { @@ -352,13 +352,13 @@ pub enum BroadcastVerificationError { } impl Broadcast for VerifiedBroadcast { - type Error = BroadcastVerificationError<::Error>; + type BroadcastError = BroadcastVerificationError<::BroadcastError>; - async fn broadcast(&mut self, msg: &impl serde::Serialize) -> Result<(), Self::Error> { + async fn broadcast(&mut self, msg: &impl serde::Serialize) -> Result<(), Self::BroadcastError> { self.broadcast(msg).await } - async fn symmetric_broadcast(&mut self, msg: T) -> Result, Self::Error> + async fn symmetric_broadcast(&mut self, msg: T) -> Result, Self::BroadcastError> where T: serde::Serialize + serde::de::DeserializeOwned, { @@ -368,7 +368,7 @@ impl Broadcast for VerifiedBroadcast { fn recv_from( &mut self, idx: usize, - ) -> impl Future> { + ) -> impl Future> { self.recv_from(idx) } diff --git a/src/net/mod.rs b/src/net/mod.rs index 95480ce..d8f0c2e 100644 --- a/src/net/mod.rs +++ b/src/net/mod.rs @@ -72,24 +72,24 @@ impl<'a, C: Channel> Channel for &'a mut C { /// Tune to a specific channel pub trait Tuneable { - type Error: Error + Send + 'static; + type TuningError: Error + Send + 'static; fn id(&self) -> usize; fn recv_from( &mut self, idx: usize, - ) -> impl Future>; + ) -> impl Future>; fn send_to( &mut self, idx: usize, msg: &T, - ) -> impl std::future::Future>; + ) -> impl std::future::Future>; } impl<'a, R: Tuneable + ?Sized> Tuneable for &'a mut R { - type Error = R::Error; + type TuningError = R::TuningError; fn id(&self) -> usize { (**self).id() @@ -98,7 +98,7 @@ impl<'a, R: Tuneable + ?Sized> Tuneable for &'a mut R { fn recv_from( &mut self, idx: usize, - ) -> impl Future> { + ) -> impl Future> { (**self).recv_from(idx) } @@ -106,7 +106,7 @@ impl<'a, R: Tuneable + ?Sized> Tuneable for &'a mut R { &mut self, idx: usize, msg: &T, - ) -> impl std::future::Future> { + ) -> impl std::future::Future> { (**self).send_to(idx, msg) } } diff --git a/src/net/network.rs b/src/net/network.rs index cafca33..8b6303d 100644 --- a/src/net/network.rs +++ b/src/net/network.rs @@ -298,18 +298,53 @@ impl Network { let n = n + 1; // We need to count ourselves. 0..n } + + async fn drop_party(_id: usize) -> Result<(), ()> { + todo!("Initiate a drop vote"); + + } } +// TODO: Implement a handler system, such we can handle ad-hoc requests from other parties, +// such as dropping/kicking other parties for cheating, being slow, etc. +// +// Outline: +// Currently we do not handle any unprepared protocols, but only expected 'happy path' behaviour. +// In case of protocols or communication failure we return an error, but we do not provide a solution. +// The current expection is for the downstream user to handle it themselves, instead of doing +// something automatic. However, we currently do not have any methods for removing parties, +// and if we had we still need all other parties to come to the same conclusion. +// +// First, +// we are in need of some voting protocols, such we can initiate a 'drop' vote. +// How this should be done is not clear-cut, but we can start with something simple. +// +// Second, +// We need the ability to handle these ad-hoc as these voting requests can come at any point in +// time, while we could check for votes manually each 'round' between each protocol, this would not +// probably not suffice. +// +// We can use asyncness to run these in the back, racing/selecting between the happy-path and +// incoming vote requests. A handler should be able to be set up so the policies/code for how to +// react on these requests should be handled. +// +// The issue here becomes that we need to process channels before deciding to relay them or handle +// it with the vote handler. +// +// +// + + impl Unicast for Network { - type Error = NetworkError; + type UnicastError = NetworkError; #[tracing::instrument(skip_all)] - async fn unicast(&mut self, msgs: &[impl serde::Serialize + Sync]) -> Result<(), Self::Error> { + async fn unicast(&mut self, msgs: &[impl serde::Serialize + Sync]) -> Result<(), Self::UnicastError> { self.unicast(msgs).await } #[tracing::instrument(skip_all)] - async fn symmetric_unicast(&mut self, msgs: Vec) -> Result, Self::Error> + async fn symmetric_unicast(&mut self, msgs: Vec) -> Result, Self::UnicastError> where T: serde::Serialize + serde::de::DeserializeOwned + Sync, { @@ -317,7 +352,7 @@ impl Unicast for Network { } #[tracing::instrument(skip_all)] - async fn receive_all(&mut self) -> Result, Self::Error> { + async fn receive_all(&mut self) -> Result, Self::UnicastError> { self.receive_all().await } @@ -327,15 +362,15 @@ impl Unicast for Network { } impl Broadcast for Network { - type Error = NetworkError; + type BroadcastError = NetworkError; #[tracing::instrument(skip_all)] - async fn broadcast(&mut self, msg: &(impl serde::Serialize + Sync)) -> Result<(), Self::Error> { + async fn broadcast(&mut self, msg: &(impl serde::Serialize + Sync)) -> Result<(), Self::BroadcastError> { self.broadcast(msg).await } #[tracing::instrument(skip_all)] - async fn symmetric_broadcast(&mut self, msg: T) -> Result, Self::Error> + async fn symmetric_broadcast(&mut self, msg: T) -> Result, Self::BroadcastError> where T: serde::Serialize + serde::de::DeserializeOwned + Sync, { @@ -345,7 +380,7 @@ impl Broadcast for Network { fn recv_from( &mut self, idx: usize, - ) -> impl Future> { + ) -> impl Future> { Tuneable::recv_from(self, idx).map_err(move |e| NetworkError { id: idx as u32, source: e, @@ -358,7 +393,7 @@ impl Broadcast for Network { } impl Tuneable for Network { - type Error = C::Error; + type TuningError = C::Error; fn id(&self) -> usize { self.index @@ -367,7 +402,7 @@ impl Tuneable for Network { async fn recv_from( &mut self, idx: usize, - ) -> Result { + ) -> Result { let idx = self.id_to_index(idx); self.connections[idx].recv().await } @@ -376,7 +411,7 @@ impl Tuneable for Network { &mut self, idx: usize, msg: &T, - ) -> Result<(), Self::Error> { + ) -> Result<(), Self::TuningError> { let idx = self.id_to_index(idx); self.connections[idx].send(msg).await } diff --git a/src/protocols/cutnchoose.rs b/src/protocols/cutnchoose.rs index 00e620c..e7c5251 100644 --- a/src/protocols/cutnchoose.rs +++ b/src/protocols/cutnchoose.rs @@ -107,16 +107,16 @@ mod test { } impl Broadcast for SingleBroadcast { - type Error = ::Error; + type BroadcastError = ::Error; fn broadcast( &mut self, msg: &(impl serde::Serialize + Sync), - ) -> impl std::future::Future> { + ) -> impl std::future::Future> { self.inner.send(msg) } - async fn symmetric_broadcast(&mut self, msg: T) -> Result, Self::Error> + async fn symmetric_broadcast(&mut self, msg: T) -> Result, Self::BroadcastError> where T: serde::Serialize + serde::de::DeserializeOwned + Sync, { @@ -134,7 +134,7 @@ mod test { fn recv_from( &mut self, _idx: usize, - ) -> impl futures::prelude::Future> { + ) -> impl futures::prelude::Future> { self.inner.recv() } diff --git a/src/protocols/mod.rs b/src/protocols/mod.rs index 4434be7..87ba523 100644 --- a/src/protocols/mod.rs +++ b/src/protocols/mod.rs @@ -2,3 +2,4 @@ pub mod beaver; pub mod cointoss; mod cutnchoose; mod rand; +pub mod voting; diff --git a/src/protocols/voting.rs b/src/protocols/voting.rs new file mode 100644 index 0000000..b6ce2d8 --- /dev/null +++ b/src/protocols/voting.rs @@ -0,0 +1,63 @@ +use std::env::Args; + +use serde::{de::DeserializeOwned, Deserialize, Serialize}; + +use crate::net::Communicate; + +#[derive(Clone, Serialize, Deserialize)] +pub struct Proposal { + initative: T, + creator: usize, +} + + +pub trait Initiative: Serialize + DeserializeOwned + Sync { + type Args; + fn name() -> &'static str; + fn execute(args: Args); +} + +impl Proposal { + + pub async fn initiate(initative: T, mut coms: C) -> Result, C::BroadcastError> { + let creator = coms.id(); + let proposal = Self {initative, creator}; + let request = ProposalRequest(proposal); + + coms.broadcast(&request).await?; + request.accept(coms).await + } + + pub fn execute(self, args: Args) { + T::execute(args) + } + +} + +#[repr(transparent)] +#[derive(Clone, Serialize, Deserialize)] +pub struct ProposalRequest(Proposal); + +impl ProposalRequest { + + async fn vote(self, vote: bool, mut coms: C) -> Result>, C::BroadcastError> { + let votes = coms.symmetric_broadcast(vote).await?; + let n = votes.len(); + let yes_votes = votes.into_iter().filter(|&v| v).count(); + let res = if yes_votes > n { + Some(self.0) + } else { + None + }; + Ok(res) + } + + pub async fn accept(self, coms: C) -> Result>, C::BroadcastError> { + self.vote(true, coms).await + } + + pub async fn reject(self, coms: C) -> Result>, C::BroadcastError>{ + self.vote(false, coms).await + + } +} diff --git a/src/schemes/shamir.rs b/src/schemes/shamir.rs index 36522b7..c83e756 100644 --- a/src/schemes/shamir.rs +++ b/src/schemes/shamir.rs @@ -289,7 +289,7 @@ pub async fn deflate, net: &mut U, rng: &mut impl RngCore, -) -> Result, ::Error> { +) -> Result, ::UnicastError> { let z = z.0; // let x = z.x; let n = ctx.ids.len();