Skip to content
Merged
Show file tree
Hide file tree
Changes from 13 commits
Commits
Show all changes
16 commits
Select commit Hold shift + click to select a range
821130c
fix: remove unneeded peer_reputation.json file
PastaPastaPasta Aug 27, 2025
37278b2
chore: remove unneeded peer_reputation.json
PastaPastaPasta Aug 27, 2025
2c7517b
fix: resolve all compiler warnings in dash-spv and dash-spv-ffi
PastaPastaPasta Aug 27, 2025
290591b
Remove unused variable in dash_spv_ffi_client_get_balance_with_mempool
PastaPastaPasta Aug 27, 2025
8cb60a0
dash-spv: ignore long-running real-node tests via #[ignore]\n\n dash-…
PastaPastaPasta Aug 27, 2025
2e58f57
chore(spv): resolve warnings and remove dead code; add feature gate f…
PastaPastaPasta Aug 27, 2025
ad3ba8f
fix: resolve all compiler warnings in dash-spv-ffi package
PastaPastaPasta Aug 27, 2025
1709656
fix: resolve compiler warnings in dash-spv package
PastaPastaPasta Aug 27, 2025
cce215f
Replace hardcoded addresses with deterministic P2PKH generation
PastaPastaPasta Aug 27, 2025
bf0ab36
fix: refactor WatchItem test helpers to use snake_case
PastaPastaPasta Aug 27, 2025
d9e6ead
fix: add owned array destroyer for address history
PastaPastaPasta Aug 27, 2025
e1fea31
ffi(test_error_handling): fix UB by matching extern "C" signature and…
PastaPastaPasta Aug 27, 2025
fcf86c0
Fix compilation errors in dash-spv tests
PastaPastaPasta Aug 28, 2025
51aa741
dashcore: fix all-features test build
PastaPastaPasta Aug 28, 2025
749805e
Fix critical compilation error in dashcore-rpc
PastaPastaPasta Aug 28, 2025
4529dcd
fix: resolve test concurrency issue in dash-spv-ffi error handling
PastaPastaPasta Aug 28, 2025
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
1 change: 1 addition & 0 deletions dash-network/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ use std::fmt;
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
#[cfg_attr(feature = "serde", serde(rename_all = "lowercase"))]
#[non_exhaustive]
#[repr(u8)]
#[cfg_attr(feature = "bincode", derive(Encode, Decode))]
pub enum Network {
/// Classic Dash Core Payment Chain
Expand Down
85 changes: 47 additions & 38 deletions dash-spv-ffi/include/dash_spv_ffi.h
Original file line number Diff line number Diff line change
Expand Up @@ -32,13 +32,13 @@ typedef enum FFIValidationMode {
Full = 2,
} FFIValidationMode;

typedef struct FFIClientConfig FFIClientConfig;

/**
* FFIDashSpvClient structure
*/
typedef struct FFIDashSpvClient FFIDashSpvClient;

typedef ClientConfig FFIClientConfig;

Comment on lines +40 to +41
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue

C typedef is invalid: ClientConfig is unknown in C

Revert to an opaque forward-declared struct. Current typedef will break all C consumers.

-typedef ClientConfig FFIClientConfig;
+typedef struct FFIClientConfig FFIClientConfig;
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
typedef ClientConfig FFIClientConfig;
++ b/dash-spv-ffi/include/dash_spv_ffi.h
@@ -136,1 +136,1 @@
typedef struct FFIClientConfig FFIClientConfig;
🤖 Prompt for AI Agents
In dash-spv-ffi/include/dash_spv_ffi.h around lines 136-137, the line "typedef
ClientConfig FFIClientConfig;" is invalid for C consumers because ClientConfig
is a C++ type and unknown in C; revert this to an opaque forward-declared struct
by declaring an incomplete struct type for FFIClientConfig and using that as the
typedef (i.e., expose only an opaque pointer-compatible type in the header),
ensuring the header contains no C++-only type names so C callers can compile.

typedef struct FFIString {
char *ptr;
uintptr_t length;
Expand Down Expand Up @@ -100,6 +100,8 @@ typedef struct FFIArray {
void *data;
uintptr_t len;
uintptr_t capacity;
uintptr_t elem_size;
uintptr_t elem_align;
} FFIArray;

typedef void (*BlockCallback)(uint32_t height, const uint8_t (*hash)[32], void *user_data);
Expand Down Expand Up @@ -209,7 +211,7 @@ typedef struct FFIUnconfirmedTransaction {
uintptr_t addresses_len;
} FFIUnconfirmedTransaction;

struct FFIDashSpvClient *dash_spv_ffi_client_new(const struct FFIClientConfig *config);
struct FFIDashSpvClient *dash_spv_ffi_client_new(const FFIClientConfig *config);

int32_t dash_spv_ffi_client_start(struct FFIDashSpvClient *client);

Expand Down Expand Up @@ -315,10 +317,10 @@ bool dash_spv_ffi_client_is_filter_sync_available(struct FFIDashSpvClient *clien
FFIBalance *dash_spv_ffi_client_get_address_balance(struct FFIDashSpvClient *client,
const char *address);

struct FFIArray dash_spv_ffi_client_get_utxos(struct FFIDashSpvClient *client);
struct FFIArray *dash_spv_ffi_client_get_utxos(struct FFIDashSpvClient *client);

struct FFIArray dash_spv_ffi_client_get_utxos_for_address(struct FFIDashSpvClient *client,
const char *address);
struct FFIArray *dash_spv_ffi_client_get_utxos_for_address(struct FFIDashSpvClient *client,
const char *address);

Comment on lines +320 to 324
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Verification agent

🧩 Analysis chain

API surface changes to pointer-returning arrays look coherent

Signatures align with Rust. Once owned/typed destroyers are added and documented, this is good.

Run to ensure Swift header sync is updated after regen:

Also applies to: 509-511, 535-537, 746-748


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "Public header decls for new owned/typed destroyers:"
rg -n 'dash_spv_ffi_(array_destroy_owned|string_array_destroy_owned|utxo_array_destroy)' dash-spv-ffi/include/dash_spv_ffi.h || true

echo
echo "Swift SDK header sync check:"
# Expect these to exist after sync if SDK mirrors FFI header
rg -n 'dash_spv_ffi_(array_destroy_owned|string_array_destroy_owned|utxo_array_destroy)' swift-dash-core-sdk/Sources/DashSPVFFI/include/dash_spv_ffi.h || true

Length of output: 501


Add missing owned/typed destroyers and sync Swift header

It looks like the new destroyer functions aren’t present in either the C public header or its Swift mirror. These are critical for FFI memory safety and must be added before merging.

Locations needing updates:

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

Suggested additions to dash-spv-ffi/include/dash_spv_ffi.h:

/// Releases ownership of an FFIArray returned from the FFI.
/// Caller must invoke this to avoid leaks.
void dash_spv_ffi_array_destroy_owned(struct FFIArray *array);

/// Releases ownership of a string-array returned from the FFI.
/// Caller must invoke this to avoid leaks.
void dash_spv_ffi_string_array_destroy_owned(struct FFIArray *array);

/// Releases ownership of a UTXO-array returned from the FFI.
/// Caller must invoke this to avoid leaks.
void dash_spv_ffi_utxo_array_destroy(struct FFIArray *array);

After adding these to the C header, regenerate and commit the synced header in the Swift SDK at:

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

so it mirrors the updated declarations.

🤖 Prompt for AI Agents
In dash-spv-ffi/include/dash_spv_ffi.h around lines 487-491 the new FFI
destroyer functions for owned/typed arrays are missing; add declarations for
dash_spv_ffi_array_destroy_owned(struct FFIArray *array),
dash_spv_ffi_string_array_destroy_owned(struct FFIArray *array), and
dash_spv_ffi_utxo_array_destroy(struct FFIArray *array) to the public C header,
then regenerate and commit the mirrored header at
swift-dash-core-sdk/Sources/DashSPVFFI/include/dash_spv_ffi.h so the Swift SDK
matches the updated C declarations.

int32_t dash_spv_ffi_client_set_event_callbacks(struct FFIDashSpvClient *client,
struct FFIEventCallbacks callbacks);
Expand All @@ -337,18 +339,18 @@ int32_t dash_spv_ffi_client_watch_script(struct FFIDashSpvClient *client, const

int32_t dash_spv_ffi_client_unwatch_script(struct FFIDashSpvClient *client, const char *script_hex);

struct FFIArray dash_spv_ffi_client_get_address_history(struct FFIDashSpvClient *client,
const char *address);
struct FFIArray *dash_spv_ffi_client_get_address_history(struct FFIDashSpvClient *client,
const char *address);

struct FFITransaction *dash_spv_ffi_client_get_transaction(struct FFIDashSpvClient *client,
const char *txid);

int32_t dash_spv_ffi_client_broadcast_transaction(struct FFIDashSpvClient *client,
const char *tx_hex);

struct FFIArray dash_spv_ffi_client_get_watched_addresses(struct FFIDashSpvClient *client);
struct FFIArray *dash_spv_ffi_client_get_watched_addresses(struct FFIDashSpvClient *client);

struct FFIArray dash_spv_ffi_client_get_watched_scripts(struct FFIDashSpvClient *client);
struct FFIArray *dash_spv_ffi_client_get_watched_scripts(struct FFIDashSpvClient *client);

Comment on lines +351 to 354
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion

Clarify element type for watched addresses/scripts and required destructor

Document these as arrays of FFIString* and point to dash_spv_ffi_string_array_destroy_owned().

-struct FFIArray *dash_spv_ffi_client_get_watched_addresses(struct FFIDashSpvClient *client);
+/* Returns an FFIArray of FFIString* (addresses). Free with dash_spv_ffi_string_array_destroy_owned(). */
+struct FFIArray *dash_spv_ffi_client_get_watched_addresses(struct FFIDashSpvClient *client);
@@
-struct FFIArray *dash_spv_ffi_client_get_watched_scripts(struct FFIDashSpvClient *client);
+/* Returns an FFIArray of FFIString* (hex scripts). Free with dash_spv_ffi_string_array_destroy_owned(). */
+struct FFIArray *dash_spv_ffi_client_get_watched_scripts(struct FFIDashSpvClient *client);

Also applies to: 740-742

🤖 Prompt for AI Agents
In dash-spv-ffi/include/dash_spv_ffi.h around lines 518-521 (and similarly at
740-742), the declarations for dash_spv_ffi_client_get_watched_addresses and
dash_spv_ffi_client_get_watched_scripts lack documentation of the element type
and the required destructor; update the comments for these functions to state
they return an FFIArray of FFIString* (i.e., an array whose elements are
FFIString pointers) and explicitly instruct callers to free the returned array
with dash_spv_ffi_string_array_destroy_owned().

FFIBalance *dash_spv_ffi_client_get_total_balance(struct FFIDashSpvClient *client);

Expand All @@ -363,8 +365,8 @@ int32_t dash_spv_ffi_client_is_transaction_confirmed(struct FFIDashSpvClient *cl

void dash_spv_ffi_transaction_destroy(struct FFITransaction *tx);

struct FFIArray dash_spv_ffi_client_get_address_utxos(struct FFIDashSpvClient *client,
const char *address);
struct FFIArray *dash_spv_ffi_client_get_address_utxos(struct FFIDashSpvClient *client,
const char *address);

int32_t dash_spv_ffi_client_enable_mempool_tracking(struct FFIDashSpvClient *client,
enum FFIMempoolStrategy strategy);
Expand All @@ -378,57 +380,54 @@ int32_t dash_spv_ffi_client_record_send(struct FFIDashSpvClient *client, const c
FFIBalance *dash_spv_ffi_client_get_mempool_balance(struct FFIDashSpvClient *client,
const char *address);

struct FFIClientConfig *dash_spv_ffi_config_new(enum FFINetwork network);
FFIClientConfig *dash_spv_ffi_config_new(enum FFINetwork network);

struct FFIClientConfig *dash_spv_ffi_config_mainnet(void);
FFIClientConfig *dash_spv_ffi_config_mainnet(void);

struct FFIClientConfig *dash_spv_ffi_config_testnet(void);
FFIClientConfig *dash_spv_ffi_config_testnet(void);

int32_t dash_spv_ffi_config_set_data_dir(struct FFIClientConfig *config, const char *path);
int32_t dash_spv_ffi_config_set_data_dir(FFIClientConfig *config, const char *path);

int32_t dash_spv_ffi_config_set_validation_mode(struct FFIClientConfig *config,
int32_t dash_spv_ffi_config_set_validation_mode(FFIClientConfig *config,
enum FFIValidationMode mode);

int32_t dash_spv_ffi_config_set_max_peers(struct FFIClientConfig *config, uint32_t max_peers);
int32_t dash_spv_ffi_config_set_max_peers(FFIClientConfig *config, uint32_t max_peers);

int32_t dash_spv_ffi_config_add_peer(struct FFIClientConfig *config, const char *addr);
int32_t dash_spv_ffi_config_add_peer(FFIClientConfig *config, const char *addr);

int32_t dash_spv_ffi_config_set_user_agent(struct FFIClientConfig *config, const char *user_agent);
int32_t dash_spv_ffi_config_set_user_agent(FFIClientConfig *config, const char *user_agent);

int32_t dash_spv_ffi_config_set_relay_transactions(struct FFIClientConfig *config, bool _relay);
int32_t dash_spv_ffi_config_set_relay_transactions(FFIClientConfig *config, bool _relay);

int32_t dash_spv_ffi_config_set_filter_load(struct FFIClientConfig *config, bool load_filters);
int32_t dash_spv_ffi_config_set_filter_load(FFIClientConfig *config, bool load_filters);

enum FFINetwork dash_spv_ffi_config_get_network(const struct FFIClientConfig *config);
enum FFINetwork dash_spv_ffi_config_get_network(const FFIClientConfig *config);

struct FFIString dash_spv_ffi_config_get_data_dir(const struct FFIClientConfig *config);
struct FFIString dash_spv_ffi_config_get_data_dir(const FFIClientConfig *config);

void dash_spv_ffi_config_destroy(struct FFIClientConfig *config);
void dash_spv_ffi_config_destroy(FFIClientConfig *config);

int32_t dash_spv_ffi_config_set_mempool_tracking(struct FFIClientConfig *config, bool enable);
int32_t dash_spv_ffi_config_set_mempool_tracking(FFIClientConfig *config, bool enable);

int32_t dash_spv_ffi_config_set_mempool_strategy(struct FFIClientConfig *config,
int32_t dash_spv_ffi_config_set_mempool_strategy(FFIClientConfig *config,
enum FFIMempoolStrategy strategy);

int32_t dash_spv_ffi_config_set_max_mempool_transactions(struct FFIClientConfig *config,
int32_t dash_spv_ffi_config_set_max_mempool_transactions(FFIClientConfig *config,
uint32_t max_transactions);

int32_t dash_spv_ffi_config_set_mempool_timeout(struct FFIClientConfig *config,
uint64_t timeout_secs);
int32_t dash_spv_ffi_config_set_mempool_timeout(FFIClientConfig *config, uint64_t timeout_secs);

int32_t dash_spv_ffi_config_set_fetch_mempool_transactions(struct FFIClientConfig *config,
bool fetch);
int32_t dash_spv_ffi_config_set_fetch_mempool_transactions(FFIClientConfig *config, bool fetch);

int32_t dash_spv_ffi_config_set_persist_mempool(struct FFIClientConfig *config, bool persist);
int32_t dash_spv_ffi_config_set_persist_mempool(FFIClientConfig *config, bool persist);

bool dash_spv_ffi_config_get_mempool_tracking(const struct FFIClientConfig *config);
bool dash_spv_ffi_config_get_mempool_tracking(const FFIClientConfig *config);

enum FFIMempoolStrategy dash_spv_ffi_config_get_mempool_strategy(const struct FFIClientConfig *config);
enum FFIMempoolStrategy dash_spv_ffi_config_get_mempool_strategy(const FFIClientConfig *config);

int32_t dash_spv_ffi_config_set_start_from_height(struct FFIClientConfig *config, uint32_t height);
int32_t dash_spv_ffi_config_set_start_from_height(FFIClientConfig *config, uint32_t height);

int32_t dash_spv_ffi_config_set_wallet_creation_time(struct FFIClientConfig *config,
uint32_t timestamp);
int32_t dash_spv_ffi_config_set_wallet_creation_time(FFIClientConfig *config, uint32_t timestamp);

const char *dash_spv_ffi_get_last_error(void);

Expand Down Expand Up @@ -490,6 +489,16 @@ void dash_spv_ffi_string_destroy(struct FFIString s);

void dash_spv_ffi_array_destroy(struct FFIArray *arr);

/**
* Destroy an array of FFIString pointers (Vec<*mut FFIString>) and their contents.
*
* This function:
* - Iterates the array elements as pointers to FFIString and destroys each via dash_spv_ffi_string_destroy
* - Frees the underlying vector buffer stored in FFIArray
* - Does not free the FFIArray struct itself (safe for both stack- and heap-allocated structs)
*/
void dash_spv_ffi_string_array_destroy(struct FFIArray *arr);

Comment on lines +492 to +501
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue

Missing owned and typed array destroyers in public header

Add owned variants and a typed UTXO array destroyer to prevent leaks of FFIArray and inner FFIString fields.

 void dash_spv_ffi_string_array_destroy(struct FFIArray *arr);
+
+// Owned/typed destroyers for heap-allocated arrays returned by the FFI
+void dash_spv_ffi_array_destroy_owned(struct FFIArray *arr);
+void dash_spv_ffi_string_array_destroy_owned(struct FFIArray *arr);
+void dash_spv_ffi_utxo_array_destroy(struct FFIArray *arr);
+void dash_spv_ffi_utxo_array_destroy_owned(struct FFIArray *arr);
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
/**
* Destroy an array of FFIString pointers (Vec<*mut FFIString>) and their contents.
*
* This function:
* - Iterates the array elements as pointers to FFIString and destroys each via dash_spv_ffi_string_destroy
* - Frees the underlying vector buffer stored in FFIArray
* - Does not free the FFIArray struct itself (safe for both stack- and heap-allocated structs)
*/
void dash_spv_ffi_string_array_destroy(struct FFIArray *arr);
/**
* Destroy an array of FFIString pointers (Vec<*mut FFIString>) and their contents.
*
* This function:
* - Iterates the array elements as pointers to FFIString and destroys each via dash_spv_ffi_string_destroy
* - Frees the underlying vector buffer stored in FFIArray
* - Does not free the FFIArray struct itself (safe for both stack- and heap-allocated structs)
*/
void dash_spv_ffi_string_array_destroy(struct FFIArray *arr);
// Owned/typed destroyers for heap-allocated arrays returned by the FFI
void dash_spv_ffi_array_destroy_owned(struct FFIArray *arr);
void dash_spv_ffi_string_array_destroy_owned(struct FFIArray *arr);
void dash_spv_ffi_utxo_array_destroy(struct FFIArray *arr);
void dash_spv_ffi_utxo_array_destroy_owned(struct FFIArray *arr);
🤖 Prompt for AI Agents
In dash-spv-ffi/include/dash_spv_ffi.h around lines 659 to 668, the public
header currently exposes dash_spv_ffi_string_array_destroy which frees the inner
FFIString elements and the vector buffer but does not free the FFIArray struct
itself; add two new declarations: an "owned" variant (e.g.,
dash_spv_ffi_string_array_destroy_owned) that performs the same work and also
frees the FFIArray struct pointer, and a typed UTXO array destroyer (e.g.,
dash_spv_ffi_utxo_array_destroy and dash_spv_ffi_utxo_array_destroy_owned) that
iterates and properly destroys each UTXO element's inner fields and frees the
vector buffer (and the struct for the owned variant) to prevent leaks of
FFIArray and inner FFIString/UTXO fields.

/**
* Destroys the raw transaction bytes allocated for an FFIUnconfirmedTransaction
*
Expand Down
79 changes: 0 additions & 79 deletions dash-spv-ffi/peer_reputation.json

This file was deleted.

Loading
Loading