Skip to content

fix(platform): ensure document types only target valid tokens for token payments #2631

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 9 commits into from
May 23, 2025

Conversation

QuantumExplorer
Copy link
Member

@QuantumExplorer QuantumExplorer commented May 23, 2025

Issue being fixed or feature implemented

Document types were allowing invalid tokens for token payments, which could lead to errors during validation.

What was done?

Updated the logic in the document type methods to ensure that only valid tokens are targeted for token payments. This involved modifying the create_document_types_from_document_schemas methods to include token configuration checks and updating related error handling for invalid token positions.

How Has This Been Tested?

Changes have been validated through existing unit tests, which were updated to cover new scenarios involving token configurations.

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

For repository code-owners and collaborators only

  • I have assigned this pull request to a milestone

Summary by CodeRabbit

  • New Features

    • Improved validation for token positions in document schemas, providing clearer error messages when invalid token positions are encountered.
    • Extended schema creation and validation to incorporate token configuration data from data contracts.
    • Added a new error type for redundant contractId usage in documents paid by tokens, enhancing error reporting.
    • Introduced validation for external token costs in data contract create and update transitions, ensuring referenced tokens and contracts exist.
    • Added new getters to access all document token costs and external token contract tokens.
  • Bug Fixes

    • Enhanced error handling to account for optional maximum token positions in validation errors.
  • Refactor

    • Updated method signatures to accept token configuration data for more robust schema validation.
    • Simplified internal logic for retrieving token positions.
  • Chores

    • Adjusted internal method calls and imports to support new token validation logic.
    • Updated tests and deserialization logic to include token configuration parameters.
    • Added new error variant support in consensus error handling and SDK bindings.

Copy link
Contributor

coderabbitai bot commented May 23, 2025

Caution

Review failed

The pull request is closed.

"""

Walkthrough

This change updates the document type creation and schema parsing logic to include a new token_configurations parameter, affecting several method signatures and internal calls. The update ensures that token configuration data is passed through all relevant document type creation and validation functions, and adds validation for token positions using this new parameter. It also introduces new consensus errors related to token position validity and redundant token contract IDs, with corresponding state transition validations for data contract creation and update. Additionally, new getter methods for token costs and related token contract tokens are added to document type accessors.

Changes

File(s) Change Summary
.../create_document_types_from_document_schemas/mod.rs, v0/mod.rs, v1/mod.rs Updated method signatures for create_document_types_from_document_schemas (and its versioned variants) to include a token_configurations parameter; adjusted imports and internal calls accordingly.
.../try_from_schema/mod.rs, v1/mod.rs Added token_configurations parameter to try_from_schema methods; added validation to check token positions against provided configurations; updated tests to supply empty maps where needed.
.../v0/methods/schema.rs, v1/methods/schema.rs Updated calls to create_document_types_from_document_schemas and try_from_schema to pass appropriate token configuration references (BTreeMap::new() or self.tokens).
.../v0/serialization/mod.rs, v1/serialization/mod.rs Added BTreeMap import; updated serialization methods to pass token configuration maps in document type creation.
.../errors/consensus/basic/token/invalid_token_position_error.rs Changed max_token_position in InvalidTokenPositionError from mandatory to optional; updated constructor, getter, and error message formatting.
.../state_transitions/batch/action_validation/token/token_base_transition_action/structure_v0/mod.rs Simplified retrieval of the last token key using .last().copied() for error construction.
strategy-tests/src/operations.rs Updated deserialization to pass contract tokens to try_from_schema; added necessary trait import.
.../serialized_version/mod.rs Cleaned up duplicate import of EMPTY_KEYWORDS; no logic changes.
.../query/test_index.rs Added passing an empty BTreeMap argument to try_from_schema calls in test setup.
.../data_contract/document_type/methods/validate_update/v0/mod.rs Added empty BTreeMap argument to try_from_schema calls in test code; added import of BTreeMap.
.../util/json_schema.rs Added empty BTreeMap argument to try_from_schema call in test; added import of BTreeMap.
.../errors/consensus/basic/basic_error.rs, data_contract/mod.rs, data_contract/redundant_document_paid_for_by_token_with_contract_id.rs, codes.rs, wasm-dpp/src/errors/consensus/consensus_error.rs Added new error type RedundantDocumentPaidForByTokenWithContractId with appropriate error handling, conversion, and error code assignment; integrated into consensus error hierarchy.
.../errors/consensus/state/data_contract/data_contract_not_found_error.rs, state/data_contract/mod.rs, state/state_error.rs Added new error type DataContractNotFoundError with constructor, getter, and conversion to consensus error; integrated into state error enum and exports.
.../errors/consensus/state/token/invalid_token_position_error.rs, state/token/mod.rs, state/state_error.rs Added new error type InvalidTokenPositionStateError with fields, constructor, getters, and consensus error conversion; integrated into state error enum and exports.
.../data_contract/document_type/accessors/mod.rs, accessors/v1/mod.rs, v1/accessors.rs Added new getter methods to DocumentTypeV1Getters trait and implementations to retrieve all document token costs and external token contract tokens.
.../data_contract/document_type/token_costs/accessors.rs, token_costs/mod.rs, token_costs/v0/mod.rs Extended TokenCostGettersV0 trait and implementations with reference-returning getter methods for document token costs for various actions.
packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/data_contract_create/mod.rs Added tests for data contract creation with invalid external token references and invalid token positions, asserting appropriate consensus errors.
packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/data_contract_create/state/v0/mod.rs Added validation in data contract create state transition to verify existence of external contracts and validity of token positions in external token costs; returns errors and bumps nonce on failure.
packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/data_contract_update/state/v0/mod.rs Added validation in data contract update state transition to verify existence of external contracts and validity of token positions in external token costs; returns errors and bumps nonce on failure.

Sequence Diagram(s)

sequenceDiagram
    participant Caller
    participant DocumentType
    participant TokenConfigMap
    participant SchemaValidator

    Caller->>DocumentType: create_document_types_from_document_schemas(..., &token_configurations, ...)
    DocumentType->>DocumentType: create_document_types_from_document_schemas_v0/v1(..., &token_configurations, ...)
    loop For each schema
        DocumentType->>DocumentType: try_from_schema(..., &token_configurations, ...)
        DocumentType->>SchemaValidator: Validate schema, check token positions via token_configurations
        SchemaValidator-->>DocumentType: Return validation result or error
    end
    DocumentType-->>Caller: Return created DocumentTypes or error
Loading

Possibly related PRs

  • dashpay/platform#2583: Adds validation of identities referenced in token configurations during data contract creation and update, related to token configuration handling.
  • dashpay/platform#2517: Introduces token payment info features and modifies document transition actions, aligning with this PR’s token configuration handling changes.
  • dashpay/platform#2439: Modifies token configuration and validation mechanisms in data contracts, directly related to token configuration parameter integration.

Poem

🐇 Through schemas deep and tokens bright,
I hop and check with all my might.
Positions mapped, no errors near,
Document types now crystal clear.
With configs held in tidy rows,
The rabbit’s work forever grows!
🌿✨
"""


