p2p.rs 4.9 KB

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