p2p.rs 4.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144
  1. use async_executor::Executor;
  2. use async_std::sync::Mutex;
  3. use log::*;
  4. use std::collections::{HashMap, HashSet};
  5. use std::net::SocketAddr;
  6. use std::sync::Arc;
  7. use crate::error::{Error, Result};
  8. use crate::net::messages::Message;
  9. use crate::net::sessions::{InboundSession, OutboundSession, SeedSession};
  10. use crate::net::{Channel, ChannelPtr, Hosts, HostsPtr, Settings, SettingsPtr};
  11. use crate::system::{Subscriber, SubscriberPtr, Subscription};
  12. /// List of channels that are awaiting connection.
  13. pub type PendingChannels = Mutex<HashSet<SocketAddr>>;
  14. /// List of connected channels.
  15. pub type ConnectedChannels<T> = Mutex<HashMap<SocketAddr, Arc<T>>>;
  16. /// Atomic pointer to p2p interface.
  17. pub type P2pPtr = Arc<P2p>;
  18. /// Top level peer-to-peer networking interface.
  19. pub struct P2p {
  20. pending: PendingChannels,
  21. channels: ConnectedChannels<Channel>,
  22. channel_subscriber: SubscriberPtr<Result<ChannelPtr>>,
  23. // Used both internally and externally
  24. stop_subscriber: SubscriberPtr<Error>,
  25. hosts: HostsPtr,
  26. settings: SettingsPtr,
  27. }
  28. impl P2p {
  29. /// Create a new p2p network.
  30. pub fn new(settings: Settings) -> Arc<Self> {
  31. let settings = Arc::new(settings);
  32. Arc::new(Self {
  33. pending: Mutex::new(HashSet::new()),
  34. channels: Mutex::new(HashMap::new()),
  35. channel_subscriber: Subscriber::new(),
  36. stop_subscriber: Subscriber::new(),
  37. hosts: Hosts::new(),
  38. settings,
  39. })
  40. }
  41. /// Invoke startup and seeding sequence. Call from constructing thread.
  42. pub async fn start(self: Arc<Self>, executor: Arc<Executor<'_>>) -> Result<()> {
  43. debug!(target: "net", "P2p::start() [BEGIN]");
  44. // Start manual connections
  45. // Start seed session
  46. let seed = SeedSession::new(Arc::downgrade(&self));
  47. // This will block until all seed queries have finished
  48. seed.start(executor.clone()).await?;
  49. debug!(target: "net", "P2p::start() [END]");
  50. Ok(())
  51. }
  52. /// Synchronize the blockchain and then begin long running sessions,
  53. /// call after start() is invoked.
  54. pub async fn run(self: Arc<Self>, executor: Arc<Executor<'_>>) -> Result<()> {
  55. debug!(target: "net", "P2p::run() [BEGIN]");
  56. let inbound = InboundSession::new(Arc::downgrade(&self));
  57. inbound.clone().start(executor.clone())?;
  58. let outbound = OutboundSession::new(Arc::downgrade(&self));
  59. outbound.clone().start(executor.clone()).await?;
  60. let stop_sub = self.subscribe_stop().await;
  61. // Wait for stop signal
  62. stop_sub.receive().await;
  63. // Stop the sessions
  64. inbound.stop().await;
  65. outbound.stop().await;
  66. debug!(target: "net", "P2p::run() [BEGIN]");
  67. Ok(())
  68. }
  69. /// Broadcasts a message across all channels.
  70. pub async fn broadcast<M: Message + Clone>(&self, message: M) -> Result<()> {
  71. for channel in self.channels.lock().await.values() {
  72. channel.send(message.clone()).await?;
  73. }
  74. Ok(())
  75. }
  76. /// Add channel address to the list of connected channels.
  77. pub async fn store(&self, channel: ChannelPtr) {
  78. self.channels
  79. .lock()
  80. .await
  81. .insert(channel.address(), channel.clone());
  82. self.channel_subscriber.notify(Ok(channel)).await;
  83. }
  84. /// Remove a channel from the list of connected channels.
  85. pub async fn remove(&self, channel: ChannelPtr) {
  86. self.channels.lock().await.remove(&channel.address());
  87. }
  88. /// Check whether a channel is stored in the list of connected channels.
  89. pub async fn exists(&self, addr: &SocketAddr) -> bool {
  90. self.channels.lock().await.contains_key(addr)
  91. }
  92. /// Add a channel to the list of pending channels.
  93. pub async fn add_pending(&self, addr: SocketAddr) -> bool {
  94. self.pending.lock().await.insert(addr)
  95. }
  96. /// Remove a channel from the list of pending channels.
  97. pub async fn remove_pending(&self, addr: &SocketAddr) {
  98. self.pending.lock().await.remove(addr);
  99. }
  100. /// Return the number of connected channels.
  101. pub async fn connections_count(&self) -> usize {
  102. self.channels.lock().await.len()
  103. }
  104. /// Return an atomic pointer to the default network settings.
  105. pub fn settings(&self) -> SettingsPtr {
  106. self.settings.clone()
  107. }
  108. /// Return an atomic pointer to the list of hosts.
  109. pub fn hosts(&self) -> HostsPtr {
  110. self.hosts.clone()
  111. }
  112. /// Subscribe to a channel.
  113. pub async fn subscribe_channel(&self) -> Subscription<Result<ChannelPtr>> {
  114. self.channel_subscriber.clone().subscribe().await
  115. }
  116. /// Subscribe to a stop signal.
  117. pub async fn subscribe_stop(&self) -> Subscription<Error> {
  118. self.stop_subscriber.clone().subscribe().await
  119. }
  120. }