📜 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 cbdffc1 and 0685362.

📒 Files selected for processing (1)
  • packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/data_contract_update/state/v0/mod.rs (3 hunks)
✨ 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.
    • Explain this complex logic.
    • 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 explain this code block.
    • @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 explain its main purpose.
    • @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: ensure document types only target valid tokens for token payments fix(dpp): ensure document types only target valid tokens for token payments May 23, 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

🔭 Outside diff range comments (1)
packages/rs-dpp/src/data_contract/document_type/class_methods/try_from_schema/mod.rs (1)

59-68: 💡 Verification agent

🧩 Analysis chain

Verify: Version 0 implementation missing token_configurations parameter

The token_configurations parameter is passed to version 1 implementation but not to version 0. This creates inconsistent behavior between versions.

If version 0 should support token configurations, this is a bug. If not, consider adding a comment explaining why version 0 doesn't need this parameter.


🏁 Script executed:

#!/bin/bash
# Check if DocumentTypeV0::try_from_schema accepts token_configurations parameter
ast-grep --pattern 'impl DocumentTypeV0 {
  $$$
  fn try_from_schema($$$) {
    $$$
  }
  $$$
}'

Length of output: 98


I’ll locate and compare the try_from_schema signatures for both v0 and v1 to confirm whether token_configurations is expected by v0.


🏁 Script executed:

#!/bin/bash
set -e

echo "Files under try_from_schema/:"
fd -e rs -d 1 packages/rs-dpp/src/data_contract/document_type/class_methods/try_from_schema

echo -e "\nAll try_from_schema definitions with context:"
rg -n 'fn try_from_schema' -C2 packages/rs-dpp/src/data_contract/document_type/class_methods/try_from_schema

Length of output: 785


Inspecting both version implementations to confirm their signatures:


🏁 Script executed:

#!/bin/bash
set -e

echo "Files in try_from_schema/:"
find packages/rs-dpp/src/data_contract/document_type/class_methods/try_from_schema -maxdepth 1 -type f

echo -e "\n--- v0 signature ---"
rg -n "fn try_from_schema" -C3 packages/rs-dpp/src/data_contract/document_type/class_methods/try_from_schema/v0.rs

echo -e "\n--- v1 signature ---"
rg -n "fn try_from_schema" -C3 packages/rs-dpp/src/data_contract/document_type/class_methods/try_from_schema/v1.rs

Length of output: 559


To locate where the v0/v1 implementations live and inspect their signatures:


🏁 Script executed:

#!/bin/bash
set -e

echo "Subdirectories under try_from_schema:"
find packages/rs-dpp/src/data_contract/document_type/class_methods/try_from_schema -maxdepth 1 -type d

echo -e "\n--- v0 implementation signature ---"
if [ -d packages/rs-dpp/src/data_contract/document_type/class_methods/try_from_schema/v0 ]; then
  rg -n "fn try_from_schema" -C3 packages/rs-dpp/src/data_contract/document_type/class_methods/try_from_schema/v0
else
  echo "No v0 directory found"
fi

echo -e "\n--- v1 implementation signature ---"
if [ -d packages/rs-dpp/src/data_contract/document_type/class_methods/try_from_schema/v1 ]; then
  rg -n "fn try_from_schema" -C3 packages/rs-dpp/src/data_contract/document_type/class_methods/try_from_schema/v1
else
  echo "No v1 directory found"
fi

Length of output: 2764


Gathering full try_from_schema signatures for both versions:


🏁 Script executed:

#!/bin/bash
set -e

echo "--- v0 signature ---"
rg -n "pub(super) fn try_from_schema" -A15 packages/rs-dpp/src/data_contract/document_type/class_methods/try_from_schema/v0/mod.rs

echo -e "\n--- v1 signature ---"
rg -n "pub(super) fn try_from_schema" -A15 packages/rs-dpp/src/data_contract/document_type/class_methods/try_from_schema/v1/mod.rs

Length of output: 192


Inspecting the function signatures directly from the source:


🏁 Script executed:

#!/bin/bash
set -e

echo "--- v0 signature (lines 55–90) ---"
sed -n '55,90p' packages/rs-dpp/src/data_contract/document_type/class_methods/try_from_schema/v0/mod.rs

echo -e "\n--- v1 signature (lines 70–110) ---"
sed -n '70,110p' packages/rs-dpp/src/data_contract/document_type/class_methods/try_from_schema/v1/mod.rs

Length of output: 3566


Version 0 try_from_schema missing token_configurations
Version 1’s try_from_schema takes a token_configurations: &BTreeMap<TokenContractPosition, TokenConfiguration> argument, but version 0’s signature does not—leading to inconsistent behavior between versions.

