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

refactor(sdk)!: separate dash core client error #2380

Merged
merged 3 commits into from
Dec 9, 2024

Conversation

lklimek
Copy link
Contributor

@lklimek lklimek commented Dec 6, 2024

Issue being fixed or feature implemented

For #2328 , we need to retry on some errors returned by dash core.

What was done?

  • Introduced DashCoreError that implements CanRetry

Built on top of #2328.

How Has This Been Tested?

GHA

Breaking Changes

  1. LowLevelDashCoreClient now returns DashCoreError instead of ContextProviderError.
  2. Added ContextProviderError::DashCoreError variant
  3. dash_sdk::Error::CoreClientError now uses DashCoreError instead of dashcore_rpc::Error.

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

Release Notes

  • New Features

    • Introduced a new DashCoreError variant for improved error handling within the SDK.
    • Added a caching mechanism to enhance data retrieval efficiency.
  • Bug Fixes

    • Improved error handling in the get_platform_activation_height method to better propagate errors.
  • Tests

    • Enhanced EvoNode tests with timeout mechanisms and improved assertions for status checks.
  • Chores

    • Removed unused import in the configuration test file to simplify dependencies.

Copy link
Contributor

coderabbitai bot commented Dec 6, 2024

Walkthrough

The pull request introduces several modifications across multiple files, primarily enhancing error handling mechanisms. Key changes include the introduction of a new error type, DashCoreError, and its integration into various methods within the LowLevelDashCoreClient. Additionally, the verify_signature method in the NativeBlsModule has been updated to improve its error handling without altering its signature. New structures, such as a caching mechanism in GrpcContextProvider, and refinements to asynchronous functions in sync.rs are also part of the changes, which collectively aim to improve robustness and maintainability.

Changes

File Path Change Summary
packages/rs-dpp/src/bls/native_bls.rs Updated verify_signature method to enhance error handling; other methods retain signatures and functionality.
packages/rs-drive-proof-verifier/src/error.rs Added new variant DashCoreError to ContextProviderError enum for specific error handling.
packages/rs-sdk/src/core/dash_core_client.rs Introduced DashCoreError, updated method signatures to replace ContextProviderError, simplified retry logic.
packages/rs-sdk/src/core/error.rs Defined DashCoreError enum, added constants, and implemented conversion to ContextProviderError.
packages/rs-sdk/src/core/mod.rs Added new module error and exported DashCoreError.
packages/rs-sdk/src/error.rs Updated CoreClientError to use DashCoreError, added conversion implementation for dashcore_rpc::Error.
packages/rs-sdk/src/mock/provider.rs Modified get_platform_activation_height method for error handling; added Cache struct for caching mechanisms.
packages/rs-sdk/src/sync.rs Expanded AsyncError enum, updated block_on and retry functions for improved error handling and tracing.
packages/rs-sdk/tests/fetch/config.rs Removed unused import; no changes to logic or functionality of the Config struct.
packages/rs-sdk/tests/fetch/evonode.rs Enhanced tests for EvoNode status with timeout handling and improved assertions for error scenarios.

Possibly related PRs

Suggested labels

cleanup

Suggested reviewers

  • QuantumExplorer
  • shumkov

Poem

In the code where rabbits play,
Errors once led us astray.
With DashCoreError, we now see,
A clearer path, oh joy, oh glee!
Caching data, swift and bright,
Our code hops to new heights! 🐇✨


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

@lklimek lklimek changed the title refactor(sdk!): separate dash core client error refactor(sdk)!: separate dash core client error Dec 6, 2024
@lklimek lklimek added this to the v1.7.0 milestone Dec 6, 2024
@lklimek lklimek force-pushed the refactor/dash-core-client-error branch from 87c4bcf to 4b6ecf4 Compare December 6, 2024 13:49
@lklimek lklimek marked this pull request as ready for review December 6, 2024 13:49
@lklimek
Copy link
Contributor Author

lklimek commented Dec 6, 2024

@coderabbitai review all

Copy link
Contributor

coderabbitai bot commented Dec 6, 2024

@lklimek, I'll proceed to review all the changes in the PR as requested.

✅ Actions performed

Full review triggered.

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 (4)
packages/rs-sdk/src/core/dash_core_client.rs (3)

Line range hint 146-159: Update Callers to Handle New Error Type in list_unspent

