diff --git a/zebra-network/src/constants.rs b/zebra-network/src/constants.rs index ec1a3b86e..7a54b8a26 100644 --- a/zebra-network/src/constants.rs +++ b/zebra-network/src/constants.rs @@ -3,7 +3,7 @@ use std::time::Duration; // XXX should these constants be split into protocol also? -use crate::protocol::types::*; +use crate::protocol::external::types::*; /// The timeout for requests made to a remote peer. pub const REQUEST_TIMEOUT: Duration = Duration::from_secs(10); diff --git a/zebra-network/src/network.rs b/zebra-network/src/network.rs index febbb1f21..d5cfdc478 100644 --- a/zebra-network/src/network.rs +++ b/zebra-network/src/network.rs @@ -1,4 +1,4 @@ -use crate::{constants::magics, protocol::types::Magic}; +use crate::{constants::magics, protocol::external::types::Magic}; /// An enum describing the possible network choices. #[derive(Copy, Clone, Debug, Eq, PartialEq, Hash, Serialize, Deserialize)] diff --git a/zebra-network/src/peer/connector.rs b/zebra-network/src/peer/connector.rs index aae7f5f13..a9845a68b 100644 --- a/zebra-network/src/peer/connector.rs +++ b/zebra-network/src/peer/connector.rs @@ -54,6 +54,6 @@ where let client = hs.call((stream, addr)).await?; Ok(Change::Insert(addr, client)) } - .boxed() + .boxed() } } diff --git a/zebra-network/src/peer/error.rs b/zebra-network/src/peer/error.rs index 76958c3e3..379da4c4f 100644 --- a/zebra-network/src/peer/error.rs +++ b/zebra-network/src/peer/error.rs @@ -68,7 +68,7 @@ impl ErrorSlot { pub enum HandshakeError { /// The remote peer sent an unexpected message during the handshake. #[error("The remote peer sent an unexpected message: {0:?}")] - UnexpectedMessage(crate::protocol::message::Message), + UnexpectedMessage(crate::protocol::external::Message), /// The peer connector detected handshake nonce reuse, possibly indicating self-connection. #[error("Detected nonce reuse, possible self-connection")] NonceReuse, diff --git a/zebra-network/src/peer/handshake.rs b/zebra-network/src/peer/handshake.rs index c6cf5d781..d76e9638c 100644 --- a/zebra-network/src/peer/handshake.rs +++ b/zebra-network/src/peer/handshake.rs @@ -17,7 +17,10 @@ use zebra_chain::types::BlockHeight; use crate::{ constants, - protocol::{codec::*, internal::*, message::*, types::*}, + protocol::{ + external::{types::*, Codec, Message}, + internal::{Request, Response}, + }, types::MetaAddr, BoxedStdError, Config, }; diff --git a/zebra-network/src/peer/server.rs b/zebra-network/src/peer/server.rs index aa333b57b..dc32c487c 100644 --- a/zebra-network/src/peer/server.rs +++ b/zebra-network/src/peer/server.rs @@ -16,9 +16,8 @@ use zebra_chain::{serialization::SerializationError, transaction::TransactionHas use crate::{ constants, protocol::{ + external::{InventoryHash, Message}, internal::{Request, Response}, - inv::InventoryHash, - message::Message, }, BoxedStdError, }; diff --git a/zebra-network/src/protocol.rs b/zebra-network/src/protocol.rs index 38ac65dbb..303665d8f 100644 --- a/zebra-network/src/protocol.rs +++ b/zebra-network/src/protocol.rs @@ -1,14 +1,8 @@ //! Zcash network protocol handling. -pub mod codec; -pub mod message; -pub mod types; - -pub mod inv; - -// XXX at some later point the above should move to an `external` submodule, so -// that we have -// - protocol::external::{all_bitcoin_zcash_types}; -// - protocol::internal::{all_internal_req_rsp_types}; - +/// The external Bitcoin-based protocol. +pub mod external; +/// The internal request/response protocol. pub mod internal; +/// Newtype wrappers giving semantic meaning to primitive datatypes. +pub mod types; diff --git a/zebra-network/src/protocol/external.rs b/zebra-network/src/protocol/external.rs new file mode 100644 index 000000000..befe8861e --- /dev/null +++ b/zebra-network/src/protocol/external.rs @@ -0,0 +1,12 @@ +/// A Tokio codec that transforms an `AsyncRead` into a `Stream` of `Message`s. +mod codec; +/// Inventory items. +mod inv; +/// An enum of all supported Bitcoin message types. +mod message; +/// Newtype wrappers for primitive types. +pub mod types; + +pub use codec::Codec; +pub use inv::InventoryHash; +pub use message::Message; diff --git a/zebra-network/src/protocol/codec.rs b/zebra-network/src/protocol/external/codec.rs similarity index 100% rename from zebra-network/src/protocol/codec.rs rename to zebra-network/src/protocol/external/codec.rs diff --git a/zebra-network/src/protocol/inv.rs b/zebra-network/src/protocol/external/inv.rs similarity index 100% rename from zebra-network/src/protocol/inv.rs rename to zebra-network/src/protocol/external/inv.rs diff --git a/zebra-network/src/protocol/message.rs b/zebra-network/src/protocol/external/message.rs similarity index 100% rename from zebra-network/src/protocol/message.rs rename to zebra-network/src/protocol/external/message.rs diff --git a/zebra-network/src/protocol/external/types.rs b/zebra-network/src/protocol/external/types.rs new file mode 100644 index 000000000..022cbdbe4 --- /dev/null +++ b/zebra-network/src/protocol/external/types.rs @@ -0,0 +1,55 @@ +use hex; +use std::fmt; + +/// A magic number identifying the network. +#[derive(Copy, Clone, Eq, PartialEq)] +pub struct Magic(pub [u8; 4]); + +impl fmt::Debug for Magic { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + f.debug_tuple("Magic").field(&hex::encode(&self.0)).finish() + } +} + +/// A protocol version number. +#[derive(Copy, Clone, Debug, Eq, PartialEq)] +pub struct Version(pub u32); + +bitflags! { + /// A bitflag describing services advertised by a node in the network. + /// + /// Note that bits 24-31 are reserved for temporary experiments; other + /// service bits should be allocated via the ZIP process. + #[derive(Default)] + pub struct PeerServices: u64 { + /// NODE_NETWORK means that the node is a full node capable of serving + /// blocks, as opposed to a light client that makes network requests but + /// does not provide network services. + const NODE_NETWORK = (1 << 0); + /// NODE_BLOOM means that the node supports bloom-filtered connections. + const NODE_BLOOM = (1 << 2); + } +} + +/// A nonce used in the networking layer to identify messages. +#[derive(Copy, Clone, Debug, Eq, PartialEq, Hash)] +pub struct Nonce(pub u64); + +impl Default for Nonce { + fn default() -> Self { + use rand::{thread_rng, Rng}; + Self(thread_rng().gen()) + } +} + +#[cfg(test)] +mod tests { + + use crate::constants::magics; + + #[test] + fn magic_debug() { + assert_eq!(format!("{:?}", magics::MAINNET), "Magic(\"24e92764\")"); + assert_eq!(format!("{:?}", magics::TESTNET), "Magic(\"fa1af9bf\")"); + } +} diff --git a/zebra-network/src/protocol/internal.rs b/zebra-network/src/protocol/internal.rs index 186d2fb4f..e97891a1f 100644 --- a/zebra-network/src/protocol/internal.rs +++ b/zebra-network/src/protocol/internal.rs @@ -1,52 +1,5 @@ -//! Message types for the internal request/response protocol. -//! -//! These are currently defined just as enums with all possible requests and -//! responses, so that we have unified types to pass around. No serialization -//! is performed as these are only internal types. +mod request; +mod response; -use std::error::Error; - -use zebra_chain::transaction::Transaction; - -use crate::meta_addr::MetaAddr; - -use super::types::Nonce; - -/// A network request, represented in internal format. -#[derive(Clone, Debug, Eq, PartialEq)] -pub enum Request { - /// Requests additional peers from the server. - GetPeers, - /// Advertises peers to the remote server. - PushPeers(Vec), - /// Heartbeats triggered on peer connection start. - // This is included as a bit of a hack, it should only be used - // internally for connection management. You should not expect to - // be firing or handling `Ping` requests or `Pong` responses. - Ping(Nonce), - /// Requests the transactions the remote server has verified but - /// not yet confirmed. - GetMempool, -} - -/// A response to a network request, represented in internal format. -#[derive(Clone, Debug, Eq, PartialEq)] -pub enum Response { - /// Generic success. - Ok, - /// Generic error. - Error, - /// A list of peers, used to respond to `GetPeers`. - Peers(Vec), - /// A list of transactions, such as in response to `GetMempool`. - Transactions(Vec), -} - -impl From for Response -where - E: Error, -{ - fn from(_e: E) -> Self { - Self::Error - } -} +pub use request::Request; +pub use response::Response; diff --git a/zebra-network/src/protocol/internal/request.rs b/zebra-network/src/protocol/internal/request.rs new file mode 100644 index 000000000..bfeb5bff1 --- /dev/null +++ b/zebra-network/src/protocol/internal/request.rs @@ -0,0 +1,20 @@ +use crate::meta_addr::MetaAddr; + +use super::super::types::Nonce; + +/// A network request, represented in internal format. +#[derive(Clone, Debug, Eq, PartialEq)] +pub enum Request { + /// Requests additional peers from the server. + GetPeers, + /// Advertises peers to the remote server. + PushPeers(Vec), + /// Heartbeats triggered on peer connection start. + // This is included as a bit of a hack, it should only be used + // internally for connection management. You should not expect to + // be firing or handling `Ping` requests or `Pong` responses. + Ping(Nonce), + /// Requests the transactions the remote server has verified but + /// not yet confirmed. + GetMempool, +} diff --git a/zebra-network/src/protocol/internal/response.rs b/zebra-network/src/protocol/internal/response.rs new file mode 100644 index 000000000..8441e5072 --- /dev/null +++ b/zebra-network/src/protocol/internal/response.rs @@ -0,0 +1,28 @@ +use std::error::Error; + +// XXX clean module layout of zebra_chain +use zebra_chain::transaction::Transaction; + +use crate::meta_addr::MetaAddr; + +/// A response to a network request, represented in internal format. +#[derive(Clone, Debug, Eq, PartialEq)] +pub enum Response { + /// Generic success. + Ok, + /// Generic error. + Error, + /// A list of peers, used to respond to `GetPeers`. + Peers(Vec), + /// A list of transactions, such as in response to `GetMempool`. + Transactions(Vec), +} + +impl From for Response +where + E: Error, +{ + fn from(_e: E) -> Self { + Self::Error + } +} diff --git a/zebra-network/src/protocol/types.rs b/zebra-network/src/protocol/types.rs index 6af2b7863..26121bfb0 100644 --- a/zebra-network/src/protocol/types.rs +++ b/zebra-network/src/protocol/types.rs @@ -1,57 +1,4 @@ -//! Newtype wrappers assigning semantic meaning to primitive types. - -use hex; -use std::fmt; - -/// A magic number identifying the network. -#[derive(Copy, Clone, Eq, PartialEq)] -pub struct Magic(pub [u8; 4]); - -impl fmt::Debug for Magic { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - f.debug_tuple("Magic").field(&hex::encode(&self.0)).finish() - } -} - -/// A protocol version number. -#[derive(Copy, Clone, Debug, Eq, PartialEq)] -pub struct Version(pub u32); - -bitflags! { - /// A bitflag describing services advertised by a node in the network. - /// - /// Note that bits 24-31 are reserved for temporary experiments; other - /// service bits should be allocated via the ZIP process. - #[derive(Default)] - pub struct PeerServices: u64 { - /// NODE_NETWORK means that the node is a full node capable of serving - /// blocks, as opposed to a light client that makes network requests but - /// does not provide network services. - const NODE_NETWORK = (1 << 0); - /// NODE_BLOOM means that the node supports bloom-filtered connections. - const NODE_BLOOM = (1 << 2); - } -} - -/// A nonce used in the networking layer to identify messages. -#[derive(Copy, Clone, Debug, Eq, PartialEq, Hash)] -pub struct Nonce(pub u64); - -impl Default for Nonce { - fn default() -> Self { - use rand::{thread_rng, Rng}; - Self(thread_rng().gen()) - } -} - -#[cfg(test)] -mod tests { - - use crate::constants::magics; - - #[test] - fn magic_debug() { - assert_eq!(format!("{:?}", magics::MAINNET), "Magic(\"24e92764\")"); - assert_eq!(format!("{:?}", magics::TESTNET), "Magic(\"fa1af9bf\")"); - } -} +// Because of the `ping` hack, `Nonce` is included in `Request`s. +pub use super::external::types::Nonce; +// The services flag is used in `MetaAddr`s. +pub use super::external::types::PeerServices;