Change Multiaddr representation to Bytes. (#1041)

* Change `Multiaddr` representation to `Bytes`.

* Mark several `Multiaddr` methods as deprecated.
This commit is contained in:
Toralf Wittner 2019-04-08 10:57:09 +02:00 committed by GitHub
parent 480cf380d7
commit 98b2517403
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 52 additions and 44 deletions

View File

@ -12,6 +12,7 @@ version = "0.2.0"
arrayref = "0.3" arrayref = "0.3"
bs58 = "0.2.0" bs58 = "0.2.0"
byteorder = "1.3.1" byteorder = "1.3.1"
bytes = "0.4.12"
data-encoding = "2.1" data-encoding = "2.1"
multihash = { package = "parity-multihash", version = "0.1.0", path = "../multihash" } multihash = { package = "parity-multihash", version = "0.1.0", path = "../multihash" }
serde = "1.0.70" serde = "1.0.70"

View File

@ -8,6 +8,7 @@ pub use multihash;
mod protocol; mod protocol;
mod errors; mod errors;
use bytes::Bytes;
use serde::{ use serde::{
Deserialize, Deserialize,
Deserializer, Deserializer,
@ -17,7 +18,6 @@ use serde::{
}; };
use std::{ use std::{
fmt, fmt,
io,
iter::FromIterator, iter::FromIterator,
net::{SocketAddr, SocketAddrV4, SocketAddrV6, IpAddr, Ipv4Addr, Ipv6Addr}, net::{SocketAddr, SocketAddrV4, SocketAddrV6, IpAddr, Ipv4Addr, Ipv6Addr},
result::Result as StdResult, result::Result as StdResult,
@ -28,7 +28,7 @@ pub use self::protocol::Protocol;
/// Representation of a Multiaddr. /// Representation of a Multiaddr.
#[derive(PartialEq, Eq, Clone, Hash)] #[derive(PartialEq, Eq, Clone, Hash)]
pub struct Multiaddr { bytes: Vec<u8> } pub struct Multiaddr { bytes: Bytes }
impl Serialize for Multiaddr { impl Serialize for Multiaddr {
fn serialize<S>(&self, serializer: S) -> StdResult<S::Ok, S::Error> fn serialize<S>(&self, serializer: S) -> StdResult<S::Ok, S::Error>
@ -63,7 +63,7 @@ impl<'de> Deserialize<'de> for Multiaddr {
let s = String::from_utf8(buf).map_err(DeserializerError::custom)?; let s = String::from_utf8(buf).map_err(DeserializerError::custom)?;
s.parse().map_err(DeserializerError::custom) s.parse().map_err(DeserializerError::custom)
} else { } else {
Multiaddr::from_bytes(buf).map_err(DeserializerError::custom) Multiaddr::try_from_vec(buf).map_err(DeserializerError::custom)
} }
} }
fn visit_str<E: de::Error>(self, v: &str) -> StdResult<Self::Value, E> { fn visit_str<E: de::Error>(self, v: &str) -> StdResult<Self::Value, E> {
@ -82,7 +82,7 @@ impl<'de> Deserialize<'de> for Multiaddr {
self.visit_byte_buf(v.into()) self.visit_byte_buf(v.into())
} }
fn visit_byte_buf<E: de::Error>(self, v: Vec<u8>) -> StdResult<Self::Value, E> { fn visit_byte_buf<E: de::Error>(self, v: Vec<u8>) -> StdResult<Self::Value, E> {
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 { impl Multiaddr {
/// Create a new, empty multiaddress. #[deprecated(since = "0.2.1", note = "Use `Multiaddr::to_vec` instead.")]
pub fn empty() -> Multiaddr { pub fn into_bytes(self) -> Vec<u8> {
Multiaddr { bytes: Vec::new() } self.to_vec()
} }
/// Returns the raw bytes representation of the multiaddr. #[deprecated(since = "0.2.1", note = "Use `Multiaddr::to_vec` instead.")]
#[inline] pub fn to_bytes(&self) -> Vec<u8> {
pub fn into_bytes(self) -> Vec<u8> { self.to_vec()
self.bytes }
#[deprecated(since = "0.2.1", note = "Use `Multiaddr::try_from_vec` instead.")]
pub fn from_bytes(bytes: Vec<u8>) -> Result<Multiaddr> {
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 /// Return a copy to disallow changing the bytes directly
pub fn to_bytes(&self) -> Vec<u8> { pub fn to_vec(&self) -> Vec<u8> {
self.bytes.clone() Vec::from(&self.bytes[..])
} }
/// Produces a `Multiaddr` from its bytes representation. /// Produces a `Multiaddr` from its bytes representation.
pub fn from_bytes(bytes: Vec<u8>) -> Result<Multiaddr> { pub fn try_from_vec(v: Vec<u8>) -> Result<Multiaddr> {
{ // Check if the argument is a valid `Multiaddr`
let mut ptr = &bytes[..]; // by reading its protocols.
while !ptr.is_empty() { let mut ptr = &v[..];
let (_, new_ptr) = Protocol::from_bytes(ptr)?; while !ptr.is_empty() {
ptr = new_ptr; 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. /// Extracts a slice containing the entire underlying vector.
@ -171,7 +180,7 @@ impl Multiaddr {
pub fn encapsulate<T: ToMultiaddr>(&self, input: T) -> Result<Multiaddr> { pub fn encapsulate<T: ToMultiaddr>(&self, input: T) -> Result<Multiaddr> {
let new = input.to_multiaddr()?; let new = input.to_multiaddr()?;
let mut bytes = self.bytes.clone(); let mut bytes = self.bytes.clone();
bytes.extend(new.to_bytes()); bytes.extend_from_slice(&new.bytes);
Ok(Multiaddr { bytes }) Ok(Multiaddr { bytes })
} }
@ -187,12 +196,10 @@ impl Multiaddr {
/// assert_eq!(address, "/ip4/127.0.0.1/tcp/10000".parse().unwrap()); /// assert_eq!(address, "/ip4/127.0.0.1/tcp/10000".parse().unwrap());
/// ``` /// ```
/// ///
#[inline]
pub fn append(&mut self, p: Protocol<'_>) { pub fn append(&mut self, p: Protocol<'_>) {
let n = self.bytes.len(); let mut w = Vec::new();
let mut w = io::Cursor::new(&mut self.bytes); p.write_bytes(&mut w).expect("writing to a Vec never fails");
w.set_position(n as u64); self.bytes.extend_from_slice(&w);
p.write_bytes(&mut w).expect("writing to a Vec never fails")
} }
/// Remove the outermost address. /// Remove the outermost address.
@ -223,7 +230,7 @@ impl Multiaddr {
/// ``` /// ```
/// ///
pub fn decapsulate<T: ToMultiaddr>(&self, input: T) -> Result<Multiaddr> { pub fn decapsulate<T: ToMultiaddr>(&self, input: T) -> Result<Multiaddr> {
let input = input.to_multiaddr()?.to_bytes(); let input = input.to_multiaddr()?.to_vec();
let bytes_len = self.bytes.len(); let bytes_len = self.bytes.len();
let input_length = input.len(); let input_length = input.len();
@ -246,7 +253,7 @@ impl Multiaddr {
} }
if !matches { if !matches {
return Ok(Multiaddr { bytes: self.bytes.clone() }); return Ok(self.clone())
} }
let mut bytes = self.bytes.clone(); let mut bytes = self.bytes.clone();
@ -297,7 +304,7 @@ impl<'a> From<Protocol<'a>> for Multiaddr {
fn from(p: Protocol<'a>) -> Multiaddr { fn from(p: Protocol<'a>) -> Multiaddr {
let mut w = Vec::new(); let mut w = Vec::new();
p.write_bytes(&mut w).expect("writing to a Vec never fails"); 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<Protocol<'a>> for Multiaddr {
for cmp in iter { for cmp in iter {
cmp.write_bytes(&mut writer).expect("writing to a Vec never fails"); 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"); p.write_bytes(&mut writer).expect("writing to a Vec never fails");
} }
Ok(Multiaddr { bytes: writer }) Ok(Multiaddr { bytes: writer.into() })
} }
} }

View File

@ -16,8 +16,8 @@ use std::{
#[test] #[test]
fn to_from_bytes_identity() { fn to_from_bytes_identity() {
fn prop(a: Ma) -> bool { fn prop(a: Ma) -> bool {
let b = a.0.to_bytes(); let b = a.0.to_vec();
Some(a) == Multiaddr::from_bytes(b).ok().map(Ma) Some(a) == Multiaddr::try_from_vec(b).ok().map(Ma)
} }
QuickCheck::new().quickcheck(prop as fn(Ma) -> bool) 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<Protocol<'_>>) { fn ma_valid(source: &str, target: &str, protocols: Vec<Protocol<'_>>) {
let parsed = source.parse::<Multiaddr>().unwrap(); let parsed = source.parse::<Multiaddr>().unwrap();
assert_eq!(HEXUPPER.encode(&parsed.to_bytes()[..]), target); assert_eq!(HEXUPPER.encode(&parsed.to_vec()[..]), target);
assert_eq!(parsed.iter().collect::<Vec<_>>(), protocols); assert_eq!(parsed.iter().collect::<Vec<_>>(), protocols);
assert_eq!(source.parse::<Multiaddr>().unwrap().to_string(), source); assert_eq!(source.parse::<Multiaddr>().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 { fn multihash(s: &str) -> Multihash {
@ -252,7 +252,7 @@ fn to_multiaddr() {
#[test] #[test]
fn from_bytes_fail() { fn from_bytes_fail() {
let bytes = vec![1, 2, 3, 4]; let bytes = vec![1, 2, 3, 4];
assert!(Multiaddr::from_bytes(bytes).is_err()); assert!(Multiaddr::try_from_vec(bytes).is_err());
} }

View File

@ -64,7 +64,7 @@ impl<T> IdentifySender<T> where T: AsyncWrite {
let listen_addrs = info.listen_addrs let listen_addrs = info.listen_addrs
.into_iter() .into_iter()
.map(|addr| addr.into_bytes()) .map(|addr| addr.to_vec())
.collect(); .collect();
let pubkey_bytes = info.public_key.into_protobuf_encoding(); let pubkey_bytes = info.public_key.into_protobuf_encoding();
@ -74,7 +74,7 @@ impl<T> IdentifySender<T> where T: AsyncWrite {
message.set_protocolVersion(info.protocol_version); message.set_protocolVersion(info.protocol_version);
message.set_publicKey(pubkey_bytes); message.set_publicKey(pubkey_bytes);
message.set_listenAddrs(listen_addrs); 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)); message.set_protocols(RepeatedField::from_vec(info.protocols));
let bytes = message let bytes = message
@ -234,7 +234,7 @@ fn parse_proto_msg(msg: BytesMut) -> Result<(IdentifyInfo, Multiaddr), IoError>
// Turn a `Vec<u8>` into a `Multiaddr`. If something bad happens, turn it into // Turn a `Vec<u8>` into a `Multiaddr`. If something bad happens, turn it into
// an `IoError`. // an `IoError`.
fn bytes_to_multiaddr(bytes: Vec<u8>) -> Result<Multiaddr, IoError> { fn bytes_to_multiaddr(bytes: Vec<u8>) -> Result<Multiaddr, IoError> {
Multiaddr::from_bytes(bytes) Multiaddr::try_from_vec(bytes)
.map_err(|err| IoError::new(IoErrorKind::InvalidData, err)) .map_err(|err| IoError::new(IoErrorKind::InvalidData, err))
} }

View File

@ -103,7 +103,7 @@ impl KadPeer {
let mut addrs = Vec::with_capacity(peer.get_addrs().len()); let mut addrs = Vec::with_capacity(peer.get_addrs().len());
for addr in peer.take_addrs().into_iter() { 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))?; .map_err(|err| IoError::new(IoErrorKind::InvalidData, err))?;
addrs.push(as_ma); addrs.push(as_ma);
} }
@ -124,7 +124,7 @@ impl Into<protobuf_structs::dht::Message_Peer> for KadPeer {
let mut out = protobuf_structs::dht::Message_Peer::new(); let mut out = protobuf_structs::dht::Message_Peer::new();
out.set_id(self.node_id.into_bytes()); out.set_id(self.node_id.into_bytes());
for addr in self.multiaddrs { 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.set_connection(self.connection_ty.into());
out out

View File

@ -75,7 +75,7 @@ where
.map_err(|(e, _): (io::Error, FramedRead<Negotiated<C>, UviBytes>)| e) .map_err(|(e, _): (io::Error, FramedRead<Negotiated<C>, UviBytes>)| e)
.and_then(move |(bytes, _)| { .and_then(move |(bytes, _)| {
if let Some(b) = 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))?; .map_err(|e| io::Error::new(io::ErrorKind::InvalidData, e))?;
Ok(ma) Ok(ma)
} else { } else {
@ -94,7 +94,7 @@ pub struct Sender<C> {
impl<C: AsyncWrite> Sender<C> { impl<C: AsyncWrite> Sender<C> {
/// Send address `a` to remote as the observed address. /// Send address `a` to remote as the observed address.
pub fn send_address(self, a: Multiaddr) -> impl Future<Item=(), Error=io::Error> { pub fn send_address(self, a: Multiaddr) -> impl Future<Item=(), Error=io::Error> {
self.io.send(Bytes::from(a.into_bytes())).map(|_io| ()) self.io.send(Bytes::from(a.to_vec())).map(|_io| ())
} }
} }