notify syncer on every block received (including orphans) (#379)

prefer random peers with more difficulty than us
do not keep asking for headers over and over
This commit is contained in:
AntiochP 2017-11-23 00:16:36 -05:00 committed by GitHub
parent c6b94dd2c4
commit 25969424ff
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 26 additions and 16 deletions

View file

@ -81,11 +81,10 @@ impl NetAdapter for NetToChainAdapter {
}
if self.syncing() {
match res {
Ok(_) => self.syncer.borrow().block_received(bhash),
Err(chain::Error::Unfit(_)) => self.syncer.borrow().block_received(bhash),
Err(_) => {}
}
// always notify the syncer we received a block
// otherwise we jam up the 8 download slots with orphans
debug!(LOGGER, "adapter: notifying syncer: received block {:?}", bhash);
self.syncer.borrow().block_received(bhash);
}
}

View file

@ -265,15 +265,13 @@ impl Syncer {
/// We added a header, add it to the full block download list
pub fn headers_received(&self, bhs: Vec<Hash>) {
let mut blocks_to_download = self.blocks_to_download.lock().unwrap();
let hs_len = bhs.len();
for h in bhs {
// enlist for full block download
blocks_to_download.insert(0, h);
}
// ask for more headers if we got as many as required
if hs_len == (p2p::MAX_BLOCK_HEADERS as usize) {
self.request_headers().unwrap();
}
// we may still have more headers to retrieve but the main loop
// will take care of this for us
}
/// Builds a vector of block hashes that should help the remote peer sending
@ -298,13 +296,14 @@ impl Syncer {
/// Pick a random peer and ask for a block by hash
fn request_block(&self, h: Hash) {
let peer = self.p2p.random_peer().expect("No connected peer.");
if let Some(peer) = self.p2p.random_peer() {
let peer = peer.read().unwrap();
if let Err(e) = peer.send_block_request(h) {
debug!(LOGGER, "Sync: Error requesting block: {:?}", e);
}
}
}
}
// current height back to 0 decreasing in powers of 2
fn get_locator_heights(height: u64) -> Vec<u64> {

View file

@ -287,9 +287,21 @@ impl Server {
Some(peer.clone())
}
/// Returns a random peer we're connected to.
/// Returns a random connected peer.
/// Only considers peers with at least our total_difficulty (ignores out of sync peers).
pub fn random_peer(&self) -> Option<Arc<RwLock<Peer>>> {
let peers = self.all_peers();
let difficulty = self.adapter.total_difficulty();
let peers = self
.all_peers()
.iter()
.filter(|x| {
let peer = x.read().unwrap();
peer.is_connected() && peer.info.total_difficulty >= difficulty
})
.cloned()
.collect::<Vec<_>>();
if peers.len() == 0 {
return None;
}