Skip to content

Conversation

@QuantumExplorer
Copy link
Member

@QuantumExplorer QuantumExplorer commented Sep 1, 2025

Added new functions to the FFI API for retrieving checkpoints. The following functions were introduced:

  • dash_spv_ffi_checkpoint_latest: Retrieves the latest checkpoint for a given network.
  • dash_spv_ffi_checkpoint_before_height: Gets the last checkpoint at or before a specified block height.
  • dash_spv_ffi_checkpoint_before_timestamp: Gets the last checkpoint at or before a specified UNIX timestamp.
  • dash_spv_ffi_checkpoints_between_heights: Retrieves all checkpoints between two specified heights.

Updated the documentation to reflect the new total function count and included descriptions for the newly added functions. The changes enhance the API's capability to interact with checkpoints, which is essential for maintaining blockchain state.

Summary by CodeRabbit

  • New Features

    • Added FFI APIs to retrieve checkpoints: latest, before a given height, before a given timestamp, and a list between two heights.
    • Outputs include checkpoint heights and block hashes; multi-result calls return an array for easier batch access.
  • Documentation

    • Updated FFI API documentation and table of contents to include the new checkpoint functions.
    • Added usage and memory management notes, including output buffer requirements and array deallocation guidance.

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Sep 1, 2025

✨ Finishing Touches
  • 📝 Generate Docstrings
🧪 Generate unit tests
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch featadd-checkpoint-functions

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share
🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>, please review it.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.

Support

Need help? Create a ticket on our support page for assistance with any issues or questions.

CodeRabbit Commands (Invoked using PR/Issue comments)

Type @coderabbitai help to get the list of available commands.

Other keywords and placeholders

  • Add @coderabbitai ignore or @coderabbit ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai anywhere in the PR title to generate the title automatically.

CodeRabbit Configuration File (.coderabbit.yaml)

  • You can programmatically configure CodeRabbit by adding a .coderabbit.yaml file to the root of your repository.
  • Please see the configuration documentation for more information.
  • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json

Status, Documentation and Community

  • Visit our Status Page to check the current availability of CodeRabbit.
  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 4

🧹 Nitpick comments (4)
dash-spv-ffi/include/dash_spv_ffi.h (1)

544-555: Encode 32-byte hash size in the type to prevent misuse.

Consider changing out_hash to a 32-byte array pointer in the Rust signatures (*mut [u8; 32]) so cbindgen generates uint8_t (*out_hash)[32] here. This prevents under-sized buffers at call sites.

Apply in Rust (affects all three functions):

