mod.rs 5.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144
  1. use std::sync::Arc;
  2. use async_trait::async_trait;
  3. use log::debug;
  4. use smol::Executor;
  5. use crate::Result;
  6. use super::{p2p::P2pPtr, protocol::ProtocolVersion, ChannelPtr};
  7. /// Seed connections session. Manages the creation of seed sessions. Used on
  8. /// first time connecting to the network. The seed node stores a list of other
  9. /// nodes in the network.
  10. pub mod seed_session;
  11. pub mod manual_session;
  12. /// Inbound connections session. Manages the creation of inbound sessions. Used
  13. /// to create an inbound session and start and stop the session.
  14. ///
  15. /// Class consists of 3 pointers: a weak pointer to the peer-to-peer class, an
  16. /// acceptor pointer, and a stoppable task pointer. Using a weak pointer to P2P
  17. /// allows us to avoid circular dependencies.
  18. pub mod inbound_session;
  19. /// Outbound connections session. Manages the creation of outbound sessions.
  20. /// Used to create an outbound session and stop and start the session.
  21. ///
  22. /// Class consists of a weak pointer to the peer-to-peer interface and a vector
  23. /// of outbound connection slots. Using a weak pointer to p2p allows us to avoid
  24. /// circular dependencies. The vector of slots is wrapped in a mutex lock. This
  25. /// is switched on everytime we instantiate a connection slot and insures that
  26. /// no other part of the program uses the slots at the same time.
  27. pub mod outbound_session;
  28. // bitwise selectors for the protocol_registry
  29. pub type SessionBitflag = u32;
  30. pub const SESSION_INBOUND: SessionBitflag = 0b0001;
  31. pub const SESSION_OUTBOUND: SessionBitflag = 0b0010;
  32. pub const SESSION_MANUAL: SessionBitflag = 0b0100;
  33. pub const SESSION_SEED: SessionBitflag = 0b1000;
  34. pub const SESSION_ALL: SessionBitflag = 0b1111;
  35. pub use inbound_session::InboundSession;
  36. pub use manual_session::ManualSession;
  37. pub use outbound_session::OutboundSession;
  38. pub use seed_session::SeedSession;
  39. /// Removes channel from the list of connected channels when a stop signal is
  40. /// received.
  41. async fn remove_sub_on_stop(p2p: P2pPtr, channel: ChannelPtr) {
  42. debug!(target: "net", "remove_sub_on_stop() [START]");
  43. // Subscribe to stop events
  44. let stop_sub = channel.clone().subscribe_stop().await;
  45. // Wait for a stop event
  46. let _ = stop_sub.receive().await;
  47. debug!(target: "net",
  48. "remove_sub_on_stop(): received stop event. Removing channel {}",
  49. channel.address()
  50. );
  51. // Remove channel from p2p
  52. p2p.remove(channel).await;
  53. debug!(target: "net", "remove_sub_on_stop() [END]");
  54. }
  55. #[async_trait]
  56. /// Session trait.
  57. /// Defines methods that are used across sessions. Implements registering the
  58. /// channel and initializing the channel by performing a network handshake.
  59. pub trait Session: Sync {
  60. /// Registers a new channel with the session. Performs a network handshake
  61. /// and starts the channel.
  62. async fn register_channel(
  63. self: Arc<Self>,
  64. channel: ChannelPtr,
  65. executor: Arc<Executor<'_>>,
  66. ) -> Result<()> {
  67. debug!(target: "net", "Session::register_channel() [START]");
  68. // Protocols should all be initialized but not started
  69. // We do this so that the protocols can begin receiving and buffering messages
  70. // while the handshake protocol is ongoing.
  71. // They are currently in sleep mode.
  72. let p2p = self.p2p();
  73. let protocols =
  74. p2p.protocol_registry().attach(self.selector_id(), channel.clone(), p2p.clone()).await;
  75. // Perform the handshake protocol
  76. let protocol_version = ProtocolVersion::new(channel.clone(), self.p2p().settings()).await;
  77. let handshake_task =
  78. self.perform_handshake_protocols(protocol_version, channel.clone(), executor.clone());
  79. // Switch on the channel
  80. channel.start(executor.clone());
  81. // Wait for handshake to finish.
  82. handshake_task.await?;
  83. // Now the channel is ready
  84. debug!(target: "net", "Session handshake complete. Activating remaining protocols");
  85. // Now start all the protocols
  86. // They are responsible for managing their own lifetimes and
  87. // correctly self destructing when the channel ends.
  88. for protocol in protocols {
  89. // Activate protocol
  90. protocol.start(executor.clone()).await?;
  91. }
  92. debug!(target: "net", "Session::register_channel() [END]");
  93. Ok(())
  94. }
  95. /// Performs network handshake to initialize channel. Adds the channel to
  96. /// the list of connected channels, and prepares to remove the channel
  97. /// when a stop signal is received.
  98. async fn perform_handshake_protocols(
  99. &self,
  100. protocol_version: Arc<ProtocolVersion>,
  101. channel: ChannelPtr,
  102. executor: Arc<Executor<'_>>,
  103. ) -> Result<()> {
  104. // Perform handshake
  105. protocol_version.run(executor.clone()).await?;
  106. // Channel is now initialized
  107. // Add channel to p2p
  108. self.p2p().store(channel.clone()).await;
  109. // Subscribe to stop, so can remove from p2p
  110. executor.spawn(remove_sub_on_stop(self.p2p(), channel)).detach();
  111. // Channel is ready for use
  112. Ok(())
  113. }
  114. async fn get_info(&self) -> serde_json::Value;
  115. /// Returns a pointer to the p2p network interface.
  116. fn p2p(&self) -> P2pPtr;
  117. fn selector_id(&self) -> u32;
  118. }