Please choose one of the following fixes:
• If v0 should also accept token configurations, update its signature and dispatch call to include
token_configurations, and add #[allow(unused_variables)] to ignore it in v0’s implementation.
• If token support was introduced in v1 on purpose, add a comment in v0’s impl (or above the v0 arm in mod.rs) clarifying that tokens are unsupported in v0.

Locations to update:

  • packages/rs-dpp/src/data_contract/document_type/class_methods/try_from_schema/v0/mod.rs (function signature)
  • packages/rs-dpp/src/data_contract/document_type/class_methods/try_from_schema/mod.rs (v0 arm in the version dispatch)
🧹 Nitpick comments (1)
packages/rs-dpp/src/data_contract/document_type/class_methods/try_from_schema/v1/mod.rs (1)

704-704: Test updates correctly handle the new parameter.

All test calls have been appropriately updated to pass &BTreeMap::new() for the token_configurations parameter. Using an empty map is correct for these tests since they don't involve token validation scenarios.

Consider adding dedicated tests for token position validation scenarios:

#[test]
fn should_validate_token_position_exists() {
    let platform_version = PlatformVersion::latest();
    let mut token_configurations = BTreeMap::new();
    token_configurations.insert(0, TokenConfiguration::default());
    
    let schema = platform_value!({
        "type": "object",
        "properties": {
            "name": {
                "type": "string",
                "position": 0
            }
        },
        "tokenCost": {
            "create": {
                "tokenPosition": 0,
                "amount": 100
            }
        },
        "additionalProperties": false
    });

    let config = DataContractConfig::default_for_version(platform_version)
        .expect("should create a default config");

    let result = DocumentTypeV1::try_from_schema(
        Identifier::new([1; 32]),
        "test_type",
        schema,
        None,
        &token_configurations,
        &config,
        true,
        &mut vec![],
        platform_version,
    );

    assert!(result.is_ok());
}

#[test]
fn should_fail_with_invalid_token_position() {
    let platform_version = PlatformVersion::latest();
    let token_configurations = BTreeMap::new(); // Empty map
    
    let schema = platform_value!({
        "type": "object",
        "properties": {
            "name": {
                "type": "string",
                "position": 0
            }
        },
        "tokenCost": {
            "create": {
                "tokenPosition": 999, // Invalid position
                "amount": 100
            }
        },
        "additionalProperties": false
    });

    let config = DataContractConfig::default_for_version(platform_version)
        .expect("should create a default config");

    let result = DocumentTypeV1::try_from_schema(
        Identifier::new([1; 32]),
        "test_type",
        schema,
        None,
        &token_configurations,
        &config,
        true,
        &mut vec![],
        platform_version,
    );

    assert_matches!(
        result,
        Err(ProtocolError::ConsensusError(boxed)) => {
            assert_matches!(
                boxed.as_ref(),
                ConsensusError::BasicError(
                    BasicError::InvalidTokenPositionError(_)
                )
            )
        }
    );
}

Also applies to: 736-736, 779-779, 848-848

📜 Review details

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

📥 Commits

Reviewing files that changed from the base of the PR and between fa5203c and 603679e.

📒 Files selected for processing (13)
  • packages/rs-dpp/src/data_contract/document_type/class_methods/create_document_types_from_document_schemas/mod.rs (3 hunks)
  • packages/rs-dpp/src/data_contract/document_type/class_methods/create_document_types_from_document_schemas/v0/mod.rs (3 hunks)
  • packages/rs-dpp/src/data_contract/document_type/class_methods/create_document_types_from_document_schemas/v1/mod.rs (2 hunks)
  • packages/rs-dpp/src/data_contract/document_type/class_methods/try_from_schema/mod.rs (3 hunks)
  • packages/rs-dpp/src/data_contract/document_type/class_methods/try_from_schema/v1/mod.rs (8 hunks)
  • packages/rs-dpp/src/data_contract/serialized_version/mod.rs (1 hunks)
  • packages/rs-dpp/src/data_contract/v0/methods/schema.rs (2 hunks)
  • packages/rs-dpp/src/data_contract/v0/serialization/mod.rs (3 hunks)
  • packages/rs-dpp/src/data_contract/v1/methods/schema.rs (3 hunks)
  • packages/rs-dpp/src/data_contract/v1/serialization/mod.rs (3 hunks)
  • packages/rs-dpp/src/errors/consensus/basic/token/invalid_token_position_error.rs (2 hunks)
  • packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/action_validation/token/token_base_transition_action/structure_v0/mod.rs (1 hunks)
  • packages/strategy-tests/src/operations.rs (2 hunks)
🧰 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.
⏰ Context from checks skipped due to timeout of 90000ms (19)
  • GitHub Check: Rust packages (drive-abci) / Tests
  • GitHub Check: Rust packages (drive) / Tests
  • GitHub Check: Rust packages (drive) / Unused dependencies
  • GitHub Check: Rust packages (drive) / Linting
  • GitHub Check: Rust packages (wasm-dpp) / Linting
  • GitHub Check: Rust packages (wasm-dpp) / Formatting
  • GitHub Check: Rust packages (wasm-dpp) / Tests
  • GitHub Check: Rust packages (dpp) / Check each feature
  • GitHub Check: Rust packages (dpp) / Tests
  • GitHub Check: Rust packages (dpp) / Unused dependencies
  • GitHub Check: Rust packages (dpp) / Linting
  • GitHub Check: Rust packages (dash-sdk) / Tests
  • GitHub Check: Rust packages (dash-sdk) / Linting
  • GitHub Check: Rust packages (dash-sdk) / Check each feature
  • GitHub Check: Build Docker images (DAPI, dapi, dapi) / Build DAPI image
  • GitHub Check: Build Docker images (Dashmate helper, dashmate-helper, dashmate-helper) / Build Dashmate helper image
  • GitHub Check: Build Docker images (Drive, drive, drive-abci) / Build Drive image
  • GitHub Check: Build JS packages / Build JS
  • GitHub Check: Rust crates security audit
