Add a proper PeerId to Peerstore (#115)

This commit is contained in:
Pierre Krieger 2018-02-08 12:00:25 +01:00 committed by GitHub
parent 6179778ba9
commit c89e68bfb6
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 84 additions and 16 deletions

View File

@ -22,7 +22,7 @@ extern crate libp2p_peerstore;
extern crate libp2p_swarm; extern crate libp2p_swarm;
extern crate multiaddr; extern crate multiaddr;
use libp2p_peerstore::{PeerAccess, Peerstore}; use libp2p_peerstore::{PeerId, PeerAccess, Peerstore};
use multiaddr::Multiaddr; use multiaddr::Multiaddr;
use std::time::Duration; use std::time::Duration;
@ -58,7 +58,7 @@ where
peer_store peer_store
.clone() .clone()
.peer_or_create(&public_key) .peer_or_create(&PeerId::from_bytes(public_key).unwrap())
.add_addr(multiaddr, ttl.clone()); .add_addr(multiaddr, ttl.clone());
} }
} }

View File

@ -9,6 +9,7 @@ datastore = { path = "../datastore" }
futures = "0.1.0" futures = "0.1.0"
owning_ref = "0.3.3" owning_ref = "0.3.3"
multiaddr = "0.2" multiaddr = "0.2"
multihash = "0.7.0"
serde = "1.0" serde = "1.0"
serde_derive = "1.0" serde_derive = "1.0"

View File

@ -67,13 +67,13 @@ impl<'a> Peerstore for &'a JsonPeerstore {
#[inline] #[inline]
fn peer(self, peer_id: &PeerId) -> Option<Self::PeerAccess> { fn peer(self, peer_id: &PeerId) -> Option<Self::PeerAccess> {
let hash = peer_id.to_base58(); let hash = peer_id.as_bytes().to_base58();
self.store.lock(hash.into()).map(JsonPeerstoreAccess) self.store.lock(hash.into()).map(JsonPeerstoreAccess)
} }
#[inline] #[inline]
fn peer_or_create(self, peer_id: &PeerId) -> Self::PeerAccess { fn peer_or_create(self, peer_id: &PeerId) -> Self::PeerAccess {
let hash = peer_id.to_base58(); let hash = peer_id.as_bytes().to_base58();
JsonPeerstoreAccess(self.store.lock_or_create(hash.into())) JsonPeerstoreAccess(self.store.lock_or_create(hash.into()))
} }
@ -90,7 +90,7 @@ impl<'a> Peerstore for &'a JsonPeerstore {
let list = query.filter_map(|(key, _)| { let list = query.filter_map(|(key, _)| {
// We filter out invalid elements. This can happen if the JSON storage file was // We filter out invalid elements. This can happen if the JSON storage file was
// corrupted or manually modified by the user. // corrupted or manually modified by the user.
key.from_base58().ok() PeerId::from_bytes(key.from_base58().ok()?).ok()
}) })
.collect() .collect()
.wait(); // Wait can never block for the JSON datastore. .wait(); // Wait can never block for the JSON datastore.

View File

@ -42,13 +42,13 @@
//! //!
//! # fn main() { //! # fn main() {
//! use libp2p_peerstore::memory_peerstore::MemoryPeerstore; //! use libp2p_peerstore::memory_peerstore::MemoryPeerstore;
//! use libp2p_peerstore::{Peerstore, PeerAccess}; //! use libp2p_peerstore::{PeerId, Peerstore, PeerAccess};
//! use multiaddr::Multiaddr; //! use multiaddr::Multiaddr;
//! use std::time::Duration; //! use std::time::Duration;
//! //!
//! // In this example we use a `MemoryPeerstore`, but you can easily swap it for another backend. //! // In this example we use a `MemoryPeerstore`, but you can easily swap it for another backend.
//! let mut peerstore = MemoryPeerstore::empty(); //! let mut peerstore = MemoryPeerstore::empty();
//! let peer_id = vec![1, 2, 3, 4]; //! let peer_id = PeerId::from_public_key(&[1, 2, 3, 4]);
//! //!
//! // Let's write some information about a peer. //! // Let's write some information about a peer.
//! { //! {
@ -73,11 +73,15 @@ extern crate base58;
extern crate datastore; extern crate datastore;
extern crate futures; extern crate futures;
extern crate multiaddr; extern crate multiaddr;
extern crate multihash;
extern crate owning_ref; extern crate owning_ref;
extern crate serde; extern crate serde;
#[macro_use] #[macro_use]
extern crate serde_derive; extern crate serde_derive;
use std::fmt;
use base58::ToBase58;
pub use self::peerstore::{Peerstore, PeerAccess}; pub use self::peerstore::{Peerstore, PeerAccess};
#[macro_use] #[macro_use]
@ -88,5 +92,68 @@ pub mod memory_peerstore;
mod peerstore; mod peerstore;
mod peer_info; mod peer_info;
pub type PeerId = Vec<u8>;
pub type TTL = std::time::Duration; pub type TTL = std::time::Duration;
/// Identifier of a peer of the network.
///
/// The data is a multihash of the public key of the peer.
// TODO: maybe keep things in decoded version?
#[derive(Clone, PartialEq, Eq, Hash)]
pub struct PeerId {
multihash: Vec<u8>,
}
impl fmt::Debug for PeerId {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "PeerId({})", self.multihash.to_base58())
}
}
impl PeerId {
/// Builds a `PeerId` from a public key.
#[inline]
pub fn from_public_key(public_key: &[u8]) -> PeerId {
let data = multihash::encode(multihash::Hash::SHA2256, public_key)
.expect("sha2-256 is always supported");
PeerId { multihash: data }
}
/// Checks whether `data` is a valid `PeerId`. If so, returns the `PeerId`. If not, returns
/// back the data as an error.
#[inline]
pub fn from_bytes(data: Vec<u8>) -> Result<PeerId, Vec<u8>> {
match multihash::decode(&data) {
Ok(_) => Ok(PeerId { multihash: data }),
Err(_) => Err(data),
}
}
/// Returns a raw bytes representation of this `PeerId`.
#[inline]
pub fn into_bytes(self) -> Vec<u8> {
self.multihash
}
/// Returns a raw bytes representation of this `PeerId`.
#[inline]
pub fn as_bytes(&self) -> &[u8] {
&self.multihash
}
/// Returns the raw bytes of the hash of this `PeerId`.
#[inline]
pub fn hash(&self) -> &[u8] {
let multihash::Multihash { digest, .. } = multihash::decode(&self.multihash)
.expect("our inner value should always be valid");
digest
}
/// Checks whether the public key passed as parameter matches the public key of this `PeerId`.
pub fn is_public_key(&self, public_key: &[u8]) -> bool {
let multihash::Multihash { alg, .. } = multihash::decode(&self.multihash)
.expect("our inner value should always be valid");
let compare = multihash::encode(alg, public_key)
.expect("unsupported multihash algorithm"); // TODO: what to do here?
compare == self.multihash
}
}

