Skip to content

feat(platform)!: reference validation for documents (refersTo) - #2993

Merged
QuantumExplorer merged 4 commits into
v4.2-devfrom
feat/reference-validation
Aug 12, 2026
Merged

feat(platform)!: reference validation for documents (refersTo)#2993
QuantumExplorer merged 4 commits into
v4.2-devfrom
feat/reference-validation

Conversation

@lklimek

@lklimek lklimek commented Jan 15, 2026

Copy link
Copy Markdown
Contributor

Issue being fixed or feature implemented

Implements the refersTo document 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-dev as a single commit and re-homed in the current protocol version 14 architecture.

What was done?

  • Extended the v3 document meta-schema (the protocol v14 generation) to accept a refersTo object (type: "identity" | "contract" | "token") and constrained it to identifier-shaped properties via dependentSchemas (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.
  • The reference lives in the property type itself: a new DocumentPropertyType::IdentifierWithReference(DocumentPropertyReferenceTarget) variant (appended to the enum, keeping it append-only; plain identifiers stay Identifier), mirroring how String/ByteArray carry their metadata in-variant and making a reference on a non-identifier property unrepresentable. try_from_schema folds refersTo into 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: OptionalFeatureVersion on DocumentTypeSchemaVersionsNone before CONTRACT_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.
  • New versioned DocumentReferenceValidation dispatcher + v0 implementation in drive-abci that walks flattened properties (nested paths supported), matching IdentifierWithReference(target), and performs a billed existence check per target:
    • identityfetch_identity_revision, billed as RetrieveIdentityInfo::only_revision();
    • contractget_contract_with_fetch_info_and_fee, billed as a precalculated fee (charged even when the contract is cached or absent);
    • tokenfetch_token_contract_info_with_costs against the token contract info record, billed as a precalculated fee.
  • New state_v2 for document create and state_v1 for document replace transition actions; replace validates references only on changed fields. Changed-field matching is ancestor-aware: changed_data_fields holds top-level keys, so a nested reference path (meta.nestedUserId) is validated whenever its top-level ancestor changed.
  • Optional reference properties that are absent are not validated (whether a property may be absent is the document type's required concern); an absent-but-required reference is still rejected by schema validation, and a present reference is always checked.
  • Version gating: DRIVE_ABCI_VALIDATION_VERSIONS_V10 — the table introduced by the still-unreleased protocol v14 — is amended in place (create state validation → 2, replace → 1, new document_reference_validation feature version).
  • Defined ReferencedEntityNotFoundError as 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 unused BasicError twin variant was dropped.
  • JSON-schema compatibility rules reject adding, removing, or modifying refersTo on contract updates.
  • wasm-dpp exposes the new consensus error.

Differences from the original branch: the mustExist flag was removedrefersTo present 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-test stack_size attributes had already landed separately.

How Has This Been Tested?

  • 15 drive-abci integration tests (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.
  • rs-dpp unit tests: refersTo parsing (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 ensuring refersTo cannot be added or modified post-creation.
  • json-schema-compatibility-validator rule examples + integration test.
  • Full dpp lib suite (3879 tests) and cargo clippy --all-targets clean on all touched crates.

Breaking Changes

  • New consensus rule gated by protocol version 14 (in development): contracts using refersTo are only valid from v14, and documents referencing missing identities, contracts, or tokens are rejected from v14.
  • New consensus error code 40120 (ReferencedEntityNotFoundError) — clients need updated error handling.

Checklist:

  • I have performed a self-review of my own code
  • I have commented my code, particularly in hard-to-understand areas
  • I have added or updated relevant unit/integration/functional/e2e tests
  • I have added "!" to the title and described breaking changes in the corresponding section if my code contains any
  • I have made corresponding changes to the documentation if needed

For repository code-owners and collaborators only

  • I have assigned this pull request to a milestone

@coderabbitai

coderabbitai Bot commented Jan 15, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

Note

Reviews paused

It 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 reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro Plus

Run ID: 3be60753-f5f4-4e8b-8c96-018b51b60120

📥 Commits

Reviewing files that changed from the base of the PR and between a69c16d and 1f0dcaa.

📒 Files selected for processing (3)
  • packages/rs-platform-version/src/version/drive_abci_versions/drive_abci_validation_versions/mod.rs
  • packages/rs-platform-version/src/version/drive_abci_versions/drive_abci_validation_versions/v10.rs
  • packages/rs-platform-version/src/version/v14.rs
🚧 Files skipped from review as they are similar to previous changes (1)
  • packages/rs-platform-version/src/version/drive_abci_versions/drive_abci_validation_versions/mod.rs

📝 Walkthrough

Walkthrough

The change adds refersTo metadata for document properties, validates referenced identities during document creation and replacement, adds missing-entity consensus errors, exposes them through WASM, and activates the validation through platform-version configuration.

Changes

Document reference validation

Layer / File(s) Summary
Schema and property reference model
packages/rs-dpp/schema/meta_schemas/document/v3/document-meta.json, packages/rs-dpp/src/data_contract/document_type/...
Document schemas and DocumentProperty now support identity or contract targets, optional mustExist, serialization, and nested or inline reference metadata.
Schema compatibility validation
packages/rs-dpp/src/validation/meta_validators/mod.rs, packages/rs-json-schema-compatibility-validator/..., packages/rs-dpp/src/data_contract/document_type/methods/validate_update/common/mod.rs
Validation accepts supported v3 references, rejects unsupported placements and targets, and treats reference metadata additions or changes as incompatible schema updates.
Referenced entity error surface
packages/rs-dpp/src/errors/consensus/..., packages/wasm-dpp/src/errors/consensus/...
A ReferencedEntityNotFoundError records the entity identifier, target type, and property path. The error maps to consensus code 40120 and has a WASM representation.
State-transition reference checks
packages/rs-drive-abci/src/execution/validation/state_transition/...
Document creation and replacement dispatch to reference validation. The validator traverses relevant fields, checks required identity references, resolves identity revisions, and returns validation errors for missing entities.
Platform activation and integration coverage
packages/rs-platform-version/src/version/..., packages/rs-drive-abci/src/execution/validation/state_transition/.../tests/document/*, packages/rs-drive-abci/tests/supporting_files/contract/reference-validation/*
Platform versions configure document reference validation. Tests cover existing, missing, optional, nested, multiple, and changed references for creation and replacement.

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
Loading

Suggested reviewers: quantumexplorer

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 64.06% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly and concisely summarizes the pull request's main change: adding document reference validation for the refersTo keyword.
✨ Finishing Touches 💡 1
📝 Generate docstrings 💡
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feat/reference-validation

Comment @coderabbitai help to get the list of available commands.

@github-actions github-actions Bot added this to the v3.0.0 milestone Jan 15, 2026
@lklimek
lklimek force-pushed the feat/reference-validation branch from 72fede5 to 2eab1ca Compare January 20, 2026 12:56
@lklimek lklimek modified the milestones: v3.0.0, v3.1.0 Jan 22, 2026
@lklimek
lklimek marked this pull request as ready for review January 22, 2026 13:02
@lklimek

lklimek commented Jan 22, 2026

Copy link
Copy Markdown
Contributor Author

@coderabbitai review

@coderabbitai

coderabbitai Bot commented Jan 22, 2026

Copy link
Copy Markdown
Contributor
✅ Actions performed

Review triggered.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

@github-actions github-actions Bot modified the milestones: v3.1.0, v3.0.0 Jan 22, 2026
@lklimek lklimek modified the milestones: v3.0.0, v3.1.0 Jan 22, 2026

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

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: Align refersTo validation across object/non-object paths.

insert_values only calls parse_property_reference on non-object properties, so a refersTo placed on an object property could be silently ignored, while insert_values_nested rejects it. Consider validating refersTo before 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 omitting reference: null from serialized output.

If DocumentProperty is serialized anywhere, the new field will emit reference: null for properties without references. If you want to preserve the previous JSON shape, skip serialization when it’s None.

♻️ 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>,
 }

Comment thread docs/specs/reference-validation.md Outdated
Comment thread packages/rs-dpp/schema/meta_schemas/document/v0/document-meta.json Outdated
Comment thread packages/rs-json-schema-compatibility-validator/tests/rules.rs
Comment thread packages/rs-platform-version/src/version/v12.rs Outdated
@github-actions github-actions Bot modified the milestones: v3.1.0, v3.0.0 Jan 22, 2026
@lklimek
lklimek changed the base branch from v3.0-dev to v3.1-dev January 23, 2026 08:47
@github-actions github-actions Bot modified the milestones: v3.0.0, v3.1.0 Jan 23, 2026
@lklimek
lklimek marked this pull request as draft February 10, 2026 10:49
@QuantumExplorer QuantumExplorer modified the milestones: v4.0.0, v4.1.0 Jun 1, 2026
@shumkov
shumkov changed the base branch from v4.0-dev to v4.1-dev July 2, 2026 08:12
@QuantumExplorer
QuantumExplorer changed the base branch from v4.1-dev to v4.2-dev July 24, 2026 20:08
@github-actions github-actions Bot modified the milestones: v4.1.0, v4.2.0 Jul 24, 2026
@QuantumExplorer
QuantumExplorer force-pushed the feat/reference-validation branch from 5b92420 to a69c16d Compare August 12, 2026 19:32
@QuantumExplorer
QuantumExplorer marked this pull request as ready for review August 12, 2026 19:33
@coderabbitai

coderabbitai Bot commented Aug 12, 2026

Copy link
Copy Markdown
Contributor

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.

@thepastaclaw

thepastaclaw commented Aug 12, 2026

Copy link
Copy Markdown
Collaborator

🕓 Ready for review — 1 ahead in queue (commit f0c03d7)
Queue position: 2/10 · 1 review active
ETA: start ~23:31 UTC · complete ~23:47 UTC (median 16m across 30 recent reviews; 2 slots)
Queued 43m ago · Last checked: 2026-08-12 23:20 UTC

@QuantumExplorer QuantumExplorer changed the title feat: identity reference validation feat(platform)!: identity reference validation for documents (refersTo) Aug 12, 2026

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Actionable comments posted: 3

🧹 Nitpick comments (2)
packages/rs-platform-version/src/version/v14.rs (1)

106-115: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Add a version-boundary assertion for the new reference-validation fields.

The existing test contested_index_cross_check_is_v14_only pins only document_create_transition_structure_validation. The activation of refersTo validation depends on document_create_transition_state_validation, document_replace_transition_state_validation, and document_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 win

Assert 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 the toUserId path.
  • 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 the meta.nestedUserId path.
🤖 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

📥 Commits

Reviewing files that changed from the base of the PR and between f05bf82 and a69c16d.

📒 Files selected for processing (41)
  • packages/rs-dpp/schema/meta_schemas/document/v3/document-meta.json
  • packages/rs-dpp/src/data_contract/document_type/class_methods/try_from_schema/mod.rs
  • packages/rs-dpp/src/data_contract/document_type/methods/validate_update/common/mod.rs
  • packages/rs-dpp/src/data_contract/document_type/mod.rs
  • packages/rs-dpp/src/data_contract/document_type/property/mod.rs
  • packages/rs-dpp/src/data_contract/document_type/v0/random_document_type.rs
  • packages/rs-dpp/src/errors/consensus/codes.rs
  • packages/rs-dpp/src/errors/consensus/state/document/mod.rs
  • packages/rs-dpp/src/errors/consensus/state/document/referenced_entity_not_found_error.rs
  • packages/rs-dpp/src/errors/consensus/state/state_error.rs
  • packages/rs-dpp/src/validation/meta_validators/mod.rs
  • packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/action_validation/document/document_create_transition_action/mod.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-drive-abci/src/execution/validation/state_transition/state_transitions/batch/action_validation/document/document_reference_validation/mod.rs
  • packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/action_validation/document/document_reference_validation/v0/mod.rs
  • packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/action_validation/document/document_replace_transition_action/mod.rs
  • packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/action_validation/document/document_replace_transition_action/state_v1/mod.rs
  • packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/action_validation/document/mod.rs
  • packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/tests/document/creation.rs
  • packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/tests/document/replacement.rs
  • packages/rs-drive-abci/tests/supporting_files/contract/reference-validation/reference-validation-contract-must-exist-false.json
  • packages/rs-drive-abci/tests/supporting_files/contract/reference-validation/reference-validation-contract-nested.json
  • packages/rs-drive-abci/tests/supporting_files/contract/reference-validation/reference-validation-contract.json
  • packages/rs-json-schema-compatibility-validator/src/rules/rule_set.rs
  • packages/rs-json-schema-compatibility-validator/tests/rules.rs
  • packages/rs-platform-version/src/version/drive_abci_versions/drive_abci_validation_versions/mod.rs
  • packages/rs-platform-version/src/version/drive_abci_versions/drive_abci_validation_versions/v1.rs
  • packages/rs-platform-version/src/version/drive_abci_versions/drive_abci_validation_versions/v10.rs
  • packages/rs-platform-version/src/version/drive_abci_versions/drive_abci_validation_versions/v11.rs
  • packages/rs-platform-version/src/version/drive_abci_versions/drive_abci_validation_versions/v2.rs
  • packages/rs-platform-version/src/version/drive_abci_versions/drive_abci_validation_versions/v3.rs
  • 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/v5.rs
  • packages/rs-platform-version/src/version/drive_abci_versions/drive_abci_validation_versions/v6.rs
  • packages/rs-platform-version/src/version/drive_abci_versions/drive_abci_validation_versions/v7.rs
  • packages/rs-platform-version/src/version/drive_abci_versions/drive_abci_validation_versions/v8.rs
  • packages/rs-platform-version/src/version/drive_abci_versions/drive_abci_validation_versions/v9.rs
  • packages/rs-platform-version/src/version/v14.rs
  • packages/wasm-dpp/src/errors/consensus/consensus_error.rs
  • packages/wasm-dpp/src/errors/consensus/state/document/mod.rs
  • packages/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

QuantumExplorer added a commit that referenced this pull request Aug 12, 2026
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>
@QuantumExplorer
QuantumExplorer force-pushed the feat/reference-validation branch from a69c16d to 1f0dcaa Compare August 12, 2026 19:43
@codecov

codecov Bot commented Aug 12, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 83.83333% with 97 lines in your changes missing coverage. Please review.
✅ Project coverage is 86.67%. Comparing base (f05bf82) to head (f0c03d7).

Files with missing lines Patch % Lines
...pp/src/data_contract/document_type/property/mod.rs 50.81% 30 Missing ⚠️
...ocument_type/methods/validate_update/common/mod.rs 74.41% 22 Missing ⚠️
...document_type/class_methods/try_from_schema/mod.rs 93.63% 10 Missing ⚠️
...n/document/document_reference_validation/v0/mod.rs 91.42% 9 Missing ⚠️
...kages/rs-dpp/src/validation/meta_validators/mod.rs 91.52% 5 Missing ⚠️
...tion/document/document_reference_validation/mod.rs 83.33% 5 Missing ⚠️
packages/rs-drive/src/query/conditions.rs 44.44% 5 Missing ⚠️
...document/document_replace_transition_action/mod.rs 70.00% 3 Missing ⚠️
...document_replace_transition_action/state_v1/mod.rs 91.17% 3 Missing ⚠️
.../document/document_create_transition_action/mod.rs 77.77% 2 Missing ⚠️
... and 2 more
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     
Components Coverage Δ
dpp 86.72% <81.57%> (-2.15%) ⬇️
drive 85.79% <44.44%> (-0.40%) ⬇️
drive-abci 88.75% <89.18%> (-0.48%) ⬇️
sdk ∅ <ø> (∅)
dapi-client ∅ <ø> (∅)
platform-version ∅ <ø> (∅)
platform-value 92.92% <ø> (ø)
platform-wallet ∅ <ø> (∅)
drive-proof-verifier 48.02% <ø> (ø)
🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

QuantumExplorer added a commit that referenced this pull request Aug 12, 2026
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>
@QuantumExplorer
QuantumExplorer force-pushed the feat/reference-validation branch from 1f0dcaa to 9f9a919 Compare August 12, 2026 20:14
@QuantumExplorer QuantumExplorer changed the title feat(platform)!: identity reference validation for documents (refersTo) feat(platform)!: reference validation for documents (refersTo) Aug 12, 2026
QuantumExplorer added a commit that referenced this pull request Aug 12, 2026
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>
@QuantumExplorer
QuantumExplorer force-pushed the feat/reference-validation branch from 9f9a919 to f274156 Compare August 12, 2026 20:49
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>
@QuantumExplorer
QuantumExplorer force-pushed the feat/reference-validation branch from f274156 to 73ec7ac Compare August 12, 2026 21:03
QuantumExplorer and others added 3 commits August 13, 2026 04:49
… 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>
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.

Feature Request: Allow Contracts to reference existing identity identifiers.

3 participants