use std::sync::Arc;
use std::collections::HashMap;
use crate::chain::sync_packet::{PacketInfo, SyncPacket};
use bytes::Bytes;
use client_traits::BlockChainClient;
use private_tx::PrivateStateDB;
use network::client_version::ClientVersion;
use network::{NetworkContext, PeerId, PacketId, Error, SessionInfo, ProtocolId};
use parking_lot::RwLock;
use vapcore_snapshot::SnapshotService;
use common_types::BlockNumber;
pub trait SyncIo {
fn disable_peer(&mut self, peer_id: PeerId);
fn disconnect_peer(&mut self, peer_id: PeerId);
fn respond(&mut self, packet_id: PacketId, data: Vec<u8>) -> Result<(), Error>;
fn send(&mut self, peer_id: PeerId, packet_id: SyncPacket, data: Vec<u8>) -> Result<(), Error>;
fn chain(&self) -> &dyn BlockChainClient;
fn snapshot_service(&self) -> &dyn SnapshotService;
fn private_state(&self) -> Option<Arc<PrivateStateDB>>;
fn peer_version(&self, peer_id: PeerId) -> ClientVersion {
ClientVersion::from(peer_id.to_string())
}
fn peer_enode(&self, peer_id: PeerId) -> Option<String>;
fn peer_session_info(&self, peer_id: PeerId) -> Option<SessionInfo>;
fn vap_protocol_version(&self, peer_id: PeerId) -> u8;
fn protocol_version(&self, protocol: &ProtocolId, peer_id: PeerId) -> u8;
fn is_chain_queue_empty(&self) -> bool {
self.chain().is_queue_empty()
}
fn is_expired(&self) -> bool;
fn chain_overlay(&self) -> &RwLock<HashMap<BlockNumber, Bytes>>;
fn payload_soft_limit(&self) -> usize;
}
pub struct NetSyncIo<'s> {
network: &'s dyn NetworkContext,
chain: &'s dyn BlockChainClient,
snapshot_service: &'s dyn SnapshotService,
chain_overlay: &'s RwLock<HashMap<BlockNumber, Bytes>>,
private_state: Option<Arc<PrivateStateDB>>,
}
impl<'s> NetSyncIo<'s> {
pub fn new(network: &'s dyn NetworkContext,
chain: &'s dyn BlockChainClient,
snapshot_service: &'s dyn SnapshotService,
chain_overlay: &'s RwLock<HashMap<BlockNumber, Bytes>>,
private_state: Option<Arc<PrivateStateDB>>) -> NetSyncIo<'s> {
NetSyncIo {
network,
chain,
snapshot_service,
chain_overlay,
private_state,
}
}
}
impl<'s> SyncIo for NetSyncIo<'s> {
fn disable_peer(&mut self, peer_id: PeerId) {
self.network.disable_peer(peer_id);
}
fn disconnect_peer(&mut self, peer_id: PeerId) {
self.network.disconnect_peer(peer_id);
}
fn respond(&mut self, packet_id: PacketId, data: Vec<u8>) -> Result<(), Error>{
self.network.respond(packet_id, data)
}
fn send(&mut self, peer_id: PeerId, packet_id: SyncPacket, data: Vec<u8>) -> Result<(), Error>{
self.network.send_protocol(packet_id.protocol(), peer_id, packet_id.id(), data)
}
fn chain(&self) -> &dyn BlockChainClient {
self.chain
}
fn snapshot_service(&self) -> &dyn SnapshotService {
self.snapshot_service
}
fn private_state(&self) -> Option<Arc<PrivateStateDB>> {
self.private_state.clone()
}
fn peer_version(&self, peer_id: PeerId) -> ClientVersion {
self.network.peer_client_version(peer_id)
}
fn peer_enode(&self, peer_id: PeerId) -> Option<String> {
self.network.session_info(peer_id).and_then(|info| {
info.id.map(|node_id| {
format!("enode:://{}@{}", node_id, info.remote_address)
})
})
}
fn peer_session_info(&self, peer_id: PeerId) -> Option<SessionInfo> {
self.network.session_info(peer_id)
}
fn vap_protocol_version(&self, peer_id: PeerId) -> u8 {
self.network.protocol_version(self.network.subprotocol_name(), peer_id).unwrap_or(0)
}
fn protocol_version(&self, protocol: &ProtocolId, peer_id: PeerId) -> u8 {
self.network.protocol_version(*protocol, peer_id).unwrap_or(0)
}
fn is_expired(&self) -> bool {
self.network.is_expired()
}
fn chain_overlay(&self) -> &RwLock<HashMap<BlockNumber, Bytes>> {
self.chain_overlay
}
fn payload_soft_limit(&self) -> usize {
self.network.payload_soft_limit()
}
}