View File

@ -32,14 +32,14 @@ macro_rules! peerstore_tests {
extern crate multihash; extern crate multihash;
use std::thread; use std::thread;
use std::time::Duration; use std::time::Duration;
use {Peerstore, PeerAccess}; use {Peerstore, PeerAccess, PeerId};
use multiaddr::Multiaddr; use multiaddr::Multiaddr;
#[test] #[test]
fn initially_empty() { fn initially_empty() {
$($stmt;)* $($stmt;)*
let peer_store = $create_peerstore; let peer_store = $create_peerstore;
let peer_id = multihash::encode(multihash::Hash::SHA2512, &[1, 2, 3]).unwrap(); let peer_id = PeerId::from_public_key(&[1, 2, 3]);
assert_eq!(peer_store.peers().count(), 0); assert_eq!(peer_store.peers().count(), 0);
assert!(peer_store.peer(&peer_id).is_none()); assert!(peer_store.peer(&peer_id).is_none());
} }
@ -48,7 +48,7 @@ macro_rules! peerstore_tests {
fn set_pub_key_then_retreive() { fn set_pub_key_then_retreive() {
$($stmt;)* $($stmt;)*
let peer_store = $create_peerstore; let peer_store = $create_peerstore;
let peer_id = multihash::encode(multihash::Hash::SHA2512, &[1, 2, 3]).unwrap(); let peer_id = PeerId::from_public_key(&[1, 2, 3]);
peer_store.peer_or_create(&peer_id).set_pub_key(vec![9, 8, 7]); peer_store.peer_or_create(&peer_id).set_pub_key(vec![9, 8, 7]);
@ -61,7 +61,7 @@ macro_rules! peerstore_tests {
fn set_then_get_addr() { fn set_then_get_addr() {
$($stmt;)* $($stmt;)*
let peer_store = $create_peerstore; let peer_store = $create_peerstore;
let peer_id = multihash::encode(multihash::Hash::SHA2512, &[1, 2, 3]).unwrap(); let peer_id = PeerId::from_public_key(&[1, 2, 3]);
let addr = "/ip4/0.0.0.0/tcp/0".parse::<Multiaddr>().unwrap(); let addr = "/ip4/0.0.0.0/tcp/0".parse::<Multiaddr>().unwrap();
peer_store.peer_or_create(&peer_id).add_addr(addr.clone(), Duration::from_millis(5000)); peer_store.peer_or_create(&peer_id).add_addr(addr.clone(), Duration::from_millis(5000));
@ -75,7 +75,7 @@ macro_rules! peerstore_tests {
// Add an already-expired address to a peer. // Add an already-expired address to a peer.
$($stmt;)* $($stmt;)*
let peer_store = $create_peerstore; let peer_store = $create_peerstore;
let peer_id = multihash::encode(multihash::Hash::SHA2512, &[1, 2, 3]).unwrap(); let peer_id = PeerId::from_public_key(&[1, 2, 3]);
let addr = "/ip4/0.0.0.0/tcp/0".parse::<Multiaddr>().unwrap(); let addr = "/ip4/0.0.0.0/tcp/0".parse::<Multiaddr>().unwrap();
peer_store.peer_or_create(&peer_id).add_addr(addr.clone(), Duration::from_millis(0)); peer_store.peer_or_create(&peer_id).add_addr(addr.clone(), Duration::from_millis(0));
@ -89,7 +89,7 @@ macro_rules! peerstore_tests {
fn clear_addrs() { fn clear_addrs() {
$($stmt;)* $($stmt;)*
let peer_store = $create_peerstore; let peer_store = $create_peerstore;
let peer_id = multihash::encode(multihash::Hash::SHA2512, &[1, 2, 3]).unwrap(); let peer_id = PeerId::from_public_key(&[1, 2, 3]);
let addr = "/ip4/0.0.0.0/tcp/0".parse::<Multiaddr>().unwrap(); let addr = "/ip4/0.0.0.0/tcp/0".parse::<Multiaddr>().unwrap();
peer_store.peer_or_create(&peer_id).add_addr(addr.clone(), Duration::from_millis(5000)); peer_store.peer_or_create(&peer_id).add_addr(addr.clone(), Duration::from_millis(5000));
@ -103,7 +103,7 @@ macro_rules! peerstore_tests {
fn no_update_ttl() { fn no_update_ttl() {
$($stmt;)* $($stmt;)*
let peer_store = $create_peerstore; let peer_store = $create_peerstore;
let peer_id = multihash::encode(multihash::Hash::SHA2512, &[1, 2, 3]).unwrap(); let peer_id = PeerId::from_public_key(&[1, 2, 3]);
let addr1 = "/ip4/0.0.0.0/tcp/0".parse::<Multiaddr>().unwrap(); let addr1 = "/ip4/0.0.0.0/tcp/0".parse::<Multiaddr>().unwrap();
let addr2 = "/ip4/0.0.0.1/tcp/0".parse::<Multiaddr>().unwrap(); let addr2 = "/ip4/0.0.0.1/tcp/0".parse::<Multiaddr>().unwrap();
@ -122,7 +122,7 @@ macro_rules! peerstore_tests {
fn force_update_ttl() { fn force_update_ttl() {
$($stmt;)* $($stmt;)*
let peer_store = $create_peerstore; let peer_store = $create_peerstore;
let peer_id = multihash::encode(multihash::Hash::SHA2512, &[1, 2, 3]).unwrap(); let peer_id = PeerId::from_public_key(&[1, 2, 3]);
let addr1 = "/ip4/0.0.0.0/tcp/0".parse::<Multiaddr>().unwrap(); let addr1 = "/ip4/0.0.0.0/tcp/0".parse::<Multiaddr>().unwrap();
let addr2 = "/ip4/0.0.0.1/tcp/0".parse::<Multiaddr>().unwrap(); let addr2 = "/ip4/0.0.0.1/tcp/0".parse::<Multiaddr>().unwrap();