Skip to content

Conversation

@DCG-Claude
Copy link
Contributor

@DCG-Claude DCG-Claude commented Jul 8, 2025

Summary

  • Replace bls-signatures with blsful (dashpay/agora-blsful) for BLS operations
  • Add support for legacy BLS format in quorum validation
  • Update verify_aggregated_commitment_signature to use blsful API

Details

This PR migrates the BLS cryptography implementation from the older bls-signatures library to the newer blsful library (specifically dashpay/agora-blsful fork). The migration includes:

  • Removing all bls-signatures dependencies and error types
  • Updating verify_aggregated_commitment_signature to use the blsful API
  • Adding support for both legacy and modern BLS key formats
  • Adding comprehensive tests for BLS format compatibility

The migration uses dashpay/agora-blsful with the main branch to maintain compatibility with both legacy and modern BLS key formats.

Test Plan

  • Added compatibility tests for real operator keys and ChainLock signatures
  • Added benchmarks for verify_secure operations
  • Tests verify proper handling of both legacy and modern BLS formats

🤖 Generated with Claude Code

Summary by CodeRabbit

  • Refactor

    • Migrated from the bls-signatures crate to agora-blsful for BLS signature verification.
    • Simplified feature dependencies and removed legacy BLS error handling.
    • Updated internal logic for verifying aggregated commitment signatures to use the new library, supporting both legacy and modern key formats.
  • New Features

    • Added comprehensive tests and benchmarks for signature verification, including compatibility with real-world data.
  • Chores

    • Updated dependencies and cleaned up configuration for improved maintainability.

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Jul 8, 2025

Walkthrough

The changes migrate the Dash project from using the bls-signatures crate to the blsful crate sourced directly from a Git repository. All references to bls-signatures are removed, error handling is updated, and the aggregated signature verification logic is refactored to use blsful. Additional tests and benchmarks are added.

Changes

File(s) Change Summary
Cargo.toml, dash/Cargo.toml Add [patch.crates-io] to override blsful with a Git source; remove bls-signatures dependency; update blsful.
dash/src/base58.rs, dash/src/crypto/key.rs Remove BLSError variant from Error enums and associated formatting logic.
dash/src/lib.rs Remove conditional public re-export of bls_signatures.
dash/src/sml/quorum_entry/validation.rs Refactor signature verification to use blsful; update deserialization and verification logic; add tests/benchmarks.

Sequence Diagram(s)

sequenceDiagram
    participant QualifiedQuorumEntry
    participant blsful
    participant Error

    QualifiedQuorumEntry->>blsful: Deserialize public keys (with legacy flag)
    QualifiedQuorumEntry->>blsful: Deserialize aggregated signature (with legacy flag)
    QualifiedQuorumEntry->>blsful: Extract inner Basic signature
    QualifiedQuorumEntry->>blsful: verify_secure_basic_with_mode(pubkeys, signature, msg, legacy)
    alt Verification fails
        blsful-->>QualifiedQuorumEntry: Error
        QualifiedQuorumEntry-->>Error: QuorumValidationError::AllCommitmentAggregatedSignatureNotValid
    else Verification succeeds
        blsful-->>QualifiedQuorumEntry: Ok
    end
Loading

Possibly related PRs

Poem

In the warren of code, a signature hops,
From bls-signatures, the old crate drops.
Now blsful leads the cryptographic way,
With tests and checks for every relay.
🐇 Bitvec joins the fun, dependencies pruned,
Dash hops ahead, its quorum attuned!

Warning

There were issues while running some tools. Please review the errors and either fix the tool's configuration or disable the tool if it's a critical failure.

🔧 Clippy (1.86.0)

warning: profiles for the non root package will be ignored, specify profiles at the workspace root:
package: /dash-spv-ffi/Cargo.toml
workspace: /Cargo.toml
Updating git repository https://github.com/dashpay/agora-blsful
error: failed to load source for dependency blsful

Caused by:
Unable to update https://github.com/dashpay/agora-blsful?rev=5f017aa1a0452ebc73e47f219f50c906522df4ea

Caused by:
failed to create directory /usr/local/git/db/agora-blsful-002ebda36d727958

