Skip to content
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(sdk): asset lock quorum and core locked height verification #2030

Open
wants to merge 18 commits into
base: v1.7-dev
Choose a base branch
from

Conversation

lklimek
Copy link
Contributor

@lklimek lklimek commented Jul 31, 2024

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:

  • I have performed a self-review of my own code
  • I have commented my code, particularly in hard-to-understand areas
  • I have added or updated relevant unit/integration/functional/e2e tests
  • I have added "!" to the title and described breaking changes in the corresponding section if my code contains any
  • I have made corresponding changes to the documentation if needed

For repository code-owners and collaborators only

  • I have assigned this pull request to a milestone

Summary by CodeRabbit

  • New Features

    • Introduced a new public module for network configurations, including support for Mainnet, Testnet, Devnet, and custom setups.
    • Added functionality for verifying asset lock proofs with a dedicated trait and its implementation.
    • Implemented new methods for managing identity on the platform, enhancing identity management capabilities.
  • Bug Fixes

    • Improved error handling for asset lock verification scenarios.
  • Documentation

    • Updated comments and documentation for clarity on new features and changes.
  • Tests

    • Added tests for asset lock proofs to ensure verification logic works correctly across various scenarios.
    • Introduced a new configuration setup for testing with the Devnet network type.

@lklimek lklimek changed the title feat(sdk): asset lock quorum verify against platform fix(sdk): core chain lock is not verified before sending Jul 31, 2024
@lklimek lklimek changed the base branch from v1.0-dev to v1.1-dev July 31, 2024 10:17
@lklimek lklimek force-pushed the fix/sdk-invalid-quorum branch from 9c21078 to b3f5f17 Compare July 31, 2024 10:18
@lklimek lklimek marked this pull request as ready for review August 15, 2024 11:18
@lklimek lklimek added this to the v1.1.0 milestone Aug 16, 2024
@lklimek lklimek changed the title fix(sdk): core chain lock is not verified before sending feat(sdk): core chain lock verification against the platform Aug 16, 2024
@lklimek lklimek changed the title feat(sdk): core chain lock verification against the platform feat(sdk): asset lock quorum and core locked height verification Aug 16, 2024
@lklimek lklimek force-pushed the fix/sdk-invalid-quorum branch from a328081 to f57e455 Compare August 16, 2024 11:31

