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

fix(sdk): small sdk improvements and fixes for v1.4 #2200

Merged
merged 8 commits into from
Oct 3, 2024

Conversation

QuantumExplorer
Copy link
Member

@QuantumExplorer QuantumExplorer commented Oct 3, 2024

Issue being fixed or feature implemented

This PR introduces the implementation of Display traits for several types and improves mock serialization and deserialization. Additionally, it addresses a panic issue related to the PubkeyHash length mismatch and improves support for fetching multiple elements and queries.

What was done?

•	Implemented Display for ValidatorSet and ValidatorSetV0, providing readable formatting for debugging and logging.
•	Addressed panic caused by incorrect PubkeyHash length by replacing a 32-byte slice with a 20-byte slice.
•	Implemented MockResponse for Element, ensuring proper serialization and deserialization using bincode.
•	Added support for fetching multiple Elements with the FetchMany trait implementation.
•	Implemented Display for WithdrawalStatus to provide human-readable status values.
•	Added query implementation for GetCurrentQuorumsInfoRequest via NoParamQuery.

How Has This Been Tested?

•	Manually verified the new Display implementations for ValidatorSet, ValidatorSetV0, and WithdrawalStatus in logs.
•	Verified the panic no longer occurs with the correct PubkeyHash length in different scenarios.
•	Ensured that fetching elements using FetchMany works as expected.

Breaking Changes

•	No breaking changes in functionality, but this PR fixes a potential panic related to PubkeyHash.

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

    • Enhanced debugging capabilities for ValidatorV0 and ValidatorSetV0 with improved string formatting.
    • Added new request type GetPathElementsRequest to support fetching multiple elements in the FetchMany trait.
    • Introduced Display implementations for WithdrawalStatus, providing user-friendly string representations.
  • Bug Fixes

    • Improved error handling in the maybe_from_unproved_with_metadata method for CurrentQuorumsInfo.
  • Documentation

    • Updated import statements for better organization and clarity.

Copy link
Contributor

coderabbitai bot commented Oct 3, 2024

Walkthrough

The changes in this pull request primarily involve modifications to the Debug and Display trait implementations across various structs and enums, enhancing their string representation for debugging and logging purposes. Key updates include new implementations for ValidatorSet, ValidatorSetV0, and WithdrawalStatus, along with improved error handling in the FromUnproved trait. Import statements have also been reorganized to accommodate these changes, and new request types have been introduced in the FetchMany and Query traits.

Changes

File Path Change Summary
packages/rs-dpp/src/core_types/validator/v0/mod.rs Updated import statements; modified Debug trait implementation for ValidatorV0.
packages/rs-dpp/src/core_types/validator_set/mod.rs Added Display trait implementation for ValidatorSet.
packages/rs-dpp/src/core_types/validator_set/v0/mod.rs Added Display implementation for ValidatorSetV0; updated Debug implementation.
packages/rs-drive-proof-verifier/src/unproved.rs Enhanced error handling in maybe_from_unproved_with_metadata for CurrentQuorumsInfo; updated node_id field in ValidatorV0.
packages/rs-sdk/src/mock/requests.rs Added mock_serialize and mock_deserialize methods for Element.
packages/rs-sdk/src/platform/fetch_many.rs Introduced GetPathElementsRequest to FetchMany trait for Element.
packages/rs-sdk/src/platform/query.rs Added support for GetCurrentQuorumsInfoRequestV0 in Query trait; modified existing implementations.
packages/withdrawals-contract/src/lib.rs Added Display trait implementation for WithdrawalStatus.

Possibly related PRs

Suggested reviewers

  • shumkov
  • lklimek

Poem

In the code where rabbits hop,
Traits and structs take a stop.
With Display shining bright,
Debugging now feels just right.
From Validator to Set,
New paths we won't forget! 🐇✨


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.

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 (8)
packages/withdrawals-contract/src/lib.rs (2)

48-59: LGTM: Implementation of fmt::Display for WithdrawalStatus.

The implementation is correct and improves the usability of the WithdrawalStatus enum by providing human-readable string representations. All enum variants are covered, ensuring exhaustiveness.

