diff --git a/grin/src/adapters.rs b/grin/src/adapters.rs index 4c0f0d323..8aa1edf72 100644 --- a/grin/src/adapters.rs +++ b/grin/src/adapters.rs @@ -94,10 +94,11 @@ impl NetAdapter for NetToChainAdapter { Ok(_) => { added_hs.push(bh.hash()); } - Err(chain::Error::Unfit(_)) => { - info!("Received unfit block header {} at {}.", + Err(chain::Error::Unfit(s)) => { + info!("Received unfit block header {} at {}: {}.", bh.hash(), - bh.height); + bh.height, + s); } Err(chain::Error::StoreErr(e)) => { error!("Store error processing block header {}: {:?}", bh.hash(), e); diff --git a/grin/src/seed.rs b/grin/src/seed.rs index cce67f5a8..dbadebe9a 100644 --- a/grin/src/seed.rs +++ b/grin/src/seed.rs @@ -98,16 +98,20 @@ impl Seeder { let mut peers = peer_store.find_peers(p2p::State::Healthy, p2p::UNKNOWN, (2 * PEER_MAX_COUNT) as usize); - debug!("Got {} more peers from db, trying to connect.", peers.len()); - thread_rng().shuffle(&mut peers[..]); - let sz = min(PEER_PREFERRED_COUNT as usize, peers.len()); - for p in &peers[0..sz] { - tx.send(p.addr).unwrap(); + peers.retain(|p| !p2p_server.is_known(p.addr)); + if peers.len() > 0 { + debug!("Got {} more peers from db, trying to connect.", peers.len()); + thread_rng().shuffle(&mut peers[..]); + let sz = min(PEER_PREFERRED_COUNT as usize, peers.len()); + for p in &peers[0..sz] { + tx.send(p.addr).unwrap(); + } } } Ok(()) }) .map_err(|e| e.to_string()); + Box::new(mon_loop) } @@ -223,15 +227,17 @@ fn connect_and_req(capab: p2p::Capabilities, addr: SocketAddr) -> Box> { let fut = p2p.connect_peer(addr, h) - .and_then(move |p| { - if let Some(p) = p { - p.send_peer_request(capab); + .then(move |p| { + match p { + Ok(Some(p)) => { + p.send_peer_request(capab); + } + Err(e) => { + error!("Peer request error: {:?}", e); + } + _ => {} } Ok(()) - }) - .map_err(|e| { - error!("Peer request error {:?}", e); - () }); Box::new(fut) } diff --git a/grin/src/server.rs b/grin/src/server.rs index 76fbb1284..a854b1506 100644 --- a/grin/src/server.rs +++ b/grin/src/server.rs @@ -30,6 +30,7 @@ use api; use chain; use chain::ChainStore; use core; +use core::core::hash::Hashed; use miner; use p2p; use seed; @@ -174,5 +175,14 @@ fn store_head(config: &ServerConfig) } Err(e) => return Err(Error::Store(e)), }; + + let head = chain_store.head()?; + let head_header = chain_store.head_header()?; + info!("Starting server with head {} at {} and header head {} at {}", + head.last_block_h, + head.height, + head_header.hash(), + head_header.height); + Ok((Arc::new(chain_store), head)) } diff --git a/grin/src/sync.rs b/grin/src/sync.rs index 92324a51d..8f133a91a 100644 --- a/grin/src/sync.rs +++ b/grin/src/sync.rs @@ -66,7 +66,7 @@ impl Syncer { if pc > 3 { break; } - if pc > 0 && (Instant::now() - start > Duration::from_secs(15)) { + if pc > 0 && (Instant::now() - start > Duration::from_secs(10)) { break; } thread::sleep(Duration::from_millis(200)); @@ -178,7 +178,10 @@ impl Syncer { let peer = self.p2p.most_work_peer(); let locator = self.get_locator(&tip)?; if let Some(p) = peer { - debug!("Asking peer {} for more block headers.", p.info.addr); + debug!("Asking peer {} for more block headers starting from {} at {}.", + p.info.addr, + tip.last_block_h, + tip.height); p.send_header_request(locator)?; } else { warn!("Could not get most worked peer to request headers."); diff --git a/p2p/src/server.rs b/p2p/src/server.rs index b3c112daa..71d020bbb 100644 --- a/p2p/src/server.rs +++ b/p2p/src/server.rs @@ -145,16 +145,16 @@ impl Server { addr: SocketAddr, h: reactor::Handle) -> Box>, Error = Error>> { - for p in self.peers.read().unwrap().deref() { + if let Some(p) = self.get_peer(addr) { // if we're already connected to the addr, just return the peer - if p.info.addr == addr { - return Box::new(future::ok(Some((*p).clone()))); - } + return Box::new(future::ok(Some(p))); } - // asked to connect to ourselves - if addr.ip() == self.config.host && addr.port() == self.config.port { + if self.is_self(addr) { + // asked to connect to ourselves return Box::new(future::ok(None)); } + + // cloneapalooza let peers = self.peers.clone(); let adapter1 = self.adapter.clone(); let adapter2 = self.adapter.clone(); @@ -186,6 +186,27 @@ impl Server { Box::new(request) } + /// Check if the server already knows this peer (is already connected). In + /// addition we consider to know ourselves. + pub fn is_known(&self, addr: SocketAddr) -> bool { + self.get_peer(addr).is_some() || self.is_self(addr) + } + + /// Whether the provided address is ourselves. + pub fn is_self(&self, addr: SocketAddr) -> bool { + addr.ip() == self.config.host && addr.port() == self.config.port + } + + /// Get a peer we're connected to by address. + pub fn get_peer(&self, addr: SocketAddr) -> Option> { + for p in self.peers.read().unwrap().deref() { + if p.info.addr == addr { + return Some((*p).clone()); + } + } + None + } + /// Have the server iterate over its peer list and prune all peers we have /// lost connection to or have been deemed problematic. The removed peers /// are returned. diff --git a/p2p/src/store.rs b/p2p/src/store.rs index 603843579..59a7b03f0 100644 --- a/p2p/src/store.rs +++ b/p2p/src/store.rs @@ -37,6 +37,7 @@ enum_from_primitive! { } /// Data stored for any given peer we've encountered. +#[derive(Debug)] pub struct PeerData { /// Network address of the peer. pub addr: SocketAddr,