diff --git a/grin/src/seed.rs b/grin/src/seed.rs index f098a12d4..79ce46bb6 100644 --- a/grin/src/seed.rs +++ b/grin/src/seed.rs @@ -22,6 +22,7 @@ use std::net::SocketAddr; use std::str::{self, FromStr}; use std::sync::Arc; use std::time; +use std::time::Duration; use cpupool; use futures::{self, future, Future, Stream}; @@ -117,7 +118,7 @@ impl Seeder { if peers.len() > 0 { debug!( LOGGER, - "Got {} more peers from db, trying to connect.", + "Got {} peers from db, trying to connect.", peers.len() ); thread_rng().shuffle(&mut peers[..]); @@ -274,7 +275,11 @@ fn connect_and_req( h: reactor::Handle, addr: SocketAddr, ) -> Box<Future<Item = (), Error = ()>> { - let fut = p2p.connect_peer(addr, h).then(move |p| { + let connect_peer = p2p.connect_peer(addr, h).map_err(|_| ()); + let timer = Timer::default(); + let timeout = timer.timeout(connect_peer, Duration::from_secs(5)); + + let fut = timeout.then(move |p| { match p { Ok(Some(p)) => { let peer_result = p.send_peer_request(capab); @@ -283,8 +288,7 @@ fn connect_and_req( Err(_) => {} } } - Err(e) => { - error!(LOGGER, "Peer request error: {:?}", e); + Err(_) => { let update_result = peer_store.update_state(addr, p2p::State::Defunct); match update_result { Ok(()) => {} diff --git a/p2p/src/store.rs b/p2p/src/store.rs index 0b3aa0f11..3dee7e421 100644 --- a/p2p/src/store.rs +++ b/p2p/src/store.rs @@ -16,6 +16,7 @@ use std::net::SocketAddr; use num::FromPrimitive; +use rand::{thread_rng, Rng}; use core::ser::{self, Readable, Reader, Writeable, Writer}; use grin_store::{self, option_to_not_found, to_key, Error}; @@ -38,7 +39,7 @@ enum_from_primitive! { } /// Data stored for any given peer we've encountered. -#[derive(Debug, Serialize)] +#[derive(Debug, Clone, Serialize)] pub struct PeerData { /// Network address of the peer. pub addr: SocketAddr, @@ -118,18 +119,12 @@ impl PeerStore { } pub fn find_peers(&self, state: State, cap: Capabilities, count: usize) -> Vec<PeerData> { - let peers_iter = self.db - .iter::<PeerData>(&to_key(PEER_PREFIX, &mut "".to_string().into_bytes())); - let mut peers = Vec::with_capacity(count); - for p in peers_iter { - if p.flags == state && p.capabilities.contains(cap) { - peers.push(p); - } - if peers.len() >= count { - break; - } - } - peers + let mut peers = self.db + .iter::<PeerData>(&to_key(PEER_PREFIX, &mut "".to_string().into_bytes())) + .filter(|p| p.flags == state && p.capabilities.contains(cap)) + .collect::<Vec<_>>(); + thread_rng().shuffle(&mut peers[..]); + peers.iter().take(count).cloned().collect() } /// List all known peers (for the /v1/peers api endpoint)