-pub extern "C" fn dash_spv_ffi_checkpoint_latest(
+pub extern "C" fn dash_spv_ffi_checkpoint_latest(
     network: FFINetwork,
     out_height: *mut u32,
-    out_hash: *mut u8, // expects at least 32 bytes
+    out_hash: *mut [u8; 32],
 ) -> i32 { /* ... */ }

-    out_hash: *mut u8, // expects at least 32 bytes
+    out_hash: *mut [u8; 32],

-    out_hash: *mut u8, // expects at least 32 bytes
+    out_hash: *mut [u8; 32],

And in the bodies:

-            let hash = cp.block_hash.to_byte_array();
-            std::ptr::copy_nonoverlapping(hash.as_ptr(), out_hash, 32);
+            let hash = cp.block_hash.to_byte_array();
+            (*out_hash).copy_from_slice(&hash);
dash-spv-ffi/FFI_API.md (1)

833-891: Document FFICheckpoint in “Type Definitions” and note error codes.

Add FFICheckpoint to the Types section and list possible error codes for each checkpoint API (Success, NullPointer, InvalidArgument, ValidationError/NotImplemented).

I can wire Rust doc comments so the generator includes the type and error semantics—want a patch?

dash-spv-ffi/src/checkpoints.rs (2)

29-56: Make hash output size-safe and deduplicate write-out logic.

Use a typed 32-byte pointer and a small helper to avoid repetition.

-    out_hash: *mut u8, // expects at least 32 bytes
+    out_hash: *mut [u8; 32],
@@
-        unsafe {
-            *out_height = cp.height;
-            let hash = cp.block_hash.to_byte_array();
-            std::ptr::copy_nonoverlapping(hash.as_ptr(), out_hash, 32);
-        }
+        unsafe {
+            *out_height = cp.height;
+            let hash = cp.block_hash.to_byte_array();
+            (*out_hash).copy_from_slice(&hash);
+        }

Optionally extract:

#[inline]
fn write_out(out_height: *mut u32, out_hash: *mut [u8; 32], h: u32, hash: [u8;32]) {
    unsafe { *out_height = h; (*out_hash).copy_from_slice(&hash); }
}

Also applies to: 64-92, 100-128


135-168: Avoid unnecessary scanning; handle inverted ranges.

  • Early-return empty when start > end.
  • If heights are sorted asc, break once h > end to avoid full scan.
 pub extern "C" fn dash_spv_ffi_checkpoints_between_heights(
@@
 ) -> FFIArray {
-    match manager_for_network(network) {
+    if start_height > end_height {
+        return FFIArray::new(Vec::<FFICheckpoint>::new());
+    }
+    match manager_for_network(network) {
         Ok(mgr) => {
             // Collect checkpoints within inclusive range
             let mut out: Vec<FFICheckpoint> = Vec::new();
             for &h in mgr.checkpoint_heights() {
                 if h >= start_height && h <= end_height {
                     if let Some(cp) = mgr.get_checkpoint(h) {
                         out.push(FFICheckpoint {
                             height: cp.height,
                             block_hash: cp.block_hash.to_byte_array(),
                         });
                     }
+                } else if h > end_height {
+                    break;
                 }
             }
             FFIArray::new(out)

Confirm checkpoint_heights() returns ascending order; if not guaranteed, skip the break.

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

💡 Knowledge Base configuration:

  • MCP integration is disabled by default for public repositories
  • Jira integration is disabled by default for public repositories
  • Linear integration is disabled by default for public repositories

You can enable these sources in your CodeRabbit configuration.

📥 Commits

Reviewing files that changed from the base of the PR and between 66b18fb and 1656d76.

📒 Files selected for processing (4)
  • dash-spv-ffi/FFI_API.md (3 hunks)
  • dash-spv-ffi/include/dash_spv_ffi.h (2 hunks)
  • dash-spv-ffi/src/checkpoints.rs (1 hunks)
  • dash-spv-ffi/src/lib.rs (2 hunks)
🧰 Additional context used
📓 Path-based instructions (6)
dash-spv-ffi/src/**/*.rs

📄 CodeRabbit inference engine (dash-spv-ffi/CLAUDE.md)

dash-spv-ffi/src/**/*.rs: FFI functions must be declared with #[no_mangle] extern "C"
Expose complex Rust types to C as opaque pointers (e.g., FFIDashSpvClient*)
Provide corresponding _destroy() functions for all FFI-owned types to enforce explicit memory management
Return Rust strings to C as *const c_char; allocate so the caller can free with dash_string_free
Accept input strings from C as *const c_char (borrowed; do not free inputs)
Functions returning pointers transfer ownership to the caller; functions taking pointers only borrow
Add cbindgen annotations for complex types so headers are generated correctly

Files:

  • dash-spv-ffi/src/lib.rs
  • dash-spv-ffi/src/checkpoints.rs
**/*.rs

📄 CodeRabbit inference engine (CLAUDE.md)

**/*.rs: Use proper error types with thiserror and propagate errors appropriately
Use the tokio runtime for async operations in Rust
Use conditional compilation feature flags for optional features (#[cfg(feature = ...)])
Format Rust code with cargo fmt (and enforce via cargo fmt --check)
Run clippy with -D warnings and fix all lints
Adhere to MSRV Rust 1.89 (avoid features requiring newer compiler)

**/*.rs: Format Rust code with rustfmt (per rustfmt.toml); run cargo fmt --all before commits
Lint with clippy; treat warnings as errors in CI
Follow Rust naming: snake_case for functions/variables, UpperCamelCase for types/traits, SCREAMING_SNAKE_CASE for consts
Prefer async using tokio where applicable

Files:

  • dash-spv-ffi/src/lib.rs
  • dash-spv-ffi/src/checkpoints.rs
{dash-network-ffi,dash-spv-ffi,key-wallet-ffi,swift-dash-core-sdk}/**/*.{rs,c,h,swift}

📄 CodeRabbit inference engine (CLAUDE.md)

Be careful with memory management at FFI boundaries (C/Swift interop)

Files:

  • dash-spv-ffi/src/lib.rs
  • dash-spv-ffi/src/checkpoints.rs
  • dash-spv-ffi/include/dash_spv_ffi.h
**/src/**/*.rs

📄 CodeRabbit inference engine (AGENTS.md)

**/src/**/*.rs: Each crate keeps sources in src/
Avoid unwrap()/expect() in library code; use proper error types (e.g., thiserror)
Place unit tests alongside code with #[cfg(test)]

Files:

  • dash-spv-ffi/src/lib.rs
  • dash-spv-ffi/src/checkpoints.rs
*-ffi/**

📄 CodeRabbit inference engine (AGENTS.md)

FFI bindings live in *-ffi crates

Files:

  • dash-spv-ffi/src/lib.rs
  • dash-spv-ffi/src/checkpoints.rs
  • dash-spv-ffi/FFI_API.md
  • dash-spv-ffi/include/dash_spv_ffi.h
dash-spv-ffi/include/dash_spv_ffi.h

📄 CodeRabbit inference engine (dash-spv-ffi/CLAUDE.md)

The public C header is generated; ensure it reflects FFI changes after builds

Files:

  • dash-spv-ffi/include/dash_spv_ffi.h
🧠 Learnings (17)
📚 Learning: 2025-08-16T04:14:07.718Z
Learnt from: CR
PR: dashpay/rust-dashcore#0
File: dash-spv-ffi/CLAUDE.md:0-0
Timestamp: 2025-08-16T04:14:07.718Z
Learning: Applies to dash-spv-ffi/src/**/*.rs : Expose complex Rust types to C as opaque pointers (e.g., FFIDashSpvClient*)

Applied to files:

  • dash-spv-ffi/src/lib.rs
  • dash-spv-ffi/src/checkpoints.rs
📚 Learning: 2025-08-16T04:14:07.718Z
Learnt from: CR
PR: dashpay/rust-dashcore#0
File: dash-spv-ffi/CLAUDE.md:0-0
Timestamp: 2025-08-16T04:14:07.718Z
Learning: Applies to dash-spv-ffi/include/dash_spv_ffi.h : The public C header is generated; ensure it reflects FFI changes after builds

Applied to files:

  • dash-spv-ffi/src/lib.rs
  • dash-spv-ffi/src/checkpoints.rs
  • dash-spv-ffi/FFI_API.md
  • dash-spv-ffi/include/dash_spv_ffi.h
📚 Learning: 2025-08-25T17:15:59.361Z
Learnt from: CR
PR: dashpay/rust-dashcore#0
File: dash-spv/CLAUDE.md:0-0
Timestamp: 2025-08-25T17:15:59.361Z
Learning: Applies to dash-spv/**/*.rs : All code must be clippy-clean: run `cargo clippy --all-targets --all-features -- -D warnings`

Applied to files:

  • dash-spv-ffi/src/lib.rs
📚 Learning: 2025-08-16T04:14:07.718Z
Learnt from: CR
PR: dashpay/rust-dashcore#0
File: dash-spv-ffi/CLAUDE.md:0-0
Timestamp: 2025-08-16T04:14:07.718Z
Learning: Applies to dash-spv-ffi/src/**/*.rs : FFI functions must be declared with #[no_mangle] extern "C"

Applied to files:

  • dash-spv-ffi/src/lib.rs
  • dash-spv-ffi/src/checkpoints.rs
📚 Learning: 2025-08-16T04:14:07.718Z
Learnt from: CR
PR: dashpay/rust-dashcore#0
File: dash-spv-ffi/CLAUDE.md:0-0
Timestamp: 2025-08-16T04:14:07.718Z
Learning: Applies to dash-spv-ffi/tests/unit/**/*.rs : Add a corresponding Rust unit test for each new FFI function

Applied to files:

  • dash-spv-ffi/src/lib.rs
  • dash-spv-ffi/src/checkpoints.rs
  • dash-spv-ffi/FFI_API.md
📚 Learning: 2025-08-16T04:14:07.718Z
Learnt from: CR
PR: dashpay/rust-dashcore#0
File: dash-spv-ffi/CLAUDE.md:0-0
Timestamp: 2025-08-16T04:14:07.718Z
Learning: Applies to dash-spv-ffi/src/**/*.rs : Provide corresponding _destroy() functions for all FFI-owned types to enforce explicit memory management

Applied to files:

  • dash-spv-ffi/src/lib.rs
  • dash-spv-ffi/src/checkpoints.rs
📚 Learning: 2025-08-16T04:14:07.718Z
Learnt from: CR
PR: dashpay/rust-dashcore#0
File: dash-spv-ffi/CLAUDE.md:0-0
Timestamp: 2025-08-16T04:14:07.718Z
Learning: Applies to dash-spv-ffi/src/**/*.rs : Add cbindgen annotations for complex types so headers are generated correctly

Applied to files:

  • dash-spv-ffi/src/lib.rs
  • dash-spv-ffi/src/checkpoints.rs
📚 Learning: 2025-08-16T04:14:07.718Z
Learnt from: CR
PR: dashpay/rust-dashcore#0
File: dash-spv-ffi/CLAUDE.md:0-0
Timestamp: 2025-08-16T04:14:07.718Z
Learning: Applies to dash-spv-ffi/src/**/*.rs : Functions returning pointers transfer ownership to the caller; functions taking pointers only borrow

Applied to files:

  • dash-spv-ffi/src/lib.rs
  • dash-spv-ffi/src/checkpoints.rs
📚 Learning: 2025-08-29T04:00:14.154Z
Learnt from: CR
PR: dashpay/rust-dashcore#0
File: CLAUDE.md:0-0
Timestamp: 2025-08-29T04:00:14.154Z
Learning: Applies to {dash-network-ffi,dash-spv-ffi,key-wallet-ffi,swift-dash-core-sdk}/**/*.{rs,c,h,swift} : Be careful with memory management at FFI boundaries (C/Swift interop)

Applied to files:

  • dash-spv-ffi/src/checkpoints.rs
  • dash-spv-ffi/FFI_API.md
  • dash-spv-ffi/include/dash_spv_ffi.h
📚 Learning: 2025-08-16T04:14:07.718Z
Learnt from: CR
PR: dashpay/rust-dashcore#0
File: dash-spv-ffi/CLAUDE.md:0-0
Timestamp: 2025-08-16T04:14:07.718Z
Learning: Applies to dash-spv-ffi/tests/c_tests/**/*.c : Add a corresponding C test for each new FFI function

Applied to files:

  • dash-spv-ffi/src/checkpoints.rs
📚 Learning: 2025-08-16T04:14:07.718Z
Learnt from: CR
PR: dashpay/rust-dashcore#0
File: dash-spv-ffi/CLAUDE.md:0-0
Timestamp: 2025-08-16T04:14:07.718Z
Learning: Applies to dash-spv-ffi/src/callbacks.rs : Use C function pointers for async progress/completion callbacks; callbacks may be invoked from any thread

Applied to files:

  • dash-spv-ffi/src/checkpoints.rs
📚 Learning: 2025-08-16T04:15:29.335Z
Learnt from: CR
PR: dashpay/rust-dashcore#0
File: swift-dash-core-sdk/CLAUDE.md:0-0
Timestamp: 2025-08-16T04:15:29.335Z
Learning: Applies to swift-dash-core-sdk/Sources/DashSPVFFI/include/dash_spv_ffi.h : After updating dash-spv-ffi, synchronize the generated header into the Swift SDK using ./sync-headers.sh so Sources/DashSPVFFI/include/dash_spv_ffi.h stays up to date

Applied to files:

  • dash-spv-ffi/FFI_API.md
  • dash-spv-ffi/include/dash_spv_ffi.h
📚 Learning: 2025-08-16T04:15:57.225Z
Learnt from: CR
PR: dashpay/rust-dashcore#0
File: swift-dash-core-sdk/Examples/DashHDWalletExample/CLAUDE.md:0-0
Timestamp: 2025-08-16T04:15:57.225Z
Learning: Applies to swift-dash-core-sdk/Examples/DashHDWalletExample/**/*.swift : When accessing SPV functionality, use DashSDK public APIs instead of direct client access; add public wrapper methods to DashSDK if needed

Applied to files:

  • dash-spv-ffi/include/dash_spv_ffi.h
📚 Learning: 2025-08-16T04:15:29.335Z
Learnt from: CR
PR: dashpay/rust-dashcore#0
File: swift-dash-core-sdk/CLAUDE.md:0-0
Timestamp: 2025-08-16T04:15:29.335Z
Learning: Applies to swift-dash-core-sdk/Sources/**/FFIBridge.swift : Manage FFI pointers manually using RAII-style wrappers and defer blocks to ensure cleanup

Applied to files:

  • dash-spv-ffi/include/dash_spv_ffi.h
📚 Learning: 2025-08-16T04:15:29.335Z
Learnt from: CR
PR: dashpay/rust-dashcore#0
File: swift-dash-core-sdk/CLAUDE.md:0-0
Timestamp: 2025-08-16T04:15:29.335Z
Learning: Applies to swift-dash-core-sdk/Sources/**/FFIBridge.swift : At the FFI boundary, convert FFI errors to DashSDKError and use Result types; log FFI errors before converting

Applied to files:

  • dash-spv-ffi/include/dash_spv_ffi.h
📚 Learning: 2025-08-16T04:15:29.335Z
Learnt from: CR
PR: dashpay/rust-dashcore#0
File: swift-dash-core-sdk/CLAUDE.md:0-0
Timestamp: 2025-08-16T04:15:29.335Z
Learning: Applies to swift-dash-core-sdk/Sources/**/FFIBridge.swift : Add a Swift wrapper in FFIBridge.swift for each new FFI function, handling type conversions and cross-language error mapping

Applied to files:

  • dash-spv-ffi/include/dash_spv_ffi.h
📚 Learning: 2025-08-16T04:15:29.335Z
Learnt from: CR
PR: dashpay/rust-dashcore#0
File: swift-dash-core-sdk/CLAUDE.md:0-0
Timestamp: 2025-08-16T04:15:29.335Z
Learning: Applies to swift-dash-core-sdk/Sources/**/AsyncBridge.swift : Provide async wrappers in AsyncBridge.swift (e.g., AsyncSequence/Combine publishers) for callback-based FFI APIs

Applied to files:

  • dash-spv-ffi/include/dash_spv_ffi.h
🧬 Code graph analysis (2)
dash-spv-ffi/src/checkpoints.rs (2)
dash-spv-ffi/src/error.rs (1)
  • set_last_error (26-31)
dash-spv/src/chain/checkpoints.rs (2)
  • mainnet_checkpoints (271-358)
  • testnet_checkpoints (361-412)
dash-spv-ffi/include/dash_spv_ffi.h (1)
dash-spv-ffi/src/checkpoints.rs (4)
  • dash_spv_ffi_checkpoint_latest (29-56)
  • dash_spv_ffi_checkpoint_before_height (64-92)
  • dash_spv_ffi_checkpoint_before_timestamp (100-128)
  • dash_spv_ffi_checkpoints_between_heights (135-168)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (20)
  • GitHub Check: RPC Tests (stable, true)
  • GitHub Check: Core Components Tests
  • GitHub Check: fuzz (hashes_sha512)
  • GitHub Check: Clippy (Non-strict)
  • GitHub Check: fuzz (hashes_json)
  • GitHub Check: fuzz (hashes_sha512_256)
  • GitHub Check: fuzz (hashes_cbor)
  • GitHub Check: fuzz (hashes_sha1)
  • GitHub Check: fuzz (hashes_sha256)
  • GitHub Check: SPV Components Tests
  • GitHub Check: fuzz (dash_deserialize_witness)
  • GitHub Check: fuzz (dash_deserialize_script)
  • GitHub Check: fuzz (hashes_ripemd160)
  • GitHub Check: fuzz (dash_deserialize_block)
  • GitHub Check: fuzz (dash_script_bytes_to_asm_fmt)
  • GitHub Check: Strict Warnings and Clippy Checks
  • GitHub Check: fuzz (dash_deserialize_amount)
  • GitHub Check: fuzz (dash_deserialize_address)
  • GitHub Check: fuzz (dash_deser_net_msg)
  • GitHub Check: fuzz (dash_outpoint_string)
🔇 Additional comments (5)
dash-spv-ffi/src/lib.rs (2)

4-4: Re-export module publicly: LGTM.

Module wiring is correct and matches FFI guidelines.


13-13: Public surface re-export: LGTM.

Makes the checkpoint FFI available at the crate root; no concerns.

dash-spv-ffi/include/dash_spv_ffi.h (1)

151-165: Vendored header synced. dash_spv_ffi.h in swift-dash-core-sdk/Sources/DashSPVFFI/include has been updated via sync-headers.sh; no further action required.

dash-spv-ffi/src/checkpoints.rs (2)

14-21: Network mapping: LGTM.

Clear error for unsupported networks; fine for FFI.


23-28: Docs and FFI hygiene: LGTM.

  • #[no_mangle] extern "C" present.
  • Null-pointer checks and error propagation consistent.

Also applies to: 58-63, 94-99, 130-134

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

**Total Functions**: 57
**Total Functions**: 61
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

Function count updated: please verify it’s auto-generated, not hand-edited.

Ensure the generator reflects 61 functions and that the header and doc stay in lockstep.


🏁 Script executed:

#!/bin/bash
# Count public FFI functions in header vs documented count
DOC_CNT=$(rg -n '^\\*\\*Total Functions\\*\\*:\\s*(\\d+)$' -or '$1' dash-spv-ffi/FFI_API.md)
HDR_CNT=$(rg -nP '^\s*(?:int32_t|bool|void|struct\s+FFIArray|FFIClientConfig\s*\*|FFINetwork\b|const\s+char\s*\*)\s+dash_spv_ffi_' dash-spv-ffi/include/dash_spv_ffi.h | wc -l | tr -d ' ')
echo "Doc: $DOC_CNT, Header: $HDR_CNT"
test "$DOC_CNT" = "$HDR_CNT" || { echo "Mismatch"; exit 1; }

Length of output: 384


🏁 Script executed:

#!/bin/bash
# Correctly extract documented total functions
DOC_CNT=$(rg -P -o '^\*\*Total Functions\*\*:\s*(\d+)$' -r '$1' dash-spv-ffi/FFI_API.md)
# Count public FFI functions in header
HDR_CNT=$(rg -P '^\s*(?:int32_t|bool|void|struct\s+FFIArray|FFIClientConfig\s*\*|FFINetwork\b|const\s+char\s*\*)\s+dash_spv_ffi_' -c dash-spv-ffi/include/dash_spv_ffi.h)
echo "Doc: $DOC_CNT, Header: $HDR_CNT"
if [ "$DOC_CNT" = "$HDR_CNT" ]; then
  echo "Match"
else
  echo "Mismatch"
fi

Length of output: 360


Sync FFI_API.md function count with header: Documented total (61) doesn’t match actual public FFI functions in dash-spv-ffi/include/dash_spv_ffi.h (46). Re-run the API doc generator (not manual edit) and commit the updated FFI_API.md so counts stay in lockstep.

🤖 Prompt for AI Agents
In dash-spv-ffi/FFI_API.md around line 7, the documented total functions (61) is
out of sync with the actual public FFI functions in
dash-spv-ffi/include/dash_spv_ffi.h (46); re-run the API documentation generator
(do not manually edit the count) pointing it at
dash-spv-ffi/include/dash_spv_ffi.h so the generator recomputes the total and
updates FFI_API.md, verify the generated total matches the header’s exported
functions, and commit the regenerated FFI_API.md to the branch.

Comment on lines +556 to +559
struct FFIArray dash_spv_ffi_checkpoints_between_heights(FFINetwork network,
uint32_t start_height,
uint32_t end_height);

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

Header lacks FFICheckpoint definition used by the returned FFIArray.

C consumers cannot interpret elements without a typedef struct FFICheckpoint. Ensure cbindgen exports it.

Apply in Rust (so cbindgen emits the type):

-/// FFI representation of a checkpoint (height + block hash)
+/// FFI representation of a checkpoint (height + block hash)
+/// cbindgen:export
 #[repr(C)]
 pub struct FFICheckpoint {
     pub height: u32,
     pub block_hash: [u8; 32],
 }

Run to confirm the struct appears in the generated header:


🏁 Script executed:

#!/bin/bash
rg -nP 'typedef\s+struct\s+FFICheckpoint' dash-spv-ffi/include/dash_spv_ffi.h -C2

Length of output: 83


🏁 Script executed:

#!/bin/bash
# Check for FFICheckpoint in the generated C header
echo "Header occurrences:"
rg -n 'FFICheckpoint' dash-spv-ffi/include/dash_spv_ffi.h -C2

# Check Rust source for the FFICheckpoint definition and cbindgen annotations
echo "Rust source occurrences:"
rg -nP 'struct\s+FFICheckpoint' -C2 dash-spv-ffi/src/**/*.rs

Length of output: 299


🏁 Script executed:

#!/bin/bash
# Search entire repository for any mentions of FFICheckpoint
echo "Occurrences of 'FFICheckpoint' in repo:"
rg -n 'FFICheckpoint' -C2 .

# Search for cbindgen annotations in Rust source
echo "Occurrences of 'cbindgen' annotations in Rust files:"
rg -n 'cbindgen' -C2 --type=rs

Length of output: 2722


Add cbindgen export for FFICheckpoint in Rust
Header lacks FFICheckpoint typedef; annotate struct so cbindgen generates it:

/// FFI representation of a checkpoint (height + block hash)
+/// cbindgen:export
#[repr(C)]
pub struct FFICheckpoint {
    pub height: u32,
    pub block_hash: [u8; 32],
}

Committable suggestion skipped: line range outside the PR's diff.

🤖 Prompt for AI Agents
In dash-spv-ffi/include/dash_spv_ffi.h around lines 556 to 559: the header lacks
a typedef for FFICheckpoint because the corresponding Rust struct wasn't
exported for cbindgen; update the Rust definition to be a public, C-compatible
struct (add pub, #[repr(C)], and derive Copy/Clone) and ensure it is visible to
cbindgen (keep it in a module cbindgen scans or add a cfg_attr if you use
conditional export) so cbindgen will generate the FFICheckpoint typedef in the C
header.

Comment on lines +1 to +21
use crate::{set_last_error, FFIArray, FFIErrorCode};
use dash_spv::chain::checkpoints::{mainnet_checkpoints, testnet_checkpoints, CheckpointManager};
use dashcore::Network;
use dashcore::hashes::Hash;
use key_wallet_ffi::FFINetwork;

/// FFI representation of a checkpoint (height + block hash)
#[repr(C)]
pub struct FFICheckpoint {
pub height: u32,
pub block_hash: [u8; 32],
}

fn manager_for_network(network: FFINetwork) -> Result<CheckpointManager, String> {
let net: Network = network.into();
match net {
Network::Dash => Ok(CheckpointManager::new(mainnet_checkpoints())),
Network::Testnet => Ok(CheckpointManager::new(testnet_checkpoints())),
_ => Err("Checkpoints are only available for Dash and Testnet".to_string()),
}
}
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

Add unit and C tests for new FFI endpoints.

Per repo guidelines, add Rust unit tests and C tests covering success/edge cases for all four functions.

I can scaffold tests (Rust + C) for mainnet/testnet networks and error paths—want me to open a follow-up patch?


🏁 Script executed:

#!/bin/bash
# Quick audit for tests referencing new symbols
rg -nP 'checkpoint_(latest|before_height|before_timestamp)|checkpoints_between_heights' dash-spv-ffi/tests

Length of output: 108


🏁 Script executed:

#!/bin/bash
set -eux

# List all test files in dash-spv-ffi/tests
echo "=== Test files ==="
find dash-spv-ffi/tests -type f

# Search for any occurrences of 'checkpoint' in those test files
echo "=== Occurrences of 'checkpoint' in tests ==="
rg -n 'checkpoint' dash-spv-ffi/tests

Length of output: 1490


Add tests for new checkpoint FFI endpoints. Add Rust unit tests in dash-spv-ffi/tests/unit covering all four functions (checkpoint_latest, checkpoint_before_height, checkpoint_before_timestamp, checkpoints_between_heights) with success and edge cases, and add corresponding C tests in dash-spv-ffi/tests/c_tests.

🤖 Prompt for AI Agents
In dash-spv-ffi/src/checkpoints.rs around lines 1 to 21, add comprehensive tests
for the new checkpoint FFI: create Rust unit tests in dash-spv-ffi/tests/unit
that exercise checkpoint_latest, checkpoint_before_height,
checkpoint_before_timestamp, and checkpoints_between_heights for both Dash and
Testnet covering normal success cases and edge cases (no checkpoint found,
boundary heights/timestamps, empty range), validate returned FFICheckpoint data,
and assert correct error handling/FFI error codes and set_last_error behavior;
also add corresponding C integration tests in dash-spv-ffi/tests/c_tests that
call the FFI functions from C, mirror the same success and edge cases, validate
returned structures and error codes/messages, and ensure tests run under cargo
test (and the project’s C test harness) so the new endpoints are fully exercised
across both Rust unit and C integration layers.

Comment on lines +7 to +12
/// FFI representation of a checkpoint (height + block hash)
#[repr(C)]
pub struct FFICheckpoint {
pub height: u32,
pub block_hash: [u8; 32],
}
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

Export FFICheckpoint to C headers via cbindgen.

Without explicit export, cbindgen may omit this struct; C consumers won’t know the element layout of FFIArray.

Apply:

-/// FFI representation of a checkpoint (height + block hash)
+/// FFI representation of a checkpoint (height + block hash)
+/// cbindgen:export
 #[repr(C)]
 pub struct FFICheckpoint {
     pub height: u32,
     pub block_hash: [u8; 32],
 }
📝 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
/// FFI representation of a checkpoint (height + block hash)
#[repr(C)]
pub struct FFICheckpoint {
pub height: u32,
pub block_hash: [u8; 32],
}
/// FFI representation of a checkpoint (height + block hash)
/// cbindgen:export
#[repr(C)]
pub struct FFICheckpoint {
pub height: u32,
pub block_hash: [u8; 32],
}
🤖 Prompt for AI Agents
In dash-spv-ffi/src/checkpoints.rs around lines 7–12, the FFICheckpoint struct
is public and repr(C) but cbindgen may still omit it unless it is explicitly
exported in the crate public API; update the file to make the type
cbindgen-visible by deriving Copy and Clone for safe FFI value semantics, add a
conditional export attribute for header generation (e.g. #[cfg_attr(feature =
"cbindgen", export_name = "FFICheckpoint")]) and ensure the type is re-exported
from the crate root (pub use crate::checkpoints::FFICheckpoint;) so cbindgen
sees and emits the struct layout in the generated C headers.

@QuantumExplorer QuantumExplorer merged commit 018a32a into v0.40-dev Sep 1, 2025
27 of 32 checks passed
@QuantumExplorer QuantumExplorer deleted the featadd-checkpoint-functions branch September 1, 2025 20:59
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants