diff --git a/src/network/address.rs b/src/network/address.rs index 707ee93f..6ac93735 100644 --- a/src/network/address.rs +++ b/src/network/address.rs @@ -33,15 +33,17 @@ pub struct Address { pub port: u16 } +fn addr_to_be(addr: [u16; 8]) -> [u16; 8] { + [addr[0].to_be(), addr[1].to_be(), addr[2].to_be(), addr[3].to_be(), + addr[4].to_be(), addr[5].to_be(), addr[6].to_be(), addr[7].to_be()] +} + impl ConsensusEncodable for Address { #[inline] fn consensus_encode(&self, s: &mut S) -> Result<(), S::Error> { try!(self.services.consensus_encode(s)); - try!(self.address.consensus_encode(s)); - // Explicitly code the port since it needs to be big-endian - try!(((self.port / 0x100) as u8).consensus_encode(s)); - try!(((self.port % 0x100) as u8).consensus_encode(s)); - Ok(()) + try!(addr_to_be(self.address).consensus_encode(s)); + self.port.to_be().consensus_encode(s) } } @@ -50,13 +52,8 @@ impl ConsensusDecodable for Address { fn consensus_decode(d: &mut D) -> Result { Ok(Address { services: try!(ConsensusDecodable::consensus_decode(d)), - address: try!(ConsensusDecodable::consensus_decode(d)), - // Explicitly code the port since it needs to be big-endian - port: { - let b1: u8 = try!(ConsensusDecodable::consensus_decode(d)); - let b2: u8 = try!(ConsensusDecodable::consensus_decode(d)); - (b1 as u16 * 0x100) + (b2 as u16) - } + address: addr_to_be(try!(ConsensusDecodable::consensus_decode(d))), + port: u16::from_be(try!(ConsensusDecodable::consensus_decode(d))) }) } } @@ -117,9 +114,9 @@ mod test { 0, 1, 0x20, 0x8d]); assert!(addr.is_ok()); let full = addr.unwrap(); - assert!(full.services == 1); - assert!(full.address == [0, 0, 0, 0, 0, 0xffff, 0x0a00, 0x0001]); - assert!(full.port == 8333); + assert_eq!(full.services, 1); + 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]); diff --git a/src/network/encodable.rs b/src/network/encodable.rs index 8b0f7a00..ac2ce445 100644 --- a/src/network/encodable.rs +++ b/src/network/encodable.rs @@ -59,35 +59,28 @@ pub struct VarInt(pub u64); pub struct CheckedData(pub Vec); // Primitive types -impl ConsensusEncodable for u8 { - #[inline] - fn consensus_encode(&self, s: &mut S) -> Result<(), S::Error> { s.emit_u8(*self) } +macro_rules! impl_int_encodable{ + ($ty:ident, $meth_dec:ident, $meth_enc:ident) => ( + impl ConsensusDecodable for $ty { + #[inline] + fn consensus_decode(d: &mut D) -> Result<$ty, D::Error> { d.$meth_dec().map($ty::from_le) } + } + + impl ConsensusEncodable for $ty { + #[inline] + fn consensus_encode(&self, s: &mut S) -> Result<(), S::Error> { s.$meth_enc(self.to_le()) } + } + ) } -impl ConsensusEncodable for u16 { - #[inline] - fn consensus_encode(&self, s: &mut S) -> Result<(), S::Error> { s.emit_u16(self.to_le()) } -} - -impl ConsensusEncodable for u32 { - #[inline] - fn consensus_encode(&self, s: &mut S) -> Result<(), S::Error> { s.emit_u32(self.to_le()) } -} - -impl ConsensusEncodable for u64 { - #[inline] - fn consensus_encode(&self, s: &mut S) -> Result<(), S::Error> { s.emit_u64(self.to_le()) } -} - -impl ConsensusEncodable for i32 { - #[inline] - fn consensus_encode(&self, s: &mut S) -> Result<(), S::Error> { s.emit_i32(self.to_le()) } -} - -impl ConsensusEncodable for i64 { - #[inline] - fn consensus_encode(&self, s: &mut S) -> Result<(), S::Error> { s.emit_i64(self.to_le()) } -} +impl_int_encodable!(u8, read_u8, emit_u8); +impl_int_encodable!(u16, read_u16, emit_u16); +impl_int_encodable!(u32, read_u32, emit_u32); +impl_int_encodable!(u64, read_u64, emit_u64); +impl_int_encodable!(i8, read_i8, emit_i8); +impl_int_encodable!(i16, read_i16, emit_i16); +impl_int_encodable!(i32, read_i32, emit_i32); +impl_int_encodable!(i64, read_i64, emit_i64); impl ConsensusEncodable for VarInt { #[inline] @@ -101,36 +94,6 @@ impl ConsensusEncodable for VarInt { } } -impl ConsensusDecodable for u8 { - #[inline] - fn consensus_decode(d: &mut D) -> Result { d.read_u8() } -} - -impl ConsensusDecodable for u16 { - #[inline] - fn consensus_decode(d: &mut D) -> Result { d.read_u16().map(|n| u16::from_le(n)) } -} - -impl ConsensusDecodable for u32 { - #[inline] - fn consensus_decode(d: &mut D) -> Result { d.read_u32().map(|n| u32::from_le(n)) } -} - -impl ConsensusDecodable for u64 { - #[inline] - fn consensus_decode(d: &mut D) -> Result { d.read_u64().map(|n| u64::from_le(n)) } -} - -impl ConsensusDecodable for i32 { - #[inline] - fn consensus_decode(d: &mut D) -> Result { d.read_i32().map(|n| i32::from_le(n)) } -} - -impl ConsensusDecodable for i64 { - #[inline] - fn consensus_decode(d: &mut D) -> Result { d.read_i64().map(|n| i64::from_le(n)) } -} - impl ConsensusDecodable for VarInt { #[inline] fn consensus_decode(d: &mut D) -> Result {