seed_protocol.rs 5.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183
  1. use async_dup::Arc;
  2. use log::*;
  3. use smol::{Async, Executor};
  4. use std::net::{SocketAddr, TcpStream};
  5. use std::sync::atomic::{AtomicU64, Ordering};
  6. use crate::error::Result;
  7. use crate::net::net;
  8. use crate::net::protocol::protocol_base;
  9. use crate::utility::{get_current_time, AddrsStorage};
  10. type Clock = Arc<AtomicU64>;
  11. pub struct SeedProtocol {
  12. send_sx: async_channel::Sender<net::Message>,
  13. send_rx: async_channel::Receiver<net::Message>,
  14. main_process: Option<smol::Task<()>>,
  15. }
  16. #[derive(PartialEq)]
  17. enum ProtocolSignal {
  18. Waiting,
  19. Finished,
  20. Timeout
  21. }
  22. impl SeedProtocol {
  23. pub fn new() -> Self {
  24. let (send_sx, send_rx) = async_channel::unbounded::<net::Message>();
  25. Self {
  26. send_sx,
  27. send_rx,
  28. main_process: None,
  29. }
  30. }
  31. pub async fn start(
  32. &mut self,
  33. seed_addr: SocketAddr,
  34. local_addr: Option<SocketAddr>,
  35. stored_addrs: AddrsStorage,
  36. executor: Arc<Executor<'_>>,
  37. ) {
  38. let (send_sx, send_rx) = (self.send_sx.clone(), self.send_rx.clone());
  39. let ex = executor.clone();
  40. self.main_process = Some(ex.spawn(async move {
  41. match Async::<TcpStream>::connect(seed_addr.clone()).await {
  42. Ok(stream) => {
  43. let _ = Self::handle_connect(
  44. stream,
  45. &stored_addrs,
  46. seed_addr.clone(),
  47. local_addr,
  48. (send_sx.clone(), send_rx.clone()),
  49. executor.clone(),
  50. )
  51. .await;
  52. }
  53. Err(err) => { warn!("Unable to connect to seed {}: {}", seed_addr, err) },
  54. }
  55. }));
  56. }
  57. pub async fn await_finish(self) {
  58. if let Some(process) = self.main_process {
  59. process.await;
  60. }
  61. }
  62. async fn handle_connect(
  63. stream: Async<TcpStream>,
  64. stored_addrs: &AddrsStorage,
  65. seed_addr: SocketAddr,
  66. local_addr: Option<SocketAddr>,
  67. (send_sx, send_rx): (
  68. async_channel::Sender<net::Message>,
  69. async_channel::Receiver<net::Message>,
  70. ),
  71. executor: Arc<Executor<'_>>,
  72. ) -> Result<()> {
  73. if let Some(local_addr) = local_addr {
  74. send_sx
  75. .send(net::Message::Addrs(net::AddrsMessage { addrs: vec![local_addr] }))
  76. .await?;
  77. }
  78. send_sx
  79. .send(net::Message::GetAddrs(net::GetAddrsMessage {}))
  80. .await?;
  81. let stream = Arc::new(stream);
  82. // Run event loop
  83. match Self::event_loop_process(
  84. stream,
  85. stored_addrs.clone(),
  86. (send_sx, send_rx),
  87. executor,
  88. )
  89. .await
  90. {
  91. Ok(ProtocolSignal::Finished) => {
  92. info!("Seed node queried successfully: {}", seed_addr);
  93. }
  94. Ok(ProtocolSignal::Timeout) => {
  95. warn!("Seed node timeout: {}", seed_addr);
  96. }
  97. Ok(_) => { unreachable!(); }
  98. Err(err) => {
  99. warn!("Seed disconnected: {} {}", seed_addr, err);
  100. }
  101. }
  102. Ok(())
  103. }
  104. async fn event_loop_process(
  105. mut stream: net::AsyncTcpStream,
  106. stored_addrs: AddrsStorage,
  107. (send_sx, send_rx): (
  108. async_channel::Sender<net::Message>,
  109. async_channel::Receiver<net::Message>,
  110. ),
  111. executor: Arc<Executor<'_>>,
  112. ) -> Result<ProtocolSignal> {
  113. let inactivity_timer = net::InactivityTimer::new(executor.clone());
  114. let clock = Arc::new(AtomicU64::new(0));
  115. let _ping_task = executor.spawn(protocol_base::repeat_ping(send_sx.clone(), clock.clone()));
  116. loop {
  117. let event = net::select_event(&mut stream, &send_rx, &inactivity_timer).await?;
  118. match event {
  119. net::Event::Send(message) => {
  120. net::send_message(&mut stream, message).await?;
  121. }
  122. net::Event::Receive(message) => {
  123. inactivity_timer.reset().await?;
  124. let signal = Self::protocol(message, &stored_addrs, &send_sx, &clock).await?;
  125. if signal == ProtocolSignal::Finished {
  126. return Ok(ProtocolSignal::Finished);
  127. }
  128. }
  129. net::Event::Timeout => return Ok(ProtocolSignal::Timeout),
  130. }
  131. }
  132. // These aren't needed since drop() cancels tasks anyway
  133. //ping_task.cancel().await;
  134. //inactivity_timer.stop().await;
  135. }
  136. async fn protocol(
  137. message: net::Message,
  138. stored_addrs: &AddrsStorage,
  139. _send_sx: &async_channel::Sender<net::Message>,
  140. clock: &Clock,
  141. ) -> Result<ProtocolSignal> {
  142. match message {
  143. net::Message::Pong => {
  144. let current_time = get_current_time();
  145. let elapsed = current_time - clock.load(Ordering::Relaxed);
  146. info!("Ping time: {} ms", elapsed);
  147. }
  148. net::Message::Addrs(message) => {
  149. info!("received AddrMessage");
  150. let mut stored_addrs = stored_addrs.lock().await;
  151. for addr in message.addrs {
  152. if !stored_addrs.contains(&addr) {
  153. stored_addrs.push(addr);
  154. info!("Added new address to storage {}", addr.to_string());
  155. }
  156. }
  157. return Ok(ProtocolSignal::Finished);
  158. }
  159. _ => {}
  160. }
  161. Ok(ProtocolSignal::Waiting)
  162. }
  163. }