protocol_privmsg.rs 7.2 KB

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