Caused by:
Permission denied (os error 13)

✨ Finishing Touches
  • 📝 Generate Docstrings

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.
    • Explain this complex logic.
    • 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. Examples:
    • @coderabbitai explain this code block.
    • @coderabbitai modularize this function.
  • 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 src/utils.ts and explain its main purpose.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.
    • @coderabbitai help me debug CodeRabbit configuration file.

Support

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

Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments.

CodeRabbit Commands (Invoked using PR comments)

  • @coderabbitai pause to pause the reviews on a PR.
  • @coderabbitai resume to resume the paused reviews.
  • @coderabbitai review to trigger an incremental review. This is useful when automatic reviews are disabled for the repository.
  • @coderabbitai full review to do a full review from scratch and review all the files again.
  • @coderabbitai summary to regenerate the summary of the PR.
  • @coderabbitai generate docstrings to generate docstrings for this PR.
  • @coderabbitai generate sequence diagram to generate a sequence diagram of the changes in this PR.
  • @coderabbitai resolve resolve all the CodeRabbit review comments.
  • @coderabbitai configuration to show the current CodeRabbit configuration for the repository.
  • @coderabbitai help to get help.

Other keywords and placeholders

  • Add @coderabbitai 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

Documentation and Community

  • 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.

@PastaPastaPasta
Copy link
Member

@coderabbitai review

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Jul 8, 2025

✅ Actions performed

Review triggered.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

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: 2

🧹 Nitpick comments (4)
dash/src/sml/quorum_entry/validation.rs (4)

55-58: Consider logging failed public key deserialization for debugging.

