Skip to content

feat(drive)!: timeRange buckets on indexOnly indexes - #4508

Merged
QuantumExplorer merged 1 commit into
v4.2-devfrom
feat/index-only-time-range-buckets
Aug 28, 2026
Merged

feat(drive)!: timeRange buckets on indexOnly indexes#4508
QuantumExplorer merged 1 commit into
v4.2-devfrom
feat/index-only-time-range-buckets

Conversation

@QuantumExplorer

@QuantumExplorer QuantumExplorer commented Aug 28, 2026

Copy link
Copy Markdown
Member

Issue being fixed or feature implemented

Stacked on #4506#4506 merged; this PR is now rebased directly onto v4.2-dev (single commit, its own diff only).

The second protocol-scale indexOnly extension: timeRange buckets. "Trending under #dash this hour" needs likes bucketed by creation time — #3740 shipped exactly this for stored types, but the indexOnly parser rejected timeRange with "not yet supported".

What was done?

Nearly everything composes from #3740 + the indexOnly stack; the walkers' bucket fan-out, IN_TIME_RANGE resolution/admission, and the count aggregate surfaces are shared and unchanged:

  • dpp: the rejection is removed — with zero new rules. The shared timeRange rules force a required system timestamp as the index's first property, and the indexOnly prefix rule admits only $ownerId/$createdAt as system properties, which pins the source to $createdAt (the only timestamp an immutable, create-once document carries). A bucketed index involves $createdAt, so the existing admission rule keeps it from being the proof index; required membership makes delete-by-values reproduce the exact bucket set the create wrote.
  • probes: entry path derivation becomes plural (index_only_entry_paths_and_key) — level segments via Index::level_key, bucket value keys via TimeRangeTransform::entry_keys_for_raw, the same derivation the walkers write with so probe and write paths cannot drift. The delete-side commitment probe requires ALL bucket entries to carry the row commitment (probe-all-buckets, fail-closed); the create-side duplicate probe fires on ANY existing entry.
  • read surface (v1 = aggregates only): document synthesis over a bucketed indexOnly index is refused with guidance — the bucket level carries bucket-start granularity, not the document's timestamp, and the type's non-bucketed indexes serve the raw entries. Guarded in both the route and the synthesis index resolution (prover, no-proof executor and verifier refuse alike); the terminal-clause matcher excludes bucketed indexes so a raw query never walks grid-keyed levels; the from-values proof builder rejects them defensively. IN_TIME_RANGE count aggregates work through the existing pickers unchanged.
  • estimation: the per-entry item padding rises 16 → 32 bytes. The e2e upper-bound test caught a real under-run: the documented per-entry-chain estimation under-count exceeded the old pad once the bucket fan-out (4 entry chains under one grid tree) removed the incidental slack other levels contribute. The pad is per entry, so it scales with any overlap factor. Measured margins after: like +81B, tip +351B, beat +57B. The indexOnly 0-tree's stateless apply now also claims its real value-tree parent type instead of NormalTree.
  • fixture/tests: the yappr fixture gains a beat doctype (byHourHashtag [$createdAt, hashtag] → $ownerId on a 3600s/900s grid — overlap factor 4 — with the count axes; byHashtag as the $createdAt-free proof index). E2e pins: one commitment entry per bucket at arithmetic-pinned starts (and none outside), resolved IN_TIME_RANGE bucket counts with unproved/proved parity, the synthesis refusal, delete removing every bucket entry plus falsified-timestamp refusal on the commitment probe, estimation upper bounds, and duplicate/overlap semantics. ABCI: full lifecycle with executed create/delete proofs through the non-bucketed proof index and duplicate refusal.
  • book: the indexOnly chapter's constraint matrix and a new buckets paragraph.

Note: ranked* axes on timeRange indexes stay rejected — that is #3740's general rule ("ranked queries have no time-bucket semantics"), not an indexOnly restriction.

How Has This Been Tested?

  • cargo test -p dpp --features validation index_only — 37 passed (3 new bucketed tests)
  • cargo test -p drive --features server,verify,fixtures-and-mocks --lib index_only — 32 passed (6 new beat tests); query:: — 582 passed; count query module — 56 passed
  • cargo test -p drive-abci index_only — 10 passed
  • cargo clippy -p dpp -p drive -p drive-abci --all-features --all-targets -- -D warnings clean; cargo check --workspace --all-features clean

Breaking Changes

Consensus-breaking on the unreleased PV14 only: contracts declaring timeRange on indexOnly indexes were rejected and can now register; the estimation padding change alters dry-run (never applied) fees for indexOnly types. No released protocol version changes behavior.

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

For repository code-owners and collaborators only

  • I have assigned this pull request to a milestone

🤖 Generated with Claude Code

@coderabbitai

coderabbitai Bot commented Aug 28, 2026

Copy link
Copy Markdown
Contributor

Warning

Review limit reached

Next included review available in 28 minutes.

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: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro Plus

Run ID: 8ccc6d35-90cd-4dc6-89f7-df8d4617582c

📥 Commits

Reviewing files that changed from the base of the PR and between 63e8739 and dac8758.

📒 Files selected for processing (10)
  • book/src/drive/index-only-document-types.md
  • packages/rs-dpp/src/data_contract/document_type/class_methods/try_from_schema/common/mod.rs
  • packages/rs-dpp/src/data_contract/document_type/class_methods/try_from_schema/v3/index_only_tests.rs
  • packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/tests/document/index_only.rs
  • packages/rs-drive/src/drive/contract/insert/insert_contract/v0/tests/index_only_e2e_tests.rs
  • packages/rs-drive/src/drive/document/index_level_tree_types.rs
  • packages/rs-drive/src/drive/document/index_only.rs
  • packages/rs-drive/src/drive/document/insert/add_reference_for_index_level_for_contract_operations/v0/mod.rs
  • packages/rs-drive/src/query/index_only_synthesis.rs
  • packages/rs-drive/tests/supporting_files/contract/yappr-likes/yappr-likes-contract.json

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 Aug 28, 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-08-28T13:05:56.218Z

