protocol_privmsg.rs 8.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272
  1. use std::cmp::Ordering;
  2. use async_executor::Executor;
  3. use async_std::sync::Arc;
  4. use async_trait::async_trait;
  5. use chrono::Utc;
  6. use log::debug;
  7. use rand::{rngs::OsRng, RngCore};
  8. use darkfi::{
  9. net,
  10. serial::{SerialDecodable, SerialEncodable},
  11. Result,
  12. };
  13. use crate::{buffers::Buffers, settings, Privmsg};
  14. #[derive(SerialDecodable, SerialEncodable, Clone, Debug)]
  15. struct Inv {
  16. id: u64,
  17. invs: Vec<InvObject>,
  18. }
  19. #[derive(SerialDecodable, SerialEncodable, Clone, Debug)]
  20. pub struct LastTerm {
  21. pub term: u64,
  22. }
  23. impl Inv {
  24. fn new(invs: Vec<InvObject>) -> Self {
  25. let id = OsRng.next_u64();
  26. Self { id, invs }
  27. }
  28. }
  29. #[derive(SerialDecodable, SerialEncodable, Clone, Debug)]
  30. struct GetData {
  31. invs: Vec<InvObject>,
  32. term: Option<u64>,
  33. }
  34. impl GetData {
  35. fn new(invs: Vec<InvObject>, term: Option<u64>) -> Self {
  36. Self { invs, term }
  37. }
  38. }
  39. #[derive(SerialDecodable, SerialEncodable, Clone, Debug)]
  40. struct InvObject(String);
  41. pub struct ProtocolPrivmsg {
  42. jobsman: net::ProtocolJobsManagerPtr,
  43. notify: async_channel::Sender<Privmsg>,
  44. msg_sub: net::MessageSubscription<Privmsg>,
  45. inv_sub: net::MessageSubscription<Inv>,
  46. getdata_sub: net::MessageSubscription<GetData>,
  47. last_term_sub: net::MessageSubscription<LastTerm>,
  48. p2p: net::P2pPtr,
  49. channel: net::ChannelPtr,
  50. buffers: Buffers,
  51. }
  52. impl ProtocolPrivmsg {
  53. pub async fn init(
  54. channel: net::ChannelPtr,
  55. notify: async_channel::Sender<Privmsg>,
  56. p2p: net::P2pPtr,
  57. buffers: Buffers,
  58. ) -> net::ProtocolBasePtr {
  59. let message_subsytem = channel.get_message_subsystem();
  60. message_subsytem.add_dispatch::<Privmsg>().await;
  61. message_subsytem.add_dispatch::<Inv>().await;
  62. message_subsytem.add_dispatch::<GetData>().await;
  63. message_subsytem.add_dispatch::<LastTerm>().await;
  64. let msg_sub =
  65. channel.clone().subscribe_msg::<Privmsg>().await.expect("Missing Privmsg dispatcher!");
  66. let inv_sub = channel.subscribe_msg::<Inv>().await.expect("Missing Inv dispatcher!");
  67. let getdata_sub =
  68. channel.clone().subscribe_msg::<GetData>().await.expect("Missing GetData dispatcher!");
  69. let last_term_sub = channel
  70. .clone()
  71. .subscribe_msg::<LastTerm>()
  72. .await
  73. .expect("Missing LastTerm dispatcher!");
  74. Arc::new(Self {
  75. notify,
  76. msg_sub,
  77. inv_sub,
  78. getdata_sub,
  79. last_term_sub,
  80. jobsman: net::ProtocolJobsManager::new("ProtocolPrivmsg", channel.clone()),
  81. p2p,
  82. channel,
  83. buffers,
  84. })
  85. }
  86. async fn handle_receive_inv(self: Arc<Self>) -> Result<()> {
  87. debug!(target: "ircd", "ProtocolPrivmsg::handle_receive_inv() [START]");
  88. let exclude_list = vec![self.channel.address()];
  89. loop {
  90. let inv = self.inv_sub.receive().await?;
  91. let inv = (*inv).to_owned();
  92. if !self.buffers.seen_ids.push(inv.id).await {
  93. continue
  94. }
  95. let mut inv_requested = vec![];
  96. for inv_object in inv.invs.iter() {
  97. if !self.buffers.unread_msgs.inc_read_confirms(&inv_object.0).await {
  98. inv_requested.push(inv_object.clone());
  99. }
  100. }
  101. if !inv_requested.is_empty() {
  102. self.channel.send(GetData::new(inv_requested, None)).await?;
  103. }
  104. self.update_unread_msgs().await?;
  105. self.p2p.broadcast_with_exclude(inv, &exclude_list).await?;
  106. }
  107. }
  108. async fn handle_receive_msg(self: Arc<Self>) -> Result<()> {
  109. debug!(target: "ircd", "ProtocolPrivmsg::handle_receive_msg() [START]");
  110. let exclude_list = vec![self.channel.address()];
  111. loop {
  112. let msg = self.msg_sub.receive().await?;
  113. let mut msg = (*msg).to_owned();
  114. if !self.buffers.seen_ids.push(msg.id).await {
  115. continue
  116. }
  117. if msg.read_confirms >= settings::MAX_CONFIRM {
  118. self.add_to_msgs(&msg).await?;
  119. } else {
  120. msg.read_confirms += 1;
  121. let hash = self.add_to_unread_msgs(&msg).await;
  122. self.p2p.broadcast(Inv::new(vec![InvObject(hash)])).await?;
  123. }
  124. self.update_unread_msgs().await?;
  125. self.p2p.broadcast_with_exclude(msg, &exclude_list).await?;
  126. }
  127. }
  128. async fn handle_receive_last_term(self: Arc<Self>) -> Result<()> {
  129. debug!(target: "ircd", "ProtocolPrivmsg::handle_receive_last_term() [START]");
  130. loop {
  131. let last_term = self.last_term_sub.receive().await?;
  132. let last_term = last_term.term;
  133. self.update_unread_msgs().await?;
  134. match self.buffers.privmsgs.last_term().await.cmp(&last_term) {
  135. Ordering::Greater => {
  136. for msg in self.buffers.privmsgs.fetch_msgs(last_term).await {
  137. self.channel.send(msg).await?;
  138. }
  139. }
  140. Ordering::Less => {
  141. self.channel.send(GetData::new(vec![], Some(last_term))).await?;
  142. }
  143. Ordering::Equal => continue,
  144. }
  145. }
  146. }
  147. async fn handle_receive_getdata(self: Arc<Self>) -> Result<()> {
  148. debug!(target: "ircd", "ProtocolPrivmsg::handle_receive_getdata() [START]");
  149. loop {
  150. let getdata = self.getdata_sub.receive().await?;
  151. let getdata = (*getdata).to_owned();
  152. for inv in getdata.invs {
  153. if let Some(msg) = self.buffers.unread_msgs.get(&inv.0).await {
  154. self.channel.send(msg.clone()).await?;
  155. }
  156. }
  157. if let Some(term) = getdata.term {
  158. for msg in self.buffers.privmsgs.fetch_msgs(term).await {
  159. self.channel.send(msg).await?;
  160. }
  161. }
  162. }
  163. }
  164. async fn add_to_unread_msgs(&self, msg: &Privmsg) -> String {
  165. self.buffers.unread_msgs.insert(msg).await
  166. }
  167. async fn update_unread_msgs(&self) -> Result<()> {
  168. for (hash, msg) in self.buffers.unread_msgs.load().await {
  169. if msg.timestamp + settings::UNREAD_MSG_EXPIRE_TIME < Utc::now().timestamp() {
  170. self.buffers.unread_msgs.remove(&hash).await;
  171. continue
  172. }
  173. if msg.read_confirms >= settings::MAX_CONFIRM {
  174. if let Some(msg) = self.buffers.unread_msgs.remove(&hash).await {
  175. self.add_to_msgs(&msg).await?;
  176. }
  177. }
  178. }
  179. Ok(())
  180. }
  181. async fn add_to_msgs(&self, msg: &Privmsg) -> Result<()> {
  182. self.buffers.privmsgs.push(msg).await;
  183. self.notify.send(msg.clone()).await?;
  184. Ok(())
  185. }
  186. }
  187. #[async_trait]
  188. impl net::ProtocolBase for ProtocolPrivmsg {
  189. /// Starts ping-pong keep-alive messages exchange. Runs ping-pong in the
  190. /// protocol task manager, then queues the reply. Sends out a ping and
  191. /// waits for pong reply. Waits for ping and replies with a pong.
  192. async fn start(self: Arc<Self>, executor: Arc<Executor<'_>>) -> Result<()> {
  193. // once a channel get started
  194. for m in self.buffers.privmsgs.load().await {
  195. self.channel.send(m).await?;
  196. }
  197. debug!(target: "ircd", "ProtocolPrivmsg::start() [START]");
  198. self.jobsman.clone().start(executor.clone());
  199. self.jobsman.clone().spawn(self.clone().handle_receive_msg(), executor.clone()).await;
  200. self.jobsman.clone().spawn(self.clone().handle_receive_inv(), executor.clone()).await;
  201. self.jobsman.clone().spawn(self.clone().handle_receive_getdata(), executor.clone()).await;
  202. self.jobsman.clone().spawn(self.clone().handle_receive_last_term(), executor.clone()).await;
  203. debug!(target: "ircd", "ProtocolPrivmsg::start() [END]");
  204. Ok(())
  205. }
  206. fn name(&self) -> &'static str {
  207. "ProtocolPrivmsg"
  208. }
  209. }
  210. impl net::Message for Privmsg {
  211. fn name() -> &'static str {
  212. "privmsg"
  213. }
  214. }
  215. impl net::Message for Inv {
  216. fn name() -> &'static str {
  217. "inv"
  218. }
  219. }
  220. impl net::Message for GetData {
  221. fn name() -> &'static str {
  222. "getdata"
  223. }
  224. }
  225. impl net::Message for LastTerm {
  226. fn name() -> &'static str {
  227. "last_term"
  228. }
  229. }