🔇 Additional comments (26)
packages/rs-dpp/src/data_contract/serialized_version/mod.rs (1)

9-9: LGTM: Clean import organization.

The reorganization of the EMPTY_KEYWORDS import improves code organization and aligns with the broader changes involving BTreeMap usage for token configurations.

packages/rs-dpp/src/data_contract/v0/serialization/mod.rs (2)

8-8: LGTM: Appropriate import addition.

The BTreeMap import is correctly added to support the new token configuration parameter in document type creation methods.


98-98: LGTM: Correct handling of token configurations for v0 contracts.

Passing an empty BTreeMap for token configurations is appropriate for v0 contracts since they don't support tokens. This maintains backward compatibility while integrating with the new token-aware document type creation API.

Also applies to: 139-139

packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/action_validation/token/token_base_transition_action/structure_v0/mod.rs (1)

35-35: LGTM: Cleaner token key retrieval.

The use of .last().copied() is more concise and safer than explicit dereferencing with expect. This change aligns well with the broader improvements to token position handling and the optional nature of max_token_position in error scenarios.

packages/strategy-tests/src/operations.rs (2)

4-4: LGTM: Necessary import for token access.

The import of DataContractV1Getters is required to access the tokens() method used in the document type deserialization process.


434-434: LGTM: Proper token configuration integration in tests.

Adding contract.tokens() as a parameter to DocumentType::try_from_schema correctly integrates token configuration validation into the test deserialization process. This ensures that token-related validations are properly exercised during document type reconstruction in strategy tests.

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

7-7: LGTM!

The BTreeMap import is correctly added to support the new token configuration parameter.


97-97: Correct implementation for v0 compatibility.

Passing an empty BTreeMap for v0 data contracts is appropriate since version 0 doesn't support tokens. This maintains backward compatibility while integrating with the new token validation system.


156-156: Proper token configuration integration for v1.

Correctly passes the actual tokens from the v1 data contract for validation. The logic appropriately uses the tokens for document type creation when they're available.

packages/rs-dpp/src/data_contract/v1/methods/schema.rs (2)

25-25: Correct token configuration integration.

Properly passes the tokens from the data contract to enable token validation during document type creation from schemas.


49-49: Consistent token configuration passing.

Using self.tokens() method call is appropriate for single document schema operations and maintains consistency with the token validation system.

packages/rs-dpp/src/data_contract/v0/methods/schema.rs (2)

25-25: Appropriate v0 compatibility handling.

Using an empty BTreeMap for v0 data contracts is correct since version 0 doesn't support tokens. This maintains backward compatibility with the existing v0 behavior.


49-49: Consistent v0 token handling.

Correctly passes an empty token configuration map for single document schema operations in v0, maintaining consistency with the v0 design that doesn't include token support.

packages/rs-dpp/src/errors/consensus/basic/token/invalid_token_position_error.rs (4)

13-19: Well-designed conditional error message formatting.

The error message formatting correctly handles both cases - when a maximum token position is set and when it's not. The conditional logic using if let Some(max) is clear and provides appropriate messages for both scenarios.


22-22: Appropriate field type change.

Making max_token_position optional provides the necessary flexibility for cases where no maximum token position limit is defined, which aligns with the enhanced token validation system.


27-35: Constructor correctly updated for optional field.

The constructor properly accepts an optional max_token_position parameter and initializes the struct consistently. This maintains the API's usability while supporting the new optional behavior.


37-39: Getter properly returns optional type.

The getter method correctly returns Option<TokenContractPosition> to match the updated field type, maintaining consistency throughout the API.

packages/rs-dpp/src/data_contract/document_type/class_methods/try_from_schema/mod.rs (1)

8-8: LGTM: Token configuration integration looks good

The addition of token configuration support to the schema parsing is well implemented. The parameter is properly typed and threaded through the API.

Also applies to: 46-46, 75-75

packages/rs-dpp/src/data_contract/document_type/class_methods/create_document_types_from_document_schemas/v0/mod.rs (2)

12-12: LGTM: Clean integration of token configurations

The implementation correctly:

  • Moves from DocumentTypeV0 to DocumentType
  • Adds the token_configurations parameter to the method signature
  • Passes it through to the try_from_schema call

This maintains consistency with the API evolution across versions.

Also applies to: 17-17, 43-43


88-88: Good test update for backward compatibility

The test correctly passes an empty BTreeMap for the new token_configurations parameter, maintaining backward compatibility while testing the new signature.

packages/rs-dpp/src/data_contract/document_type/class_methods/create_document_types_from_document_schemas/mod.rs (2)

6-6: LGTM: Consistent API evolution

The addition of token_configurations parameter to the main entry point method is well-designed and maintains consistency across the document type creation API.

Also applies to: 42-42


56-77: Good refactoring: Consolidated version handling

The change from DocumentTypeV0:: and DocumentTypeV1:: to DocumentType:: for both versions simplifies the API and consolidates version handling. The token_configurations parameter is correctly passed to both version implementations.

packages/rs-dpp/src/data_contract/document_type/class_methods/create_document_types_from_document_schemas/v1/mod.rs (1)

12-12: LGTM: Consistent v1 implementation

The changes mirror the v0 implementation perfectly:

  • Moves from DocumentTypeV0 to DocumentType
  • Adds the token_configurations parameter
  • Passes it through to try_from_schema

This maintains consistency across all version implementations.

Also applies to: 18-18, 45-45

packages/rs-dpp/src/data_contract/document_type/class_methods/try_from_schema/v1/mod.rs (3)

35-35: LGTM: Appropriate imports added for token validation.

The new imports for InvalidTokenPositionError, TokenConfiguration, and TokenContractPosition are necessary for implementing the token position validation functionality.

Also applies to: 60-60


