From ccdf5d587372f23d2ad9a4d6f05d5b01a8a67c3a Mon Sep 17 00:00:00 2001 From: Robert Habermeier Date: Mon, 19 Dec 2016 12:28:42 +0100 Subject: [PATCH] increase tick timer and limit peers to one req --- ethcore/light/src/net/error.rs | 8 ++++++-- ethcore/light/src/net/mod.rs | 35 +++++++++++++++++++++++++--------- sync/src/light_sync/mod.rs | 2 -- 3 files changed, 32 insertions(+), 13 deletions(-) diff --git a/ethcore/light/src/net/error.rs b/ethcore/light/src/net/error.rs index 42d038679..6a7746543 100644 --- a/ethcore/light/src/net/error.rs +++ b/ethcore/light/src/net/error.rs @@ -62,6 +62,8 @@ pub enum Error { UnsupportedProtocolVersion(u8), /// Bad protocol version. BadProtocolVersion, + /// Peer is overburdened. + Overburdened, } impl Error { @@ -79,6 +81,7 @@ impl Error { Error::NotServer => Punishment::Disable, Error::UnsupportedProtocolVersion(_) => Punishment::Disable, Error::BadProtocolVersion => Punishment::Disable, + Error::Overburdened => Punishment::None, } } } @@ -107,8 +110,9 @@ impl fmt::Display for Error { Error::UnknownPeer => write!(f, "Unknown peer"), Error::UnsolicitedResponse => write!(f, "Peer provided unsolicited data"), Error::NotServer => write!(f, "Peer not a server."), - Error::UnsupportedProtocolVersion(pv) => write!(f, "Unsupported protocol version: {}", pv), + Error::UnsupportedProtocolVersion(pv) => write!(f, "Unsupported protocol version: {}", pv), Error::BadProtocolVersion => write!(f, "Bad protocol version in handshake"), + Error::Overburdened => write!(f, "Peer overburdened"), } } -} \ No newline at end of file +} diff --git a/ethcore/light/src/net/mod.rs b/ethcore/light/src/net/mod.rs index 464c71fbe..766cd9c4b 100644 --- a/ethcore/light/src/net/mod.rs +++ b/ethcore/light/src/net/mod.rs @@ -55,6 +55,9 @@ pub use self::status::{Status, Capabilities, Announcement}; const TIMEOUT: TimerToken = 0; const TIMEOUT_INTERVAL_MS: u64 = 1000; +const TICK_TIMEOUT: TimerToken = 1; +const TICK_TIMEOUT_INTERVAL_MS: u64 = 5000; + // minimum interval between updates. const UPDATE_INTERVAL_MS: i64 = 5000; @@ -132,8 +135,9 @@ struct Peer { status: Status, capabilities: Capabilities, remote_flow: Option<(Buffer, FlowParams)>, - sent_head: H256, // last head we've given them. + sent_head: H256, // last chain head we've given them. last_update: SteadyTime, + idle: bool, // make into a current percentage of max buffer being requested? } impl Peer { @@ -263,10 +267,16 @@ impl LightProtocol { pub fn max_requests(&self, peer: PeerId, kind: request::Kind) -> usize { self.peers.read().get(&peer).and_then(|peer| { let mut peer = peer.lock(); - match peer.remote_flow.as_mut() { - Some(&mut (ref mut buf, ref flow)) => { + let idle = peer.idle; + match peer.remote_flow { + Some((ref mut buf, ref flow)) => { flow.recharge(buf); - Some(flow.max_amount(&*buf, kind)) + + if !idle { + Some(0) + } else { + Some(flow.max_amount(&*buf, kind)) + } } None => None, } @@ -284,6 +294,8 @@ impl LightProtocol { let peer = try!(peers.get(peer_id).ok_or_else(|| Error::UnknownPeer)); let mut peer = peer.lock(); + if !peer.idle { return Err(Error::Overburdened) } + match peer.remote_flow { Some((ref mut buf, ref flow)) => { flow.recharge(buf); @@ -309,6 +321,7 @@ impl LightProtocol { io.send(*peer_id, packet_id, packet_data); + peer.idle = false; self.pending_requests.write().insert(req_id, Requested { request: request, timestamp: SteadyTime::now(), @@ -412,6 +425,8 @@ impl LightProtocol { match peers.get(peer) { Some(peer_info) => { let mut peer_info = peer_info.lock(); + peer_info.idle = true; + match peer_info.remote_flow.as_mut() { Some(&mut (ref mut buf, ref mut flow)) => { let actual_buffer = ::std::cmp::min(cur_buffer, *flow.limit()); @@ -620,6 +635,7 @@ impl LightProtocol { remote_flow: remote_flow, sent_head: pending.sent_head, last_update: pending.last_update, + idle: true, })); for handler in &self.handlers { @@ -1124,7 +1140,10 @@ fn punish(peer: PeerId, io: &IoContext, e: Error) { impl NetworkProtocolHandler for LightProtocol { fn initialize(&self, io: &NetworkContext) { - io.register_timer(TIMEOUT, TIMEOUT_INTERVAL_MS).expect("Error registering sync timer."); + io.register_timer(TIMEOUT, TIMEOUT_INTERVAL_MS) + .expect("Error registering sync timer."); + io.register_timer(TICK_TIMEOUT, TICK_TIMEOUT_INTERVAL_MS) + .expect("Error registering sync timer."); } fn read(&self, io: &NetworkContext, peer: &PeerId, packet_id: u8, data: &[u8]) { @@ -1141,10 +1160,8 @@ impl NetworkProtocolHandler for LightProtocol { fn timeout(&self, io: &NetworkContext, timer: TimerToken) { match timer { - TIMEOUT => { - self.timeout_check(io); - self.tick_handlers(io); - }, + TIMEOUT => self.timeout_check(io), + TICK_TIMEOUT => self.tick_handlers(io), _ => warn!(target: "les", "received timeout on unknown token {}", timer), } } diff --git a/sync/src/light_sync/mod.rs b/sync/src/light_sync/mod.rs index 97ddfad46..6f5a53c5f 100644 --- a/sync/src/light_sync/mod.rs +++ b/sync/src/light_sync/mod.rs @@ -417,8 +417,6 @@ impl LightSync { rng.shuffle(&mut peer_ids); for peer in &peer_ids { - let peer_info = peers.get(peer).expect("key known to be present; qed"); - let mut peer_info = peer_info.lock(); if ctx.max_requests(*peer, request::Kind::Headers) >= req.max { match ctx.request_from(*peer, request::Request::Headers(req.clone())) { Ok(id) => {