use network::{NetworkContext, PeerId, NodeId};
use super::{Announcement, LightProtocol, ReqId};
use super::error::Error;
use request::NetworkRequests as Requests;
pub trait IoContext {
fn send(&self, peer: PeerId, packet_id: u8, packet_body: Vec<u8>);
fn respond(&self, packet_id: u8, packet_body: Vec<u8>);
fn disconnect_peer(&self, peer: PeerId);
fn disable_peer(&self, peer: PeerId);
fn protocol_version(&self, peer: PeerId) -> Option<u8>;
fn persistent_peer_id(&self, peer: PeerId) -> Option<NodeId>;
fn is_reserved_peer(&self, peer: PeerId) -> bool;
}
impl<T> IoContext for T where T: ?Sized + NetworkContext {
fn send(&self, peer: PeerId, packet_id: u8, packet_body: Vec<u8>) {
if let Err(e) = self.send(peer, packet_id, packet_body) {
debug!(target: "pip", "Error sending packet to peer {}: {}", peer, e);
}
}
fn respond(&self, packet_id: u8, packet_body: Vec<u8>) {
if let Err(e) = self.respond(packet_id, packet_body) {
debug!(target: "pip", "Error responding to peer message: {}", e);
}
}
fn disconnect_peer(&self, peer: PeerId) {
trace!(target: "pip", "Initiating disconnect of peer {}", peer);
NetworkContext::disconnect_peer(self, peer);
}
fn disable_peer(&self, peer: PeerId) {
trace!(target: "pip", "Initiating disable of peer {}", peer);
NetworkContext::disable_peer(self, peer);
}
fn protocol_version(&self, peer: PeerId) -> Option<u8> {
self.protocol_version(self.subprotocol_name(), peer)
}
fn persistent_peer_id(&self, peer: PeerId) -> Option<NodeId> {
self.session_info(peer).and_then(|info| info.id)
}
fn is_reserved_peer(&self, peer: PeerId) -> bool {
NetworkContext::is_reserved_peer(self, peer)
}
}
pub trait BasicContext {
fn persistent_peer_id(&self, peer: PeerId) -> Option<NodeId>;
fn request_from(&self, peer: PeerId, request: Requests) -> Result<ReqId, Error>;
fn make_announcement(&self, announcement: Announcement);
fn disconnect_peer(&self, peer: PeerId);
fn disable_peer(&self, peer: PeerId);
}
pub trait EventContext: BasicContext {
fn peer(&self) -> PeerId;
fn as_basic(&self) -> &dyn BasicContext;
}
pub struct TickCtx<'a> {
pub io: &'a dyn IoContext,
pub proto: &'a LightProtocol,
}
impl<'a> BasicContext for TickCtx<'a> {
fn persistent_peer_id(&self, id: PeerId) -> Option<NodeId> {
self.io.persistent_peer_id(id)
}
fn request_from(&self, peer: PeerId, requests: Requests) -> Result<ReqId, Error> {
self.proto.request_from(self.io, peer, requests)
}
fn make_announcement(&self, announcement: Announcement) {
self.proto.make_announcement(self.io, announcement);
}
fn disconnect_peer(&self, peer: PeerId) {
self.io.disconnect_peer(peer);
}
fn disable_peer(&self, peer: PeerId) {
self.io.disable_peer(peer);
}
}
pub struct Ctx<'a> {
pub io: &'a dyn IoContext,
pub proto: &'a LightProtocol,
pub peer: PeerId,
}
impl<'a> BasicContext for Ctx<'a> {
fn persistent_peer_id(&self, id: PeerId) -> Option<NodeId> {
self.io.persistent_peer_id(id)
}
fn request_from(&self, peer: PeerId, requests: Requests) -> Result<ReqId, Error> {
self.proto.request_from(self.io, peer, requests)
}
fn make_announcement(&self, announcement: Announcement) {
self.proto.make_announcement(self.io, announcement);
}
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
}
fn as_basic(&self) -> &dyn BasicContext {
&*self
}
}