582-594: Well-implemented token position validation logic.

The validation correctly:

  • Only runs under full_validation and validation feature flag
  • Checks if the token position exists in the provided configurations
  • Returns an appropriate error with context (last valid position and invalid position)
  • Uses last_key_value() to get the maximum valid position for error reporting

The error construction provides helpful context for debugging invalid token positions.


82-82:

✅ Verification successful

Breaking change: Method signature updated with token configurations parameter.

The addition of the token_configurations parameter is a breaking change but aligns with the PR objectives to ensure document types only target valid tokens. The parameter type &BTreeMap<TokenContractPosition, TokenConfiguration> is appropriate for efficient lookups during validation.

Verify that all callers of this method have been updated to provide the token configurations parameter:


🏁 Script executed:

#!/bin/bash
# Description: Find all calls to DocumentTypeV1::try_from_schema to ensure they've been updated
# Expected: All calls should include the new token_configurations parameter

rg -A 10 "DocumentTypeV1::try_from_schema" --type rust

Length of output: 6570


Confirmed: All try_from_schema invocations updated
I’ve verified that every call to DocumentTypeV1::try_from_schema now includes the new token_configurations: &BTreeMap<TokenContractPosition, TokenConfiguration> argument. No further changes are required.

@QuantumExplorer QuantumExplorer added this to the v2.0.0 milestone May 23, 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

🧹 Nitpick comments (2)
packages/wasm-dpp/src/errors/consensus/consensus_error.rs (1)

64-64: Consider breaking up the long import line for better readability.

While the import follows the existing pattern, the line is quite long. Consider splitting it into multiple lines for improved maintainability.

-use dpp::consensus::basic::data_contract::{ContestedUniqueIndexOnMutableDocumentTypeError, ContestedUniqueIndexWithUniqueIndexError, DataContractTokenConfigurationUpdateError, DecimalsOverLimitError, DuplicateKeywordsError, GroupExceedsMaxMembersError, GroupMemberHasPowerOfZeroError, GroupMemberHasPowerOverLimitError, GroupNonUnilateralMemberPowerHasLessThanRequiredPowerError, GroupPositionDoesNotExistError, GroupRequiredPowerIsInvalidError, GroupTotalPowerLessThanRequiredError, InvalidDescriptionLengthError, InvalidDocumentTypeRequiredSecurityLevelError, InvalidKeywordCharacterError, InvalidKeywordLengthError, InvalidTokenBaseSupplyError, InvalidTokenDistributionFunctionDivideByZeroError, InvalidTokenDistributionFunctionIncoherenceError, InvalidTokenDistributionFunctionInvalidParameterError, InvalidTokenDistributionFunctionInvalidParameterTupleError, InvalidTokenLanguageCodeError, InvalidTokenNameCharacterError, InvalidTokenNameLengthError, MainGroupIsNotDefinedError, NewTokensDestinationIdentityOptionRequiredError, NonContiguousContractGroupPositionsError, NonContiguousContractTokenPositionsError, RedundantDocumentPaidForByTokenWithContractId, TokenPaymentByBurningOnlyAllowedOnInternalTokenError, TooManyKeywordsError, UnknownDocumentActionTokenEffectError, UnknownDocumentCreationRestrictionModeError, UnknownGasFeesPaidByError, UnknownSecurityLevelError, UnknownStorageKeyRequirementsError, UnknownTradeModeError, UnknownTransferableTypeError};
+use dpp::consensus::basic::data_contract::{
+    ContestedUniqueIndexOnMutableDocumentTypeError, ContestedUniqueIndexWithUniqueIndexError,
+    DataContractTokenConfigurationUpdateError, DecimalsOverLimitError, DuplicateKeywordsError,
+    GroupExceedsMaxMembersError, GroupMemberHasPowerOfZeroError, GroupMemberHasPowerOverLimitError,
+    GroupNonUnilateralMemberPowerHasLessThanRequiredPowerError, GroupPositionDoesNotExistError,
+    GroupRequiredPowerIsInvalidError, GroupTotalPowerLessThanRequiredError,
+    InvalidDescriptionLengthError, InvalidDocumentTypeRequiredSecurityLevelError,
+    InvalidKeywordCharacterError, InvalidKeywordLengthError, InvalidTokenBaseSupplyError,
+    InvalidTokenDistributionFunctionDivideByZeroError, InvalidTokenDistributionFunctionIncoherenceError,
+    InvalidTokenDistributionFunctionInvalidParameterError, InvalidTokenDistributionFunctionInvalidParameterTupleError,
+    InvalidTokenLanguageCodeError, InvalidTokenNameCharacterError, InvalidTokenNameLengthError,
+    MainGroupIsNotDefinedError, NewTokensDestinationIdentityOptionRequiredError,
+    NonContiguousContractGroupPositionsError, NonContiguousContractTokenPositionsError,
+    RedundantDocumentPaidForByTokenWithContractId, TokenPaymentByBurningOnlyAllowedOnInternalTokenError,
+    TooManyKeywordsError, UnknownDocumentActionTokenEffectError, UnknownDocumentCreationRestrictionModeError,
+    UnknownGasFeesPaidByError, UnknownSecurityLevelError, UnknownStorageKeyRequirementsError,
+    UnknownTradeModeError, UnknownTransferableTypeError
+};
packages/rs-dpp/src/errors/consensus/basic/data_contract/redundant_document_paid_for_by_token_with_contract_id.rs (1)

9-16: Consider including contract_id in error message for better debugging.

The error struct is well-implemented with appropriate derives and a clear message. Consider enhancing the error message to include the contract_id value for improved debugging experience.

-#[error("Document paid for by a token has a contractId {contract_id} set, which is redundant because it is targeting the current contract")]
+#[error("Document paid for by a token has a contractId {contract_id} set, which is redundant because it is targeting the current contract")]

The current placeholder {contract_id} should automatically display the field value when the error is formatted.

📜 Review details

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