For consistency with the enum variant names, consider using uppercase strings in the match arms:

 impl fmt::Display for WithdrawalStatus {
     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
         let status_str = match self {
-            WithdrawalStatus::QUEUED => "Queued",
-            WithdrawalStatus::POOLED => "Pooled",
-            WithdrawalStatus::BROADCASTED => "Broadcasted",
-            WithdrawalStatus::COMPLETE => "Complete",
-            WithdrawalStatus::EXPIRED => "Expired",
+            WithdrawalStatus::QUEUED => "QUEUED",
+            WithdrawalStatus::POOLED => "POOLED",
+            WithdrawalStatus::BROADCASTED => "BROADCASTED",
+            WithdrawalStatus::COMPLETE => "COMPLETE",
+            WithdrawalStatus::EXPIRED => "EXPIRED",
         };
         write!(f, "{}", status_str)
     }
 }

This change would maintain consistency with the enum variant names and potentially make it easier to match string representations back to enum variants if needed.


7-7: Summary: Improved WithdrawalStatus enum usability.

The changes in this file are minimal and focused, aligning well with the PR objectives of making small SDK improvements. The implementation of fmt::Display for WithdrawalStatus enhances the usability of the enum by providing human-readable string representations. This change does not introduce any breaking changes and should improve the developer experience when working with withdrawal statuses.

Consider adding unit tests for the new fmt::Display implementation to ensure correct functionality and prevent regressions in future updates.

Also applies to: 48-59

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

38-44: LGTM! Consider future-proofing the implementation.

The Display implementation for ValidatorSet is correct and follows Rust's idiomatic patterns. It properly delegates the formatting to the contained ValidatorSetV0 instance.

For future-proofing, consider adding a catch-all arm to the match expression. This will ensure that the code continues to compile if new variants are added to the ValidatorSet enum in the future. Here's a suggested improvement:

impl Display for ValidatorSet {
    fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
        match self {
            ValidatorSet::V0(v0) => write!(f, "{}", v0),
            _ => write!(f, "Unknown ValidatorSet variant"),
        }
    }
}

This change will make the code more resilient to future updates of the ValidatorSet enum.

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

170-191: LGTM! Consider using the global BINCODE_CONFIG for consistency.

The implementation of MockResponse for Element looks good and follows the pattern established for other types in this file. It correctly implements both mock_serialize and mock_deserialize methods using bincode.

For consistency with other implementations in this file, consider using the global BINCODE_CONFIG instead of creating a new standard configuration in each method. Here's a suggested modification:

 impl MockResponse for Element {
     fn mock_serialize(&self, _sdk: &MockDashPlatformSdk) -> Vec<u8> {
-        // Create a bincode configuration
-        let config = standard();
-
-        // Serialize using the specified configuration
-        bincode::encode_to_vec(self, config).expect("Failed to serialize Element")
+        bincode::encode_to_vec(self, BINCODE_CONFIG).expect("Failed to serialize Element")
     }

     fn mock_deserialize(_sdk: &MockDashPlatformSdk, buf: &[u8]) -> Self
     where
         Self: Sized,
     {
-        // Create a bincode configuration
-        let config = standard();
-
-        // Deserialize using the specified configuration
-        bincode::decode_from_slice(buf, config)
+        bincode::decode_from_slice(buf, BINCODE_CONFIG)
             .expect("Failed to deserialize Element")
             .0
     }
 }

This change would make the implementation more consistent with other MockResponse implementations in the file and reduce redundancy.

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

40-67: LGTM: Well-implemented Display trait with a minor suggestion.

The Display implementation for ValidatorSetV0 is well-structured and provides a clear, human-readable representation of the struct. It correctly handles all fields, including the optional quorum_index.

For consistency, consider using the to_string() method for quorum_hash and threshold_public_key instead of hex::encode(), similar to how it's done in the Debug implementation. This would make the code more uniform across different trait implementations. For example:

write!(
    f,
    "ValidatorSet {{
    quorum_hash: {},
    // ... other fields ...
    threshold_public_key: {}
}}",
    self.quorum_hash.to_string(),
    // ... other fields ...
    self.threshold_public_key.to_string()
)

This change would maintain consistency with the Debug implementation while still providing a readable output.

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

