p2p.rs 7.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243
  1. use async_std::sync::Mutex;
  2. use std::{
  3. collections::{HashMap, HashSet},
  4. fmt,
  5. net::SocketAddr,
  6. sync::Arc,
  7. };
  8. use async_executor::Executor;
  9. use log::debug;
  10. use serde_json::json;
  11. use crate::{
  12. error::{Error, Result},
  13. net::{
  14. message::Message,
  15. protocol::{register_default_protocols, ProtocolRegistry},
  16. session::{InboundSession, ManualSession, OutboundSession, SeedSession, Session},
  17. Channel, ChannelPtr, Hosts, HostsPtr, Settings, SettingsPtr,
  18. },
  19. system::{Subscriber, SubscriberPtr, Subscription},
  20. };
  21. /// List of channels that are awaiting connection.
  22. pub type PendingChannels = Mutex<HashSet<SocketAddr>>;
  23. /// List of connected channels.
  24. pub type ConnectedChannels<T> = Mutex<HashMap<SocketAddr, Arc<T>>>;
  25. /// Atomic pointer to p2p interface.
  26. pub type P2pPtr = Arc<P2p>;
  27. enum P2pState {
  28. // The p2p object has been created but not yet started.
  29. Open,
  30. // We are performing the initial seed session
  31. Start,
  32. // Seed session finished, but not yet running
  33. Started,
  34. // p2p is running and the network is active.
  35. Run,
  36. }
  37. impl fmt::Display for P2pState {
  38. fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
  39. write!(
  40. f,
  41. "{}",
  42. match self {
  43. Self::Open => "open",
  44. Self::Start => "start",
  45. Self::Started => "started",
  46. Self::Run => "run",
  47. }
  48. )
  49. }
  50. }
  51. /// Top level peer-to-peer networking interface.
  52. pub struct P2p {
  53. pending: PendingChannels,
  54. channels: ConnectedChannels<Channel>,
  55. channel_subscriber: SubscriberPtr<Result<ChannelPtr>>,
  56. // Used both internally and externally
  57. stop_subscriber: SubscriberPtr<Error>,
  58. hosts: HostsPtr,
  59. protocol_registry: ProtocolRegistry,
  60. // We keep a reference to the sessions used for get info
  61. session_manual: Mutex<Option<Arc<ManualSession>>>,
  62. session_inbound: Mutex<Option<Arc<InboundSession>>>,
  63. session_outbound: Mutex<Option<Arc<OutboundSession>>>,
  64. state: Mutex<P2pState>,
  65. settings: SettingsPtr,
  66. }
  67. impl P2p {
  68. /// Create a new p2p network.
  69. pub async fn new(settings: Settings) -> Arc<Self> {
  70. let settings = Arc::new(settings);
  71. let self_ = Arc::new(Self {
  72. pending: Mutex::new(HashSet::new()),
  73. channels: Mutex::new(HashMap::new()),
  74. channel_subscriber: Subscriber::new(),
  75. stop_subscriber: Subscriber::new(),
  76. hosts: Hosts::new(),
  77. protocol_registry: ProtocolRegistry::new(),
  78. session_manual: Mutex::new(None),
  79. session_inbound: Mutex::new(None),
  80. session_outbound: Mutex::new(None),
  81. state: Mutex::new(P2pState::Open),
  82. settings,
  83. });
  84. let parent = Arc::downgrade(&self_);
  85. *self_.session_manual.lock().await = Some(ManualSession::new(parent.clone()));
  86. *self_.session_inbound.lock().await = Some(InboundSession::new(parent.clone()));
  87. *self_.session_outbound.lock().await = Some(OutboundSession::new(parent));
  88. register_default_protocols(self_.clone()).await;
  89. self_
  90. }
  91. pub async fn get_info(&self) -> serde_json::Value {
  92. let external_addr = self
  93. .settings
  94. .external_addr
  95. .map(|addr| serde_json::Value::from(addr.to_string()))
  96. .unwrap_or(serde_json::Value::Null);
  97. json!({
  98. "external_addr": external_addr,
  99. "session_manual": self.session_manual().await.get_info().await,
  100. "session_inbound": self.session_inbound().await.get_info().await,
  101. "session_outbound": self.session_outbound().await.get_info().await,
  102. "state": self.state.lock().await.to_string(),
  103. })
  104. }
  105. /// Invoke startup and seeding sequence. Call from constructing thread.
  106. pub async fn start(self: Arc<Self>, executor: Arc<Executor<'_>>) -> Result<()> {
  107. debug!(target: "net", "P2p::start() [BEGIN]");
  108. *self.state.lock().await = P2pState::Start;
  109. // Start seed session
  110. let seed = SeedSession::new(Arc::downgrade(&self));
  111. // This will block until all seed queries have finished
  112. seed.start(executor.clone()).await?;
  113. *self.state.lock().await = P2pState::Started;
  114. debug!(target: "net", "P2p::start() [END]");
  115. Ok(())
  116. }
  117. pub async fn session_manual(&self) -> Arc<ManualSession> {
  118. self.session_manual.lock().await.as_ref().unwrap().clone()
  119. }
  120. pub async fn session_inbound(&self) -> Arc<InboundSession> {
  121. self.session_inbound.lock().await.as_ref().unwrap().clone()
  122. }
  123. pub async fn session_outbound(&self) -> Arc<OutboundSession> {
  124. self.session_outbound.lock().await.as_ref().unwrap().clone()
  125. }
  126. /// Synchronize the blockchain and then begin long running sessions,
  127. /// call after start() is invoked.
  128. pub async fn run(self: Arc<Self>, executor: Arc<Executor<'_>>) -> Result<()> {
  129. debug!(target: "net", "P2p::run() [BEGIN]");
  130. *self.state.lock().await = P2pState::Run;
  131. let manual = self.session_manual().await;
  132. for peer in &self.settings.peers {
  133. manual.clone().connect(peer, executor.clone()).await;
  134. }
  135. let inbound = self.session_inbound().await;
  136. inbound.clone().start(executor.clone())?;
  137. let outbound = self.session_outbound().await;
  138. outbound.clone().start(executor.clone()).await?;
  139. let stop_sub = self.subscribe_stop().await;
  140. // Wait for stop signal
  141. stop_sub.receive().await;
  142. // Stop the sessions
  143. manual.stop().await;
  144. inbound.stop().await;
  145. outbound.stop().await;
  146. debug!(target: "net", "P2p::run() [END]");
  147. Ok(())
  148. }
  149. /// Broadcasts a message across all channels.
  150. pub async fn broadcast<M: Message + Clone>(&self, message: M) -> Result<()> {
  151. for channel in self.channels.lock().await.values() {
  152. channel.send(message.clone()).await?;
  153. }
  154. Ok(())
  155. }
  156. /// Add channel address to the list of connected channels.
  157. pub async fn store(&self, channel: ChannelPtr) {
  158. self.channels.lock().await.insert(channel.address(), channel.clone());
  159. self.channel_subscriber.notify(Ok(channel)).await;
  160. }
  161. /// Remove a channel from the list of connected channels.
  162. pub async fn remove(&self, channel: ChannelPtr) {
  163. self.channels.lock().await.remove(&channel.address());
  164. }
  165. /// Check whether a channel is stored in the list of connected channels.
  166. pub async fn exists(&self, addr: &SocketAddr) -> bool {
  167. self.channels.lock().await.contains_key(addr)
  168. }
  169. /// Add a channel to the list of pending channels.
  170. pub async fn add_pending(&self, addr: SocketAddr) -> bool {
  171. self.pending.lock().await.insert(addr)
  172. }
  173. /// Remove a channel from the list of pending channels.
  174. pub async fn remove_pending(&self, addr: &SocketAddr) {
  175. self.pending.lock().await.remove(addr);
  176. }
  177. /// Return the number of connected channels.
  178. pub async fn connections_count(&self) -> usize {
  179. self.channels.lock().await.len()
  180. }
  181. /// Return an atomic pointer to the default network settings.
  182. pub fn settings(&self) -> SettingsPtr {
  183. self.settings.clone()
  184. }
  185. /// Return an atomic pointer to the list of hosts.
  186. pub fn hosts(&self) -> HostsPtr {
  187. self.hosts.clone()
  188. }
  189. pub fn protocol_registry(&self) -> &ProtocolRegistry {
  190. &self.protocol_registry
  191. }
  192. /// Subscribe to a channel.
  193. pub async fn subscribe_channel(&self) -> Subscription<Result<ChannelPtr>> {
  194. self.channel_subscriber.clone().subscribe().await
  195. }
  196. /// Subscribe to a stop signal.
  197. pub async fn subscribe_stop(&self) -> Subscription<Error> {
  198. self.stop_subscriber.clone().subscribe().await
  199. }
  200. }