proto.rs 32 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793
  1. /* This file is part of DarkFi (https://dark.fi)
  2. *
  3. * Copyright (C) 2020-2026 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::{
  19. collections::{BTreeMap, HashSet, VecDeque},
  20. slice,
  21. str::FromStr,
  22. sync::{
  23. atomic::{AtomicUsize, Ordering::SeqCst},
  24. Arc,
  25. },
  26. };
  27. use darkfi_serial::{async_trait, deserialize_async, SerialDecodable, SerialEncodable};
  28. use smol::Executor;
  29. use tracing::{debug, error, trace, warn};
  30. use super::{event::Header, Event, EventGraphPtr, LayerUTips, NULL_ID, NULL_PARENTS};
  31. use crate::{
  32. impl_p2p_message,
  33. net::{
  34. metering::{MeteringConfiguration, DEFAULT_METERING_CONFIGURATION},
  35. ChannelPtr, Message, MessageSubscription, ProtocolBase, ProtocolBasePtr,
  36. ProtocolJobsManager, ProtocolJobsManagerPtr,
  37. },
  38. system::msleep,
  39. util::time::NanoTimestamp,
  40. Error, Result,
  41. };
  42. /// Malicious behaviour threshold. If the threshold is reached, we will
  43. /// drop the peer from our P2P connection.
  44. const MALICIOUS_THRESHOLD: usize = 5;
  45. /// Global limit of messages per window
  46. const WINDOW_MAXSIZE: usize = 200;
  47. /// Rolling length of the window
  48. const WINDOW_EXPIRY_TIME: NanoTimestamp = NanoTimestamp::from_secs(60);
  49. /// Rolling length of the window
  50. const RATELIMIT_EXPIRY_TIME: NanoTimestamp = NanoTimestamp::from_secs(10);
  51. /// Ratelimit kicks in above this count
  52. const RATELIMIT_MIN_COUNT: usize = 6;
  53. /// Sample point used to calculate sleep time when ratelimit is active
  54. const RATELIMIT_SAMPLE_IDX: usize = 10;
  55. /// Sleep for this amount of time when `count == RATE_LIMIT_SAMPLE_IDX`.
  56. const RATELIMIT_SAMPLE_SLEEP: usize = 1000;
  57. struct MovingWindow {
  58. times: VecDeque<NanoTimestamp>,
  59. expiry_time: NanoTimestamp,
  60. }
  61. impl MovingWindow {
  62. fn new(expiry_time: NanoTimestamp) -> Self {
  63. Self { times: VecDeque::new(), expiry_time }
  64. }
  65. /// Clean out expired timestamps from the window.
  66. fn clean(&mut self) {
  67. while let Some(ts) = self.times.front() {
  68. let Ok(elapsed) = ts.elapsed() else {
  69. debug!(target: "event_graph::protocol::MovingWindow::clean", "Timestamp [{ts}] is in future. Removing...");
  70. let _ = self.times.pop_front();
  71. continue
  72. };
  73. if elapsed < self.expiry_time {
  74. break
  75. }
  76. let _ = self.times.pop_front();
  77. }
  78. }
  79. /// Add new timestamp
  80. fn ticktock(&mut self) {
  81. self.clean();
  82. self.times.push_back(NanoTimestamp::current_time());
  83. }
  84. #[inline]
  85. fn count(&self) -> usize {
  86. self.times.len()
  87. }
  88. }
  89. /// P2P protocol implementation for the Event Graph.
  90. pub struct ProtocolEventGraph {
  91. /// Pointer to the connected peer
  92. channel: ChannelPtr,
  93. /// Pointer to the Event Graph instance
  94. event_graph: EventGraphPtr,
  95. /// `MessageSubscriber` for `EventPut`
  96. ev_put_sub: MessageSubscription<EventPut>,
  97. /// `MessageSubscriber` for `EventReq`
  98. ev_req_sub: MessageSubscription<EventReq>,
  99. /// `MessageSubscriber` for `EventRep`
  100. ev_rep_sub: MessageSubscription<EventRep>,
  101. /// `MessageSubscriber` for `HeaderPut`
  102. _hdr_put_sub: MessageSubscription<HeaderPut>,
  103. /// `MessageSubscriber` for `HeaderReq`
  104. hdr_req_sub: MessageSubscription<HeaderReq>,
  105. /// `MessageSubscriber` for `HeaderRep`
  106. _hdr_rep_sub: MessageSubscription<HeaderRep>,
  107. /// `MessageSubscriber` for `TipReq`
  108. tip_req_sub: MessageSubscription<TipReq>,
  109. /// `MessageSubscriber` for `TipRep`
  110. _tip_rep_sub: MessageSubscription<TipRep>,
  111. /// Peer malicious message count
  112. malicious_count: AtomicUsize,
  113. /// P2P jobs manager pointer
  114. jobsman: ProtocolJobsManagerPtr,
  115. /// To apply the rate-limit, we don't broadcast directly but instead send into the
  116. /// sending queue.
  117. broadcaster_push: smol::channel::Sender<EventPut>,
  118. /// Receive send requests and rate-limit broadcasting them.
  119. broadcaster_pull: smol::channel::Receiver<EventPut>,
  120. }
  121. /// A P2P message representing publishing an event on the network
  122. #[derive(Clone, SerialEncodable, SerialDecodable)]
  123. pub struct EventPut(pub Event);
  124. impl_p2p_message!(EventPut, "EventGraph::EventPut", 0, 0, DEFAULT_METERING_CONFIGURATION);
  125. /// A P2P message representing an event request
  126. #[derive(Clone, SerialEncodable, SerialDecodable)]
  127. pub struct EventReq(pub Vec<blake3::Hash>);
  128. impl_p2p_message!(EventReq, "EventGraph::EventReq", 0, 0, DEFAULT_METERING_CONFIGURATION);
  129. /// A P2P message representing an event reply
  130. #[derive(Clone, SerialEncodable, SerialDecodable)]
  131. pub struct EventRep(pub Vec<Event>);
  132. impl_p2p_message!(EventRep, "EventGraph::EventRep", 0, 0, DEFAULT_METERING_CONFIGURATION);
  133. /// A P2P message representing publishing an event's header on the network
  134. #[derive(Clone, SerialEncodable, SerialDecodable)]
  135. pub struct HeaderPut(pub Header);
  136. impl_p2p_message!(HeaderPut, "EventGraph::HeaderPut", 0, 0, DEFAULT_METERING_CONFIGURATION);
  137. /// A P2P message representing a header request
  138. #[derive(Clone, SerialEncodable, SerialDecodable)]
  139. pub struct HeaderReq(pub String);
  140. impl_p2p_message!(HeaderReq, "EventGraph::HeaderReq", 0, 0, DEFAULT_METERING_CONFIGURATION);
  141. /// A P2P message representing a header reply
  142. #[derive(Clone, SerialEncodable, SerialDecodable)]
  143. pub struct HeaderRep(pub Vec<Header>);
  144. impl_p2p_message!(HeaderRep, "EventGraph::HeaderRep", 0, 0, DEFAULT_METERING_CONFIGURATION);
  145. /// A P2P message representing a request for a peer's DAG tips
  146. #[derive(Clone, SerialEncodable, SerialDecodable)]
  147. pub struct TipReq(pub String);
  148. impl_p2p_message!(TipReq, "EventGraph::TipReq", 0, 0, DEFAULT_METERING_CONFIGURATION);
  149. /// A P2P message representing a reply for the peer's DAG tips
  150. #[derive(Clone, SerialEncodable, SerialDecodable)]
  151. pub struct TipRep(pub LayerUTips);
  152. impl_p2p_message!(TipRep, "EventGraph::TipRep", 0, 0, DEFAULT_METERING_CONFIGURATION);
  153. #[async_trait]
  154. impl ProtocolBase for ProtocolEventGraph {
  155. async fn start(self: Arc<Self>, ex: Arc<Executor<'_>>) -> Result<()> {
  156. self.jobsman.clone().start(ex.clone());
  157. self.jobsman.clone().spawn(self.clone().handle_event_put(), ex.clone()).await;
  158. self.jobsman.clone().spawn(self.clone().handle_event_req(), ex.clone()).await;
  159. // self.jobsman.clone().spawn(self.clone().handle_header_put(), ex.clone()).await;
  160. // self.jobsman.clone().spawn(self.clone().handle_header_req(), ex.clone()).await;
  161. self.jobsman.clone().spawn(self.clone().handle_header_req(), ex.clone()).await;
  162. self.jobsman.clone().spawn(self.clone().handle_tip_req(), ex.clone()).await;
  163. self.jobsman.clone().spawn(self.clone().broadcast_rate_limiter(), ex.clone()).await;
  164. Ok(())
  165. }
  166. fn name(&self) -> &'static str {
  167. "ProtocolEventGraph"
  168. }
  169. }
  170. impl ProtocolEventGraph {
  171. pub async fn init(event_graph: EventGraphPtr, channel: ChannelPtr) -> Result<ProtocolBasePtr> {
  172. let msg_subsystem = channel.message_subsystem();
  173. msg_subsystem.add_dispatch::<EventPut>().await;
  174. msg_subsystem.add_dispatch::<EventReq>().await;
  175. msg_subsystem.add_dispatch::<EventRep>().await;
  176. msg_subsystem.add_dispatch::<HeaderPut>().await;
  177. msg_subsystem.add_dispatch::<HeaderReq>().await;
  178. msg_subsystem.add_dispatch::<HeaderRep>().await;
  179. msg_subsystem.add_dispatch::<TipReq>().await;
  180. msg_subsystem.add_dispatch::<TipRep>().await;
  181. let ev_put_sub = channel.subscribe_msg::<EventPut>().await?;
  182. let ev_req_sub = channel.subscribe_msg::<EventReq>().await?;
  183. let ev_rep_sub = channel.subscribe_msg::<EventRep>().await?;
  184. let _hdr_put_sub = channel.subscribe_msg::<HeaderPut>().await?;
  185. let hdr_req_sub = channel.subscribe_msg::<HeaderReq>().await?;
  186. let _hdr_rep_sub = channel.subscribe_msg::<HeaderRep>().await?;
  187. let tip_req_sub = channel.subscribe_msg::<TipReq>().await?;
  188. let _tip_rep_sub = channel.subscribe_msg::<TipRep>().await?;
  189. let (broadcaster_push, broadcaster_pull) = smol::channel::unbounded();
  190. Ok(Arc::new(Self {
  191. channel: channel.clone(),
  192. event_graph,
  193. ev_put_sub,
  194. ev_req_sub,
  195. ev_rep_sub,
  196. _hdr_put_sub,
  197. hdr_req_sub,
  198. _hdr_rep_sub,
  199. tip_req_sub,
  200. _tip_rep_sub,
  201. malicious_count: AtomicUsize::new(0),
  202. jobsman: ProtocolJobsManager::new("ProtocolEventGraph", channel.clone()),
  203. broadcaster_push,
  204. broadcaster_pull,
  205. }))
  206. }
  207. async fn increase_malicious_count(self: Arc<Self>) -> Result<()> {
  208. let malicious_count = self.malicious_count.fetch_add(1, SeqCst);
  209. if malicious_count + 1 == MALICIOUS_THRESHOLD {
  210. error!(
  211. target: "event_graph::protocol::handle_event_put",
  212. "[EVENTGRAPH] Peer {} reached malicious threshold. Dropping connection.",
  213. self.channel.display_address(),
  214. );
  215. self.channel.stop().await;
  216. return Err(Error::ChannelStopped)
  217. }
  218. warn!(
  219. target: "event_graph::protocol::handle_event_put",
  220. "[EVENTGRAPH] Peer {} sent us a malicious event", self.channel.display_address(),
  221. );
  222. Ok(())
  223. }
  224. /// Protocol function handling `EventPut`.
  225. /// This is triggered whenever someone broadcasts (or relays) a new
  226. /// event on the network.
  227. async fn handle_event_put(self: Arc<Self>) -> Result<()> {
  228. // Rolling window of event timestamps on this channel
  229. let mut bantimes = MovingWindow::new(WINDOW_EXPIRY_TIME);
  230. loop {
  231. let event = match self.ev_put_sub.receive().await {
  232. Ok(v) => v.0.clone(),
  233. Err(_) => continue,
  234. };
  235. trace!(
  236. target: "event_graph::protocol::handle_event_put",
  237. "Got EventPut: {} [{}]", event.id(), self.channel.display_address(),
  238. );
  239. // Check if node has finished syncing its DAG
  240. if !*self.event_graph.synced.read().await {
  241. debug!(
  242. target: "event_graph::protocol::handle_event_put",
  243. "DAG is still syncing, skipping..."
  244. );
  245. continue
  246. }
  247. // If we have already seen the event, we'll stay quiet.
  248. let current_genesis = self.event_graph.current_genesis.read().await;
  249. let dag_name = current_genesis.header.timestamp.to_string();
  250. let hdr_tree_name = format!("headers_{dag_name}");
  251. let event_id = event.id();
  252. if self
  253. .event_graph
  254. .dag_store
  255. .read()
  256. .await
  257. .get_dag(&hdr_tree_name)
  258. .contains_key(event_id.as_bytes())
  259. .unwrap()
  260. {
  261. debug!(
  262. target: "event_graph::protocol::handle_event_put",
  263. "Event {event_id} is already known"
  264. );
  265. continue
  266. }
  267. // There's a new unique event.
  268. // Apply ban logic to stop network floods.
  269. bantimes.ticktock();
  270. if bantimes.count() > WINDOW_MAXSIZE {
  271. self.channel.ban().await;
  272. // This error is actually unused. We could return Ok here too.
  273. return Err(Error::MaliciousFlood)
  274. }
  275. // We received an event. Check if we already have it in our DAG.
  276. // Check event is not older that current genesis event timestamp.
  277. // Also check if we have the event's parents. In the case we do
  278. // not have the parents, we'll request them from the peer that has
  279. // sent this event to us. In case they do not reply in time, we drop
  280. // the event.
  281. // Check if the event is older than the genesis event. If so, we should
  282. // not include it in our Dag.
  283. // The genesis event marks the last time the Dag has been pruned of old
  284. // events. The pruning interval is defined by the days_rotation field
  285. // of [`EventGraph`].
  286. let genesis_timestamp = self.event_graph.current_genesis.read().await.header.timestamp;
  287. if event.header.timestamp < genesis_timestamp {
  288. debug!(
  289. target: "event_graph::protocol::handle_event_put",
  290. "Event {} is older than genesis. Event timestamp: `{}`. Genesis timestamp: `{genesis_timestamp}`",
  291. event.id(), event.header.timestamp
  292. );
  293. }
  294. // Validate the new event first. If we do not consider it valid, we
  295. // will just drop it and stay quiet. If the malicious threshold
  296. // is reached, we will stop the connection.
  297. if !event.validate_new() {
  298. self.clone().increase_malicious_count().await?;
  299. continue
  300. }
  301. // At this point, this is a new event to us. Let's see if we
  302. // have all of its parents.
  303. debug!(
  304. target: "event_graph::protocol::handle_event_put",
  305. "Event {event_id} is new"
  306. );
  307. let mut missing_parents = HashSet::new();
  308. for parent_id in event.header.parents.iter() {
  309. // `event.validate_new()` should have already made sure that
  310. // not all parents are NULL, and that there are no duplicates.
  311. if parent_id == &NULL_ID {
  312. continue
  313. }
  314. if !self
  315. .event_graph
  316. .dag_store
  317. .read()
  318. .await
  319. .get_dag(&hdr_tree_name)
  320. .contains_key(parent_id.as_bytes())
  321. .unwrap()
  322. {
  323. missing_parents.insert(*parent_id);
  324. }
  325. }
  326. // If we have missing parents, then we have to attempt to
  327. // fetch them from this peer. Do this recursively until we
  328. // find all of them.
  329. if !missing_parents.is_empty() {
  330. // We track the received events mapped by their layer.
  331. // If/when we get all of them, we need to insert them in order so
  332. // the DAG state stays correct and unreferenced tips represent the
  333. // actual thing they should. If we insert them out of order, then
  334. // we might have wrong unreferenced tips.
  335. let mut received_events: BTreeMap<u64, Vec<Event>> = BTreeMap::new();
  336. let mut received_events_hashes = HashSet::new();
  337. debug!(
  338. target: "event_graph::protocol::handle_event_put",
  339. "Event has {} missing parents. Requesting...", missing_parents.len(),
  340. );
  341. let current_genesis = self.event_graph.current_genesis.read().await;
  342. let dag_name = current_genesis.header.timestamp.to_string();
  343. let hdr_tree_name = format!("headers_{dag_name}");
  344. while !missing_parents.is_empty() {
  345. // for parent_id in missing_parents.clone().iter() {
  346. debug!(
  347. target: "event_graph::protocol::handle_event_put",
  348. "Requesting {missing_parents:?}..."
  349. );
  350. self.channel
  351. .send(&EventReq(missing_parents.clone().into_iter().collect()))
  352. .await?;
  353. let outbound_connect_timeout = self
  354. .event_graph
  355. .p2p
  356. .settings()
  357. .read_arc()
  358. .await
  359. .outbound_connect_timeout(self.channel.address().scheme());
  360. // Node waits for response
  361. let Ok(parents) =
  362. self.ev_rep_sub.receive_with_timeout(outbound_connect_timeout).await
  363. else {
  364. error!(
  365. target: "event_graph::protocol::handle_event_put",
  366. "[EVENTGRAPH] Timeout while waiting for parents {missing_parents:?} from {}",
  367. self.channel.display_address(),
  368. );
  369. self.channel.stop().await;
  370. return Err(Error::ChannelStopped)
  371. };
  372. let parents = parents.0.clone();
  373. for parent in parents {
  374. let parent_id = parent.id();
  375. if !missing_parents.contains(&parent_id) {
  376. error!(
  377. target: "event_graph::protocol::handle_event_put",
  378. "[EVENTGRAPH] Peer {} replied with a wrong event: {}",
  379. self.channel.display_address(), parent.id(),
  380. );
  381. self.channel.stop().await;
  382. return Err(Error::ChannelStopped)
  383. }
  384. debug!(
  385. target: "event_graph::protocol::handle_event_put",
  386. "Got correct parent event {}", parent.id(),
  387. );
  388. if let Some(layer_events) = received_events.get_mut(&parent.header.layer) {
  389. layer_events.push(parent.clone());
  390. } else {
  391. let layer_events = vec![parent.clone()];
  392. received_events.insert(parent.header.layer, layer_events);
  393. }
  394. received_events_hashes.insert(parent_id);
  395. missing_parents.remove(&parent_id);
  396. // See if we have the upper parents
  397. for upper_parent in parent.header.parents.iter() {
  398. if upper_parent == &NULL_ID {
  399. continue
  400. }
  401. if !missing_parents.contains(upper_parent) &&
  402. !received_events_hashes.contains(upper_parent) &&
  403. !self
  404. .event_graph
  405. .dag_store
  406. .read()
  407. .await
  408. .get_dag(&hdr_tree_name)
  409. .contains_key(upper_parent.as_bytes())
  410. .unwrap()
  411. {
  412. debug!(
  413. target: "event_graph::protocol::handle_event_put",
  414. "Found upper missing parent event {upper_parent}"
  415. );
  416. missing_parents.insert(*upper_parent);
  417. }
  418. }
  419. }
  420. } // <-- while !missing_parents.is_empty()
  421. // At this point we should've got all the events.
  422. // We should add them to the DAG.
  423. let mut events = vec![];
  424. for (_, tips) in received_events {
  425. for tip in tips {
  426. events.push(tip);
  427. }
  428. }
  429. let headers = events.iter().map(|x| x.header.clone()).collect();
  430. if self.event_graph.header_dag_insert(headers, &dag_name).await.is_err() {
  431. self.clone().increase_malicious_count().await?;
  432. continue
  433. }
  434. // FIXME
  435. if !self.event_graph.fast_mode {
  436. if self.event_graph.dag_insert(&events, &dag_name).await.is_err() {
  437. self.clone().increase_malicious_count().await?;
  438. continue
  439. }
  440. }
  441. } // <-- !missing_parents.is_empty()
  442. // If we're here, we have all the parents, and we can now
  443. // perform a full validation and add the actual event to
  444. // the DAG.
  445. debug!(
  446. target: "event_graph::protocol::handle_event_put",
  447. "Got all parents necessary for insertion",
  448. );
  449. if self
  450. .event_graph
  451. .header_dag_insert(vec![event.header.clone()], &dag_name)
  452. .await
  453. .is_err()
  454. {
  455. self.clone().increase_malicious_count().await?;
  456. continue
  457. }
  458. if self.event_graph.dag_insert(slice::from_ref(&event), &dag_name).await.is_err() {
  459. self.clone().increase_malicious_count().await?;
  460. continue
  461. }
  462. self.broadcaster_push.send(EventPut(event)).await.expect("push broadcaster closed");
  463. }
  464. }
  465. /// Protocol function handling `EventReq`.
  466. /// This is triggered whenever someone requests an event from us.
  467. async fn handle_event_req(self: Arc<Self>) -> Result<()> {
  468. loop {
  469. let event_ids = match self.ev_req_sub.receive().await {
  470. Ok(v) => v.0.clone(),
  471. Err(_) => continue,
  472. };
  473. trace!(
  474. target: "event_graph::protocol::handle_event_req",
  475. "Got EventReq: {event_ids:?} [{}]", self.channel.display_address(),
  476. );
  477. // Check if node has finished syncing its DAG
  478. if !*self.event_graph.synced.read().await {
  479. debug!(
  480. target: "event_graph::protocol::handle_event_req",
  481. "DAG is still syncing, skipping..."
  482. );
  483. continue
  484. }
  485. // We received an event request from somebody.
  486. // If we do have it, we will send it back to them as `EventRep`.
  487. // Otherwise, we'll stay quiet. An honest node should always have
  488. // something to reply with provided that the request is legitimate,
  489. // i.e. we've sent something to them and they did not have some of
  490. // the parents.
  491. // Check if we expected this request to come around.
  492. // I dunno if this is a good idea, but it seems it will help
  493. // against malicious event requests where they want us to keep
  494. // reading our db and steal our bandwidth.
  495. let mut events = vec![];
  496. for event_id in event_ids.iter() {
  497. if let Ok(event) = self
  498. .event_graph
  499. .fetch_event_from_dags(event_id)
  500. .await?
  501. .ok_or(Error::EventNotFound("The requested event is not found".to_owned()))
  502. {
  503. // At this point we should have it in our DAG.
  504. // This code panics if this is not the case.
  505. debug!(
  506. target: "event_graph::protocol::handle_event_req()",
  507. "Fetching event {:?} from DAG", event_id,
  508. );
  509. events.push(event);
  510. } else {
  511. let malicious_count = self.malicious_count.fetch_add(1, SeqCst);
  512. if malicious_count + 1 == MALICIOUS_THRESHOLD {
  513. error!(
  514. target: "event_graph::protocol::handle_event_req",
  515. "[EVENTGRAPH] Peer {} reached malicious threshold. Dropping connection.",
  516. self.channel.display_address(),
  517. );
  518. self.channel.stop().await;
  519. return Err(Error::ChannelStopped)
  520. }
  521. warn!(
  522. target: "event_graph::protocol::handle_event_req",
  523. "[EVENTGRAPH] Peer {} requested an unexpected event {event_id:?}",
  524. self.channel.display_address()
  525. );
  526. continue
  527. }
  528. }
  529. // Check if the incoming event is older than the genesis event. If so, something
  530. // has gone wrong. The event should have been pruned during the last
  531. // rotation.
  532. let genesis_timestamp = self.event_graph.current_genesis.read().await.header.timestamp;
  533. let mut bcast_ids = self.event_graph.broadcasted_ids.write().await;
  534. for event in events.iter() {
  535. if event.header.timestamp < genesis_timestamp {
  536. error!(
  537. target: "event_graph::protocol::handle_event_req",
  538. "Requested event by peer {} is older than previous rotation period. It should have been pruned.
  539. Event timestamp: `{}`. Genesis timestamp: `{genesis_timestamp}`",
  540. event.id(), event.header.timestamp
  541. );
  542. }
  543. // Now let's get the upper level of event IDs. When we reply, we could
  544. // get requests for those IDs as well.
  545. for parent_id in event.header.parents.iter() {
  546. if parent_id != &NULL_ID {
  547. bcast_ids.insert(*parent_id);
  548. }
  549. }
  550. }
  551. // TODO: We should remove the reply from the bcast IDs for this specific channel.
  552. // We can't remove them for everyone.
  553. //bcast_ids.remove(&event_id);
  554. drop(bcast_ids);
  555. // Reply with the event
  556. self.channel.send(&EventRep(events)).await?;
  557. }
  558. }
  559. /// Protocol function handling `HeaderReq`.
  560. /// This is triggered whenever someone requests syncing headers by
  561. /// sending their current headers.
  562. async fn handle_header_req(self: Arc<Self>) -> Result<()> {
  563. loop {
  564. let dag_name = match self.hdr_req_sub.receive().await {
  565. Ok(v) => v.0.clone(),
  566. Err(_) => continue,
  567. };
  568. trace!(
  569. target: "event_graph::protocol::handle_tip_req",
  570. "Got TipReq [{}]", self.channel.display_address(),
  571. );
  572. // Check if node has finished syncing its DAG
  573. if !*self.event_graph.synced.read().await {
  574. debug!(
  575. target: "event_graph::protocol::handle_tip_req",
  576. "DAG is still syncing, skipping..."
  577. );
  578. continue
  579. }
  580. // TODO: Rate limit
  581. // We received header request. Let's find them, add them to
  582. // our bcast ids list, and reply with them.
  583. let dag_timestamp = u64::from_str(&dag_name)?;
  584. let store = self.event_graph.dag_store.read().await;
  585. if !store.header_dags.contains_key(&dag_timestamp) {
  586. continue
  587. }
  588. let main_dag = store.get_dag(&dag_name);
  589. let mut headers = vec![];
  590. for item in main_dag.iter() {
  591. let (_, event) = item.unwrap();
  592. let event: Event = deserialize_async(&event).await.unwrap();
  593. if !headers.contains(&event.header) || event.header.parents != NULL_PARENTS {
  594. headers.push(event.header);
  595. }
  596. }
  597. // let mut bcast_ids = self.event_graph.broadcasted_ids.write().await;
  598. // for (_, tips) in layers.iter() {
  599. // for tip in tips {
  600. // bcast_ids.insert(*tip);
  601. // }
  602. // }
  603. // drop(bcast_ids);
  604. self.channel.send(&HeaderRep(headers)).await?;
  605. }
  606. // Ok(())
  607. }
  608. /// Protocol function handling `TipReq`.
  609. /// This is triggered when someone requests the current unreferenced
  610. /// tips of our DAG.
  611. async fn handle_tip_req(self: Arc<Self>) -> Result<()> {
  612. loop {
  613. let dag_name = match self.tip_req_sub.receive().await {
  614. Ok(v) => v.0.clone(),
  615. Err(_) => continue,
  616. };
  617. trace!(
  618. target: "event_graph::protocol::handle_tip_req",
  619. "Got TipReq [{}]", self.channel.display_address(),
  620. );
  621. // Check if node has finished syncing its DAG
  622. if !*self.event_graph.synced.read().await {
  623. debug!(
  624. target: "event_graph::protocol::handle_tip_req",
  625. "DAG is still syncing, skipping..."
  626. );
  627. continue
  628. }
  629. // TODO: Rate limit
  630. // We received a tip request. Let's find them, add them to
  631. // our bcast ids list, and reply with them.
  632. let dag_timestamp = u64::from_str(&dag_name)?;
  633. let store = self.event_graph.dag_store.read().await;
  634. let (_, layers) = match store.header_dags.get(&dag_timestamp) {
  635. Some(v) => v,
  636. None => continue,
  637. };
  638. // let layers = self.event_graph.dag_store.read().await.find_unreferenced_tips(&dag_name).await;
  639. let mut bcast_ids = self.event_graph.broadcasted_ids.write().await;
  640. for (_, tips) in layers.iter() {
  641. for tip in tips {
  642. bcast_ids.insert(*tip);
  643. }
  644. }
  645. drop(bcast_ids);
  646. self.channel.send(&TipRep(layers.clone())).await?;
  647. }
  648. }
  649. /// We need to rate limit message propagation so malicious nodes don't get us banned
  650. /// for flooding. We do that by aggregating messages here into a queue then apply
  651. /// rate limit logic before broadcasting.
  652. ///
  653. /// The rate limit logic is this:
  654. ///
  655. /// * If the count is less then RATELIMIT_MIN_COUNT then do nothing.
  656. /// * Otherwise sleep for `sleep_time` ms.
  657. ///
  658. /// To calculate the sleep time, we use the RATELIMIT_SAMPLE_* values.
  659. /// For example RATELIMIT_SAMPLE_IDX = 10, RATELIMIT_SAMPLE_SLEEP = 1000
  660. /// means that when N = 10, then sleep for 1000 ms.
  661. ///
  662. /// Let RATELIMIT_MIN_COUNT = 6, then here's a table of sleep times:
  663. ///
  664. /// | Count | Sleep Time / ms |
  665. /// |-------|-----------------|
  666. /// | 0 | 0 |
  667. /// | 4 | 0 |
  668. /// | 6 | 0 |
  669. /// | 10 | 1000 |
  670. /// | 14 | 2000 |
  671. /// | 18 | 3000 |
  672. ///
  673. /// So we use the sample to calculate a straight line from RATELIMIT_MIN_COUNT.
  674. async fn broadcast_rate_limiter(self: Arc<Self>) -> Result<()> {
  675. let mut ratelimit = MovingWindow::new(RATELIMIT_EXPIRY_TIME);
  676. loop {
  677. let event_put = self.broadcaster_pull.recv().await.expect("pull broadcaster closed");
  678. ratelimit.ticktock();
  679. if ratelimit.count() > RATELIMIT_MIN_COUNT {
  680. let sleep_time =
  681. ((ratelimit.count() - RATELIMIT_MIN_COUNT) * RATELIMIT_SAMPLE_SLEEP /
  682. (RATELIMIT_SAMPLE_IDX - RATELIMIT_MIN_COUNT)) as u64;
  683. debug!(
  684. target: "event_graph::protocol::broadcast_rate_limiter",
  685. "Activated rate limit: sleeping {sleep_time} ms [count={}]",
  686. ratelimit.count()
  687. );
  688. // Apply the ratelimit
  689. msleep(sleep_time).await;
  690. }
  691. // Relay the event to other peers.
  692. self.event_graph
  693. .p2p
  694. .broadcast_with_exclude(&event_put, &[self.channel.address().clone()])
  695. .await;
  696. }
  697. }
  698. }
  699. #[cfg(test)]
  700. mod test {
  701. use super::*;
  702. use std::time::UNIX_EPOCH;
  703. #[test]
  704. fn test_eventgraph_moving_window_clean_future() {
  705. let mut window = MovingWindow::new(NanoTimestamp::from_secs(60));
  706. let future = UNIX_EPOCH.elapsed().unwrap().as_secs() + 100;
  707. window.times.push_back(NanoTimestamp::from_secs(future.into()));
  708. window.clean();
  709. assert_eq!(window.count(), 0);
  710. }
  711. }