protocol_version.rs 6.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180
  1. /* This file is part of DarkFi (https://dark.fi)
  2. *
  3. * Copyright (C) 2020-2023 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::time::Duration;
  19. use async_std::{future::timeout, sync::Arc};
  20. use log::{debug, error};
  21. use smol::Executor;
  22. use super::super::{
  23. channel::ChannelPtr,
  24. hosts::HostsPtr,
  25. message::{VerackMessage, VersionMessage},
  26. message_subscriber::MessageSubscription,
  27. settings::SettingsPtr,
  28. };
  29. use crate::{Error, Result};
  30. /// Implements the protocol version handshake sent out by nodes at
  31. /// the beginning of a connection.
  32. pub struct ProtocolVersion {
  33. channel: ChannelPtr,
  34. version_sub: MessageSubscription<VersionMessage>,
  35. verack_sub: MessageSubscription<VerackMessage>,
  36. settings: SettingsPtr,
  37. hosts: HostsPtr,
  38. }
  39. impl ProtocolVersion {
  40. /// Create a new version protocol. Makes a version and version ack
  41. /// subscription, then adds them to a version protocol instance.
  42. pub async fn new(channel: ChannelPtr, settings: SettingsPtr, hosts: HostsPtr) -> Arc<Self> {
  43. // Creates a versi5on subscription
  44. let version_sub =
  45. channel.subscribe_msg::<VersionMessage>().await.expect("Missing version dispatcher!");
  46. // Creates a version acknowledgement subscription
  47. let verack_sub =
  48. channel.subscribe_msg::<VerackMessage>().await.expect("Missing verack dispatcher!");
  49. Arc::new(Self { channel, version_sub, verack_sub, settings, hosts })
  50. }
  51. /// Start version information exchange. Start the timer. Send version
  52. /// info and wait for version ack. Wait for version info and send
  53. /// version ack.
  54. pub async fn run(self: Arc<Self>, executor: Arc<Executor<'_>>) -> Result<()> {
  55. debug!(target: "net::protocol_version::run()", "START => address={}", self.channel.address());
  56. // Start timer
  57. // Send version, wait for verack
  58. // Wait for version, send verack
  59. // Fin.
  60. let result = timeout(
  61. Duration::from_secs(self.settings.channel_handshake_timeout),
  62. self.clone().exchange_versions(executor),
  63. )
  64. .await;
  65. if let Err(e) = result {
  66. error!(
  67. target: "net::protocol_version::run()",
  68. "[P2P] Version Exchange failed [{}]: {}",
  69. self.channel.address(), e,
  70. );
  71. // Remove from hosts
  72. self.hosts.remove(self.channel.address()).await;
  73. self.channel.stop().await;
  74. return Err(Error::ChannelTimeout)
  75. }
  76. debug!(target: "net::protocol_version::run()", "END => address={}", self.channel.address());
  77. Ok(())
  78. }
  79. /// Send and receive version information
  80. async fn exchange_versions(self: Arc<Self>, executor: Arc<Executor<'_>>) -> Result<()> {
  81. debug!(
  82. target: "net::protocol_version::exchange_versions()",
  83. "START => address={}", self.channel.address(),
  84. );
  85. let send = executor.spawn(self.clone().send_version());
  86. let recv = executor.spawn(self.clone().recv_version());
  87. send.await?;
  88. recv.await?;
  89. debug!(
  90. target: "net::protocol_version::exchange_versions()",
  91. "END => address={}", self.channel.address(),
  92. );
  93. Ok(())
  94. }
  95. /// Send version info and wait for version acknowledgement.
  96. /// Ensures that the app version is the same.
  97. async fn send_version(self: Arc<Self>) -> Result<()> {
  98. debug!(
  99. target: "net::protocol_version::send_version()",
  100. "START => address={}", self.channel.address(),
  101. );
  102. let version = VersionMessage { node_id: self.settings.node_id.clone() };
  103. self.channel.send(&version).await?;
  104. // Wait for verack
  105. let verack_msg = self.verack_sub.receive().await?;
  106. // Validate peer received version against our version.
  107. // Seeds get ignored
  108. if self.settings.seeds.contains(self.channel.address()) {
  109. debug!(target: "net::protocol_version::send_version()", "Peer is a seed, skipping version");
  110. debug!(target: "net::protocol_version::send_version()", "END => address={}", self.channel.address());
  111. return Ok(())
  112. }
  113. debug!(
  114. target: "net::protocol_version::send_version()",
  115. "App version: {}, Recv version: {}",
  116. self.settings.app_version, verack_msg.app_version,
  117. );
  118. // MAJOR and MINOR should be the same.
  119. if self.settings.app_version.major != verack_msg.app_version.major ||
  120. self.settings.app_version.minor != verack_msg.app_version.minor
  121. {
  122. error!(
  123. target: "net::protocol_version::send_version()",
  124. "[P2P] Version mismatch from {}. Disconnecting...",
  125. self.channel.address(),
  126. );
  127. self.hosts.remove(self.channel.address()).await;
  128. self.channel.stop().await;
  129. return Err(Error::ChannelStopped)
  130. }
  131. // Versions are compatible
  132. Ok(())
  133. }
  134. /// Receive version info, check the message is okay and send verack
  135. /// with app version attached.
  136. async fn recv_version(self: Arc<Self>) -> Result<()> {
  137. debug!(
  138. target: "net::protocol_version::recv_version()",
  139. "START => address={}", self.channel.address(),
  140. );
  141. // Receive version message
  142. let _version = self.version_sub.receive().await?;
  143. //self.channel.set_remote_node_id(version.node_id.clone()).await;
  144. // Send verack
  145. let verack = VerackMessage { app_version: self.settings.app_version.clone() };
  146. self.channel.send(&verack).await?;
  147. debug!(
  148. target: "net::protocol_version::recv_version()",
  149. "END => address={}", self.channel.address(),
  150. );
  151. Ok(())
  152. }
  153. }