📥 Commits

Reviewing files that changed from the base of the PR and between cdf70dd and f2dba50.

📒 Files selected for processing (7)
  • packages/rs-dpp/src/data_contract/document_type/class_methods/try_from_schema/v1/mod.rs (10 hunks)
  • packages/rs-dpp/src/errors/consensus/basic/basic_error.rs (2 hunks)
  • packages/rs-dpp/src/errors/consensus/basic/data_contract/mod.rs (2 hunks)
  • packages/rs-dpp/src/errors/consensus/basic/data_contract/redundant_document_paid_for_by_token_with_contract_id.rs (1 hunks)
  • packages/rs-dpp/src/errors/consensus/codes.rs (1 hunks)
  • packages/rs-sdk/tests/fetch/common.rs (2 hunks)
  • packages/wasm-dpp/src/errors/consensus/consensus_error.rs (2 hunks)
✅ Files skipped from review due to trivial changes (1)
  • packages/rs-dpp/src/errors/consensus/basic/data_contract/mod.rs
🚧 Files skipped from review as they are similar to previous changes (1)
  • packages/rs-dpp/src/data_contract/document_type/class_methods/try_from_schema/v1/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.
⏰ Context from checks skipped due to timeout of 90000ms (20)
  • 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) / Unused dependencies
  • GitHub Check: Rust packages (drive-abci) / Linting
  • 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) / Linting
  • GitHub Check: Rust packages (drive) / Unused dependencies
  • GitHub Check: Rust packages (drive) / Tests
  • GitHub Check: Rust packages (drive) / Formatting
  • GitHub Check: Rust packages (wasm-dpp) / Tests
  • GitHub Check: Rust packages (wasm-dpp) / Formatting
  • GitHub Check: Rust packages (wasm-dpp) / Linting
  • GitHub Check: Rust packages (wasm-dpp) / Unused dependencies
  • 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 (9)
packages/rs-dpp/src/errors/consensus/codes.rs (1)

119-119: LGTM! Error code assignment follows established patterns.

The new error code 10272 is correctly placed in the DataContract Errors range (10200-10349) and follows the sequential numbering pattern.

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

827-829: LGTM! Error conversion follows established pattern.

The error conversion logic correctly uses the generic_consensus_error! macro consistent with other error types.

packages/rs-sdk/tests/fetch/common.rs (2)

6-6: LGTM! Clean import addition.

The BTreeMap import is appropriately added to support the new token_configurations parameter.


43-43: LGTM! Appropriate handling of new parameter in test code.

Passing an empty BTreeMap for token_configurations is the correct approach for test utilities where specific token configurations aren't needed.

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

26-26: LGTM! Import addition follows established pattern.

The RedundantDocumentPaidForByTokenWithContractId import is correctly added to the existing import statement.


568-569: LGTM! Error variant addition follows established pattern.

The new error variant correctly uses the #[error(transparent)] attribute and follows the same pattern as other error variants. Placing it at the end of the enum maintains serialization compatibility.

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

1-7: LGTM! Well-organized imports.

The import statements are well-structured and include all necessary dependencies for implementing a consensus error type with proper serialization support.


18-26: LGTM! Clean and idiomatic implementation.

The constructor and getter methods follow Rust conventions perfectly. The implementation is clean, minimal, and provides good encapsulation.


28-34: LGTM! Proper integration with consensus error hierarchy.

The From trait implementation correctly wraps this error in the BasicError enum and integrates seamlessly with the consensus error framework.

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

🧹 Nitpick comments (2)
packages/rs-dpp/src/errors/consensus/state/token/invalid_token_position_error.rs (1)

12-19: Consider simplifying the error message formatting.

While the conditional formatting works correctly, the inline conditional expression in the error macro is quite complex and may impact readability.

Consider moving the message formatting to the Display implementation or using a simpler approach:

-#[error(
-    "Invalid token position: {invalid_token_position}. {max_token_message}",
-    max_token_message = if let Some(max) = self.max_token_position {
-        format!("The maximum allowed token position is {}", max)
-    } else {
-        "No maximum token position limit is set.".to_string()
-    }
-)]
+#[error("Invalid token position: {invalid_token_position}")]

And implement a custom Display trait if more complex formatting is needed.

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

2446-2557: Well-structured test for non-existent external token contract validation.

This test properly validates that referencing a non-existent external token contract results in a DataContractNotFoundError. The test setup is comprehensive and follows the established pattern in the file.

A minor suggestion for improved clarity:

 {
     let document_type = data_contract
         .document_types_mut()
         .get_mut("card")
         .expect("expected a document type with name card");
+    // Set up token cost with non-existent contract ID to test validation
     document_type.set_document_creation_token_cost(Some(DocumentActionTokenCost {
         contract_id: Some(Identifier::new([0; 32])),
📜 Review details

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

📥 Commits

Reviewing files that changed from the base of the PR and between f2dba50 and cbdffc1.

📒 Files selected for processing (16)
  • packages/rs-dpp/src/data_contract/document_type/accessors/mod.rs (4 hunks)
  • packages/rs-dpp/src/data_contract/document_type/accessors/v1/mod.rs (2 hunks)
  • packages/rs-dpp/src/data_contract/document_type/token_costs/accessors.rs (1 hunks)
  • packages/rs-dpp/src/data_contract/document_type/token_costs/mod.rs (1 hunks)
  • packages/rs-dpp/src/data_contract/document_type/token_costs/v0/mod.rs (1 hunks)
  • packages/rs-dpp/src/data_contract/document_type/v1/accessors.rs (2 hunks)
  • packages/rs-dpp/src/errors/consensus/codes.rs (2 hunks)
  • packages/rs-dpp/src/errors/consensus/state/data_contract/data_contract_not_found_error.rs (1 hunks)
  • packages/rs-dpp/src/errors/consensus/state/data_contract/mod.rs (1 hunks)
  • packages/rs-dpp/src/errors/consensus/state/state_error.rs (3 hunks)
  • packages/rs-dpp/src/errors/consensus/state/token/invalid_token_position_error.rs (1 hunks)
  • packages/rs-dpp/src/errors/consensus/state/token/mod.rs (2 hunks)
  • packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/data_contract_create/mod.rs (1 hunks)
  • packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/data_contract_create/state/v0/mod.rs (2 hunks)
  • packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/data_contract_update/state/v0/mod.rs (3 hunks)
  • packages/wasm-dpp/src/errors/consensus/consensus_error.rs (4 hunks)
✅ Files skipped from review due to trivial changes (2)
  • packages/rs-dpp/src/errors/consensus/state/data_contract/mod.rs
  • packages/rs-dpp/src/errors/consensus/state/token/mod.rs
🚧 Files skipped from review as they are similar to previous changes (2)
  • packages/wasm-dpp/src/errors/consensus/consensus_error.rs
  • packages/rs-dpp/src/errors/consensus/codes.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 (6)
packages/rs-dpp/src/data_contract/document_type/token_costs/mod.rs (2)
packages/rs-dpp/src/data_contract/document_type/token_costs/accessors.rs (6)
  • document_creation_token_cost_ref (24-24)
  • document_replacement_token_cost_ref (27-27)
  • document_deletion_token_cost_ref (30-30)
  • document_transfer_token_cost_ref (33-33)
  • document_price_update_token_cost_ref (36-36)
  • document_purchase_token_cost_ref (39-39)
packages/rs-dpp/src/data_contract/document_type/token_costs/v0/mod.rs (6)
  • document_creation_token_cost_ref (54-56)
  • document_replacement_token_cost_ref (58-60)
  • document_deletion_token_cost_ref (62-64)
  • document_transfer_token_cost_ref (66-68)
  • document_price_update_token_cost_ref (70-72)
  • document_purchase_token_cost_ref (74-76)
packages/rs-dpp/src/data_contract/document_type/accessors/mod.rs (2)
packages/rs-dpp/src/data_contract/document_type/accessors/v1/mod.rs (2)
  • all_document_token_costs (51-51)
  • all_external_token_costs_contract_tokens (55-57)
packages/rs-dpp/src/data_contract/document_type/v1/accessors.rs (2)
  • all_document_token_costs (158-181)
  • all_external_token_costs_contract_tokens (183-197)
packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/data_contract_create/state/v0/mod.rs (2)
packages/rs-dpp/src/errors/consensus/state/data_contract/data_contract_not_found_error.rs (1)
  • new (19-21)
packages/rs-dpp/src/errors/consensus/state/token/invalid_token_position_error.rs (1)
  • new (27-35)
packages/rs-dpp/src/data_contract/document_type/accessors/v1/mod.rs (2)
packages/rs-dpp/src/data_contract/document_type/v1/accessors.rs (2)
  • all_document_token_costs (158-181)
  • all_external_token_costs_contract_tokens (183-197)
packages/rs-dpp/src/data_contract/document_type/accessors/mod.rs (6)
  • all_document_token_costs (630-635)
  • all_document_token_costs (690-695)
  • all_document_token_costs (750-755)
  • all_external_token_costs_contract_tokens (637-644)
  • all_external_token_costs_contract_tokens (697-704)
  • all_external_token_costs_contract_tokens (757-764)
packages/rs-dpp/src/errors/consensus/state/data_contract/data_contract_not_found_error.rs (2)
packages/rs-dpp/src/errors/consensus/state/token/invalid_token_position_error.rs (1)
  • from (47-49)
packages/rs-dpp/src/errors/consensus/state/state_error.rs (1)
  • from (327-329)
packages/rs-dpp/src/data_contract/document_type/v1/accessors.rs (2)
packages/rs-dpp/src/data_contract/document_type/accessors/v1/mod.rs (2)
  • all_document_token_costs (51-51)
  • all_external_token_costs_contract_tokens (55-57)
packages/rs-dpp/src/data_contract/document_type/accessors/mod.rs (6)
  • all_document_token_costs (630-635)
  • all_document_token_costs (690-695)
  • all_document_token_costs (750-755)
  • all_external_token_costs_contract_tokens (637-644)
  • all_external_token_costs_contract_tokens (697-704)
  • all_external_token_costs_contract_tokens (757-764)
⏰ Context from checks skipped due to timeout of 90000ms (19)
  • GitHub Check: Rust packages (wasm-dpp) / Tests
  • GitHub Check: Rust packages (wasm-dpp) / Unused dependencies
  • GitHub Check: Rust packages (wasm-dpp) / Formatting
  • GitHub Check: Rust packages (dash-sdk) / Linting
  • GitHub Check: Rust packages (wasm-dpp) / Linting
  • GitHub Check: Rust packages (dash-sdk) / Check each feature
  • GitHub Check: Rust packages (dash-sdk) / Tests
  • GitHub Check: Rust packages (dpp) / Tests
  • GitHub Check: Rust packages (dpp) / Linting
  • GitHub Check: Rust packages (dpp) / Check each feature
  • GitHub Check: Rust packages (drive-abci) / Linting
  • GitHub Check: Rust packages (drive-abci) / Tests
  • GitHub Check: Rust packages (drive-abci) / Check each feature
  • GitHub Check: Rust packages (drive) / Linting
  • GitHub Check: Rust packages (drive) / Tests
  • 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
🔇 Additional comments (17)
packages/rs-dpp/src/errors/consensus/state/state_error.rs (1)

27-27: LGTM! Error enum updates follow established patterns.

The new error variants DataContractNotFoundError and InvalidTokenPositionStateError are correctly added to the StateError enum following the existing pattern with proper imports and #[error(transparent)] annotations.

Also applies to: 47-47, 319-323

packages/rs-dpp/src/data_contract/document_type/accessors/v1/mod.rs (2)

1-4: LGTM! Imports are appropriate for the new trait methods.

The added imports (TokenContractPosition, Identifier, BTreeMap, BTreeSet) are necessary for the return types of the new trait methods.


50-57: LGTM! Well-documented trait methods for internal validation.

The new trait methods all_document_token_costs and all_external_token_costs_contract_tokens are properly documented and clearly indicate their purpose for internal validation. The return types are appropriate for their intended use.

packages/rs-dpp/src/data_contract/document_type/v1/accessors.rs (3)

16-16: LGTM! Import added for required type.

The TokenContractPosition import is necessary for the new method implementations.


158-181: LGTM! Comprehensive collection of all document token costs.

The implementation correctly collects all possible document token costs from the various operation types (creation, replacement, deletion, transfer, price update, purchase) and returns them as a vector of references.


183-197: LGTM! Efficient mapping of external token costs.

The implementation correctly filters for external token costs (those with a contract_id) and builds a map from contract identifiers to sets of token contract positions. The logic efficiently leverages the all_document_token_costs method and uses appropriate data structures.

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

9-9: LGTM! Imports correctly added for new validation features.

The imports for DataContractNotFoundError, InvalidTokenPositionStateError, and DocumentTypeV1Getters are necessary for the new external token cost validation logic.

Also applies to: 15-15, 24-24

packages/rs-dpp/src/data_contract/document_type/token_costs/v0/mod.rs (1)

54-76: Good addition of reference-returning methods for performance optimization.

The new methods provide efficient read-only access to token costs without cloning. The implementation correctly uses .as_ref() to convert Option<T> to Option<&T>.

packages/rs-dpp/src/data_contract/document_type/token_costs/accessors.rs (1)

23-39: Well-designed trait extension with reference accessors.

The trait methods are properly documented and follow a consistent naming convention with the _ref suffix. This complements the owned-value accessors and provides flexibility for callers.

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

8-25: Appropriate imports for external token validation.

The new imports for error types and accessor traits support the external token cost validation logic.


319-385: Well-implemented validation for external token costs.

The validation logic correctly:

  • Fetches external contracts and adds fees to the execution context
  • Validates contract existence before checking token positions
  • Uses proper error types (DataContractNotFoundError and InvalidTokenPositionStateError)
  • Maintains consistency with the existing validation patterns

The use of last_key_value() at line 360 to get the maximum token position is appropriate since BTreeMap maintains sorted order.

packages/rs-dpp/src/data_contract/document_type/token_costs/mod.rs (1)

56-90: LGTM! Consistent implementation of reference-returning accessors.

The new reference-returning getter methods follow the established pattern perfectly:

  • Consistent naming convention with _ref suffix
  • Proper delegation to inner TokenCostsV0 implementation
  • Maintains the same structure as existing owned-value getters

This provides efficient reference access to token costs without unnecessary cloning.

packages/rs-dpp/src/errors/consensus/state/data_contract/data_contract_not_found_error.rs (1)

1-32: LGTM! Well-structured error type following established patterns.

The DataContractNotFoundError implementation is excellent:

  • Proper derive attributes for error handling, serialization, and debugging
  • Clear error message including the missing data contract ID
  • Consistent constructor and getter pattern
  • Proper conversion to ConsensusError via StateError wrapping

This follows the same patterns as other error types in the codebase and will integrate well with the consensus error handling framework.

packages/rs-dpp/src/errors/consensus/state/token/invalid_token_position_error.rs (1)

26-50: LGTM! Standard error type implementation.

The constructor, getters, and ConsensusError conversion follow established patterns perfectly:

  • Clear constructor with descriptive parameter names
  • Simple getter methods for both fields
  • Proper conversion via StateError wrapping

The implementation is consistent with other error types in the consensus framework.

packages/rs-dpp/src/data_contract/document_type/accessors/mod.rs (2)

630-644: LGTM! Well-designed aggregate accessor methods.

The new all_document_token_costs and all_external_token_costs_contract_tokens methods are excellent additions:

  • Version compatibility: V0 returns empty collections, V1 delegates appropriately
  • Clear naming: Method names clearly indicate they return aggregate data
  • Proper return types: Using references and appropriate collection types
  • Consistent pattern: Follows the same structure as other V1Getters methods

These methods provide valuable aggregate access to token cost information.


690-704: LGTM! Consistent implementation across all document type variants.

The implementations for DocumentTypeRef and DocumentTypeMutRef correctly mirror the main DocumentType implementation:

  • Identical patterns: All three implementations follow the same V0/V1 branching logic
  • Type consistency: Each returns the same types and handles empty cases properly
  • Complete coverage: All document type variants now support these aggregate accessors

This ensures consistent behavior regardless of which document type variant is used.

Also applies to: 750-764

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

2559-2684: Excellent test coverage for invalid token position validation.

This test effectively validates that referencing an invalid token position (position 4) within an existing external token contract triggers an InvalidTokenPositionStateError. The test properly creates a valid token contract first, then references an invalid position, which is the correct approach for this scenario.

The test structure is solid and the error assertion is appropriate:

assert_matches!(
    processing_result.execution_results().as_slice(),
    [StateTransitionExecutionResult::PaidConsensusError(
        ConsensusError::StateError(StateError::InvalidTokenPositionStateError(_)),
        _
    )]
);

@QuantumExplorer QuantumExplorer changed the title fix(dpp): ensure document types only target valid tokens for token payments fix(platform): ensure document types only target valid tokens for token payments May 23, 2025
Copy link
Member Author

@QuantumExplorer QuantumExplorer left a comment

Choose a reason for hiding this comment

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

Self Reviewed

@QuantumExplorer QuantumExplorer merged commit a86708f into v2.0-dev May 23, 2025
40 of 41 checks passed
@QuantumExplorer QuantumExplorer deleted the fixvalid-token-targets-for-payments branch May 23, 2025 15:08
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.

1 participant