From b19bd7d527cedde25d98528ce8bb813e71d75fe3 Mon Sep 17 00:00:00 2001 From: xdustinface Date: Thu, 15 Jan 2026 23:30:22 +0100 Subject: [PATCH] refactor: drop `DashSpvClient.sync_to_tip` It's basically doing nothing except logging some things. --- dash-spv-ffi/FFI_API.md | 24 +--- dash-spv-ffi/FFI_DOCS_README.md | 20 --- dash-spv-ffi/README.md | 1 - dash-spv-ffi/include/dash_spv_ffi.h | 29 ---- dash-spv-ffi/scripts/generate_ffi_docs.py | 3 - dash-spv-ffi/src/client.rs | 128 +----------------- dash-spv-ffi/tests/c_tests/test_advanced.c | 16 --- .../tests/integration/test_full_workflow.rs | 20 +-- dash-spv-ffi/tests/test_event_callbacks.rs | 7 - .../tests/unit/test_async_operations.rs | 15 -- .../tests/unit/test_client_lifecycle.rs | 9 +- dash-spv/README.md | 8 +- dash-spv/examples/filter_sync.rs | 3 - dash-spv/examples/simple_sync.rs | 6 - dash-spv/examples/spv_with_wallet.rs | 5 - dash-spv/src/client/lifecycle.rs | 6 - dash-spv/src/client/sync_coordinator.rs | 36 ----- dash-spv/src/lib.rs | 9 +- dash-spv/src/main.rs | 16 --- 19 files changed, 14 insertions(+), 347 deletions(-) diff --git a/dash-spv-ffi/FFI_API.md b/dash-spv-ffi/FFI_API.md index b07f1f902..d87b92a76 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**: 68 +**Total Functions**: 67 ## Table of Contents @@ -66,14 +66,13 @@ Functions: 25 ### Synchronization -Functions: 7 +Functions: 6 | Function | Description | Module | |----------|-------------|--------| | `dash_spv_ffi_client_cancel_sync` | Cancels the sync operation | client | | `dash_spv_ffi_client_get_sync_progress` | Get the current sync progress snapshot | client | | `dash_spv_ffi_client_is_filter_sync_available` | Check if compact filter sync is currently available | client | -| `dash_spv_ffi_client_sync_to_tip` | Sync the SPV client to the chain tip | client | | `dash_spv_ffi_client_sync_to_tip_with_progress` | Sync the SPV client to the chain tip with detailed progress updates | client | | `dash_spv_ffi_client_test_sync` | Performs a test synchronization of the SPV client # Parameters - `client`:... | client | | `dash_spv_ffi_sync_progress_destroy` | Destroy a `FFISyncProgress` object returned by this crate | client | @@ -661,22 +660,6 @@ Check if compact filter sync is currently available. # Safety - `client` must b --- -#### `dash_spv_ffi_client_sync_to_tip` - -```c -dash_spv_ffi_client_sync_to_tip(client: *mut FFIDashSpvClient, completion_callback: Option, user_data: *mut c_void,) -> i32 -``` - -**Description:** -Sync the SPV client to the chain tip. # Safety This function is unsafe because: - `client` must be a valid pointer to an initialized `FFIDashSpvClient` - `user_data` must satisfy thread safety requirements: - If non-null, it must point to data that is safe to access from multiple threads - The caller must ensure proper synchronization if the data is mutable - The data must remain valid for the entire duration of the sync operation - `completion_callback` must be thread-safe and can be called from any thread # Parameters - `client`: Pointer to the SPV client - `completion_callback`: Optional callback invoked on completion - `user_data`: Optional user data pointer passed to callbacks # Returns 0 on success, error code on failure - -**Safety:** -This function is unsafe because: - `client` must be a valid pointer to an initialized `FFIDashSpvClient` - `user_data` must satisfy thread safety requirements: - If non-null, it must point to data that is safe to access from multiple threads - The caller must ensure proper synchronization if the data is mutable - The data must remain valid for the entire duration of the sync operation - `completion_callback` must be thread-safe and can be called from any thread - -**Module:** `client` - ---- - #### `dash_spv_ffi_client_sync_to_tip_with_progress` ```c @@ -1258,9 +1241,6 @@ if (result != 0) { // Handle error } -// Sync to chain tip -dash_spv_ffi_client_sync_to_tip(client, NULL, NULL); - // Get wallet manager (shares ownership with the client) FFIWalletManager* wallet_manager = dash_spv_ffi_client_get_wallet_manager(client); diff --git a/dash-spv-ffi/FFI_DOCS_README.md b/dash-spv-ffi/FFI_DOCS_README.md index c7915f2c1..26afe966f 100644 --- a/dash-spv-ffi/FFI_DOCS_README.md +++ b/dash-spv-ffi/FFI_DOCS_README.md @@ -73,26 +73,6 @@ When adding new FFI functions: 4. Run `make update-docs` to regenerate documentation 5. Commit both the code changes and updated `FFI_API.md` -## Example FFI Function - -```rust -/// Sync the SPV client to the chain tip -/// -/// # Safety -/// -/// - `client` must be a valid pointer to an FFIDashSpvClient -/// - `on_progress` callback may be invoked from any thread -/// - `on_completion` will be called exactly once -#[no_mangle] -pub unsafe extern "C" fn dash_spv_ffi_client_sync_to_tip( - client: *mut FFIDashSpvClient, - on_progress: Option, - on_completion: Option, -) -> i32 { - // Implementation -} -``` - ## CI/CD Integration The documentation verification is integrated into the CI pipeline: diff --git a/dash-spv-ffi/README.md b/dash-spv-ffi/README.md index 432876caa..29c7c5af4 100644 --- a/dash-spv-ffi/README.md +++ b/dash-spv-ffi/README.md @@ -90,7 +90,6 @@ dash_spv_ffi_config_destroy(config); - `dash_spv_ffi_client_new(config)` - Create new client - `dash_spv_ffi_client_start(client)` - Start the client - `dash_spv_ffi_client_stop(client)` - Stop the client -- `dash_spv_ffi_client_sync_to_tip(client, callbacks)` - Sync to chain tip - `dash_spv_ffi_client_get_sync_progress(client)` - Get sync progress - `dash_spv_ffi_client_get_stats(client)` - Get client statistics - `dash_spv_ffi_client_destroy(client)` - Free client memory diff --git a/dash-spv-ffi/include/dash_spv_ffi.h b/dash-spv-ffi/include/dash_spv_ffi.h index b2e47e587..4fcf2e12d 100644 --- a/dash-spv-ffi/include/dash_spv_ffi.h +++ b/dash-spv-ffi/include/dash_spv_ffi.h @@ -322,35 +322,6 @@ int32_t dash_spv_ffi_client_update_config(struct FFIDashSpvClient *client, */ int32_t dash_spv_ffi_client_stop(struct FFIDashSpvClient *client) ; -/** - * Sync the SPV client to the chain tip. - * - * # Safety - * - * This function is unsafe because: - * - `client` must be a valid pointer to an initialized `FFIDashSpvClient` - * - `user_data` must satisfy thread safety requirements: - * - If non-null, it must point to data that is safe to access from multiple threads - * - The caller must ensure proper synchronization if the data is mutable - * - The data must remain valid for the entire duration of the sync operation - * - `completion_callback` must be thread-safe and can be called from any thread - * - * # Parameters - * - * - `client`: Pointer to the SPV client - * - `completion_callback`: Optional callback invoked on completion - * - `user_data`: Optional user data pointer passed to callbacks - * - * # Returns - * - * 0 on success, error code on failure - */ - -int32_t dash_spv_ffi_client_sync_to_tip(struct FFIDashSpvClient *client, - void (*completion_callback)(bool, const char*, void*), - void *user_data) -; - /** * Performs a test synchronization of the SPV client * diff --git a/dash-spv-ffi/scripts/generate_ffi_docs.py b/dash-spv-ffi/scripts/generate_ffi_docs.py index 1b8c9c4bb..239ed43be 100755 --- a/dash-spv-ffi/scripts/generate_ffi_docs.py +++ b/dash-spv-ffi/scripts/generate_ffi_docs.py @@ -317,9 +317,6 @@ def generate_markdown(functions: List[FFIFunction]) -> str: md.append(" // Handle error") md.append("}") md.append("") - md.append("// Sync to chain tip") - md.append("dash_spv_ffi_client_sync_to_tip(client, NULL, NULL);") - md.append("") md.append("// Get wallet manager (shares ownership with the client)") md.append("FFIWalletManager* wallet_manager = dash_spv_ffi_client_get_wallet_manager(client);") md.append("") diff --git a/dash-spv-ffi/src/client.rs b/dash-spv-ffi/src/client.rs index 3335a7056..8848d188b 100644 --- a/dash-spv-ffi/src/client.rs +++ b/dash-spv-ffi/src/client.rs @@ -44,11 +44,6 @@ enum CallbackInfo { completion_callback: Option, user_data: *mut c_void, }, - /// Simple progress callbacks (used by sync_to_tip) - Simple { - completion_callback: Option, - user_data: *mut c_void, - }, } /// # Safety @@ -541,115 +536,6 @@ pub unsafe extern "C" fn dash_spv_ffi_client_stop(client: *mut FFIDashSpvClient) } } -/// Sync the SPV client to the chain tip. -/// -/// # Safety -/// -/// This function is unsafe because: -/// - `client` must be a valid pointer to an initialized `FFIDashSpvClient` -/// - `user_data` must satisfy thread safety requirements: -/// - If non-null, it must point to data that is safe to access from multiple threads -/// - The caller must ensure proper synchronization if the data is mutable -/// - The data must remain valid for the entire duration of the sync operation -/// - `completion_callback` must be thread-safe and can be called from any thread -/// -/// # Parameters -/// -/// - `client`: Pointer to the SPV client -/// - `completion_callback`: Optional callback invoked on completion -/// - `user_data`: Optional user data pointer passed to callbacks -/// -/// # Returns -/// -/// 0 on success, error code on failure -#[no_mangle] -pub unsafe extern "C" fn dash_spv_ffi_client_sync_to_tip( - client: *mut FFIDashSpvClient, - completion_callback: Option, - user_data: *mut c_void, -) -> i32 { - null_check!(client); - - let client = &(*client); - let inner = client.inner.clone(); - let runtime = client.runtime.clone(); - - // Register callbacks in the global registry for safe lifetime management - let callback_info = CallbackInfo::Simple { - completion_callback, - user_data, - }; - let callback_id = CALLBACK_REGISTRY.lock().unwrap().register(callback_info); - - // Execute sync in the runtime - let result = runtime.block_on(async { - let mut 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(), - ))) - } - } - }; - match spv_client.sync_to_tip().await { - Ok(_sync_result) => { - // sync_to_tip returns a SyncResult, not a stream - // Progress callbacks removed as sync_to_tip doesn't provide real progress updates - - // Report completion and unregister callbacks - let mut registry = CALLBACK_REGISTRY.lock().unwrap(); - if let Some(CallbackInfo::Simple { - completion_callback: Some(callback), - user_data, - }) = registry.unregister(callback_id) - { - let msg = CString::new("Sync completed successfully").unwrap_or_else(|_| { - CString::new("Sync completed").expect("hardcoded string is safe") - }); - callback(true, msg.as_ptr(), user_data); - } - - // Put client back - let mut guard = inner.lock().unwrap(); - *guard = Some(spv_client); - - Ok(()) - } - Err(e) => { - // Report error and unregister callbacks - let mut registry = CALLBACK_REGISTRY.lock().unwrap(); - if let Some(CallbackInfo::Simple { - completion_callback: Some(callback), - user_data, - }) = registry.unregister(callback_id) - { - let msg = match CString::new(format!("Sync failed: {}", e)) { - Ok(s) => s, - Err(_) => CString::new("Sync failed").expect("hardcoded string is safe"), - }; - callback(false, msg.as_ptr(), user_data); - } - - // Put client back - let mut guard = inner.lock().unwrap(); - *guard = Some(spv_client); - Err(e) - } - } - }); - - match result { - Ok(()) => FFIErrorCode::Success as i32, - Err(e) => { - set_last_error(&e.to_string()); - FFIErrorCode::from(e) as i32 - } - } -} - /// Performs a test synchronization of the SPV client /// /// # Parameters @@ -668,7 +554,7 @@ pub unsafe extern "C" fn dash_spv_ffi_client_test_sync(client: *mut FFIDashSpvCl let client = &(*client); let result = client.runtime.block_on(async { - let mut spv_client = { + let spv_client = { let mut guard = client.inner.lock().unwrap(); match guard.take() { Some(client) => client, @@ -689,18 +575,6 @@ pub unsafe extern "C" fn dash_spv_ffi_client_test_sync(client: *mut FFIDashSpvCl }; tracing::info!("Initial height: {}", start_height); - // Start sync - match spv_client.sync_to_tip().await { - Ok(_) => tracing::info!("Sync started successfully"), - Err(e) => { - tracing::error!("Failed to start sync: {}", e); - // put back before returning - let mut guard = client.inner.lock().unwrap(); - *guard = Some(spv_client); - return Err(e); - } - } - // Wait a bit for headers to download tokio::time::sleep(Duration::from_secs(10)).await; diff --git a/dash-spv-ffi/tests/c_tests/test_advanced.c b/dash-spv-ffi/tests/c_tests/test_advanced.c index 1813c4c20..66429ee6c 100644 --- a/dash-spv-ffi/tests/c_tests/test_advanced.c +++ b/dash-spv-ffi/tests/c_tests/test_advanced.c @@ -299,25 +299,9 @@ void test_callbacks_with_operations() { FFIDashSpvClient* client = dash_spv_ffi_client_new(config); TEST_ASSERT(client != NULL); - CallbackData callback_data = {0}; - - FFICallbacks callbacks = {0}; - callbacks.on_progress = real_progress_callback; - callbacks.on_completion = real_completion_callback; - callbacks.on_data = NULL; - callbacks.user_data = &callback_data; - - // Start sync operation - int32_t result = dash_spv_ffi_client_sync_to_tip(client, callbacks); - // Wait a bit for callbacks usleep(100000); // 100ms - // Callbacks might or might not be called depending on network - printf("Progress callbacks: %d, Completion: %d\n", - callback_data.progress_count, - callback_data.completion_called); - dash_spv_ffi_client_destroy(client); dash_spv_ffi_config_destroy(config); diff --git a/dash-spv-ffi/tests/integration/test_full_workflow.rs b/dash-spv-ffi/tests/integration/test_full_workflow.rs index fa79d8f7c..cf0ceb09c 100644 --- a/dash-spv-ffi/tests/integration/test_full_workflow.rs +++ b/dash-spv-ffi/tests/integration/test_full_workflow.rs @@ -100,9 +100,6 @@ mod tests { // Start the client let result = dash_spv_ffi_client_start(ctx.client); - // Start syncing - let sync_result = dash_spv_ffi_client_sync_to_tip(ctx.client, callbacks); - // Wait for sync to complete or timeout let start = Instant::now(); let timeout = Duration::from_secs(10); @@ -391,11 +388,7 @@ mod tests { // 1. Start without peers let result = dash_spv_ffi_client_start(ctx.client); - // 2. Try to sync without being started (if not started above) - let callbacks = FFICallbacks::default(); - let sync_result = dash_spv_ffi_client_sync_to_tip(ctx.client, callbacks); - - // 3. Add invalid address + // 2. Add invalid address let invalid_addr = CString::new("invalid_address").unwrap(); let watch_result = dash_spv_ffi_client_watch_address(ctx.client, invalid_addr.as_ptr()); assert_eq!(watch_result, FFIErrorCode::InvalidArgument as i32); @@ -516,17 +509,6 @@ mod tests { // Start with network issues let start_result = dash_spv_ffi_client_start(ctx.client); - // Try to sync with poor connectivity - let sync_start = Instant::now(); - let callbacks = FFICallbacks { - on_progress: None, - on_completion: None, - on_data: None, - user_data: std::ptr::null_mut(), - }; - - dash_spv_ffi_client_sync_to_tip(ctx.client, callbacks); - // Should handle timeouts gracefully thread::sleep(Duration::from_secs(3)); diff --git a/dash-spv-ffi/tests/test_event_callbacks.rs b/dash-spv-ffi/tests/test_event_callbacks.rs index 9f01ad1ba..9e1838038 100644 --- a/dash-spv-ffi/tests/test_event_callbacks.rs +++ b/dash-spv-ffi/tests/test_event_callbacks.rs @@ -186,13 +186,6 @@ fn test_event_callbacks_setup() { println!("Client started, waiting for events..."); - // Try to sync for a short time to see if we get any events - println!("Starting sync to trigger events..."); - let sync_result = dash_spv_ffi_client_test_sync(client); - if sync_result != 0 { - println!("Warning: Test sync failed"); - } - // Wait a bit for events to be processed thread::sleep(Duration::from_secs(5)); diff --git a/dash-spv-ffi/tests/unit/test_async_operations.rs b/dash-spv-ffi/tests/unit/test_async_operations.rs index aafc90856..5546a7151 100644 --- a/dash-spv-ffi/tests/unit/test_async_operations.rs +++ b/dash-spv-ffi/tests/unit/test_async_operations.rs @@ -83,7 +83,6 @@ mod tests { let (client, config, _temp_dir) = create_test_client(); assert!(!client.is_null()); - // Don't call sync_to_tip on unstarted client as it will hang // Instead, test that we can safely destroy a client with null callbacks // The test is really about null pointer safety, not sync functionality println!("Testing null callback safety without starting client"); @@ -103,7 +102,6 @@ mod tests { let (client, config, _temp_dir) = create_test_client(); assert!(!client.is_null()); - // Don't call sync_to_tip on unstarted client as it will hang // Test null user_data handling in a different way println!("Testing null user_data safety without starting client"); @@ -172,12 +170,6 @@ mod tests { // Stop client first to ensure sync fails dash_spv_ffi_client_stop(client); - dash_spv_ffi_client_sync_to_tip( - client, - Some(test_completion_callback), - &test_data as *const _ as *mut c_void, - ); - // Wait for completion let start = Instant::now(); while !test_data.completion_called.load(Ordering::SeqCst) @@ -303,13 +295,6 @@ mod tests { // Now test reentrancy by invoking callback directly and through FFI reentrant_callback(true, std::ptr::null(), &reentrant_data as *const _ as *mut c_void); - // Also test with a real async operation using sync_to_tip - let _sync_result = dash_spv_ffi_client_sync_to_tip( - client, - Some(reentrant_callback), - &reentrant_data as *const _ as *mut c_void, - ); - // Wait for operations to complete thread::sleep(Duration::from_millis(500)); diff --git a/dash-spv-ffi/tests/unit/test_client_lifecycle.rs b/dash-spv-ffi/tests/unit/test_client_lifecycle.rs index 752d8e356..6d031995b 100644 --- a/dash-spv-ffi/tests/unit/test_client_lifecycle.rs +++ b/dash-spv-ffi/tests/unit/test_client_lifecycle.rs @@ -90,7 +90,7 @@ mod tests { #[test] #[serial] - #[ignore] // Requires network - sync_to_tip hangs without peers + #[ignore] // Requires network fn test_client_destruction_while_operations_pending() { unsafe { let (config, _temp_dir) = create_test_config_with_dir(); @@ -99,7 +99,7 @@ mod tests { // Start a sync operation in background // Start sync (non-blocking) - dash_spv_ffi_client_sync_to_tip(client, None, std::ptr::null_mut()); + dash_spv_ffi_client_start(client); // Immediately destroy client (should handle pending operations) dash_spv_ffi_client_destroy(client); @@ -176,11 +176,6 @@ mod tests { FFIErrorCode::NullPointer as i32 ); - assert_eq!( - dash_spv_ffi_client_sync_to_tip(std::ptr::null_mut(), None, std::ptr::null_mut()), - FFIErrorCode::NullPointer as i32 - ); - 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()); diff --git a/dash-spv/README.md b/dash-spv/README.md index 9c7f0f50f..0bd1e6ac5 100644 --- a/dash-spv/README.md +++ b/dash-spv/README.md @@ -62,11 +62,11 @@ async fn main() -> Result<(), Box> { let mut client = DashSpvClient::new(config).await?; client.start().await?; - // Synchronize to tip - let progress = client.sync_to_tip().await?; - println!("Synced to height {}", progress.header_height); + let (_command_sender, command_receiver) = tokio::sync::mpsc::unbounded_channel(); + let shutdown_token = CancellationToken::new(); - client.stop().await?; + client.run(command_receiver, shutdown_token).await?; + Ok(()) } ``` diff --git a/dash-spv/examples/filter_sync.rs b/dash-spv/examples/filter_sync.rs index 6d0e7a395..9503136ef 100644 --- a/dash-spv/examples/filter_sync.rs +++ b/dash-spv/examples/filter_sync.rs @@ -42,9 +42,6 @@ async fn main() -> Result<(), Box> { println!("Starting synchronization with filter support..."); println!("Watching address: {:?}", watch_address); - // Full sync including filters - client.sync_to_tip().await?; - let (_command_sender, command_receiver) = tokio::sync::mpsc::unbounded_channel(); let shutdown_token = CancellationToken::new(); diff --git a/dash-spv/examples/simple_sync.rs b/dash-spv/examples/simple_sync.rs index 57e266fa2..373e30cc7 100644 --- a/dash-spv/examples/simple_sync.rs +++ b/dash-spv/examples/simple_sync.rs @@ -37,12 +37,6 @@ async fn main() -> Result<(), Box> { println!("Starting header synchronization..."); - // Sync headers only - let progress = client.sync_to_tip().await?; - - println!("Synchronization completed!"); - println!("Synced {} headers", progress.header_height); - // Get some statistics let stats = client.stats().await?; println!("Headers downloaded: {}", stats.headers_downloaded); diff --git a/dash-spv/examples/spv_with_wallet.rs b/dash-spv/examples/spv_with_wallet.rs index 0a15e6d61..f6d4a42da 100644 --- a/dash-spv/examples/spv_with_wallet.rs +++ b/dash-spv/examples/spv_with_wallet.rs @@ -38,11 +38,6 @@ async fn main() -> Result<(), Box> { println!("Starting SPV client..."); client.start().await?; - // Sync to the tip of the blockchain - println!("Syncing to blockchain tip..."); - let progress = client.sync_to_tip().await?; - println!("Synced to height: {}", progress.header_height); - // The wallet will automatically be notified of: // - New blocks via process_block() // - Mempool transactions via process_mempool_transaction() diff --git a/dash-spv/src/client/lifecycle.rs b/dash-spv/src/client/lifecycle.rs index 477e8cbee..ce061bc8d 100644 --- a/dash-spv/src/client/lifecycle.rs +++ b/dash-spv/src/client/lifecycle.rs @@ -211,12 +211,6 @@ impl DashSpvClient Result<()> { - self.sync_to_tip().await?; - Ok(()) - } - /// Initialize genesis block or checkpoint. pub(super) async fn initialize_genesis_block(&mut self) -> Result<()> { // Check if we already have any headers in storage diff --git a/dash-spv/src/client/sync_coordinator.rs b/dash-spv/src/client/sync_coordinator.rs index afb741f99..356e3c20c 100644 --- a/dash-spv/src/client/sync_coordinator.rs +++ b/dash-spv/src/client/sync_coordinator.rs @@ -1,7 +1,6 @@ //! Sync coordination and orchestration. //! //! This module contains the core sync orchestration logic: -//! - sync_to_tip: Initiate blockchain sync //! - monitor_network: Main event loop for processing network messages //! - Sync state persistence and restoration //! - Filter sync coordination @@ -24,41 +23,6 @@ use tokio::sync::mpsc::UnboundedReceiver; use tokio_util::sync::CancellationToken; impl DashSpvClient { - /// Synchronize to the tip of the blockchain. - pub async fn sync_to_tip(&mut self) -> Result { - let running = self.running.read().await; - if !*running { - return Err(SpvError::Config("Client not running".to_string())); - } - drop(running); - - // Prepare sync state but don't send requests (monitoring loop will handle that) - tracing::info!("Preparing sync state for monitoring loop..."); - let result = SyncProgress { - header_height: { - let storage = self.storage.lock().await; - storage.get_tip_height().await.unwrap_or(0) - }, - filter_header_height: { - let storage = self.storage.lock().await; - storage.get_filter_tip_height().await.map_err(SpvError::Storage)?.unwrap_or(0) - }, - ..SyncProgress::default() - }; - - // Update status display after initial sync - self.update_status_display().await; - - tracing::info!( - "✅ Prepared initial sync state - Headers: {}, Filter headers: {}", - result.header_height, - result.filter_header_height - ); - tracing::info!("📊 Sync requests will be sent by the monitoring loop"); - - Ok(result) - } - /// Run continuous monitoring for new blocks, ChainLocks, InstantLocks, etc. /// /// This is the sole network message receiver to prevent race conditions. diff --git a/dash-spv/src/lib.rs b/dash-spv/src/lib.rs index ca9ac22a4..472784574 100644 --- a/dash-spv/src/lib.rs +++ b/dash-spv/src/lib.rs @@ -20,6 +20,7 @@ //! use key_wallet_manager::wallet_manager::WalletManager; //! use std::sync::Arc; //! use tokio::sync::RwLock; +//! use tokio_util::sync::CancellationToken; //! //! #[tokio::main] //! async fn main() -> Result<(), Box> { @@ -36,12 +37,10 @@ //! let mut client = DashSpvClient::new(config.clone(), network, storage, wallet).await?; //! client.start().await?; //! -//! // Synchronize to the tip of the blockchain -//! let progress = client.sync_to_tip().await?; -//! println!("Synced to height {}", progress.header_height); +//! let (_command_sender, command_receiver) = tokio::sync::mpsc::unbounded_channel(); +//! let shutdown_token = CancellationToken::new(); //! -//! // Stop the client -//! client.stop().await?; +//! client.run(command_receiver, shutdown_token).await?; //! //! Ok(()) //! } diff --git a/dash-spv/src/main.rs b/dash-spv/src/main.rs index 8f98a3c46..5566c5116 100644 --- a/dash-spv/src/main.rs +++ b/dash-spv/src/main.rs @@ -609,22 +609,6 @@ async fn run_client( !monitored.is_empty() && !matches.get_flag("no-filters") }; - // Start synchronization first, then monitoring immediately - // The key is to minimize the gap between sync requests and monitoring startup - tracing::info!("Starting synchronization to tip..."); - match client.sync_to_tip().await { - Ok(progress) => { - tracing::info!("Synchronization requests sent! (actual sync happens asynchronously)"); - tracing::info!("Current Header height: {}", progress.header_height); - tracing::info!("Current Filter header height: {}", progress.filter_header_height); - tracing::info!("Current Masternode height: {}", progress.masternode_height); - } - Err(e) => { - tracing::error!("Synchronization startup failed: {}", e); - return Err(format!("SPV client synchronization startup failed: {}", e).into()); - } - } - // Start monitoring immediately after sync requests are sent tracing::info!("Starting network monitoring...");