diff --git a/bitcoin/src/network/address.rs b/bitcoin/src/network/address.rs index 76234df7..2015970d 100644 --- a/bitcoin/src/network/address.rs +++ b/bitcoin/src/network/address.rs @@ -7,14 +7,13 @@ //! network addresses in Bitcoin messages. //! -use crate::prelude::*; - use core::{fmt, iter}; -use std::net::{SocketAddr, Ipv6Addr, SocketAddrV4, SocketAddrV6, Ipv4Addr, ToSocketAddrs}; +use std::net::{Ipv4Addr, Ipv6Addr, SocketAddr, SocketAddrV4, SocketAddrV6, ToSocketAddrs}; +use crate::consensus::encode::{self, Decodable, Encodable, ReadExt, VarInt, WriteExt}; use crate::io; use crate::network::constants::ServiceFlags; -use crate::consensus::encode::{self, Decodable, Encodable, VarInt, ReadExt, WriteExt}; +use crate::prelude::*; /// A message which can be sent on the Bitcoin network #[derive(Clone, PartialEq, Eq, Hash)] @@ -24,17 +23,17 @@ pub struct Address { /// Network byte-order ipv6 address, or ipv4-mapped ipv6 address pub address: [u16; 8], /// Network port - pub port: u16 + pub port: u16, } const ONION: [u16; 3] = [0xFD87, 0xD87E, 0xEB43]; impl Address { /// Create an address message for a socket - pub fn new(socket :&SocketAddr, services: ServiceFlags) -> Address { + pub fn new(socket: &SocketAddr, services: ServiceFlags) -> Address { let (address, port) = match *socket { SocketAddr::V4(addr) => (addr.ip().to_ipv6_mapped().segments(), addr.port()), - SocketAddr::V6(addr) => (addr.ip().segments(), addr.port()) + SocketAddr::V6(addr) => (addr.ip().segments(), addr.port()), }; Address { address, port, services } } @@ -47,7 +46,8 @@ impl Address { if addr[0..3] == ONION { return Err(io::Error::from(io::ErrorKind::AddrNotAvailable)); } - let ipv6 = Ipv6Addr::new(addr[0], addr[1], addr[2], addr[3], addr[4], addr[5], addr[6], addr[7]); + let ipv6 = + Ipv6Addr::new(addr[0], addr[1], addr[2], addr[3], addr[4], addr[5], addr[6], addr[7]); if let Some(ipv4) = ipv6.to_ipv4() { Ok(SocketAddr::V4(SocketAddrV4::new(ipv4, self.port))) } else { @@ -79,7 +79,7 @@ impl Decodable for Address { Ok(Address { services: Decodable::consensus_decode(r)?, address: read_be_address(r)?, - port: u16::swap_bytes(Decodable::consensus_decode(r)?) + port: u16::swap_bytes(Decodable::consensus_decode(r)?), }) } } @@ -101,10 +101,16 @@ impl fmt::Debug for Address { let ipv6 = Ipv6Addr::from(self.address); match ipv6.to_ipv4() { - Some(addr) => write!(f, "Address {{services: {}, address: {}, port: {}}}", - self.services, addr, self.port), - None => write!(f, "Address {{services: {}, address: {}, port: {}}}", - self.services, ipv6, self.port) + Some(addr) => write!( + f, + "Address {{services: {}, address: {}, port: {}}}", + self.services, addr, self.port + ), + None => write!( + f, + "Address {{services: {}, address: {}, port: {}}}", + self.services, ipv6, self.port + ), } } } @@ -137,7 +143,11 @@ pub enum AddrV2 { impl Encodable for AddrV2 { fn consensus_encode(&self, e: &mut W) -> Result { - fn encode_addr(w: &mut W, network: u8, bytes: &[u8]) -> Result { + fn encode_addr( + w: &mut W, + network: u8, + bytes: &[u8], + ) -> Result { let len = network.consensus_encode(w)? + VarInt(bytes.len() as u64).consensus_encode(w)? + bytes.len(); @@ -151,7 +161,7 @@ impl Encodable for AddrV2 { AddrV2::TorV3(ref bytes) => encode_addr(e, 4, bytes)?, AddrV2::I2p(ref bytes) => encode_addr(e, 5, bytes)?, AddrV2::Cjdns(ref addr) => encode_addr(e, 6, &addr.octets())?, - AddrV2::Unknown(network, ref bytes) => encode_addr(e, network, bytes)? + AddrV2::Unknown(network, ref bytes) => encode_addr(e, network, bytes)?, }) } } @@ -170,43 +180,49 @@ impl Decodable for AddrV2 { } let addr: [u8; 4] = Decodable::consensus_decode(r)?; AddrV2::Ipv4(Ipv4Addr::new(addr[0], addr[1], addr[2], addr[3])) - }, + } 2 => { if len != 16 { return Err(encode::Error::ParseFailed("Invalid IPv6 address")); } let addr: [u16; 8] = read_be_address(r)?; if addr[0..3] == ONION { - return Err(encode::Error::ParseFailed("OnionCat address sent with IPv6 network id")); + return Err(encode::Error::ParseFailed( + "OnionCat address sent with IPv6 network id", + )); } if addr[0..6] == [0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xFFFF] { - return Err(encode::Error::ParseFailed("IPV4 wrapped address sent with IPv6 network id")); + return Err(encode::Error::ParseFailed( + "IPV4 wrapped address sent with IPv6 network id", + )); } - AddrV2::Ipv6(Ipv6Addr::new(addr[0], addr[1], addr[2], addr[3], addr[4], addr[5], addr[6], addr[7])) - }, + AddrV2::Ipv6(Ipv6Addr::new( + addr[0], addr[1], addr[2], addr[3], addr[4], addr[5], addr[6], addr[7], + )) + } 3 => { if len != 10 { return Err(encode::Error::ParseFailed("Invalid TorV2 address")); } let id = Decodable::consensus_decode(r)?; AddrV2::TorV2(id) - }, + } 4 => { if len != 32 { return Err(encode::Error::ParseFailed("Invalid TorV3 address")); } let pubkey = Decodable::consensus_decode(r)?; AddrV2::TorV3(pubkey) - }, + } 5 => { if len != 32 { return Err(encode::Error::ParseFailed("Invalid I2P address")); } let hash = Decodable::consensus_decode(r)?; AddrV2::I2p(hash) - }, + } 6 => { - if len != 16 { + if len != 16 { return Err(encode::Error::ParseFailed("Invalid CJDNS address")); } let addr: [u16; 8] = read_be_address(r)?; @@ -214,8 +230,10 @@ impl Decodable for AddrV2 { if addr[0] != u16::from_be_bytes([0xFC, 0x00]) { return Err(encode::Error::ParseFailed("Invalid CJDNS address")); } - AddrV2::Cjdns(Ipv6Addr::new(addr[0], addr[1], addr[2], addr[3], addr[4], addr[5], addr[6], addr[7])) - }, + AddrV2::Cjdns(Ipv6Addr::new( + addr[0], addr[1], addr[2], addr[3], addr[4], addr[5], addr[6], addr[7], + )) + } _ => { // len already checked above to be <= 512 let mut addr = vec![0u8; len as usize]; @@ -236,7 +254,7 @@ pub struct AddrV2Message { /// Network ID + Network Address pub addr: AddrV2, /// Network port, 0 if not applicable - pub port: u16 + pub port: u16, } impl AddrV2Message { @@ -287,22 +305,26 @@ impl ToSocketAddrs for AddrV2Message { #[cfg(test)] mod test { use core::str::FromStr; - use super::{AddrV2Message, AddrV2, Address}; - use crate::network::constants::ServiceFlags; - use std::net::{SocketAddr, IpAddr, Ipv4Addr, Ipv6Addr}; - use crate::hashes::hex::FromHex; + use std::net::{IpAddr, Ipv4Addr, Ipv6Addr, SocketAddr}; + use super::{AddrV2, AddrV2Message, Address}; use crate::consensus::encode::{deserialize, serialize}; + use crate::hashes::hex::FromHex; + use crate::network::constants::ServiceFlags; #[test] fn serialize_address_test() { - assert_eq!(serialize(&Address { - services: ServiceFlags::NETWORK, - address: [0, 0, 0, 0, 0, 0xffff, 0x0a00, 0x0001], - port: 8333 - }), - vec![1u8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0xff, 0xff, 0x0a, 0, 0, 1, 0x20, 0x8d]); + assert_eq!( + serialize(&Address { + services: ServiceFlags::NETWORK, + address: [0, 0, 0, 0, 0, 0xffff, 0x0a00, 0x0001], + port: 8333 + }), + vec![ + 1u8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0xff, 0xff, 0x0a, 0, 0, 1, + 0x20, 0x8d + ] + ); } #[test] @@ -329,41 +351,47 @@ mod test { #[test] fn deserialize_address_test() { - let mut addr: Result = deserialize(&[1u8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0xff, 0xff, 0x0a, 0, - 0, 1, 0x20, 0x8d]); + let mut addr: Result = deserialize(&[ + 1u8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0xff, 0xff, 0x0a, 0, 0, 1, + 0x20, 0x8d, + ]); assert!(addr.is_ok()); let full = addr.unwrap(); assert!(match full.socket_addr().unwrap() { - SocketAddr::V4(_) => true, - _ => false - } - ); + SocketAddr::V4(_) => true, + _ => false, + }); assert_eq!(full.services, ServiceFlags::NETWORK); assert_eq!(full.address, [0, 0, 0, 0, 0, 0xffff, 0x0a00, 0x0001]); assert_eq!(full.port, 8333); - addr = deserialize(&[1u8, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0xff, 0xff, 0x0a, 0, 0, 1]); + addr = deserialize(&[ + 1u8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0xff, 0xff, 0x0a, 0, 0, 1, + ]); assert!(addr.is_err()); } #[test] - fn test_socket_addr () { - let s4 = SocketAddr::new(IpAddr::V4(Ipv4Addr::new(111,222,123,4)), 5555); + fn test_socket_addr() { + let s4 = SocketAddr::new(IpAddr::V4(Ipv4Addr::new(111, 222, 123, 4)), 5555); let a4 = Address::new(&s4, ServiceFlags::NETWORK | ServiceFlags::WITNESS); assert_eq!(a4.socket_addr().unwrap(), s4); - let s6 = SocketAddr::new(IpAddr::V6(Ipv6Addr::new(0x1111, 0x2222, 0x3333, 0x4444, - 0x5555, 0x6666, 0x7777, 0x8888)), 9999); + let s6 = SocketAddr::new( + IpAddr::V6(Ipv6Addr::new( + 0x1111, 0x2222, 0x3333, 0x4444, 0x5555, 0x6666, 0x7777, 0x8888, + )), + 9999, + ); let a6 = Address::new(&s6, ServiceFlags::NETWORK | ServiceFlags::WITNESS); assert_eq!(a6.socket_addr().unwrap(), s6); } #[test] - fn onion_test () { + fn onion_test() { let onionaddr = SocketAddr::new( - IpAddr::V6( - Ipv6Addr::from_str("FD87:D87E:EB43:edb1:8e4:3588:e546:35ca").unwrap()), 1111); + IpAddr::V6(Ipv6Addr::from_str("FD87:D87E:EB43:edb1:8e4:3588:e546:35ca").unwrap()), + 1111, + ); let addr = Address::new(&onionaddr, ServiceFlags::NONE); assert!(addr.socket_addr().is_err()); } @@ -375,17 +403,32 @@ mod test { let ip = AddrV2::Ipv4(Ipv4Addr::new(1, 2, 3, 4)); assert_eq!(serialize(&ip), Vec::from_hex("010401020304").unwrap()); - let ip = AddrV2::Ipv6(Ipv6Addr::from_str("1a1b:2a2b:3a3b:4a4b:5a5b:6a6b:7a7b:8a8b").unwrap()); + let ip = + AddrV2::Ipv6(Ipv6Addr::from_str("1a1b:2a2b:3a3b:4a4b:5a5b:6a6b:7a7b:8a8b").unwrap()); assert_eq!(serialize(&ip), Vec::from_hex("02101a1b2a2b3a3b4a4b5a5b6a6b7a7b8a8b").unwrap()); let ip = AddrV2::TorV2(FromHex::from_hex("f1f2f3f4f5f6f7f8f9fa").unwrap()); assert_eq!(serialize(&ip), Vec::from_hex("030af1f2f3f4f5f6f7f8f9fa").unwrap()); - let ip = AddrV2::TorV3(FromHex::from_hex("53cd5648488c4707914182655b7664034e09e66f7e8cbf1084e654eb56c5bd88").unwrap()); - assert_eq!(serialize(&ip), Vec::from_hex("042053cd5648488c4707914182655b7664034e09e66f7e8cbf1084e654eb56c5bd88").unwrap()); + let ip = AddrV2::TorV3( + FromHex::from_hex("53cd5648488c4707914182655b7664034e09e66f7e8cbf1084e654eb56c5bd88") + .unwrap(), + ); + assert_eq!( + serialize(&ip), + Vec::from_hex("042053cd5648488c4707914182655b7664034e09e66f7e8cbf1084e654eb56c5bd88") + .unwrap() + ); - let ip = AddrV2::I2p(FromHex::from_hex("a2894dabaec08c0051a481a6dac88b64f98232ae42d4b6fd2fa81952dfe36a87").unwrap()); - assert_eq!(serialize(&ip), Vec::from_hex("0520a2894dabaec08c0051a481a6dac88b64f98232ae42d4b6fd2fa81952dfe36a87").unwrap()); + let ip = AddrV2::I2p( + FromHex::from_hex("a2894dabaec08c0051a481a6dac88b64f98232ae42d4b6fd2fa81952dfe36a87") + .unwrap(), + ); + assert_eq!( + serialize(&ip), + Vec::from_hex("0520a2894dabaec08c0051a481a6dac88b64f98232ae42d4b6fd2fa81952dfe36a87") + .unwrap() + ); let ip = AddrV2::Cjdns(Ipv6Addr::from_str("fc00:1:2:3:4:5:6:7").unwrap()); assert_eq!(serialize(&ip), Vec::from_hex("0610fc000001000200030004000500060007").unwrap()); @@ -412,17 +455,27 @@ mod test { assert!(deserialize::(&Vec::from_hex("01fd010201020304").unwrap()).is_err()); // Valid IPv6. - let ip: AddrV2 = deserialize(&Vec::from_hex("02100102030405060708090a0b0c0d0e0f10").unwrap()).unwrap(); - assert_eq!(ip, AddrV2::Ipv6(Ipv6Addr::from_str("102:304:506:708:90a:b0c:d0e:f10").unwrap())); + let ip: AddrV2 = + deserialize(&Vec::from_hex("02100102030405060708090a0b0c0d0e0f10").unwrap()).unwrap(); + assert_eq!( + ip, + AddrV2::Ipv6(Ipv6Addr::from_str("102:304:506:708:90a:b0c:d0e:f10").unwrap()) + ); // Invalid IPv6, with bogus length. assert!(deserialize::(&Vec::from_hex("020400").unwrap()).is_err()); // Invalid IPv6, contains embedded IPv4. - assert!(deserialize::(&Vec::from_hex("021000000000000000000000ffff01020304").unwrap()).is_err()); + assert!(deserialize::( + &Vec::from_hex("021000000000000000000000ffff01020304").unwrap() + ) + .is_err()); // Invalid IPv6, contains embedded TORv2. - assert!(deserialize::(&Vec::from_hex("0210fd87d87eeb430102030405060708090a").unwrap()).is_err()); + assert!(deserialize::( + &Vec::from_hex("0210fd87d87eeb430102030405060708090a").unwrap() + ) + .is_err()); // Valid TORv2. let ip: AddrV2 = deserialize(&Vec::from_hex("030af1f2f3f4f5f6f7f8f9fa").unwrap()).unwrap(); @@ -432,31 +485,61 @@ mod test { assert!(deserialize::(&Vec::from_hex("030700").unwrap()).is_err()); // Valid TORv3. - let ip: AddrV2 = deserialize(&Vec::from_hex("042079bcc625184b05194975c28b66b66b0469f7f6556fb1ac3189a79b40dda32f1f").unwrap()).unwrap(); - assert_eq!(ip, AddrV2::TorV3(FromHex::from_hex("79bcc625184b05194975c28b66b66b0469f7f6556fb1ac3189a79b40dda32f1f").unwrap())); + let ip: AddrV2 = deserialize( + &Vec::from_hex("042079bcc625184b05194975c28b66b66b0469f7f6556fb1ac3189a79b40dda32f1f") + .unwrap(), + ) + .unwrap(); + assert_eq!( + ip, + AddrV2::TorV3( + FromHex::from_hex( + "79bcc625184b05194975c28b66b66b0469f7f6556fb1ac3189a79b40dda32f1f" + ) + .unwrap() + ) + ); // Invalid TORv3, with bogus length. assert!(deserialize::(&Vec::from_hex("040000").unwrap()).is_err()); // Valid I2P. - let ip: AddrV2 = deserialize(&Vec::from_hex("0520a2894dabaec08c0051a481a6dac88b64f98232ae42d4b6fd2fa81952dfe36a87").unwrap()).unwrap(); - assert_eq!(ip, AddrV2::I2p(FromHex::from_hex("a2894dabaec08c0051a481a6dac88b64f98232ae42d4b6fd2fa81952dfe36a87").unwrap())); + let ip: AddrV2 = deserialize( + &Vec::from_hex("0520a2894dabaec08c0051a481a6dac88b64f98232ae42d4b6fd2fa81952dfe36a87") + .unwrap(), + ) + .unwrap(); + assert_eq!( + ip, + AddrV2::I2p( + FromHex::from_hex( + "a2894dabaec08c0051a481a6dac88b64f98232ae42d4b6fd2fa81952dfe36a87" + ) + .unwrap() + ) + ); // Invalid I2P, with bogus length. assert!(deserialize::(&Vec::from_hex("050300").unwrap()).is_err()); // Valid CJDNS. - let ip: AddrV2 = deserialize(&Vec::from_hex("0610fc000001000200030004000500060007").unwrap()).unwrap(); + let ip: AddrV2 = + deserialize(&Vec::from_hex("0610fc000001000200030004000500060007").unwrap()).unwrap(); assert_eq!(ip, AddrV2::Cjdns(Ipv6Addr::from_str("fc00:1:2:3:4:5:6:7").unwrap())); // Invalid CJDNS, incorrect marker - assert!(deserialize::(&Vec::from_hex("0610fd000001000200030004000500060007").unwrap()).is_err()); + assert!(deserialize::( + &Vec::from_hex("0610fd000001000200030004000500060007").unwrap() + ) + .is_err()); // Invalid CJDNS, with bogus length. assert!(deserialize::(&Vec::from_hex("060100").unwrap()).is_err()); // Unknown, with extreme length. - assert!(deserialize::(&Vec::from_hex("aafe0000000201020304050607").unwrap()).is_err()); + assert!( + deserialize::(&Vec::from_hex("aafe0000000201020304050607").unwrap()).is_err() + ); // Unknown, with reasonable length. let ip: AddrV2 = deserialize(&Vec::from_hex("aa0401020304").unwrap()).unwrap(); @@ -472,10 +555,25 @@ mod test { let raw = Vec::from_hex("0261bc6649019902abab208d79627683fd4804010409090909208d").unwrap(); let addresses: Vec = deserialize(&raw).unwrap(); - assert_eq!(addresses, vec![ - AddrV2Message{services: ServiceFlags::NETWORK, time: 0x4966bc61, port: 8333, addr: AddrV2::Unknown(153, Vec::from_hex("abab").unwrap())}, - AddrV2Message{services: ServiceFlags::NETWORK_LIMITED | ServiceFlags::WITNESS | ServiceFlags::COMPACT_FILTERS, time: 0x83766279, port: 8333, addr: AddrV2::Ipv4(Ipv4Addr::new(9, 9, 9, 9))}, - ]); + assert_eq!( + addresses, + vec![ + AddrV2Message { + services: ServiceFlags::NETWORK, + time: 0x4966bc61, + port: 8333, + addr: AddrV2::Unknown(153, Vec::from_hex("abab").unwrap()) + }, + AddrV2Message { + services: ServiceFlags::NETWORK_LIMITED + | ServiceFlags::WITNESS + | ServiceFlags::COMPACT_FILTERS, + time: 0x83766279, + port: 8333, + addr: AddrV2::Ipv4(Ipv4Addr::new(9, 9, 9, 9)) + }, + ] + ); assert_eq!(serialize(&addresses), raw); } diff --git a/bitcoin/src/network/constants.rs b/bitcoin/src/network/constants.rs index 3cff507f..a8025ee3 100644 --- a/bitcoin/src/network/constants.rs +++ b/bitcoin/src/network/constants.rs @@ -26,19 +26,20 @@ //! assert_eq!(&bytes[..], &[0xF9, 0xBE, 0xB4, 0xD9]); //! ``` -use core::{fmt, ops, convert::TryFrom, borrow::Borrow, borrow::BorrowMut}; +use core::borrow::{Borrow, BorrowMut}; +use core::convert::TryFrom; use core::str::FromStr; +use core::{fmt, ops}; +use bitcoin_internals::{debug_from_display, write_err}; #[cfg(feature = "serde")] use serde::{Deserialize, Serialize}; -use bitcoin_internals::{debug_from_display, write_err}; - +use crate::consensus::encode::{self, Decodable, Encodable}; +use crate::error::impl_std_error; +use crate::hashes::hex::{Error, FromHex}; use crate::io; use crate::prelude::{String, ToOwned}; -use crate::consensus::encode::{self, Encodable, Decodable}; -use crate::hashes::hex::{FromHex, Error}; -use crate::error::impl_std_error; /// Version of the protocol as appearing in network message headers /// This constant is used to signal to other peers which features you support. @@ -86,9 +87,7 @@ impl Network { /// assert_eq!(Ok(Network::Bitcoin), Network::try_from(Magic::from_bytes([0xF9, 0xBE, 0xB4, 0xD9]))); /// assert_eq!(None, Network::from_magic(Magic::from_bytes([0xFF, 0xFF, 0xFF, 0xFF]))); /// ``` - pub fn from_magic(magic: Magic) -> Option { - Network::try_from(magic).ok() - } + pub fn from_magic(magic: Magic) -> Option { Network::try_from(magic).ok() } /// Return the network magic bytes, which should be encoded little-endian /// at the start of every message @@ -101,9 +100,7 @@ impl Network { /// let network = Network::Bitcoin; /// assert_eq!(network.magic(), Magic::from_bytes([0xF9, 0xBE, 0xB4, 0xD9])); /// ``` - pub fn magic(self) -> Magic { - Magic::from(self) - } + pub fn magic(self) -> Magic { Magic::from(self) } } /// An error in parsing network string. @@ -129,7 +126,7 @@ impl FromStr for Network { "testnet" => Testnet, "signet" => Signet, "regtest" => Regtest, - _ => return Err(ParseNetworkError(s.to_owned())) + _ => return Err(ParseNetworkError(s.to_owned())), }; Ok(network) } @@ -164,14 +161,10 @@ impl Magic { pub const REGTEST: Self = Self([0xFA, 0xBF, 0xB5, 0xDA]); /// Create network magic from bytes. - pub fn from_bytes(bytes: [u8; 4]) -> Magic { - Magic(bytes) - } + pub fn from_bytes(bytes: [u8; 4]) -> Magic { Magic(bytes) } /// Get network magic bytes. - pub fn to_bytes(self) -> [u8; 4] { - self.0 - } + pub fn to_bytes(self) -> [u8; 4] { self.0 } } /// An error in parsing magic bytes. @@ -180,7 +173,7 @@ pub struct ParseMagicError { /// The error that occurred when parsing the string. error: Error, /// The byte string that failed to parse. - magic: String + magic: String, } impl FromStr for Magic { @@ -189,7 +182,7 @@ impl FromStr for Magic { fn from_str(s: &str) -> Result { match <[u8; 4]>::from_hex(s) { Ok(magic) => Ok(Magic::from_bytes(magic)), - Err(e) => Err(ParseMagicError { error: e, magic: s.to_owned() }) + Err(e) => Err(ParseMagicError { error: e, magic: s.to_owned() }), } } } @@ -201,7 +194,7 @@ impl From for Magic { Network::Bitcoin => Magic::BITCOIN, Network::Testnet => Magic::TESTNET, Network::Signet => Magic::SIGNET, - Network::Regtest => Magic::REGTEST + Network::Regtest => Magic::REGTEST, } } } @@ -220,7 +213,7 @@ impl TryFrom for Network { Magic::TESTNET => Ok(Network::Testnet), Magic::SIGNET => Ok(Network::Signet), Magic::REGTEST => Ok(Network::Regtest), - _ => Err(UnknownMagic(magic)) + _ => Err(UnknownMagic(magic)), } } } @@ -260,51 +253,35 @@ impl Decodable for Magic { } impl AsRef<[u8]> for Magic { - fn as_ref(&self) -> &[u8] { - &self.0 - } + fn as_ref(&self) -> &[u8] { &self.0 } } impl AsRef<[u8; 4]> for Magic { - fn as_ref(&self) -> &[u8; 4] { - &self.0 - } + fn as_ref(&self) -> &[u8; 4] { &self.0 } } impl AsMut<[u8]> for Magic { - fn as_mut(&mut self) -> &mut [u8] { - &mut self.0 - } + fn as_mut(&mut self) -> &mut [u8] { &mut self.0 } } impl AsMut<[u8; 4]> for Magic { - fn as_mut(&mut self) -> &mut [u8; 4] { - &mut self.0 - } + fn as_mut(&mut self) -> &mut [u8; 4] { &mut self.0 } } impl Borrow<[u8]> for Magic { - fn borrow(&self) -> &[u8] { - &self.0 - } + fn borrow(&self) -> &[u8] { &self.0 } } impl Borrow<[u8; 4]> for Magic { - fn borrow(&self) -> &[u8; 4] { - &self.0 - } + fn borrow(&self) -> &[u8; 4] { &self.0 } } impl BorrowMut<[u8]> for Magic { - fn borrow_mut(&mut self) -> &mut [u8] { - &mut self.0 - } + fn borrow_mut(&mut self) -> &mut [u8] { &mut self.0 } } impl BorrowMut<[u8; 4]> for Magic { - fn borrow_mut(&mut self) -> &mut [u8; 4] { - &mut self.0 - } + fn borrow_mut(&mut self) -> &mut [u8; 4] { &mut self.0 } } impl fmt::Display for ParseMagicError { @@ -376,26 +353,18 @@ impl ServiceFlags { } /// Check whether [ServiceFlags] are included in this one. - pub fn has(self, flags: ServiceFlags) -> bool { - (self.0 | flags.0) == self.0 - } + pub fn has(self, flags: ServiceFlags) -> bool { (self.0 | flags.0) == self.0 } /// Gets the integer representation of this [`ServiceFlags`]. - pub fn to_u64(self) -> u64 { - self.0 - } + pub fn to_u64(self) -> u64 { self.0 } } impl fmt::LowerHex for ServiceFlags { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - fmt::LowerHex::fmt(&self.0, f) - } + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { fmt::LowerHex::fmt(&self.0, f) } } impl fmt::UpperHex for ServiceFlags { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - fmt::UpperHex::fmt(&self.0, f) - } + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { fmt::UpperHex::fmt(&self.0, f) } } impl fmt::Display for ServiceFlags { @@ -415,7 +384,7 @@ impl fmt::Display for ServiceFlags { write!(f, stringify!($f))?; flags.remove(ServiceFlags::$f); } - } + }; } write!(f, "ServiceFlags(")?; write_flag!(NETWORK); @@ -436,43 +405,31 @@ impl fmt::Display for ServiceFlags { } impl From for ServiceFlags { - fn from(f: u64) -> Self { - ServiceFlags(f) - } + fn from(f: u64) -> Self { ServiceFlags(f) } } impl From for u64 { - fn from(flags: ServiceFlags) -> Self { - flags.0 - } + fn from(flags: ServiceFlags) -> Self { flags.0 } } impl ops::BitOr for ServiceFlags { type Output = Self; - fn bitor(mut self, rhs: Self) -> Self { - self.add(rhs) - } + fn bitor(mut self, rhs: Self) -> Self { self.add(rhs) } } impl ops::BitOrAssign for ServiceFlags { - fn bitor_assign(&mut self, rhs: Self) { - self.add(rhs); - } + fn bitor_assign(&mut self, rhs: Self) { self.add(rhs); } } impl ops::BitXor for ServiceFlags { type Output = Self; - fn bitxor(mut self, rhs: Self) -> Self { - self.remove(rhs) - } + fn bitxor(mut self, rhs: Self) -> Self { self.remove(rhs) } } impl ops::BitXorAssign for ServiceFlags { - fn bitxor_assign(&mut self, rhs: Self) { - self.remove(rhs); - } + fn bitxor_assign(&mut self, rhs: Self) { self.remove(rhs); } } impl Encodable for ServiceFlags { @@ -491,11 +448,12 @@ impl Decodable for ServiceFlags { #[cfg(test)] mod tests { - use super::{Network, ServiceFlags, Magic}; - use crate::consensus::encode::{deserialize, serialize}; use std::convert::TryFrom; use std::str::FromStr; + use super::{Magic, Network, ServiceFlags}; + use crate::consensus::encode::{deserialize, serialize}; + #[test] fn serialize_test() { assert_eq!(serialize(&Network::Bitcoin.magic()), &[0xf9, 0xbe, 0xb4, 0xd9]); @@ -507,7 +465,6 @@ mod tests { assert_eq!(deserialize(&[0x0b, 0x11, 0x09, 0x07]).ok(), Some(Network::Testnet.magic())); assert_eq!(deserialize(&[0x0a, 0x03, 0xcf, 0x40]).ok(), Some(Network::Signet.magic())); assert_eq!(deserialize(&[0xfa, 0xbf, 0xb5, 0xda]).ok(), Some(Network::Regtest.magic())); - } #[test] @@ -568,7 +525,12 @@ mod tests { #[cfg(feature = "serde")] fn serde_roundtrip() { use Network::*; - let tests = vec![(Bitcoin, "bitcoin"), (Testnet, "testnet"), (Signet, "signet"), (Regtest, "regtest")]; + let tests = vec![ + (Bitcoin, "bitcoin"), + (Testnet, "testnet"), + (Signet, "signet"), + (Regtest, "regtest"), + ]; for tc in tests { let network = tc.0; diff --git a/bitcoin/src/network/message.rs b/bitcoin/src/network/message.rs index 008a871e..22479796 100644 --- a/bitcoin/src/network/message.rs +++ b/bitcoin/src/network/message.rs @@ -7,24 +7,22 @@ //! are used for (de)serializing Bitcoin objects for transmission on the network. //! -use crate::prelude::*; - -use core::{fmt, iter}; use core::convert::TryFrom; +use core::{fmt, iter}; -use crate::io; use io::Read as _; -use crate::blockdata::block; -use crate::blockdata::transaction; -use crate::network::address::{Address, AddrV2Message}; -use crate::network::{message_network, message_bloom}; -use crate::network::message_blockdata; -use crate::network::message_filter; -use crate::network::message_compact_blocks; -use crate::network::constants::Magic; + +use crate::blockdata::{block, transaction}; use crate::consensus::encode::{CheckedData, Decodable, Encodable, VarInt}; use crate::consensus::{encode, serialize}; +use crate::io; use crate::merkle_tree::MerkleBlock; +use crate::network::address::{AddrV2Message, Address}; +use crate::network::constants::Magic; +use crate::network::{ + message_blockdata, message_bloom, message_compact_blocks, message_filter, message_network, +}; +use crate::prelude::*; /// The maximum number of [super::message_blockdata::Inventory] items in an `inv` message. /// @@ -95,15 +93,11 @@ impl core::str::FromStr for CommandString { } impl fmt::Display for CommandString { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - f.write_str(self.0.as_ref()) - } + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { f.write_str(self.0.as_ref()) } } impl AsRef for CommandString { - fn as_ref(&self) -> &str { - self.0.as_ref() - } + fn as_ref(&self) -> &str { self.0.as_ref() } } impl Encodable for CommandString { @@ -121,11 +115,13 @@ impl Decodable for CommandString { #[inline] fn consensus_decode(r: &mut R) -> Result { let rawbytes: [u8; 12] = Decodable::consensus_decode(r)?; - let rv = iter::FromIterator::from_iter( - rawbytes - .iter() - .filter_map(|&u| if u > 0 { Some(u as char) } else { None }) - ); + let rv = iter::FromIterator::from_iter(rawbytes.iter().filter_map(|&u| { + if u > 0 { + Some(u as char) + } else { + None + } + })); Ok(CommandString(rv)) } } @@ -140,7 +136,12 @@ pub struct CommandStringError { impl fmt::Display for CommandStringError { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - write!(f, "the command string '{}' has length {} which is larger than 12", self.cow, self.cow.len()) + write!( + f, + "the command string '{}' has length {} which is larger than 12", + self.cow, + self.cow.len() + ) } } @@ -152,7 +153,7 @@ pub struct RawNetworkMessage { /// Magic bytes to identify the network these messages are meant for pub magic: Magic, /// The actual message data - pub payload: NetworkMessage + pub payload: NetworkMessage, } /// A Network message payload. Proper documentation is available on at @@ -241,7 +242,7 @@ pub enum NetworkMessage { command: CommandString, /// The payload of this message. payload: Vec, - } + }, } impl NetworkMessage { @@ -253,25 +254,25 @@ impl NetworkMessage { pub fn cmd(&self) -> &'static str { match *self { NetworkMessage::Version(_) => "version", - NetworkMessage::Verack => "verack", - NetworkMessage::Addr(_) => "addr", - NetworkMessage::Inv(_) => "inv", + NetworkMessage::Verack => "verack", + NetworkMessage::Addr(_) => "addr", + NetworkMessage::Inv(_) => "inv", NetworkMessage::GetData(_) => "getdata", NetworkMessage::NotFound(_) => "notfound", NetworkMessage::GetBlocks(_) => "getblocks", NetworkMessage::GetHeaders(_) => "getheaders", - NetworkMessage::MemPool => "mempool", - NetworkMessage::Tx(_) => "tx", - NetworkMessage::Block(_) => "block", + NetworkMessage::MemPool => "mempool", + NetworkMessage::Tx(_) => "tx", + NetworkMessage::Block(_) => "block", NetworkMessage::Headers(_) => "headers", NetworkMessage::SendHeaders => "sendheaders", - NetworkMessage::GetAddr => "getaddr", - NetworkMessage::Ping(_) => "ping", - NetworkMessage::Pong(_) => "pong", + NetworkMessage::GetAddr => "getaddr", + NetworkMessage::Ping(_) => "ping", + NetworkMessage::Pong(_) => "pong", NetworkMessage::MerkleBlock(_) => "merkleblock", NetworkMessage::FilterLoad(_) => "filterload", - NetworkMessage::FilterAdd(_) => "filteradd", - NetworkMessage::FilterClear => "filterclear", + NetworkMessage::FilterAdd(_) => "filteradd", + NetworkMessage::FilterClear => "filterclear", NetworkMessage::GetCFilters(_) => "getcfilters", NetworkMessage::CFilter(_) => "cfilter", NetworkMessage::GetCFHeaders(_) => "getcfheaders", @@ -282,8 +283,8 @@ impl NetworkMessage { NetworkMessage::CmpctBlock(_) => "cmpctblock", NetworkMessage::GetBlockTxn(_) => "getblocktxn", NetworkMessage::BlockTxn(_) => "blocktxn", - NetworkMessage::Alert(_) => "alert", - NetworkMessage::Reject(_) => "reject", + NetworkMessage::Alert(_) => "alert", + NetworkMessage::Reject(_) => "reject", NetworkMessage::FeeFilter(_) => "feefilter", NetworkMessage::WtxidRelay => "wtxidrelay", NetworkMessage::AddrV2(_) => "addrv2", @@ -296,7 +297,7 @@ impl NetworkMessage { pub fn command(&self) -> CommandString { match *self { NetworkMessage::Unknown { command: ref c, .. } => c.clone(), - _ => CommandString::try_from_static(self.cmd()).expect("cmd returns valid commands") + _ => CommandString::try_from_static(self.cmd()).expect("cmd returns valid commands"), } } } @@ -307,14 +308,10 @@ impl RawNetworkMessage { /// This returns `"unknown"` for [NetworkMessage::Unknown], /// regardless of the actual command in the unknown message. /// Use the [Self::command] method to get the command for unknown messages. - pub fn cmd(&self) -> &'static str { - self.payload.cmd() - } + pub fn cmd(&self) -> &'static str { self.payload.cmd() } /// Return the CommandString for the message command. - pub fn command(&self) -> CommandString { - self.payload.command() - } + pub fn command(&self) -> CommandString { self.payload.command() } } struct HeaderSerializationWrapper<'a>(&'a Vec); @@ -339,20 +336,20 @@ impl Encodable for RawNetworkMessage { len += self.command().consensus_encode(w)?; len += CheckedData(match self.payload { NetworkMessage::Version(ref dat) => serialize(dat), - NetworkMessage::Addr(ref dat) => serialize(dat), - NetworkMessage::Inv(ref dat) => serialize(dat), + NetworkMessage::Addr(ref dat) => serialize(dat), + NetworkMessage::Inv(ref dat) => serialize(dat), NetworkMessage::GetData(ref dat) => serialize(dat), NetworkMessage::NotFound(ref dat) => serialize(dat), NetworkMessage::GetBlocks(ref dat) => serialize(dat), NetworkMessage::GetHeaders(ref dat) => serialize(dat), - NetworkMessage::Tx(ref dat) => serialize(dat), - NetworkMessage::Block(ref dat) => serialize(dat), + NetworkMessage::Tx(ref dat) => serialize(dat), + NetworkMessage::Block(ref dat) => serialize(dat), NetworkMessage::Headers(ref dat) => serialize(&HeaderSerializationWrapper(dat)), - NetworkMessage::Ping(ref dat) => serialize(dat), - NetworkMessage::Pong(ref dat) => serialize(dat), - NetworkMessage::MerkleBlock(ref dat) => serialize(dat), - NetworkMessage::FilterLoad(ref dat) => serialize(dat), - NetworkMessage::FilterAdd(ref dat) => serialize(dat), + NetworkMessage::Ping(ref dat) => serialize(dat), + NetworkMessage::Pong(ref dat) => serialize(dat), + NetworkMessage::MerkleBlock(ref dat) => serialize(dat), + NetworkMessage::FilterLoad(ref dat) => serialize(dat), + NetworkMessage::FilterAdd(ref dat) => serialize(dat), NetworkMessage::GetCFilters(ref dat) => serialize(dat), NetworkMessage::CFilter(ref dat) => serialize(dat), NetworkMessage::GetCFHeaders(ref dat) => serialize(dat), @@ -363,7 +360,7 @@ impl Encodable for RawNetworkMessage { NetworkMessage::CmpctBlock(ref dat) => serialize(dat), NetworkMessage::GetBlockTxn(ref dat) => serialize(dat), NetworkMessage::BlockTxn(ref dat) => serialize(dat), - NetworkMessage::Alert(ref dat) => serialize(dat), + NetworkMessage::Alert(ref dat) => serialize(dat), NetworkMessage::Reject(ref dat) => serialize(dat), NetworkMessage::FeeFilter(ref data) => serialize(data), NetworkMessage::AddrV2(ref dat) => serialize(dat), @@ -375,7 +372,8 @@ impl Encodable for RawNetworkMessage { | NetworkMessage::FilterClear | NetworkMessage::SendAddrV2 => vec![], NetworkMessage::Unknown { payload: ref data, .. } => serialize(data), - }).consensus_encode(w)?; + }) + .consensus_encode(w)?; Ok(len) } } @@ -384,7 +382,9 @@ struct HeaderDeserializationWrapper(Vec); impl Decodable for HeaderDeserializationWrapper { #[inline] - fn consensus_decode_from_finite_reader(r: &mut R) -> Result { + fn consensus_decode_from_finite_reader( + r: &mut R, + ) -> Result { let len = VarInt::consensus_decode(r)?.0; // should be above usual number of items to avoid // allocation @@ -392,7 +392,9 @@ impl Decodable for HeaderDeserializationWrapper { for _ in 0..len { ret.push(Decodable::consensus_decode(r)?); if u8::consensus_decode(r)? != 0u8 { - return Err(encode::Error::ParseFailed("Headers message should not contain transactions")); + return Err(encode::Error::ParseFailed( + "Headers message should not contain transactions", + )); } } Ok(HeaderDeserializationWrapper(ret)) @@ -405,60 +407,99 @@ impl Decodable for HeaderDeserializationWrapper { } impl Decodable for RawNetworkMessage { - fn consensus_decode_from_finite_reader(r: &mut R) -> Result { + fn consensus_decode_from_finite_reader( + r: &mut R, + ) -> Result { let magic = Decodable::consensus_decode_from_finite_reader(r)?; let cmd = CommandString::consensus_decode_from_finite_reader(r)?; let raw_payload = CheckedData::consensus_decode_from_finite_reader(r)?.0; let mut mem_d = io::Cursor::new(raw_payload); let payload = match &cmd.0[..] { - "version" => NetworkMessage::Version(Decodable::consensus_decode_from_finite_reader(&mut mem_d)?), - "verack" => NetworkMessage::Verack, - "addr" => NetworkMessage::Addr(Decodable::consensus_decode_from_finite_reader(&mut mem_d)?), - "inv" => NetworkMessage::Inv(Decodable::consensus_decode_from_finite_reader(&mut mem_d)?), - "getdata" => NetworkMessage::GetData(Decodable::consensus_decode_from_finite_reader(&mut mem_d)?), - "notfound" => NetworkMessage::NotFound(Decodable::consensus_decode_from_finite_reader(&mut mem_d)?), - "getblocks" => NetworkMessage::GetBlocks(Decodable::consensus_decode_from_finite_reader(&mut mem_d)?), - "getheaders" => NetworkMessage::GetHeaders(Decodable::consensus_decode_from_finite_reader(&mut mem_d)?), + "version" => + NetworkMessage::Version(Decodable::consensus_decode_from_finite_reader(&mut mem_d)?), + "verack" => NetworkMessage::Verack, + "addr" => + NetworkMessage::Addr(Decodable::consensus_decode_from_finite_reader(&mut mem_d)?), + "inv" => + NetworkMessage::Inv(Decodable::consensus_decode_from_finite_reader(&mut mem_d)?), + "getdata" => + NetworkMessage::GetData(Decodable::consensus_decode_from_finite_reader(&mut mem_d)?), + "notfound" => NetworkMessage::NotFound(Decodable::consensus_decode_from_finite_reader( + &mut mem_d, + )?), + "getblocks" => NetworkMessage::GetBlocks( + Decodable::consensus_decode_from_finite_reader(&mut mem_d)?, + ), + "getheaders" => NetworkMessage::GetHeaders( + Decodable::consensus_decode_from_finite_reader(&mut mem_d)?, + ), "mempool" => NetworkMessage::MemPool, - "block" => NetworkMessage::Block(Decodable::consensus_decode_from_finite_reader(&mut mem_d)?), + "block" => + NetworkMessage::Block(Decodable::consensus_decode_from_finite_reader(&mut mem_d)?), "headers" => NetworkMessage::Headers( - HeaderDeserializationWrapper::consensus_decode_from_finite_reader(&mut mem_d)?.0 + HeaderDeserializationWrapper::consensus_decode_from_finite_reader(&mut mem_d)?.0, ), "sendheaders" => NetworkMessage::SendHeaders, "getaddr" => NetworkMessage::GetAddr, - "ping" => NetworkMessage::Ping(Decodable::consensus_decode_from_finite_reader(&mut mem_d)?), - "pong" => NetworkMessage::Pong(Decodable::consensus_decode_from_finite_reader(&mut mem_d)?), - "merkleblock" => NetworkMessage::MerkleBlock(Decodable::consensus_decode_from_finite_reader(&mut mem_d)?), - "filterload" => NetworkMessage::FilterLoad(Decodable::consensus_decode_from_finite_reader(&mut mem_d)?), - "filteradd" => NetworkMessage::FilterAdd(Decodable::consensus_decode_from_finite_reader(&mut mem_d)?), + "ping" => + NetworkMessage::Ping(Decodable::consensus_decode_from_finite_reader(&mut mem_d)?), + "pong" => + NetworkMessage::Pong(Decodable::consensus_decode_from_finite_reader(&mut mem_d)?), + "merkleblock" => NetworkMessage::MerkleBlock( + Decodable::consensus_decode_from_finite_reader(&mut mem_d)?, + ), + "filterload" => NetworkMessage::FilterLoad( + Decodable::consensus_decode_from_finite_reader(&mut mem_d)?, + ), + "filteradd" => NetworkMessage::FilterAdd( + Decodable::consensus_decode_from_finite_reader(&mut mem_d)?, + ), "filterclear" => NetworkMessage::FilterClear, - "tx" => NetworkMessage::Tx(Decodable::consensus_decode_from_finite_reader(&mut mem_d)?), - "getcfilters" => NetworkMessage::GetCFilters(Decodable::consensus_decode_from_finite_reader(&mut mem_d)?), - "cfilter" => NetworkMessage::CFilter(Decodable::consensus_decode_from_finite_reader(&mut mem_d)?), - "getcfheaders" => NetworkMessage::GetCFHeaders(Decodable::consensus_decode_from_finite_reader(&mut mem_d)?), - "cfheaders" => NetworkMessage::CFHeaders(Decodable::consensus_decode_from_finite_reader(&mut mem_d)?), - "getcfcheckpt" => NetworkMessage::GetCFCheckpt(Decodable::consensus_decode_from_finite_reader(&mut mem_d)?), - "cfcheckpt" => NetworkMessage::CFCheckpt(Decodable::consensus_decode_from_finite_reader(&mut mem_d)?), - "reject" => NetworkMessage::Reject(Decodable::consensus_decode_from_finite_reader(&mut mem_d)?), - "alert" => NetworkMessage::Alert(Decodable::consensus_decode_from_finite_reader(&mut mem_d)?), - "feefilter" => NetworkMessage::FeeFilter(Decodable::consensus_decode_from_finite_reader(&mut mem_d)?), - "sendcmpct" => NetworkMessage::SendCmpct(Decodable::consensus_decode_from_finite_reader(&mut mem_d)?), - "cmpctblock" => NetworkMessage::CmpctBlock(Decodable::consensus_decode_from_finite_reader(&mut mem_d)?), - "getblocktxn" => NetworkMessage::GetBlockTxn(Decodable::consensus_decode_from_finite_reader(&mut mem_d)?), - "blocktxn" => NetworkMessage::BlockTxn(Decodable::consensus_decode_from_finite_reader(&mut mem_d)?), + "tx" => NetworkMessage::Tx(Decodable::consensus_decode_from_finite_reader(&mut mem_d)?), + "getcfilters" => NetworkMessage::GetCFilters( + Decodable::consensus_decode_from_finite_reader(&mut mem_d)?, + ), + "cfilter" => + NetworkMessage::CFilter(Decodable::consensus_decode_from_finite_reader(&mut mem_d)?), + "getcfheaders" => NetworkMessage::GetCFHeaders( + Decodable::consensus_decode_from_finite_reader(&mut mem_d)?, + ), + "cfheaders" => NetworkMessage::CFHeaders( + Decodable::consensus_decode_from_finite_reader(&mut mem_d)?, + ), + "getcfcheckpt" => NetworkMessage::GetCFCheckpt( + Decodable::consensus_decode_from_finite_reader(&mut mem_d)?, + ), + "cfcheckpt" => NetworkMessage::CFCheckpt( + Decodable::consensus_decode_from_finite_reader(&mut mem_d)?, + ), + "reject" => + NetworkMessage::Reject(Decodable::consensus_decode_from_finite_reader(&mut mem_d)?), + "alert" => + NetworkMessage::Alert(Decodable::consensus_decode_from_finite_reader(&mut mem_d)?), + "feefilter" => NetworkMessage::FeeFilter( + Decodable::consensus_decode_from_finite_reader(&mut mem_d)?, + ), + "sendcmpct" => NetworkMessage::SendCmpct( + Decodable::consensus_decode_from_finite_reader(&mut mem_d)?, + ), + "cmpctblock" => NetworkMessage::CmpctBlock( + Decodable::consensus_decode_from_finite_reader(&mut mem_d)?, + ), + "getblocktxn" => NetworkMessage::GetBlockTxn( + Decodable::consensus_decode_from_finite_reader(&mut mem_d)?, + ), + "blocktxn" => NetworkMessage::BlockTxn(Decodable::consensus_decode_from_finite_reader( + &mut mem_d, + )?), "wtxidrelay" => NetworkMessage::WtxidRelay, - "addrv2" => NetworkMessage::AddrV2(Decodable::consensus_decode_from_finite_reader(&mut mem_d)?), + "addrv2" => + NetworkMessage::AddrV2(Decodable::consensus_decode_from_finite_reader(&mut mem_d)?), "sendaddrv2" => NetworkMessage::SendAddrV2, - _ => NetworkMessage::Unknown { - command: cmd, - payload: mem_d.into_inner(), - } + _ => NetworkMessage::Unknown { command: cmd, payload: mem_d.into_inner() }, }; - Ok(RawNetworkMessage { - magic, - payload, - }) + Ok(RawNetworkMessage { magic, payload }) } #[inline] @@ -469,29 +510,28 @@ impl Decodable for RawNetworkMessage { #[cfg(test)] mod test { - use super::*; - use std::net::Ipv4Addr; - use super::{RawNetworkMessage, NetworkMessage, CommandString}; - use crate::network::constants::{ServiceFlags, Magic, Network}; + + use super::message_network::{Reject, RejectReason, VersionMessage}; + use super::{CommandString, NetworkMessage, RawNetworkMessage, *}; + use crate::bip152::BlockTransactionsRequest; + use crate::blockdata::block::{self, Block}; + use crate::blockdata::script::Script; + use crate::blockdata::transaction::Transaction; use crate::consensus::encode::{deserialize, deserialize_partial, serialize}; use crate::hashes::hex::FromHex; use crate::hashes::sha256d::Hash; use crate::hashes::Hash as HashTrait; - use crate::network::address::{Address, AddrV2, AddrV2Message}; - use super::message_network::{Reject, RejectReason, VersionMessage}; - use crate::network::message_blockdata::{Inventory, GetBlocksMessage, GetHeadersMessage}; - use crate::blockdata::block::{self, Block}; - use crate::network::message_filter::{GetCFilters, CFilter, GetCFHeaders, CFHeaders, GetCFCheckpt, CFCheckpt}; - use crate::blockdata::transaction::Transaction; - use crate::blockdata::script::Script; - use crate::network::message_bloom::{FilterAdd, FilterLoad, BloomFlags}; + use crate::network::address::{AddrV2, AddrV2Message, Address}; + use crate::network::constants::{Magic, Network, ServiceFlags}; + use crate::network::message_blockdata::{GetBlocksMessage, GetHeadersMessage, Inventory}; + use crate::network::message_bloom::{BloomFlags, FilterAdd, FilterLoad}; use crate::network::message_compact_blocks::{GetBlockTxn, SendCmpct}; - use crate::bip152::BlockTransactionsRequest; + use crate::network::message_filter::{ + CFCheckpt, CFHeaders, CFilter, GetCFCheckpt, GetCFHeaders, GetCFilters, + }; - fn hash(slice: [u8;32]) -> Hash { - Hash::from_slice(&slice).unwrap() - } + fn hash(slice: [u8; 32]) -> Hash { Hash::from_slice(&slice).unwrap() } #[test] fn full_round_ser_der_raw_network_message_test() { @@ -500,21 +540,32 @@ mod test { let tx: Transaction = deserialize(&Vec::from_hex("0100000001a15d57094aa7a21a28cb20b59aab8fc7d1149a3bdbcddba9c622e4f5f6a99ece010000006c493046022100f93bb0e7d8db7bd46e40132d1f8242026e045f03a0efe71bbb8e3f475e970d790221009337cd7f1f929f00cc6ff01f03729b069a7c21b59b1736ddfee5db5946c5da8c0121033b9b137ee87d5a812d6f506efdd37f0affa7ffc310711c06c7f3e097c9447c52ffffffff0100e1f505000000001976a9140389035a9225b3839e2bbf32d826a1e222031fd888ac00000000").unwrap()).unwrap(); let block: Block = deserialize(&include_bytes!("../../tests/data/testnet_block_000000000000045e0b1660b6445b5e5c5ab63c9a4f956be7e1e69be04fa4497b.raw")[..]).unwrap(); let header: block::Header = deserialize(&Vec::from_hex("010000004ddccd549d28f385ab457e98d1b11ce80bfea2c5ab93015ade4973e400000000bf4473e53794beae34e64fccc471dace6ae544180816f89591894e0f417a914cd74d6e49ffff001d323b3a7b").unwrap()).unwrap(); - let script: Script = deserialize(&Vec::from_hex("1976a91431a420903c05a0a7de2de40c9f02ebedbacdc17288ac").unwrap()).unwrap(); + let script: Script = deserialize( + &Vec::from_hex("1976a91431a420903c05a0a7de2de40c9f02ebedbacdc17288ac").unwrap(), + ) + .unwrap(); let merkle_block: MerkleBlock = deserialize(&Vec::from_hex("0100000079cda856b143d9db2c1caff01d1aecc8630d30625d10e8b4b8b0000000000000b50cc069d6a3e33e3ff84a5c41d9d3febe7c770fdcc96b2c3ff60abe184f196367291b4d4c86041b8fa45d630100000001b50cc069d6a3e33e3ff84a5c41d9d3febe7c770fdcc96b2c3ff60abe184f19630101").unwrap()).unwrap(); let cmptblock = deserialize(&Vec::from_hex("00000030d923ad36ff2d955abab07f8a0a6e813bc6e066b973e780c5e36674cad5d1cd1f6e265f2a17a0d35cbe701fe9d06e2c6324cfe135f6233e8b767bfa3fb4479b71115dc562ffff7f2006000000000000000000000000010002000000010000000000000000000000000000000000000000000000000000000000000000ffffffff0302ee00ffffffff0100f9029500000000015100000000").unwrap()).unwrap(); let blocktxn = deserialize(&Vec::from_hex("2e93c0cff39ff605020072d96bc3a8d20b8447e294d08092351c8583e08d9b5a01020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff0402dc0000ffffffff0200f90295000000001976a9142b4569203694fc997e13f2c0a1383b9e16c77a0d88ac0000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000000000000").unwrap()).unwrap(); - let msgs = vec![ NetworkMessage::Version(version_msg), NetworkMessage::Verack, - NetworkMessage::Addr(vec![(45, Address::new(&([123,255,000,100], 833).into(), ServiceFlags::NETWORK))]), + NetworkMessage::Addr(vec![( + 45, + Address::new(&([123, 255, 000, 100], 833).into(), ServiceFlags::NETWORK), + )]), NetworkMessage::Inv(vec![Inventory::Block(hash([8u8; 32]).into())]), NetworkMessage::GetData(vec![Inventory::Transaction(hash([45u8; 32]).into())]), NetworkMessage::NotFound(vec![Inventory::Error]), - NetworkMessage::GetBlocks(GetBlocksMessage::new(vec![hash([1u8; 32]).into(), hash([4u8; 32]).into()], hash([5u8; 32]).into())), - NetworkMessage::GetHeaders(GetHeadersMessage::new(vec![hash([10u8; 32]).into(), hash([40u8; 32]).into()], hash([50u8; 32]).into())), + NetworkMessage::GetBlocks(GetBlocksMessage::new( + vec![hash([1u8; 32]).into(), hash([4u8; 32]).into()], + hash([5u8; 32]).into(), + )), + NetworkMessage::GetHeaders(GetHeadersMessage::new( + vec![hash([10u8; 32]).into(), hash([40u8; 32]).into()], + hash([50u8; 32]).into(), + )), NetworkMessage::MemPool, NetworkMessage::Tx(tx), NetworkMessage::Block(block), @@ -524,39 +575,86 @@ mod test { NetworkMessage::Ping(15), NetworkMessage::Pong(23), NetworkMessage::MerkleBlock(merkle_block), - NetworkMessage::FilterLoad(FilterLoad {filter: Vec::from_hex("03614e9b050000000000000001").unwrap(), hash_funcs: 1, tweak: 2, flags: BloomFlags::All}), - NetworkMessage::FilterAdd(FilterAdd {data: script.as_bytes().to_vec()}), - NetworkMessage::FilterAdd(FilterAdd {data: hash([29u8; 32]).to_vec()}), + NetworkMessage::FilterLoad(FilterLoad { + filter: Vec::from_hex("03614e9b050000000000000001").unwrap(), + hash_funcs: 1, + tweak: 2, + flags: BloomFlags::All, + }), + NetworkMessage::FilterAdd(FilterAdd { data: script.as_bytes().to_vec() }), + NetworkMessage::FilterAdd(FilterAdd { data: hash([29u8; 32]).to_vec() }), NetworkMessage::FilterClear, - NetworkMessage::GetCFilters(GetCFilters{filter_type: 2, start_height: 52, stop_hash: hash([42u8; 32]).into()}), - NetworkMessage::CFilter(CFilter{filter_type: 7, block_hash: hash([25u8; 32]).into(), filter: vec![1,2,3]}), - NetworkMessage::GetCFHeaders(GetCFHeaders{filter_type: 4, start_height: 102, stop_hash: hash([47u8; 32]).into()}), - NetworkMessage::CFHeaders(CFHeaders{filter_type: 13, stop_hash: hash([53u8; 32]).into(), previous_filter_header: hash([12u8; 32]).into(), filter_hashes: vec![hash([4u8; 32]).into(), hash([12u8; 32]).into()]}), - NetworkMessage::GetCFCheckpt(GetCFCheckpt{filter_type: 17, stop_hash: hash([25u8; 32]).into()}), - NetworkMessage::CFCheckpt(CFCheckpt{filter_type: 27, stop_hash: hash([77u8; 32]).into(), filter_headers: vec![hash([3u8; 32]).into(), hash([99u8; 32]).into()]}), - NetworkMessage::Alert(vec![45,66,3,2,6,8,9,12,3,130]), - NetworkMessage::Reject(Reject{message: "Test reject".into(), ccode: RejectReason::Duplicate, reason: "Cause".into(), hash: hash([255u8; 32])}), + NetworkMessage::GetCFilters(GetCFilters { + filter_type: 2, + start_height: 52, + stop_hash: hash([42u8; 32]).into(), + }), + NetworkMessage::CFilter(CFilter { + filter_type: 7, + block_hash: hash([25u8; 32]).into(), + filter: vec![1, 2, 3], + }), + NetworkMessage::GetCFHeaders(GetCFHeaders { + filter_type: 4, + start_height: 102, + stop_hash: hash([47u8; 32]).into(), + }), + NetworkMessage::CFHeaders(CFHeaders { + filter_type: 13, + stop_hash: hash([53u8; 32]).into(), + previous_filter_header: hash([12u8; 32]).into(), + filter_hashes: vec![hash([4u8; 32]).into(), hash([12u8; 32]).into()], + }), + NetworkMessage::GetCFCheckpt(GetCFCheckpt { + filter_type: 17, + stop_hash: hash([25u8; 32]).into(), + }), + NetworkMessage::CFCheckpt(CFCheckpt { + filter_type: 27, + stop_hash: hash([77u8; 32]).into(), + filter_headers: vec![hash([3u8; 32]).into(), hash([99u8; 32]).into()], + }), + NetworkMessage::Alert(vec![45, 66, 3, 2, 6, 8, 9, 12, 3, 130]), + NetworkMessage::Reject(Reject { + message: "Test reject".into(), + ccode: RejectReason::Duplicate, + reason: "Cause".into(), + hash: hash([255u8; 32]), + }), NetworkMessage::FeeFilter(1000), NetworkMessage::WtxidRelay, - NetworkMessage::AddrV2(vec![AddrV2Message{ addr: AddrV2::Ipv4(Ipv4Addr::new(127, 0, 0, 1)), port: 0, services: ServiceFlags::NONE, time: 0 }]), + NetworkMessage::AddrV2(vec![AddrV2Message { + addr: AddrV2::Ipv4(Ipv4Addr::new(127, 0, 0, 1)), + port: 0, + services: ServiceFlags::NONE, + time: 0, + }]), NetworkMessage::SendAddrV2, NetworkMessage::CmpctBlock(cmptblock), - NetworkMessage::GetBlockTxn(GetBlockTxn { txs_request: BlockTransactionsRequest { block_hash: hash([11u8; 32]).into(), indexes: vec![0, 1, 2, 3, 10, 3002] } }), + NetworkMessage::GetBlockTxn(GetBlockTxn { + txs_request: BlockTransactionsRequest { + block_hash: hash([11u8; 32]).into(), + indexes: vec![0, 1, 2, 3, 10, 3002], + }, + }), NetworkMessage::BlockTxn(blocktxn), - NetworkMessage::SendCmpct(SendCmpct{send_compact: true, version: 8333}), + NetworkMessage::SendCmpct(SendCmpct { send_compact: true, version: 8333 }), ]; for msg in msgs { - let raw_msg = RawNetworkMessage {magic: Magic::from_bytes([57, 0, 0, 0]), payload: msg}; + let raw_msg = + RawNetworkMessage { magic: Magic::from_bytes([57, 0, 0, 0]), payload: msg }; assert_eq!(deserialize::(&serialize(&raw_msg)).unwrap(), raw_msg); } - } #[test] fn commandstring_test() { // Test converting. - assert_eq!(CommandString::try_from_static("AndrewAndrew").unwrap().as_ref(), "AndrewAndrew"); + assert_eq!( + CommandString::try_from_static("AndrewAndrew").unwrap().as_ref(), + "AndrewAndrew" + ); assert!(CommandString::try_from_static("AndrewAndrewA").is_err()); // Test serializing. @@ -564,12 +662,14 @@ mod test { assert_eq!(serialize(&cs), vec![0x41u8, 0x6e, 0x64, 0x72, 0x65, 0x77, 0, 0, 0, 0, 0, 0]); // Test deserializing - let cs: Result = deserialize(&[0x41u8, 0x6e, 0x64, 0x72, 0x65, 0x77, 0, 0, 0, 0, 0, 0]); + let cs: Result = + deserialize(&[0x41u8, 0x6e, 0x64, 0x72, 0x65, 0x77, 0, 0, 0, 0, 0, 0]); assert!(cs.is_ok()); assert_eq!(cs.as_ref().unwrap().to_string(), "Andrew".to_owned()); assert_eq!(cs.unwrap(), CommandString::try_from_static("Andrew").unwrap()); - let short_cs: Result = deserialize(&[0x41u8, 0x6e, 0x64, 0x72, 0x65, 0x77, 0, 0, 0, 0, 0]); + let short_cs: Result = + deserialize(&[0x41u8, 0x6e, 0x64, 0x72, 0x65, 0x77, 0, 0, 0, 0, 0]); assert!(short_cs.is_err()); } @@ -592,7 +692,6 @@ mod test { 0x64, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00]); } - #[test] #[rustfmt::skip] fn serialize_mempool_test() { @@ -619,9 +718,12 @@ mod test { 0x64, 0x64, 0x72, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x5d, 0xf6, 0xe0, 0xe2 ]); - let preimage = RawNetworkMessage { magic: Magic::from(Network::Bitcoin), payload: NetworkMessage::GetAddr }; + let preimage = RawNetworkMessage { + magic: Magic::from(Network::Bitcoin), + payload: NetworkMessage::GetAddr, + }; assert!(msg.is_ok()); - let msg : RawNetworkMessage = msg.unwrap(); + let msg: RawNetworkMessage = msg.unwrap(); assert_eq!(preimage.magic, msg.magic); assert_eq!(preimage.payload, msg.payload); } @@ -653,7 +755,13 @@ mod test { assert_eq!(msg.magic, Magic::from(Network::Bitcoin)); if let NetworkMessage::Version(version_msg) = msg.payload { assert_eq!(version_msg.version, 70015); - assert_eq!(version_msg.services, ServiceFlags::NETWORK | ServiceFlags::BLOOM | ServiceFlags::WITNESS | ServiceFlags::NETWORK_LIMITED); + assert_eq!( + version_msg.services, + ServiceFlags::NETWORK + | ServiceFlags::BLOOM + | ServiceFlags::WITNESS + | ServiceFlags::NETWORK_LIMITED + ); assert_eq!(version_msg.timestamp, 1548554224); assert_eq!(version_msg.nonce, 13952548347456104954); assert_eq!(version_msg.user_agent, "/Satoshi:0.17.1/"); @@ -693,7 +801,13 @@ mod test { assert_eq!(msg.magic, Magic::from(Network::Bitcoin)); if let NetworkMessage::Version(version_msg) = msg.payload { assert_eq!(version_msg.version, 70015); - assert_eq!(version_msg.services, ServiceFlags::NETWORK | ServiceFlags::BLOOM | ServiceFlags::WITNESS | ServiceFlags::NETWORK_LIMITED); + assert_eq!( + version_msg.services, + ServiceFlags::NETWORK + | ServiceFlags::BLOOM + | ServiceFlags::WITNESS + | ServiceFlags::NETWORK_LIMITED + ); assert_eq!(version_msg.timestamp, 1548554224); assert_eq!(version_msg.nonce, 13952548347456104954); assert_eq!(version_msg.user_agent, "/Satoshi:0.17.1/"); diff --git a/bitcoin/src/network/message_blockdata.rs b/bitcoin/src/network/message_blockdata.rs index 0e51748f..8521616d 100644 --- a/bitcoin/src/network/message_blockdata.rs +++ b/bitcoin/src/network/message_blockdata.rs @@ -7,16 +7,13 @@ //! Bitcoin data (blocks and transactions) around. //! -use crate::prelude::*; - -use crate::io; - -use crate::hashes::{Hash as _, sha256d}; - -use crate::network::constants; use crate::consensus::encode::{self, Decodable, Encodable}; use crate::hash_types::{BlockHash, Txid, Wtxid}; +use crate::hashes::{sha256d, Hash as _}; use crate::internal_macros::impl_consensus_encoding; +use crate::io; +use crate::network::constants; +use crate::prelude::*; /// An inventory item. #[derive(PartialEq, Eq, Clone, Debug, Copy, Hash, PartialOrd, Ord)] @@ -41,7 +38,7 @@ pub enum Inventory { inv_type: u32, /// The hash of the inventory item hash: [u8; 32], - } + }, } impl Encodable for Inventory { @@ -50,7 +47,7 @@ impl Encodable for Inventory { macro_rules! encode_inv { ($code:expr, $item:expr) => { u32::consensus_encode(&$code, w)? + $item.consensus_encode(w)? - } + }; } Ok(match *self { Inventory::Error => encode_inv!(0, sha256d::Hash::all_zeros()), @@ -77,10 +74,7 @@ impl Decodable for Inventory { 5 => Inventory::WTx(Decodable::consensus_decode(r)?), 0x40000001 => Inventory::WitnessTransaction(Decodable::consensus_decode(r)?), 0x40000002 => Inventory::WitnessBlock(Decodable::consensus_decode(r)?), - tp => Inventory::Unknown { - inv_type: tp, - hash: Decodable::consensus_decode(r)?, - } + tp => Inventory::Unknown { inv_type: tp, hash: Decodable::consensus_decode(r)? }, }) } } @@ -110,17 +104,13 @@ pub struct GetHeadersMessage { /// if possible and block 1 otherwise. pub locator_hashes: Vec, /// References the header to stop at, or zero to just fetch the maximum 2000 headers - pub stop_hash: BlockHash + pub stop_hash: BlockHash, } impl GetBlocksMessage { /// Construct a new `getblocks` message pub fn new(locator_hashes: Vec, stop_hash: BlockHash) -> GetBlocksMessage { - GetBlocksMessage { - version: constants::PROTOCOL_VERSION, - locator_hashes, - stop_hash, - } + GetBlocksMessage { version: constants::PROTOCOL_VERSION, locator_hashes, stop_hash } } } @@ -129,11 +119,7 @@ impl_consensus_encoding!(GetBlocksMessage, version, locator_hashes, stop_hash); impl GetHeadersMessage { /// Construct a new `getheaders` message pub fn new(locator_hashes: Vec, stop_hash: BlockHash) -> GetHeadersMessage { - GetHeadersMessage { - version: constants::PROTOCOL_VERSION, - locator_hashes, - stop_hash, - } + GetHeadersMessage { version: constants::PROTOCOL_VERSION, locator_hashes, stop_hash } } } @@ -141,16 +127,17 @@ impl_consensus_encoding!(GetHeadersMessage, version, locator_hashes, stop_hash); #[cfg(test)] mod tests { - use super::{Vec, GetHeadersMessage, GetBlocksMessage}; - + use super::{GetBlocksMessage, GetHeadersMessage, Vec}; + use crate::consensus::encode::{deserialize, serialize}; use crate::hashes::hex::FromHex; use crate::hashes::Hash; - use crate::consensus::encode::{deserialize, serialize}; #[test] fn getblocks_message_test() { let from_sat = Vec::from_hex("72110100014a5e1e4baab89f3a32518a88c31bc87f618f76673e2cc77ab2127b7afdeda33b0000000000000000000000000000000000000000000000000000000000000000").unwrap(); - let genhash = Vec::from_hex("4a5e1e4baab89f3a32518a88c31bc87f618f76673e2cc77ab2127b7afdeda33b").unwrap(); + let genhash = + Vec::from_hex("4a5e1e4baab89f3a32518a88c31bc87f618f76673e2cc77ab2127b7afdeda33b") + .unwrap(); let decode: Result = deserialize(&from_sat); assert!(decode.is_ok()); @@ -166,7 +153,9 @@ mod tests { #[test] fn getheaders_message_test() { let from_sat = Vec::from_hex("72110100014a5e1e4baab89f3a32518a88c31bc87f618f76673e2cc77ab2127b7afdeda33b0000000000000000000000000000000000000000000000000000000000000000").unwrap(); - let genhash = Vec::from_hex("4a5e1e4baab89f3a32518a88c31bc87f618f76673e2cc77ab2127b7afdeda33b").unwrap(); + let genhash = + Vec::from_hex("4a5e1e4baab89f3a32518a88c31bc87f618f76673e2cc77ab2127b7afdeda33b") + .unwrap(); let decode: Result = deserialize(&from_sat); assert!(decode.is_ok()); diff --git a/bitcoin/src/network/message_bloom.rs b/bitcoin/src/network/message_bloom.rs index 31430869..e3dcbe18 100644 --- a/bitcoin/src/network/message_bloom.rs +++ b/bitcoin/src/network/message_bloom.rs @@ -5,11 +5,11 @@ //! This module describes BIP37 Connection Bloom filtering network messages. //! -use crate::consensus::encode; -use crate::consensus::{Decodable, Encodable, ReadExt}; -use crate::internal_macros::impl_consensus_encoding; use std::io; +use crate::consensus::{encode, Decodable, Encodable, ReadExt}; +use crate::internal_macros::impl_consensus_encoding; + /// `filterload` message sets the current bloom filter #[derive(Clone, PartialEq, Eq, Debug)] pub struct FilterLoad { diff --git a/bitcoin/src/network/message_compact_blocks.rs b/bitcoin/src/network/message_compact_blocks.rs index 6a92a15d..8827e543 100644 --- a/bitcoin/src/network/message_compact_blocks.rs +++ b/bitcoin/src/network/message_compact_blocks.rs @@ -2,8 +2,8 @@ //! BIP152 Compact Blocks network messages //! -use crate::internal_macros::impl_consensus_encoding; use crate::bip152; +use crate::internal_macros::impl_consensus_encoding; /// sendcmpct message #[derive(PartialEq, Eq, Clone, Debug, Copy, PartialOrd, Ord, Hash)] diff --git a/bitcoin/src/network/message_network.rs b/bitcoin/src/network/message_network.rs index 1db65b82..b8ac228e 100644 --- a/bitcoin/src/network/message_network.rs +++ b/bitcoin/src/network/message_network.rs @@ -7,16 +7,13 @@ //! capabilities. //! -use crate::prelude::*; - -use crate::io; - -use crate::network::address::Address; -use crate::network::constants::{self, ServiceFlags}; -use crate::consensus::{Encodable, Decodable, ReadExt}; -use crate::consensus::encode; +use crate::consensus::{encode, Decodable, Encodable, ReadExt}; use crate::hashes::sha256d; use crate::internal_macros::impl_consensus_encoding; +use crate::io; +use crate::network::address::Address; +use crate::network::constants::{self, ServiceFlags}; +use crate::prelude::*; /// Some simple messages @@ -42,7 +39,7 @@ pub struct VersionMessage { /// Whether the receiving peer should relay messages to the sender; used /// if the sender is bandwidth-limited and would like to support bloom /// filtering. Defaults to false. - pub relay: bool + pub relay: bool, } impl VersionMessage { @@ -70,9 +67,18 @@ impl VersionMessage { } } -impl_consensus_encoding!(VersionMessage, version, services, timestamp, - receiver, sender, nonce, - user_agent, start_height, relay); +impl_consensus_encoding!( + VersionMessage, + version, + services, + timestamp, + receiver, + sender, + nonce, + user_agent, + start_height, + relay +); /// message rejection reason as a code #[derive(PartialEq, Eq, Clone, Copy, Debug)] @@ -92,7 +98,7 @@ pub enum RejectReason { /// insufficient fee Fee = 0x42, /// checkpoint - Checkpoint = 0x43 + Checkpoint = 0x43, } impl Encodable for RejectReason { @@ -113,7 +119,7 @@ impl Decodable for RejectReason { 0x41 => RejectReason::Dust, 0x42 => RejectReason::Fee, 0x43 => RejectReason::Checkpoint, - _ => return Err(encode::Error::ParseFailed("unknown reject code")) + _ => return Err(encode::Error::ParseFailed("unknown reject code")), }) } } @@ -128,23 +134,19 @@ pub struct Reject { /// reason of rejectection pub reason: Cow<'static, str>, /// reference to rejected item - pub hash: sha256d::Hash + pub hash: sha256d::Hash, } impl_consensus_encoding!(Reject, message, ccode, reason, hash); #[cfg(test)] mod tests { - use super::VersionMessage; - use super::Reject; - use super::RejectReason; - + use super::{Reject, RejectReason, VersionMessage}; + use crate::consensus::encode::{deserialize, serialize}; use crate::hashes::hex::FromHex; use crate::hashes::sha256d::Hash; use crate::network::constants::ServiceFlags; - use crate::consensus::encode::{deserialize, serialize}; - #[test] fn version_message_test() { // This message is from my satoshi node, morning of May 27 2014 @@ -181,7 +183,8 @@ mod tests { assert_eq!(RejectReason::Duplicate, conflict.ccode); assert_eq!("txn-mempool-conflict", conflict.reason); assert_eq!( - Hash::from_hex("0470f4f2dc4191221b59884bcffaaf00932748ab46356a80413c0b86d354df05").unwrap(), + Hash::from_hex("0470f4f2dc4191221b59884bcffaaf00932748ab46356a80413c0b86d354df05") + .unwrap(), conflict.hash ); @@ -190,7 +193,8 @@ mod tests { assert_eq!(RejectReason::NonStandard, nonfinal.ccode); assert_eq!("non-final", nonfinal.reason); assert_eq!( - Hash::from_hex("0b46a539138b5fde4e341b37f2d945c23d41193b30caa7fcbd8bdb836cbe9b25").unwrap(), + Hash::from_hex("0b46a539138b5fde4e341b37f2d945c23d41193b30caa7fcbd8bdb836cbe9b25") + .unwrap(), nonfinal.hash ); diff --git a/bitcoin/src/network/mod.rs b/bitcoin/src/network/mod.rs index dfefbb6f..0450156f 100644 --- a/bitcoin/src/network/mod.rs +++ b/bitcoin/src/network/mod.rs @@ -29,7 +29,7 @@ pub mod message_bloom; pub mod message_compact_blocks; #[cfg(feature = "std")] #[cfg_attr(docsrs, doc(cfg(feature = "std")))] -pub mod message_network; +pub mod message_filter; #[cfg(feature = "std")] #[cfg_attr(docsrs, doc(cfg(feature = "std")))] -pub mod message_filter; +pub mod message_network;