diff --git a/misc/multiaddr/Cargo.toml b/misc/multiaddr/Cargo.toml index b3f769b5..9ad1484b 100644 --- a/misc/multiaddr/Cargo.toml +++ b/misc/multiaddr/Cargo.toml @@ -12,6 +12,7 @@ version = "0.2.0" arrayref = "0.3" bs58 = "0.2.0" byteorder = "1.3.1" +bytes = "0.4.12" data-encoding = "2.1" multihash = { package = "parity-multihash", version = "0.1.0", path = "../multihash" } serde = "1.0.70" diff --git a/misc/multiaddr/src/lib.rs b/misc/multiaddr/src/lib.rs index f180de01..7eac66e1 100644 --- a/misc/multiaddr/src/lib.rs +++ b/misc/multiaddr/src/lib.rs @@ -8,6 +8,7 @@ pub use multihash; mod protocol; mod errors; +use bytes::Bytes; use serde::{ Deserialize, Deserializer, @@ -17,7 +18,6 @@ use serde::{ }; use std::{ fmt, - io, iter::FromIterator, net::{SocketAddr, SocketAddrV4, SocketAddrV6, IpAddr, Ipv4Addr, Ipv6Addr}, result::Result as StdResult, @@ -28,7 +28,7 @@ pub use self::protocol::Protocol; /// Representation of a Multiaddr. #[derive(PartialEq, Eq, Clone, Hash)] -pub struct Multiaddr { bytes: Vec } +pub struct Multiaddr { bytes: Bytes } impl Serialize for Multiaddr { fn serialize(&self, serializer: S) -> StdResult @@ -63,7 +63,7 @@ impl<'de> Deserialize<'de> for Multiaddr { let s = String::from_utf8(buf).map_err(DeserializerError::custom)?; s.parse().map_err(DeserializerError::custom) } else { - Multiaddr::from_bytes(buf).map_err(DeserializerError::custom) + Multiaddr::try_from_vec(buf).map_err(DeserializerError::custom) } } fn visit_str(self, v: &str) -> StdResult { @@ -82,7 +82,7 @@ impl<'de> Deserialize<'de> for Multiaddr { self.visit_byte_buf(v.into()) } fn visit_byte_buf(self, v: Vec) -> StdResult { - Multiaddr::from_bytes(v).map_err(DeserializerError::custom) + Multiaddr::try_from_vec(v).map_err(DeserializerError::custom) } } @@ -123,32 +123,41 @@ impl fmt::Display for Multiaddr { } impl Multiaddr { - /// Create a new, empty multiaddress. - pub fn empty() -> Multiaddr { - Multiaddr { bytes: Vec::new() } + #[deprecated(since = "0.2.1", note = "Use `Multiaddr::to_vec` instead.")] + pub fn into_bytes(self) -> Vec { + self.to_vec() } - /// Returns the raw bytes representation of the multiaddr. - #[inline] - pub fn into_bytes(self) -> Vec { - self.bytes + #[deprecated(since = "0.2.1", note = "Use `Multiaddr::to_vec` instead.")] + pub fn to_bytes(&self) -> Vec { + self.to_vec() + } + + #[deprecated(since = "0.2.1", note = "Use `Multiaddr::try_from_vec` instead.")] + pub fn from_bytes(bytes: Vec) -> Result { + Self::try_from_vec(bytes) + } + + /// Create a new, empty multiaddress. + pub fn empty() -> Multiaddr { + Multiaddr { bytes: Bytes::new() } } /// Return a copy to disallow changing the bytes directly - pub fn to_bytes(&self) -> Vec { - self.bytes.clone() + pub fn to_vec(&self) -> Vec { + Vec::from(&self.bytes[..]) } /// Produces a `Multiaddr` from its bytes representation. - pub fn from_bytes(bytes: Vec) -> Result { - { - let mut ptr = &bytes[..]; - while !ptr.is_empty() { - let (_, new_ptr) = Protocol::from_bytes(ptr)?; - ptr = new_ptr; - } + pub fn try_from_vec(v: Vec) -> Result { + // Check if the argument is a valid `Multiaddr` + // by reading its protocols. + let mut ptr = &v[..]; + while !ptr.is_empty() { + let (_, new_ptr) = Protocol::from_bytes(ptr)?; + ptr = new_ptr; } - Ok(Multiaddr { bytes }) + Ok(Multiaddr { bytes: v.into() }) } /// Extracts a slice containing the entire underlying vector. @@ -171,7 +180,7 @@ impl Multiaddr { pub fn encapsulate(&self, input: T) -> Result { let new = input.to_multiaddr()?; let mut bytes = self.bytes.clone(); - bytes.extend(new.to_bytes()); + bytes.extend_from_slice(&new.bytes); Ok(Multiaddr { bytes }) } @@ -187,12 +196,10 @@ impl Multiaddr { /// assert_eq!(address, "/ip4/127.0.0.1/tcp/10000".parse().unwrap()); /// ``` /// - #[inline] pub fn append(&mut self, p: Protocol<'_>) { - let n = self.bytes.len(); - let mut w = io::Cursor::new(&mut self.bytes); - w.set_position(n as u64); - p.write_bytes(&mut w).expect("writing to a Vec never fails") + let mut w = Vec::new(); + p.write_bytes(&mut w).expect("writing to a Vec never fails"); + self.bytes.extend_from_slice(&w); } /// Remove the outermost address. @@ -223,7 +230,7 @@ impl Multiaddr { /// ``` /// pub fn decapsulate(&self, input: T) -> Result { - let input = input.to_multiaddr()?.to_bytes(); + let input = input.to_multiaddr()?.to_vec(); let bytes_len = self.bytes.len(); let input_length = input.len(); @@ -246,7 +253,7 @@ impl Multiaddr { } if !matches { - return Ok(Multiaddr { bytes: self.bytes.clone() }); + return Ok(self.clone()) } let mut bytes = self.bytes.clone(); @@ -297,7 +304,7 @@ impl<'a> From> for Multiaddr { fn from(p: Protocol<'a>) -> Multiaddr { let mut w = Vec::new(); p.write_bytes(&mut w).expect("writing to a Vec never fails"); - Multiaddr { bytes: w } + Multiaddr { bytes: w.into() } } } @@ -320,7 +327,7 @@ impl<'a> FromIterator> for Multiaddr { for cmp in iter { cmp.write_bytes(&mut writer).expect("writing to a Vec never fails"); } - Multiaddr { bytes: writer } + Multiaddr { bytes: writer.into() } } } @@ -342,7 +349,7 @@ impl FromStr for Multiaddr { p.write_bytes(&mut writer).expect("writing to a Vec never fails"); } - Ok(Multiaddr { bytes: writer }) + Ok(Multiaddr { bytes: writer.into() }) } } diff --git a/misc/multiaddr/tests/lib.rs b/misc/multiaddr/tests/lib.rs index d42c8521..fdd35693 100644 --- a/misc/multiaddr/tests/lib.rs +++ b/misc/multiaddr/tests/lib.rs @@ -16,8 +16,8 @@ use std::{ #[test] fn to_from_bytes_identity() { fn prop(a: Ma) -> bool { - let b = a.0.to_bytes(); - Some(a) == Multiaddr::from_bytes(b).ok().map(Ma) + let b = a.0.to_vec(); + Some(a) == Multiaddr::try_from_vec(b).ok().map(Ma) } QuickCheck::new().quickcheck(prop as fn(Ma) -> bool) } @@ -102,10 +102,10 @@ impl Arbitrary for SubString { fn ma_valid(source: &str, target: &str, protocols: Vec>) { let parsed = source.parse::().unwrap(); - assert_eq!(HEXUPPER.encode(&parsed.to_bytes()[..]), target); + assert_eq!(HEXUPPER.encode(&parsed.to_vec()[..]), target); assert_eq!(parsed.iter().collect::>(), protocols); assert_eq!(source.parse::().unwrap().to_string(), source); - assert_eq!(Multiaddr::from_bytes(HEXUPPER.decode(target.as_bytes()).unwrap()).unwrap(), parsed); + assert_eq!(Multiaddr::try_from_vec(HEXUPPER.decode(target.as_bytes()).unwrap()).unwrap(), parsed); } fn multihash(s: &str) -> Multihash { @@ -252,7 +252,7 @@ fn to_multiaddr() { #[test] fn from_bytes_fail() { let bytes = vec![1, 2, 3, 4]; - assert!(Multiaddr::from_bytes(bytes).is_err()); + assert!(Multiaddr::try_from_vec(bytes).is_err()); } diff --git a/protocols/identify/src/protocol.rs b/protocols/identify/src/protocol.rs index 27f84c4b..411fe30c 100644 --- a/protocols/identify/src/protocol.rs +++ b/protocols/identify/src/protocol.rs @@ -64,7 +64,7 @@ impl IdentifySender where T: AsyncWrite { let listen_addrs = info.listen_addrs .into_iter() - .map(|addr| addr.into_bytes()) + .map(|addr| addr.to_vec()) .collect(); let pubkey_bytes = info.public_key.into_protobuf_encoding(); @@ -74,7 +74,7 @@ impl IdentifySender where T: AsyncWrite { message.set_protocolVersion(info.protocol_version); message.set_publicKey(pubkey_bytes); message.set_listenAddrs(listen_addrs); - message.set_observedAddr(observed_addr.to_bytes()); + message.set_observedAddr(observed_addr.to_vec()); message.set_protocols(RepeatedField::from_vec(info.protocols)); let bytes = message @@ -234,7 +234,7 @@ fn parse_proto_msg(msg: BytesMut) -> Result<(IdentifyInfo, Multiaddr), IoError> // Turn a `Vec` into a `Multiaddr`. If something bad happens, turn it into // an `IoError`. fn bytes_to_multiaddr(bytes: Vec) -> Result { - Multiaddr::from_bytes(bytes) + Multiaddr::try_from_vec(bytes) .map_err(|err| IoError::new(IoErrorKind::InvalidData, err)) } diff --git a/protocols/kad/src/protocol.rs b/protocols/kad/src/protocol.rs index 5efc0fcb..eff8a664 100644 --- a/protocols/kad/src/protocol.rs +++ b/protocols/kad/src/protocol.rs @@ -103,7 +103,7 @@ impl KadPeer { let mut addrs = Vec::with_capacity(peer.get_addrs().len()); for addr in peer.take_addrs().into_iter() { - let as_ma = Multiaddr::from_bytes(addr) + let as_ma = Multiaddr::try_from_vec(addr) .map_err(|err| IoError::new(IoErrorKind::InvalidData, err))?; addrs.push(as_ma); } @@ -124,7 +124,7 @@ impl Into for KadPeer { let mut out = protobuf_structs::dht::Message_Peer::new(); out.set_id(self.node_id.into_bytes()); for addr in self.multiaddrs { - out.mut_addrs().push(addr.into_bytes()); + out.mut_addrs().push(addr.to_vec()); } out.set_connection(self.connection_ty.into()); out diff --git a/protocols/observed/src/lib.rs b/protocols/observed/src/lib.rs index 227e958e..c312fbb2 100644 --- a/protocols/observed/src/lib.rs +++ b/protocols/observed/src/lib.rs @@ -75,7 +75,7 @@ where .map_err(|(e, _): (io::Error, FramedRead, UviBytes>)| e) .and_then(move |(bytes, _)| { if let Some(b) = bytes { - let ma = Multiaddr::from_bytes(b.to_vec()) + let ma = Multiaddr::try_from_vec(b.to_vec()) .map_err(|e| io::Error::new(io::ErrorKind::InvalidData, e))?; Ok(ma) } else { @@ -94,7 +94,7 @@ pub struct Sender { impl Sender { /// Send address `a` to remote as the observed address. pub fn send_address(self, a: Multiaddr) -> impl Future { - self.io.send(Bytes::from(a.into_bytes())).map(|_io| ()) + self.io.send(Bytes::from(a.to_vec())).map(|_io| ()) } }