protocol_privmsg.rs 7.3 KB

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