/ node / sync / src / block_sync / metrics.rs
metrics.rs
 1  // Copyright (c) 2025-2026 ACDC Network
 2  // This file is part of the alphaos library.
 3  //
 4  // Alpha Chain | Delta Chain Protocol
 5  // International Monetary Graphite.
 6  //
 7  // Derived from Aleo (https://aleo.org) and ProvableHQ (https://provable.com).
 8  // They built world-class ZK infrastructure. We installed the EASY button.
 9  // Their cryptography: elegant. Our modifications: bureaucracy-compatible.
10  // Original brilliance: theirs. Robert's Rules: ours. Bugs: definitely ours.
11  //
12  // Original Aleo/ProvableHQ code subject to Apache 2.0 https://www.apache.org/licenses/LICENSE-2.0
13  // All modifications and new work: CC0 1.0 Universal Public Domain Dedication.
14  // No rights reserved. No permission required. No warranty. No refunds.
15  //
16  // https://creativecommons.org/publicdomain/zero/1.0/
17  // SPDX-License-Identifier: CC0-1.0
18  
19  use std::{
20      collections::VecDeque,
21      time::{Duration, Instant},
22  };
23  
24  #[cfg(feature = "locktick")]
25  use locktick::parking_lot::Mutex;
26  
27  #[cfg(not(feature = "locktick"))]
28  use parking_lot::Mutex;
29  
30  #[derive(Default)]
31  struct SyncMetricsData {
32      /// The number of block requests completed since the last update.
33      completed_requests: VecDeque<Instant>,
34  
35      /// The current sync speed
36      sync_speed: f64,
37  }
38  
39  #[derive(Default)]
40  pub struct BlockSyncMetrics {
41      data: Mutex<SyncMetricsData>,
42  }
43  
44  impl BlockSyncMetrics {
45      /// Sync speed is calculated on a sliding window.
46      const METRIC_WINDOW: Duration = Duration::from_secs(60);
47  
48      /// Updates the sync speed and returns the new value.
49      pub fn get_sync_speed(&self) -> f64 {
50          let mut data = self.data.lock();
51  
52          // Remove requests that are past the sliding window.
53          while let Some(time) = data.completed_requests.front() {
54              if time.elapsed() > Self::METRIC_WINDOW {
55                  data.completed_requests.pop_front();
56              } else {
57                  break;
58              }
59          }
60  
61          // Update sync speed based on the last minute.
62          data.sync_speed = data.completed_requests.len() as f64 / Self::METRIC_WINDOW.as_secs_f64();
63  
64          data.sync_speed
65      }
66  
67      pub fn count_request_completed(&self) {
68          let mut data = self.data.lock();
69  
70          // Remove requests that are past the sliding window.
71          while let Some(time) = data.completed_requests.front() {
72              if time.elapsed() > Self::METRIC_WINDOW {
73                  data.completed_requests.pop_front();
74              } else {
75                  break;
76              }
77          }
78  
79          // Add time for the new request.
80          data.completed_requests.push_back(Instant::now());
81      }
82  
83      pub fn mark_fully_synced(&self) {
84          // Set speed to zero because it otherwise only gets updated during sync.
85          // Keep request data, in case we resume syncing.
86          self.data.lock().sync_speed = 0.0;
87      }
88  }