Skip to content

feat(drive-abci): improve token name localization validation #2593

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

Merged
merged 6 commits into from
May 7, 2025

Conversation

QuantumExplorer
Copy link
Member

@QuantumExplorer QuantumExplorer commented May 7, 2025

Issue being fixed or feature implemented

This PR improves validation of token localizations within token configuration conventions. It ensures that localization entries adhere to expected constraints on structure, character validity, and length.

What was done?

  • Introduced new consensus validation errors to ensure correctness and clarity:

    • InvalidKeywordCharacterError
    • InvalidTokenNameCharacterError
    • InvalidTokenNameLengthError
    • InvalidTokenLanguageCodeError
    • DecimalsOverLimitError

  • Updated TokenConfigurationConvention::validate_localizations_v0 to enforce the following validation rules:

    • Token names (singular and plural) must not contain whitespace or control characters.
    • Token name lengths must be between 3 and 25 characters.
    • Language codes must:
    • Match the BCP 47-compatible regex format.
    • Have a length between 2 and 12 characters.
    • At least one localization must be provided in English.

  • The decimals value must not exceed 16.

  • Registered all new errors in the ConsensusError conversion match block via generic_consensus_error!.

How Has This Been Tested?

Not yet tested, will do so in DET

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.

For repository code-owners and collaborators only

  • I have assigned this pull request to a milestone

Summary by CodeRabbit

Summary by CodeRabbit

  • New Features

    • Introduced stricter validation for token names, language codes, and keywords, including checks for invalid characters and length constraints.
    • Added new error messages for issues such as invalid token names, language codes, decimals over limit, and invalid keyword characters.
    • Added setter methods to update token decimals and localizations.
  • Improvements

    • Increased the maximum allowed keywords in data contracts from 20 to 50.
    • All keywords are now automatically lowercased during deserialization.
    • The maximum allowed token decimals is now enforced at 16.
    • Token decimals type changed to use a smaller data size for efficiency.
  • Bug Fixes

    • Improved error reporting for token and keyword validation failures with more descriptive messages.

Copy link
Contributor

coderabbitai bot commented May 7, 2025

"""

Walkthrough

This update introduces stricter validation for token and keyword fields in data contracts, including new error types for invalid characters, lengths, and decimal limits. The maximum allowed keywords increases from 20 to 50. The decimals field type changes from u16 to u8, and new setter methods are added. Error handling and serialization logic are extended to accommodate these changes.

Changes

Files/Paths Change Summary
.../token_configuration_convention/accessors/mod.rs
.../token_configuration_convention/accessors/v0/mod.rs
.../token_configuration_convention/v0/mod.rs
Changed decimals field and related methods from u16 to u8. Added setter methods for localizations and decimals.
.../token_configuration_convention/methods/validate_localizations/v0/mod.rs Enhanced localization validation: checks for decimals limit, invalid characters, length, and language code format.
.../methods/validate_update/v0/mod.rs
.../state_transitions/data_contract_create/.../mod.rs
.../state_transitions/data_contract_update/mod.rs
Increased keyword limit from 20 to 50. Added validation for invalid characters in keywords. Updated test data accordingly.
.../v1/serialization/mod.rs Lowercases keywords during deserialization.
.../consensus/basic/basic_error.rs
.../consensus/basic/data_contract/mod.rs
.../consensus/basic/codes.rs
Added new error variants for token and keyword validation; added new error modules and updated error codes accordingly.
.../data_contract/invalid_keyword_character_error.rs Added new error type for keywords with invalid characters.
.../data_contract/invalid_token_language_code_error.rs Added new error type for invalid token language codes.
.../data_contract/invalid_token_name_character_error.rs Added new error type for token names with invalid characters.
.../data_contract/invalid_token_name_length_error.rs Added new error type for token names with invalid lengths.
.../data_contract/token_decimals_over_limit_error.rs Added new error type for decimals exceeding allowed limit.
.../keywords_over_limit.rs Updated error message to reflect increased keyword limit.
.../wasm-dpp/src/errors/consensus/consensus_error.rs Added handling for new error variants in WASM consensus error conversion.
.../drive/votes/resolved/vote_polls/contested_document_resource_vote_poll/resolve.rs Added missing #[cfg(feature = "server")] attribute to import.

Sequence Diagram(s)

sequenceDiagram
    participant User
    participant DataContract
    participant Validator
    participant ErrorTypes

    User->>DataContract: Submit contract with tokens/keywords
    DataContract->>Validator: validate_localizations_v0 / validate_update_v0
    Validator->>ErrorTypes: Check for invalid characters, length, decimals, language code
    alt Validation fails
        ErrorTypes-->>Validator: Return specific error
        Validator-->>DataContract: Return error
        DataContract-->>User: Error response
    else Validation passes
        Validator-->>DataContract: Success
        DataContract-->>User: Success response
    end
Loading

Possibly related PRs

  • feat: validate token name localizations #2468: Extends TokenConfigurationConvention by changing the decimals type from u16 to u8 and adding getter/setter traits for localizations, closely related to this PR’s changes in token configuration accessors and validation.
  • feat(platform): keyword search system contract #2523: Adds the Keyword Search system contract package and related schema, documents, and tests, directly related to this PR’s changes to data contract keyword fields and validation.

Suggested reviewers

  • shumkov

Poem

A hop, a skip, a validation leap,
Now tokens and keywords no secrets keep!
Decimals are tiny, errors are new,
Fifty keywords now, not just a few.
If your language code’s wrong or your name is too long,
The rabbit will catch it before it goes wrong!
🐇✨
"""


