Use round robin for peer selection in body sync

We select a peer to ask a block randomly. Peer's send channel has
capacity 10. If we need too many blocks we limit number of blocks to asks as a number of peers
* 10, which means that there is some probability (pretty high) that we
will overflow send buffer capacity.
This fix freezes a peer list (which gives also some performance boost)
and create a cycle iteraror to equally distribute requests among the
peers.
There is a risk that a peer may be disconnected while we are sending a
request to the chanel, but stricltly speaking it was possible in the old
code too, perhaps with a lower probability.
Fixes #1748
This commit is contained in:
hashmap 2018-10-15 23:08:12 +02:00
parent 5bcc4508fd
commit 466ce986a6
No known key found for this signature in database
GPG key ID: 5EA3C2D2455ED9C8

View file

@ -126,9 +126,14 @@ impl BodySync {
// if we have 5 peers to sync from then ask for 50 blocks total (peer_count *
// 10) max will be 80 if all 8 peers are advertising more work
// also if the chain is already saturated with orphans, throttle
let peer_count = self.peers.more_work_peers().len();
let peers = if oldest_height < header_head.height.saturating_sub(horizon) {
self.peers.more_work_archival_peers()
} else {
self.peers.more_work_peers()
};
let block_count = cmp::min(
cmp::min(100, peer_count * 10),
cmp::min(100, peers.len() * 10),
chain::MAX_ORPHAN_SIZE.saturating_sub(self.chain.orphans_len()) + 1,
);
@ -148,17 +153,13 @@ impl BodySync {
body_head.height,
header_head.height,
hashes_to_get,
peer_count,
peers.len(),
);
let mut peers_iter = peers.iter().cycle();
for hash in hashes_to_get.clone() {
// only archival peers can be expected to have blocks older than horizon
let peer = if oldest_height < header_head.height.saturating_sub(horizon) {
self.peers.more_work_archival_peer()
} else {
self.peers.more_work_peer()
};
if let Some(peer) = peer {
if let Some(peer) = peers_iter.next() {
if let Err(e) = peer.send_block_request(*hash) {
debug!(LOGGER, "Skipped request to {}: {:?}", peer.info.addr, e);
} else {