-
Notifications
You must be signed in to change notification settings - Fork 43
feat(sdk): asset lock quorum and core locked height verification #2030
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
base: v2.0-dev
Are you sure you want to change the base?
Conversation
9c21078
to
b3f5f17
Compare
a328081
to
f57e455
Compare
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 (5)
packages/rs-sdk/src/sdk.rs (1)
788-788
: Consider a different default value.The default value of
NetworkType::Mock
in theDefault
implementation means that users must explicitly set a network type for non-mock usage. While this is handled with an error check in thebuild
method, it might be better to use a more sensible default such asNetworkType::Testnet
for development ease.packages/rs-sdk/src/error.rs (1)
69-76
: Fix typo in error message.There's a small typo in the error message: "avaiable" should be "available".
- #[error("Asset lock for core locked height {0} not available yet, max avaiable locked core height is {1}; try again later")] + #[error("Asset lock for core locked height {0} not available yet, max available locked core height is {1}; try again later")]packages/rs-sdk/src/platform/transition/asset_lock.rs (3)
33-115
: Consider adding more comprehensive tests for the entire verification flow.While the signature verification is well-tested, it would be beneficial to add tests for the complete
verify
method implementation, covering both chain and instant asset locks, including success and failure scenarios (e.g., core height not available, quorum not found, etc.).Would you like me to suggest a structure for these additional tests to ensure comprehensive test coverage of the
verify
method?
116-123
:❓ Verification inconclusive
Consider refactoring signature verification function for reuse.
As noted in the TODO comment, the
verify_instant_lock_signature
function is a generalization of existing code from drive-abci. Consider moving this function to a shared location to promote code reuse and maintainability across the codebase.
🏁 Script executed:
#!/bin/bash # Check where the original function exists and other potential places for the shared code echo "Searching for the original function in drive-abci..." rg "verify_recent_instant_lock_signature_locally_v0" --type rust echo "Checking for potential shared utility modules for cryptographic verification..." fd -e rs -p ".*util.*crypto|.*crypto.*util|.*verification"Length of output: 2083
Refactor Signature Verification for Reuse
Based on our search results, the function in question is indeed a generalization of theverify_recent_instant_lock_signature_locally_v0
function from drive-abci. To improve maintainability and reduce duplication, please consider refactoring theverify_instant_lock_signature
function by moving its common logic to a shared location. Here are some actionable points:
Shared Module Suggestion:
Evaluate creating (or extending) a common cryptographic utilities module—possibly within a new shared crate or an existing shared location—so that both rs-sdk and drive-abci can reuse the signature verification logic.Consistency Check:
Ensure that any changes or move of the function maintain feature parity with drive-abci’sverify_recent_instant_lock_signature_locally_v0
and that all related call sites are updated accordingly.Discussion & Roadmap:
As noted in the TODO, it might be useful to discuss this move with the team to determine the best long-term arrangement for shared cryptographic verification routines across the codebase.
41-42
:❓ Verification inconclusive
Consider implementing a caching mechanism for core chain lock info.
As noted in the TODO comment, implementing a caching mechanism would help avoid redundant fetches of the same data, which could improve performance, especially when processing multiple asset locks in quick succession.
🏁 Script executed:
#!/bin/bash # Check for existing caching implementations in the codebase that could be reused echo "Searching for existing caching implementations..." rg -A 5 "cache.*mechanism|cach(e|ing)" --type rustLength of output: 76300
Action Required: Leverage Existing Caching Patterns for Chain Lock Data
The asset lock transition currently includes a TODO for adding a caching mechanism. Given that the codebase already provides several caching implementations (e.g., in
packages/rs-dapi-client/src/connection_pool.rs
and various modules underpackages/rs-drive/src/cache/
), it would be beneficial to reuse or adapt one of these patterns. This reuse can help avoid redundant fetches for core chain lock info, optimizing performance when processing multiple asset locks.
- Review the caching pattern in the connection pool and data contract cache implementations as potential models.
- Ensure that the caching added here integrates cleanly with the existing caching infrastructure for consistency.
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (3)
packages/rs-sdk/src/error.rs
(3 hunks)packages/rs-sdk/src/platform/transition/asset_lock.rs
(1 hunks)packages/rs-sdk/src/sdk.rs
(12 hunks)
⏰ Context from checks skipped due to timeout of 90000ms (20)
- GitHub Check: Rust packages (drive) / Linting
- GitHub Check: Rust packages (drive) / Formatting
- GitHub Check: Rust packages (dpp) / Tests
- GitHub Check: Rust packages (dpp) / Unused dependencies
- GitHub Check: Rust packages (dpp) / Linting
- GitHub Check: Rust packages (dpp) / Check each feature
- GitHub Check: Rust packages (dash-sdk) / Unused dependencies
- GitHub Check: Rust packages (dash-sdk) / Tests
- GitHub Check: Rust packages (dash-sdk) / Linting
- GitHub Check: Rust packages (dash-sdk) / Check each feature
- GitHub Check: Rust packages (dapi-grpc) / Unused dependencies
- GitHub Check: Rust packages (dapi-grpc) / Tests
- GitHub Check: Rust packages (dapi-grpc) / Linting
- GitHub Check: Rust packages (dapi-grpc) / Check each feature
- GitHub Check: Rust packages (dapi-grpc) / Formatting
- GitHub Check: Build Docker images (DAPI, dapi, dapi) / Build DAPI image
- GitHub Check: Build Docker images (Dashmate helper, dashmate-helper, dashmate-helper) / Build Dashmate helper image
- GitHub Check: Build Docker images (Drive, drive, drive-abci) / Build Drive image
- GitHub Check: Build JS packages / Build JS
- GitHub Check: Rust crates security audit
🔇 Additional comments (18)
packages/rs-sdk/src/sdk.rs (10)
8-8
: LGTM: Good addition of network types module import.The addition of the
NetworkType
andQuorumParams
imports aligns well with the PR objective of implementing asset lock quorum verification.
101-102
: Documentation matches implementation.The field documentation clearly explains the purpose of the
network_type
field, which is to determine parameters like quorum types. This is essential for the asset lock verification functionality mentioned in the PR objectives.
155-155
: Good implementation detail.Properly included the new
network_type
field in theClone
implementation, ensuring complete and consistent cloning of theSdk
struct.
534-537
: Excellent method for asset lock verification support.The
quorum_params
method is a key addition for the asset lock verification functionality. It provides access to the network-specific quorum parameters that will be used by theAssetLockProofVerifier
trait mentioned in the PR objectives.
735-735
: Field matches design intent.The
network_type
field in theSdkBuilder
struct is well-placed and matches the overall design intent of configuring the SDK before building it.
817-821
: Clear documentation on required configuration.The documentation for
new
method properly explains that users need to set theNetworkType
withwith_network_type()
. This makes the API requirements clear to users.
952-959
: Well-designed and documented method for network type configuration.The
with_network_type
method is well-implemented and properly documented. It follows the builder pattern consistently and provides clear guidance for users on which network types to use in different scenarios.
1048-1052
: Appropriate error handling for build-time validation.The validation in the
build
method ensures that users don't accidentally create an SDK with the defaultMock
network type in non-mock mode. This is an important safeguard for the asset lock verification functionality.
1069-1069
: Consistent usage across both normal and mock modes.The
network_type
field is properly set in both the normal mode and mock mode SDK instances, ensuring consistent behavior regardless of which mode is used.Also applies to: 1138-1138
718-720
:✅ Verification successful
Verify asset lock verification dependencies.
The documentation now includes setting the network type as a mandatory step, which is required for asset lock verification. However, you should verify that the dependent PR (#2061) mentioned in the PR objectives provides the actual implementation of the
AssetLockProofVerifier
trait that will use this infrastructure.
🏁 Script executed:
#!/bin/bash # Description: Check for the implementation of AssetLockProofVerifier trait echo "Checking for AssetLockProofVerifier trait implementation..." # Search for AssetLockProofVerifier trait definition echo "Searching for AssetLockProofVerifier trait definition:" rg -A 5 "trait\s+AssetLockProofVerifier" # Search for implementations of AssetLockProofVerifier echo "Searching for implementations of AssetLockProofVerifier:" rg -A 5 "impl\s+AssetLockProofVerifier" # Search for any verify() methods related to asset locks echo "Searching for verify() methods related to asset locks:" rg -A 5 "fn\s+verify.*asset.*lock" # Check if quorum_params is being used anywhere echo "Checking if quorum_params is being used anywhere:" rg -A 5 "quorum_params\(\)"Length of output: 5247
Asset Lock Verification Dependencies Confirmed
- The
AssetLockProofVerifier
trait is defined inpackages/rs-sdk/src/platform/transition/asset_lock.rs
, and an implementation (impl AssetLockProofVerifier for AssetLockProof
) is present in the same file.- The required usage of
quorum_params()
—which ties the network type to asset lock verification—is properly integrated in bothnetworks.rs
andsdk.rs
.- Based on the verification, the dependency mentioned in the PR objectives (dependent PR fix(sdk)!: mock sdk cannot find quorum keys in offline mode #2061) appears to provide the necessary implementation. Please ensure this integration remains consistent and is covered by appropriate tests.
packages/rs-sdk/src/error.rs (3)
58-67
: Well-implemented error handling for missing quorums.The
QuorumNotFound
error variant provides comprehensive details about the quorum that couldn't be found, including the hex representation of the quorum hash, quorum type, core chain locked height, and the underlying error. This will be valuable for debugging and proper error propagation.
78-84
: LGTM: Good error message for invalid asset locks.The error message clearly indicates that the asset lock is invalid and includes the detailed reason, which will help developers diagnose and fix issues more easily.
209-215
: Appropriate retry behavior for asset lock errors.The
can_retry
method has been correctly updated to include the new error variants related to asset locks that represent temporary conditions (CoreLockedHeightNotYetAvailable
andQuorumNotFound
). This ensures that operations can be retried when these transient errors occur, improving resilience.packages/rs-sdk/src/platform/transition/asset_lock.rs (5)
16-31
: Well-designed trait and documentation for asset lock verification.The
AssetLockProofVerifier
trait provides a clear interface with comprehensive documentation that explains its purpose, possible error scenarios, and retry conditions. This is excellent for guiding developers on how to handle asset lock verification.
55-65
: Correctly implements core locked height verification.The implementation properly verifies that the asset lock's core chain locked height doesn't exceed the platform's current core chain locked height, which is consistent with the previous review comment that it "must be lower or equal".
66-112
: Comprehensive instant asset lock verification with proper error handling.The verification logic for instant asset locks is thorough, including:
- Structure validation
- Quorum public key retrieval with appropriate error handling
- Signature verification with clear error messages
The code correctly implements the required verification steps and provides detailed error information when verification fails.
123-180
: Well-implemented signature verification with detailed error handling.The
verify_instant_lock_signature
function is well-structured with:
- Clear input validation
- Proper handling of malformed signatures
- Detailed error propagation
- Correct BLS signature verification against the quorum public key
This comprehensive implementation ensures that only valid asset locks will be accepted by the platform.
182-245
: Good test coverage for signature verification.The tests provide good coverage of the signature verification functionality, including:
- A valid signature test case
- Test cases with incorrect quorum hash and public key
- Real-world test vectors generated from the Dash CLI
These tests ensure the reliability of the signature verification logic.
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: 1
♻️ Duplicate comments (1)
packages/rs-sdk/src/platform/transition/asset_lock.rs (1)
58-58
:⚠️ Potential issueCore chain locked height condition check should be
>=
not>
.As noted in a previous review comment, the verification should check if the asset lock's core chain locked height is less than or equal to the platform's height, not strictly greater than. The current condition will fail when the heights are equal, which is a valid case.
- if asset_lock.core_chain_locked_height > platform_core_chain_locked_height { + if asset_lock.core_chain_locked_height <= platform_core_chain_locked_height { + Ok(()) + } else { Err(Error::CoreLockedHeightNotYetAvailable( asset_lock.core_chain_locked_height, platform_core_chain_locked_height, )) - } else { - Ok(()) }
🧹 Nitpick comments (9)
packages/rs-sdk/src/platform/transition/asset_lock.rs (4)
43-43
: Consider implementing caching mechanism.The TODO comment suggests implementing a caching mechanism to avoid fetching the same data multiple times. This would be a valuable performance optimization, especially in scenarios where multiple asset locks are verified in succession.
You could implement a simple time-based cache for the epochs info using a struct with the data and a timestamp, stored in the SDK instance or in a dedicated cache manager.
67-113
: Consider extracting instant asset lock verification to a separate method.The verification logic for instant asset locks is complex and involves multiple steps. Consider extracting it to a dedicated method to improve readability and maintainability.
- AssetLockProof::Instant(instant_asset_lock_proof) => { - instant_asset_lock_proof.validate_structure(sdk.version())?; - - let quorum_hash = instant_asset_lock_proof - .instant_lock() - .cyclehash - .to_raw_hash() - .to_byte_array(); - let quorum_type: QuorumType = sdk.network_settings().chain_locks_quorum_type(); - // Try to fetch the quorum public key; if it fails, we assume platform does not have this quorum yet - let quorum_pubkey = match context_provider.get_quorum_public_key( - quorum_type as u32, - quorum_hash, - platform_core_chain_locked_height, - ) { - Err(ContextProviderError::InvalidQuorum(s)) => Err(Error::QuorumNotFound { - e: ContextProviderError::InvalidQuorum(s), - quorum_hash_hex: hex::encode(quorum_hash), - quorum_type: quorum_type as u32, - core_chain_locked_height: platform_core_chain_locked_height, - }), - Err(e) => Err(e.into()), - Ok(key) => Ok(key), - }?; - - verify_instant_lock_signature( - instant_asset_lock_proof.instant_lock(), - &quorum_type, - &quorum_hash, - &quorum_pubkey, - ) - .map_err(|e| { - Error::InvalidAssetLock(format!( - "error during instant asset lock verification: {}", - e - )) - }) - .and_then(|correct| { - if correct { - Ok(()) - } else { - Err(Error::InvalidAssetLock( - "invalid asset lock signature".to_string(), - )) - } - }) + AssetLockProof::Instant(instant_asset_lock_proof) => { + self.verify_instant_asset_lock(instant_asset_lock_proof, sdk, context_provider, platform_core_chain_locked_height) + }Then implement a private method:
fn verify_instant_asset_lock( &self, instant_asset_lock_proof: &InstantAssetLockProof, sdk: &Sdk, context_provider: &dyn ContextProvider, platform_core_chain_locked_height: u32, ) -> Result<(), Error> { // ... Extracted logic here }
119-122
: Fix typo in function documentation.There's a typo in the function documentation for
verify_instant_lock_signature
: "Retrurns" should be "Returns".- /// Retrurns Ok(true) when signature is valid, Ok(false) when signature is invalid, or an error when something goes wrong. + /// Returns Ok(true) when signature is valid, Ok(false) when signature is invalid, or an error when something goes wrong.
124-181
: Consider enhancing error reporting in signature verification.The error reporting in the signature verification function could be more detailed to help with debugging. When a signature is invalid, it would be helpful to include more context about what specifically failed.
match signature.verify( &threshold_public_key, message_digest.as_byte_array().as_slice(), ) { Ok(()) => Ok(true), - Err(BlsError::InvalidSignature) => Ok(false), + Err(BlsError::InvalidSignature) => { + tracing::debug!( + instant_lock_txid = %instant_lock.txid, + quorum_type = ?quorum_type, + quorum_hash_hex = %hex::encode(quorum_hash), + "Invalid signature for instant lock" + ); + Ok(false) + }, Err(e) => Err(Error::Protocol(e.into())), }packages/rs-sdk/src/networks.rs (5)
6-25
: Consider converting commented consensus parameters into actual code.These consensus parameters appear to be important reference information copied from the original Dash implementation. Since this is related to the PR's asset lock quorum verification functionality, it would be better to implement these as actual constants or a configuration structure instead of keeping them as comments.
- /* - Mainnet: - consensus.llmqTypeChainLocks = Consensus::LLMQType::LLMQ_400_60; - consensus.llmqTypeDIP0024InstantSend = Consensus::LLMQType::LLMQ_60_75; - consensus.llmqTypePlatform = Consensus::LLMQType::LLMQ_100_67; - consensus.llmqTypeMnhf = Consensus::LLMQType::LLMQ_400_85; - - Testnet: - consensus.llmqTypeChainLocks = Consensus::LLMQType::LLMQ_50_60; - consensus.llmqTypeDIP0024InstantSend = Consensus::LLMQType::LLMQ_60_75; - consensus.llmqTypePlatform = Consensus::LLMQType::LLMQ_25_67; - consensus.llmqTypeMnhf = Consensus::LLMQType::LLMQ_50_60; - - Devnet: - consensus.llmqTypeChainLocks = Consensus::LLMQType::LLMQ_DEVNET; - consensus.llmqTypeDIP0024InstantSend = Consensus::LLMQType::LLMQ_DEVNET_DIP0024; - consensus.llmqTypePlatform = Consensus::LLMQType::LLMQ_DEVNET_PLATFORM; - consensus.llmqTypeMnhf = Consensus::LLMQType::LLMQ_DEVNET; - - */ + /// Network consensus parameters for different Dash networks + pub struct ConsensusParams { + pub llmq_type_chain_locks: QuorumType, + pub llmq_type_dip0024_instant_send: QuorumType, + pub llmq_type_platform: QuorumType, + pub llmq_type_mnhf: QuorumType, + } + + /// Mainnet consensus parameters + pub const MAINNET_CONSENSUS: ConsensusParams = ConsensusParams { + llmq_type_chain_locks: QuorumType::LLMQ_400_60, + llmq_type_dip0024_instant_send: QuorumType::LLMQ_60_75, + llmq_type_platform: QuorumType::LLMQ_100_67, + llmq_type_mnhf: QuorumType::LLMQ_400_85, + }; + + /// Testnet consensus parameters + pub const TESTNET_CONSENSUS: ConsensusParams = ConsensusParams { + llmq_type_chain_locks: QuorumType::LLMQ_50_60, + llmq_type_dip0024_instant_send: QuorumType::LLMQ_60_75, + llmq_type_platform: QuorumType::LLMQ_25_67, + llmq_type_mnhf: QuorumType::LLMQ_50_60, + }; + + /// Devnet consensus parameters + pub const DEVNET_CONSENSUS: ConsensusParams = ConsensusParams { + llmq_type_chain_locks: QuorumType::LLMQ_DEVNET, + llmq_type_dip0024_instant_send: QuorumType::LLMQ_DEVNET_DIP0024, + llmq_type_platform: QuorumType::LLMQ_DEVNET_PLATFORM, + llmq_type_mnhf: QuorumType::LLMQ_DEVNET, + };
36-37
: Fix typo in documentation comment.There's a typo in the documentation for the local development network.
- /// Local development network, run in containers on a local machine for development purposess + /// Local development network, run in containers on a local machine for development purposes
38-42
: Improve documentation for the NetworkSettings trait methods.The
NetworkSettings
trait lacks documentation for its methods. Adding detailed documentation would help clarify their purpose and expected behavior, which is especially important for public traits.pub trait NetworkSettings { + /// Returns the core network type fn core_network(&self) -> Network; + /// Returns the quorum type used for chain locks based on the network type fn chain_locks_quorum_type(&self) -> QuorumType; }
49-52
: Add comment explaining the type conversion logic.The conversion from
u8
tou32
needs explanation. This type casting sequence might not be immediately obvious to future developers.fn chain_locks_quorum_type(&self) -> QuorumType { let llmq_type: u8 = self.chain_locks_type().into(); + // Convert u8 to u32 as required by QuorumType::from QuorumType::from(llmq_type as u32) }
27-53
: Implement getter methods for other quorum types mentioned in the comments.The implementation currently only provides a method for chain locks quorum type, but the commented section mentions other quorum types (DIP0024InstantSend, Platform, Mnhf). Consider implementing getter methods for these as well to provide a complete API.
pub trait NetworkSettings { fn core_network(&self) -> Network; fn chain_locks_quorum_type(&self) -> QuorumType; + + /// Returns the quorum type used for InstantSend based on the network type + fn instant_send_quorum_type(&self) -> QuorumType; + + /// Returns the quorum type used for Platform based on the network type + fn platform_quorum_type(&self) -> QuorumType; + + /// Returns the quorum type used for MNHF based on the network type + fn mnhf_quorum_type(&self) -> QuorumType; } impl NetworkSettings for Network { fn core_network(&self) -> Network { *self } fn chain_locks_quorum_type(&self) -> QuorumType { let llmq_type: u8 = self.chain_locks_type().into(); QuorumType::from(llmq_type as u32) } + + fn instant_send_quorum_type(&self) -> QuorumType { + // Implementation based on network type + match self { + Network::Dash => QuorumType::LLMQ_60_75, + Network::Testnet => QuorumType::LLMQ_60_75, + Network::Regtest => QuorumType::LLMQ_DEVNET_DIP0024, + // Add other network types as needed + _ => QuorumType::LLMQ_DEVNET_DIP0024, + } + } + + fn platform_quorum_type(&self) -> QuorumType { + // Implementation based on network type + match self { + Network::Dash => QuorumType::LLMQ_100_67, + Network::Testnet => QuorumType::LLMQ_25_67, + Network::Regtest => QuorumType::LLMQ_DEVNET_PLATFORM, + // Add other network types as needed + _ => QuorumType::LLMQ_DEVNET_PLATFORM, + } + } + + fn mnhf_quorum_type(&self) -> QuorumType { + // Implementation based on network type + match self { + Network::Dash => QuorumType::LLMQ_400_85, + Network::Testnet => QuorumType::LLMQ_50_60, + Network::Regtest => QuorumType::LLMQ_DEVNET, + // Add other network types as needed + _ => QuorumType::LLMQ_DEVNET, + } + } }
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (5)
packages/rs-dpp/Cargo.toml
(1 hunks)packages/rs-sdk/src/networks.rs
(1 hunks)packages/rs-sdk/src/platform/fetch_unproved.rs
(1 hunks)packages/rs-sdk/src/platform/transition/asset_lock.rs
(1 hunks)packages/rs-sdk/src/sdk.rs
(12 hunks)
✅ Files skipped from review due to trivial changes (1)
- packages/rs-dpp/Cargo.toml
🚧 Files skipped from review as they are similar to previous changes (1)
- packages/rs-sdk/src/sdk.rs
⏰ Context from checks skipped due to timeout of 90000ms (20)
- GitHub Check: Rust packages (drive-abci) / Check each feature
- GitHub Check: Rust packages (drive) / Unused dependencies
- GitHub Check: Rust packages (drive) / Tests
- GitHub Check: Rust packages (drive) / Linting
- GitHub Check: Rust packages (drive) / Formatting
- GitHub Check: Rust packages (dpp) / Unused dependencies
- GitHub Check: Rust packages (dpp) / Tests
- GitHub Check: Rust packages (dpp) / Linting
- GitHub Check: Rust packages (dpp) / Check each feature
- GitHub Check: Rust packages (dash-sdk) / Tests
- GitHub Check: Rust packages (dash-sdk) / Linting
- GitHub Check: Rust packages (dash-sdk) / Check each feature
- GitHub Check: Rust packages (dapi-grpc) / Unused dependencies
- GitHub Check: Rust packages (dapi-grpc) / Tests
- GitHub Check: Rust packages (dapi-grpc) / Check each feature
- GitHub Check: Rust packages (dapi-grpc) / Linting
- GitHub Check: Build Docker images (Dashmate helper, dashmate-helper, dashmate-helper) / Build Dashmate helper image
- GitHub Check: Build Docker images (DAPI, dapi, dapi) / Build DAPI image
- GitHub Check: Build Docker images (Drive, drive, drive-abci) / Build Drive image
- GitHub Check: Build JS packages / Build JS
🔇 Additional comments (5)
packages/rs-sdk/src/platform/fetch_unproved.rs (1)
92-92
: Encapsulation improvement.The code now uses
sdk.core_network()
instead of directly accessingsdk.network
. This change enhances encapsulation by using the dedicated accessor method instead of accessing the field directly, following good API design principles.packages/rs-sdk/src/platform/transition/asset_lock.rs (3)
17-32
: Well-defined trait with clear error documentation.The
AssetLockProofVerifier
trait is well-designed with a clear contract and comprehensive documentation of possible error cases. The documentation clearly explains when each error type might be returned, which is excellent for API consumers.
192-246
: Comprehensive test coverage with good test vectors.The test module includes well-structured test cases for the signature verification functionality, covering both valid and invalid scenarios. The source of the test vectors is also documented, which is excellent for future reference and validation.
123-123
:❓ Verification inconclusive
Consider making the asset lock signature verification more reusable.
As the TODO comment indicates, this functionality could be useful in multiple places. Consider evaluating whether this function should be moved to a shared crate that can be used by both the SDK and drive-abci.
🏁 Script executed:
#!/bin/bash # Check if there are similar functions in drive-abci that could be consolidated # Look for similar signature verification functions rg -A 5 "verify.*instant.*lock.*signature" --type rustLength of output: 7443
Consolidate Asset Lock Signature Verification
We’ve confirmed that a similar instant lock signature verification function exists in drive-abci (e.g.,
verify_recent_instant_lock_signature_locally_v0
). To minimize duplication and improve maintainability, please consider moving the common verification logic to a shared module or crate that can serve both the SDK and drive-abci.packages/rs-sdk/src/networks.rs (1)
1-5
: Well-documented file introduction.The documentation header provides clear context and includes a useful reference to the original Dash chainparams implementation.
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 (2)
packages/rs-sdk/src/networks.rs (1)
52-61
: Consider adding a unit test for chain_locks_quorum_type conversion.The implementation looks correct, but to ensure the conversion between the chain locks type and QuorumType works as expected across all network types, it would be beneficial to add unit tests.
#[cfg(test)] mod tests { use super::*; #[test] fn test_chain_locks_quorum_type_conversion() { // Test for each network type assert_eq!(NETWORK_MAINNET.chain_locks_quorum_type(), QuorumType::from(NETWORK_MAINNET.chain_locks_type().into() as u32)); assert_eq!(NETWORK_TESTNET.chain_locks_quorum_type(), QuorumType::from(NETWORK_TESTNET.chain_locks_type().into() as u32)); assert_eq!(NETWORK_DEVNET.chain_locks_quorum_type(), QuorumType::from(NETWORK_DEVNET.chain_locks_type().into() as u32)); assert_eq!(NETWORK_LOCAL.chain_locks_quorum_type(), QuorumType::from(NETWORK_LOCAL.chain_locks_type().into() as u32)); } }packages/rs-sdk/src/sdk.rs (1)
817-821
: Documentation references non-existent method.The documentation refers to
SdkBuilder::with_network_settings()
but this method doesn't appear to exist in the provided code. The actual method iswith_network()
. Please update the documentation to reference the correct method.-/// Once created, you need to set [NetworkType] with [`SdkBuilder::with_network_settings()`]. +/// Once created, you need to set [Network] with [`SdkBuilder::with_network()`].
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (2)
packages/rs-sdk/src/networks.rs
(1 hunks)packages/rs-sdk/src/sdk.rs
(12 hunks)
⏰ Context from checks skipped due to timeout of 90000ms (18)
- GitHub Check: Rust packages (drive) / Linting
- GitHub Check: Rust packages (drive) / Formatting
- GitHub Check: Rust packages (dpp) / Tests
- GitHub Check: Rust packages (dpp) / Check each feature
- GitHub Check: Rust packages (dpp) / Unused dependencies
- GitHub Check: Rust packages (dpp) / Linting
- GitHub Check: Rust packages (dash-sdk) / Unused dependencies
- GitHub Check: Rust packages (dash-sdk) / Tests
- GitHub Check: Rust packages (dash-sdk) / Check each feature
- GitHub Check: Rust packages (dash-sdk) / Linting
- GitHub Check: Rust packages (dapi-grpc) / Tests
- GitHub Check: Rust packages (dapi-grpc) / Check each feature
- GitHub Check: Rust packages (dapi-grpc) / Unused dependencies
- GitHub Check: Rust packages (dapi-grpc) / Linting
- GitHub Check: Build Docker images (Drive, drive, drive-abci) / Build Drive image
- GitHub Check: Build Docker images (Dashmate helper, dashmate-helper, dashmate-helper) / Build Dashmate helper image
- GitHub Check: Build Docker images (DAPI, dapi, dapi) / Build DAPI image
- GitHub Check: Build JS packages / Build JS
🔇 Additional comments (12)
packages/rs-sdk/src/networks.rs (3)
6-25
: Well-structured documentation for network quorum parameters.The commented block provides valuable context about the quorum parameters for different networks, making it clear what types of quorums are used for different functions across network types. This documentation is useful for understanding the platform's consensus mechanism configuration.
36-37
: Proper implementation of Devnet constant.Good addition of the
NETWORK_DEVNET
constant which was previously missing. This ensures consistency with the network types used elsewhere in the codebase.
42-47
: Well-designed NetworkConfiguration trait.The trait appropriately separates the network-specific configuration concerns, with well-documented methods that provide clear functionality. The separation between network type and quorum configuration is a good design choice.
packages/rs-sdk/src/sdk.rs (9)
8-8
: Good import of network module components.The import statement properly brings in the necessary components from the new networks module, ensuring a clean integration with the existing codebase.
99-101
: Excellent encapsulation of network field.The modification of the network field from public to private with improved documentation is a good design improvement. It ensures that network settings are accessed through appropriate methods rather than directly, which will make future refactoring easier.
279-283
: Well-implemented core_network method.The new method provides a clean interface for obtaining the core network type, correctly delegating to the network_settings implementation for the actual conversion.
308-308
: Proper usage of core_network() method.Correctly updated to use the new core_network() method instead of directly accessing the network field, maintaining the encapsulation pattern.
535-538
: Excellent implementation of network_settings method.This method provides access to the network configuration while maintaining proper encapsulation. The return type using
impl NetworkConfiguration
is a good use of Rust's type system to hide the concrete implementation details.
734-737
: Updated documentation for network field in SdkBuilder.The documentation correctly references the new network constants from the networks module, providing better clarity on the default value and usage.
789-789
: Consistent use of network constant.Properly updated to use the NETWORK_MAINNET constant instead of Network::Dash, ensuring consistency with the new network module approach.
862-872
: Improved documentation for with_network method.The documentation is now more informative, correctly referencing the network constants and providing examples of available network types. This makes the API more discoverable and user-friendly.
1060-1061
:❓ Verification inconclusive
Verify all occurrences of network field updates.
The network field is now properly assigned during SDK initialization. While the changes look good, ensure all places where the network field is used have been properly updated to use the core_network() or network_settings() methods.
🏁 Script executed:
#!/bin/bash # Description: Find all places where 'network' field is directly accessed. # 1. Find direct access to 'network' field in SDK struct echo "Looking for direct access to SDK network field..." rg "\.network\b" --type rust -g "!*/target/*" -A 2 -B 2 # 2. Check if all old usages of Network::Dash have been replaced with NETWORK_MAINNET echo "Looking for Network::Dash usages that might need to be replaced..." rg "Network::Dash" --type rust -g "!*/target/*" -A 2 -B 2Length of output: 32177
Network Field Usage Consistency – Please Verify Across the Codebase
The SDK initialization now correctly assigns the network field (as seen in lines 1060–1061 of
packages/rs-sdk/src/sdk.rs
). However, the search output reveals several direct references to the network field (and direct comparisons againstNetwork::Dash
) in multiple modules. In particular:
- In
packages/rs-sdk/src/sdk.rs
, instances likestill use the field directly instead of via the accessor. Please review whether these should be updated to callnetwork: self.network, proofs: self.proofs,network_settings()
(orcore_network()
) for consistency.- Other modules (e.g., within
rs-drive-abci
,rs-dpp
, and elsewhere) continue to compare or assign the network field directly (for example,if config.network == Network::Dash
). Verify that these usages are either intentionally left unchanged or are updated to use the standardized accessor methods (and possibly theNETWORK_MAINNET
constant defined inpackages/rs-sdk/src/networks.rs
).If the direct field access is intentional (e.g., for performance or clarity reasons), please add clear documentation or inline comments explaining the rationale. Otherwise, refactor these accesses to follow the updated pattern for consistency.
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 (3)
packages/rs-sdk/src/error.rs (1)
75-75
: Fix typo in error messageThere's a minor typo in the error message: "avaiable" should be "available".
-#[error("Asset lock for core locked height {core_locked_height_in_asset_lock} not available yet, max avaiable locked core height is {core_locked_height_on_platform}; try again later")] +#[error("Asset lock for core locked height {core_locked_height_in_asset_lock} not available yet, max available locked core height is {core_locked_height_on_platform}; try again later")]packages/rs-sdk/src/platform/transition/asset_lock.rs (2)
61-61
: Fix typo in commentSmall typo in the comment: "Detch" should be "Fetch".
-// 2. Detch quorum public key for this hash. +// 2. Fetch quorum public key for this hash.
75-92
: Consider implementing caching for platform locked height.The function correctly fetches the current core chain locked height, but as noted in the TODO comment, implementing a caching mechanism would improve performance for scenarios where multiple asset locks are being verified in succession.
In the future implementation, consider using a time-based cache with a short TTL (e.g., 10-30 seconds) to balance freshness with performance.
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (3)
packages/rs-sdk/src/error.rs
(3 hunks)packages/rs-sdk/src/platform/transition/asset_lock.rs
(1 hunks)packages/rs-sdk/src/sdk.rs
(10 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
- packages/rs-sdk/src/sdk.rs
⏰ Context from checks skipped due to timeout of 90000ms (20)
- GitHub Check: Rust packages (drive) / Tests
- GitHub Check: Rust packages (drive) / Detect immutable structure changes
- GitHub Check: Rust packages (drive) / Linting
- GitHub Check: Rust packages (drive) / Formatting
- GitHub Check: Rust packages (dpp) / Unused dependencies
- GitHub Check: Rust packages (dpp) / Tests
- GitHub Check: Rust packages (dpp) / Check each feature
- GitHub Check: Rust packages (dpp) / Linting
- GitHub Check: Rust packages (dash-sdk) / Unused dependencies
- GitHub Check: Rust packages (dash-sdk) / Tests
- GitHub Check: Rust packages (dash-sdk) / Linting
- GitHub Check: Rust packages (dapi-grpc) / Unused dependencies
- GitHub Check: Rust packages (dash-sdk) / Check each feature
- GitHub Check: Rust packages (dapi-grpc) / Tests
- GitHub Check: Rust packages (dapi-grpc) / Linting
- GitHub Check: Rust packages (dapi-grpc) / Check each feature
- GitHub Check: Build Docker images (Drive, drive, drive-abci) / Build Drive image
- GitHub Check: Build Docker images (Dashmate helper, dashmate-helper, dashmate-helper) / Build Dashmate helper image
- GitHub Check: Build Docker images (DAPI, dapi, dapi) / Build DAPI image
- GitHub Check: Build JS packages / Build JS
🔇 Additional comments (7)
packages/rs-sdk/src/error.rs (4)
58-67
: Well-structured error variant for quorum not found scenarios.The new error variant provides comprehensive information about the missing quorum, including its hash, type, and relevant core chain height. This information will be valuable for debugging when quorums can't be located.
76-79
: Clear parameter structure for CoreLockedHeightNotYetAvailable error.The error variant contains the essential information needed to understand the timing issue with the asset lock, providing both the requested height and the current platform height.
81-87
: Good addition of InvalidAssetLock error variant.This generic error variant will be useful for various asset lock validation failures that don't fit the other more specific categories.
211-219
: Correctly updated retry logic for new error types.The
can_retry
implementation has been appropriately extended to include the new error variants that represent temporary conditions (CoreLockedHeightNotYetAvailable
andQuorumNotFound
), which is essential for proper error handling.packages/rs-sdk/src/platform/transition/asset_lock.rs (3)
10-39
: Well-documented trait with clear purpose and limitations.The
AssetLockProofVerifier
trait is thoroughly documented, clearly explaining its purpose, limitations, and potential error conditions. This makes it easy for developers to understand how to use it correctly.
43-55
: Correct implementation for Chain asset lock verification.The verification logic for Chain asset locks properly checks if the core locked height in the asset lock is greater than the current platform height, returning an appropriate error when necessary.
56-70
: Incomplete instant asset lock verification implementation.The implementation acknowledges that full verification for instant asset locks is not yet possible due to limitations in the SDK regarding quorum processing. While the current implementation validates the structure, it doesn't verify the signature, which could allow invalid asset locks to be accepted.
Given that this is a known limitation mentioned in past review comments, please consider one of these approaches:
- Add a warning log when accepting instant asset locks without full verification
- Document this limitation more prominently in user-facing documentation
- Create a tracking issue to implement full verification when quorum processing is added to the SDK
This implementation matches the PR description which focuses on verifying whether the platform can process an asset lock, but users should be aware of this verification gap.
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 (5)
packages/rs-drive-proof-verifier/src/verify.rs (1)
133-133
: Improved parameter passing by removing unnecessary reference level.The change removes an unnecessary level of reference by directly passing
signature
instead of&signature
to thefrom_compressed
method. Sincesignature
is already a reference (&[u8; 96]
), this simplifies the code without changing functionality.Consider adding a brief comment explaining the signature verification approach or expected format, as BLS signature verification is complex and can be error-prone.
packages/rs-sdk/src/error.rs (1)
81-87
: Consider using a structured error format for invalid asset locks.
Right now, it takes just a single string describing the error. It might be beneficial to store structured information for better troubleshooting and automated handling in the future.packages/rs-sdk/tests/fetch/asset_lock.rs (2)
17-34
: Avoid panicking on missing metadata or proof.
Using.expect(...)
ensures a quick failure, but returning a custom error could offer a more user-friendly diagnostic path and reduce the risk of abrupt test termination.
36-105
: Minor text fix in test assertion description.
Typographical issue: “expeced” should be “expected.” Apply the following diff to correct the message:- "tc {} expeced err = {}, got err = {}: {:?}", + "tc {} expected err = {}, got err = {}: {:?}",packages/rs-sdk/src/platform/transition/asset_lock.rs (1)
57-70
: Offer assistance for full signature verification.
Instant asset locks currently bypass signature verification, which can leave them vulnerable. Let me know if you’d like help implementing the signature validation flow or opening a new issue to track this.
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (15)
packages/rs-dpp/Cargo.toml
(2 hunks)packages/rs-drive-proof-verifier/src/provider.rs
(1 hunks)packages/rs-drive-proof-verifier/src/types/evonode_status.rs
(1 hunks)packages/rs-drive-proof-verifier/src/verify.rs
(1 hunks)packages/rs-sdk/src/error.rs
(3 hunks)packages/rs-sdk/src/platform/query.rs
(1 hunks)packages/rs-sdk/src/platform/transition.rs
(1 hunks)packages/rs-sdk/src/platform/transition/asset_lock.rs
(1 hunks)packages/rs-sdk/src/platform/transition/builder.rs
(1 hunks)packages/rs-sdk/src/platform/transition/put_identity.rs
(1 hunks)packages/rs-sdk/src/platform/transition/update_price_of_document.rs
(0 hunks)packages/rs-sdk/src/platform/types/proposed_blocks.rs
(0 hunks)packages/rs-sdk/src/sdk.rs
(10 hunks)packages/rs-sdk/tests/fetch/asset_lock.rs
(1 hunks)packages/rs-sdk/tests/fetch/config.rs
(1 hunks)
💤 Files with no reviewable changes (2)
- packages/rs-sdk/src/platform/types/proposed_blocks.rs
- packages/rs-sdk/src/platform/transition/update_price_of_document.rs
✅ Files skipped from review due to trivial changes (2)
- packages/rs-sdk/src/platform/transition/put_identity.rs
- packages/rs-sdk/src/platform/query.rs
🚧 Files skipped from review as they are similar to previous changes (1)
- packages/rs-dpp/Cargo.toml
⏰ Context from checks skipped due to timeout of 90000ms (4)
- GitHub Check: Rust packages (drive-abci) / Tests
- GitHub Check: Rust packages (drive-abci) / Linting
- GitHub Check: Rust packages (drive) / Tests
- GitHub Check: Build JS packages / Build JS
🔇 Additional comments (17)
packages/rs-sdk/src/platform/transition/builder.rs (1)
12-12
: Good addition of the#[allow(async_fn_in_trait)]
attribute.This attribute explicitly acknowledges the use of async functions within the trait, which is important as async functions in traits are stabilizing in Rust but may still generate warnings in some compiler versions. The attribute ensures the code compiles without warnings while maintaining the trait's intended asynchronous behavior.
packages/rs-drive-proof-verifier/src/types/evonode_status.rs (1)
244-244
: Good optimization: removed unnecessary clone operation.The change removes the
.clone()
call on theprotocol
field, which is an optimization that reduces unnecessary memory allocations and copying. Since the cloned value was only used once, this change maintains the same functionality with improved efficiency.packages/rs-drive-proof-verifier/src/provider.rs (1)
89-89
:✅ Verification successful
Simplified trait implementation by removing unnecessary lifetime parameter.
The lifetime parameter
'a
has been removed from the implementation ofContextProvider
forstd::sync::Mutex<T>
. This is a good simplification that makes the code more flexible and easier to understand, as it now allowsT
to be any type that implementsContextProvider
without a specific lifetime constraint.
🏁 Script executed:
#!/bin/bash # Check if there are any usages of the ContextProvider trait that might be affected by this change echo "Checking ContextProvider implementations and usages..." rg "impl.*ContextProvider" --type rust echo "Checking Mutex usage with ContextProvider..." rg "Mutex.*ContextProvider" --type rustLength of output: 3028
Approved: Simplified trait implementation verified
The change removing the unnecessary lifetime parameter from the
ContextProvider
implementation forstd::sync::Mutex<T>
inpackages/rs-drive-proof-verifier/src/provider.rs
has been verified. The repository search forContextProvider
usages confirms that this simplification doesn’t adversely affect other parts of the codebase.
- The implementation:
now correctly supports flexible usage without an unneeded lifetime constraint.impl<T: ContextProvider> ContextProvider for std::sync::Mutex<T>- Other implementations and usages of
ContextProvider
remain consistent and unaffected.packages/rs-sdk/tests/fetch/config.rs (1)
58-60
: Conditionally compiled field looks appropriate
The new conditional attribute forplatform_ca_cert_path
aligns well with the intended feature-bound functionality. No issues spotted.packages/rs-sdk/src/platform/transition.rs (1)
2-2
: New public modules introduced seamlessly
The addition ofpub mod asset_lock;
,pub mod builder;
, andpub mod fungible_tokens;
appears consistent with the PR’s objective of expanding transition functionality. Ensure each module has its own test coverage for thorough validation.Also applies to: 6-7
packages/rs-sdk/src/sdk.rs (7)
98-100
: Privatenetwork
field documentation
The updated documentation for the privatenetwork
field is clear and maintains good encapsulation.
278-282
: Getter method for Dash Core network
Introducingcore_network()
is logical to expose the internalnetwork
without jeopardizing encapsulation.
713-716
: Step-by-step builder documentation
The revised doc comments clarify SDK assembly steps. This improves overall readability for new users.
728-732
: Expanded doc comments explainingnetwork
usage
These lines succinctly clarify that the SDK defaults toNetwork::Dash
. The approach is sound.
856-862
: Additional notes on configuring network type
The updated documentation forwith_network
helps guide users toward correct environment setup.
1055-1055
: Assigning the builder’s network
Assigningself.network
to the SDK ensures a consistent configuration in non-mock mode.
1123-1123
: Network assignment in mock mode
Similarly, setting thenetwork
field here ensures that mock builds remain consistent with the real environment.packages/rs-sdk/src/error.rs (4)
58-67
: Looks good for handling missing quorums.
These new fields provide sufficient context for troubleshooting quorum availability issues.
69-79
: Clear and actionable error regarding future availability.
This error variant effectively conveys that the asset lock can't yet be processed and invites a retry.
134-134
: Graceful handling of parsed consensus errors.
Great approach to parse the returned error data and gracefully fallback to a generic error if parsing fails.
212-218
: Correctly marking transient errors as retryable.
IncludingQuorumNotFound
andCoreLockedHeightNotYetAvailable
in the retry logic is appropriate, given they are expected to resolve on subsequent attempts.packages/rs-sdk/src/platform/transition/asset_lock.rs (1)
47-47
: Logic matches previous discussion.
Retaining the>
comparison is correct per your justification that the platform cannot verify locks exceeding the known locked height.
Issue being fixed or feature implemented
We want to be able to check if the platform can process an asset lock.
What was done?
Added AssetLockProofVerifier trait with verify() method, implemented on AssetLockProof.
How Has This Been Tested?
Added test.
Note: Requires #2061 to pass the tests.
Breaking Changes
None
Checklist:
For repository code-owners and collaborators only
Summary by CodeRabbit
New Features
Bug Fixes
Tests
Documentation