From 72f7391551f1615d2f721f3f144ff4cc7cbbaa97 Mon Sep 17 00:00:00 2001 From: Robert Habermeier Date: Thu, 15 Dec 2016 19:25:52 +0100 Subject: [PATCH] add BasicContext trait for handler ticking --- ethcore/light/src/net/context.rs | 73 ++++++++++++++++++++++++-------- ethcore/light/src/net/mod.rs | 20 +++++++-- 2 files changed, 73 insertions(+), 20 deletions(-) diff --git a/ethcore/light/src/net/context.rs b/ethcore/light/src/net/context.rs index 7f55dd229..74d8ad811 100644 --- a/ethcore/light/src/net/context.rs +++ b/ethcore/light/src/net/context.rs @@ -77,12 +77,8 @@ impl<'a> IoContext for NetworkContext<'a> { } } -/// Context for a protocol event. -pub trait EventContext { - /// Get the peer relevant to the event e.g. message sender, - /// disconnected/connected peer. - fn peer(&self) -> PeerId; - +/// Basic context for a the protocol. +pub trait BasicContext { /// Returns the relevant's peer persistent Id (aka NodeId). fn persistent_peer_id(&self, peer: PeerId) -> Option; @@ -104,22 +100,22 @@ pub trait EventContext { fn disable_peer(&self, peer: PeerId); } -/// Concrete implementation of `EventContext` over the light protocol struct and -/// an io context. -pub struct Ctx<'a> { - /// Io context to enable immediate response to events. +/// Context for a protocol event which has a peer ID attached. +pub trait EventContext: BasicContext { + /// Get the peer relevant to the event e.g. message sender, + /// disconnected/connected peer. + fn peer(&self) -> PeerId; +} + +/// Basic context. +pub struct TickCtx<'a> { + /// Io context to enable dispatch. pub io: &'a IoContext, /// Protocol implementation. pub proto: &'a LightProtocol, - /// Relevant peer for event. - pub peer: PeerId, } -impl<'a> EventContext for Ctx<'a> { - fn peer(&self) -> PeerId { - self.peer - } - +impl<'a> BasicContext for TickCtx<'a> { fn persistent_peer_id(&self, id: PeerId) -> Option { self.io.persistent_peer_id(id) } @@ -144,3 +140,46 @@ impl<'a> EventContext for Ctx<'a> { self.io.disable_peer(peer); } } + +/// Concrete implementation of `EventContext` over the light protocol struct and +/// an io context. +pub struct Ctx<'a> { + /// Io context to enable immediate response to events. + pub io: &'a IoContext, + /// Protocol implementation. + pub proto: &'a LightProtocol, + /// Relevant peer for event. + pub peer: PeerId, +} + +impl<'a> BasicContext for Ctx<'a> { + fn persistent_peer_id(&self, id: PeerId) -> Option { + self.io.persistent_peer_id(id) + } + + fn request_from(&self, peer: PeerId, request: Request) -> Result { + self.proto.request_from(self.io, &peer, request) + } + + fn make_announcement(&self, announcement: Announcement) { + self.proto.make_announcement(self.io, announcement); + } + + fn max_requests(&self, peer: PeerId, kind: request::Kind) -> usize { + self.proto.max_requests(peer, kind) + } + + fn disconnect_peer(&self, peer: PeerId) { + self.io.disconnect_peer(peer); + } + + fn disable_peer(&self, peer: PeerId) { + self.io.disable_peer(peer); + } +} + +impl<'a> EventContext for Ctx<'a> { + fn peer(&self) -> PeerId { + self.peer + } +} diff --git a/ethcore/light/src/net/mod.rs b/ethcore/light/src/net/mod.rs index 6da964f99..08bd3347d 100644 --- a/ethcore/light/src/net/mod.rs +++ b/ethcore/light/src/net/mod.rs @@ -37,7 +37,7 @@ use provider::Provider; use request::{self, HashOrNumber, Request}; use self::buffer_flow::{Buffer, FlowParams}; -use self::context::Ctx; +use self::context::{Ctx, TickCtx}; use self::error::Punishment; mod buffer_flow; @@ -49,7 +49,7 @@ mod status; mod tests; pub use self::error::Error; -pub use self::context::{EventContext, IoContext}; +pub use self::context::{BasicContext, EventContext, IoContext}; pub use self::status::{Status, Capabilities, Announcement}; const TIMEOUT: TimerToken = 0; @@ -189,6 +189,8 @@ pub trait Handler: Send + Sync { /// Called when a peer responds with header proofs. Each proof is a block header coupled /// with a series of trie nodes is ascending order by distance from the root. fn on_header_proofs(&self, _ctx: &EventContext, _req_id: ReqId, _proofs: &[(Bytes, Vec)]) { } + /// Called to "tick" the handler periodically. + fn tick(&self, _ctx: &BasicContext) { } /// Called on abort. This signals to handlers that they should clean up /// and ignore peers. // TODO: coreresponding `on_activate`? @@ -509,6 +511,15 @@ impl LightProtocol { } } } + + fn tick_handlers(&self, io: &IoContext) { + for handler in &self.handlers { + handler.tick(&TickCtx { + io: io, + proto: self, + }) + } + } } impl LightProtocol { @@ -1128,7 +1139,10 @@ impl NetworkProtocolHandler for LightProtocol { fn timeout(&self, io: &NetworkContext, timer: TimerToken) { match timer { - TIMEOUT => self.timeout_check(io), + TIMEOUT => { + self.timeout_check(io); + self.tick_handlers(io); + }, _ => warn!(target: "les", "received timeout on unknown token {}", timer), } }