626-642: Implementation looks good, with a minor suggestion for improvement.

The new implementation of Query for NoParamQuery is correct and follows the established patterns in the file. However, consider replacing the unimplemented! macro with a proper Error return for better error handling when prove is true.

Consider replacing the unimplemented! macro with an Error return:

 fn query(self, prove: bool) -> Result<GetCurrentQuorumsInfoRequest, Error> {
     if prove {
-        unimplemented!(
-            "query with proof are not supported yet for GetCurrentQuorumsInfoRequest"
-        );
+        return Err(Error::Generic("Query with proof is not supported yet for GetCurrentQuorumsInfoRequest".into()));
     }

     let request: GetCurrentQuorumsInfoRequest = GetCurrentQuorumsInfoRequest {
         version: Some(get_current_quorums_info_request::Version::V0(
             GetCurrentQuorumsInfoRequestV0 {},
         )),
     };

     Ok(request)
 }

This change would provide a more graceful error handling approach and avoid potential panics in production code.

packages/rs-sdk/src/platform/fetch_many.rs (2)

19-20: Missing documentation for the new request type GetPathElementsRequest.

The newly added GetPathElementsRequest in the import statements lacks accompanying documentation. Providing documentation will enhance code readability and help other developers understand its purpose.


425-431: Add documentation for the new FetchMany implementation for Element.

The implementation of FetchMany<Key, Elements> for Element lacks documentation. To maintain consistency with other trait implementations and assist developers in understanding how to use this functionality, please add comprehensive documentation, including the purpose, usage examples, and supported query types.

Here's a suggested addition:

/// Fetch multiple elements from Platform.
///
/// Returns [Elements](drive_proof_verifier::types::Elements) indexed by their [Key](drive::grovedb::query_result_type::Key).
///
/// ## Supported query types
///
/// * [KeysInPath] - Specifies the path and keys from which to fetch elements.
///
/// ## Example
///
/// ```rust
/// use dash_sdk::platform::{FetchMany, KeysInPath};
/// use dash_sdk::Sdk;
/// use drive::grovedb::Element;
///
/// #[tokio::main]
/// async fn main() -> Result<(), dash_sdk::error::Error> {
///     let sdk = Sdk::new();
///     let path = vec!["some", "path"];
///     let keys = vec![b"key1".to_vec(), b"key2".to_vec()];
///     let query = KeysInPath::new(path, keys);
///     let elements = Element::fetch_many(&sdk, query).await?;
///     Ok(())
/// }
/// ```
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL

📥 Commits

Files that changed from the base of the PR and between 5eacc13 and ce17bee.

📒 Files selected for processing (8)
  • packages/rs-dpp/src/core_types/validator/v0/mod.rs (1 hunks)
  • packages/rs-dpp/src/core_types/validator_set/mod.rs (2 hunks)
  • packages/rs-dpp/src/core_types/validator_set/v0/mod.rs (2 hunks)
  • packages/rs-drive-proof-verifier/src/unproved.rs (1 hunks)
  • packages/rs-sdk/src/mock/requests.rs (3 hunks)
  • packages/rs-sdk/src/platform/fetch_many.rs (3 hunks)
  • packages/rs-sdk/src/platform/query.rs (2 hunks)
  • packages/withdrawals-contract/src/lib.rs (2 hunks)
🔇 Additional comments (10)
packages/withdrawals-contract/src/lib.rs (1)

7-7: LGTM: Import statement for fmt module.

The import statement for std::fmt is correctly added and necessary for implementing the fmt::Display trait.

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

Line range hint 1-45: Summary: Display trait implementation enhances ValidatorSet usability

The addition of the Display trait implementation for ValidatorSet is a positive change that improves the enum's usability by providing a string representation. This implementation is consistent with the existing code structure and doesn't introduce any breaking changes or affect the existing functionality.

The change aligns well with the PR objectives of implementing minor improvements to the SDK. It enhances the developer experience by allowing easier debugging and logging of ValidatorSet instances.

packages/rs-dpp/src/core_types/validator/v0/mod.rs (3)

2-3: LGTM: Import statements reorganized.