pub fn new_devnet() -> Self {
QuorumParams {
// FIXME: local devnet uses regtest
Copy link
Contributor Author

Choose a reason for hiding this comment

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

This needs discussion how to handle that.

Ok(())
}
}
AssetLockProof::Instant(v) => {
Copy link
Member

Choose a reason for hiding this comment

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

It's not gonna check if we can verify signature in Drive, right?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

If you have any hint how to do that client-side, I would be happy to include this here.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

@QuantumExplorer can you give me some formula to add it here?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

From what we discussed, we have no better solution than what's already implemented.

@lklimek lklimek modified the milestones: v1.1.0, v1.2.0 Aug 23, 2024
@shumkov shumkov changed the base branch from v1.1-dev to master August 25, 2024 07:39
@shumkov shumkov requested a review from antouhou as a code owner August 25, 2024 07:39
@thephez thephez removed this from the v1.2.0 milestone Sep 11, 2024
@lklimek lklimek changed the base branch from master to v1.7-dev December 10, 2024 09:08
Copy link
Contributor

coderabbitai bot commented Dec 10, 2024

Walkthrough

This pull request introduces several modifications across multiple files, primarily focusing on enhancing the request and response handling within the SDK. Key changes include the expansion of versioned requests and responses in build.rs, the introduction of new traits and methods in the SDK for handling asset locks and identities, and the addition of a new module for network configurations. New error variants are also introduced to improve error handling. Overall, these changes aim to refine the SDK's structure and functionality.

Changes

File Change Summary
packages/dapi-grpc/build.rs Expanded VERSIONED_REQUESTS from 30 to 31 entries and VERSIONED_RESPONSES from 29 to 31 entries, added new entries, removed outdated ones, and updated comments for clarity.
packages/rs-dapi-client/src/executor.rs Implemented VersionedGrpcResponse trait for ExecutionResponse, adding methods for metadata and proof handling.
packages/rs-dpp/src/core_types/validator_set/v0/mod.rs Simplified assignment of pro_tx_hash in ValidatorV0 struct for memory optimization.
packages/rs-sdk/src/error.rs Added new error variants QuorumNotFound and CoreLockedHeightNotYetAvailable to the Error enum and updated can_retry method.
packages/rs-sdk/src/lib.rs Introduced a new public module networks.
packages/rs-sdk/src/networks.rs Defined NetworkType enum and QuorumParams struct for managing Dash network configurations.
packages/rs-sdk/src/platform/transition.rs Added a new public module asset_lock.
packages/rs-sdk/src/platform/transition/asset_lock.rs Introduced AssetLockProofVerifier trait and its implementation for verifying asset lock proofs.
packages/rs-sdk/src/platform/transition/put_identity.rs Added PutIdentity trait for handling identity operations with two asynchronous methods.
packages/rs-sdk/src/platform/types/epoch.rs Updated documentation for Epoch type alias without structural changes.
packages/rs-sdk/src/sdk.rs Added network_type field to Sdk and SdkBuilder, along with methods for setting and retrieving quorum parameters.
packages/rs-sdk/tests/fetch/asset_lock.rs Introduced tests for asset lock proofs, including a function for retrieving the current platform state.
packages/rs-sdk/tests/fetch/config.rs Updated setup_api method to include network type configuration for Devnet.
packages/rs-sdk/tests/fetch/mod.rs Added new module declaration for asset_lock.
packages/rs-sdk/tests/vectors/test_asset_lock_proof/quorum_pubkey-100-4ce7fd81273c2b394c0f32367374fc5b09ba912e017aacb366d2171e9ca6f9d5.json Added a new JSON file containing a cryptographic hash.

Possibly related PRs

Suggested labels

cleanup

Suggested reviewers

  • QuantumExplorer
  • shumkov

🐇 In the land of code, where changes abound,
New requests and responses are joyfully found.
With traits and modules, the SDK grows bright,
Asset locks verified, all errors in sight.
So hop along, friends, let’s celebrate this cheer,
For the code is now better, let’s give a big cheer! 🎉


Thank you for using CodeRabbit. We offer it for free to the OSS community and would appreciate your support in helping us grow. If you find it useful, would you consider giving us a shout-out on your favorite social media?

❤️ 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.
    • Generate unit testing code for this file.
    • 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 generate unit testing code for this file.
    • @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 generate unit testing code.
    • @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.

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. (Experiment)
  • @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.

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

🧹 Outside diff range and nitpick comments (11)
packages/rs-sdk/src/platform/transition/put_identity.rs (2)

Line range hint 21-21: Consider consuming self in put_to_platform to prevent misuse.

The TODO comment suggests that put_to_platform might need to consume self since the identity is no longer valid after the operation (e.g., identity ID is changed). Consuming self can prevent accidental use of an invalid identity object.

Would you like assistance in refactoring the method to consume self or opening a GitHub issue to track this task?


Line range hint 41-58: Add verification of asset_lock_proof before broadcasting.

Before broadcasting the state transition, it's important to verify the asset_lock_proof to ensure its validity. This can be done by calling asset_lock_proof.verify(sdk).await? prior to proceeding.

Apply this diff to add the verification step:

 async fn put_to_platform(
     &self,
     sdk: &Sdk,
     asset_lock_proof: AssetLockProof,
     asset_lock_proof_private_key: &PrivateKey,
     signer: &S,
     settings: Option<PutSettings>,
 ) -> Result<StateTransition, Error> {
+    // Verify the asset lock proof
+    asset_lock_proof.verify(sdk).await?;

     let (state_transition, _) = self.broadcast_request_for_new_identity(
         asset_lock_proof,
         asset_lock_proof_private_key,
         signer,
         sdk.version(),
     )?;

     // response is empty for a broadcast, result comes from the stream wait for state transition result
     state_transition.broadcast(sdk, settings).await?;
     Ok(state_transition)
 }
packages/rs-sdk/tests/fetch/mod.rs (1)

Line range hint 1-1: Consider addressing the TODO comment in a separate PR

The comment about renaming the test package should be tracked and addressed separately from the current asset lock implementation.

Would you like me to create a GitHub issue to track this TODO?

packages/rs-sdk/src/networks.rs (3)

32-32: Fix typo in documentation

There's a typo in the Mock variant documentation: "feaults" should be "defaults".

-    /// Mock implementation; in practice, feaults to Devnet config for Mock mode. Errors when used in non-mock mode.
+    /// Mock implementation; in practice, defaults to Devnet config for Mock mode. Errors when used in non-mock mode.

88-90: Consider documenting Mock implementation details

The Mock configuration currently defaults to devnet settings. This implementation detail should be documented to explain why this is appropriate and any limitations.

     pub fn new_mock() -> Self {
+        // Mock configuration uses devnet settings as they are suitable for testing
         Self::new_devnet()
     }

64-66: Consider future extensibility of QuorumParams

The QuorumParams struct currently only contains instant_lock_quorum_type. Consider documenting if more parameters will be added in the future, as suggested by the comprehensive network configurations in the comments above.

packages/rs-sdk/tests/fetch/asset_lock.rs (4)

17-34: Consider improving error handling in test helper function.

The use of expect() in helper functions can make test failures harder to debug. Consider either:

  1. Propagating the errors with proper context using ? operator
  2. Using more descriptive expect messages that include the actual values
 async fn current_platform_state(sdk: &dash_sdk::Sdk) -> (u32, Vec<u8>) {
     let req: GetEpochsInfoRequest = GetEpochsInfoRequestV0 {
         ascending: false,
         count: 1,
         prove: true,
         start_epoch: None,
     }
     .into();

     let resp: GetEpochsInfoResponse = req
         .execute(sdk, Default::default())
         .await
-        .expect("get epoch info")
+        .expect("failed to execute GetEpochsInfoRequest")
         .into_inner();
-    let core_height = resp.metadata().expect("metadata").core_chain_locked_height;
-    let quorum_hash = resp.proof().expect("proof").quorum_hash.clone();
+    let core_height = resp.metadata()
+        .expect("response metadata missing")
+        .core_chain_locked_height;
+    let quorum_hash = resp.proof()
+        .expect("response proof missing")
+        .quorum_hash
+        .clone();
     (core_height, quorum_hash)
 }

56-59: Document the purpose of hardcoded transaction data.

The hardcoded transaction hex string lacks documentation explaining its purpose and structure. This makes it harder to maintain or modify the test in the future.

Add a comment explaining:

  1. What this transaction represents
  2. Why this specific transaction was chosen
  3. The key properties that make it suitable for testing

61-98: Improve test case documentation and constants.

The test cases could be more maintainable and self-documenting:

  1. Add descriptions for each test case
  2. Extract magic numbers into named constants
+    const FUTURE_HEIGHT_OFFSET: u32 = 100;
+
     struct TestCase {
         asset_lock_proof: AssetLockProof,
-        // expect err that can be retried
+        /// Whether this test case should result in a retryable error
         expect_err: bool,
+        /// Description of what this test case verifies
+        description: String,
     }
     
     let test_cases = vec![
         TestCase {
             asset_lock_proof: AssetLockProof::Chain(ChainAssetLockProof::new(
                 core_chain_locked_height,
                 out_point,
             )),
             expect_err: false,
+            description: "Valid chain asset lock at current height".to_string(),
         },
         // ... similar changes for other test cases
         TestCase {
             asset_lock_proof: AssetLockProof::Chain(ChainAssetLockProof::new(
-                core_chain_locked_height + 100,
+                core_chain_locked_height + FUTURE_HEIGHT_OFFSET,
                 out_point,
             )),
             expect_err: true,
+            description: "Invalid chain asset lock with future height".to_string(),
         },

100-111: Enhance test failure messages.

The current assertion message could be more helpful in identifying which test case failed and why.

     for (i, tc) in test_cases.into_iter().enumerate() {
         let result = tc.asset_lock_proof.verify(&sdk).await;
         assert_eq!(
             result.is_err(),
             tc.expect_err,
-            "tc {} expeced err = {}, got err = {}: {:?}",
+            "Test case {} failed: {}\nExpected error: {}\nGot: {}\nError details: {:?}",
             i,
+            tc.description,
             tc.expect_err,
             result.is_err(),
             result
         );
packages/rs-sdk/tests/vectors/test_asset_lock_proof/quorum_pubkey-100-4ce7fd81273c2b394c0f32367374fc5b09ba912e017aacb366d2171e9ca6f9d5.json (1)

1-1: Add documentation for the test vector

Since this is a test vector file, it would be helpful to include metadata about what this value represents and how it's used in testing. Consider structuring the JSON to include:

  • Description of the test case
  • Expected results
  • Any relevant parameters

Example structure:

{
  "description": "Test vector for quorum public key verification",
  "quorumPublicKey": "8aa46461c5a7e1b5da330050d97b3dc928445c3908c2b0f9d3b1b84fd4a7a2ecdd2da5e7480690b0f0f5e10ae51555a7",
  "expectedResult": true,
  "testParameters": {
    "quorumIndex": 100
  }
}
🧰 Tools
🪛 Biome (1.9.4)

[error] 1-1: String values must be double quoted.

(parse)

📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL

📥 Commits

Reviewing files that changed from the base of the PR and between 6270ef0 and 727cc20.

📒 Files selected for processing (15)
  • packages/dapi-grpc/build.rs (2 hunks)
  • packages/rs-dapi-client/src/executor.rs (2 hunks)
  • packages/rs-dpp/src/core_types/validator_set/v0/mod.rs (1 hunks)
  • packages/rs-sdk/src/error.rs (2 hunks)
  • packages/rs-sdk/src/lib.rs (1 hunks)
  • packages/rs-sdk/src/networks.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/put_identity.rs (1 hunks)
  • packages/rs-sdk/src/platform/types/epoch.rs (1 hunks)
  • packages/rs-sdk/src/sdk.rs (12 hunks)
  • packages/rs-sdk/tests/fetch/asset_lock.rs (1 hunks)
  • packages/rs-sdk/tests/fetch/config.rs (2 hunks)
  • packages/rs-sdk/tests/fetch/mod.rs (1 hunks)
  • packages/rs-sdk/tests/vectors/test_asset_lock_proof/quorum_pubkey-100-4ce7fd81273c2b394c0f32367374fc5b09ba912e017aacb366d2171e9ca6f9d5.json (1 hunks)
✅ Files skipped from review due to trivial changes (1)
  • packages/rs-sdk/src/platform/types/epoch.rs
🧰 Additional context used
🪛 Biome (1.9.4)
packages/rs-sdk/tests/vectors/test_asset_lock_proof/quorum_pubkey-100-4ce7fd81273c2b394c0f32367374fc5b09ba912e017aacb366d2171e9ca6f9d5.json

[error] 1-1: String values must be double quoted.

(parse)

🔇 Additional comments (15)
packages/rs-sdk/src/platform/transition/asset_lock.rs (1)

1-82: AssetLockProof verification logic is correctly implemented.

The AssetLockProofVerifier trait and its implementation accurately verify both Chain and Instant asset lock proofs. Error handling is comprehensive and appropriately addresses different failure scenarios.

packages/rs-sdk/src/sdk.rs (1)

99-100: Integration of network_type enhances configurability.

The addition of the network_type field to Sdk and SdkBuilder, along with related methods, successfully improves the SDK's configurability. The with_network_type method and the validations in the build method ensure that the network type is properly set, preventing misconfiguration.

Also applies to: 153-153, 531-534, 729-730, 778-778, 805-809, 895-902, 991-996, 1006-1006, 1075-1075

packages/rs-sdk/src/platform/transition.rs (1)

2-2: Module asset_lock added appropriately.

The new asset_lock module is correctly declared and integrates seamlessly with existing modules in the platform::transition package.

packages/rs-sdk/tests/fetch/mod.rs (1)

8-8: LGTM! Module declaration aligns with PR objectives

The addition of the asset_lock module is consistent with the PR's goal of implementing asset lock verification functionality.

packages/rs-sdk/src/lib.rs (1)

68-68: LGTM! Clean module addition

The networks module is properly declared as public and follows the existing module organization pattern.

packages/rs-sdk/src/networks.rs (3)

1-25: Well-documented network configurations

The comprehensive documentation with references to chainparams.cpp provides excellent context for the network configurations.


31-42: LGTM! Clear network type enumeration

The NetworkType enum provides a clean abstraction for different network configurations with appropriate documentation.


83-84: Address FIXME comment about devnet configuration

The FIXME comment indicates that local devnet uses regtest, which needs to be properly documented and potentially discussed.

Let's verify if this is documented elsewhere:

Would you like me to:

  1. Create a GitHub issue to track this FIXME?
  2. Help document the devnet/regtest relationship?
✅ Verification successful

Let me gather more context about the network configuration to better understand the relationship between devnet and regtest.


Let me check if there are any configuration files or tests that might provide more context about the devnet and regtest relationship.


Let me check for any test configurations or documentation about the QuorumType::LlmqTest usage.


FIXME comment is accurate and can be resolved

Based on the evidence found in rs-drive-abci/src/config.rs, the FIXME comment is correct. The local development environment (devnet) indeed uses regtest network configuration with QuorumType::LlmqTest. This is explicitly shown in the default_local() configuration where the network is set to Network::Regtest and uses QuorumType::LlmqTest for instant locks.

  • The comment can be updated to be more descriptive:
// Local devnet uses regtest network configuration with LlmqTest quorum type
instant_lock_quorum_type: QuorumType::LlmqTest,
🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Search for documentation about devnet using regtest
rg -i "devnet.*regtest|regtest.*devnet" --type md

Length of output: 315


Script:

#!/bin/bash
# Search for network configuration related code and comments
rg -i "devnet|regtest" packages/rs-sdk/src/networks.rs -A 5 -B 5

Length of output: 2108


Script:

#!/bin/bash
# Search for devnet configuration in test files and configuration files
rg -i "llmqtest.*devnet|devnet.*llmqtest" 

Length of output: 43


Script:

#!/bin/bash
# Search for LlmqTest configuration and usage
rg "LlmqTest" -A 5 -B 5

Length of output: 8560

packages/rs-sdk/src/error.rs (2)

57-75: LGTM! Well-structured error variants.

The new error variants are well-documented and appropriately designed:

  1. QuorumNotFound includes all necessary context for debugging
  2. CoreLockedHeightNotYetAvailable clearly explains the issue with height parameters

150-156: LGTM! Appropriate retry behavior.

The updated can_retry implementation correctly includes the new error variants as retryable conditions.

packages/rs-dapi-client/src/executor.rs (1)

125-139: LGTM! Clean trait implementation.

The VersionedGrpcResponse implementation for ExecutionResponse correctly delegates to the inner response while maintaining the execution context.

packages/dapi-grpc/build.rs (2)

Line range hint 50-83: LGTM! The VERSIONED_REQUESTS array is properly updated.

The array has been expanded to include new request types while maintaining alphabetical order, which aids in maintenance and readability.


90-122: LGTM! The VERSIONED_RESPONSES array is properly updated.

The array has been expanded with new response types while maintaining alphabetical order. The comment about GetEvonodesProposedEpochBlocksResponse being used for 2 requests provides helpful context.

packages/rs-sdk/tests/fetch/config.rs (1)

6-6: LGTM! Network type configuration is properly added.

The addition of .with_network_type(dash_sdk::networks::NetworkType::Devnet) ensures that tests are executed against the correct network environment.

Also applies to: 185-192

packages/rs-dpp/src/core_types/validator_set/v0/mod.rs (1)

303-303: LGTM! Simplified pro_tx_hash assignment.

Removed unnecessary cloning of pro_tx_hash in the test function, which is a good optimization.

@lklimek lklimek requested a review from shumkov December 10, 2024 09:30
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.

3 participants