Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
39 changes: 2 additions & 37 deletions dash-spv-ffi/FFI_API.md
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand Down Expand Up @@ -125,7 +125,7 @@ Functions: 2

### Utility Functions

Functions: 19
Functions: 17

| Function | Description | Module |
|----------|-------------|--------|
Expand All @@ -135,15 +135,13 @@ 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 |
| `dash_spv_ffi_client_record_send` | Record that we attempted to send a transaction by its txid | client |
| `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 |
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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
Expand Down
31 changes: 0 additions & 31 deletions dash-spv-ffi/include/dash_spv_ffi.h
Original file line number Diff line number Diff line change
Expand Up @@ -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],
Expand Down Expand Up @@ -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.
*
Expand Down Expand Up @@ -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).
*
Expand Down
1 change: 0 additions & 1 deletion dash-spv-ffi/scripts/generate_ffi_docs.py
Original file line number Diff line number Diff line change
Expand Up @@ -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")
Expand Down
53 changes: 1 addition & 52 deletions dash-spv-ffi/src/client.rs
Original file line number Diff line number Diff line change
@@ -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;
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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).
Expand Down
37 changes: 1 addition & 36 deletions dash-spv-ffi/src/types.rs
Original file line number Diff line number Diff line change
@@ -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};

Expand Down Expand Up @@ -200,41 +200,6 @@ impl From<ChainState> 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<SpvStats> 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
Expand Down
23 changes: 2 additions & 21 deletions dash-spv-ffi/tests/c_tests/test_advanced.c
Original file line number Diff line number Diff line change
Expand Up @@ -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);

Expand All @@ -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);
Expand All @@ -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,
Expand All @@ -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);
Expand Down
10 changes: 0 additions & 10 deletions dash-spv-ffi/tests/c_tests/test_integration.c
Original file line number Diff line number Diff line change
Expand Up @@ -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);
}

Expand Down
1 change: 0 additions & 1 deletion dash-spv-ffi/tests/integration/test_cross_language.rs
Original file line number Diff line number Diff line change
Expand Up @@ -104,7 +104,6 @@ mod tests {
// Check alignment of structs
assert!(std::mem::align_of::<FFISyncProgress>() <= 8);
assert!(std::mem::align_of::<FFIBalance>() <= 8);
assert!(std::mem::align_of::<FFISpvStats>() <= 8);

// Verify FFIString is pointer-sized
assert_eq!(std::mem::size_of::<FFIString>(), std::mem::size_of::<*mut c_char>());
Expand Down
10 changes: 0 additions & 10 deletions dash-spv-ffi/tests/test_client.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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());
}
}

Expand Down Expand Up @@ -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);
}
Expand Down
Loading
Loading