protocol_privmsg2.rs 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390
  1. use async_std::sync::{Arc, Mutex};
  2. use std::collections::VecDeque;
  3. use async_executor::Executor;
  4. use async_trait::async_trait;
  5. use chrono::Utc;
  6. use fxhash::FxHashMap;
  7. use log::debug;
  8. use rand::{rngs::OsRng, RngCore};
  9. use darkfi::{
  10. net,
  11. util::{
  12. serial::{SerialDecodable, SerialEncodable},
  13. sleep,
  14. },
  15. Result,
  16. };
  17. use crate::{
  18. chains::{Chains, Privmsg},
  19. settings,
  20. };
  21. #[derive(Clone)]
  22. pub struct RingBuffer<T> {
  23. pub items: VecDeque<T>,
  24. }
  25. impl<T: Eq + PartialEq + Clone> RingBuffer<T> {
  26. pub fn new(capacity: usize) -> Self {
  27. let items = VecDeque::with_capacity(capacity);
  28. Self { items }
  29. }
  30. pub fn push(&mut self, val: T) {
  31. if self.items.len() == self.items.capacity() {
  32. self.items.pop_front();
  33. }
  34. self.items.push_back(val);
  35. }
  36. pub fn contains(&self, val: &T) -> bool {
  37. self.items.contains(val)
  38. }
  39. }
  40. pub struct SeenIds {
  41. ids: Mutex<RingBuffer<String>>,
  42. }
  43. impl SeenIds {
  44. pub fn new() -> Self {
  45. Self { ids: Mutex::new(RingBuffer::new(settings::SIZE_OF_IDSS_BUFFER)) }
  46. }
  47. pub async fn push(&self, id: &String) -> bool {
  48. let ids = &mut self.ids.lock().await;
  49. if !ids.contains(id) {
  50. ids.push(id.clone());
  51. return true
  52. }
  53. false
  54. }
  55. }
  56. pub struct UnreadMsgs {
  57. msgs: Mutex<FxHashMap<String, Privmsg>>,
  58. }
  59. impl UnreadMsgs {
  60. pub fn new() -> Self {
  61. Self { msgs: Mutex::new(FxHashMap::default()) }
  62. }
  63. pub async fn contains(&self, key: &str) -> bool {
  64. self.msgs.lock().await.contains_key(key)
  65. }
  66. // Increase the read_confirms for a message, if it has exceeded the MAX_CONFIRM
  67. // then remove it from the hash_map and return Some(msg), otherwise return None
  68. pub async fn inc_read_confirms(&self, key: &str) -> Option<Privmsg> {
  69. let msgs = &mut self.msgs.lock().await;
  70. let mut result = None;
  71. if let Some(msg) = msgs.get_mut(key) {
  72. msg.read_confirms += 1;
  73. if msg.read_confirms >= settings::MAX_CONFIRM {
  74. result = Some(msg.clone())
  75. }
  76. }
  77. if result.is_some() {
  78. msgs.remove(key);
  79. }
  80. result
  81. }
  82. pub async fn insert(&self, msg: &Privmsg) {
  83. let msgs = &mut self.msgs.lock().await;
  84. // prune expired msgs
  85. let mut prune_ids = vec![];
  86. for (id, m) in msgs.iter() {
  87. if m.timestamp + settings::UNREAD_MSG_EXPIRE_TIME < Utc::now().timestamp() {
  88. prune_ids.push(id.clone());
  89. }
  90. }
  91. for id in prune_ids {
  92. msgs.remove(&id);
  93. }
  94. msgs.insert(msg.id.clone(), msg.clone());
  95. }
  96. }
  97. #[derive(SerialDecodable, SerialEncodable, Clone, Debug)]
  98. struct Inv {
  99. id: String,
  100. hash: String,
  101. target: String,
  102. }
  103. #[derive(SerialDecodable, SerialEncodable, Clone, Debug)]
  104. struct GetMsgs {
  105. invs: Vec<String>,
  106. target: String,
  107. }
  108. #[derive(SerialDecodable, SerialEncodable, Clone, Debug)]
  109. struct Hashes {
  110. hashes: Vec<String>,
  111. height: usize,
  112. target: String,
  113. }
  114. #[derive(SerialDecodable, SerialEncodable, Clone, Debug)]
  115. struct SyncHash {
  116. height: usize,
  117. target: String,
  118. }
  119. pub struct ProtocolPrivmsg {
  120. jobsman: net::ProtocolJobsManagerPtr,
  121. notify: async_channel::Sender<Privmsg>,
  122. msg_sub: net::MessageSubscription<Privmsg>,
  123. inv_sub: net::MessageSubscription<Inv>,
  124. getmsgs_sub: net::MessageSubscription<GetMsgs>,
  125. hashes_sub: net::MessageSubscription<Hashes>,
  126. synchash_sub: net::MessageSubscription<SyncHash>,
  127. p2p: net::P2pPtr,
  128. channel: net::ChannelPtr,
  129. chains: Chains,
  130. seen_ids: SeenIds,
  131. unread_msgs: UnreadMsgs,
  132. }
  133. impl ProtocolPrivmsg {
  134. pub async fn init(
  135. channel: net::ChannelPtr,
  136. notify: async_channel::Sender<Privmsg>,
  137. p2p: net::P2pPtr,
  138. chains: Chains,
  139. seen_ids: SeenIds,
  140. unread_msgs: UnreadMsgs,
  141. ) -> net::ProtocolBasePtr {
  142. let message_subsytem = channel.get_message_subsystem();
  143. message_subsytem.add_dispatch::<Privmsg>().await;
  144. message_subsytem.add_dispatch::<Inv>().await;
  145. message_subsytem.add_dispatch::<GetMsgs>().await;
  146. message_subsytem.add_dispatch::<Hashes>().await;
  147. message_subsytem.add_dispatch::<SyncHash>().await;
  148. let msg_sub =
  149. channel.clone().subscribe_msg::<Privmsg>().await.expect("Missing Privmsg dispatcher!");
  150. let inv_sub = channel.subscribe_msg::<Inv>().await.expect("Missing Inv dispatcher!");
  151. let getmsgs_sub =
  152. channel.clone().subscribe_msg::<GetMsgs>().await.expect("Missing GetMsgs dispatcher!");
  153. let hashes_sub =
  154. channel.clone().subscribe_msg::<Hashes>().await.expect("Missing Hashes dispatcher!");
  155. let synchash_sub = channel
  156. .clone()
  157. .subscribe_msg::<SyncHash>()
  158. .await
  159. .expect("Missing HashSync dispatcher!");
  160. Arc::new(Self {
  161. notify,
  162. msg_sub,
  163. inv_sub,
  164. getmsgs_sub,
  165. hashes_sub,
  166. synchash_sub,
  167. jobsman: net::ProtocolJobsManager::new("ProtocolPrivmsg", channel.clone()),
  168. p2p,
  169. channel,
  170. chains,
  171. seen_ids,
  172. unread_msgs,
  173. })
  174. }
  175. async fn handle_receive_inv(self: Arc<Self>) -> Result<()> {
  176. debug!(target: "ircd", "ProtocolPrivmsg::handle_receive_inv() [START]");
  177. let exclude_list = vec![self.channel.address()];
  178. loop {
  179. let inv = self.inv_sub.receive().await?;
  180. let inv = (*inv).to_owned();
  181. if !self.seen_ids.push(&inv.id).await {
  182. continue
  183. }
  184. // On receive inv message, if the unread_msgs buffer has the msg's hash then increase
  185. // the read_confirms, if not then send GetMsgs contain the msg's hash
  186. if !self.unread_msgs.contains(&inv.hash).await {
  187. self.send_getmsgs(&inv.target, vec![inv.hash.clone()]).await?;
  188. } else if let Some(msg) = self.unread_msgs.inc_read_confirms(&inv.hash).await {
  189. self.new_msg(&msg).await?;
  190. }
  191. // Either way, broadcast the inv msg
  192. self.p2p.broadcast_with_exclude(inv, &exclude_list).await?;
  193. }
  194. }
  195. async fn handle_receive_msg(self: Arc<Self>) -> Result<()> {
  196. debug!(target: "ircd", "ProtocolPrivmsg::handle_receive_msg() [START]");
  197. let exclude_list = vec![self.channel.address()];
  198. loop {
  199. let msg = self.msg_sub.receive().await?;
  200. let mut msg = (*msg).to_owned();
  201. if !self.seen_ids.push(&msg.id).await {
  202. continue
  203. }
  204. // If the msg has read_confirms greater or equal to MAX_CONFIRM, it will be added to
  205. // the chains, otherwise increase the msg's read_confirms, add it to unread_msgs, and
  206. // broadcast an Inv msg contain the hash of the message
  207. if msg.read_confirms >= settings::MAX_CONFIRM {
  208. self.new_msg(&msg).await?;
  209. } else {
  210. msg.read_confirms += 1;
  211. self.unread_msgs.insert(&msg).await;
  212. self.send_inv_msg(&msg).await?;
  213. }
  214. // Broadcast the msg
  215. self.p2p.broadcast_with_exclude(msg, &exclude_list).await?;
  216. }
  217. }
  218. async fn handle_receive_getmsgs(self: Arc<Self>) -> Result<()> {
  219. debug!(target: "ircd", "ProtocolPrivmsg::handle_receive_getmsgs() [START]");
  220. loop {
  221. let getmsgs = self.getmsgs_sub.receive().await?;
  222. // Load the msgs from the chains, and send them back to the sender
  223. let msgs = self.chains.get_msgs(&getmsgs.target, &getmsgs.invs).await;
  224. for msg in msgs {
  225. self.channel.send(msg.clone()).await?;
  226. }
  227. }
  228. }
  229. async fn handle_receive_hashes(self: Arc<Self>) -> Result<()> {
  230. debug!(target: "ircd", "ProtocolPrivmsg::handle_receive_hashes() [START]");
  231. loop {
  232. let hashmsg = self.hashes_sub.receive().await?;
  233. self.chains
  234. .push_hashes(hashmsg.target.clone(), hashmsg.height, hashmsg.hashes.clone())
  235. .await;
  236. }
  237. }
  238. async fn handle_receive_synchash(self: Arc<Self>) -> Result<()> {
  239. debug!(target: "ircd", "ProtocolPrivmsg::handle_receive_synchash() [START]");
  240. loop {
  241. let synchash = self.synchash_sub.receive().await?;
  242. if synchash.height < self.chains.get_height(&synchash.target).await {
  243. let hashes = self.chains.get_hashes(&synchash.target, synchash.height + 1).await;
  244. // send the hashes from the chain
  245. self.channel
  246. .send(Hashes {
  247. target: synchash.target.clone(),
  248. height: synchash.height + 1,
  249. hashes: hashes.clone(),
  250. })
  251. .await?;
  252. // send the msgs from the chain's buffer
  253. let msgs = self.chains.get_msgs(&synchash.target, &hashes).await;
  254. for msg in msgs {
  255. self.channel.send(msg).await?;
  256. }
  257. }
  258. }
  259. }
  260. // every 2 seconds send a SyncHash msg, contain the last_height for each chain
  261. async fn send_sync_hash_loop(self: Arc<Self>) -> Result<()> {
  262. loop {
  263. // TODO loop through preconfigured channels
  264. let height = self.chains.get_height("").await;
  265. self.channel.send(SyncHash { target: "".to_string(), height }).await?;
  266. sleep(2).await;
  267. }
  268. }
  269. async fn new_msg(&self, msg: &Privmsg) -> Result<()> {
  270. if self.chains.push_msg(msg).await {
  271. self.notify.send(msg.clone()).await?;
  272. }
  273. Ok(())
  274. }
  275. async fn send_inv_msg(&self, msg: &Privmsg) -> Result<()> {
  276. let inv_id = OsRng.next_u64().to_string();
  277. self.p2p
  278. .broadcast(Inv { id: inv_id, hash: msg.id.clone(), target: msg.target.clone() })
  279. .await?;
  280. Ok(())
  281. }
  282. async fn send_getmsgs(&self, target: &str, hashes: Vec<String>) -> Result<()> {
  283. self.channel.send(GetMsgs { target: target.to_string(), invs: hashes }).await?;
  284. Ok(())
  285. }
  286. }
  287. #[async_trait]
  288. impl net::ProtocolBase for ProtocolPrivmsg {
  289. /// Starts ping-pong keep-alive messages exchange. Runs ping-pong in the
  290. /// protocol task manager, then queues the reply. Sends out a ping and
  291. /// waits for pong reply. Waits for ping and replies with a pong.
  292. async fn start(self: Arc<Self>, executor: Arc<Executor<'_>>) -> Result<()> {
  293. debug!(target: "ircd", "ProtocolPrivmsg::start() [START]");
  294. self.jobsman.clone().start(executor.clone());
  295. self.jobsman.clone().spawn(self.clone().handle_receive_msg(), executor.clone()).await;
  296. self.jobsman.clone().spawn(self.clone().handle_receive_inv(), executor.clone()).await;
  297. self.jobsman.clone().spawn(self.clone().handle_receive_getmsgs(), executor.clone()).await;
  298. self.jobsman.clone().spawn(self.clone().handle_receive_hashes(), executor.clone()).await;
  299. self.jobsman.clone().spawn(self.clone().handle_receive_synchash(), executor.clone()).await;
  300. self.jobsman.clone().spawn(self.clone().send_sync_hash_loop(), executor.clone()).await;
  301. debug!(target: "ircd", "ProtocolPrivmsg::start() [END]");
  302. Ok(())
  303. }
  304. fn name(&self) -> &'static str {
  305. "ProtocolPrivmsg"
  306. }
  307. }
  308. impl net::Message for Privmsg {
  309. fn name() -> &'static str {
  310. "privmsg"
  311. }
  312. }
  313. impl net::Message for Inv {
  314. fn name() -> &'static str {
  315. "inv"
  316. }
  317. }
  318. impl net::Message for GetMsgs {
  319. fn name() -> &'static str {
  320. "getmsgs"
  321. }
  322. }
  323. impl net::Message for Hashes {
  324. fn name() -> &'static str {
  325. "hashes"
  326. }
  327. }
  328. impl net::Message for SyncHash {
  329. fn name() -> &'static str {
  330. "synchash"
  331. }
  332. }