Use a Multihash in AddrComponent::P2P, drop cid (#407)

* Use a Multihash in AddrComponent::P2P
* Remove the cid crate from the repo
This commit is contained in:
Pierre Krieger 2018-08-10 17:47:02 +02:00 committed by Benjamin Kampmann
parent d4b98e8646
commit d94fe1b831
20 changed files with 70 additions and 666 deletions

View File

@ -1,6 +1,5 @@
[workspace]
members = [
"cid",
"circular-buffer",
"datastore",
"dns",

3
cid/.gitignore vendored
View File

@ -1,3 +0,0 @@
target
Cargo.lock
*.bk

View File

@ -1,35 +0,0 @@
sudo: false
language: rust
addons:
apt:
packages:
- libcurl4-openssl-dev
- libelf-dev
- libdw-dev
- binutils-dev
rust:
- beta
- stable
before_script:
- |
pip install 'travis-cargo<0.2' --user &&
export PATH=$HOME/.local/bin:$PATH
install:
- pip install --user travis-cargo codecov
- export PATH=$PATH:$HOME/.local/bin
script:
- |
travis-cargo build &&
travis-cargo test &&
travis-cargo --only stable doc
after_success:
- travis-cargo coverage --no-sudo
- travis-cargo --only stable doc-upload
- travis-cargo coveralls --no-sudo --verify

View File

@ -1,22 +0,0 @@
[package]
name = "cid"
version = "0.2.3"
description = "CID in rust"
homepage = "https://github.com/ipld/rust-cid"
authors = ["Friedel Ziegelmayer <dignifiedquire@gmail.com>"]
keywords = ["ipld", "ipfs", "cid", "multihash"]
license = "MIT"
readme = "README.md"
[dependencies]
multihash = { path = "../multihash" }
multibase = "~0.6.0"
integer-encoding = "~1.0.3"
[package.metadata.release]
upload-doc = true
pre-release-commit-message = "Release {{version}} 🎉🎉"
no-dev-version = true

View File

@ -1,64 +0,0 @@
# rust-cid
[![](https://img.shields.io/badge/made%20by-Protocol%20Labs-blue.svg?style=flat-square)](http://ipn.io)
[![](https://img.shields.io/badge/project-ipld-blue.svg?style=flat-square)](https://github.com/ipld/ipld)
[![](https://img.shields.io/badge/freenode-%23ipfs-blue.svg?style=flat-square)](https://webchat.freenode.net/?channels=%23ipfs)
[![Travis CI](https://img.shields.io/travis/ipld/rust-cid.svg?style=flat-square&branch=master)](https://travis-ci.org/ipld/rust-cid)
[![](https://img.shields.io/badge/rust-docs-blue.svg?style=flat-square)](https://docs.rs/crate/cid)
[![crates.io](https://img.shields.io/badge/crates.io-v0.1.0-orange.svg?style=flat-square )](https://crates.io/crates/cid)
[![](https://img.shields.io/badge/readme%20style-standard-brightgreen.svg?style=flat-square)](https://github.com/RichardLitt/standard-readme)
> [CID](https://github.com/ipld/cid) implementation in Rust.
## Table of Contents
- [Install](#install)
- [Usage](#usage)
- [Maintainers](#maintainers)
- [Contribute](#contribute)
- [License](#license)
## Install
First add this to your `Cargo.toml`
```toml
[dependencies]
cid = "*"
```
Then run `cargo build`.
## Usage
```rust
extern crate cid;
extern crate multihash;
use multihash::Hash;
use cid::{Cid, Codec, Version};
let h = multihash::encode(multihash::Hash::SHA2256, b"beep boop").unwrap();
let cid = Cid::new(Codec::DagProtobuf, Version::V1, &h);
let data = cid.to_bytes();
let out = Cid::from(data).unwrap();
assert_eq!(cid, out);
```
## Maintainers
Captain: [@dignifiedquire](https://github.com/dignifiedquire).
## Contribute
Contributions welcome. Please check out [the issues](https://github.com/ipld/rust-cid/issues).
Check out our [contributing document](https://github.com/ipld/ipld/blob/master/contributing.md) for more information on how we work, and about contributing in general. Please be aware that all interactions related to ipld are subject to the IPFS [Code of Conduct](https://github.com/ipfs/community/blob/master/code-of-conduct.md).
Small note: If editing the README, please conform to the [standard-readme](https://github.com/RichardLitt/standard-readme) specification.
## License
[MIT](LICENSE) © 2017 Friedel Ziegelmayer

View File

@ -1,52 +0,0 @@
use {Error, Result};
macro_rules! build_codec_enum {
{$( $val:expr => $var:ident, )*} => {
#[derive(PartialEq, Eq, Clone, Copy, Debug)]
pub enum Codec {
$( $var, )*
}
use Codec::*;
impl Codec {
/// Convert a number to the matching codec
pub fn from(raw: u64) -> Result<Codec> {
match raw {
$( $val => Ok($var), )*
_ => Err(Error::UnknownCodec),
}
}
}
impl From<Codec> for u64 {
/// Convert to the matching integer code
fn from(codec: Codec) -> u64 {
match codec {
$( $var => $val, )*
}
}
}
}
}
build_codec_enum! {
0x55 => Raw,
0x70 => DagProtobuf,
0x71 => DagCBOR,
0x78 => GitRaw,
0x90 => EthereumBlock,
0x91 => EthereumBlockList,
0x92 => EthereumTxTrie,
0x93 => EthereumTx,
0x94 => EthereumTxReceiptTrie,
0x95 => EthereumTxReceipt,
0x96 => EthereumStateTrie,
0x97 => EthereumAccountSnapshot,
0x98 => EthereumStorageTrie,
0xb0 => BitcoinBlock,
0xb1 => BitcoinTx,
0xc0 => ZcashBlock,
0xc1 => ZcashTx,
}

View File

@ -1,63 +0,0 @@
use std::{fmt, error, io};
use multibase;
use multihash;
pub type Result<T> = ::std::result::Result<T, Error>;
/// Error types
#[derive(PartialEq, Eq, Clone, Copy, Debug)]
pub enum Error {
UnknownCodec,
InputTooShort,
ParsingError,
InvalidCidVersion,
}
impl fmt::Display for Error {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
f.write_str(error::Error::description(self))
}
}
impl error::Error for Error {
fn description(&self) -> &str {
use self::Error::*;
match *self {
UnknownCodec => "Unknown codec",
InputTooShort => "Input too short",
ParsingError => "Failed to parse multihash",
InvalidCidVersion => "Unrecognized CID version",
}
}
}
impl From<io::Error> for Error {
fn from(_: io::Error) -> Error {
Error::ParsingError
}
}
impl From<multibase::Error> for Error {
fn from(_: multibase::Error) -> Error {
Error::ParsingError
}
}
impl From<multihash::DecodeError> for Error {
fn from(_: multihash::DecodeError) -> Error {
Error::ParsingError
}
}
impl From<multihash::DecodeOwnedError> for Error {
fn from(_: multihash::DecodeOwnedError) -> Error {
Error::ParsingError
}
}
impl From<Error> for fmt::Error {
fn from(_: Error) -> fmt::Error {
fmt::Error {}
}
}

View File

@ -1,165 +0,0 @@
/// ! # cid
/// !
/// ! Implementation of [cid](https://github.com/ipld/cid) in Rust.
extern crate multihash;
extern crate multibase;
extern crate integer_encoding;
mod to_cid;
mod error;
mod codec;
mod version;
pub use to_cid::ToCid;
pub use version::Version;
pub use codec::Codec;
pub use error::{Error, Result};
use integer_encoding::{VarIntReader, VarIntWriter};
use std::fmt;
use std::io::Cursor;
/// Representation of a CID.
#[derive(PartialEq, Eq, Clone, Debug)]
pub struct Cid {
pub version: Version,
pub codec: Codec,
pub hash: Vec<u8>,
}
/// Prefix represents all metadata of a CID, without the actual content.
#[derive(PartialEq, Eq, Clone, Debug)]
pub struct Prefix {
pub version: Version,
pub codec: Codec,
pub mh_type: multihash::Hash,
pub mh_len: usize,
}
impl Cid {
/// Create a new CID.
pub fn new(codec: Codec, version: Version, hash: &[u8]) -> Cid {
Cid {
version: version,
codec: codec,
hash: hash.into(),
}
}
/// Create a new CID from raw data (binary or multibase encoded string)
pub fn from<T: ToCid>(data: T) -> Result<Cid> {
data.to_cid()
}
/// Create a new CID from a prefix and some data.
pub fn new_from_prefix(prefix: &Prefix, data: &[u8]) -> Cid {
let mut hash = multihash::encode(prefix.mh_type.to_owned(), data).unwrap().into_bytes();
hash.truncate(prefix.mh_len + 2);
Cid {
version: prefix.version,
codec: prefix.codec.to_owned(),
hash: hash,
}
}
fn to_string_v0(&self) -> String {
use multibase::{encode, Base};
let mut string = encode(Base::Base58btc, self.hash.as_slice());
// Drop the first character as v0 does not know
// about multibase
string.remove(0);
string
}
fn to_string_v1(&self) -> String {
use multibase::{encode, Base};
encode(Base::Base58btc, self.to_bytes().as_slice())
}
pub fn to_string(&self) -> String {
match self.version {
Version::V0 => self.to_string_v0(),
Version::V1 => self.to_string_v1(),
}
}
fn to_bytes_v0(&self) -> Vec<u8> {
self.hash.clone()
}
fn to_bytes_v1(&self) -> Vec<u8> {
let mut res = Vec::with_capacity(16);
res.write_varint(u64::from(self.version)).unwrap();
res.write_varint(u64::from(self.codec)).unwrap();
res.extend_from_slice(&self.hash);
res
}
pub fn to_bytes(&self) -> Vec<u8> {
match self.version {
Version::V0 => self.to_bytes_v0(),
Version::V1 => self.to_bytes_v1(),
}
}
pub fn prefix(&self) -> Prefix {
// Unwrap is safe, as this should have been validated on creation
let mh = multihash::MultihashRef::from_slice(self.hash.as_slice()).unwrap();
Prefix {
version: self.version,
codec: self.codec.to_owned(),
mh_type: mh.algorithm(),
mh_len: mh.digest().len(),
}
}
}
impl fmt::Display for Cid {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "{}", Cid::to_string(self))
}
}
impl Prefix {
pub fn new_from_bytes(data: &[u8]) -> Result<Prefix> {
let mut cur = Cursor::new(data);
let raw_version = cur.read_varint()?;
let raw_codec = cur.read_varint()?;
let raw_mh_type: u64 = cur.read_varint()?;
let version = Version::from(raw_version)?;
let codec = Codec::from(raw_codec)?;
let mh_type = multihash::Hash::from_code(raw_mh_type as u8)
.ok_or(Error::ParsingError)?;
let mh_len = cur.read_varint()?;
Ok(Prefix {
version: version,
codec: codec,
mh_type: mh_type,
mh_len: mh_len,
})
}
pub fn as_bytes(&self) -> Vec<u8> {
let mut res = Vec::with_capacity(4);
// io can't fail on Vec
res.write_varint(u64::from(self.version)).unwrap();
res.write_varint(u64::from(self.codec)).unwrap();
res.write_varint(self.mh_type.code() as u64).unwrap();
res.write_varint(self.mh_len as u64).unwrap();
res
}
}

View File

@ -1,93 +0,0 @@
use std::io::Cursor;
use multibase;
use multihash;
use integer_encoding::VarIntReader;
use {Cid, Version, Codec, Error, Result};
pub trait ToCid {
fn to_cid(&self) -> Result<Cid>;
}
impl ToCid for Vec<u8> {
/// Create a Cid from a byte vector.
#[inline]
fn to_cid(&self) -> Result<Cid> {
self.as_slice().to_cid()
}
}
impl ToCid for String {
/// Create a Cid from an owned String.
#[inline]
fn to_cid(&self) -> Result<Cid> {
self.as_str().to_cid()
}
}
impl<'a> ToCid for &'a str {
#[inline]
fn to_cid(&self) -> Result<Cid> {
ToCid::to_cid(*self)
}
}
impl ToCid for str {
fn to_cid(&self) -> Result<Cid> {
static IPFS_DELIMETER: &'static str = "/ipfs/";
let hash = match self.find(IPFS_DELIMETER) {
Some(index) => &self[index + IPFS_DELIMETER.len()..],
_ => self
};
if hash.len() < 2 {
return Err(Error::InputTooShort);
}
let (_, decoded) = if Version::is_v0_str(hash) {
// TODO: could avoid the roundtrip here and just use underlying
// base-x base58btc decoder here.
let hash = multibase::Base::Base58btc.code().to_string() + &hash;
multibase::decode(hash)
} else {
multibase::decode(hash)
}?;
decoded.to_cid()
}
}
impl<'a> ToCid for &'a [u8] {
#[inline]
fn to_cid(&self) -> Result<Cid> {
ToCid::to_cid(*self)
}
}
impl ToCid for [u8] {
/// Create a Cid from a byte slice.
fn to_cid(&self) -> Result<Cid> {
if Version::is_v0_binary(self) {
// Verify that hash can be decoded, this is very cheap
multihash::MultihashRef::from_slice(self)?;
Ok(Cid::new(Codec::DagProtobuf, Version::V0, self))
} else {
let mut cur = Cursor::new(self);
let raw_version = cur.read_varint()?;
let raw_codec = cur.read_varint()?;
let version = Version::from(raw_version)?;
let codec = Codec::from(raw_codec)?;
let hash = &self[cur.position() as usize..];
// Verify that hash can be decoded, this is very cheap
multihash::MultihashRef::from_slice(hash)?;
Ok(Cid::new(codec, version, hash))
}
}
}

View File

@ -1,38 +0,0 @@
use {Error, Result};
#[derive(PartialEq, Eq, Clone, Copy, Debug)]
pub enum Version {
V0,
V1,
}
use Version::*;
impl Version {
pub fn from(raw: u64) -> Result<Version> {
match raw {
0 => Ok(V0),
1 => Ok(V1),
_ => Err(Error::InvalidCidVersion)
}
}
pub fn is_v0_str(data: &str) -> bool {
// v0 is a base58btc encoded sha hash, so it has
// fixed length and always begins with "Qm"
data.len() == 46 && data.starts_with("Qm")
}
pub fn is_v0_binary(data: &[u8]) -> bool {
data.len() == 34 && data.starts_with(&[0x12,0x20])
}
}
impl From<Version> for u64 {
fn from(ver: Version) -> u64 {
match ver {
V0 => 0,
V1 => 1,
}
}
}

View File

@ -1,76 +0,0 @@
extern crate cid;
extern crate multihash;
use cid::{Cid, Version, Codec, Error, Prefix};
#[test]
fn basic_marshalling() {
let h = multihash::encode(multihash::Hash::SHA2256, b"beep boop").unwrap();
let cid = Cid::new(Codec::DagProtobuf, Version::V1, h.as_bytes());
let data = cid.to_bytes();
let out = Cid::from(data).unwrap();
assert_eq!(cid, out);
let s = cid.to_string();
let out2 = Cid::from(&s[..]).unwrap();
assert_eq!(cid, out2);
}
#[test]
fn empty_string() {
assert_eq!(Cid::from(""), Err(Error::InputTooShort));
}
#[test]
fn v0_handling() {
let old = "QmdfTbBqBPQ7VNxZEYEj14VmRuZBkqFbiwReogJgS1zR1n";
let cid = Cid::from(old).unwrap();
assert_eq!(cid.version, Version::V0);
assert_eq!(cid.to_string(), old);
}
#[test]
fn v0_error() {
let bad = "QmdfTbBqBPQ7VNxZEYEj14VmRuZBkqFbiwReogJgS1zIII";
assert_eq!(Cid::from(bad), Err(Error::ParsingError));
}
#[test]
fn prefix_roundtrip() {
let data = b"awesome test content";
let h = multihash::encode(multihash::Hash::SHA2256, data).unwrap();
let cid = Cid::new(Codec::DagProtobuf, Version::V1, h.as_bytes());
let prefix = cid.prefix();
let cid2 = Cid::new_from_prefix(&prefix, data);
assert_eq!(cid, cid2);
let prefix_bytes = prefix.as_bytes();
let prefix2 = Prefix::new_from_bytes(&prefix_bytes).unwrap();
assert_eq!(prefix, prefix2);
}
#[test]
fn from() {
let the_hash = "QmdfTbBqBPQ7VNxZEYEj14VmRuZBkqFbiwReogJgS1zR1n";
let cases = vec![
format!("/ipfs/{:}", &the_hash),
format!("https://ipfs.io/ipfs/{:}", &the_hash),
format!("http://localhost:8080/ipfs/{:}", &the_hash),
];
for case in cases {
let cid = Cid::from(case).unwrap();
assert_eq!(cid.version, Version::V0);
assert_eq!(cid.to_string(), the_hash);
}
}

View File

@ -53,11 +53,28 @@ impl PeerId {
#[inline]
pub fn from_bytes(data: Vec<u8>) -> Result<PeerId, Vec<u8>> {
match multihash::Multihash::from_bytes(data) {
Ok(multihash) => Ok(PeerId { multihash }),
Ok(multihash) => {
if multihash.algorithm() == multihash::Hash::SHA2256 {
Ok(PeerId { multihash })
} else {
Err(multihash.into_bytes())
}
},
Err(err) => Err(err.data),
}
}
/// Turns a `Multihash` into a `PeerId`. If the multihash doesn't use the correct algorithm,
/// returns back the data as an error.
#[inline]
pub fn from_multihash(data: multihash::Multihash) -> Result<PeerId, multihash::Multihash> {
if data.algorithm() == multihash::Hash::SHA2256 {
Ok(PeerId { multihash: data })
} else {
Err(data)
}
}
/// Returns a raw bytes representation of this `PeerId`.
///
/// Note that this is not the same as the public key of the peer.
@ -106,6 +123,13 @@ impl From<PublicKey> for PeerId {
}
}
impl Into<multihash::Multihash> for PeerId {
#[inline]
fn into(self) -> multihash::Multihash {
self.multihash
}
}
quick_error! {
#[derive(Debug)]
pub enum ParseError {

View File

@ -46,7 +46,7 @@ use futures::sync::mpsc;
use futures::{future, Future, Poll, Sink, Stream};
use libp2p_core::{ConnectionUpgrade, Endpoint, PeerId};
use log::Level;
use multiaddr::{AddrComponent, Multiaddr, ToCid};
use multiaddr::{AddrComponent, Multiaddr};
use parking_lot::{Mutex, RwLock, RwLockUpgradableReadGuard};
use protobuf::Message as ProtobufMessage;
use smallvec::SmallVec;
@ -593,15 +593,15 @@ fn handle_packet_received(
continue;
}
let cid = match from.to_cid() {
Ok(cid) => cid,
let peer_id = match PeerId::from_bytes(bytes.to_vec()) {
Ok(id) => id,
Err(err) => {
trace!("Parsing Cid failed: {}. Skipping.", err);
trace!("Parsing PeerId failed: {:?}. Skipping.", err);
continue
}
};
let from: Multiaddr = AddrComponent::P2P(cid).into();
let from: Multiaddr = AddrComponent::P2P(peer_id.into()).into();
let topics = publish
.take_topicIDs()

View File

@ -21,7 +21,7 @@
use futures::{future, stream, Future, Stream};
use identify_transport::{IdentifyTransport, IdentifyTransportOutcome};
use libp2p_core::{PeerId, MuxedTransport, Transport};
use multiaddr::{AddrComponent, Multiaddr, ToCid};
use multiaddr::{AddrComponent, Multiaddr};
use std::io::{Error as IoError, ErrorKind as IoErrorKind};
use tokio_io::{AsyncRead, AsyncWrite};
@ -93,14 +93,8 @@ where
.map(move |info| {
let peer_id = info.info.public_key.clone().into_peer_id();
debug!("Identified {} as {:?}", original_addr, peer_id);
match peer_id.as_bytes().to_cid() {
Ok(cid) => {
let addr: Multiaddr = AddrComponent::P2P(cid).into();
Ok(addr)
},
Err(e) => Err(IoError::new(IoErrorKind::InvalidData, e))
}
}).flatten()) as Box<Future<Item = _, Error = _>>;
AddrComponent::P2P(peer_id.into()).into()
})) as Box<Future<Item = _, Error = _>>;
(out, real_addr)
});
@ -200,14 +194,8 @@ where
.map(move |info| {
let peer_id = info.info.public_key.clone().into_peer_id();
debug!("Identified {} as {:?}", original_addr, peer_id);
match peer_id.as_bytes().to_cid() {
Ok(cid) => {
let addr: Multiaddr = AddrComponent::P2P(cid).into();
Ok(addr)
},
Err(e) => Err(IoError::new(IoErrorKind::InvalidData, e))
}
}).flatten()) as Box<Future<Item = _, Error = _>>;
AddrComponent::P2P(peer_id.into()).into()
})) as Box<Future<Item = _, Error = _>>;
(out, real_addr)
});
@ -254,14 +242,8 @@ where
.map(move |info| {
let peer_id = info.info.public_key.clone().into_peer_id();
debug!("Identified {} as {:?}", original_addr, peer_id);
match peer_id.as_bytes().to_cid() {
Ok(cid) => {
let addr: Multiaddr = AddrComponent::P2P(cid).into();
Ok(addr)
},
Err(e) => Err(IoError::new(IoErrorKind::InvalidData, e))
}
}).flatten()) as Box<Future<Item = _, Error = _>>;
AddrComponent::P2P(peer_id.into()).into()
})) as Box<Future<Item = _, Error = _>>;
(out, real_addr)
});
@ -297,7 +279,7 @@ fn multiaddr_to_peerid(addr: Multiaddr) -> Result<PeerId, Multiaddr> {
match components.last() {
Some(&AddrComponent::P2P(ref peer_id)) => {
match PeerId::from_bytes(peer_id.to_bytes()) {
match PeerId::from_multihash(peer_id.clone()) {
Ok(peer_id) => Ok(peer_id),
Err(_) => Err(addr),
}
@ -315,7 +297,7 @@ mod tests {
use PeerIdTransport;
use futures::{Future, Stream};
use libp2p_core::{Transport, PeerId, PublicKey};
use multiaddr::{AddrComponent, Multiaddr, ToCid};
use multiaddr::{AddrComponent, Multiaddr};
use std::io::Error as IoError;
use std::iter;
@ -369,7 +351,7 @@ mod tests {
});
let future = transport
.dial(iter::once(AddrComponent::P2P(peer_id.into_bytes().to_cid().unwrap())).collect())
.dial(iter::once(AddrComponent::P2P(peer_id.into())).collect())
.unwrap_or_else(|_| panic!())
.then::<_, Result<(), ()>>(|_| Ok(()));

View File

@ -30,7 +30,7 @@ extern crate multiaddr;
use bigint::U512;
use futures::{Future, Stream};
use libp2p::peerstore::{PeerAccess, PeerId, Peerstore};
use multiaddr::{Multiaddr, ToCid};
use multiaddr::Multiaddr;
use std::collections::HashMap;
use std::env;
use std::sync::{Arc, Mutex};
@ -191,8 +191,7 @@ fn main() {
let finish_enum = kad_system
.find_node(my_peer_id.clone(), |peer| {
let cid = peer.clone().into_bytes().to_cid().unwrap();
let addr = Multiaddr::from(libp2p::multiaddr::AddrComponent::P2P(cid));
let addr = Multiaddr::from(libp2p::multiaddr::AddrComponent::P2P(peer.clone().into()));
active_kad_connections.lock().unwrap().entry(peer.clone())
.or_insert_with(Default::default)
.dial(&swarm_controller, &addr, transport.clone().with_upgrade(KadConnecConfig::new()))
@ -245,7 +244,7 @@ fn p2p_multiaddr_to_node_id(client_addr: Multiaddr) -> PeerId {
}
match (first, second) {
(Some(libp2p::multiaddr::AddrComponent::P2P(node_id)), None) =>
PeerId::from_bytes(node_id.to_bytes()).expect("libp2p always reports a valid node id"),
PeerId::from_multihash(node_id).expect("libp2p always reports a valid node id"),
_ => panic!("Reported multiaddress is in the wrong format ; programmer error")
}
}
@ -270,7 +269,7 @@ where
let p2p_component = multiaddr.pop().expect("hard-coded multiaddr is empty");
let peer = match p2p_component {
libp2p::multiaddr::AddrComponent::P2P(key) => {
PeerId::from_bytes(key.to_bytes()).expect("invalid peer id")
PeerId::from_multihash(key).expect("invalid peer id")
}
_ => panic!("hard-coded multiaddr didn't end with /p2p/"),
};

View File

@ -9,8 +9,9 @@ readme = "README.md"
version = "0.3.0"
[dependencies]
bs58 = "0.2.0"
byteorder = "~0.4"
cid = { path = "../cid" }
multihash = { path = "../multihash" }
integer-encoding = "~1.0.3"
[dev-dependencies]

View File

@ -1,5 +1,6 @@
use std::{net, fmt, error, io, num, string};
use cid;
use bs58;
use multihash;
use byteorder;
pub type Result<T> = ::std::result::Result<T, Error>;
@ -46,12 +47,19 @@ impl From<io::Error> for Error {
}
}
impl From<cid::Error> for Error {
fn from(err: cid::Error) -> Error {
impl From<multihash::DecodeOwnedError> for Error {
fn from(err: multihash::DecodeOwnedError) -> Error {
Error::ParsingError(err.into())
}
}
impl From<bs58::decode::DecodeError> for Error {
fn from(err: bs58::decode::DecodeError) -> Error {
Error::ParsingError(err.into())
}
}
impl From<net::AddrParseError> for Error {
fn from(err: net::AddrParseError) -> Error {
Error::ParsingError(err.into())

View File

@ -2,16 +2,17 @@
///!
///! Implementation of [multiaddr](https://github.com/jbenet/multiaddr)
///! in Rust.
extern crate bs58;
extern crate byteorder;
extern crate cid;
extern crate integer_encoding;
pub extern crate multihash;
mod protocol;
mod errors;
pub use errors::{Result, Error};
pub use protocol::{Protocol, ProtocolArgSize, AddrComponent};
pub use self::cid::{Cid, ToCid};
use std::fmt;
use std::iter::FromIterator;

View File

@ -1,10 +1,10 @@
use bs58;
use std::net::{Ipv4Addr, Ipv6Addr};
use std::str::FromStr;
use std::convert::From;
use std::io::{Cursor, Write, Result as IoResult};
use byteorder::{BigEndian, ReadBytesExt, WriteBytesExt};
use cid::Cid;
use cid::ToCid;
use multihash::Multihash;
use integer_encoding::{VarInt, VarIntWriter};
use {Result, Error};
@ -256,7 +256,8 @@ impl Protocol {
Ok(AddrComponent::SCTP(parsed))
}
Protocol::P2P => {
Ok(AddrComponent::P2P(a.to_cid()?))
let decoded = bs58::decode(a).into_vec()?;
Ok(AddrComponent::P2P(Multihash::from_bytes(decoded)?))
}
Protocol::ONION => unimplemented!(), // TODO:
Protocol::QUIC => Ok(AddrComponent::QUIC),
@ -291,7 +292,7 @@ pub enum AddrComponent {
UDT,
UTP,
UNIX(String),
P2P(Cid),
P2P(Multihash),
HTTP,
HTTPS,
ONION(Vec<u8>),
@ -406,7 +407,7 @@ impl AddrComponent {
AddrComponent::UNIX(String::from_utf8(data.to_owned())?)
}
Protocol::P2P => {
AddrComponent::P2P(data.to_cid()?)
AddrComponent::P2P(Multihash::from_bytes(data.to_owned())?)
}
Protocol::ONION => unimplemented!(), // TODO:
Protocol::QUIC => AddrComponent::QUIC,
@ -448,8 +449,8 @@ impl AddrComponent {
out.write_varint(bytes.len())?;
out.write_all(&bytes)?;
}
AddrComponent::P2P(cid) => {
let bytes = cid.to_bytes();
AddrComponent::P2P(multihash) => {
let bytes = multihash.into_bytes();
out.write_varint(bytes.len())?;
out.write_all(&bytes)?;
}
@ -488,7 +489,7 @@ impl ToString for AddrComponent {
AddrComponent::UDT => format!("/udt"),
AddrComponent::UTP => format!("/utp"),
AddrComponent::UNIX(ref s) => format!("/unix/{}", s.clone()),
AddrComponent::P2P(ref c) => format!("/p2p/{}", c),
AddrComponent::P2P(ref c) => format!("/p2p/{}", bs58::encode(c.as_bytes()).into_string()),
AddrComponent::HTTP => format!("/http"),
AddrComponent::HTTPS => format!("/https"),
AddrComponent::ONION(_) => unimplemented!(),//format!("/onion"), // TODO:

View File

@ -146,7 +146,7 @@ impl Peer {
pub(crate) fn from(mut addr: Multiaddr) -> Option<Peer> {
match addr.pop() {
Some(AddrComponent::P2P(id)) => {
PeerId::from_bytes(id.to_bytes()).ok().map(|pid| {
PeerId::from_multihash(id).ok().map(|pid| {
if addr.iter().count() == 0 {
Peer {
id: pid,