📜 Recent review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 097fcf4 and 5d6a49b.

📒 Files selected for processing (1)
  • packages/rs-dpp/src/data_contract/methods/validate_update/v0/mod.rs (4 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
  • packages/rs-dpp/src/data_contract/methods/validate_update/v0/mod.rs
⏰ Context from checks skipped due to timeout of 90000ms (20)
  • GitHub Check: Rust packages (dpp) / Tests
  • GitHub Check: Rust packages (dpp) / Formatting
  • GitHub Check: Rust packages (drive-abci) / Unused dependencies
  • GitHub Check: Rust packages (drive-abci) / Linting
  • GitHub Check: Rust packages (drive-abci) / Check each feature
  • GitHub Check: Rust packages (drive) / Tests
  • GitHub Check: Rust packages (drive-abci) / Tests
  • GitHub Check: Rust packages (dash-sdk) / Unused dependencies
  • GitHub Check: Rust packages (dash-sdk) / Linting
  • GitHub Check: Rust packages (dash-sdk) / Check each feature
  • GitHub Check: Rust packages (dash-sdk) / Tests
  • GitHub Check: Rust packages (dash-sdk) / Formatting
  • GitHub Check: Rust packages (wasm-dpp) / Unused dependencies
  • GitHub Check: Rust packages (wasm-dpp) / Tests
  • GitHub Check: Rust packages (drive) / Linting
  • GitHub Check: Rust packages (wasm-dpp) / 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
✨ Finishing Touches
  • 📝 Generate Docstrings

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

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

Support

Need help? Create a ticket on our support page for assistance with any issues or questions.

Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments.

CodeRabbit Commands (Invoked using PR comments)

  • @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.
  • @coderabbitai generate sequence diagram to generate a sequence diagram of the changes in this 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.

@QuantumExplorer QuantumExplorer changed the title fix: correct decimal validation errors and improve error handling feat(drive-abci): improve localization validation May 7, 2025
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: 2

🧹 Nitpick comments (4)
packages/rs-dpp/src/data_contract/associated_token/token_configuration_convention/methods/validate_localizations/v0/mod.rs (2)

31-36: Hard-code replaced with magic number – promote to a named constant

16 is repeated here as the upper limit for decimals. Surfacing this number as a const MAX_DECIMALS: u8 = 16; at module scope (or re-using an existing constant if one already exists) will:

  • avoid “magic number” drift when specs change,
  • make unit tests clearer, and
  • give the compiler a single source of truth.
+const MAX_DECIMALS: u8 = 16;
 ...
-// Max decimals is defined as 16
-if self.decimals() > 16 {
+// Upper-bound decimals
+if self.decimals() > MAX_DECIMALS {
     return SimpleConsensusValidationResult::new_with_error(
-        DecimalsOverLimitError::new(self.decimals(), 16).into(),
+        DecimalsOverLimitError::new(self.decimals(), MAX_DECIMALS).into(),
     );
 }

38-68: Minor duplication – consider extracting a helper for character validation

The three blocks that validate control/whitespace characters for singular_form, plural_form, and language are identical apart from the labels. A small helper would remove duplication and lower the cognitive load for future changes.

packages/rs-dpp/src/data_contract/associated_token/token_configuration_convention/accessors/mod.rs (1)

46-61: Setter implementation forwards only V0 – remember to extend when new versions appear

The match arms delegate correctly for V0, but future enum variants will silently ignore setters unless this block is updated. A #[allow(unreachable_patterns)] + _ => unreachable!() arm (or todo!() placeholder) can safeguard against accidental omissions.

packages/rs-dpp/src/errors/consensus/basic/data_contract/invalid_token_name_length_error.rs (1)

1-56: Well-structured error type with minor style inconsistency.

The error type provides clear information about length validation failures with appropriate fields and a descriptive error message. The implementation follows the standard pattern with one minor style inconsistency.

Line 54 uses ConsensusError::BasicError while other similar implementations use Self::BasicError. For consistency, consider:

-        ConsensusError::BasicError(BasicError::InvalidTokenNameLengthError(err))
+        Self::BasicError(BasicError::InvalidTokenNameLengthError(err))
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 31d2e35 and 8d09bad.

📒 Files selected for processing (17)
  • packages/rs-dpp/src/data_contract/associated_token/token_configuration_convention/accessors/mod.rs (2 hunks)
  • packages/rs-dpp/src/data_contract/associated_token/token_configuration_convention/accessors/v0/mod.rs (2 hunks)
  • packages/rs-dpp/src/data_contract/associated_token/token_configuration_convention/methods/validate_localizations/v0/mod.rs (2 hunks)
  • packages/rs-dpp/src/data_contract/associated_token/token_configuration_convention/v0/mod.rs (3 hunks)
  • packages/rs-dpp/src/data_contract/methods/validate_update/v0/mod.rs (3 hunks)
  • packages/rs-dpp/src/data_contract/v1/serialization/mod.rs (1 hunks)
  • packages/rs-dpp/src/errors/consensus/basic/basic_error.rs (2 hunks)
  • packages/rs-dpp/src/errors/consensus/basic/data_contract/invalid_keyword_character_error.rs (1 hunks)
  • packages/rs-dpp/src/errors/consensus/basic/data_contract/invalid_token_language_code_error.rs (1 hunks)
  • packages/rs-dpp/src/errors/consensus/basic/data_contract/invalid_token_name_character_error.rs (1 hunks)
  • packages/rs-dpp/src/errors/consensus/basic/data_contract/invalid_token_name_length_error.rs (1 hunks)
  • packages/rs-dpp/src/errors/consensus/basic/data_contract/keywords_over_limit.rs (1 hunks)
  • packages/rs-dpp/src/errors/consensus/basic/data_contract/mod.rs (2 hunks)
  • packages/rs-dpp/src/errors/consensus/basic/data_contract/token_decimals_over_limit_error.rs (1 hunks)
  • packages/rs-dpp/src/errors/consensus/codes.rs (1 hunks)
  • packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/data_contract_create/basic_structure/v0/mod.rs (3 hunks)
  • packages/wasm-dpp/src/errors/consensus/consensus_error.rs (2 hunks)
🧰 Additional context used
🧠 Learnings (2)
packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/data_contract_create/basic_structure/v0/mod.rs (2)
Learnt from: pauldelucia
PR: dashpay/platform#2523
File: packages/rs-drive/src/drive/contract/insert/add_new_keywords/v1/mod.rs:22-22
Timestamp: 2025-04-11T09:08:11.528Z
Learning: The validation for data contract keywords (ensuring no more than 20 unique keywords with appropriate length) is handled in the validation logic elsewhere in the codebase (particularly in the advanced structure validation and data contract update validation), not in the Drive implementation that handles storage operations.
Learnt from: pauldelucia
PR: dashpay/platform#2523
File: packages/rs-drive/src/drive/contract/insert/add_new_keywords/v1/mod.rs:22-22
Timestamp: 2025-04-11T09:08:11.528Z
Learning: The validation for data contract keywords (ensuring no more than 20 unique keywords with appropriate length) is handled in the validation logic elsewhere in the codebase (particularly in the advanced structure validation and data contract update validation), not in the Drive implementation that handles storage operations.
packages/rs-dpp/src/data_contract/methods/validate_update/v0/mod.rs (2)
Learnt from: pauldelucia
PR: dashpay/platform#2523
File: packages/rs-drive/src/drive/contract/update/update_contract/v1/update_description/v1/mod.rs:147-151
Timestamp: 2025-04-11T09:08:05.652Z
Learning: Description length validation for data contracts (ensuring it's between 3 and 100 characters) is already handled at the data contract validation level in packages/rs-dpp/src/data_contract/methods/validate_update/v0/mod.rs, making additional checks in the update operations redundant.
Learnt from: pauldelucia
PR: dashpay/platform#2523
File: packages/rs-drive/src/drive/contract/update/update_contract/v1/update_description/v1/mod.rs:147-151
Timestamp: 2025-04-11T09:08:05.652Z
Learning: Description length validation for data contracts is already handled in the data contract validation process, specifically in packages/rs-dpp/src/data_contract/methods/validate_update/v0/mod.rs.
🧬 Code Graph Analysis (8)
packages/rs-dpp/src/data_contract/associated_token/token_configuration_convention/accessors/v0/mod.rs (3)
packages/rs-dpp/src/data_contract/associated_token/token_configuration_convention/v0/mod.rs (2)
  • decimals (87-89)
  • set_decimals (100-102)
packages/rs-dpp/src/data_contract/associated_token/token_configuration_convention/accessors/mod.rs (2)
  • decimals (39-43)
  • set_decimals (56-60)
packages/rs-dpp/src/errors/consensus/basic/data_contract/token_decimals_over_limit_error.rs (1)
  • decimals (31-33)
packages/rs-dpp/src/data_contract/associated_token/token_configuration_convention/methods/validate_localizations/v0/mod.rs (4)
packages/rs-dpp/src/errors/consensus/basic/data_contract/invalid_token_language_code_error.rs (1)
  • new (21-23)
packages/rs-dpp/src/errors/consensus/basic/data_contract/invalid_token_name_length_error.rs (1)
  • new (26-33)
packages/rs-dpp/src/errors/consensus/basic/data_contract/invalid_token_name_character_error.rs (1)
  • new (24-26)
packages/rs-dpp/src/errors/consensus/basic/data_contract/token_decimals_over_limit_error.rs (1)
  • new (24-29)
packages/rs-dpp/src/errors/consensus/basic/data_contract/token_decimals_over_limit_error.rs (6)
packages/rs-dpp/src/errors/consensus/basic/data_contract/invalid_keyword_character_error.rs (2)
  • new (25-30)
  • from (42-44)
packages/rs-dpp/src/errors/consensus/basic/data_contract/invalid_token_language_code_error.rs (2)
  • new (21-23)
  • from (31-33)
packages/rs-dpp/src/errors/consensus/basic/data_contract/invalid_token_name_length_error.rs (2)
  • new (26-33)
  • from (53-55)
packages/rs-dpp/src/errors/consensus/basic/data_contract/invalid_token_name_character_error.rs (2)
  • new (24-26)
  • from (38-40)
packages/rs-dpp/src/errors/consensus/basic/data_contract/keywords_over_limit.rs (2)
  • new (27-32)
  • from (44-46)
packages/rs-dpp/src/errors/consensus/basic/basic_error.rs (1)
  • from (560-562)
packages/rs-dpp/src/errors/consensus/basic/data_contract/invalid_token_language_code_error.rs (6)
packages/rs-dpp/src/errors/consensus/basic/data_contract/invalid_keyword_character_error.rs (2)
  • new (25-30)
  • from (42-44)
packages/rs-dpp/src/errors/consensus/basic/data_contract/invalid_token_name_length_error.rs (2)
  • new (26-33)
  • from (53-55)
packages/rs-dpp/src/errors/consensus/basic/data_contract/invalid_token_name_character_error.rs (2)
  • new (24-26)
  • from (38-40)
packages/rs-dpp/src/errors/consensus/basic/data_contract/keywords_over_limit.rs (2)
  • new (27-32)
  • from (44-46)
packages/rs-dpp/src/errors/consensus/basic/data_contract/token_decimals_over_limit_error.rs (2)
  • new (24-29)
  • from (41-43)
packages/rs-dpp/src/errors/consensus/basic/basic_error.rs (1)
  • from (560-562)
packages/rs-dpp/src/data_contract/methods/validate_update/v0/mod.rs (2)
packages/rs-dpp/src/errors/consensus/basic/data_contract/invalid_keyword_character_error.rs (2)
  • keyword (36-38)
  • new (25-30)
packages/rs-dpp/src/errors/consensus/basic/data_contract/keywords_over_limit.rs (1)
  • new (27-32)
packages/rs-dpp/src/errors/consensus/basic/data_contract/invalid_keyword_character_error.rs (4)
packages/rs-dpp/src/errors/consensus/basic/data_contract/invalid_token_language_code_error.rs (2)
  • new (21-23)
  • from (31-33)
packages/rs-dpp/src/errors/consensus/basic/data_contract/invalid_token_name_character_error.rs (2)
  • new (24-26)
  • from (38-40)
packages/rs-dpp/src/errors/consensus/basic/data_contract/keywords_over_limit.rs (3)
  • new (27-32)
  • data_contract_id (34-36)
  • from (44-46)
packages/rs-dpp/src/errors/consensus/basic/basic_error.rs (1)
  • from (560-562)
packages/rs-dpp/src/errors/consensus/basic/data_contract/invalid_token_name_character_error.rs (3)
packages/rs-dpp/src/errors/consensus/basic/data_contract/invalid_token_language_code_error.rs (2)
  • new (21-23)
  • from (31-33)
packages/rs-dpp/src/errors/consensus/basic/data_contract/invalid_token_name_length_error.rs (3)
  • new (26-33)
  • form (47-49)
  • from (53-55)
packages/rs-dpp/src/errors/consensus/basic/basic_error.rs (1)
  • from (560-562)
packages/rs-dpp/src/data_contract/associated_token/token_configuration_convention/v0/mod.rs (3)
packages/rs-dpp/src/data_contract/associated_token/token_configuration_convention/accessors/v0/mod.rs (4)
  • decimals (17-17)
  • set_localizations (23-26)
  • localizations (11-11)
  • set_decimals (29-29)
packages/rs-dpp/src/data_contract/associated_token/token_configuration_convention/accessors/mod.rs (4)
  • decimals (39-43)
  • set_localizations (47-54)
  • localizations (27-31)
  • set_decimals (56-60)
packages/rs-dpp/src/errors/consensus/basic/data_contract/token_decimals_over_limit_error.rs (1)
  • decimals (31-33)
⏰ Context from checks skipped due to timeout of 90000ms (17)
  • GitHub Check: Rust packages (dash-sdk) / Linting
  • GitHub Check: Rust packages (dash-sdk) / Formatting
  • GitHub Check: Rust packages (drive-abci) / Linting
  • GitHub Check: Rust packages (dash-sdk) / Check each feature
  • GitHub Check: Rust packages (drive-abci) / Tests
  • GitHub Check: Rust packages (drive-abci) / Check each feature
  • GitHub Check: Rust packages (drive-abci) / Unused dependencies
  • GitHub Check: Rust packages (drive) / Tests
  • GitHub Check: Rust packages (drive) / Linting
  • GitHub Check: Rust packages (wasm-dpp) / Tests
  • GitHub Check: Rust packages (dpp) / Tests
  • GitHub Check: Rust packages (dpp) / Check each feature
  • GitHub Check: Rust packages (dpp) / 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 (28)
packages/rs-dpp/src/errors/consensus/basic/data_contract/keywords_over_limit.rs (1)

13-13: Updated error message to reflect new keyword limit

The error message has been updated to indicate that the maximum number of keywords allowed is now 50 (previously 20), which aligns with the PR objective to improve error handling and validation for data contracts.

packages/rs-dpp/src/data_contract/v1/serialization/mod.rs (1)

176-179: Improved keyword normalization during deserialization

This change ensures all keywords are converted to lowercase during deserialization, which is a good practice for maintaining consistency. This prevents potential issues with case-sensitive comparisons and improves the reliability of keyword matching.

packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/data_contract_create/basic_structure/v0/mod.rs (3)

4-4: LGTM: Added import for new error type

The import for InvalidKeywordCharacterError has been correctly added to support the new validation checks.


120-121: Updated keyword limit from 20 to 50

The comment and validation logic have been updated to reflect the new maximum limit of 50 keywords, which aligns with the changes in the error message from the first file. This is consistent with the PR objectives to improve data contract validation.


147-160: Added validation for invalid keyword characters

New validation logic has been added to ensure keywords don't contain control or whitespace characters, improving the robustness of the data contract validation process. This check is properly positioned between length validation and uniqueness validation, forming a logical sequence of validation steps.

packages/rs-dpp/src/data_contract/associated_token/token_configuration_convention/accessors/v0/mod.rs (2)

17-17: Changed decimals type from u16 to u8

The return type of decimals() method has been changed from u16 to u8, which aligns with the broader changes in the PR to refine decimal validation. Since decimal places in tokens typically don't exceed 18 (and certainly not 255), this change is appropriate and more memory-efficient.


29-29: Updated decimals setter parameter type to match getter

The parameter type of set_decimals() method has been changed from u16 to u8 to maintain consistency with the getter method. This change is correctly synchronized with the corresponding implementation changes in the actual struct, ensuring type consistency throughout the codebase.

packages/rs-dpp/src/data_contract/methods/validate_update/v0/mod.rs (3)

10-11: Updated imports reflect new keyword validation functionality.

Imports were updated to include InvalidKeywordCharacterError for the new keyword character validation logic.


271-272: Keyword limit increased from 20 to 50.

The maximum allowed number of keywords has been increased from 20 to 50, providing more flexibility for data contract metadata.


288-300: Added keyword character validation.

Added new validation to ensure keywords don't contain control characters or whitespace. This check occurs before the uniqueness validation, providing a better validation sequence.

packages/wasm-dpp/src/errors/consensus/consensus_error.rs (2)

64-64: Extended import list for error types.

The import list has been expanded to include new token and keyword validation error types that are now being handled in the conversion functions.


795-809: Added handlers for new error types.

Added conversion logic for the new error types to ensure proper JavaScript value conversion in the WebAssembly bindings:

  • InvalidKeywordCharacterError
  • InvalidTokenNameCharacterError
  • DecimalsOverLimitError
  • InvalidTokenNameLengthError
  • InvalidTokenLanguageCodeError

This ensures that the WebAssembly interface correctly exposes these validation errors.

packages/rs-dpp/src/errors/consensus/basic/data_contract/mod.rs (2)

31-31: Added new error module declarations.

Added module declarations for new error types related to token and keyword validation:

  • invalid_keyword_character_error
  • invalid_token_language_code_error
  • invalid_token_name_character_error
  • invalid_token_name_length_error
  • token_decimals_over_limit_error

Also applies to: 38-40, 46-46


92-92: Added public exports for new error types.

Added corresponding public exports for the new error modules, making them available for use in other parts of the codebase. This maintains the module's pattern of exporting all error types.

Also applies to: 99-101, 106-106

packages/rs-dpp/src/errors/consensus/codes.rs (1)

111-118: Added error codes for new validation error types.

Updated error codes and added new ones for the newly introduced validation errors:

  • InvalidDescriptionLengthError -> 10264
  • NewTokensDestinationIdentityOptionRequiredError -> 10265
  • InvalidTokenNameCharacterError -> 10266
  • InvalidTokenNameLengthError -> 10267
  • InvalidTokenLanguageCodeError -> 10268
  • InvalidKeywordCharacterError -> 10269
  • InvalidKeywordLengthError -> 10270
  • DecimalsOverLimitError -> 10271

These codes ensure that each error type has a unique identifier in the consensus system.

packages/rs-dpp/src/errors/consensus/basic/data_contract/invalid_token_language_code_error.rs (1)

30-34: Looks good – error is correctly wired into ConsensusError

Conversion into ConsensusError follows the existing pattern and will propagate cleanly through the consensus layer.

packages/rs-dpp/src/data_contract/associated_token/token_configuration_convention/accessors/mod.rs (1)

39-43: Return type update is consistent with type change elsewhere

Changing decimals() to return u8 aligns with the underlying struct’s refactor. No functional issues spotted.

packages/rs-dpp/src/errors/consensus/basic/data_contract/token_decimals_over_limit_error.rs (1)

1-44: Well-structured error type for decimal limit validation.

The implementation follows the standard error pattern in the codebase with all necessary traits, clear error messaging, and proper conversion to the general consensus error type. The use of u8 for decimal limits is appropriate since decimals are typically small values and this type provides sufficient range while being memory efficient.

packages/rs-dpp/src/errors/consensus/basic/data_contract/invalid_keyword_character_error.rs (1)

1-45: Well-implemented error type for keyword character validation.

The error type correctly captures both the contract ID and the problematic keyword, providing clear context in the error message about the validation requirements. The implementation follows the standard error pattern in the codebase with appropriate traits and conversion methods.

packages/rs-dpp/src/errors/consensus/basic/data_contract/invalid_token_name_character_error.rs (1)

1-41: Properly implemented error type for token name character validation.

The error correctly tracks both the form and token name with invalid characters, providing clear context in the error message. The implementation follows the established error pattern in the codebase with all necessary traits and conversion methods.

packages/rs-dpp/src/errors/consensus/basic/basic_error.rs (3)

11-17: Appropriate expansion of error imports.

The imports are correctly updated to include the new error types for token and keyword validation.


19-25: Good organization of related imports.

The new error types are properly grouped with related token validation imports, maintaining code organization and readability.


543-556: Well-structured error variant additions.

The new error variants for token and keyword validation are properly implemented:

  • Each variant uses #[error(transparent)] for correct error propagation
  • Naming follows established conventions in the codebase
  • Variants are added at the end of the enum, preserving compatibility

These additions align with the PR objective of improving error handling for decimal validation errors.

packages/rs-dpp/src/data_contract/associated_token/token_configuration_convention/v0/mod.rs (5)

1-3: Import updated to include new setter trait.

The import statement is correctly expanded to include both getter and setter traits.


39-39: Type refinement: u16 to u8 for decimals field.

The decimals field type change from u16 to u8 is appropriate since token decimal places are typically small values. This change aligns with the PR objective to improve decimal validation and is consistent with the relevant code changes in other files.


43-43: Default function return type updated.

The return type for default_decimals() is correctly updated to match the field type change.


87-87: Getter method return type updated.

The decimals() method return type is correctly changed to u8 to maintain consistency with the field type change.


92-103: Good addition of setter methods.

The implementation of TokenConfigurationConventionV0Setters trait with methods for modifying localizations and decimals is well-structured and follows established patterns in the codebase. This addition improves the API without breaking existing functionality.

@QuantumExplorer QuantumExplorer added this to the v2.0.0 milestone May 7, 2025
@QuantumExplorer QuantumExplorer changed the title feat(drive-abci): improve localization validation feat(drive-abci): improve token name localization validation May 7, 2025
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: 0

♻️ Duplicate comments (1)
packages/rs-dpp/src/data_contract/associated_token/token_configuration_convention/methods/validate_localizations/v0/mod.rs (1)

97-101: Fixed parameter in error constructor

The correct parameter language.len() is now used in the InvalidTokenNameLengthError constructor, which addresses a previously identified issue. This ensures that error messages correctly reflect the actual length of the language code.

🧹 Nitpick comments (1)
packages/rs-dpp/src/data_contract/associated_token/token_configuration_convention/methods/validate_localizations/v0/mod.rs (1)

38-108: Consider refactoring duplicate validation logic

The validation logic for singular and plural forms contains nearly identical code blocks. Consider extracting this into a helper method to reduce duplication.

 impl TokenConfigurationConvention {
     #[inline(always)]
     pub(super) fn validate_localizations_v0(&self) -> SimpleConsensusValidationResult {
         // ... existing code ...
+        
+        fn validate_token_name(name: &str, form_type: &str) -> Option<Box<dyn anyhow::Error>> {
+            if !name.chars().all(|c| !c.is_control() && !c.is_whitespace()) {
+                return Some(
+                    InvalidTokenNameCharacterError::new(
+                        form_type.to_string(),
+                        name.to_string(),
+                    )
+                    .into(),
+                );
+            }
+            
+            if name.len() < 3 || name.len() > 25 {
+                return Some(
+                    InvalidTokenNameLengthError::new(name.len(), 3, 25, form_type)
+                        .into(),
+                );
+            }
+            
+            None
+        }
 
         for (language, localization) in self.localizations() {
             let singular_form = localization.singular_form();
             let plural_form = localization.plural_form();
 
-            if !singular_form
-                .chars()
-                .all(|c| !c.is_control() && !c.is_whitespace())
-            {
-                // This would mean we have an invalid character
-                return SimpleConsensusValidationResult::new_with_error(
-                    InvalidTokenNameCharacterError::new(
-                        "singular form".to_string(),
-                        singular_form.to_string(),
-                    )
-                    .into(),
-                );
-            }
-
-            if !plural_form
-                .chars()
-                .all(|c| !c.is_control() && !c.is_whitespace())
-            {
-                // This would mean we have an invalid character
-                return SimpleConsensusValidationResult::new_with_error(
-                    InvalidTokenNameCharacterError::new(
-                        "plural form".to_string(),
-                        plural_form.to_string(),
-                    )
-                    .into(),
-                );
-            }
+            if let Some(err) = validate_token_name(singular_form, "singular form") {
+                return SimpleConsensusValidationResult::new_with_error(err);
+            }
+            
+            if let Some(err) = validate_token_name(plural_form, "plural form") {
+                return SimpleConsensusValidationResult::new_with_error(err);
+            }
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 8d09bad and 67e62b0.

📒 Files selected for processing (5)
  • packages/rs-dpp/src/data_contract/associated_token/token_configuration_convention/methods/validate_localizations/v0/mod.rs (2 hunks)
  • packages/rs-dpp/src/data_contract/methods/validate_update/v0/mod.rs (3 hunks)
  • packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/data_contract_create/mod.rs (2 hunks)
  • packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/data_contract_update/mod.rs (3 hunks)
  • packages/rs-drive/src/drive/votes/resolved/vote_polls/contested_document_resource_vote_poll/resolve.rs (1 hunks)
✅ Files skipped from review due to trivial changes (1)
  • packages/rs-drive/src/drive/votes/resolved/vote_polls/contested_document_resource_vote_poll/resolve.rs
🚧 Files skipped from review as they are similar to previous changes (1)
  • packages/rs-dpp/src/data_contract/methods/validate_update/v0/mod.rs
🧰 Additional context used
🧠 Learnings (1)
📓 Common learnings
Learnt from: QuantumExplorer
PR: dashpay/platform#2257
File: packages/rs-drive-abci/src/mimic/test_quorum.rs:159-164
Timestamp: 2024-11-20T16:16:01.830Z
Learning: QuantumExplorer prefers not to receive auto-generated messages asking to post on social media.
🧬 Code Graph Analysis (1)
packages/rs-dpp/src/data_contract/associated_token/token_configuration_convention/methods/validate_localizations/v0/mod.rs (4)
packages/rs-dpp/src/errors/consensus/basic/data_contract/invalid_token_language_code_error.rs (1)
  • new (21-23)
packages/rs-dpp/src/errors/consensus/basic/data_contract/invalid_token_name_character_error.rs (1)
  • new (24-26)
packages/rs-dpp/src/errors/consensus/basic/data_contract/invalid_token_name_length_error.rs (1)
  • new (26-33)
packages/rs-dpp/src/errors/consensus/basic/data_contract/token_decimals_over_limit_error.rs (1)
  • new (24-29)
⏰ Context from checks skipped due to timeout of 90000ms (20)
  • GitHub Check: Rust packages (drive-abci) / Check each feature
  • GitHub Check: Rust packages (dash-sdk) / Detect immutable structure changes
  • GitHub Check: Rust packages (dash-sdk) / Linting
  • GitHub Check: Rust packages (dash-sdk) / Formatting
  • GitHub Check: Rust packages (dpp) / Check each feature
  • GitHub Check: Rust packages (drive) / Tests
  • GitHub Check: Rust packages (dash-sdk) / Unused dependencies
  • 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 (wasm-dpp) / Unused dependencies
  • GitHub Check: Rust packages (wasm-dpp) / Tests
  • GitHub Check: Rust packages (wasm-dpp) / Linting
  • 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 Docker images (DAPI, dapi, dapi) / Build DAPI image
  • GitHub Check: Build JS packages / Build JS
  • GitHub Check: Rust crates security audit
🔇 Additional comments (11)
packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/data_contract_create/mod.rs (2)

3349-3349: LGTM: Updated test reflects new keyword limit of 50

This test function name clearly indicates it's testing the new 50 keyword limit as mentioned in the PR.


3377-3377: Appropriate test case for validating the new limit

Test correctly creates 51 keywords to verify that the system rejects contracts exceeding the 50 keyword limit (previously 20).

packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/data_contract_update/mod.rs (5)

2499-2501: Change correctly implements increased keyword limit from 20 to 50.

The test case has been updated to test the new maximum keyword limit of 50 by adding keywords "kw21" through "kw50". This aligns with the PR's changes to increase the maximum allowed keywords in data contracts.


2572-2572: Updated test case to expect lowercase keywords.

This change correctly accounts for the new behavior where keywords are converted to lowercase during deserialization, ensuring tests align with the implementation.


2581-2583: Updated assertions to match lowercase keyword expectations.

These assertion changes correctly verify that the lowercase versions of keywords ("newa", "newb", "newc") are stored in the database, consistent with the lowercase conversion during deserialization.


1213-1220: All imports look good for token configuration validation.

The imports related to token configuration and validation are properly structured to support the enhanced token name localization validation described in the PR objectives.


1731-1824: Test case properly validates token localization requirements.

This test correctly verifies that tokens must have valid localizations, which aligns with the PR objective of enhancing validation for token localizations. The test specifically checks that empty localization maps are rejected.

packages/rs-dpp/src/data_contract/associated_token/token_configuration_convention/methods/validate_localizations/v0/mod.rs (4)

1-4: Good error import organization

The imports are well-structured, clearly identifying the specific error types needed for token validation.


10-15: Well-implemented BCP 47 regex pattern

Using once_cell::Lazy ensures the regex is compiled only once, which is efficient. The pattern correctly implements the BCP 47 language tag format with appropriate segments for language, script, region, variant, extension, and private use.


31-36: Good implementation of decimals limit validation

The 16 decimal limit is properly enforced with an appropriate error message containing both the actual and maximum allowed values.


103-107: Comprehensive language code validation

The implementation properly validates language codes against the BCP 47 standard using the pre-compiled regex pattern. The error message includes the invalid language code for easier debugging.

@QuantumExplorer
Copy link
Member Author

Self Reviewed

@QuantumExplorer QuantumExplorer merged commit ee8c09d into v2.0-dev May 7, 2025
122 of 124 checks passed
@QuantumExplorer QuantumExplorer deleted the fixdecimal-validation-errors branch May 7, 2025 16:49
@thephez
Copy link
Collaborator

thephez commented May 7, 2025

This is technically a breaking change due to tightening some constrains (e.g., token name length), correct?

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