The list_unspent method now returns DashCoreError. Ensure that all callers of this method are updated to handle DashCoreError instead of the previous ContextProviderError to prevent compilation errors and ensure proper error handling.

Run the following script to identify callers of list_unspent:

#!/bin/bash
# Description: Find all usages of `list_unspent` in the codebase.

rg 'list_unspent\(.*\)'

Verify that each usage handles DashCoreError appropriately.


Line range hint 160-168: Update Callers to Handle New Error Type in get_balance

The get_balance method's return type has changed to Result<Amount, DashCoreError>. Confirm that any code invoking this method is updated to manage the new error type, ensuring consistency in error handling.

Search for usages of get_balance:

#!/bin/bash
# Description: Find all usages of `get_balance` in the codebase.

rg '\.get_balance\(\)'

Ensure that error handling for DashCoreError is properly implemented in each case.


Line range hint 170-187: Handle Potential Errors in get_quorum_public_key Conversion

The method get_quorum_public_key performs a conversion from a slice to a QuorumHash, which may fail. Ensure that the error handling for this conversion is comprehensive, and consider providing more context in the error message if necessary.

Consider enhancing the error message:

-    .map_err(|e| DashCoreError::InvalidQuorum(format!("invalid quorum hash: {}", e)))?;
+    .map_err(|e| DashCoreError::InvalidQuorum(format!("Invalid quorum hash provided: {}", e)))?;
packages/rs-sdk/src/mock/provider.rs (1)

218-218: Consider enhancing the Cache implementation

The thread-safe cache implementation looks solid, but could benefit from the following improvements:

  1. Add validation for the capacity parameter
  2. Enhance error messages for lock poisoning
  3. Add usage examples in documentation

