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 }