diff --git a/dash-spv-ffi/FFI_API.md b/dash-spv-ffi/FFI_API.md index 043c69396..0f890e08b 100644 --- a/dash-spv-ffi/FFI_API.md +++ b/dash-spv-ffi/FFI_API.md @@ -4,7 +4,7 @@ This document provides a comprehensive reference for all FFI (Foreign Function I **Auto-generated**: This documentation is automatically generated from the source code. Do not edit manually. -**Total Functions**: 66 +**Total Functions**: 64 ## Table of Contents @@ -125,7 +125,7 @@ Functions: 2 ### Utility Functions -Functions: 19 +Functions: 17 | Function | Description | Module | |----------|-------------|--------| @@ -135,7 +135,6 @@ Functions: 19 | `dash_spv_ffi_checkpoint_latest` | Get the latest checkpoint for the given network | checkpoints | | `dash_spv_ffi_checkpoints_between_heights` | Get all checkpoints between two heights (inclusive) | checkpoints | | `dash_spv_ffi_client_clear_storage` | Clear all persisted SPV storage (headers, filters, metadata, sync state) | client | -| `dash_spv_ffi_client_get_stats` | Get current runtime statistics for the SPV client | client | | `dash_spv_ffi_client_get_tip_hash` | Get the current chain tip hash (32 bytes) if available | client | | `dash_spv_ffi_client_get_tip_height` | Get the current chain tip height (absolute) | client | | `dash_spv_ffi_client_get_wallet_manager` | Get the wallet manager from the SPV client Returns a pointer to an... | client | @@ -143,7 +142,6 @@ Functions: 19 | `dash_spv_ffi_client_rescan_blockchain` | Request a rescan of the blockchain from a given height (not yet implemented) | client | | `dash_spv_ffi_enable_test_mode` | No description | utils | | `dash_spv_ffi_init_logging` | Initialize logging for the SPV library | utils | -| `dash_spv_ffi_spv_stats_destroy` | Destroy an `FFISpvStats` object returned by this crate | client | | `dash_spv_ffi_string_array_destroy` | Destroy an array of FFIString pointers (Vec<*mut FFIString>) and their contents | types | | `dash_spv_ffi_string_destroy` | No description | types | | `dash_spv_ffi_version` | No description | utils | @@ -978,22 +976,6 @@ Clear all persisted SPV storage (headers, filters, metadata, sync state). # Saf --- -#### `dash_spv_ffi_client_get_stats` - -```c -dash_spv_ffi_client_get_stats(client: *mut FFIDashSpvClient,) -> *mut FFISpvStats -``` - -**Description:** -Get current runtime statistics for the SPV client. # Safety - `client` must be a valid, non-null pointer. - -**Safety:** -- `client` must be a valid, non-null pointer. - -**Module:** `client` - ---- - #### `dash_spv_ffi_client_get_tip_hash` ```c @@ -1100,22 +1082,6 @@ Initialize logging for the SPV library. # Arguments - `level`: Log level string --- -#### `dash_spv_ffi_spv_stats_destroy` - -```c -dash_spv_ffi_spv_stats_destroy(stats: *mut FFISpvStats) -> () -``` - -**Description:** -Destroy an `FFISpvStats` object returned by this crate. # Safety - `stats` must be a pointer returned from this crate, or null. - -**Safety:** -- `stats` must be a pointer returned from this crate, or null. - -**Module:** `client` - ---- - #### `dash_spv_ffi_string_array_destroy` ```c @@ -1173,7 +1139,6 @@ Release a wallet manager obtained from `dash_spv_ffi_client_get_wallet_manager`. - `FFIClientConfig` - Client configuration - `FFISyncProgress` - Synchronization progress - `FFIDetailedSyncProgress` - Detailed sync progress -- `FFISpvStats` - SPV statistics - `FFITransaction` - Transaction information - `FFIUnconfirmedTransaction` - Unconfirmed transaction - `FFIEventCallbacks` - Event callback structure diff --git a/dash-spv-ffi/include/dash_spv_ffi.h b/dash-spv-ffi/include/dash_spv_ffi.h index 934b2597c..0edad000f 100644 --- a/dash-spv-ffi/include/dash_spv_ffi.h +++ b/dash-spv-ffi/include/dash_spv_ffi.h @@ -94,21 +94,6 @@ typedef struct FFIDetailedSyncProgress { int64_t sync_start_timestamp; } FFIDetailedSyncProgress; -typedef struct FFISpvStats { - uint32_t connected_peers; - uint32_t total_peers; - uint32_t header_height; - uint32_t filter_height; - uint64_t headers_downloaded; - uint64_t filter_headers_downloaded; - uint64_t filters_downloaded; - uint64_t filters_matched; - uint64_t blocks_processed; - uint64_t bytes_received; - uint64_t bytes_sent; - uint64_t uptime; -} FFISpvStats; - typedef void (*BlockCallback)(uint32_t height, const uint8_t (*hash)[32], void *user_data); typedef void (*TransactionCallback)(const uint8_t (*txid)[32], @@ -394,14 +379,6 @@ int32_t dash_spv_ffi_client_sync_to_tip_with_progress(struct FFIDashSpvClient *c */ struct FFISyncProgress *dash_spv_ffi_client_get_sync_progress(struct FFIDashSpvClient *client) ; -/** - * Get current runtime statistics for the SPV client. - * - * # Safety - * - `client` must be a valid, non-null pointer. - */ - struct FFISpvStats *dash_spv_ffi_client_get_stats(struct FFIDashSpvClient *client) ; - /** * Get the current chain tip hash (32 bytes) if available. * @@ -463,14 +440,6 @@ int32_t dash_spv_ffi_client_set_event_callbacks(struct FFIDashSpvClient *client, */ void dash_spv_ffi_sync_progress_destroy(struct FFISyncProgress *progress) ; -/** - * Destroy an `FFISpvStats` object returned by this crate. - * - * # Safety - * - `stats` must be a pointer returned from this crate, or null. - */ - void dash_spv_ffi_spv_stats_destroy(struct FFISpvStats *stats) ; - /** * Request a rescan of the blockchain from a given height (not yet implemented). * diff --git a/dash-spv-ffi/scripts/generate_ffi_docs.py b/dash-spv-ffi/scripts/generate_ffi_docs.py index 239ed43be..635fec438 100755 --- a/dash-spv-ffi/scripts/generate_ffi_docs.py +++ b/dash-spv-ffi/scripts/generate_ffi_docs.py @@ -268,7 +268,6 @@ def generate_markdown(functions: List[FFIFunction]) -> str: md.append("- `FFIClientConfig` - Client configuration") md.append("- `FFISyncProgress` - Synchronization progress") md.append("- `FFIDetailedSyncProgress` - Detailed sync progress") - md.append("- `FFISpvStats` - SPV statistics") md.append("- `FFITransaction` - Transaction information") md.append("- `FFIUnconfirmedTransaction` - Unconfirmed transaction") md.append("- `FFIEventCallbacks` - Event callback structure") diff --git a/dash-spv-ffi/src/client.rs b/dash-spv-ffi/src/client.rs index f5959d289..688531911 100644 --- a/dash-spv-ffi/src/client.rs +++ b/dash-spv-ffi/src/client.rs @@ -1,6 +1,6 @@ use crate::{ null_check, set_last_error, FFIClientConfig, FFIDetailedSyncProgress, FFIErrorCode, - FFIEventCallbacks, FFISpvStats, FFISyncProgress, FFIWalletManager, + FFIEventCallbacks, FFISyncProgress, FFIWalletManager, }; // Import wallet types from key-wallet-ffi use key_wallet_ffi::FFIWalletManager as KeyWalletFFIWalletManager; @@ -891,46 +891,6 @@ pub unsafe extern "C" fn dash_spv_ffi_client_get_sync_progress( } } -/// Get current runtime statistics for the SPV client. -/// -/// # Safety -/// - `client` must be a valid, non-null pointer. -#[no_mangle] -pub unsafe extern "C" fn dash_spv_ffi_client_get_stats( - client: *mut FFIDashSpvClient, -) -> *mut FFISpvStats { - null_check!(client, std::ptr::null_mut()); - - let client = &(*client); - let inner = client.inner.clone(); - - let result = client.runtime.block_on(async { - let spv_client = { - let mut guard = inner.lock().unwrap(); - match guard.take() { - Some(client) => client, - None => { - return Err(dash_spv::SpvError::Storage(dash_spv::StorageError::NotFound( - "Client not initialized".to_string(), - ))) - } - } - }; - let res = spv_client.stats().await; - let mut guard = inner.lock().unwrap(); - *guard = Some(spv_client); - res - }); - - match result { - Ok(stats) => Box::into_raw(Box::new(stats.into())), - Err(e) => { - set_last_error(&e.to_string()); - std::ptr::null_mut() - } - } -} - /// Get the current chain tip hash (32 bytes) if available. /// /// # Safety @@ -1182,17 +1142,6 @@ pub unsafe extern "C" fn dash_spv_ffi_sync_progress_destroy(progress: *mut FFISy } } -/// Destroy an `FFISpvStats` object returned by this crate. -/// -/// # Safety -/// - `stats` must be a pointer returned from this crate, or null. -#[no_mangle] -pub unsafe extern "C" fn dash_spv_ffi_spv_stats_destroy(stats: *mut FFISpvStats) { - if !stats.is_null() { - let _ = Box::from_raw(stats); - } -} - // Wallet operations /// Request a rescan of the blockchain from a given height (not yet implemented). diff --git a/dash-spv-ffi/src/types.rs b/dash-spv-ffi/src/types.rs index 3261eedf1..dffef6abb 100644 --- a/dash-spv-ffi/src/types.rs +++ b/dash-spv-ffi/src/types.rs @@ -1,6 +1,6 @@ use dash_spv::client::config::MempoolStrategy; use dash_spv::types::{DetailedSyncProgress, MempoolRemovalReason, SyncStage}; -use dash_spv::{ChainState, SpvStats, SyncProgress}; +use dash_spv::{ChainState, SyncProgress}; use std::ffi::{CStr, CString}; use std::os::raw::{c_char, c_void}; @@ -200,41 +200,6 @@ impl From for FFIChainState { } } -#[repr(C)] -pub struct FFISpvStats { - pub connected_peers: u32, - pub total_peers: u32, - pub header_height: u32, - pub filter_height: u32, - pub headers_downloaded: u64, - pub filter_headers_downloaded: u64, - pub filters_downloaded: u64, - pub filters_matched: u64, - pub blocks_processed: u64, - pub bytes_received: u64, - pub bytes_sent: u64, - pub uptime: u64, -} - -impl From for FFISpvStats { - fn from(stats: SpvStats) -> Self { - FFISpvStats { - connected_peers: stats.connected_peers, - total_peers: stats.total_peers, - header_height: stats.header_height, - filter_height: stats.filter_height, - headers_downloaded: stats.headers_downloaded, - filter_headers_downloaded: stats.filter_headers_downloaded, - filters_downloaded: stats.filters_downloaded, - filters_matched: stats.filters_matched, - blocks_processed: stats.blocks_processed, - bytes_received: stats.bytes_received, - bytes_sent: stats.bytes_sent, - uptime: stats.uptime.as_secs(), - } - } -} - /// FFI-safe array that transfers ownership of memory to the C caller. /// /// # Safety diff --git a/dash-spv-ffi/tests/c_tests/test_advanced.c b/dash-spv-ffi/tests/c_tests/test_advanced.c index 66429ee6c..15fafde71 100644 --- a/dash-spv-ffi/tests/c_tests/test_advanced.c +++ b/dash-spv-ffi/tests/c_tests/test_advanced.c @@ -88,17 +88,6 @@ void test_sync_progress() { dash_spv_ffi_sync_progress_destroy(progress); } - // Get stats - FFISpvStats* stats = dash_spv_ffi_client_get_stats(client); - if (stats != NULL) { - TEST_ASSERT(stats->headers_downloaded >= 0); - TEST_ASSERT(stats->filters_downloaded >= 0); - TEST_ASSERT(stats->bytes_received >= 0); - TEST_ASSERT(stats->bytes_sent >= 0); - - dash_spv_ffi_spv_stats_destroy(stats); - } - dash_spv_ffi_client_destroy(client); dash_spv_ffi_config_destroy(config); @@ -118,7 +107,7 @@ void* concurrent_operations(void* arg) { for (int i = 0; i < 100; i++) { // Perform various operations - switch (i % 4) { + switch (i % 3) { case 0: { // Get sync progress FFISyncProgress* progress = dash_spv_ffi_client_get_sync_progress(data->client); @@ -128,14 +117,6 @@ void* concurrent_operations(void* arg) { break; } case 1: { - // Get stats - FFISpvStats* stats = dash_spv_ffi_client_get_stats(data->client); - if (stats != NULL) { - dash_spv_ffi_spv_stats_destroy(stats); - } - break; - } - case 2: { // Check address balance FFIBalance* balance = dash_spv_ffi_client_get_address_balance( data->client, @@ -146,7 +127,7 @@ void* concurrent_operations(void* arg) { } break; } - case 3: { + case 2: { // Watch/unwatch address char addr[64]; snprintf(addr, sizeof(addr), "XjSgy6PaVCB3V4KhCiCDkaVbx9ewxe9R%02d", i); diff --git a/dash-spv-ffi/tests/c_tests/test_integration.c b/dash-spv-ffi/tests/c_tests/test_integration.c index 7b33cb8e1..823faf8c7 100644 --- a/dash-spv-ffi/tests/c_tests/test_integration.c +++ b/dash-spv-ffi/tests/c_tests/test_integration.c @@ -111,16 +111,6 @@ void test_full_workflow() { dash_spv_ffi_sync_progress_destroy(progress); } - // Check stats - FFISpvStats* stats = dash_spv_ffi_client_get_stats(ctx.client); - if (stats != NULL) { - printf("Stats: headers=%llu, filters=%llu, bytes_received=%llu\n", - (unsigned long long)stats->headers_downloaded, - (unsigned long long)stats->filters_downloaded, - (unsigned long long)stats->bytes_received); - dash_spv_ffi_spv_stats_destroy(stats); - } - sleep(1); } diff --git a/dash-spv-ffi/tests/integration/test_cross_language.rs b/dash-spv-ffi/tests/integration/test_cross_language.rs index d071fde8c..61fc71c51 100644 --- a/dash-spv-ffi/tests/integration/test_cross_language.rs +++ b/dash-spv-ffi/tests/integration/test_cross_language.rs @@ -104,7 +104,6 @@ mod tests { // Check alignment of structs assert!(std::mem::align_of::() <= 8); assert!(std::mem::align_of::() <= 8); - assert!(std::mem::align_of::() <= 8); // Verify FFIString is pointer-sized assert_eq!(std::mem::size_of::(), std::mem::size_of::<*mut c_char>()); diff --git a/dash-spv-ffi/tests/test_client.rs b/dash-spv-ffi/tests/test_client.rs index 532238559..28a91cb22 100644 --- a/dash-spv-ffi/tests/test_client.rs +++ b/dash-spv-ffi/tests/test_client.rs @@ -97,9 +97,6 @@ mod tests { let progress = dash_spv_ffi_client_get_sync_progress(std::ptr::null_mut()); assert!(progress.is_null()); - - let stats = dash_spv_ffi_client_get_stats(std::ptr::null_mut()); - assert!(stats.is_null()); } } @@ -129,13 +126,6 @@ mod tests { let (config, _temp_dir) = create_test_config(); let client = dash_spv_ffi_client_new(config); - let stats = dash_spv_ffi_client_get_stats(client); - if !stats.is_null() { - let _stats_ref = &*stats; - // headers_downloaded and bytes_received are u64, always >= 0 - dash_spv_ffi_spv_stats_destroy(stats); - } - dash_spv_ffi_client_destroy(client); dash_spv_ffi_config_destroy(config); } diff --git a/dash-spv-ffi/tests/unit/test_client_lifecycle.rs b/dash-spv-ffi/tests/unit/test_client_lifecycle.rs index 6d031995b..ead73b240 100644 --- a/dash-spv-ffi/tests/unit/test_client_lifecycle.rs +++ b/dash-spv-ffi/tests/unit/test_client_lifecycle.rs @@ -143,10 +143,8 @@ mod tests { // Do some operations let progress = dash_spv_ffi_client_get_sync_progress(client); - let stats = dash_spv_ffi_client_get_stats(client); dash_spv_ffi_sync_progress_destroy(progress); - dash_spv_ffi_spv_stats_destroy(stats); dash_spv_ffi_client_destroy(client); dash_spv_ffi_config_destroy(config); @@ -177,7 +175,6 @@ mod tests { ); assert!(dash_spv_ffi_client_get_sync_progress(std::ptr::null_mut()).is_null()); - assert!(dash_spv_ffi_client_get_stats(std::ptr::null_mut()).is_null()); // Test destroy with null (should be safe) dash_spv_ffi_client_destroy(std::ptr::null_mut()); @@ -195,12 +192,10 @@ mod tests { // Get initial state let progress1 = dash_spv_ffi_client_get_sync_progress(client); - let stats1 = dash_spv_ffi_client_get_stats(client); // State should be consistent - if !progress1.is_null() && !stats1.is_null() { + if !progress1.is_null() { let progress = &*progress1; - let _stats = &*stats1; // Basic consistency checks assert!( @@ -210,7 +205,6 @@ mod tests { // headers_downloaded is u64, always >= 0 dash_spv_ffi_sync_progress_destroy(progress1); - dash_spv_ffi_spv_stats_destroy(stats1); } dash_spv_ffi_client_destroy(client); diff --git a/dash-spv-ffi/tests/unit/test_memory_management.rs b/dash-spv-ffi/tests/unit/test_memory_management.rs index 4ceeba5da..9c38bfffd 100644 --- a/dash-spv-ffi/tests/unit/test_memory_management.rs +++ b/dash-spv-ffi/tests/unit/test_memory_management.rs @@ -87,11 +87,6 @@ mod tests { dash_spv_ffi_sync_progress_destroy(progress); } - let stats = dash_spv_ffi_client_get_stats(client); - if !stats.is_null() { - dash_spv_ffi_spv_stats_destroy(stats); - } - dash_spv_ffi_client_destroy(client); } @@ -282,12 +277,6 @@ mod tests { dash_spv_ffi_sync_progress_destroy(progress); } - let stats = dash_spv_ffi_client_get_stats(client); - if !stats.is_null() { - // Stats might contain strings or other allocated data - dash_spv_ffi_spv_stats_destroy(stats); - } - dash_spv_ffi_client_destroy(client); dash_spv_ffi_config_destroy(config); } diff --git a/dash-spv-ffi/tests/unit/test_type_conversions.rs b/dash-spv-ffi/tests/unit/test_type_conversions.rs index ae8c480d8..bf3f41661 100644 --- a/dash-spv-ffi/tests/unit/test_type_conversions.rs +++ b/dash-spv-ffi/tests/unit/test_type_conversions.rs @@ -184,48 +184,6 @@ mod tests { } } - #[test] - fn test_spv_stats_extreme_values() { - let stats = dash_spv::SpvStats { - headers_downloaded: u64::MAX, - filter_headers_downloaded: u64::MAX, - filters_downloaded: u64::MAX, - filters_matched: u64::MAX, - blocks_with_relevant_transactions: u64::MAX, - blocks_requested: u64::MAX, - blocks_processed: u64::MAX, - masternode_diffs_processed: u64::MAX, - bytes_received: u64::MAX, - bytes_sent: u64::MAX, - uptime: std::time::Duration::from_secs(u64::MAX), - filters_requested: u64::MAX, - filters_received: u64::MAX, - filter_sync_start_time: None, - last_filter_received_time: None, - received_filter_heights: std::sync::Arc::new(tokio::sync::Mutex::new( - std::collections::HashSet::new(), - )), - active_filter_requests: 0, - pending_filter_requests: 0, - filter_request_timeouts: u64::MAX, - filter_requests_retried: u64::MAX, - connected_peers: 0, - total_peers: 0, - header_height: 0, - filter_height: 0, - }; - - let ffi_stats = FFISpvStats::from(stats); - assert_eq!(ffi_stats.headers_downloaded, u64::MAX); - assert_eq!(ffi_stats.filter_headers_downloaded, u64::MAX); - assert_eq!(ffi_stats.filters_downloaded, u64::MAX); - assert_eq!(ffi_stats.filters_matched, u64::MAX); - assert_eq!(ffi_stats.blocks_processed, u64::MAX); - assert_eq!(ffi_stats.bytes_received, u64::MAX); - assert_eq!(ffi_stats.bytes_sent, u64::MAX); - assert_eq!(ffi_stats.uptime, u64::MAX); - } - #[test] fn test_concurrent_ffi_string_creation() { use std::sync::atomic::{AtomicUsize, Ordering}; diff --git a/dash-spv/examples/simple_sync.rs b/dash-spv/examples/simple_sync.rs index 004545545..4e097c77c 100644 --- a/dash-spv/examples/simple_sync.rs +++ b/dash-spv/examples/simple_sync.rs @@ -38,11 +38,6 @@ async fn main() -> Result<(), Box> { println!("Starting header synchronization..."); - // Get some statistics - let stats = client.stats().await?; - println!("Headers downloaded: {}", stats.headers_downloaded); - println!("Bytes received: {}", stats.bytes_received); - let (_command_sender, command_receiver) = tokio::sync::mpsc::unbounded_channel(); let shutdown_token = CancellationToken::new(); diff --git a/dash-spv/src/client/core.rs b/dash-spv/src/client/core.rs index a4fa6fde3..512dd21ae 100644 --- a/dash-spv/src/client/core.rs +++ b/dash-spv/src/client/core.rs @@ -21,7 +21,7 @@ use crate::network::NetworkManager; use crate::storage::StorageManager; use crate::sync::legacy::filters::FilterNotificationSender; use crate::sync::legacy::SyncManager; -use crate::types::{ChainState, DetailedSyncProgress, MempoolState, SpvEvent, SpvStats}; +use crate::types::{ChainState, DetailedSyncProgress, MempoolState, SpvEvent}; use key_wallet_manager::wallet_interface::WalletInterface; use super::{ClientConfig, StatusDisplay}; @@ -100,7 +100,6 @@ use super::{ClientConfig, StatusDisplay}; pub struct DashSpvClient { pub(super) config: ClientConfig, pub(super) state: Arc>, - pub(super) stats: Arc>, pub(super) network: N, pub(super) storage: Arc>, /// External wallet implementation (required) @@ -217,43 +216,6 @@ impl DashSpvClient DashSpvClient StatusDisplay<'_, S, W> { StatusDisplay::new( &self.state, - &self.stats, self.storage.clone(), Some(&self.wallet), &self.terminal_ui, @@ -317,7 +278,6 @@ impl DashSpvClient StatusDisplay<'_, S, W> { StatusDisplay::new( &self.state, - &self.stats, self.storage.clone(), Some(&self.wallet), &None, diff --git a/dash-spv/src/client/lifecycle.rs b/dash-spv/src/client/lifecycle.rs index d9223b82e..b9b45e351 100644 --- a/dash-spv/src/client/lifecycle.rs +++ b/dash-spv/src/client/lifecycle.rs @@ -18,7 +18,7 @@ use crate::mempool_filter::MempoolFilter; use crate::network::NetworkManager; use crate::storage::StorageManager; use crate::sync::legacy::SyncManager; -use crate::types::{ChainState, MempoolState, SpvStats}; +use crate::types::{ChainState, MempoolState, SharedFilterHeights}; use dashcore::network::constants::NetworkExt; use dashcore_hashes::Hash; use key_wallet_manager::wallet_interface::WalletInterface; @@ -38,22 +38,16 @@ impl DashSpvClient let storage = Arc::new(Mutex::new(storage)); // Create sync manager - let received_filter_heights = stats.read().await.received_filter_heights.clone(); tracing::info!("Creating sequential sync manager"); - let sync_manager = SyncManager::new( - &config, - received_filter_heights, - wallet.clone(), - state.clone(), - stats.clone(), - ) - .map_err(SpvError::Sync)?; + let received_filter_heights = SharedFilterHeights::new(Mutex::new(HashSet::new())); + let sync_manager = + SyncManager::new(&config, received_filter_heights, wallet.clone(), state.clone()) + .map_err(SpvError::Sync)?; // Create ChainLock manager let chainlock_manager = Arc::new(ChainLockManager::new(true)); @@ -70,7 +64,6 @@ impl DashSpvClient>`) //! 2. state (`Arc>`) -//! 3. stats (`Arc>`) -//! 4. mempool_state (`Arc>`) -//! 5. storage (`Arc>`) +//! 3. mempool_state (`Arc>`) +//! 4. storage (`Arc>`) //! //! Never acquire locks in reverse order or deadlock will occur! diff --git a/dash-spv/src/client/progress.rs b/dash-spv/src/client/progress.rs index eddd9f5fa..c6dcf6cbb 100644 --- a/dash-spv/src/client/progress.rs +++ b/dash-spv/src/client/progress.rs @@ -9,7 +9,7 @@ use crate::error::Result; use crate::network::NetworkManager; use crate::storage::StorageManager; use crate::sync::legacy::SyncPhase; -use crate::types::{SpvStats, SyncProgress, SyncStage}; +use crate::types::{SyncProgress, SyncStage}; use key_wallet_manager::wallet_interface::WalletInterface; use super::DashSpvClient; @@ -21,37 +21,6 @@ impl DashSpvClient Result { - let display = self.create_status_display().await; - let mut stats = display.stats().await?; - - // Add real-time peer count and heights - stats.connected_peers = self.network.peer_count() as u32; - stats.total_peers = self.network.peer_count() as u32; // TODO: Track total discovered peers - - // Get current heights from storage - { - let storage = self.storage.lock().await; - if let Some(header_height) = storage.get_tip_height().await { - stats.header_height = header_height; - } - - if let Ok(Some(filter_height)) = storage.get_filter_tip_height().await { - stats.filter_height = filter_height; - } - } - - tracing::debug!( - "get_stats: header_height={}, filter_height={}, peers={}", - stats.header_height, - stats.filter_height, - stats.connected_peers - ); - - Ok(stats) - } - /// Map a sync phase to a sync stage for progress reporting. pub(super) fn map_phase_to_stage( phase: &SyncPhase, diff --git a/dash-spv/src/client/status_display.rs b/dash-spv/src/client/status_display.rs index cc3e9aee5..9efb65f13 100644 --- a/dash-spv/src/client/status_display.rs +++ b/dash-spv/src/client/status_display.rs @@ -8,13 +8,12 @@ use crate::error::Result; use crate::storage::StorageManager; #[cfg(feature = "terminal-ui")] use crate::terminal::TerminalUI; -use crate::types::{ChainState, SpvStats, SyncProgress}; +use crate::types::{ChainState, SyncProgress}; use key_wallet_manager::wallet_interface::WalletInterface; /// Status display manager for updating UI and reporting sync progress. pub struct StatusDisplay<'a, S: StorageManager, W: WalletInterface> { state: &'a Arc>, - stats: &'a Arc>, storage: Arc>, wallet: Option<&'a Arc>>, #[cfg(feature = "terminal-ui")] @@ -28,7 +27,6 @@ impl<'a, S: StorageManager, W: WalletInterface> StatusDisplay<'a, S, W> { #[cfg(feature = "terminal-ui")] pub fn new( state: &'a Arc>, - stats: &'a Arc>, storage: Arc>, wallet: Option<&'a Arc>>, terminal_ui: &'a Option>, @@ -36,7 +34,6 @@ impl<'a, S: StorageManager, W: WalletInterface> StatusDisplay<'a, S, W> { ) -> Self { Self { state, - stats, storage, wallet, terminal_ui, @@ -48,7 +45,6 @@ impl<'a, S: StorageManager, W: WalletInterface> StatusDisplay<'a, S, W> { #[cfg(not(feature = "terminal-ui"))] pub fn new( state: &'a Arc>, - stats: &'a Arc>, storage: Arc>, wallet: Option<&'a Arc>>, _terminal_ui: &'a Option<()>, @@ -56,7 +52,6 @@ impl<'a, S: StorageManager, W: WalletInterface> StatusDisplay<'a, S, W> { ) -> Self { Self { state, - stats, storage, wallet, config, @@ -100,17 +95,6 @@ impl<'a, S: StorageManager, W: WalletInterface> StatusDisplay<'a, S, W> { /// Get current sync progress. pub async fn sync_progress(&self) -> Result { let state = self.state.read().await; - // Clone the inner heights handle and copy needed counters without awaiting while holding the RwLock - let (filters_received, received_heights) = { - let stats = self.stats.read().await; - (stats.filters_received, std::sync::Arc::clone(&stats.received_filter_heights)) - }; - - // Calculate last synced filter height from received filter heights without holding the RwLock guard - let last_synced_filter_height = { - let heights = received_heights.lock().await; - heights.iter().max().copied() - }; // Calculate the actual header height considering checkpoint sync let header_height = self.calculate_header_height(&state).await; @@ -127,19 +111,13 @@ impl<'a, S: StorageManager, W: WalletInterface> StatusDisplay<'a, S, W> { masternode_height: state.last_masternode_diff_height.unwrap_or(0), peer_count: 1, // TODO: Get from network manager filter_sync_available: false, // TODO: Get from network manager - filters_downloaded: filters_received, - last_synced_filter_height, + filters_downloaded: 0, + last_synced_filter_height: None, sync_start: std::time::SystemTime::now(), // TODO: Track properly last_update: std::time::SystemTime::now(), }) } - /// Get current statistics. - pub async fn stats(&self) -> Result { - let stats = self.stats.read().await; - Ok(stats.clone()) - } - /// Get current chain state (read-only). pub async fn chain_state(&self) -> ChainState { let state = self.state.read().await; @@ -259,14 +237,6 @@ impl<'a, S: StorageManager, W: WalletInterface> StatusDisplay<'a, S, W> { state.last_chainlock_height.unwrap_or(0) }; - // Get filter and block processing statistics - let stats = self.stats.read().await; - let filters_received = stats.filters_received; - let filters_matched = stats.filters_matched; - let blocks_with_relevant_transactions = stats.blocks_with_relevant_transactions; - let blocks_processed = stats.blocks_processed; - drop(stats); - // Get wallet balance if available let balance_str = if let Some(wallet_ref) = self.wallet { let wallet_guard = wallet_ref.read().await; @@ -281,18 +251,14 @@ impl<'a, S: StorageManager, W: WalletInterface> StatusDisplay<'a, S, W> { }; tracing::info!( - "📊 [SYNC STATUS] Headers: {} | Filter Headers: {} | Filters: {} | Latest ChainLock: {} | Filters Matched: {} | Blocks w/ Relevant Txs: {} | Blocks Processed: {}{}", + "📊 [SYNC STATUS] Headers: {} | Filter Headers: {} | Latest ChainLock: {} | {}", header_height, filter_height, - filters_received, if chainlock_height > 0 { format!("#{}", chainlock_height) } else { "None".to_string() }, - filters_matched, - blocks_with_relevant_transactions, - blocks_processed, balance_str ); } diff --git a/dash-spv/src/lib.rs b/dash-spv/src/lib.rs index 69c7c96f3..96fdb4975 100644 --- a/dash-spv/src/lib.rs +++ b/dash-spv/src/lib.rs @@ -79,7 +79,7 @@ pub use error::{ }; pub use logging::{init_console_logging, init_logging, LogFileConfig, LoggingConfig, LoggingGuard}; pub use tracing::level_filters::LevelFilter; -pub use types::{ChainState, FilterMatch, SpvStats, SyncProgress, ValidationMode}; +pub use types::{ChainState, FilterMatch, SyncProgress, ValidationMode}; // Re-export commonly used dashcore types pub use dashcore::{Address, BlockHash, Network, OutPoint, QuorumHash, ScriptBuf}; diff --git a/dash-spv/src/sync/legacy/manager.rs b/dash-spv/src/sync/legacy/manager.rs index d0ce00cf9..a2e64fbf0 100644 --- a/dash-spv/src/sync/legacy/manager.rs +++ b/dash-spv/src/sync/legacy/manager.rs @@ -10,7 +10,7 @@ use crate::sync::legacy::{ FilterSyncManager, HeaderSyncManager, MasternodeSyncManager, ReorgConfig, }; use crate::types::{SharedFilterHeights, SyncProgress}; -use crate::{SpvStats, SyncError}; +use crate::SyncError; use dashcore::prelude::CoreBlockHeight; use dashcore::BlockHash; use key_wallet_manager::wallet_interface::WalletInterface; @@ -97,9 +97,6 @@ pub struct SyncManager /// Optional wallet reference for filter checking pub(super) wallet: std::sync::Arc>, - - /// Statistics for tracking sync progress - pub(super) stats: std::sync::Arc>, } impl SyncManager { @@ -109,7 +106,6 @@ impl SyncManager>, chain_state: Arc>, - stats: Arc>, ) -> SyncResult { // Create reorg config with sensible defaults let reorg_config = ReorgConfig::default(); @@ -129,7 +125,6 @@ impl SyncManager SyncManager` or `Arc` when used. //! Always acquire locks in consistent order to prevent deadlocks: //! 1. state (ChainState) -//! 2. stats (SpvStats) -//! 3. mempool_state (MempoolState) +//! 2. mempool_state (MempoolState) use std::time::{Duration, Instant, SystemTime}; @@ -417,118 +415,6 @@ pub struct FilterMatch { // WatchItem has been removed in favor of using key-wallet-manager's address tracking -/// Statistics about the SPV client. -#[derive(Debug, Clone, Serialize, Deserialize)] -pub struct SpvStats { - /// Number of connected peers. - pub connected_peers: u32, - - /// Total number of known peers. - pub total_peers: u32, - - /// Current blockchain height. - pub header_height: u32, - - /// Current filter height. - pub filter_height: u32, - - /// Number of headers downloaded. - pub headers_downloaded: u64, - - /// Number of filter headers downloaded. - pub filter_headers_downloaded: u64, - - /// Number of filters downloaded. - pub filters_downloaded: u64, - - /// Number of compact filters that matched watch items. - pub filters_matched: u64, - - /// Number of blocks with relevant transactions (after full block processing). - pub blocks_with_relevant_transactions: u64, - - /// Number of full blocks requested. - pub blocks_requested: u64, - - /// Number of full blocks processed. - pub blocks_processed: u64, - - /// Number of masternode diffs processed. - pub masternode_diffs_processed: u64, - - /// Total bytes received. - pub bytes_received: u64, - - /// Total bytes sent. - pub bytes_sent: u64, - - /// Connection uptime. - pub uptime: std::time::Duration, - - /// Number of filters requested during sync. - pub filters_requested: u64, - - /// Number of filters received during sync. - pub filters_received: u64, - - /// Filter sync start time. - #[serde(skip)] - pub filter_sync_start_time: Option, - - /// Last time a filter was received. - #[serde(skip)] - pub last_filter_received_time: Option, - - /// Received filter heights for gap tracking (shared with FilterSyncManager). - #[serde(skip)] - pub received_filter_heights: SharedFilterHeights, - - /// Number of filter requests currently active. - pub active_filter_requests: u32, - - /// Number of filter requests currently queued. - pub pending_filter_requests: u32, - - /// Number of filter request timeouts. - pub filter_request_timeouts: u64, - - /// Number of filter requests retried. - pub filter_requests_retried: u64, -} - -impl Default for SpvStats { - fn default() -> Self { - Self { - connected_peers: 0, - total_peers: 0, - header_height: 0, - filter_height: 0, - headers_downloaded: 0, - filter_headers_downloaded: 0, - filters_downloaded: 0, - filters_matched: 0, - blocks_with_relevant_transactions: 0, - blocks_requested: 0, - blocks_processed: 0, - masternode_diffs_processed: 0, - bytes_received: 0, - bytes_sent: 0, - uptime: std::time::Duration::default(), - filters_requested: 0, - filters_received: 0, - filter_sync_start_time: None, - last_filter_received_time: None, - received_filter_heights: std::sync::Arc::new(tokio::sync::Mutex::new( - std::collections::HashSet::new(), - )), - active_filter_requests: 0, - pending_filter_requests: 0, - filter_request_timeouts: 0, - filter_requests_retried: 0, - } - } -} - /// Balance information for an address. #[derive(Debug, Clone, PartialEq, Eq)] pub struct AddressBalance {