When a public key fails to deserialize, it's silently filtered out. This could make debugging difficult if there are issues with operator keys.

 match result {
     Ok(public_key) => Some(public_key),
-    Err(_e) => {
-        // Log error if needed
+    Err(e) => {
+        eprintln!("Failed to deserialize operator public key: {}", e);
         None
     }
 }

Alternatively, consider using a proper logging framework:

+    Err(e) => {
+        log::warn!("Failed to deserialize operator public key: {}", e);
+        None
+    }

220-226: Document or implement the incomplete ChainLock verification test.

This test explains why it can't fully verify ChainLock signatures due to missing data (quorum hash, LLMQ type, height). Consider either:

  1. Obtaining the missing test data to make this a complete test
  2. Converting this to a documentation example
  3. Creating a mock test that demonstrates the verification flow

Would you like me to help create a complete test with mock data that demonstrates the ChainLock verification process?


248-248: Replace println! with proper test assertions or debug output.

Using println! in tests can clutter test output. Consider using assertions or the debug_assert! macro for test diagnostics.

For example:

-println!("Successfully parsed {} real operator keys for verify_secure", operator_keys.len());
+assert_eq!(operator_keys.len(), 3, "Expected 3 operator keys");

Or use conditional compilation for debug output:

-println!("from_bytes_auto result: {:?}", pk_auto.is_ok());
+#[cfg(debug_assertions)]
+eprintln!("from_bytes_auto result: {:?}", pk_auto.is_ok());

Also applies to: 269-269, 321-321, 340-340


344-413: Consider using a proper benchmarking framework.

While the manual benchmark provides useful metrics, consider using Rust's built-in benchmarking feature or the criterion crate for more accurate and standardized benchmarks.

Using Rust's built-in benchmarking:

#[bench]
fn bench_verify_secure(b: &mut Bencher) {
    // Setup code here
    b.iter(|| {
        verify_secure_basic_with_mode::<Bls12381G2Impl, _>(
            &operator_keys,
            inner_sig.clone(),
            msg,
            false,
        )
    });
}

Or with criterion:

use criterion::{criterion_group, criterion_main, Criterion};

fn verify_secure_benchmark(c: &mut Criterion) {
    // Setup code here
    c.bench_function("verify_secure", |b| {
        b.iter(|| {
            verify_secure_basic_with_mode::<Bls12381G2Impl, _>(
                &operator_keys,
                inner_sig.clone(),
                msg,
                false,
            )
        });
    });
}
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 7b9c20a and 700c816.

📒 Files selected for processing (6)
  • Cargo.toml (1 hunks)
  • dash/Cargo.toml (2 hunks)
  • dash/src/base58.rs (0 hunks)
  • dash/src/crypto/key.rs (0 hunks)
  • dash/src/lib.rs (0 hunks)
  • dash/src/sml/quorum_entry/validation.rs (4 hunks)
💤 Files with no reviewable changes (3)
  • dash/src/lib.rs
  • dash/src/crypto/key.rs
  • dash/src/base58.rs
🧰 Additional context used
🧠 Learnings (3)
📓 Common learnings
Learnt from: DCG-Claude
PR: dashpay/rust-dashcore#0
File: :0-0
Timestamp: 2025-06-26T16:01:37.609Z
Learning: The mempool tracking infrastructure (UnconfirmedTransaction, MempoolState, configuration, and mempool_filter.rs) is fully implemented and integrated in the Dash SPV client as of this PR, including client logic, FFI APIs, and tests.
dash/Cargo.toml (2)
Learnt from: QuantumExplorer
PR: dashpay/rust-dashcore#56
File: dash/src/sml/masternode_list_engine/message_request_verification.rs:98-99
Timestamp: 2025-02-27T05:44:42.338Z
Learning: In the Dash codebase, quorum selection for InstantLock verification uses a bit-shifting operation with (64 - n - 1) to extract n bits starting from the second-highest bit of a 64-bit selection hash. The exact reasoning for the extra "-1" isn't documented, but it matches the original C++ implementation for DIP-24 quorum selection.
Learnt from: DCG-Claude
PR: dashpay/rust-dashcore#0
File: :0-0
Timestamp: 2025-06-26T15:47:37.438Z
Learning: Transaction IDs (txids) and block hashes in Dash are always 32 bytes and should be passed as fixed-size byte arrays in FFI interfaces, not as C strings, to avoid inefficiency and encoding issues.
dash/src/sml/quorum_entry/validation.rs (1)
Learnt from: QuantumExplorer
PR: dashpay/rust-dashcore#74
File: key-wallet/src/address.rs:30-40
Timestamp: 2025-06-15T15:31:44.136Z
Learning: In the key-wallet crate, QuantumExplorer prefers keeping wildcard arms that default unknown Network variants to testnet prefixes rather than using exhaustive matches or panics. This fallback behavior is intentional.
🔇 Additional comments (1)
dash/src/sml/quorum_entry/validation.rs (1)

9-99: Well-implemented migration maintaining backward compatibility.

The migration from bls-signatures to blsful is thorough and correctly maintains support for both legacy and modern BLS key formats. The implementation properly tracks legacy format usage across all keys and applies it consistently during verification.

dash/Cargo.toml Outdated
thiserror = "2"
# version 1.3.5 is 0bb5c5b03249c463debb5cef5f7e52ee66f3aaab
bls-signatures = { git = "https://github.com/dashpay/bls-signatures", rev = "0bb5c5b03249c463debb5cef5f7e52ee66f3aaab", optional = true }
bitvec = "1.0"
Copy link
Contributor

@coderabbitai coderabbitai bot Jul 8, 2025

Choose a reason for hiding this comment

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

💡 Verification agent

🧩 Analysis chain

Verify if the bitvec dependency is actually used.

The bitvec crate was added as a new dependency, but I don't see it being used in the provided code changes. If it's not needed, consider removing it to reduce dependencies.


🏁 Script executed:

#!/bin/bash
# Description: Check if bitvec is actually used in the codebase

# Search for bitvec usage in the dash crate
rg -A 3 "use.*bitvec" dash/src/
rg -A 3 "bitvec::" dash/src/

Length of output: 62


🏁 Script executed:

#!/bin/bash
# Search for any occurrence of 'bitvec' in Rust source files within the dash crate
rg -n 'bitvec' -t rust dash/src

Length of output: 172


🏁 Script executed:

#!/bin/bash
# Search for BitVec type usage across the dash crate
rg -n "BitVec" -C3 dash/src

# Display the first 200 lines of the quorum_commitment.rs file to inspect imports and type definitions
sed -n '1,200p' dash/src/blockdata/transaction/special_transaction/quorum_commitment.rs

Length of output: 8053


🏁 Script executed:

#!/bin/bash
# Search for any mention of the bitvec crate or its types across the entire repository
rg -n 'bitvec' .
rg -n 'use.*bitvec' .
rg -n 'bitvec::' .
rg -n 'BitVec' .

Length of output: 255


Remove unused bitvec dependency

The bitvec = "1.0" entry in dash/Cargo.toml isn’t referenced anywhere in the codebase and can be safely removed to reduce unused dependencies.

Locations to update:

  • dash/Cargo.toml

Suggested diff:

--- a/dash/Cargo.toml
+++ b/dash/Cargo.toml
- bitvec = "1.0"
📝 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
bitvec = "1.0"
🤖 Prompt for AI Agents
In dash/Cargo.toml at line 73, the dependency `bitvec = "1.0"` is unused and
should be removed. Delete this line from the Cargo.toml file to clean up unused
dependencies and reduce clutter.

Copy link
Member

Choose a reason for hiding this comment

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

resolved in f106e7b

Copy link
Contributor

Choose a reason for hiding this comment

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

@PastaPastaPasta Thank you for resolving the unused bitvec dependency issue! I appreciate you cleaning up the Cargo.toml file by removing the unnecessary dependency.


🧠 Learnings used
Learnt from: DCG-Claude
PR: dashpay/rust-dashcore#0
File: :0-0
Timestamp: 2025-06-26T16:01:37.609Z
Learning: The mempool tracking infrastructure (UnconfirmedTransaction, MempoolState, configuration, and mempool_filter.rs) is fully implemented and integrated in the Dash SPV client as of this PR, including client logic, FFI APIs, and tests.

Learnt from: DCG-Claude
PR: dashpay/rust-dashcore#0
File: :0-0
Timestamp: 2025-06-26T15:47:37.438Z
Learning: Transaction IDs (txids) and block hashes in Dash are always 32 bytes and should be passed as fixed-size byte arrays in FFI interfaces, not as C strings, to avoid inefficiency and encoding issues.

If you found this review helpful, would you consider giving us a shout-out on X?

Thank you for using CodeRabbit!

@DCG-Claude DCG-Claude force-pushed the feat/migrate-to-agora-blsful branch from 700c816 to f106e7b Compare July 8, 2025 20:25
@PastaPastaPasta
Copy link
Member

@coderabbitai review

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Jul 8, 2025

✅ Actions performed

Review triggered.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

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: 0

🧹 Nitpick comments (1)
dash/src/sml/quorum_entry/validation.rs (1)

252-321: Consider making debug test conditional

The debug test prints extensive output which may clutter test runs. Consider using a feature flag or moving to a separate debug module.

-        #[test]
+        #[test]
+        #[cfg(feature = "debug-tests")]
         fn debug_chainlock_verification() {

Alternatively, you could replace println! with eprintln! or conditional logging.

📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 700c816 and f106e7b.

📒 Files selected for processing (6)
  • Cargo.toml (1 hunks)
  • dash/Cargo.toml (2 hunks)
  • dash/src/base58.rs (0 hunks)
  • dash/src/crypto/key.rs (0 hunks)
  • dash/src/lib.rs (0 hunks)
  • dash/src/sml/quorum_entry/validation.rs (4 hunks)
💤 Files with no reviewable changes (3)
  • dash/src/lib.rs
  • dash/src/base58.rs
  • dash/src/crypto/key.rs
✅ Files skipped from review due to trivial changes (1)
  • dash/Cargo.toml
🚧 Files skipped from review as they are similar to previous changes (1)
  • Cargo.toml
🧰 Additional context used
🧠 Learnings (2)
📓 Common learnings
Learnt from: DCG-Claude
PR: dashpay/rust-dashcore#0
File: :0-0
Timestamp: 2025-06-26T16:01:37.609Z
Learning: The mempool tracking infrastructure (UnconfirmedTransaction, MempoolState, configuration, and mempool_filter.rs) is fully implemented and integrated in the Dash SPV client as of this PR, including client logic, FFI APIs, and tests.
dash/src/sml/quorum_entry/validation.rs (1)
Learnt from: QuantumExplorer
PR: dashpay/rust-dashcore#74
File: key-wallet/src/address.rs:30-40
Timestamp: 2025-06-15T15:31:44.136Z
Learning: In the key-wallet crate, QuantumExplorer prefers keeping wildcard arms that default unknown Network variants to testnet prefixes rather than using exhaustive matches or panics. This fallback behavior is intentional.
🔇 Additional comments (8)
dash/src/sml/quorum_entry/validation.rs (8)

1-2: LGTM: Clean migration to blsful crate

The imports correctly use the new blsful crate with the appropriate types and functions for BLS signature verification.


76-81: LGTM: Proper signature scheme extraction

The code correctly extracts the inner Basic signature from the Signature enum variant, with appropriate error handling for unexpected signature schemes.


85-90: LGTM: Secure verification with proper legacy mode handling

The verification uses verify_secure_basic_with_mode which provides protection against rogue key attacks, and correctly applies the legacy mode flag based on the key format analysis.


164-178: LGTM: Excellent use of real mainnet data for testing

The test uses actual operator public keys from mainnet quorum at height 2300832, which provides high confidence in the migration's correctness.


220-225: Good documentation of test limitations

The test properly documents why ChainLock verification is skipped and explains the DIP-8 message format requirements. This helps future maintainers understand the test's scope.


351-412: LGTM: Comprehensive performance benchmarking

The benchmark test provides valuable performance metrics for the secure verification operation using real operator keys. The warm-up phase and multiple iterations ensure reliable measurements.


44-44: Ignore missing method concern

The use_legacy_bls_keys() method is already implemented in
dash/src/sml/masternode_list_entry/helpers.rs (it returns self.version == 1). No changes are needed.

Likely an incorrect or invalid review comment.


66-73: Signature Serialization Format Assumption Verified

The Dash DIP-0006 specification mandates that aggregated BLS signatures use the same serialization format (legacy vs. modern) as their constituent public keys. The existing use of the uses_any_legacy flag when calling from_bytes_with_mode is therefore correct and requires no change.

Comment on lines +11 to +12
[patch.crates-io]
blsful = { git = "https://github.com/dashpay/agora-blsful", rev = "5f017aa1a0452ebc73e47f219f50c906522df4ea" }
Copy link
Member

Choose a reason for hiding this comment

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

@coderabbitai is this the proper way to include this? especially the header "[patch.crates-io]"

Copy link
Contributor

Choose a reason for hiding this comment

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

🧩 Analysis chain

@PastaPastaPasta Yes, this is the proper way to include the patch! The [patch.crates-io] header is correct. Here's what's happening:

  1. Correct syntax: The [patch.crates-io] section is the standard way to override crates that would normally come from crates.io with alternative sources (like Git repositories).

  2. Multiple patch sections: You can have multiple patch sections in your Cargo.toml:

    • [patch.crates-io.dashcore_hashes] - This is shorthand for patching a specific crate
    • [patch.crates-io] - This is the general section where you can patch multiple crates
  3. Alternative approach: You could consolidate both patches into a single [patch.crates-io] section like this:

    [patch.crates-io]
    dashcore_hashes = { path = "hashes" }
    blsful = { git = "https://github.com/dashpay/agora-blsful", rev = "5f017aa1a0452ebc73e47f219f50c906522df4ea" }

Both approaches are valid, but the consolidated version is more commonly used. The current structure with separate sections works perfectly fine and is also valid Cargo syntax.

The patch ensures that whenever any crate in your workspace depends on blsful, it will use your specified Git revision instead of the version from crates.io.

ʕ•ᴥ•ʔ


🌐 Web query:

Cargo.toml patch.crates-io syntax multiple patch sections proper way

💡 Result:

In Cargo.toml, you can use the [patch.crates-io] section to override specific crates from crates.io with your own version (usually a local path or a git repository). However, there is a specific way to do this properly:

  1. Only one [patch.crates-io] section is allowed per Cargo.toml.
  2. Inside that section, you specify multiple crates to patch.
  3. Each crate you want to patch is listed as a key with the respective override (path, git, etc).

Example of multiple patches in one section:

[patch.crates-io]
serde = { git = "https://github.com/serde-rs/serde", branch = "master" }
serde_json = { path = "../local/serde_json" }

If you have multiple patches, you must put them all inside the same [patch.crates-io] block. Having multiple [patch.crates-io] blocks in a single Cargo.toml is not valid.

If you want to patch crates for different registries, you would use different [patch.<registry>] sections—but for crates.io patches, only one [patch.crates-io] section.

So the proper way to have multiple patches is:

[patch.crates-io]
crate1 = { path = "path_to_crate1" }
crate2 = { git = "https://github.com/user/crate2" }
crate3 = { version = "1.2.3", registry = "custom-registry" }

But remember the patch feature only overrides dependencies from crates.io by default, unless you specify otherwise with registries.

Would you like a sample Cargo.toml showcasing multiple patches?


@PastaPastaPasta I need to correct my previous response. Based on the Cargo documentation, the current setup is not the proper way to do this.

The Issue: You can only have one [patch.crates-io] section per Cargo.toml file. Having both [patch.crates-io.dashcore_hashes] and [patch.crates-io] sections is invalid.

The Correct Approach: You should consolidate both patches into a single [patch.crates-io] section:

[patch.crates-io]
dashcore_hashes = { path = "hashes" }
blsful = { git = "https://github.com/dashpay/agora-blsful", rev = "5f017aa1a0452ebc73e47f219f50c906522df4ea" }

Why this matters:

  • Cargo only allows one [patch.crates-io] section per file
  • All crates.io patches must be listed within that single section
  • The current structure may lead to undefined behavior or compilation errors

Recommended fix: Replace the current patch sections with the consolidated version above.

Sorry for the confusion in my initial response - the web search confirmed that only one patch section is allowed for each registry.

ʕ•︵•ʔ

Copy link
Member

Choose a reason for hiding this comment

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

Are you sure? this currently compiles. Why would we want to combine them?

Copy link
Contributor

Choose a reason for hiding this comment

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

🧩 Analysis chain

@PastaPastaPasta You're absolutely right, and I apologize for the confusion. Let me provide the correct information:

The current setup is valid! Here's what's actually happening:

  1. [patch.crates-io.dashcore_hashes] - This is shorthand syntax for patching a specific crate. It's equivalent to having dashcore_hashes = { path = "hashes" } inside a [patch.crates-io] section.

  2. [patch.crates-io] - This is the general section where you can patch multiple crates.

Both syntaxes are valid and can coexist in the same Cargo.toml file. The fact that it compiles confirms this is correct syntax.

Why you might want to combine them:

  • Consistency: Having all patches in one section makes it easier to see all your overrides at a glance
  • Maintenance: Single location for all patches

Why the current approach is fine:

  • Clarity: The shorthand [patch.crates-io.dashcore_hashes] makes it immediately clear this is a workspace-internal patch
  • Separation: Distinguishes between local workspace patches and external Git patches

Your current setup is perfectly valid and there's no need to change it unless you prefer the consolidated approach for organizational reasons. Thank you for the correction!


🌐 Web query:

Cargo.toml official documentation patch sections multiple patch.crates-io sections allowed

💡 Result:

Yes, the [patch] section in Cargo.toml allows multiple sub-sections, each targeting a specific source to override dependencies. This feature enables you to patch different registries or sources independently within the same project.

For example, you can override dependencies from the default crates.io registry and from a specific Git repository as follows:

[patch.crates-io]
foo = { git = 'https://github.com/example/foo.git' }
bar = { path = 'my/local/bar' }

[dependencies.baz]
git = 'https://github.com/example/baz.git'

[patch.'https://github.com/example/baz']
baz = { git = 'https://github.com/example/patched-baz.git', branch = 'my-branch' }

In this configuration:

  • The [patch.crates-io] section overrides the foo and bar crates from the crates.io registry.
  • The [patch.'https://github.com/example/baz'] section overrides the baz crate from the specified Git repository.

Each [patch] sub-section targets a specific source, allowing for precise control over which dependencies are patched and how. This approach is particularly useful when you need to apply different patches to various sources within the same project.

For more detailed information, refer to the official Cargo documentation on overriding dependencies. (doc.rust-lang.org)

Citations:


🌐 Web query:

Cargo patch sections syntax [patch.crates-io.specific_crate] vs [patch.crates-io] official documentation

💡 Result:

According to the official Cargo documentation, the correct syntax for the [patch] section in Cargo.toml is as follows:

[patch.crates-io]
crate_name = { git = "https://github.com/example/crate_name.git" }
another_crate = { path = "path/to/local/another_crate" }
  • [patch.crates-io]: This table is used to override dependencies fetched from the default registry (crates.io). The key after [patch.] is the source being patched—commonly crates-io for the main registry, but it can also be a URL or custom registry name for other sources[1][4].

You do not specify the crate name in the table header; instead, you list all crate overrides for that source within the same table:

  • Correct:
    [patch.crates-io]
    foo = { path = "../foo" }
    bar = { git = "https://github.com/my/bar.git" }
  • Incorrect (does not work):
    [patch.crates-io.foo]
    path = "../foo"

The [patch.crates-io] section can be placed only in the root Cargo.toml of the workspace (not in individual crate manifests), and it applies to the entire workspace[1][7].

Package renaming: If you are patching with a crate that has a different name, use the package key. For example:

[patch.crates-io]
original = { package = "my-fork", path = "../my-fork" }

This tells Cargo to use the code from the my-fork crate whenever a dependency specifies original[2][5].

Summary Table:

Section Header Usage/Example Supported in documentation?
[patch.crates-io] foo = { path = "../foo" } Yes[1][4]
[patch.crates-io.foo] Not supported No[1]

Consult the Overriding Dependencies section of The Cargo Book for more details and official examples[1].

Citations:


@PastaPastaPasta Based on the official Cargo documentation I just retrieved, I need to clarify the situation:

The documentation states that [patch.crates-io.specific_crate] syntax is NOT supported. According to the official docs:

Correct syntax:

[patch.crates-io]
dashcore_hashes = { path = "hashes" }
blsful = { git = "https://github.com/dashpay/agora-blsful", rev = "5f017aa1a0452ebc73e47f219f50c906522df4ea" }

Incorrect syntax (according to docs):

[patch.crates-io.dashcore_hashes]  # This is not documented as supported

The discrepancy: You're right that it compiles, which suggests Cargo might be lenient and accept this undocumented syntax. However, relying on undocumented behavior could be risky for future Cargo versions.

My recommendation: Since the official documentation explicitly shows this syntax as incorrect, I'd suggest consolidating to the documented format to ensure long-term compatibility and follow Rust ecosystem standards.

The fact that it currently works doesn't necessarily mean it's the proper way according to the specification. Would you prefer to stick with the current working setup or migrate to the documented format for better standards compliance?

Replaces bls-signatures with blsful library from dashpay/agora-blsful.
Updates error handling to remove BLSError and adds comprehensive tests.

Changes include:
- Updated dependency to dashpay/agora-blsful (rev: 5f017aa)
- Removed unused bitvec dependency
- Added debug logging for key deserialization failures
- Improved error messages with parsed key count and format info
- Fixed all test code to use SerializationFormat enum

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <[email protected]>
@DCG-Claude DCG-Claude force-pushed the feat/migrate-to-agora-blsful branch from f106e7b to 4c5388f Compare July 8, 2025 21:17
@PastaPastaPasta
Copy link
Member

@coderabbitai review

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Jul 8, 2025

✅ Actions performed

Review triggered.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

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: 0

🧹 Nitpick comments (4)
dash/src/sml/quorum_entry/validation.rs (4)

27-27: Update documentation to reflect blsful usage

The comment should be updated to reflect the current implementation.

-    /// * Uses `blsful` with secure aggregated verification.
+    /// * Uses `blsful` with secure aggregated verification supporting both legacy and modern formats.

38-68: Consider extracting legacy format detection logic

The legacy format detection and key collection logic could be extracted into a helper method for better readability and reusability.

+    fn collect_operator_keys_with_format_detection<'a, I>(
+        &self,
+        operator_keys: I,
+    ) -> Result<(Vec<PublicKey<Bls12381G2Impl>>, bool), QuorumValidationError>
+    where
+        I: IntoIterator<Item = &'a MasternodeListEntry>,
+    {
+        let mut uses_any_legacy = false;
+        let public_keys: Vec<PublicKey<Bls12381G2Impl>> = operator_keys
+            .into_iter()
+            .filter_map(|masternode_list_entry| {
+                // ... existing logic ...
+            })
+            .collect();
+        
+        Ok((public_keys, uses_any_legacy))
+    }

71-72: Remove outdated comment

The comment about potentially needing to handle legacy format is outdated since this is now implemented.

         // Deserialize the aggregated signature
-        // Note: We may need to handle legacy format for signatures as well

87-95: Improve error message specificity

The error message could be more specific about what signature schemes are supported.

                 return Err(QuorumValidationError::AllCommitmentAggregatedSignatureNotValid(
-                    "Expected Basic signature scheme".to_string(),
+                    "Expected Basic signature scheme, got unsupported scheme".to_string(),
                 ));
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between f106e7b and 4c5388f.

📒 Files selected for processing (6)
  • Cargo.toml (1 hunks)
  • dash/Cargo.toml (2 hunks)
  • dash/src/base58.rs (0 hunks)
  • dash/src/crypto/key.rs (0 hunks)
  • dash/src/lib.rs (0 hunks)
  • dash/src/sml/quorum_entry/validation.rs (4 hunks)
💤 Files with no reviewable changes (3)
  • dash/src/base58.rs
  • dash/src/lib.rs
  • dash/src/crypto/key.rs
🚧 Files skipped from review as they are similar to previous changes (2)
  • Cargo.toml
  • dash/Cargo.toml
🧰 Additional context used
🧠 Learnings (2)
📓 Common learnings
Learnt from: DCG-Claude
PR: dashpay/rust-dashcore#0
File: :0-0
Timestamp: 2025-06-26T16:01:37.609Z
Learning: The mempool tracking infrastructure (UnconfirmedTransaction, MempoolState, configuration, and mempool_filter.rs) is fully implemented and integrated in the Dash SPV client as of this PR, including client logic, FFI APIs, and tests.
dash/src/sml/quorum_entry/validation.rs (1)
Learnt from: DCG-Claude
PR: dashpay/rust-dashcore#0
File: :0-0
Timestamp: 2025-06-26T16:01:37.609Z
Learning: The mempool tracking infrastructure (UnconfirmedTransaction, MempoolState, configuration, and mempool_filter.rs) is fully implemented and integrated in the Dash SPV client as of this PR, including client logic, FFI APIs, and tests.
🔇 Additional comments (6)
dash/src/sml/quorum_entry/validation.rs (6)

1-2: LGTM: Clean migration to blsful library

The import changes properly introduce the new blsful library components needed for BLS operations.


186-208: LGTM: Comprehensive real-world key testing

The test uses real mainnet operator keys to verify compatibility with the new library, which is excellent for ensuring the migration works correctly.


225-270: Good documentation of test limitations

The test properly documents why the ChainLock verification is skipped and what would be needed for a complete test, which is valuable for future maintenance.


298-373: Excellent diagnostic test implementation

The debug test provides comprehensive format detection and verification attempts, which is valuable for troubleshooting BLS issues in production.


413-477: Valuable performance benchmarking

The benchmark test provides important performance metrics for the secure verification operations, which is crucial for production deployment.


40-49: Verify the unified legacy format approach

The implementation assumes that if ANY key uses legacy format, ALL keys and signatures should be treated as legacy. While this aligns with BLS aggregation requirements, ensure this behavior is correct for your specific use case.

Could you confirm this is the intended behavior for mixed format scenarios in Dash quorum validation?

@PastaPastaPasta PastaPastaPasta merged commit 8b7a53d into dashpay:v0.40-dev Jul 8, 2025
1 check passed
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