seedsync_session.rs 5.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168
  1. use async_std::{
  2. future::timeout,
  3. sync::{Arc, Weak},
  4. };
  5. use futures::future;
  6. use std::time::Duration;
  7. use async_executor::Executor;
  8. use async_trait::async_trait;
  9. use log::*;
  10. use serde_json::json;
  11. use url::Url;
  12. use crate::{Error, Result};
  13. use super::{
  14. super::{Connector, P2p},
  15. Session, SessionBitflag, SESSION_SEED,
  16. };
  17. /// Defines seed connections session.
  18. pub struct SeedSyncSession {
  19. p2p: Weak<P2p>,
  20. }
  21. impl SeedSyncSession {
  22. /// Create a new seed sync session instance.
  23. pub fn new(p2p: Weak<P2p>) -> Arc<Self> {
  24. Arc::new(Self { p2p })
  25. }
  26. /// Start the seed sync session. Creates a new task for every seed connection and
  27. /// starts the seed on each task.
  28. pub async fn start(self: Arc<Self>, executor: Arc<Executor<'_>>) -> Result<()> {
  29. debug!(target: "net", "SeedSyncSession::start() [START]");
  30. let settings = self.p2p().settings();
  31. if settings.seeds.is_empty() {
  32. warn!("Skipping seed sync process since no seeds are configured.");
  33. // Store external address in hosts explicitly
  34. match &settings.external_addr {
  35. Some(addr) => self.p2p().hosts().store(vec![addr.clone()]).await,
  36. None => (),
  37. }
  38. return Ok(())
  39. }
  40. // if cached addresses then quit
  41. let mut tasks = Vec::new();
  42. // This loops through all the seeds and tries to start them.
  43. // If the seed_query_timeout_seconds times out before they are finished,
  44. // it will return an error.
  45. for (i, seed) in settings.seeds.iter().enumerate() {
  46. let ex2 = executor.clone();
  47. let self2 = self.clone();
  48. let sett2 = settings.clone();
  49. tasks.push(async move {
  50. let task = self2.clone().start_seed(i, seed.clone(), ex2.clone());
  51. let result =
  52. timeout(Duration::from_secs(sett2.seed_query_timeout_seconds.into()), task)
  53. .await;
  54. match result {
  55. Ok(t) => match t {
  56. Ok(()) => {
  57. info!("Seed #{} connected successfully", i)
  58. }
  59. Err(err) => {
  60. warn!("Seed #{} failed for reason {}", i, err)
  61. }
  62. },
  63. Err(_err) => error!("Seed #{} timed out", i),
  64. }
  65. });
  66. }
  67. future::join_all(tasks).await;
  68. // Seed process complete
  69. if self.p2p().hosts().is_empty().await {
  70. error!("Hosts pool still empty after seeding");
  71. return Err(Error::NetworkOperationFailed)
  72. }
  73. debug!(target: "net", "SeedSyncSession::start() [END]");
  74. Ok(())
  75. }
  76. /// Connects to a seed socket address.
  77. async fn start_seed(
  78. self: Arc<Self>,
  79. seed_index: usize,
  80. seed: Url,
  81. executor: Arc<Executor<'_>>,
  82. ) -> Result<()> {
  83. debug!(target: "net", "SeedSyncSession::start_seed(i={}) [START]", seed_index);
  84. let (_hosts, settings) = {
  85. let p2p = self.p2p.upgrade().unwrap();
  86. (p2p.hosts(), p2p.settings())
  87. };
  88. let parent = Arc::downgrade(&self);
  89. let connector = Connector::new(settings.clone(), Arc::new(parent));
  90. match connector.connect(seed.clone()).await {
  91. Ok(channel) => {
  92. // Blacklist goes here
  93. info!("Connected seed #{} [{}]", seed_index, seed);
  94. if let Err(err) =
  95. self.clone().register_channel(channel.clone(), executor.clone()).await
  96. {
  97. warn!("Failure during seed sync session #{} [{}]: {}", seed_index, seed, err);
  98. }
  99. info!("Disconnecting from seed #{} [{}]", seed_index, seed);
  100. channel.stop().await;
  101. debug!(target: "net", "SeedSyncSession::start_seed(i={}) [END]", seed_index);
  102. Ok(())
  103. }
  104. Err(err) => {
  105. warn!("Failure contacting seed #{} [{}]: {}", seed_index, seed, err);
  106. Err(err)
  107. }
  108. }
  109. }
  110. // Starts keep-alive messages and seed protocol.
  111. /*async fn attach_protocols(
  112. self: Arc<Self>,
  113. channel: ChannelPtr,
  114. hosts: HostsPtr,
  115. settings: SettingsPtr,
  116. executor: Arc<Executor<'_>>,
  117. ) -> Result<()> {
  118. let protocol_ping = ProtocolPing::new(channel.clone(), self.p2p());
  119. protocol_ping.start(executor.clone()).await;
  120. let protocol_seed = ProtocolSeed::new(channel.clone(), hosts, settings.clone());
  121. // This will block until seed process is complete
  122. protocol_seed.start(executor.clone()).await?;
  123. channel.stop().await;
  124. Ok(())
  125. }*/
  126. }
  127. #[async_trait]
  128. impl Session for SeedSyncSession {
  129. async fn get_info(&self) -> serde_json::Value {
  130. json!({
  131. "key": 110
  132. })
  133. }
  134. fn p2p(&self) -> Arc<P2p> {
  135. self.p2p.upgrade().unwrap()
  136. }
  137. fn type_id(&self) -> SessionBitflag {
  138. SESSION_SEED
  139. }
  140. }