@thepastaclaw

thepastaclaw commented Aug 28, 2026

Copy link
Copy Markdown
Collaborator

🕓 Ready for review — 1 ahead in queue (commit dac8758)
Queue position: 2/2
ETA: start ~13:20 UTC · complete ~13:41 UTC (median 21m across 30 recent reviews; 2 slots)
Queued 13m ago · Last checked: 2026-08-28 13:20 UTC

Base automatically changed from feat/index-only-sum-axes to v4.2-dev August 28, 2026 13:02
@github-actions github-actions Bot added this to the v4.2.0 milestone Aug 28, 2026
Lift the parser rejection of timeRange on indexOnly indexes. A bucketed
indexOnly index writes one commitment entry per containing bucket under
the grid-qualified level, exactly as stored types do — the walkers'
bucket fan-out, the IN_TIME_RANGE resolution/admission machinery, and
the count aggregate surfaces are all shared and unchanged.

- dpp: remove the rejection; no new source rule is needed — the shared
  timeRange rules force a required system timestamp as the first
  property, and the indexOnly prefix rule admits only $ownerId and
  $createdAt, which pins the source to $createdAt. A bucketed index
  involves $createdAt, so it never counts as the required
  $createdAt-free proof index, and delete-by-values stays
  deterministic (the carried $createdAt reproduces the bucket set).
- probes: the entry path derivation becomes plural
  (index_only_entry_paths_and_key) — level segments through
  Index::level_key and bucket value keys through entry_keys_for_raw,
  the same derivation the walkers write with. The delete-side
  commitment probe requires ALL bucket entries to match; the
  create-side duplicate probe fires on ANY existing entry.
- read surface: document synthesis over a bucketed indexOnly index is
  refused with guidance (the bucket level carries bucket-start
  granularity, not the document's timestamp) — guarded in both the
  route and the synthesis index resolution so prover, no-proof executor
  and verifier refuse alike; the terminal-clause matcher excludes
  bucketed indexes so a raw query never walks grid-keyed levels; the
  from-values proof builder rejects bucketed indexes defensively.
- estimation: the per-entry item padding rises 16 → 32 bytes — the
  documented per-entry-chain under-count exceeded the old pad once the
  bucket fan-out removed the slack other levels contribute; the pad is
  per entry so it scales with the fan-out. The indexOnly 0-tree's
  stateless apply now also claims the real value-tree parent type.
- fixture/tests: yappr beat doctype (byHourHashtag bucketed on a
  3600s/900s grid with the count axes; byHashtag as the proof index).
  E2e pins: one entry per bucket at arithmetic-pinned starts, resolved
  IN_TIME_RANGE bucket counts (unproved + proved parity), synthesis
  refusal, delete removing every bucket entry + falsified-timestamp
  refusal, estimation upper bounds, duplicate/overlap semantics; abci
  lifecycle with executed create/delete proofs through the non-bucketed
  proof index.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@QuantumExplorer
QuantumExplorer force-pushed the feat/index-only-time-range-buckets branch from b094b81 to dac8758 Compare August 28, 2026 13:05
@codecov

codecov Bot commented Aug 28, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 55.81395% with 76 lines in your changes missing coverage. Please review.
✅ Project coverage is 83.24%. Comparing base (6a34ba2) to head (dac8758).
⚠️ Report is 1 commits behind head on v4.2-dev.

Files with missing lines Patch % Lines
...ackages/rs-drive/src/query/index_only_synthesis.rs 42.10% 33 Missing ⚠️
packages/rs-drive/src/drive/document/index_only.rs 77.10% 19 Missing ⚠️
...t_type/class_methods/try_from_schema/common/mod.rs 0.00% 14 Missing ⚠️
..._for_index_level_for_contract_operations/v0/mod.rs 25.00% 6 Missing ⚠️
...drive/src/drive/document/index_level_tree_types.rs 60.00% 4 Missing ⚠️
Additional details and impacted files
@@             Coverage Diff              @@
##           v4.2-dev    #4508      +/-   ##
============================================
+ Coverage     82.66%   83.24%   +0.57%     
============================================
  Files          2744     2773      +29     
  Lines        370075   374003    +3928     
============================================
+ Hits         305916   311325    +5409     
+ Misses        64159    62678    -1481     
Components Coverage Δ
dpp 83.13% <0.00%> (+1.06%) ⬆️
drive 81.69% <56.94%> (+0.34%) ⬆️
drive-abci 86.87% <ø> (+1.08%) ⬆️
sdk ∅ <ø> (∅)
dapi-client ∅ <ø> (∅)
platform-version ∅ <ø> (∅)
platform-value 92.92% <ø> (ø)
platform-wallet ∅ <ø> (∅)
drive-proof-verifier 48.41% <ø> (ø)
🚀 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

Copy link
Copy Markdown
Member Author

Reviewed

@QuantumExplorer
QuantumExplorer merged commit 09b7f0a into v4.2-dev Aug 28, 2026
34 checks passed
@QuantumExplorer
QuantumExplorer deleted the feat/index-only-time-range-buckets branch August 28, 2026 13:23
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.

2 participants