Add PeerId::random() (#661)

This commit is contained in:
Pierre Krieger
2018-11-20 13:44:36 +01:00
committed by GitHub
parent 080a75451f
commit b213fd7bd7
10 changed files with 92 additions and 39 deletions

View File

@ -477,7 +477,6 @@ mod tests {
use futures::future::{self};
use tests::dummy_muxer::{DummyMuxer, DummyConnectionState};
use tests::dummy_handler::{Handler, InEvent, OutEvent, HandlerState};
use PublicKey;
use tokio::runtime::current_thread::Runtime;
use tokio::runtime::Builder;
use nodes::NodeHandlerEvent;
@ -490,7 +489,7 @@ mod tests {
#[test]
fn has_connection_is_false_before_a_connection_has_been_made() {
let cs = TestCollectionStream::new();
let peer_id = PublicKey::Rsa((0 .. 128).map(|_| -> u8 { 1 }).collect()).into_peer_id();
let peer_id = PeerId::random();
assert!(!cs.has_connection(&peer_id));
}
@ -503,7 +502,7 @@ mod tests {
#[test]
fn retrieving_a_peer_is_none_if_peer_is_missing_or_not_connected() {
let mut cs = TestCollectionStream::new();
let peer_id = PublicKey::Rsa((0 .. 128).map(|_| -> u8 { 1 }).collect()).into_peer_id();
let peer_id = PeerId::random();
assert!(cs.peer_mut(&peer_id).is_none());
let handler = Handler::default();
@ -515,7 +514,7 @@ mod tests {
#[test]
fn collection_stream_reaches_the_nodes() {
let mut cs = TestCollectionStream::new();
let peer_id = PublicKey::Rsa((0 .. 128).map(|_| -> u8 { 1 }).collect()).into_peer_id();
let peer_id = PeerId::random();
let mut muxer = DummyMuxer::new();
muxer.set_inbound_connection_state(DummyConnectionState::Pending);
@ -544,7 +543,7 @@ mod tests {
#[test]
fn accepting_a_node_yields_new_entry() {
let mut cs = TestCollectionStream::new();
let peer_id = PublicKey::Rsa((0 .. 128).map(|_| -> u8 { 1 }).collect()).into_peer_id();
let peer_id = PeerId::random();
let fut = future::ok::<_, Void>((peer_id.clone(), DummyMuxer::new()));
cs.add_reach_attempt(fut, Handler::default());
@ -581,7 +580,7 @@ mod tests {
#[test]
fn events_in_a_node_reaches_the_collection_stream() {
let cs = Arc::new(Mutex::new(TestCollectionStream::new()));
let task_peer_id = PublicKey::Rsa((0 .. 128).map(|_| -> u8 { 1 }).collect()).into_peer_id();
let task_peer_id = PeerId::random();
let mut handler = Handler::default();
handler.state = Some(HandlerState::Ready(Some(NodeHandlerEvent::Custom(OutEvent::Custom("init")))));
@ -683,7 +682,7 @@ mod tests {
#[test]
fn task_closed_with_error_when_task_is_connected_yields_node_error() {
let cs = Arc::new(Mutex::new(TestCollectionStream::new()));
let peer_id = PublicKey::Rsa((0 .. 128).map(|_| -> u8 { 1 }).collect()).into_peer_id();
let peer_id = PeerId::random();
let muxer = DummyMuxer::new();
let task_inner_fut = future::ok::<_, Void>((peer_id.clone(), muxer));
let mut handler = Handler::default();
@ -729,7 +728,7 @@ mod tests {
#[test]
fn task_closed_ok_when_task_is_connected_yields_node_closed() {
let cs = Arc::new(Mutex::new(TestCollectionStream::new()));
let peer_id = PublicKey::Rsa((0 .. 128).map(|_| -> u8 { 1 }).collect()).into_peer_id();
let peer_id = PeerId::random();
let muxer = DummyMuxer::new();
let task_inner_fut = future::ok::<_, Void>((peer_id.clone(), muxer));
let mut handler = Handler::default();
@ -795,7 +794,7 @@ mod tests {
#[test]
fn interrupting_an_established_connection_is_err() {
let cs = Arc::new(Mutex::new(TestCollectionStream::new()));
let peer_id = PublicKey::Rsa((0 .. 128).map(|_| -> u8 { 1 }).collect()).into_peer_id();
let peer_id = PeerId::random();
let muxer = DummyMuxer::new();
let task_inner_fut = future::ok::<_, Void>((peer_id.clone(), muxer));
let handler = Handler::default();

View File

@ -467,13 +467,12 @@ mod tests {
use futures::future::{self, FutureResult};
use futures::sync::mpsc::{UnboundedReceiver, UnboundedSender};
use nodes::handled_node::NodeHandlerEvent;
use rand::random;
use tests::dummy_handler::{Handler, HandlerState, InEvent, OutEvent, TestHandledNode};
use tests::dummy_muxer::{DummyMuxer, DummyConnectionState};
use tokio::runtime::Builder;
use tokio::runtime::current_thread::Runtime;
use void::Void;
use {PeerId, PublicKey};
use PeerId;
type TestNodeTask = NodeTask<
FutureResult<(PeerId, DummyMuxer), IoError>,
@ -495,7 +494,7 @@ mod tests {
task_id: TaskId(123),
inner_node: None,
inner_fut: {
let peer_id = PublicKey::Rsa((0 .. 2048).map(|_| -> u8 { random() }).collect()).into_peer_id();
let peer_id = PeerId::random();
Some(future::ok((peer_id, DummyMuxer::new())))
},
}
@ -576,7 +575,7 @@ mod tests {
}
fn handled_nodes_tasks(&mut self) -> (TestHandledNodesTasks, Vec<TaskId>) {
let mut handled_nodes = HandledNodesTasks::new();
let peer_id = PublicKey::Rsa((0 .. 2048).map(|_| -> u8 { random() }).collect()).into_peer_id();
let peer_id = PeerId::random();
let mut task_ids = Vec::new();
for _i in 0..self.task_count {
let fut = future::ok::<_, Void>((peer_id.clone(), self.muxer.clone()));
@ -628,7 +627,7 @@ mod tests {
fn task_exits_when_node_is_done() {
let mut rt = Runtime::new().unwrap();
let fut = {
let peer_id = PublicKey::Rsa((0 .. 2048).map(|_| -> u8 { random() }).collect()).into_peer_id();
let peer_id = PeerId::random();
let mut muxer = DummyMuxer::new();
muxer.set_inbound_connection_state(DummyConnectionState::Closed);
muxer.set_outbound_connection_state(DummyConnectionState::Closed);

View File

@ -75,6 +75,16 @@ impl PeerId {
}
}
/// Generates a random peer ID from a cryptographically secure PRNG.
///
/// This is useful for randomly walking on a DHT, or for testing purposes.
#[inline]
pub fn random() -> PeerId {
PeerId {
multihash: multihash::Multihash::random(multihash::Hash::SHA2256)
}
}
/// Returns a raw bytes representation of this `PeerId`.
///
/// Note that this is not the same as the public key of the peer.
@ -179,4 +189,12 @@ mod tests {
let second: PeerId = peer_id.to_base58().parse().unwrap();
assert_eq!(peer_id, second);
}
#[test]
fn random_peer_id_is_valid() {
for _ in 0 .. 5000 {
let peer_id = PeerId::random();
assert_eq!(peer_id, PeerId::from_bytes(peer_id.clone().into_bytes()).unwrap());
}
}
}

View File

@ -17,6 +17,7 @@ documentation = "https://docs.rs/multihash/"
[dependencies]
blake2 = { version = "0.7", default-features = false }
rand = { version = "0.6", default-features = false, features = ["std"] }
sha1 = "0.5"
sha2 = { version = "0.7", default-features = false }
tiny-keccak = "1.4"

View File

@ -6,6 +6,7 @@
//! A `MultihashRef` is the same as a `Multihash`, except that it doesn't own its data.
extern crate blake2;
extern crate rand;
extern crate sha1;
extern crate sha2;
extern crate tiny_keccak;
@ -132,6 +133,28 @@ impl Multihash {
Ok(Multihash { bytes })
}
/// Generates a random `Multihash` from a cryptographically secure PRNG.
pub fn random(hash: Hash) -> Multihash {
let mut buf = encode::u16_buffer();
let code = encode::u16(hash.code(), &mut buf);
let header_len = code.len() + 1;
let size = hash.size();
let mut output = Vec::new();
output.resize(header_len + size as usize, 0);
output[..code.len()].copy_from_slice(code);
output[code.len()] = size;
for b in output[header_len..].iter_mut() {
*b = rand::random();
}
Multihash {
bytes: output,
}
}
/// Returns the bytes representation of the multihash.
#[inline]
pub fn into_bytes(self) -> Vec<u8> {
@ -250,3 +273,24 @@ pub fn to_hex(bytes: &[u8]) -> String {
hex
}
#[cfg(test)]
mod tests {
use {Hash, Multihash};
#[test]
fn rand_generates_valid_multihash() {
// Iterate over every possible hash function.
for code in 0 .. u16::max_value() {
let hash_fn = match Hash::from_code(code) {
Some(c) => c,
None => continue,
};
for _ in 0 .. 2000 {
let hash = Multihash::random(hash_fn);
assert_eq!(hash, Multihash::from_bytes(hash.clone().into_bytes()).unwrap());
}
}
}
}

View File

@ -523,9 +523,8 @@ mod tests {
use futures::{Future, Poll, Sink, StartSend, Stream};
use futures::sync::mpsc;
use kad_server::{self, KadIncomingRequest, KadConnecController};
use libp2p_core::PublicKey;
use libp2p_core::PeerId;
use protocol::{KadConnectionType, KadPeer};
use rand;
// This struct merges a stream and a sink and is quite useful for tests.
struct Wrapper<St, Si>(St, Si);
@ -591,18 +590,12 @@ mod tests {
fn find_node_response() {
let (controller_a, stream_events_a, _controller_b, stream_events_b) = build_test();
let random_peer_id = {
let buf = (0 .. 1024).map(|_| -> u8 { rand::random() }).collect::<Vec<_>>();
PublicKey::Rsa(buf).into_peer_id()
};
let random_peer_id = PeerId::random();
let find_node_fut = controller_a.find_node(&random_peer_id);
let example_response = KadPeer {
node_id: {
let buf = (0 .. 1024).map(|_| -> u8 { rand::random() }).collect::<Vec<_>>();
PublicKey::Rsa(buf).into_peer_id()
},
node_id: PeerId::random(),
multiaddrs: Vec::new(),
connection_ty: KadConnectionType::Connected,
};

View File

@ -432,7 +432,7 @@ mod tests {
use self::libp2p_tcp_transport::TcpConfig;
use futures::{Future, Sink, Stream};
use libp2p_core::{Transport, PeerId, PublicKey};
use libp2p_core::{Transport, PeerId};
use multihash::{encode, Hash};
use protocol::{KadConnectionType, KadMsg, KademliaProtocolConfig, KadPeer};
use std::sync::mpsc;
@ -454,12 +454,12 @@ mod tests {
key: encode(Hash::SHA2256, &[10, 11, 12]).unwrap(),
});
test_one(KadMsg::FindNodeReq {
key: PeerId::from_public_key(PublicKey::Rsa(vec![9, 12, 0, 245, 245, 201, 28, 95]))
key: PeerId::random()
});
test_one(KadMsg::FindNodeRes {
closer_peers: vec![
KadPeer {
node_id: PeerId::from_public_key(PublicKey::Rsa(vec![93, 80, 12, 250])),
node_id: PeerId::random(),
multiaddrs: vec!["/ip4/100.101.102.103/tcp/20105".parse().unwrap()],
connection_ty: KadConnectionType::Connected,
},
@ -471,14 +471,14 @@ mod tests {
test_one(KadMsg::GetProvidersRes {
closer_peers: vec![
KadPeer {
node_id: PeerId::from_public_key(PublicKey::Rsa(vec![93, 80, 12, 250])),
node_id: PeerId::random(),
multiaddrs: vec!["/ip4/100.101.102.103/tcp/20105".parse().unwrap()],
connection_ty: KadConnectionType::Connected,
},
],
provider_peers: vec![
KadPeer {
node_id: PeerId::from_public_key(PublicKey::Rsa(vec![12, 90, 1, 28])),
node_id: PeerId::random(),
multiaddrs: vec!["/ip4/200.201.202.203/tcp/1999".parse().unwrap()],
connection_ty: KadConnectionType::NotConnected,
},
@ -487,7 +487,7 @@ mod tests {
test_one(KadMsg::AddProvider {
key: encode(Hash::SHA2256, &[9, 12, 0, 245, 245, 201, 28, 95]).unwrap(),
provider_peer: KadPeer {
node_id: PeerId::from_public_key(PublicKey::Rsa(vec![5, 6, 7, 8])),
node_id: PeerId::random(),
multiaddrs: vec!["/ip4/9.1.2.3/udp/23".parse().unwrap()],
connection_ty: KadConnectionType::Connected,
},

View File

@ -151,7 +151,7 @@ mod tests {
let temp_file = self::tempfile::NamedTempFile::new().unwrap();
let peer_store = ::json_peerstore::JsonPeerstore::new(temp_file.path()).unwrap();
let peer_id = PeerId::from_public_key(PublicKey::Ed25519(vec![1, 2, 3]));
let peer_id = PeerId::random();
let addr = "/ip4/0.0.0.0/tcp/0".parse::<Multiaddr>().unwrap();
peer_store

View File

@ -50,7 +50,7 @@
//!
//! // In this example we use a `MemoryPeerstore`, but you can easily swap it for another backend.
//! let mut peerstore = MemoryPeerstore::empty();
//! let peer_id = PeerId::from_public_key(PublicKey::Rsa(vec![1, 2, 3, 4]));
//! let peer_id = PeerId::random();
//!
//! // Let's write some information about a peer.
//! {

View File

@ -33,14 +33,13 @@ macro_rules! peerstore_tests {
use std::thread;
use std::time::Duration;
use {Peerstore, PeerAccess, PeerId};
use libp2p_core::PublicKey;
use multiaddr::Multiaddr;
#[test]
fn initially_empty() {
$($stmt;)*
let peer_store = $create_peerstore;
let peer_id = PeerId::from_public_key(PublicKey::Ed25519(vec![1, 2, 3]));
let peer_id = PeerId::random();
assert_eq!(peer_store.peers().count(), 0);
assert!(peer_store.peer(&peer_id).is_none());
}
@ -49,7 +48,7 @@ macro_rules! peerstore_tests {
fn set_then_get_addr() {
$($stmt;)*
let peer_store = $create_peerstore;
let peer_id = PeerId::from_public_key(PublicKey::Ed25519(vec![1, 2, 3]));
let peer_id = PeerId::random();
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));
@ -63,7 +62,7 @@ macro_rules! peerstore_tests {
// Add an already-expired address to a peer.
$($stmt;)*
let peer_store = $create_peerstore;
let peer_id = PeerId::from_public_key(PublicKey::Ed25519(vec![1, 2, 3]));
let peer_id = PeerId::random();
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));
@ -77,7 +76,7 @@ macro_rules! peerstore_tests {
fn clear_addrs() {
$($stmt;)*
let peer_store = $create_peerstore;
let peer_id = PeerId::from_public_key(PublicKey::Ed25519(vec![1, 2, 3]));
let peer_id = PeerId::random();
let addr = "/ip4/0.0.0.0/tcp/0".parse::<Multiaddr>().unwrap();
peer_store.peer_or_create(&peer_id)
@ -92,7 +91,7 @@ macro_rules! peerstore_tests {
fn no_update_ttl() {
$($stmt;)*
let peer_store = $create_peerstore;
let peer_id = PeerId::from_public_key(PublicKey::Ed25519(vec![1, 2, 3]));
let peer_id = PeerId::random();
let addr1 = "/ip4/0.0.0.0/tcp/0".parse::<Multiaddr>().unwrap();
let addr2 = "/ip4/0.0.0.1/tcp/0".parse::<Multiaddr>().unwrap();
@ -113,7 +112,7 @@ macro_rules! peerstore_tests {
fn force_update_ttl() {
$($stmt;)*
let peer_store = $create_peerstore;
let peer_id = PeerId::from_public_key(PublicKey::Ed25519(vec![1, 2, 3]));
let peer_id = PeerId::random();
let addr1 = "/ip4/0.0.0.0/tcp/0".parse::<Multiaddr>().unwrap();
let addr2 = "/ip4/0.0.0.1/tcp/0".parse::<Multiaddr>().unwrap();