diff --git a/zebra-network/src/constants.rs b/zebra-network/src/constants.rs index 4a9675574..624efd50b 100644 --- a/zebra-network/src/constants.rs +++ b/zebra-network/src/constants.rs @@ -12,4 +12,4 @@ pub mod magics { pub const MAINNET: Magic = Magic([0x24, 0xe9, 0x27, 0x64]); /// The testnet. pub const TESTNET: Magic = Magic([0xfa, 0x1a, 0xf9, 0xbf]); -} \ No newline at end of file +} diff --git a/zebra-network/src/lib.rs b/zebra-network/src/lib.rs index 1a49eda2b..d242fd1bf 100644 --- a/zebra-network/src/lib.rs +++ b/zebra-network/src/lib.rs @@ -5,7 +5,7 @@ #[macro_use] extern crate failure; -pub mod message; -pub mod types; mod constants; -mod meta_addr; \ No newline at end of file +pub mod message; +mod meta_addr; +pub mod types; diff --git a/zebra-network/src/message.rs b/zebra-network/src/message.rs index f39f0d0bf..d0e39e221 100644 --- a/zebra-network/src/message.rs +++ b/zebra-network/src/message.rs @@ -1,6 +1,7 @@ //! Definitions of network messages. use std::io; +use std::net; use byteorder::{LittleEndian, ReadBytesExt, WriteBytesExt}; use chrono::{DateTime, TimeZone, Utc}; @@ -57,17 +58,15 @@ pub enum Message { /// The time when the version message was sent. timestamp: DateTime, - /// The network address of the node receiving this message. + /// The network address of the node receiving this message, and its + /// advertised network services. /// - /// Note that the timestamp field of the [`MetaAddr`] is not included in - /// the serialization of `version` messages. - address_receiving: MetaAddr, + /// Q: how does the handshake know the remote peer's services already? + address_recv: (Services, net::SocketAddr), - /// The network address of the node emitting this message. - /// - /// Note that the timestamp field of the [`MetaAddr`] is not included in - /// the serialization of `version` messages. - address_from: MetaAddr, + /// The network address of the node sending this message, and its + /// advertised network services. + address_from: (Services, net::SocketAddr), /// Node random nonce, randomly generated every time a version /// packet is sent. This nonce is used to detect connections @@ -353,7 +352,7 @@ impl Message { ref version, ref services, ref timestamp, - ref address_receiving, + ref address_recv, ref address_from, ref nonce, ref user_agent, @@ -364,14 +363,13 @@ impl Message { writer.write_u64::(services.0)?; writer.write_i64::(timestamp.timestamp())?; - // We represent a Bitcoin net_addr as a `MetaAddr` internally. - // However, the version message encodes net_addrs without the - // timestamp field, so we encode the `MetaAddr`s manually here. - writer.write_u64::(address_receiving.services.0)?; - writer.write_socket_addr(address_receiving.addr)?; + let (recv_services, recv_addr) = address_recv; + writer.write_u64::(recv_services.0)?; + writer.write_socket_addr(*recv_addr)?; - writer.write_u64::(address_from.services.0)?; - writer.write_socket_addr(address_from.addr)?; + let (from_services, from_addr) = address_from; + writer.write_u64::(from_services.0)?; + writer.write_socket_addr(*from_addr)?; writer.write_u64::(nonce.0)?; writer.write_string(&user_agent)?; @@ -459,44 +457,26 @@ fn try_read_version( mut reader: R, _parsing_version: Version, ) -> Result { - let version = Version(reader.read_u32::()?); - let services = Services(reader.read_u64::()?); - let timestamp = Utc.timestamp(reader.read_i64::()?, 0); - - // We represent a Bitcoin `net_addr` as a `MetaAddr` internally. However, - // the version message encodes `net_addr`s without timestamps, so we fill in - // the timestamp field of the `MetaAddr`s with the version message's - // timestamp. - let address_receiving = MetaAddr { - services: Services(reader.read_u64::()?), - addr: reader.read_socket_addr()?, - last_seen: timestamp, - }; - let address_from = MetaAddr { - services: Services(reader.read_u64::()?), - addr: reader.read_socket_addr()?, - last_seen: timestamp, - }; - - let nonce = Nonce(reader.read_u64::()?); - let user_agent = reader.read_string()?; - let start_height = BlockHeight(reader.read_u32::()?); - let relay = match reader.read_u8()? { - 0 => false, - 1 => true, - _ => return Err(SerializationError::ParseError("non-bool value")), - }; - Ok(Message::Version { - version, - services, - timestamp, - address_receiving, - address_from, - nonce, - user_agent, - start_height, - relay, + version: Version(reader.read_u32::()?), + services: Services(reader.read_u64::()?), + timestamp: Utc.timestamp(reader.read_i64::()?, 0), + address_recv: ( + Services(reader.read_u64::()?), + reader.read_socket_addr()?, + ), + address_from: ( + Services(reader.read_u64::()?), + reader.read_socket_addr()?, + ), + nonce: Nonce(reader.read_u64::()?), + user_agent: reader.read_string()?, + start_height: BlockHeight(reader.read_u32::()?), + relay: match reader.read_u8()? { + 0 => false, + 1 => true, + _ => return Err(SerializationError::ParseError("non-bool value")), + }, }) } @@ -648,16 +628,14 @@ mod tests { services, timestamp, // XXX maybe better to have Version keep only (Services, SocketAddr) - address_receiving: MetaAddr { + address_recv: ( services, - addr: SocketAddr::new(IpAddr::V4(Ipv4Addr::new(203, 0, 113, 6)), 8233), - last_seen: timestamp, - }, - address_from: MetaAddr { + SocketAddr::new(IpAddr::V4(Ipv4Addr::new(203, 0, 113, 6)), 8233), + ), + address_from: ( services, - addr: SocketAddr::new(IpAddr::V4(Ipv4Addr::new(203, 0, 113, 6)), 8233), - last_seen: timestamp, - }, + SocketAddr::new(IpAddr::V4(Ipv4Addr::new(203, 0, 113, 6)), 8233), + ), nonce: Nonce(0x9082_4908_8927_9238), user_agent: "Zebra".to_owned(), start_height: BlockHeight(540_000), diff --git a/zebra-network/src/meta_addr.rs b/zebra-network/src/meta_addr.rs index 6005eac3a..2933543eb 100644 --- a/zebra-network/src/meta_addr.rs +++ b/zebra-network/src/meta_addr.rs @@ -6,7 +6,7 @@ use std::net::SocketAddr; use crate::types::Services; /// An address with metadata on its advertised services and last-seen time. -/// +/// /// [Bitcoin reference](https://en.bitcoin.it/wiki/Protocol_documentation#Network_address) #[derive(Copy, Clone, Debug, Eq, PartialEq)] pub struct MetaAddr { diff --git a/zebra-network/src/types.rs b/zebra-network/src/types.rs index ec5a8f95b..d4d98ae72 100644 --- a/zebra-network/src/types.rs +++ b/zebra-network/src/types.rs @@ -16,4 +16,4 @@ pub struct Services(pub u64); /// A nonce used in the networking layer to identify messages. #[derive(Copy, Clone, Debug, Eq, PartialEq)] -pub struct Nonce(pub u64); \ No newline at end of file +pub struct Nonce(pub u64);