debugmsg.rs 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140
  1. /* This file is part of DarkFi (https://dark.fi)
  2. *
  3. * Copyright (C) 2020-2023 Dyne.org foundation
  4. *
  5. * This program is free software: you can redistribute it and/or modify
  6. * it under the terms of the GNU Affero General Public License as
  7. * published by the Free Software Foundation, either version 3 of the
  8. * License, or (at your option) any later version.
  9. *
  10. * This program is distributed in the hope that it will be useful,
  11. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  13. * GNU Affero General Public License for more details.
  14. *
  15. * You should have received a copy of the GNU Affero General Public License
  16. * along with this program. If not, see <https://www.gnu.org/licenses/>.
  17. */
  18. use std::sync::Arc;
  19. use async_channel::Sender;
  20. use async_executor::Executor;
  21. use async_std::sync::Mutex;
  22. use async_trait::async_trait;
  23. use fxhash::FxHashSet;
  24. use log::debug;
  25. use darkfi::{
  26. net,
  27. util::serial::{SerialDecodable, SerialEncodable},
  28. Result,
  29. };
  30. pub type DebugmsgId = u32;
  31. #[derive(Debug, Clone, SerialEncodable, SerialDecodable)]
  32. pub struct Debugmsg {
  33. pub id: DebugmsgId,
  34. pub message: String,
  35. }
  36. impl net::Message for Debugmsg {
  37. fn name() -> &'static str {
  38. "debugmsg"
  39. }
  40. }
  41. pub struct SeenDebugmsgIds {
  42. ids: Mutex<FxHashSet<DebugmsgId>>,
  43. }
  44. pub type SeenDebugmsgIdsPtr = Arc<SeenDebugmsgIds>;
  45. impl SeenDebugmsgIds {
  46. pub fn new() -> Arc<Self> {
  47. Arc::new(Self { ids: Mutex::new(FxHashSet::default()) })
  48. }
  49. pub async fn add_seen(&self, id: u32) {
  50. self.ids.lock().await.insert(id);
  51. }
  52. pub async fn is_seen(&self, id: u32) -> bool {
  53. self.ids.lock().await.contains(&id)
  54. }
  55. }
  56. pub struct ProtocolDebugmsg {
  57. notify_queue_sender: Sender<Arc<Debugmsg>>,
  58. debugmsg_sub: net::MessageSubscription<Debugmsg>,
  59. jobsman: net::ProtocolJobsManagerPtr,
  60. seen_ids: SeenDebugmsgIdsPtr,
  61. p2p: net::P2pPtr,
  62. }
  63. #[async_trait]
  64. impl net::ProtocolBase for ProtocolDebugmsg {
  65. /// Starts ping-pong keep-alive messages exchange. Runs ping-pong in the
  66. /// protocol task manager, then queues the reply. Sends out a ping and
  67. /// waits for pong reply. Waits for ping and replies with a pong.
  68. async fn start(self: Arc<Self>, executor: Arc<Executor<'_>>) -> Result<()> {
  69. debug!(target: "ircd", "Protocoldebugmsg::start() [START]");
  70. self.jobsman.clone().start(executor.clone());
  71. self.jobsman.clone().spawn(self.clone().handle_receive_debugmsg(), executor.clone()).await;
  72. debug!(target: "ircd", "ProtocolDebugmsg::start() [END]");
  73. Ok(())
  74. }
  75. fn name(&self) -> &'static str {
  76. "Protocoldebugmsg"
  77. }
  78. }
  79. impl ProtocolDebugmsg {
  80. pub async fn init(
  81. channel: net::ChannelPtr,
  82. notify_queue_sender: Sender<Arc<Debugmsg>>,
  83. seen_ids: SeenDebugmsgIdsPtr,
  84. p2p: net::P2pPtr,
  85. ) -> net::ProtocolBasePtr {
  86. let message_subsystem = channel.get_message_subsystem();
  87. message_subsystem.add_dispatch::<Debugmsg>().await;
  88. let sub = channel.subscribe_msg::<Debugmsg>().await.expect("Missing Debugmsg dispatcher!");
  89. Arc::new(Self {
  90. notify_queue_sender,
  91. debugmsg_sub: sub,
  92. jobsman: net::ProtocolJobsManager::new("DebugmsgProtocol", channel),
  93. seen_ids,
  94. p2p,
  95. })
  96. }
  97. async fn handle_receive_debugmsg(self: Arc<Self>) -> Result<()> {
  98. debug!(target: "ircd", "ProtocolDebugmsg::handle_receive_debugmsg() [START]");
  99. loop {
  100. let debugmsg = self.debugmsg_sub.receive().await?;
  101. debug!(target: "ircd", "ProtocolDebugmsg::handle_receive_debugmsg() received {:?}", debugmsg);
  102. // Do we already have this message?
  103. if self.seen_ids.is_seen(debugmsg.id).await {
  104. continue
  105. }
  106. self.seen_ids.add_seen(debugmsg.id).await;
  107. // If not, then broadcast to network.
  108. let debugmsg_copy = (*debugmsg).clone();
  109. self.p2p.broadcast(debugmsg_copy).await?;
  110. self.notify_queue_sender
  111. .send(debugmsg)
  112. .await
  113. .expect("notify_queue_sender send failed!");
  114. }
  115. }
  116. }