channel.rs 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302
  1. use async_std::{
  2. net::TcpStream,
  3. sync::{Arc, Mutex},
  4. };
  5. use std::sync::atomic::{AtomicBool, Ordering};
  6. use futures::{
  7. io::{ReadHalf, WriteHalf},
  8. AsyncRead, AsyncReadExt, AsyncWrite,
  9. };
  10. use futures_rustls::TlsStream;
  11. use log::{debug, error, info};
  12. use rand::Rng;
  13. use serde_json::json;
  14. use smol::Executor;
  15. use url::Url;
  16. use crate::{
  17. system::{StoppableTask, StoppableTaskPtr, Subscriber, SubscriberPtr, Subscription},
  18. Error, Result,
  19. };
  20. use super::{
  21. message,
  22. message_subscriber::{MessageSubscription, MessageSubsystem},
  23. };
  24. /// Atomic pointer to async channel.
  25. pub type ChannelPtr = Arc<Channel>;
  26. struct ChannelInfo {
  27. random_id: u32,
  28. last_msg: String,
  29. last_status: String,
  30. // Message log which is cleared on querying get_info
  31. log: Mutex<Vec<(String, String)>>,
  32. }
  33. impl ChannelInfo {
  34. fn new() -> Self {
  35. Self {
  36. random_id: rand::thread_rng().gen(),
  37. last_msg: String::new(),
  38. last_status: String::new(),
  39. log: Mutex::new(Vec::new()),
  40. }
  41. }
  42. async fn get_info(&self) -> serde_json::Value {
  43. let result = json!({
  44. "random_id": self.random_id,
  45. "last_msg": self.last_msg,
  46. "last_status": self.last_status,
  47. "log": self.log.lock().await.clone(),
  48. });
  49. self.log.lock().await.clear();
  50. result
  51. }
  52. }
  53. pub trait Stream: AsyncWrite + AsyncRead + Unpin + Send + Sync {}
  54. impl Stream for TcpStream {}
  55. impl<T: Stream> Stream for TlsStream<T> {}
  56. /// Async channel for communication between nodes.
  57. pub struct Channel {
  58. reader: Mutex<ReadHalf<Box<dyn Stream>>>,
  59. writer: Mutex<WriteHalf<Box<dyn Stream>>>,
  60. address: Url,
  61. message_subsystem: MessageSubsystem,
  62. stop_subscriber: SubscriberPtr<Error>,
  63. receive_task: StoppableTaskPtr,
  64. stopped: AtomicBool,
  65. info: Mutex<ChannelInfo>,
  66. }
  67. impl Channel {
  68. /// Sets up a new channel. Creates a reader and writer TCP stream and
  69. /// summons the message subscriber subsystem. Performs a network
  70. /// handshake on the subsystem dispatchers.
  71. pub async fn new(stream: Box<dyn Stream>, address: Url) -> Arc<Self> {
  72. let (reader, writer) = stream.split();
  73. let reader = Mutex::new(reader);
  74. let writer = Mutex::new(writer);
  75. let message_subsystem = MessageSubsystem::new();
  76. Self::setup_dispatchers(&message_subsystem).await;
  77. Arc::new(Self {
  78. reader,
  79. writer,
  80. address,
  81. message_subsystem,
  82. stop_subscriber: Subscriber::new(),
  83. receive_task: StoppableTask::new(),
  84. stopped: AtomicBool::new(false),
  85. info: Mutex::new(ChannelInfo::new()),
  86. })
  87. }
  88. pub async fn get_info(&self) -> serde_json::Value {
  89. self.info.lock().await.get_info().await
  90. }
  91. /// Starts the channel. Runs a receive loop to start receiving messages or
  92. /// handles a network failure.
  93. pub fn start(self: Arc<Self>, executor: Arc<Executor<'_>>) {
  94. debug!(target: "net", "Channel::start() [START, address={}]", self.address());
  95. let self2 = self.clone();
  96. self.receive_task.clone().start(
  97. self.clone().main_receive_loop(),
  98. // Ignore stop handler
  99. |result| self2.handle_stop(result),
  100. Error::ServiceStopped,
  101. executor,
  102. );
  103. debug!(target: "net", "Channel::start() [END, address={}]", self.address());
  104. }
  105. /// Stops the channel. Steps through each component of the channel
  106. /// connection and sends a stop signal. Notifies all subscribers that
  107. /// the channel has been closed.
  108. pub async fn stop(&self) {
  109. debug!(target: "net", "Channel::stop() [START, address={}]", self.address());
  110. assert!(!self.stopped.load(Ordering::Relaxed));
  111. // Changes memory ordering to relaxed. We don't need strict thread locking here.
  112. self.stopped.store(false, Ordering::Relaxed);
  113. self.stop_subscriber.notify(Error::ChannelStopped).await;
  114. self.receive_task.stop().await;
  115. self.message_subsystem.trigger_error(Error::ChannelStopped).await;
  116. debug!(target: "net", "Channel::stop() [END, address={}]", self.address());
  117. }
  118. /// Creates a subscription to a stopped signal.
  119. pub async fn subscribe_stop(&self) -> Subscription<Error> {
  120. debug!(target: "net",
  121. "Channel::subscribe_stop() [START, address={}]",
  122. self.address()
  123. );
  124. // TODO: this should check the stopped status
  125. // Call to receive should return ChannelStopped on newly created sub
  126. let sub = self.stop_subscriber.clone().subscribe().await;
  127. debug!(target: "net",
  128. "Channel::subscribe_stop() [END, address={}]",
  129. self.address()
  130. );
  131. sub
  132. }
  133. /// Sends a message across a channel. Calls function 'send_message' that
  134. /// creates a new payload and sends it over the TCP connection as a
  135. /// packet. Returns an error if something goes wrong.
  136. pub async fn send<M: message::Message>(&self, message: M) -> Result<()> {
  137. debug!(target: "net",
  138. "Channel::send() [START, command={:?}, address={}]",
  139. M::name(),
  140. self.address()
  141. );
  142. if self.stopped.load(Ordering::Relaxed) {
  143. return Err(Error::ChannelStopped)
  144. }
  145. // Catch failure and stop channel, return a net error
  146. let result = match self.send_message(message).await {
  147. Ok(()) => Ok(()),
  148. Err(err) => {
  149. error!("Channel send error for [{}]: {}", self.address(), err);
  150. self.stop().await;
  151. Err(Error::ChannelStopped)
  152. }
  153. };
  154. debug!(target: "net",
  155. "Channel::send() [END, command={:?}, address={}]",
  156. M::name(),
  157. self.address()
  158. );
  159. {
  160. let info = &mut *self.info.lock().await;
  161. info.last_msg = M::name().to_string();
  162. info.last_status = "sent".to_string();
  163. }
  164. result
  165. }
  166. /// Implements send message functionality. Creates a new payload and encodes
  167. /// it. Then creates a message packet- the base type of the network- and
  168. /// copies the payload into it. Then we send the packet over the TCP
  169. /// stream.
  170. async fn send_message<M: message::Message>(&self, message: M) -> Result<()> {
  171. let mut payload = Vec::new();
  172. message.encode(&mut payload)?;
  173. let packet = message::Packet { command: String::from(M::name()), payload };
  174. {
  175. let info = &mut *self.info.lock().await;
  176. info.log.lock().await.push(("send".to_string(), packet.command.clone()));
  177. }
  178. let stream = &mut *self.writer.lock().await;
  179. message::send_packet(stream, packet).await
  180. }
  181. /// Subscribe to a messages on the message subsystem.
  182. pub async fn subscribe_msg<M: message::Message>(&self) -> Result<MessageSubscription<M>> {
  183. debug!(target: "net",
  184. "Channel::subscribe_msg() [START, command={:?}, address={}]",
  185. M::name(),
  186. self.address()
  187. );
  188. let sub = self.message_subsystem.subscribe::<M>().await;
  189. debug!(target: "net",
  190. "Channel::subscribe_msg() [END, command={:?}, address={}]",
  191. M::name(),
  192. self.address()
  193. );
  194. sub
  195. }
  196. /// Return the local socket address.
  197. pub fn address(&self) -> Url {
  198. self.address.clone()
  199. }
  200. /// End of file error. Triggered when unexpected end of file occurs.
  201. fn is_eof_error(err: Error) -> bool {
  202. match err {
  203. Error::Io(io_err) => io_err == std::io::ErrorKind::UnexpectedEof,
  204. _ => false,
  205. }
  206. }
  207. /// Perform network handshake for message subsystem dispatchers.
  208. async fn setup_dispatchers(message_subsystem: &MessageSubsystem) {
  209. message_subsystem.add_dispatch::<message::VersionMessage>().await;
  210. message_subsystem.add_dispatch::<message::VerackMessage>().await;
  211. message_subsystem.add_dispatch::<message::PingMessage>().await;
  212. message_subsystem.add_dispatch::<message::PongMessage>().await;
  213. message_subsystem.add_dispatch::<message::GetAddrsMessage>().await;
  214. message_subsystem.add_dispatch::<message::AddrsMessage>().await;
  215. }
  216. /// Convenience function that returns the Message Subsystem.
  217. pub fn get_message_subsystem(&self) -> &MessageSubsystem {
  218. &self.message_subsystem
  219. }
  220. /// Run the receive loop. Start receiving messages or handle network
  221. /// failure.
  222. async fn main_receive_loop(self: Arc<Self>) -> Result<()> {
  223. debug!(target: "net",
  224. "Channel::receive_loop() [START, address={}]",
  225. self.address()
  226. );
  227. let reader = &mut *self.reader.lock().await;
  228. loop {
  229. let packet = match message::read_packet(reader).await {
  230. Ok(packet) => packet,
  231. Err(err) => {
  232. if Self::is_eof_error(err.clone()) {
  233. info!("Channel {:?} disconnected", self.address());
  234. } else {
  235. error!("Read error on channel: {}", err);
  236. }
  237. debug!(target: "net",
  238. "Channel::receive_loop() stopping channel {:?}",
  239. self.address()
  240. );
  241. self.stop().await;
  242. return Err(Error::ChannelStopped)
  243. }
  244. };
  245. {
  246. let info = &mut *self.info.lock().await;
  247. info.last_msg = packet.command.clone();
  248. info.last_status = "recv".to_string();
  249. info.log.lock().await.push(("recv".to_string(), packet.command.clone()));
  250. }
  251. // Send result to our subscribers
  252. self.message_subsystem.notify(&packet.command, packet.payload).await;
  253. }
  254. }
  255. /// Handle network errors. Panic if error passes silently, otherwise
  256. /// broadcast the error.
  257. async fn handle_stop(self: Arc<Self>, result: Result<()>) {
  258. debug!(target: "net", "Channel::handle_stop() [START, address={}]", self.address());
  259. match result {
  260. Ok(()) => panic!("Channel task should never complete without error status"),
  261. Err(err) => {
  262. // Send this error to all channel subscribers
  263. self.message_subsystem.trigger_error(err).await;
  264. }
  265. }
  266. debug!(target: "net", "Channel::handle_stop() [END, address={}]", self.address());
  267. }
  268. }