Consider applying these improvements:

 pub struct Cache<K: Hash + Eq, V> {
     inner: std::sync::RwLock<lru::LruCache<K, Arc<V>>>,
 }
 
 impl<K: Hash + Eq, V> Cache<K, V> {
+    /// Creates a new cache with the specified capacity.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// use std::num::NonZeroUsize;
+    /// let cache = Cache::new(NonZeroUsize::new(100).unwrap());
+    /// ```
     pub fn new(capacity: NonZeroUsize) -> Self {
         Self {
             inner: std::sync::RwLock::new(lru::LruCache::new(capacity)),
         }
     }
 
     pub fn get(&self, k: &K) -> Option<Arc<V>> {
-        let mut guard = self.inner.write().expect("cache lock poisoned");
+        let mut guard = self.inner.write()
+            .expect("Failed to acquire write lock on cache: lock is poisoned");
         guard.get(k).map(Arc::clone)
     }
 
     pub fn put(&self, k: K, v: V) {
-        let mut guard = self.inner.write().expect("cache lock poisoned");
+        let mut guard = self.inner.write()
+            .expect("Failed to acquire write lock on cache: lock is poisoned");
         guard.put(k, Arc::new(v));
     }

Also applies to: 228-256

📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL

📥 Commits

Reviewing files that changed from the base of the PR and between 5c3f318 and 43736ef.

📒 Files selected for processing (10)
  • packages/rs-dpp/src/bls/native_bls.rs (0 hunks)
  • packages/rs-drive-proof-verifier/src/error.rs (1 hunks)
  • packages/rs-sdk/src/core/dash_core_client.rs (8 hunks)
  • packages/rs-sdk/src/core/error.rs (1 hunks)
  • packages/rs-sdk/src/core/mod.rs (1 hunks)
  • packages/rs-sdk/src/error.rs (3 hunks)
  • packages/rs-sdk/src/mock/provider.rs (1 hunks)
  • packages/rs-sdk/src/sync.rs (0 hunks)
  • packages/rs-sdk/tests/fetch/config.rs (1 hunks)
  • packages/rs-sdk/tests/fetch/evonode.rs (0 hunks)
💤 Files with no reviewable changes (3)
  • packages/rs-sdk/tests/fetch/evonode.rs
  • packages/rs-dpp/src/bls/native_bls.rs
  • packages/rs-sdk/src/sync.rs
🔇 Additional comments (11)
packages/rs-sdk/src/core/error.rs (3)

16-27: Well-structured DashCoreError Enum Enhances Error Handling

The DashCoreError enum is well-defined, covering various error scenarios when communicating with Dash Core. Utilizing the thiserror crate provides clear and informative error messages, improving maintainability and debuggability.


29-37: Effective Conversion Implementation to ContextProviderError

The From<DashCoreError> implementation for ContextProviderError ensures seamless integration with existing error handling mechanisms. This promotes consistency across the codebase.


39-56: Correct Implementation of CanRetry Trait for Retry Logic

The CanRetry trait is implemented accurately for DashCoreError. The logic correctly identifies retryable errors based on specific RPC error codes and transport errors, enhancing the robustness of retry mechanisms.

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

9-10: Expose DashCoreError for Improved Error Handling

Introducing the error module and publicly exporting DashCoreError enhances the SDK's ability to handle Dash Core errors effectively. This allows other modules to utilize the specific error types, promoting better error management.

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

49-49: Updated CoreClientError Variant Enhances Error Specificity

Changing the CoreClientError variant to use DashCoreError improves error specificity and aligns with the new error handling structure. This enhances the clarity and maintainability of error management in the SDK.


138-143: Enhanced Retry Logic Incorporates DashCoreError

The can_retry method now includes Error::CoreClientError(e) => e.can_retry(), which appropriately delegates retry logic based on the specifics of DashCoreError. This change improves the resilience of the SDK against transient errors.


130-134: Ensure Comprehensive Conversion from dashcore_rpc::Error

The From<dashcore_rpc::Error> implementation correctly converts to Error using the new DashCoreError type. Verify that all possible variants of dashcore_rpc::Error are appropriately mapped to maintain error handling consistency.

Run the following script to identify any unmapped dashcore_rpc::Error variants:

✅ Verification successful

Let me gather more information about the error types and their handling.


Let me check the DashCoreError implementation to ensure proper error mapping.


Let me try to find the correct location of the DashCoreError definition.


Let me check the DashCoreError implementation in the core error module.


Error Conversion Implementation is Comprehensive and Correct

The implementation of From<dashcore_rpc::Error> for Error is correct and comprehensive. The conversion path is:

  1. dashcore_rpc::Error -> DashCoreError::Rpc (in core/error.rs)
  2. DashCoreError -> Error::CoreClientError (in error.rs)

All variants of dashcore_rpc::Error are properly handled through this chain, and the error handling is consistent with the codebase's usage patterns seen in rs-drive-abci.

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Find all uses of `dashcore_rpc::Error` and check for missing conversions.

rg 'dashcore_rpc::Error::' --glob '!packages/rs-sdk/src/error.rs'

Length of output: 289


Script:

#!/bin/bash
# Check the implementation of Error type and its variants
cat packages/rs-sdk/src/error.rs

Length of output: 6465


Script:

#!/bin/bash
# Check the implementation of DashCoreError
cat packages/rs-sdk/src/core.rs

Length of output: 93


Script:

#!/bin/bash
# Find files containing DashCoreError
rg "DashCoreError" -l

Length of output: 378


Script:

#!/bin/bash
# Check the DashCoreError implementation
cat packages/rs-sdk/src/core/error.rs

Length of output: 1937

packages/rs-sdk/src/core/dash_core_client.rs (2)

190-205: Ensure Robust Handling in get_platform_activation_height

When retrieving the platform activation height, the code assumes the presence of the "mn_rr" key in softforks. If this key is missing, it triggers an ActivationForkError. Confirm that this assumption is valid in all expected environments, or consider handling the absence more gracefully.

Run the following script to check for possible values of softforks in different environments:

✅ Verification successful

Let me search for more context about this fork activation and error handling.


Let me search for more specific information about the mn_rr fork and error handling in the codebase.


Based on the search results, I can now provide a conclusive response about the mn_rr fork check in get_platform_activation_height. The code shows that this fork is a critical platform activation indicator used across multiple components, including Drive ABCI and proof verification.

Error Handling for Platform Activation Height is Appropriate

The current error handling in get_platform_activation_height is correct and necessary because:

  1. The mn_rr fork is the official indicator of platform activation in Dash Core
  2. The fork must be both present and active for platform functionality to work correctly
  3. The error handling is used by critical platform components to verify initialization conditions

The error cases are properly handled:

  • Missing fork info triggers ActivationForkError("no fork info for mn_rr")
  • Missing height triggers ActivationForkError("unknown fork height")
🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Simulate `get_blockchain_info` responses to verify the presence of `"mn_rr"`.

# Note: Since we cannot run the actual RPC command, review documentation or mock the responses.
echo "Check Dash Core documentation or environments to ensure 'mn_rr' is always present in 'softforks'"

Length of output: 214


Script:

#!/bin/bash
# Search for tests or mock responses related to blockchain info and mn_rr fork
rg -l "mn_rr" --type rust

# Look for related error handling patterns
ast-grep --pattern 'match $_.softforks { $$ }'

# Search for test files containing blockchain info mocks
rg -l "get_blockchain_info.*mock" --type rust

# Look for documentation about mn_rr fork
fd README -e md -X cat {}

Length of output: 65839


Script:

#!/bin/bash
# Look for mn_rr fork references and error handling
rg -A 5 -B 5 "mn_rr" --type rust

# Search for tests related to platform activation height
rg -l "get_platform_activation_height.*test" --type rust

# Look for blockchain info mock responses
rg -A 10 "get_blockchain_info.*mock" --type rust

Length of output: 12309


57-68: Confirm Correct Error Conversion in Retry Logic

In the retry! macro, the error e is converted into DashCoreError using into(). Ensure that all error types produced within the macro can be converted into DashCoreError without loss of information, and that the retry logic operates as intended.

Run the following script to verify that error conversions to DashCoreError are correctly implemented:

✅ Verification successful

Error Conversion in Retry Logic is Properly Implemented

The error conversion in the retry macro is correctly implemented. The DashCoreError enum has a #[from] attribute for dashcore_rpc::Error, which automatically implements the From trait, allowing seamless conversion of RPC errors. The enum also handles other specific error cases (InvalidQuorum, ActivationForkError) that might occur during retry operations. The error types used within the retry macro are properly convertible to DashCoreError.

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Find all error types that need to implement `Into<DashCoreError>`.

rg 'Err\((.*)\)\s+=>\s+\{' -A 1 --no-filename | grep 'let err: DashCoreError = \1.into();'

Length of output: 121


Script:

#!/bin/bash
# Find all error conversions to DashCoreError in the retry macro
rg 'let err: DashCoreError = .+into\(\);' -B 2

# Find all error types used in the retry macro
ast-grep --pattern 'retry!($$$)'

# Find implementations of Into<DashCoreError>
rg 'impl Into<DashCoreError>'

# Find error type definitions that might be converted to DashCoreError
rg 'pub enum .+Error'

Length of output: 6770


Script:

#!/bin/bash
# Find the error types that are actually used within the retry macro
rg -B 5 'let err: DashCoreError = .+into\(\);' packages/rs-sdk/src/core/dash_core_client.rs

# Find implementations of From trait for DashCoreError
rg 'impl From<.+> for DashCoreError'

# Check the DashCoreError definition
rg -A 20 'pub enum DashCoreError' packages/rs-sdk/src/core/error.rs

Length of output: 1110

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

218-218: Verify error type conversion implementation

The change correctly propagates errors from the core client, but we should verify that there's proper conversion implemented between DashCoreError and ContextProviderError.

✅ Verification successful

Error conversion is properly implemented

The verification confirms that there's a complete From<DashCoreError> implementation for ContextProviderError in core/error.rs that handles all variants of DashCoreError appropriately:

  • DashCoreError::RpcContextProviderError::DashCoreError
  • DashCoreError::InvalidQuorumContextProviderError::InvalidQuorum
  • DashCoreError::ActivationForkErrorContextProviderError::ActivationForkError
🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Check for error conversion implementation between DashCoreError and ContextProviderError

# Search for From/Into implementation
ast-grep --pattern 'impl From<DashCoreError> for ContextProviderError'

# Search for error conversion in other ways
rg -l "DashCoreError.*ContextProviderError|ContextProviderError.*DashCoreError"

Length of output: 884

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

13-13: LGTM!

Clean removal of unused import.

packages/rs-drive-proof-verifier/src/error.rs Show resolved Hide resolved
@lklimek lklimek merged commit c3a8f80 into test/testWithoutSpan Dec 9, 2024
65 of 66 checks passed
@lklimek lklimek deleted the refactor/dash-core-client-error branch December 9, 2024 15:22
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants