protocol_version.rs 6.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189
  1. /* This file is part of DarkFi (https://dark.fi)
  2. *
  3. * Copyright (C) 2020-2024 Dyne.org foundation
  4. *
  5. * This program is free software: you can redistribute it and/or modify
  6. * it under the terms of the GNU Affero General Public License as
  7. * published by the Free Software Foundation, either version 3 of the
  8. * License, or (at your option) any later version.
  9. *
  10. * This program is distributed in the hope that it will be useful,
  11. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  13. * GNU Affero General Public License for more details.
  14. *
  15. * You should have received a copy of the GNU Affero General Public License
  16. * along with this program. If not, see <https://www.gnu.org/licenses/>.
  17. */
  18. use std::{sync::Arc, time::Duration};
  19. use futures::future::join_all;
  20. use log::{debug, error};
  21. use smol::Executor;
  22. use super::super::{
  23. channel::ChannelPtr,
  24. message::{VerackMessage, VersionMessage},
  25. message_subscriber::MessageSubscription,
  26. settings::SettingsPtr,
  27. };
  28. use crate::{system::timeout::timeout, Error, Result};
  29. /// Implements the protocol version handshake sent out by nodes at
  30. /// the beginning of a connection.
  31. pub struct ProtocolVersion {
  32. channel: ChannelPtr,
  33. version_sub: MessageSubscription<VersionMessage>,
  34. verack_sub: MessageSubscription<VerackMessage>,
  35. settings: SettingsPtr,
  36. }
  37. impl ProtocolVersion {
  38. /// Create a new version protocol. Makes a version and version ack
  39. /// subscription, then adds them to a version protocol instance.
  40. pub async fn new(channel: ChannelPtr, settings: SettingsPtr) -> Arc<Self> {
  41. // Creates a versi5on subscription
  42. let version_sub =
  43. channel.subscribe_msg::<VersionMessage>().await.expect("Missing version dispatcher!");
  44. // Creates a version acknowledgement subscription
  45. let verack_sub =
  46. channel.subscribe_msg::<VerackMessage>().await.expect("Missing verack dispatcher!");
  47. Arc::new(Self { channel, version_sub, verack_sub, settings })
  48. }
  49. /// Start version information exchange. Start the timer. Send version
  50. /// info and wait for version ack. Wait for version info and send
  51. /// version ack.
  52. pub async fn run(self: Arc<Self>, executor: Arc<Executor<'_>>) -> Result<()> {
  53. debug!(target: "net::protocol_version::run()", "START => address={}", self.channel.address());
  54. // Start timer
  55. // Send version, wait for verack
  56. // Wait for version, send verack
  57. // Fin.
  58. let result = timeout(
  59. Duration::from_secs(self.settings.channel_handshake_timeout),
  60. self.clone().exchange_versions(executor),
  61. )
  62. .await;
  63. if let Err(e) = result {
  64. error!(
  65. target: "net::protocol_version::run()",
  66. "[P2P] Version Exchange failed [{}]: {}",
  67. self.channel.address(), e,
  68. );
  69. // Remove from hosts
  70. //self.hosts.remove(self.channel.address()).await;
  71. self.channel.stop().await;
  72. return Err(Error::ChannelTimeout)
  73. }
  74. debug!(target: "net::protocol_version::run()", "END => address={}", self.channel.address());
  75. Ok(())
  76. }
  77. /// Send and receive version information
  78. async fn exchange_versions(self: Arc<Self>, executor: Arc<Executor<'_>>) -> Result<()> {
  79. debug!(
  80. target: "net::protocol_version::exchange_versions()",
  81. "START => address={}", self.channel.address(),
  82. );
  83. let send = executor.spawn(self.clone().send_version());
  84. let recv = executor.spawn(self.clone().recv_version());
  85. let rets = join_all(vec![send, recv]).await;
  86. if let Err(e) = &rets[0] {
  87. error!(
  88. target: "net::protocol_version::exchange_versions()",
  89. "send_version() failed: {}", e,
  90. );
  91. return Err(e.clone())
  92. }
  93. if let Err(e) = &rets[1] {
  94. error!(
  95. target: "net::protocol_version::exchange_versions()",
  96. "recv_version() failed: {}", e,
  97. );
  98. return Err(e.clone())
  99. }
  100. debug!(
  101. target: "net::protocol_version::exchange_versions()",
  102. "END => address={}", self.channel.address(),
  103. );
  104. Ok(())
  105. }
  106. /// Send version info and wait for version acknowledgement.
  107. /// Ensures that the app version is the same.
  108. async fn send_version(self: Arc<Self>) -> Result<()> {
  109. debug!(
  110. target: "net::protocol_version::send_version()",
  111. "START => address={}", self.channel.address(),
  112. );
  113. let version = VersionMessage { node_id: self.settings.node_id.clone() };
  114. self.channel.send(&version).await?;
  115. // Wait for verack
  116. let verack_msg = self.verack_sub.receive().await?;
  117. // Validate peer received version against our version.
  118. debug!(
  119. target: "net::protocol_version::send_version()",
  120. "App version: {}, Recv version: {}",
  121. self.settings.app_version, verack_msg.app_version,
  122. );
  123. // MAJOR and MINOR should be the same.
  124. if self.settings.app_version.major != verack_msg.app_version.major ||
  125. self.settings.app_version.minor != verack_msg.app_version.minor
  126. {
  127. error!(
  128. target: "net::protocol_version::send_version()",
  129. "[P2P] Version mismatch from {}. Disconnecting...",
  130. self.channel.address(),
  131. );
  132. //self.hosts.remove(self.channel.address()).await;
  133. self.channel.stop().await;
  134. return Err(Error::ChannelStopped)
  135. }
  136. // Versions are compatible
  137. debug!(
  138. target: "net::protocol_version::send_version()",
  139. "END => address={}", self.channel.address(),
  140. );
  141. Ok(())
  142. }
  143. /// Receive version info, check the message is okay and send verack
  144. /// with app version attached.
  145. async fn recv_version(self: Arc<Self>) -> Result<()> {
  146. debug!(
  147. target: "net::protocol_version::recv_version()",
  148. "START => address={}", self.channel.address(),
  149. );
  150. // Receive version message
  151. let _version = self.version_sub.receive().await?;
  152. // TODO: self.channel.set_remote_node_id(version.node_id.clone()).await;
  153. // Send verack
  154. let verack = VerackMessage { app_version: self.settings.app_version.clone() };
  155. self.channel.send(&verack).await?;
  156. debug!(
  157. target: "net::protocol_version::recv_version()",
  158. "END => address={}", self.channel.address(),
  159. );
  160. Ok(())
  161. }
  162. }