-
Notifications
You must be signed in to change notification settings - Fork 10
feat: migrate from bls-signatures to blsful library #82
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
feat: migrate from bls-signatures to blsful library #82
Conversation
WalkthroughThe changes migrate the Dash project from using the Changes
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
Possibly related PRs
Poem
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: Caused by: Caused by: Caused by: ✨ Finishing Touches
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. 🪧 TipsChatThere are 3 ways to chat with CodeRabbit:
SupportNeed 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)
Other keywords and placeholders
CodeRabbit Configuration File (
|
|
@coderabbitai review |
✅ Actions performedReview triggered.
|
There was a problem hiding this 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:
- Obtaining the missing test data to make this a complete test
- Converting this to a documentation example
- 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: Replaceprintln!with proper test assertions or debug output.Using
println!in tests can clutter test output. Consider using assertions or thedebug_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
criterioncrate 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
📒 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-signaturestoblsfulis 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" |
There was a problem hiding this comment.
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/srcLength 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.rsLength 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.
| 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.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
resolved in f106e7b
There was a problem hiding this comment.
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!
700c816 to
f106e7b
Compare
|
@coderabbitai review |
✅ Actions performedReview triggered.
|
There was a problem hiding this 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 conditionalThe 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!witheprintln!or conditional logging.
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 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 crateThe imports correctly use the new
blsfulcrate with the appropriate types and functions for BLS signature verification.
76-81: LGTM: Proper signature scheme extractionThe code correctly extracts the inner
Basicsignature from theSignatureenum variant, with appropriate error handling for unexpected signature schemes.
85-90: LGTM: Secure verification with proper legacy mode handlingThe verification uses
verify_secure_basic_with_modewhich 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 testingThe 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 limitationsThe 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 benchmarkingThe 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 concernThe
use_legacy_bls_keys()method is already implemented in
dash/src/sml/masternode_list_entry/helpers.rs(it returnsself.version == 1). No changes are needed.Likely an incorrect or invalid review comment.
66-73: Signature Serialization Format Assumption VerifiedThe 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_legacyflag when callingfrom_bytes_with_modeis therefore correct and requires no change.
| [patch.crates-io] | ||
| blsful = { git = "https://github.com/dashpay/agora-blsful", rev = "5f017aa1a0452ebc73e47f219f50c906522df4ea" } |
There was a problem hiding this comment.
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]"
There was a problem hiding this comment.
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:
-
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). -
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
-
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:
- Only one
[patch.crates-io]section is allowed per Cargo.toml. - Inside that section, you specify multiple crates to patch.
- 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.
ʕ•︵•ʔ
There was a problem hiding this comment.
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?
There was a problem hiding this comment.
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:
-
[patch.crates-io.dashcore_hashes]- This is shorthand syntax for patching a specific crate. It's equivalent to havingdashcore_hashes = { path = "hashes" }inside a[patch.crates-io]section. -
[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 thefooandbarcrates from thecrates.ioregistry. - The
[patch.'https://github.com/example/baz']section overrides thebazcrate 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—commonlycrates-iofor 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:
- 1: https://doc.rust-lang.org/cargo/reference/overriding-dependencies.html
- 2: https://users.rust-lang.org/t/cargo-patch-crates-with-different-names/61772
- 3: Patch git dependency in a workspace or sub-directory rust-lang/cargo#9624
- 4: https://gatowololo.github.io/blog/cargo-patch/
- 5: Support patching one with another package from the same source rust-lang/cargo#9227
- 6: https://docs.rs/cargo-patch
- 7: https://users.rust-lang.org/t/patch-crates-io-at-workspace-level/90622
- 8: https://docs.rs/cargo-lock/latest/cargo_lock/struct.Patch.html
- 9: https://hackmd.io/@rust-cargo-team/rkm1ttkns
- 10: https://web.mit.edu/rust-lang_v1.25/arch/amd64_ubuntu1404/share/doc/rust/html/cargo/reference/manifest.html
@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 supportedThe 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]>
f106e7b to
4c5388f
Compare
|
@coderabbitai review |
✅ Actions performedReview triggered.
|
There was a problem hiding this 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 usageThe 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 logicThe 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 commentThe 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 specificityThe 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
📒 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 libraryThe import changes properly introduce the new
blsfullibrary components needed for BLS operations.
186-208: LGTM: Comprehensive real-world key testingThe 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 limitationsThe 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 implementationThe debug test provides comprehensive format detection and verification attempts, which is valuable for troubleshooting BLS issues in production.
413-477: Valuable performance benchmarkingThe benchmark test provides important performance metrics for the secure verification operations, which is crucial for production deployment.
40-49: Verify the unified legacy format approachThe 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?
Summary
Details
This PR migrates the BLS cryptography implementation from the older
bls-signatureslibrary to the newerblsfullibrary (specifically dashpay/agora-blsful fork). The migration includes:bls-signaturesdependencies and error typesverify_aggregated_commitment_signatureto use the blsful APIThe migration uses dashpay/agora-blsful with the main branch to maintain compatibility with both legacy and modern BLS key formats.
Test Plan
🤖 Generated with Claude Code
Summary by CodeRabbit
Refactor
New Features
Chores