use async_executor::Executor; use async_std::sync::Mutex; use std::collections::HashMap; use std::net::SocketAddr; use std::sync::Arc; use crate::net::error::NetResult; use crate::net::sessions::{InboundSession, SeedSession}; use crate::net::{Channel, ChannelPtr, Connector, Hosts, HostsPtr, Settings, SettingsPtr}; pub type Pending = Mutex>>; pub type P2pPtr = Arc; pub struct P2p { pending_connects: Pending, pending_channels: Pending, hosts: HostsPtr, settings: SettingsPtr, } impl P2p { pub fn new(settings: Settings) -> Arc { let settings = Arc::new(settings); Arc::new(Self { pending_connects: Mutex::new(HashMap::new()), pending_channels: Mutex::new(HashMap::new()), hosts: Hosts::new(settings.clone()), settings, }) } /// Invoke startup and seeding sequence. Call from constructing thread. pub async fn start(self: Arc, executor: Arc>) -> NetResult<()> { // Start manual connections // Start seed session let seed = SeedSession::new(Arc::downgrade(&self)); seed.start(executor.clone()).await?; Ok(()) } /// Synchronize the blockchain and then begin long running sessions, /// call after start() is invoked. pub async fn run(self: Arc, executor: Arc>) -> NetResult<()> { let inbound = InboundSession::new(Arc::downgrade(&self)); inbound.start(executor.clone())?; Ok(()) } pub async fn store(self: Arc, channel: ChannelPtr) { self.pending_channels .lock() .await .insert(channel.address(), channel); } pub async fn remove(self: Arc, channel: ChannelPtr) { self.pending_channels .lock() .await .remove(&channel.address()); } pub fn settings(&self) -> SettingsPtr { self.settings.clone() } pub fn hosts(&self) -> HostsPtr { self.hosts.clone() } }