Skip to content

feat(platform)!: contract references may require a minimum age of, and time since the last update to, the referenced contract - #4913

Merged
QuantumExplorer merged 2 commits into
v4.2-devfrom
claude/charter-creation-delay-9ae131
Sep 22, 2026
Merged

QuantumExplorer merged 2 commits into
v4.2-devfrom
claude/charter-creation-delay-9ae131

Conversation

@QuantumExplorer

@QuantumExplorer QuantumExplorer commented Sep 22, 2026 •

Copy link
Copy Markdown
Member

Issue being fixed or feature implemented

The moderation charters contract (#4898) lets a team apply to moderate a contract the moment that contract exists. A team that also created the target could seat itself before anyone had seen the contract. The charter's targetContractId already requires the target to declare elected moderation through refersTo: { "type": "contract", "contractRequirements": { "moderation": "elected" } } (#4909); this adds two duration requirements so a reference can demand a delay between the referenced contract's creation, or its last update, and the referring document. The second closes the gap the first leaves: an old contract updated to declare elected moderation would otherwise take its owner's charter in the next block.

What was done?

contractRequirements gains minimumAgeSeconds and minimumSecondsSinceUpdate, following the grammar of #4909 (each key an aspect of the referenced contract, its value the requirement):

"refersTo": {
  "type": "contract",
  "contractRequirements": {
    "moderation": "elected",
    "minimumAgeSeconds": 604800,
    "minimumSecondsSinceUpdate": 86400
  }
}
  • Semantics. minimumAgeSeconds: the referenced contract's recorded creation time plus that many seconds must not be after the block time of the write. minimumSecondsSinceUpdate: the same, from the later of its recorded creation and last update times, so any update restarts the clock (updated_at is set on every contract update; a contract never updated counts from its creation). The block time is used rather than the document's $createdAt: it is what "post" means, the writer cannot shift it, and the referring type need not carry $createdAt. A contract without a recorded creation time (the V0 format, created before contracts recorded it) is of unknown age and never meets either.
  • Validation. ContractReferenceRequirements::first_unmet_by now takes the block time; the document reference validation v0 passes block_info.time_ms. The check runs against the contract already fetched for the existence check, so it costs no further read. An unmet requirement refuses the write, paid, with the existing ReferencedContractRequirementNotMetError (40135) with field naming the requirement (minimumAgeSeconds or minimumSecondsSinceUpdate) and required = the number as text. No new error code or StateError discriminant. The error message was reworded from "does not declare" to "does not meet the reference's requirement" so it reads for both keys.
  • Declaration. Meta-schema v3 and apply_property_reference v0 accept, for each, an integer from 1 to 4294967295 (u32) and refuse zero, negatives, non-integers and strings. A changed value is an incompatible schema change on update, like the rest of refersTo.
  • Types. ContractReferenceRequirements.minimum_age_seconds and .minimum_seconds_since_update: Option<u32>, ContractReferenceRequirement::MinimumAgeSeconds and ::MinimumSecondsSinceUpdate, ContractReferenceRequirement::is_met_by, the pure minimum_age_is_met (saturating arithmetic) and last_change_time. required() returns a String now. Display appends "at least N seconds old" and "unchanged for at least N seconds".
  • Clients. wasm-dpp2's reference surface reports contractRequirements?: { moderation?: 'elected'; minimumAgeSeconds?: number; minimumSecondsSinceUpdate?: number }.
  • Docs. v14 changelog item 24 and the book's contract moderation chapter extended in place.

Follow-up: add minimumAgeSeconds and minimumSecondsSinceUpdate to the charter's targetContractId in #4898 once the delays are chosen.

How Has This Been Tested?

  • rs-dpp: parser tests for both keys (accepted alone, together and with moderation, up to u32::MAX; zero, negative, too large, float and string refused, the error naming the key), meta-schema v3 tests (accepted values; malformed values, unknown keys and contractRequirements on an identity reference refused), Display, the update-compatibility test (a changed value reports /properties/toUserId/refersTo/contractRequirements/<key>), a unit test of the duration arithmetic (one millisecond short, exact boundary, no recorded time, saturation) and one of last_change_time (neither, creation only, both, update only).
  • drive-abci: new fixtures reference-validation-contract-aged-contract-ref.json (minimumAgeSeconds: 3600) and reference-validation-contract-updated-contract-ref.json (minimumSecondsSinceUpdate: 3600); the reference-validation helper now takes a BlockInfo. Six new creation tests: referenced contract created one millisecond less than the minimum before the block (40135, field minimumAgeSeconds, required 3600), without a creation time (40135), created exactly the minimum before the block (success); created long ago but updated one millisecond too recently (40135, field minimumSecondsSinceUpdate), updated exactly the minimum before the block (success), never updated and created exactly the minimum before the block (success). The four existing contract-reference tests still pass.
  • cargo check -p wasm-dpp2 --target wasm32-unknown-unknown, clippy on dpp and drive-abci, rustfmt.

Breaking Changes

Consensus: a contract reference may now refuse a document write that the previous rules accepted, under protocol version 14 (unreleased), by the same code 40135 as an unmet moderation requirement. The DocumentPropertyReferenceTarget::Contract encoding gains a field, in place at the unreleased version.

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
  • If I added or changed GroveDB structure, I described it in the area's structure.rs, regenerated grovedb-structure.json, and checked the structure viewer link posted on this pull request

For repository code-owners and collaborators only

  • I have assigned this pull request to a milestone

🤖 Generated with Claude Code

PR Hygiene · 2aaa60c

  • Bots — coderabbitai not yet · thepastaclaw not yet — /skip-bots proceeds without the ones not yet reported
  • Self-review — post /self-reviewed once the bots are done
  • Within your 5 open PRs
  • Build running
  • Approvals — you own every area touched; none needed

When every box is checked the PR Hygiene check passes and this can merge.

… referenced contract

A `contract` refersTo declaration's `contractRequirements` gains
`minimumAgeSeconds`: the referenced contract's recorded creation time
plus that many seconds must not be after the block time of the write.
It gives a contract's creation a delay before a charter can be posted
against it, so a moderation team cannot be seated before anyone has
seen the contract. A contract without a recorded creation time (the V0
format) never meets it.

Checked in the document reference validation against the contract
already fetched for the existence check, so it costs no further read;
an unmet requirement refuses the write with the existing
ReferencedContractRequirementNotMetError (40135), field
`minimumAgeSeconds`, required = the number. Meta-schema v3 and the
parser bound the value to 1..=4294967295; a changed value is an
incompatible schema change on update. wasm-dpp2 reports it on the
reference surface.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
@coderabbitai

coderabbitai Bot commented Sep 22, 2026 •

Copy link
Copy Markdown
Contributor

Warning

Review limit reached

Next included review available in 37 minutes.

Check out review usage here.

View limit details

Limit details: You’ve used the included review currently available.

You've used all free OSS reviews for now. Wait for the free limit to reset to keep reviewing this public repository.

Learn how review limits work.

Review configuration:

⚙️ Run configuration

Configuration used: Repository: dashpay/platform/.coderabbit.yaml

Review profile: CHILL

Plan: Advanced

Run ID: aff2fa78-5239-446f-9138-647f8ebbbbff

📥 Commits

Reviewing files that changed from the base of the PR and between fe90c2f and 9274220.

📒 Files selected for processing (15)
  • book/src/data-model/contract-moderation.md
  • 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/errors/consensus/state/document/referenced_contract_requirement_not_met_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_reference_validation/v0/mod.rs
  • packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/tests/document/creation.rs
  • packages/rs-drive-abci/tests/supporting_files/contract/reference-validation/reference-validation-contract-aged-contract-ref.json
  • packages/rs-drive-abci/tests/supporting_files/contract/reference-validation/reference-validation-contract-updated-contract-ref.json
  • packages/rs-platform-version/src/version/v14.rs
  • packages/wasm-dpp2/src/consensus_error.rs
  • packages/wasm-dpp2/src/data_contract/document_type_reference.rs

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

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

@github-actions

github-actions Bot commented Sep 22, 2026 •

Copy link
Copy Markdown
Contributor

📖 Book Preview built successfully.

Download the preview from the workflow artifacts.
To view locally: download the artifact, unzip, and open index.html.

Updated at 2026-09-22T15:29:00.747Z

@github-actions github-actions Bot added this to the v4.2.0 milestone Sep 22, 2026
@thepastaclaw

thepastaclaw commented Sep 22, 2026 •

Copy link
Copy Markdown
Collaborator

⚠️ DEGRADED — Queued for automated review — 26th in line, estimated start in ~25 h (commit 9274220)
Estimated review time once started: ~2.0 h (two-phase automated review; median of recent runs).
The primary review models are currently out of quota; this review will run on stand-in models and be marked as degraded.

  • Request priority review — click to move this review to the front of the queue.

@github-actions github-actions Bot added the waiting-bots Waiting for the review bots to report on this head label Sep 22, 2026
… the referenced contract's last update

`contractRequirements` gains `minimumSecondsSinceUpdate`, measured from
the later of the referenced contract's recorded creation and last
update times to the block time of the write. It closes the gap the
creation delay leaves: an old contract updated to declare elected
moderation would otherwise take its owner's charter in the next block.
Any update restarts the clock; a contract never updated counts from its
creation; one without a recorded creation time never meets it.

Same declaration bounds (1..=u32::MAX), the same 40135 error with the
field naming the requirement, and the same wasm-dpp2 surface.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
@QuantumExplorer QuantumExplorer changed the title feat(platform)!: contract references may require a minimum age of the referenced contract feat(platform)!: contract references may require a minimum age of, and time since the last update to, the referenced contract Sep 22, 2026

@QuantumExplorer QuantumExplorer left a comment

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

Reviewed

@QuantumExplorer
QuantumExplorer merged commit 1a561f2 into v4.2-dev Sep 22, 2026
9 checks passed
@QuantumExplorer
QuantumExplorer deleted the claude/charter-creation-delay-9ae131 branch September 22, 2026 15:25
QuantumExplorer added a commit that referenced this pull request Sep 22, 2026
…s old

The charter's `targetContractId` reference now also carries
`minimumAgeSeconds: 432000` (#4913), so a charter for a contract created
less than five days before the block is refused with
`ReferencedContractRequirementNotMetError` (40135), like one whose target
does not declare elected moderation. The network gets notice of a contract
before any team can apply to moderate it.

`MINIMUM_TARGET_CONTRACT_AGE_SECONDS` in rs-dpp pins the schema's number
through the system contract test, which also gains the two requirement
fields #4913 added to `ContractReferenceRequirements`.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

waiting-bots Waiting for the review bots to report on this head

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants