feat(platform)!: reference validation for documents (refersTo) - #2993
Conversation
|
Note Reviews pausedIt looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the Use the following commands to manage reviews:
Use the checkboxes below for quick actions:
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: Path: .coderabbit.yaml Review profile: CHILL Plan: Pro Plus Run ID: 📒 Files selected for processing (3)
🚧 Files skipped from review as they are similar to previous changes (1)
📝 WalkthroughWalkthroughThe change adds ChangesDocument reference validation
Estimated code review effort: 4 (Complex) | ~60 minutes Sequence Diagram(s)sequenceDiagram
participant Client
participant DocumentTransition
participant ReferenceValidator
participant PlatformState
participant IdentityStore
Client->>DocumentTransition: submit document create or replace
DocumentTransition->>ReferenceValidator: validate document references
ReferenceValidator->>PlatformState: resolve document type
ReferenceValidator->>IdentityStore: retrieve required identity revision
IdentityStore-->>ReferenceValidator: identity revision or missing entity
ReferenceValidator-->>DocumentTransition: validation result
DocumentTransition-->>Client: success or ReferencedEntityNotFoundError
Suggested reviewers: 🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✨ Finishing Touches 💡 1📝 Generate docstrings 💡
🧪 Generate unit tests (beta)
Comment |
72fede5 to
2eab1ca
Compare
|
@coderabbitai review |
✅ Actions performedReview triggered.
|
There was a problem hiding this comment.
Actionable comments posted: 5
🤖 Fix all issues with AI agents
In `@docs/specs/reference-validation.md`:
- Around line 31-33: The spec currently names the error
ReferencedIdentityNotFoundError but the implementation defines
ReferencedEntityNotFoundError; update the spec text to use
ReferencedEntityNotFoundError everywhere (including any examples/fields like {
path, identityId } -> keep fields consistent with the implementation) so the
documented error name and payload match the actual error type used by the code
(ReferencedEntityNotFoundError).
In `@packages/rs-dpp/schema/meta_schemas/document/v0/document-meta.json`:
- Around line 126-144: The schema currently allows "refersTo" on any property,
which can let non-identifier fields pass validation; update the JSON Schema so
that whenever a property contains "refersTo" it is constrained to the identifier
media type and appropriate base type: add an if/then (or dependencies) clause
that checks for the presence of "refersTo" and then enforces "type": "string"
(or the correct identifier base type) and "mediaType":
"application/vnd.dash.identifier" (or the canonical identifier media type used
in the repo), and apply this guard to both occurrences of the "refersTo" block
(the one with properties including "type" and "mustExist" and the second similar
block later in the file) so reference validation no longer accepts
non-identifier fields.
In
`@packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/tests/document/replacement.rs`:
- Around line 2251-2317: The test functions in this file use imperative names
instead of the required "should ..." convention; rename the four test functions
test_document_replace_fails_when_referenced_identity_missing,
test_document_replace_succeeds_when_must_exist_false,
test_document_replace_validates_only_changed_fields, and
test_document_replace_fails_when_reference_field_changed_to_missing_identity to
start with "should" (e.g.,
should_document_replace_fail_when_referenced_identity_missing,
should_document_replace_succeed_when_must_exist_false,
should_document_replace_validate_only_changed_fields,
should_document_replace_fail_when_reference_field_changed_to_missing_identity)
so they conform to the tests/** naming guideline and update any references to
these symbols accordingly (keep function bodies and assertions unchanged).
In `@packages/rs-json-schema-compatibility-validator/tests/rules.rs`:
- Around line 54-97: Rename the test function to follow the "should …" naming
convention: change the function named test_refers_to_addition_is_incompatible to
a "should" form (for example should_refers_to_addition_be_incompatible or
should_detect_incompatible_refers_to_addition) so the test name reflects the
guideline; update the function declaration (fn
test_refers_to_addition_is_incompatible) to the new name and leave the body,
assertions (result.is_compatible, result.incompatible_changes() check) and
referenced symbols (/properties/toUserId/refersTo,
validate_schemas_compatibility, Options) unchanged.
In `@packages/rs-platform-version/src/version/v12.rs`:
- Around line 33-34: Fix the typo in the module-level documentation comment in
v12.rs: change "Intruduced" to "Introduced" in the doc comment that begins "This
version introduces document reference validation..." so the sentence reads
"Introduced in Platform release 3.1.0." This is the doc comment near the top of
the v12.rs file that documents the version change.
🧹 Nitpick comments (2)
packages/rs-dpp/src/data_contract/document_type/class_methods/try_from_schema/mod.rs (1)
117-154: AlignrefersTovalidation across object/non-object paths.
insert_valuesonly callsparse_property_referenceon non-object properties, so arefersToplaced on an object property could be silently ignored, whileinsert_values_nestedrejects it. Consider validatingrefersTobefore the match to keep behavior consistent.♻️ Suggested adjustment
- let property_type = - DocumentPropertyType::try_from_value_map(&inner_properties, &config.into())?; + let property_type = + DocumentPropertyType::try_from_value_map(&inner_properties, &config.into())?; + let reference = parse_property_reference(&inner_properties, &property_type)?; match property_type { DocumentPropertyType::Object(_) => { if let Some(properties_as_value) = inner_properties.get(property_names::PROPERTIES) { ... } } property_type => { - let reference = parse_property_reference(&inner_properties, &property_type)?; document_properties.insert( prefixed_property_key, DocumentProperty { property_type, required: is_required, transient: is_transient, reference, }, ); } };packages/rs-dpp/src/data_contract/document_type/property/mod.rs (1)
35-40: Consider omittingreference: nullfrom serialized output.If
DocumentPropertyis serialized anywhere, the new field will emitreference: nullfor properties without references. If you want to preserve the previous JSON shape, skip serialization when it’sNone.♻️ Suggested adjustment
pub struct DocumentProperty { pub property_type: DocumentPropertyType, pub required: bool, pub transient: bool, + #[serde(skip_serializing_if = "Option::is_none")] pub reference: Option<DocumentPropertyReference>, }
5b92420 to
a69c16d
Compare
|
Note GitHub couldn't provide a complete incremental comparison for this pull request, so CodeRabbit is performing a full review instead. This review may take a little longer. |
|
🕓 Ready for review — 1 ahead in queue (commit f0c03d7) |
There was a problem hiding this comment.
Actionable comments posted: 3
🧹 Nitpick comments (2)
packages/rs-platform-version/src/version/v14.rs (1)
106-115: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick winAdd a version-boundary assertion for the new reference-validation fields.
The existing test
contested_index_cross_check_is_v14_onlypins onlydocument_create_transition_structure_validation. The activation ofrefersTovalidation depends ondocument_create_transition_state_validation,document_replace_transition_state_validation, anddocument_reference_validation. Pin those values too. A silent change to the v11 table would otherwise alter consensus behavior for v13 replay without failing any test.♻️ Proposed test addition
#[test] fn reference_validation_is_v14_only() { let v13 = &PLATFORM_V13 .drive_abci .validation_and_processing .state_transitions .batch_state_transition; let v14 = &PLATFORM_V14 .drive_abci .validation_and_processing .state_transitions .batch_state_transition; assert_eq!(v13.document_create_transition_state_validation, 1); assert_eq!(v13.document_replace_transition_state_validation, 0); assert_eq!(v14.document_create_transition_state_validation, 2); assert_eq!(v14.document_replace_transition_state_validation, 1); assert_eq!(v14.document_reference_validation, 0); }Confirm the expected v13 values before you commit the assertion.
Also applies to: 127-127
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@packages/rs-platform-version/src/version/v14.rs` around lines 106 - 115, Add a version-boundary test alongside contested_index_cross_check_is_v14_only that compares PLATFORM_V13 and PLATFORM_V14 batch state-transition validation fields. Assert the expected v13 create/replace state-validation values and the v14 create, replace, and document_reference_validation values, confirming the v13 values against the version table before committing.packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/tests/document/creation.rs (1)
4804-4810: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick winAssert the reference-error metadata.
These assertions accept any
ReferencedEntityNotFoundError. A wrong entity ID, target type, or property path will pass the tests.
packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/tests/document/creation.rs#L4804-L4810: assert the generated missing ID, the identity target type, and thetoUserIdpath.packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/tests/document/creation.rs#L4875-L4880: assert the generated missing ID, the identity target type, and themeta.nestedUserIdpath.🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/tests/document/creation.rs` around lines 4804 - 4810, Strengthen the ReferencedEntityNotFoundError assertions in packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/tests/document/creation.rs:4804-4810 and 4875-4880 to match the expected generated missing ID, identity target type, and reference paths. Use toUserId at 4804-4810 and meta.nestedUserId at 4875-4880, while preserving the existing outer error matching.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In
`@packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/action_validation/document/document_reference_validation/v0/mod.rs`:
- Around line 135-147: Update the identity extraction handling in the document
reference validation flow: when get_optional_identifier_at_path returns
Ok(None), skip identifier validation and continue without producing
InvalidIdentifierError. Preserve the existing error conversion for Err cases,
allowing schema required-property validation to handle missing or null values.
- Around line 99-115: Update the match in the document reference validation flow
to handle DocumentPropertyReferenceTarget::Contract instead of skipping it,
enforcing reference.must_exist through the appropriate contract-reference
validator while preserving the existing identity validation behavior. Remove the
catch-all continue only if all supported targets are explicitly handled.
- Around line 88-93: Update the changed-field filtering in the document replace
validation loop over flattened_properties so nested paths such as
meta.nestedUserId are retained when changed_data_fields contains their parent
path meta. Either record flattened paths in changed_data_fields or match
descendant paths before applying the continue, while preserving filtering of
unrelated properties.
---
Nitpick comments:
In
`@packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/tests/document/creation.rs`:
- Around line 4804-4810: Strengthen the ReferencedEntityNotFoundError assertions
in
packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/tests/document/creation.rs:4804-4810
and 4875-4880 to match the expected generated missing ID, identity target type,
and reference paths. Use toUserId at 4804-4810 and meta.nestedUserId at
4875-4880, while preserving the existing outer error matching.
In `@packages/rs-platform-version/src/version/v14.rs`:
- Around line 106-115: Add a version-boundary test alongside
contested_index_cross_check_is_v14_only that compares PLATFORM_V13 and
PLATFORM_V14 batch state-transition validation fields. Assert the expected v13
create/replace state-validation values and the v14 create, replace, and
document_reference_validation values, confirming the v13 values against the
version table before committing.
🪄 Autofix
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro Plus
Run ID: 8238e3d1-c3b4-47f2-ae23-727c788b5e99
📒 Files selected for processing (41)
packages/rs-dpp/schema/meta_schemas/document/v3/document-meta.jsonpackages/rs-dpp/src/data_contract/document_type/class_methods/try_from_schema/mod.rspackages/rs-dpp/src/data_contract/document_type/methods/validate_update/common/mod.rspackages/rs-dpp/src/data_contract/document_type/mod.rspackages/rs-dpp/src/data_contract/document_type/property/mod.rspackages/rs-dpp/src/data_contract/document_type/v0/random_document_type.rspackages/rs-dpp/src/errors/consensus/codes.rspackages/rs-dpp/src/errors/consensus/state/document/mod.rspackages/rs-dpp/src/errors/consensus/state/document/referenced_entity_not_found_error.rspackages/rs-dpp/src/errors/consensus/state/state_error.rspackages/rs-dpp/src/validation/meta_validators/mod.rspackages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/action_validation/document/document_create_transition_action/mod.rspackages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/action_validation/document/document_create_transition_action/state_v2/mod.rspackages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/action_validation/document/document_reference_validation/mod.rspackages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/action_validation/document/document_reference_validation/v0/mod.rspackages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/action_validation/document/document_replace_transition_action/mod.rspackages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/action_validation/document/document_replace_transition_action/state_v1/mod.rspackages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/action_validation/document/mod.rspackages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/tests/document/creation.rspackages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/tests/document/replacement.rspackages/rs-drive-abci/tests/supporting_files/contract/reference-validation/reference-validation-contract-must-exist-false.jsonpackages/rs-drive-abci/tests/supporting_files/contract/reference-validation/reference-validation-contract-nested.jsonpackages/rs-drive-abci/tests/supporting_files/contract/reference-validation/reference-validation-contract.jsonpackages/rs-json-schema-compatibility-validator/src/rules/rule_set.rspackages/rs-json-schema-compatibility-validator/tests/rules.rspackages/rs-platform-version/src/version/drive_abci_versions/drive_abci_validation_versions/mod.rspackages/rs-platform-version/src/version/drive_abci_versions/drive_abci_validation_versions/v1.rspackages/rs-platform-version/src/version/drive_abci_versions/drive_abci_validation_versions/v10.rspackages/rs-platform-version/src/version/drive_abci_versions/drive_abci_validation_versions/v11.rspackages/rs-platform-version/src/version/drive_abci_versions/drive_abci_validation_versions/v2.rspackages/rs-platform-version/src/version/drive_abci_versions/drive_abci_validation_versions/v3.rspackages/rs-platform-version/src/version/drive_abci_versions/drive_abci_validation_versions/v4.rspackages/rs-platform-version/src/version/drive_abci_versions/drive_abci_validation_versions/v5.rspackages/rs-platform-version/src/version/drive_abci_versions/drive_abci_validation_versions/v6.rspackages/rs-platform-version/src/version/drive_abci_versions/drive_abci_validation_versions/v7.rspackages/rs-platform-version/src/version/drive_abci_versions/drive_abci_validation_versions/v8.rspackages/rs-platform-version/src/version/drive_abci_versions/drive_abci_validation_versions/v9.rspackages/rs-platform-version/src/version/v14.rspackages/wasm-dpp/src/errors/consensus/consensus_error.rspackages/wasm-dpp/src/errors/consensus/state/document/mod.rspackages/wasm-dpp/src/errors/consensus/state/document/referenced_entity_not_found_error.rs
🚧 Files skipped from review as they are similar to previous changes (23)
- packages/rs-dpp/src/data_contract/document_type/v0/random_document_type.rs
- packages/rs-drive-abci/tests/supporting_files/contract/reference-validation/reference-validation-contract-must-exist-false.json
- packages/rs-platform-version/src/version/drive_abci_versions/drive_abci_validation_versions/v4.rs
- packages/rs-platform-version/src/version/drive_abci_versions/drive_abci_validation_versions/v7.rs
- packages/rs-drive-abci/tests/supporting_files/contract/reference-validation/reference-validation-contract.json
- packages/rs-platform-version/src/version/drive_abci_versions/drive_abci_validation_versions/v6.rs
- packages/wasm-dpp/src/errors/consensus/consensus_error.rs
- packages/rs-platform-version/src/version/drive_abci_versions/drive_abci_validation_versions/v2.rs
- packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/action_validation/document/mod.rs
- packages/rs-dpp/src/errors/consensus/state/document/mod.rs
- packages/rs-json-schema-compatibility-validator/tests/rules.rs
- packages/wasm-dpp/src/errors/consensus/state/document/referenced_entity_not_found_error.rs
- packages/rs-dpp/src/errors/consensus/state/document/referenced_entity_not_found_error.rs
- packages/wasm-dpp/src/errors/consensus/state/document/mod.rs
- packages/rs-platform-version/src/version/drive_abci_versions/drive_abci_validation_versions/v1.rs
- packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/action_validation/document/document_create_transition_action/state_v2/mod.rs
- packages/rs-platform-version/src/version/drive_abci_versions/drive_abci_validation_versions/v3.rs
- packages/rs-dpp/src/data_contract/document_type/mod.rs
- packages/rs-json-schema-compatibility-validator/src/rules/rule_set.rs
- packages/rs-dpp/src/errors/consensus/state/state_error.rs
- packages/rs-dpp/src/data_contract/document_type/class_methods/try_from_schema/mod.rs
- packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/tests/document/replacement.rs
- packages/rs-dpp/src/data_contract/document_type/property/mod.rs
Implements the refersTo document property keyword: data contracts can declare that an identifier property references an identity, and with mustExist true (the default) document create/replace state validation rejects transitions whose referenced identity does not exist on Platform. Replace transitions only validate references on changed fields, and each existence check (via identity revision fetch) is billed through the execution context. Ported from the original v3.0-era branch (PR #2993) onto v4.2-dev: * Gated by the in-development protocol version 14 instead of a new protocol version: DRIVE_ABCI_VALIDATION_VERSIONS_V10 (new in the unreleased v14) is amended to bump document create state validation to 2 and replace to 1, and to introduce the document_reference_validation feature version. * refersTo is admitted only by the v3 document meta-schema (the PV14 generation), so contracts from earlier generations can never carry it; the meta-schema also constrains refersTo to identifier-shaped properties via dependentSchemas. * ReferencedEntityNotFoundError is a state error only (the original branch also added an unused BasicError variant) with code 40120, appended per the frozen-discriminant rules. * JSON-schema compatibility rules reject adding, removing, or modifying refersTo on contract updates. * wasm-dpp exposes the new consensus error. Co-authored-by: Lukasz Klimek <842586+lklimek@users.noreply.github.com> Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
a69c16d to
1f0dcaa
Compare
Codecov Report❌ Patch coverage is Additional details and impacted files@@ Coverage Diff @@
## v4.2-dev #2993 +/- ##
============================================
- Coverage 87.49% 86.67% -0.82%
============================================
Files 2672 2676 +4
Lines 340400 343788 +3388
============================================
+ Hits 297819 297991 +172
- Misses 42581 45797 +3216
🚀 New features to boost your workflow:
|
Implements the refersTo document property keyword: data contracts can declare that an identifier property references an identity, a contract, or a token, and document create/replace state validation rejects transitions whose referenced entity does not exist on Platform. All three targets are permanent once created, so an existence check at write time holds forever. Replace transitions only validate references on changed fields, and each existence check is billed through the execution context (identity revision fetch, contract fetch with fee, token contract info fetch with cost). Ported from the original v3.0-era branch (PR #2993) onto v4.2-dev: * Gated by the in-development protocol version 14 instead of a new protocol version: DRIVE_ABCI_VALIDATION_VERSIONS_V10 (new in the unreleased v14) is amended to bump document create state validation to 2 and replace to 1, and to introduce the document_reference_validation feature version. * refersTo is admitted only by the v3 document meta-schema (the PV14 generation), so contracts from earlier generations can never carry it; the meta-schema also constrains refersTo to identifier-shaped properties via dependentSchemas. * The original branch's mustExist flag was dropped: refersTo present always means the referent must exist, and its non-enforcing variant can be reintroduced compatibly later if ever needed. * ReferencedEntityNotFoundError is a state error only (the original branch also added an unused BasicError variant) with code 40120, appended per the frozen-discriminant rules. * JSON-schema compatibility rules reject adding, removing, or modifying refersTo on contract updates. * wasm-dpp exposes the new consensus error. Co-authored-by: Lukasz Klimek <842586+lklimek@users.noreply.github.com> Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
1f0dcaa to
9f9a919
Compare
Implements the refersTo document property keyword: data contracts can declare that an identifier property references an identity, a contract, or a token, and document create/replace state validation rejects transitions whose referenced entity does not exist on Platform. All three targets are permanent once created, so an existence check at write time holds forever. Replace transitions only validate references on changed fields, and each existence check is billed through the execution context (identity revision fetch, contract fetch with fee, token contract info fetch with cost). The reference lives in the property type itself: DocumentPropertyType::Identifier(Option<DocumentPropertyReferenceTarget>), mirroring how String and ByteArray carry their metadata in-variant and making a reference on a non-identifier property unrepresentable. The parsed document type structs are never consensus-serialized (contracts store raw document schemas and re-derive types on load), so reshaping the variant is wire-invisible. Ported from the original v3.0-era branch (PR #2993) onto v4.2-dev: * Gated by the in-development protocol version 14 instead of a new protocol version: DRIVE_ABCI_VALIDATION_VERSIONS_V10 (new in the unreleased v14) is amended to bump document create state validation to 2 and replace to 1, and to introduce the document_reference_validation feature version. * refersTo is admitted only by the v3 document meta-schema (the PV14 generation), so contracts from earlier generations can never carry it; the meta-schema also constrains refersTo to identifier-shaped properties via dependentSchemas. * The original branch's mustExist flag was dropped: refersTo present always means the referent must exist, and its non-enforcing variant can be reintroduced compatibly later if ever needed. * ReferencedEntityNotFoundError is a state error only (the original branch also added an unused BasicError variant) with code 40120, appended per the frozen-discriminant rules. * JSON-schema compatibility rules reject adding, removing, or modifying refersTo on contract updates. * wasm-dpp exposes the new consensus error. Co-authored-by: Lukasz Klimek <842586+lklimek@users.noreply.github.com> Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
9f9a919 to
f274156
Compare
Implements the refersTo document property keyword: data contracts can declare that an identifier property references an identity, a contract, or a token, and document create/replace state validation rejects transitions whose referenced entity does not exist on Platform. All three targets are permanent once created, so an existence check at write time holds forever. Replace transitions only validate references on changed fields, and each existence check is billed through the execution context (identity revision fetch, contract fetch with fee, token contract info fetch with cost). The reference lives in the property type itself: DocumentPropertyType::Identifier(Option<DocumentPropertyReferenceTarget>), mirroring how String and ByteArray carry their metadata in-variant and making a reference on a non-identifier property unrepresentable. The parsed document type structs are never consensus-serialized (contracts store raw document schemas and re-derive types on load), so reshaping the variant is wire-invisible. Ported from the original v3.0-era branch (PR #2993) onto v4.2-dev: * Gated by the in-development protocol version 14 instead of a new protocol version: DRIVE_ABCI_VALIDATION_VERSIONS_V10 (new in the unreleased v14) is amended to bump document create state validation to 2 and replace to 1, and to introduce the document_reference_validation feature version. * refersTo is admitted only by the v3 document meta-schema (the PV14 generation), so contracts from earlier generations can never carry it; the meta-schema also constrains refersTo to identifier-shaped properties via dependentSchemas. * The original branch's mustExist flag was dropped: refersTo present always means the referent must exist, and its non-enforcing variant can be reintroduced compatibly later if ever needed. * ReferencedEntityNotFoundError is a state error only (the original branch also added an unused BasicError variant) with code 40120, appended per the frozen-discriminant rules. * JSON-schema compatibility rules reject adding, removing, or modifying refersTo on contract updates. * wasm-dpp exposes the new consensus error. Co-authored-by: Lukasz Klimek <842586+lklimek@users.noreply.github.com> Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
f274156 to
73ec7ac
Compare
… reference variant The append-only CI gate rejects any change to existing variants of DocumentPropertyType, so Identifier(Option<DocumentPropertyReferenceTarget>) is split back into the original unit Identifier variant plus a new IdentifierWithReference(DocumentPropertyReferenceTarget) variant appended at the end of the enum. The reference still lives in the property type itself; a plain identifier and a referencing identifier are now separate variants instead of None/Some. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
apply_property_reference ran unconditionally in the shared insert_values helpers, so every try_from_schema generation folded (or hard-rejected) the refersTo keyword. Pre-generation-3 parses must stay byte-for-byte identical to what they produced before the keyword existed: their meta-schemas reject refersTo under full validation, but the non-validating parse path would have started folding it or erroring on it. The fold is now gated by a new admit_property_references flag on ParserGeneration, set by each generation from its own constants — false for generations 0-2 (keyword ignored entirely), true for generation 3. Regression tests pin the PV13 parse: refersTo is ignored on identifier properties and no longer errors on non-identifier ones. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…version tables Replaces the admit_property_references flag on ParserGeneration with the standard versioned-method pattern: DocumentTypeSchemaVersions gains an apply_property_reference OptionalFeatureVersion (None in contract versions 1-5, Some(0) in CONTRACT_VERSIONS_V6), insert_values and insert_values_nested take the platform version, and apply_property_reference dispatches on the table value — None ignores the keyword exactly as versions predating it did, Some(0) folds it via apply_property_reference_v0. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Issue being fixed or feature implemented
Implements the
refersTodocument property keyword, enabling data contracts to declare that identifier properties reference an identity, a contract, or a token. Document create and replace state validation rejects transitions whose referenced entity does not exist on Platform. All three targets are permanent once created (identities and contracts cannot be deleted; a token's contract info record is written at contract insertion and never removed), so an existence check at write time holds forever.Originally written against v3.0; rebased onto
v4.2-devas a single commit and re-homed in the current protocol version 14 architecture.What was done?
refersToobject (type: "identity" | "contract" | "token") and constrained it to identifier-shaped properties viadependentSchemas(array, byteArray, 32-byte, identifier content media type). Earlier meta-schema generations reject the keyword, so pre-v14 contracts can never carry it — enforcement activates exactly at protocol v14.DocumentPropertyType::IdentifierWithReference(DocumentPropertyReferenceTarget)variant (appended to the enum, keeping it append-only; plain identifiers stayIdentifier), mirroring howString/ByteArraycarry their metadata in-variant and making a reference on a non-identifier property unrepresentable.try_from_schemafoldsrefersTointo the type (apply_property_reference), with a hard parse error if it appears on a non-identifier property; the fold is versioned through the platform version tables (apply_property_reference: OptionalFeatureVersiononDocumentTypeSchemaVersions—NonebeforeCONTRACT_VERSIONS_V6,Some(0)from protocol v14): versions predating the keyword ignore it exactly as they did before it existed, keeping pre-PV14 parses byte-for-byte unchanged even on the non-validating path. The parsed document type structs are never consensus-serialized (contracts store raw document schemas and re-derive types on load), so the reshaped variant is wire-invisible.DocumentReferenceValidationdispatcher + v0 implementation in drive-abci that walks flattened properties (nested paths supported), matchingIdentifierWithReference(target), and performs a billed existence check per target:fetch_identity_revision, billed asRetrieveIdentityInfo::only_revision();get_contract_with_fetch_info_and_fee, billed as a precalculated fee (charged even when the contract is cached or absent);fetch_token_contract_info_with_costsagainst the token contract info record, billed as a precalculated fee.state_v2for document create andstate_v1for document replace transition actions; replace validates references only on changed fields. Changed-field matching is ancestor-aware:changed_data_fieldsholds top-level keys, so a nested reference path (meta.nestedUserId) is validated whenever its top-level ancestor changed.requiredconcern); an absent-but-required reference is still rejected by schema validation, and a present reference is always checked.DRIVE_ABCI_VALIDATION_VERSIONS_V10— the table introduced by the still-unreleased protocol v14 — is amended in place (create state validation → 2, replace → 1, newdocument_reference_validationfeature version).ReferencedEntityNotFoundErroras a state consensus error carrying the entity id, target type, and property path, code 40120 (40118/40119 were taken by the contested-index errors), appended per the frozen-discriminant rules (discriminant 93 pinned in the state error discriminant test). The earlier draft's unusedBasicErrortwin variant was dropped.refersToon contract updates.Differences from the original branch: the
mustExistflag was removed —refersTopresent always means the referent must exist. The non-enforcing variant was pure annotation, and dropping it now is the cheap direction (it can be reintroduced compatibly in a later meta-schema generation, whereas removing it after contracts use it cannot). The working spec document is no longer committed; unrelated cleanups (&vec![→&[churn, script fix, argument reordering) were dropped; the strategy-teststack_sizeattributes had already landed separately.How Has This Been Tested?
batch/tests/document/creation.rs,replacement.rs): missing/existing identity references, missing/existing contract references, missing/existing token references, nested and multiple references, replace failing when the reference field changes to a missing identity, a regression test for nested references changed to a missing identity on replace, optional references (absent on create, removed on replace, present-but-missing rejected), and a fee assertion proving replace only validates changed fields.refersToparsing (including rejection on non-identifier properties), reference metadata serialization, meta-schema v3 acceptance of all three targets and rejection of unknown types/extra properties (including rejection of the whole keyword by the v2 meta-schema), and contract-update tests ensuringrefersTocannot be added or modified post-creation.dpplib suite (3879 tests) andcargo clippy --all-targetsclean on all touched crates.Breaking Changes
refersToare only valid from v14, and documents referencing missing identities, contracts, or tokens are rejected from v14.ReferencedEntityNotFoundError) — clients need updated error handling.Checklist:
For repository code-owners and collaborators only