Repository navigation
feat(dpp): consume and minimumAgeBlocks on any reference judged on the create alone - #5364
QuantumExplorer wants to merge 1 commit into
Conversation
…e create alone `consume` and `minimumAgeBlocks` needed a findBy function because only a commit-and-reveal key was judged on the create alone. A reference on a document type whose documents are never replaced (documentsMutable: false) is judged on the create alone too: a replace is the one write that re-validates a reference. `DocumentReferenceLookup::is_checked_on_create_only(documents_mutable)` covers both. The age and consume refusal moves from `parse_find_by`, which has no document type, to `validate_reference_lookup_sources` (`age_or_consume_error`); meta-schema v3 only requires findBy beside either keyword. The `$ownerId` source rule, `creatorRefersTo` with a deletable lookup and the create-only skips in reference validation 0 follow the new definition; the string carrier and the repeated-key preimage refusal keep testing for a hash key. Docs: meta-schema v3, v14 note 61, the book and the wasm-dpp2 TypeScript docs. Tests: dpp parses age and consume beside a plain findBy on an immutable type and refuses them on a mutable one, both parses; creatorRefersTo the same. drive-abci: a voucher/redemption contract consumes the voucher, refuses a same-block redemption (40142) and another identity's (40127). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
Important Review skippedAuto reviews are disabled on base/target branches other than the default branch. Please check the settings in the CodeRabbit UI or the ⚙️ Run configuration
You can disable this status message by setting the Use the checkbox below for a quick retry:
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. Comment |
|
📖 Book Preview built successfully. Download the preview from the workflow artifacts. Updated at 2026-10-09T15:23:25.102Z |
|
🔍 Review in progress — actively reviewing now (commit 467451a) · triage: critical |
Basic explanation
A document can point at another document and, when it is created, delete that document (
consume) or require it to be old enough (minimumAgeBlocks). Until now that only worked for one kind of pointer: a commit-and-reveal hash. The real requirement was never the hash. It was that the pointer is only checked once, when the document is created, because a later edit would check it again and find the consumed document gone.A document type whose documents can never be edited (
documentsMutable: false) has exactly that property: nothing ever re-checks its pointers. This PR lets such types useconsumeandminimumAgeBlockswith anyfindBy, hash or not. It is the first prerequisite for DPNS name tombstones, where a tombstone consumes the name's domain.Stacked on #5337.
Issue being fixed or feature implemented
consumeandminimumAgeBlockswere refused unless the reference'sfindByheld a hash function. The reason, inDocumentReferenceLookup::is_checked_on_create_only, was that such a reference is judged on the create alone and never again. But a reference declared on a type whose documents are never replaced is judged on the create alone too: a replace is the one write that re-validates a reference (transfers, purchases, price updates, moderator field changes and restores never do, andchangeFieldsmay not name a property a reference reads).What was done?
DocumentReferenceLookup::is_checked_on_create_only(documents_mutable): a computed key, or a declaring type whose documents are never replaced.minimumAgeBlocksandconsumemoves fromparse_find_by, which has no document type, tovalidate_reference_lookup_sources(newage_or_consume_error), which runs on every parse once the type is known. Meta-schema v3 now only requiresfindBybeside either keyword."$ownerId"findBysource on a transferable or tradeable referring type;creatorRefersTowith adeletableDocumentfound byfindBy;whereandanyOfrule (create_only_leaf_error) and the immutable-property exception, both no-ops on an immutable type.hash_key().is_some()): the string or byte array carrier, which still needs a function, and the repeated-key preimage refusal.Before and after
A
redemptionthat consumes the writer'svoucher, found by its serial without a function:documentsMutable: trueis still refused (10231): "the reference must be judged on the create alone: give findBy a function, or make the document type immutable".In-place changes to shipped generations
binds_a_changed_property,validate_reference_target_v0): every protocol version selects it. Only lookups reach the changed lines, and only meta-schema v3 (protocol version 14) admitsfindBy, so nothing changes before 14. A replace never reaches either line for a type whose documents are never replaced (document replace advanced structure refuses it first), so the behaviour at 14 is unchanged too.How Has This Been Tested?
should_parse_age_and_consume_without_a_function_on_a_type_never_replaced;should_refuse_age_and_consume_without_a_function_on_a_type_whose_documents_can_be_replaced(validating and stored-contract parses);should_parse_a_deletable_creator_lookup_without_a_computed_key_on_a_type_never_replacedand its refused twin on a replaceable type;commit_reveal_lookup.rs, avoucher/redemptionfixture):should_consume_a_document_a_plain_lookup_finds_on_a_type_never_replaced;should_refuse_a_plain_lookup_redemption_in_the_block_of_its_voucher(40142);should_refuse_redeeming_another_identitys_voucher_through_a_plain_lookup(40127).cargo test -p dpp --lib,cargo test -p drive-abci --lib -- commit_reveal refers_to reference dpns document moderation,cargo clippy -p dpp -p drive-abci -p dash-sdk --all-targets,cargo check -p wasm-dpp2,cargo fmt --all -- --check.Breaking Changes
None. Contracts that registered before still register; this only admits declarations that were refused.
Checklist:
structure.rs, regeneratedgrovedb-structure.json, and checked the structure viewer link posted on this pull requestFor repository code-owners and collaborators only
🤖 Generated with Claude Code