The changes to the import statements improve the organization and flexibility of the code. Importing the whole fmt module and adding the Display trait to the specific imports is a good practice that allows for easier expansion of formatting capabilities in the future.


Line range hint 117-127: LGTM: Improved Debug implementation for ValidatorV0.

The changes to the Debug implementation for ValidatorV0 enhance the readability of the debug output. Using to_string() for the pro_tx_hash field provides a more human-readable representation. The implementation follows Rust's best practices for the Debug trait.


Line range hint 1-227: Overall assessment: Changes improve code quality.

The modifications in this file, including the reorganization of import statements and the enhancement of the Debug implementation for ValidatorV0, contribute to better code organization and improved debug output readability. These changes align well with the PR objectives of implementing small SDK improvements.

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

13-13: LGTM: Necessary import for new functionality.

The addition of use itertools::Itertools; is appropriate for the new Display implementation that uses the join method from this crate.


17-18: LGTM: Appropriate imports for Display trait implementation.

The addition of use std::fmt; and the inclusion of Display in the existing fmt import are correct and necessary for implementing the Display trait.


Line range hint 1-268: Summary: Good improvements with minor suggestions.

The changes to this file, primarily the addition of the Display trait implementation for ValidatorSetV0, are well-implemented and enhance the struct's usability. The new implementation provides a clear, human-readable representation of the struct's data.

The necessary imports have been correctly added, and the code is generally well-structured. A minor suggestion was made for consistency in string conversion methods between the Display and Debug implementations.

Overall, these changes represent a positive improvement to the codebase.

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

11-11: LGTM: New import added correctly.

The new import for GetCurrentQuorumsInfoRequestV0 is correctly placed and consistent with the existing code style.

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

34-35: Verify the necessity of importing Path.

The import of Path from drive::grovedb::query_result_type is added, but there doesn't appear to be any usage of Path within this file. Please verify if Path is required, and remove it if it's unused to keep the codebase clean.

Run the following script to check for usages of Path:

✅ Verification successful

Remove Unused Path Import

The Path import in packages/rs-sdk/src/platform/fetch_many.rs is not used and can be safely removed.

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Check if `Path` is used in the codebase.

# Search for `Path` usage in Rust files within the `packages/rs-sdk` directory.
rg --type rust '\bPath\b' packages/rs-sdk/

Length of output: 382

@@ -231,7 +231,7 @@ impl FromUnproved<platform::GetCurrentQuorumsInfoRequest> for CurrentQuorumsInfo
pro_tx_hash,
public_key: None, // Assuming it's not provided here
node_ip: member.node_ip,
node_id: PubkeyHash::from_slice(&[0; 32]).unwrap(), // Placeholder, since not provided
node_id: PubkeyHash::from_slice(&[0; 20]).expect("expected to make pub key hash from 20 byte empty array"), // Placeholder, since not provided
Copy link
Contributor

@coderabbitai coderabbitai bot Oct 3, 2024

Choose a reason for hiding this comment

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

⚠️ Potential issue

Handle missing node_id appropriately

Assigning a placeholder node_id with a zeroed array may lead to incorrect behavior or security issues. Instead of using a placeholder, consider implementing error handling or default logic to manage cases where node_id is not provided. This ensures the system remains robust and secure when encountering incomplete data.

Would you like assistance in implementing proper error handling for the missing node_id?

Copy link
Member Author

Choose a reason for hiding this comment

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

No this is what I want to do.

Copy link
Contributor

Choose a reason for hiding this comment

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

@QuantumExplorer, understood. If you have any further questions or need assistance in the future, feel free to let me know.

(ノ_・。)


✏️ Learnings added
Learnt from: QuantumExplorer
PR: dashpay/platform#2200
File: packages/rs-drive-proof-verifier/src/unproved.rs:234-234
Timestamp: 2024-10-03T05:17:52.320Z
Learning: When `node_id` is not provided, assigning a placeholder `node_id` with a zeroed array is acceptable.

Note: Learnings are effective only in the context of similar code segments. To apply general coding guidelines, please configure review instructions. You can manage existing learnings in the app.

@QuantumExplorer QuantumExplorer added this to the v1.4.0 milestone Oct 3, 2024
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