diff --git a/Cargo.lock b/Cargo.lock index 26cda7bd66..b1148b82cf 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1152,12 +1152,17 @@ dependencies = [ name = "phaselock-types" version = "0.0.6-dev" dependencies = [ + "async-std", + "async-tungstenite", + "bincode", "blake3", + "futures", "hex_fmt", "rand 0.7.3", "rand_chacha 0.2.2", "serde", "serde_bytes", + "snafu", "threshold_crypto", ] diff --git a/phaselock-types/Cargo.toml b/phaselock-types/Cargo.toml index a742b55929..b15333036f 100644 --- a/phaselock-types/Cargo.toml +++ b/phaselock-types/Cargo.toml @@ -9,10 +9,15 @@ version = "0.0.6-dev" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html [dependencies] +async-std = "1.10.0" +async-tungstenite = "0.16.1" +bincode = "1.3.3" blake3 = "1.3.1" +futures = "0.3.21" hex_fmt = "0.3.0" rand = "0.7.3" rand_chacha = "0.2.2" serde = { version = "1.0.136", features = ["derive"] } serde_bytes = "0.11.5" +snafu = "0.7.0" threshold_crypto = "0.4.0" diff --git a/phaselock-types/src/traits.rs b/phaselock-types/src/traits.rs index f8b02aa262..7339a760f3 100644 --- a/phaselock-types/src/traits.rs +++ b/phaselock-types/src/traits.rs @@ -1,5 +1,6 @@ //! Common traits for the `PhaseLock` protocol pub mod block_contents; +pub mod network; pub mod state; pub use block_contents::BlockContents; diff --git a/phaselock-types/src/traits/network.rs b/phaselock-types/src/traits/network.rs new file mode 100644 index 0000000000..44af9caf22 --- /dev/null +++ b/phaselock-types/src/traits/network.rs @@ -0,0 +1,110 @@ +//! Network access abstraction +//! +//! Contains types and traits used by `PhaseLock` to abstract over network access + +use async_tungstenite::tungstenite::error as werror; +use futures::future::BoxFuture; +use serde::{de::DeserializeOwned, Serialize}; +use snafu::Snafu; + +use crate::PubKey; + +/// A boxed future trait object with a static lifetime +pub type BoxedFuture = BoxFuture<'static, T>; + +/// Error type for networking +#[derive(Debug, Snafu)] +#[snafu(visibility(pub))] +pub enum NetworkError { + /// A Listener failed to send a message + ListenerSend, + /// Could not deliver a message to a specified recipient + CouldNotDeliver, + /// Attempted to deliver a message to an unknown node + NoSuchNode, + /// Failed to serialize a message + FailedToSerialize { + /// Originating bincode error + source: bincode::Error, + }, + /// Failed to deserealize a message + FailedToDeserialize { + /// originating bincode error + source: bincode::Error, + }, + /// WebSockets specific error + WebSocket { + /// Originating websockets error + source: werror::Error, + }, + /// Error orginiating from within the executor + ExecutorError { + /// Originating async_std error + source: async_std::io::Error, + }, + /// Failed to decode a socket specification + SocketDecodeError { + /// Input that was given + input: String, + /// Originating io error + source: std::io::Error, + }, + /// Failed to bind a listener socket + FailedToBindListener { + /// originating io error + source: std::io::Error, + }, + /// No sockets were open + NoSocketsError { + /// Input that was given + input: String, + }, + /// Generic error type for compatibility if needed + Other { + /// Originating error + inner: Box, + }, + /// Channel error + ChannelSend, + /// Could not complete handshake + IdentityHandshake, + /// The underlying connection has been shut down + ShutDown, +} + +/// Describes, generically, the behaviors a networking implementation must have +pub trait NetworkingImplementation: Send + Sync +where + M: Serialize + DeserializeOwned + Send + Clone + 'static, +{ + /// Broadcasts a message to the network + /// + /// Should provide that the message eventually reach all non-faulty nodes + fn broadcast_message(&self, message: M) -> BoxFuture<'_, Result<(), NetworkError>>; + /// Sends a direct message to a specific node + fn message_node( + &self, + message: M, + recipient: PubKey, + ) -> BoxFuture<'_, Result<(), NetworkError>>; + /// Moves out the entire queue of received broadcast messages, should there be any + /// + /// Provided as a future to allow the backend to do async locking + fn broadcast_queue(&self) -> BoxFuture<'_, Result, NetworkError>>; + /// Provides a future for the next received broadcast + /// + /// Will unwrap the underlying `NetworkMessage` + fn next_broadcast(&self) -> BoxFuture<'_, Result>; + /// Moves out the entire queue of received direct messages to this node + fn direct_queue(&self) -> BoxFuture<'_, Result, NetworkError>>; + /// Provides a future for the next received direct message to this node + /// + /// Will unwrap the underlying `NetworkMessage` + fn next_direct(&self) -> BoxFuture<'_, Result>; + /// Node's currently known to the networking implementation + /// + /// Kludge function to work around leader election + fn known_nodes(&self) -> BoxFuture<'_, Vec>; + /// Object safe clone + fn obj_clone(&self) -> Box + 'static>; +} diff --git a/src/traits/networking.rs b/src/traits/networking.rs index 1882451395..331bd4527c 100644 --- a/src/traits/networking.rs +++ b/src/traits/networking.rs @@ -8,112 +8,12 @@ //! In future, this module will contain a production ready networking implementation, very probably //! one libp2p based. -use crate::PubKey; - -use async_tungstenite::tungstenite::error as werror; -use futures::future::BoxFuture; -use serde::{de::DeserializeOwned, Serialize}; -use snafu::Snafu; - pub mod memory_network; pub mod w_network; -/// A boxed future trait object with a static lifetime -pub type BoxedFuture = BoxFuture<'static, T>; - -/// Error type for networking -#[derive(Debug, Snafu)] -#[snafu(visibility(pub(crate)))] -pub enum NetworkError { - /// A Listener failed to send a message - ListenerSend, - /// Could not deliver a message to a specified recipient - CouldNotDeliver, - /// Attempted to deliver a message to an unknown node - NoSuchNode, - /// Failed to serialize a message - FailedToSerialize { - /// Originating bincode error - source: bincode::Error, - }, - /// Failed to deserealize a message - FailedToDeserialize { - /// originating bincode error - source: bincode::Error, - }, - /// WebSockets specific error - WebSocket { - /// Originating websockets error - source: werror::Error, - }, - /// Error orginiating from within the executor - ExecutorError { - /// Originating async_std error - source: async_std::io::Error, - }, - /// Failed to decode a socket specification - SocketDecodeError { - /// Input that was given - input: String, - /// Originating io error - source: std::io::Error, - }, - /// Failed to bind a listener socket - FailedToBindListener { - /// originating io error - source: std::io::Error, - }, - /// No sockets were open - NoSocketsError { - /// Input that was given - input: String, - }, - /// Generic error type for compatibility if needed - Other { - /// Originating error - inner: Box, - }, - /// Channel error - ChannelSend, - /// Could not complete handshake - IdentityHandshake, - /// The underlying connection has been shut down - ShutDown, -} - -/// Describes, generically, the behaviors a networking implementation must have -pub trait NetworkingImplementation: Send + Sync -where - M: Serialize + DeserializeOwned + Send + Clone + 'static, -{ - /// Broadcasts a message to the network - /// - /// Should provide that the message eventually reach all non-faulty nodes - fn broadcast_message(&self, message: M) -> BoxFuture<'_, Result<(), NetworkError>>; - /// Sends a direct message to a specific node - fn message_node( - &self, - message: M, - recipient: PubKey, - ) -> BoxFuture<'_, Result<(), NetworkError>>; - /// Moves out the entire queue of received broadcast messages, should there be any - /// - /// Provided as a future to allow the backend to do async locking - fn broadcast_queue(&self) -> BoxFuture<'_, Result, NetworkError>>; - /// Provides a future for the next received broadcast - /// - /// Will unwrap the underlying `NetworkMessage` - fn next_broadcast(&self) -> BoxFuture<'_, Result>; - /// Moves out the entire queue of received direct messages to this node - fn direct_queue(&self) -> BoxFuture<'_, Result, NetworkError>>; - /// Provides a future for the next received direct message to this node - /// - /// Will unwrap the underlying `NetworkMessage` - fn next_direct(&self) -> BoxFuture<'_, Result>; - /// Node's currently known to the networking implementation - /// - /// Kludge function to work around leader election - fn known_nodes(&self) -> BoxFuture<'_, Vec>; - /// Object safe clone - fn obj_clone(&self) -> Box + 'static>; -} +pub use phaselock_types::traits::network::{ + BoxedFuture, ChannelSendSnafu, CouldNotDeliverSnafu, ExecutorSnafu, FailedToBindListenerSnafu, + FailedToDeserializeSnafu, FailedToSerializeSnafu, IdentityHandshakeSnafu, ListenerSendSnafu, + NetworkError, NetworkingImplementation, NoSocketsSnafu, NoSuchNodeSnafu, OtherSnafu, + ShutDownSnafu, SocketDecodeSnafu, WebSocketSnafu, +};