Skip to content

Commit 759bf25

Browse files
feat: add functions to update client configuration and enable masternode sync
1 parent 018a32a commit 759bf25

File tree

5 files changed

+170
-2
lines changed

5 files changed

+170
-2
lines changed

dash-spv-ffi/FFI_API.md

Lines changed: 36 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ This document provides a comprehensive reference for all FFI (Foreign Function I
44

55
**Auto-generated**: This documentation is automatically generated from the source code. Do not edit manually.
66

7-
**Total Functions**: 61
7+
**Total Functions**: 63
88

99
## Table of Contents
1010

@@ -34,10 +34,11 @@ Functions: 4
3434

3535
### Configuration
3636

37-
Functions: 23
37+
Functions: 25
3838

3939
| Function | Description | Module |
4040
|----------|-------------|--------|
41+
| `dash_spv_ffi_client_update_config` | Update the running client's configuration | client |
4142
| `dash_spv_ffi_config_add_peer` | Adds a peer address to the configuration # Safety - `config` must be a valid... | config |
4243
| `dash_spv_ffi_config_destroy` | Destroys an FFIClientConfig and frees its memory # Safety - `config` must be... | config |
4344
| `dash_spv_ffi_config_get_data_dir` | Gets the data directory path from the configuration # Safety - `config` must... | config |
@@ -49,6 +50,7 @@ Functions: 23
4950
| `dash_spv_ffi_config_set_data_dir` | Sets the data directory for storing blockchain data # Safety - `config` must... | config |
5051
| `dash_spv_ffi_config_set_fetch_mempool_transactions` | Sets whether to fetch full mempool transaction data # Safety - `config` must... | config |
5152
| `dash_spv_ffi_config_set_filter_load` | Sets whether to load bloom filters # Safety - `config` must be a valid point... | config |
53+
| `dash_spv_ffi_config_set_masternode_sync_enabled` | Enables or disables masternode synchronization # Safety - `config` must be a... | config |
5254
| `dash_spv_ffi_config_set_max_mempool_transactions` | Sets the maximum number of mempool transactions to track # Safety - `config`... | config |
5355
| `dash_spv_ffi_config_set_max_peers` | Sets the maximum number of peers to connect to # Safety - `config` must be a... | config |
5456
| `dash_spv_ffi_config_set_mempool_strategy` | Sets the mempool synchronization strategy # Safety - `config` must be a vali... | config |
@@ -198,6 +200,22 @@ dash_spv_ffi_client_stop(client: *mut FFIDashSpvClient) -> i32
198200

199201
### Configuration - Detailed
200202

203+
#### `dash_spv_ffi_client_update_config`
204+
205+
```c
206+
dash_spv_ffi_client_update_config(client: *mut FFIDashSpvClient, config: *const FFIClientConfig,) -> i32
207+
```
208+
209+
**Description:**
210+
Update the running client's configuration. # Safety - `client` must be a valid pointer to an `FFIDashSpvClient`. - `config` must be a valid pointer to an `FFIClientConfig`. - The network in `config` must match the client's network; changing networks at runtime is not supported.
211+
212+
**Safety:**
213+
- `client` must be a valid pointer to an `FFIDashSpvClient`. - `config` must be a valid pointer to an `FFIClientConfig`. - The network in `config` must match the client's network; changing networks at runtime is not supported.
214+
215+
**Module:** `client`
216+
217+
---
218+
201219
#### `dash_spv_ffi_config_add_peer`
202220
203221
```c
@@ -362,6 +380,22 @@ Sets whether to load bloom filters # Safety - `config` must be a valid pointer
362380

363381
---
364382

383+
#### `dash_spv_ffi_config_set_masternode_sync_enabled`
384+
385+
```c
386+
dash_spv_ffi_config_set_masternode_sync_enabled(config: *mut FFIClientConfig, enable: bool,) -> i32
387+
```
388+
389+
**Description:**
390+
Enables or disables masternode synchronization # Safety - `config` must be a valid pointer to an FFIClientConfig created by dash_spv_ffi_config_new/mainnet/testnet - The caller must ensure the config pointer remains valid for the duration of this call
391+
392+
**Safety:**
393+
- `config` must be a valid pointer to an FFIClientConfig created by dash_spv_ffi_config_new/mainnet/testnet - The caller must ensure the config pointer remains valid for the duration of this call
394+
395+
**Module:** `config`
396+
397+
---
398+
365399
#### `dash_spv_ffi_config_set_max_mempool_transactions`
366400
367401
```c

dash-spv-ffi/include/dash_spv_ffi.h

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -198,6 +198,17 @@ typedef struct FFIUnconfirmedTransaction {
198198

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

201+
/**
202+
* Update the running client's configuration.
203+
*
204+
* # Safety
205+
* - `client` must be a valid pointer to an `FFIDashSpvClient`.
206+
* - `config` must be a valid pointer to an `FFIClientConfig`.
207+
* - The network in `config` must match the client's network; changing networks at runtime is not supported.
208+
*/
209+
int32_t dash_spv_ffi_client_update_config(struct FFIDashSpvClient *client,
210+
const FFIClientConfig *config);
211+
201212
int32_t dash_spv_ffi_client_start(struct FFIDashSpvClient *client);
202213

203214
int32_t dash_spv_ffi_client_stop(struct FFIDashSpvClient *client);
@@ -414,6 +425,16 @@ int32_t dash_spv_ffi_config_set_relay_transactions(FFIClientConfig *config,
414425
int32_t dash_spv_ffi_config_set_filter_load(FFIClientConfig *config,
415426
bool load_filters);
416427

428+
/**
429+
* Enables or disables masternode synchronization
430+
*
431+
* # Safety
432+
* - `config` must be a valid pointer to an FFIClientConfig created by dash_spv_ffi_config_new/mainnet/testnet
433+
* - The caller must ensure the config pointer remains valid for the duration of this call
434+
*/
435+
int32_t dash_spv_ffi_config_set_masternode_sync_enabled(FFIClientConfig *config,
436+
bool enable);
437+
417438
/**
418439
* Gets the network type from the configuration
419440
*
@@ -541,18 +562,45 @@ int32_t dash_spv_ffi_config_set_start_from_height(FFIClientConfig *config,
541562
int32_t dash_spv_ffi_config_set_wallet_creation_time(FFIClientConfig *config,
542563
uint32_t timestamp);
543564

565+
/**
566+
* Get the latest checkpoint for the given network.
567+
*
568+
* # Safety
569+
* - `out_height` must be a valid pointer to a `u32`.
570+
* - `out_hash` must point to at least 32 writable bytes.
571+
*/
544572
int32_t dash_spv_ffi_checkpoint_latest(FFINetwork network, uint32_t *out_height, uint8_t *out_hash);
545573

574+
/**
575+
* Get the last checkpoint at or before a given height.
576+
*
577+
* # Safety
578+
* - `out_height` must be a valid pointer to a `u32`.
579+
* - `out_hash` must point to at least 32 writable bytes.
580+
*/
546581
int32_t dash_spv_ffi_checkpoint_before_height(FFINetwork network,
547582
uint32_t height,
548583
uint32_t *out_height,
549584
uint8_t *out_hash);
550585

586+
/**
587+
* Get the last checkpoint at or before a given UNIX timestamp (seconds).
588+
*
589+
* # Safety
590+
* - `out_height` must be a valid pointer to a `u32`.
591+
* - `out_hash` must point to at least 32 writable bytes.
592+
*/
551593
int32_t dash_spv_ffi_checkpoint_before_timestamp(FFINetwork network,
552594
uint32_t timestamp,
553595
uint32_t *out_height,
554596
uint8_t *out_hash);
555597

598+
/**
599+
* Get all checkpoints between two heights (inclusive).
600+
*
601+
* Returns an `FFIArray` of `FFICheckpoint` items. The caller owns the memory and
602+
* must free the array buffer using `dash_spv_ffi_array_destroy` when done.
603+
*/
556604
struct FFIArray dash_spv_ffi_checkpoints_between_heights(FFINetwork network,
557605
uint32_t start_height,
558606
uint32_t end_height);

dash-spv-ffi/src/client.rs

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -339,6 +339,43 @@ impl FFIDashSpvClient {
339339
}
340340
}
341341

342+
/// Update the running client's configuration.
343+
///
344+
/// # Safety
345+
/// - `client` must be a valid pointer to an `FFIDashSpvClient`.
346+
/// - `config` must be a valid pointer to an `FFIClientConfig`.
347+
/// - The network in `config` must match the client's network; changing networks at runtime is not supported.
348+
#[no_mangle]
349+
pub unsafe extern "C" fn dash_spv_ffi_client_update_config(
350+
client: *mut FFIDashSpvClient,
351+
config: *const FFIClientConfig,
352+
) -> i32 {
353+
null_check!(client);
354+
null_check!(config);
355+
356+
let client = &(*client);
357+
let new_config = (&*config).clone_inner();
358+
359+
let result = client.runtime.block_on(async {
360+
let mut guard = client.inner.lock().unwrap();
361+
if let Some(ref mut spv_client) = *guard {
362+
spv_client.update_config(new_config).await.map_err(|e| e)
363+
} else {
364+
Err(dash_spv::SpvError::Config(
365+
"Client not initialized".to_string(),
366+
))
367+
}
368+
});
369+
370+
match result {
371+
Ok(()) => FFIErrorCode::Success as i32,
372+
Err(e) => {
373+
set_last_error(&e.to_string());
374+
FFIErrorCode::from(e) as i32
375+
}
376+
}
377+
}
378+
342379
#[no_mangle]
343380
pub unsafe extern "C" fn dash_spv_ffi_client_start(client: *mut FFIDashSpvClient) -> i32 {
344381
null_check!(client);

dash-spv-ffi/src/config.rs

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -208,6 +208,23 @@ pub unsafe extern "C" fn dash_spv_ffi_config_set_filter_load(
208208
FFIErrorCode::Success as i32
209209
}
210210

211+
/// Enables or disables masternode synchronization
212+
///
213+
/// # Safety
214+
/// - `config` must be a valid pointer to an FFIClientConfig created by dash_spv_ffi_config_new/mainnet/testnet
215+
/// - The caller must ensure the config pointer remains valid for the duration of this call
216+
#[no_mangle]
217+
pub unsafe extern "C" fn dash_spv_ffi_config_set_masternode_sync_enabled(
218+
config: *mut FFIClientConfig,
219+
enable: bool,
220+
) -> i32 {
221+
null_check!(config);
222+
223+
let config = &mut (*config).inner;
224+
config.enable_masternodes = enable;
225+
FFIErrorCode::Success as i32
226+
}
227+
211228
/// Gets the network type from the configuration
212229
///
213230
/// # Safety

dash-spv/src/client/mod.rs

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -611,6 +611,38 @@ impl<
611611
Ok(())
612612
}
613613

614+
/// Update the client's configuration at runtime.
615+
///
616+
/// This applies non-network-critical settings without restarting the client.
617+
/// Changing the network is not supported at runtime.
618+
pub async fn update_config(&mut self, new_config: ClientConfig) -> Result<()> {
619+
if new_config.network != self.config.network {
620+
return Err(SpvError::Config(
621+
"Cannot change network at runtime".to_string(),
622+
));
623+
}
624+
625+
// Track changes that may require reinitialization of helpers
626+
let mempool_changed =
627+
new_config.enable_mempool_tracking != self.config.enable_mempool_tracking
628+
|| new_config.mempool_strategy != self.config.mempool_strategy
629+
|| new_config.max_mempool_transactions != self.config.max_mempool_transactions
630+
|| new_config.recent_send_window_secs != self.config.recent_send_window_secs;
631+
632+
// Apply full config replacement, preserving network (already checked equal)
633+
self.config = new_config;
634+
635+
// Update validation manager according to new mode
636+
self.validation = ValidationManager::new(self.config.validation_mode);
637+
638+
// Rebuild mempool filter if needed
639+
if mempool_changed {
640+
self.update_mempool_filter().await;
641+
}
642+
643+
Ok(())
644+
}
645+
614646
/// Synchronize to the tip of the blockchain.
615647
pub async fn sync_to_tip(&mut self) -> Result<SyncProgress> {
616648
let running = self.running.read().await;

0 commit comments

Comments
 (0)