Skip to content

Commit e8b54f4

Browse files
fix: sync progress
1 parent ef7374d commit e8b54f4

9 files changed

Lines changed: 126 additions & 67 deletions

File tree

dash-spv-ffi/dash_spv_ffi.h

Lines changed: 12 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -70,19 +70,6 @@ typedef struct FFIString {
7070
uintptr_t length;
7171
} FFIString;
7272

73-
typedef struct FFIDetailedSyncProgress {
74-
uint32_t current_height;
75-
uint32_t total_height;
76-
double percentage;
77-
double headers_per_second;
78-
int64_t estimated_seconds_remaining;
79-
enum FFISyncStage stage;
80-
struct FFIString stage_message;
81-
uint32_t connected_peers;
82-
uint64_t total_headers;
83-
int64_t sync_start_timestamp;
84-
} FFIDetailedSyncProgress;
85-
8673
typedef struct FFISyncProgress {
8774
uint32_t header_height;
8875
uint32_t filter_header_height;
@@ -96,6 +83,18 @@ typedef struct FFISyncProgress {
9683
uint32_t last_synced_filter_height;
9784
} FFISyncProgress;
9885

86+
typedef struct FFIDetailedSyncProgress {
87+
uint32_t total_height;
88+
double percentage;
89+
double headers_per_second;
90+
int64_t estimated_seconds_remaining;
91+
enum FFISyncStage stage;
92+
struct FFIString stage_message;
93+
struct FFISyncProgress overview;
94+
uint64_t total_headers;
95+
int64_t sync_start_timestamp;
96+
} FFIDetailedSyncProgress;
97+
9998
typedef struct FFISpvStats {
10099
uint32_t connected_peers;
101100
uint32_t total_peers;

dash-spv-ffi/include/dash_spv_ffi.h

Lines changed: 12 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -70,19 +70,6 @@ typedef struct FFIString {
7070
uintptr_t length;
7171
} FFIString;
7272

73-
typedef struct FFIDetailedSyncProgress {
74-
uint32_t current_height;
75-
uint32_t total_height;
76-
double percentage;
77-
double headers_per_second;
78-
int64_t estimated_seconds_remaining;
79-
enum FFISyncStage stage;
80-
struct FFIString stage_message;
81-
uint32_t connected_peers;
82-
uint64_t total_headers;
83-
int64_t sync_start_timestamp;
84-
} FFIDetailedSyncProgress;
85-
8673
typedef struct FFISyncProgress {
8774
uint32_t header_height;
8875
uint32_t filter_header_height;
@@ -96,6 +83,18 @@ typedef struct FFISyncProgress {
9683
uint32_t last_synced_filter_height;
9784
} FFISyncProgress;
9885

86+
typedef struct FFIDetailedSyncProgress {
87+
uint32_t total_height;
88+
double percentage;
89+
double headers_per_second;
90+
int64_t estimated_seconds_remaining;
91+
enum FFISyncStage stage;
92+
struct FFIString stage_message;
93+
struct FFISyncProgress overview;
94+
uint64_t total_headers;
95+
int64_t sync_start_timestamp;
96+
} FFIDetailedSyncProgress;
97+
9998
typedef struct FFISpvStats {
10099
uint32_t connected_peers;
101100
uint32_t total_peers;

dash-spv-ffi/src/bin/ffi_cli.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -35,10 +35,10 @@ extern "C" fn on_detailed_progress(progress: *const FFIDetailedSyncProgress, _ud
3535
let p = &*progress;
3636
println!(
3737
"height {}/{} {:.2}% peers {} hps {:.1}",
38-
p.current_height,
38+
p.overview.header_height,
3939
p.total_height,
4040
p.percentage * 100.0,
41-
p.connected_peers,
41+
p.overview.peer_count,
4242
p.headers_per_second
4343
);
4444
}

dash-spv-ffi/src/types.rs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -97,14 +97,13 @@ impl From<SyncStage> for FFISyncStage {
9797

9898
#[repr(C)]
9999
pub struct FFIDetailedSyncProgress {
100-
pub current_height: u32,
101100
pub total_height: u32,
102101
pub percentage: f64,
103102
pub headers_per_second: f64,
104103
pub estimated_seconds_remaining: i64, // -1 if unknown
105104
pub stage: FFISyncStage,
106105
pub stage_message: FFIString,
107-
pub connected_peers: u32,
106+
pub overview: FFISyncProgress,
108107
pub total_headers: u64,
109108
pub sync_start_timestamp: i64,
110109
}
@@ -130,8 +129,9 @@ impl From<DetailedSyncProgress> for FFIDetailedSyncProgress {
130129
SyncStage::Failed(err) => err.clone(),
131130
};
132131

132+
let overview = FFISyncProgress::from(progress.sync_progress.clone());
133+
133134
FFIDetailedSyncProgress {
134-
current_height: progress.current_height,
135135
total_height: progress.peer_best_height,
136136
percentage: progress.percentage,
137137
headers_per_second: progress.headers_per_second,
@@ -141,7 +141,7 @@ impl From<DetailedSyncProgress> for FFIDetailedSyncProgress {
141141
.unwrap_or(-1),
142142
stage: progress.sync_stage.into(),
143143
stage_message: FFIString::new(&stage_message),
144-
connected_peers: progress.connected_peers as u32,
144+
overview,
145145
total_headers: progress.total_headers_processed,
146146
sync_start_timestamp: progress
147147
.sync_start_time

dash-spv/src/client/mod.rs

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -918,8 +918,21 @@ impl<
918918
crate::types::SyncStage::Complete
919919
};
920920

921+
let status_display = self.create_status_display().await;
922+
let mut sync_progress = match status_display.sync_progress().await {
923+
Ok(p) => p,
924+
Err(e) => {
925+
tracing::warn!("Failed to compute sync progress snapshot: {}", e);
926+
SyncProgress::default()
927+
}
928+
};
929+
930+
// Update peer count with the latest network information.
931+
sync_progress.peer_count = self.network.peer_count() as u32;
932+
sync_progress.header_height = current_height;
933+
921934
let progress = DetailedSyncProgress {
922-
current_height,
935+
sync_progress,
923936
peer_best_height: peer_best,
924937
percentage: if peer_best > 0 {
925938
(current_height as f64 / peer_best as f64 * 100.0).min(100.0)
@@ -937,7 +950,6 @@ impl<
937950
None
938951
},
939952
sync_stage,
940-
connected_peers: self.network.peer_count(),
941953
total_headers_processed: current_height as u64,
942954
total_bytes_downloaded,
943955
sync_start_time,

dash-spv/src/types.rs

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -85,8 +85,8 @@ impl Default for SyncProgress {
8585
/// Detailed sync progress with performance metrics.
8686
#[derive(Debug, Clone, Serialize, Deserialize)]
8787
pub struct DetailedSyncProgress {
88-
/// Current state
89-
pub current_height: u32,
88+
/// Snapshot of the core sync metrics for quick consumption.
89+
pub sync_progress: SyncProgress,
9090
pub peer_best_height: u32,
9191
pub percentage: f64,
9292

@@ -97,7 +97,6 @@ pub struct DetailedSyncProgress {
9797

9898
/// Detailed status
9999
pub sync_stage: SyncStage,
100-
pub connected_peers: usize,
101100
pub total_headers_processed: u64,
102101
pub total_bytes_downloaded: u64,
103102

@@ -130,15 +129,17 @@ impl DetailedSyncProgress {
130129
if self.peer_best_height == 0 {
131130
return 0.0;
132131
}
133-
((self.current_height as f64 / self.peer_best_height as f64) * 100.0).min(100.0)
132+
let current_height = self.sync_progress.header_height;
133+
((current_height as f64 / self.peer_best_height as f64) * 100.0).min(100.0)
134134
}
135135

136136
pub fn calculate_eta(&self) -> Option<Duration> {
137137
if self.headers_per_second <= 0.0 {
138138
return None;
139139
}
140140

141-
let remaining = self.peer_best_height.saturating_sub(self.current_height);
141+
let current_height = self.sync_progress.header_height;
142+
let remaining = self.peer_best_height.saturating_sub(current_height);
142143
if remaining == 0 {
143144
return Some(Duration::from_secs(0));
144145
}

swift-dash-core-sdk/Sources/DashSPVFFI/include/dash_spv_ffi.h

Lines changed: 31 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,7 @@ typedef struct FFIArray {
6161

6262
typedef struct FFIClientConfig {
6363
void *inner;
64+
uint32_t worker_threads;
6465

6566
} FFIClientConfig;
6667

@@ -69,19 +70,6 @@ typedef struct FFIString {
6970
uintptr_t length;
7071
} FFIString;
7172

72-
typedef struct FFIDetailedSyncProgress {
73-
uint32_t current_height;
74-
uint32_t total_height;
75-
double percentage;
76-
double headers_per_second;
77-
int64_t estimated_seconds_remaining;
78-
enum FFISyncStage stage;
79-
struct FFIString stage_message;
80-
uint32_t connected_peers;
81-
uint64_t total_headers;
82-
int64_t sync_start_timestamp;
83-
} FFIDetailedSyncProgress;
84-
8573
typedef struct FFISyncProgress {
8674
uint32_t header_height;
8775
uint32_t filter_header_height;
@@ -95,6 +83,18 @@ typedef struct FFISyncProgress {
9583
uint32_t last_synced_filter_height;
9684
} FFISyncProgress;
9785

86+
typedef struct FFIDetailedSyncProgress {
87+
uint32_t total_height;
88+
double percentage;
89+
double headers_per_second;
90+
int64_t estimated_seconds_remaining;
91+
enum FFISyncStage stage;
92+
struct FFIString stage_message;
93+
struct FFISyncProgress overview;
94+
uint64_t total_headers;
95+
int64_t sync_start_timestamp;
96+
} FFIDetailedSyncProgress;
97+
9898
typedef struct FFISpvStats {
9999
uint32_t connected_peers;
100100
uint32_t total_peers;
@@ -281,6 +281,14 @@ struct FFIArray dash_spv_ffi_checkpoints_between_heights(FFINetwork network,
281281
*/
282282
struct FFIDashSpvClient *dash_spv_ffi_client_new(const struct FFIClientConfig *config) ;
283283

284+
/**
285+
* Drain pending events and invoke configured callbacks (non-blocking).
286+
*
287+
* # Safety
288+
* - `client` must be a valid, non-null pointer.
289+
*/
290+
int32_t dash_spv_ffi_client_drain_events(struct FFIDashSpvClient *client) ;
291+
284292
/**
285293
* Update the running client's configuration.
286294
*
@@ -392,10 +400,8 @@ int32_t dash_spv_ffi_client_sync_to_tip_with_progress(struct FFIDashSpvClient *c
392400
/**
393401
* Cancels the sync operation.
394402
*
395-
* **Note**: This function currently only stops the SPV client and clears sync callbacks,
396-
* but does not fully abort the ongoing sync process. The sync operation may continue
397-
* running in the background until it completes naturally. Full sync cancellation with
398-
* proper task abortion is not yet implemented.
403+
* This stops the SPV client, clears callbacks, and joins active threads so the sync
404+
* operation halts immediately.
399405
*
400406
* # Safety
401407
* The client pointer must be valid and non-null.
@@ -704,6 +710,14 @@ int32_t dash_spv_ffi_config_set_masternode_sync_enabled(struct FFIClientConfig *
704710
void dash_spv_ffi_config_destroy(struct FFIClientConfig *config)
705711
;
706712

713+
/**
714+
* Sets the number of Tokio worker threads for the FFI runtime (0 = auto)
715+
*
716+
* # Safety
717+
* - `config` must be a valid pointer to an FFIClientConfig
718+
*/
719+
int32_t dash_spv_ffi_config_set_worker_threads(struct FFIClientConfig *config, uint32_t threads) ;
720+
707721
/**
708722
* Enables or disables mempool tracking
709723
*

swift-dash-core-sdk/Sources/SwiftDashCoreSDK/Core/SPVClient.swift

Lines changed: 11 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -8,17 +8,19 @@ import Network
88

99
/// Detailed sync progress information with real-time statistics
1010
public struct DetailedSyncProgress: Sendable, Equatable {
11-
public let currentHeight: UInt32
11+
public let overview: SyncProgress
1212
public let totalHeight: UInt32
1313
public let percentage: Double
1414
public let headersPerSecond: Double
1515
public let estimatedSecondsRemaining: Int64
1616
public let stage: SyncStage
1717
public let stageMessage: String
18-
public let connectedPeers: UInt32
1918
public let totalHeadersProcessed: UInt64
2019
public let syncStartTimestamp: Date
2120

21+
public var currentHeight: UInt32 { overview.currentHeight }
22+
public var connectedPeers: UInt32 { overview.peerCount }
23+
2224
/// Calculated properties
2325
public var blocksRemaining: UInt32 {
2426
guard totalHeight > currentHeight else { return 0 }
@@ -65,39 +67,36 @@ public struct DetailedSyncProgress: Sendable, Equatable {
6567

6668
/// Public initializer for creating DetailedSyncProgress
6769
public init(
68-
currentHeight: UInt32,
70+
overview: SyncProgress,
6971
totalHeight: UInt32,
7072
percentage: Double,
7173
headersPerSecond: Double,
7274
estimatedSecondsRemaining: Int64,
7375
stage: SyncStage,
7476
stageMessage: String,
75-
connectedPeers: UInt32,
7677
totalHeadersProcessed: UInt64,
7778
syncStartTimestamp: Date
7879
) {
79-
self.currentHeight = currentHeight
80+
self.overview = overview
8081
self.totalHeight = totalHeight
8182
self.percentage = percentage
8283
self.headersPerSecond = headersPerSecond
8384
self.estimatedSecondsRemaining = estimatedSecondsRemaining
8485
self.stage = stage
8586
self.stageMessage = stageMessage
86-
self.connectedPeers = connectedPeers
8787
self.totalHeadersProcessed = totalHeadersProcessed
8888
self.syncStartTimestamp = syncStartTimestamp
8989
}
9090

9191
/// Initialize from FFI type
9292
internal init(ffiProgress: FFIDetailedSyncProgress) {
93-
self.currentHeight = ffiProgress.current_height
93+
self.overview = SyncProgress(ffiProgress: ffiProgress.overview)
9494
self.totalHeight = ffiProgress.total_height
9595
self.percentage = ffiProgress.percentage
9696
self.headersPerSecond = ffiProgress.headers_per_second
9797
self.estimatedSecondsRemaining = ffiProgress.estimated_seconds_remaining
9898
self.stage = SyncStage(ffiStage: ffiProgress.stage)
9999
self.stageMessage = String(cString: ffiProgress.stage_message.ptr)
100-
self.connectedPeers = ffiProgress.connected_peers
101100
self.totalHeadersProcessed = ffiProgress.total_headers
102101
self.syncStartTimestamp = Date(timeIntervalSince1970: TimeInterval(ffiProgress.sync_start_timestamp))
103102
}
@@ -308,6 +307,9 @@ extension DetailedSyncProgress {
308307
"Time Remaining": formattedTimeRemaining,
309308
"Connected Peers": "\(connectedPeers)",
310309
"Headers Processed": "\(totalHeadersProcessed)",
310+
"Filter Header Height": "\(overview.filterHeaderHeight)",
311+
"Filters Downloaded": "\(overview.filtersDownloaded)",
312+
"Peer Count": "\(overview.peerCount)",
311313
"Duration": formattedSyncDuration
312314
]
313315
}
@@ -1240,4 +1242,4 @@ extension SPVClient {
12401242
public func syncProgressStream() -> SyncProgressStream {
12411243
return SyncProgressStream(client: self)
12421244
}
1243-
}
1245+
}

0 commit comments

Comments
 (0)