Skip to content

feat(drive): compute a document type's GroveDB layout for the SDKs - #5153

Merged
QuantumExplorer merged 5 commits into
v4.2-devfrom
feat/drive-document-type-layout
Sep 28, 2026
Merged

QuantumExplorer merged 5 commits into
v4.2-devfrom
feat/drive-document-type-layout

Conversation

@QuantumExplorer

@QuantumExplorer QuantumExplorer commented Sep 28, 2026 •

Copy link
Copy Markdown
Member

Basic explanation

What this does: Drive stores each document type as a set of nested GroveDB trees: one for the documents and, for every index, a tree per indexed property and per value, down to where the index ends. Which kind of tree each one is depends on the index's keywords: a plain tree, a tree that counts or sums its entries, a ranked tree, and so on. Until now the only way to see this for a real contract was to read the insert code. This PR adds a function, document_type_layout, that computes the layout of any document type from the contract alone, using the same rules Drive uses when it inserts documents. It is exposed to JavaScript as documentTypeLayout(contract, documentTypeName, platformVersion) in wasm-sdk, and so in @dashevo/evo-sdk.

Value:

  • App developers and reviewers can see how a document type is stored, and what an index keyword costs in storage and proofs, without reading Drive.
  • The contract visualizer can show it per document type, and link each layer to the GroveDB structure viewer, where the general description of that kind of layer lives.
  • A test holds the function to what Drive really writes: it inserts documents for 19 contracts and fails if any stored element differs from the computed layout, or if the layout names a layer Drive did not write. The layout cannot quietly go stale.

Risks: Low, and no consensus change.

  • The insert, update and delete walkers are touched only to move three small decisions they already made into shared functions, so the walkers and the layout use the same code. Nothing else in them changes. The decisions and error messages are identical, and the rs-drive document tests pass.
  • The layout follows the walkers of protocol version 14 (unreleased). For an earlier version, whose walkers pick other trees for some shapes, it refuses rather than return a layout Drive does not write.
  • Three rule files now also compile under rs-drive's verify feature (the one wasm-sdk uses). No new crate enters the wasm build: grovedb already depends on grovedb-merk there.

Issue being fixed or feature implemented

The contract visualizer needs a way to show a document type's index structure. The GroveDB structure description (grovedb-structure.json) covers every document type at once, so its document layers are templates: "an index property" that can be any of 8 tree kinds. The rules that pick the kind for a given index (primary_key_tree_type, property_name_tree_type_and_ranked_axes_for_level, index_level_tree_types_with_continuation_demotion, terminal_member_tree_type, and the wrapper choice for continuation trees) were server-only, so no client could compute a concrete layout.

What was done?

  • drive::document::layout (new, server or verify):
    • document_type_layout(document_type, platform_version) -> DocumentTypeLayout walks the document type's IndexLevel structure. It refuses (UnknownVersionMismatch) a platform version whose index walkers are not v2, i.e. before protocol version 14. For each layer it gives:
      • the key: fixed (the type name, [0], a property name, a time-window grid key such as $createdAt#86400#3600, a flat indexOnly key) or a family of keys (the document id, a property's values, the window starts, an indexOnly entry's terminal components, the revision time);
      • the element: the tree type, or Item / ItemWithSumItem / Reference / ReferenceWithSumItem;
      • the zero-contribution wrapper (NonCounted, NotSummed, NotCountedOrSummed), and the ranking axes of an indexed tree;
      • the indexes that use the layer;
      • conditions as notes: indexOnly, nullSearchable, contested, skipIfAbsent, preallocated, time-window overlap and TTL. skipIfAbsent is noted only on a property that can be absent: an optional, non-system property of an indexOnly type, the only case where Drive skips the entry.
    • A unique index's [0] records its alternative: the tree of members Drive writes instead when a value is null. The alternative does not repeat the [0]'s indexes and notes.
    • Each layer names the node of the structure description it is an instance of (structure_node()), for linking to the viewer.
    • to_value() gives the JSON shape the SDK returns. A layer that has no wrapper or no alternative leaves the key out, and time-window seconds are plain numbers (not BigInts) in JavaScript.
    • For Rust callers, ZeroContributionWrapper is re-exported from layout, and LayoutRole::name and LayoutNote::code (the codes to_value emits) are public.
  • Shared rules:
    • primary_key_tree_type, ranked_index_tree_type and index_level_tree_types compile under verify as well as server, taking TreeType from grovedb-merk (a new optional direct dependency of rs-drive, enabled by both features). time_range_index_keys, which needs server-only key types, stays server-only.
    • The wrapper matrix of LowLevelDriveOperation::for_known_path_key_empty_tree_contributing_zero_to_parent moved into zero_contribution_wrapper, which returns a typed refusal; the dispatcher maps each refusal to its existing error text.
    • The condition "does this continuation tree contribute zero to its parent value tree", inlined in the v2 index walker, the preallocation path and the v1 update walker, moved into continuation_contributes_zero and level_counts_continuations.
    • The skipIfAbsent condition of the v2 top-level insert and delete walkers ("an unrequired property of an indexOnly type") moved into index_only_level_skips_when_absent, which the layout's note uses too.
  • wasm-sdk: documentTypeLayout(contract, documentTypeName, platformVersion), with a DocumentTypeLayout TypeScript type. evo-sdk re-exports it. It borrows the contract through a new AsRef<DataContract> for wasm-dpp2's DataContractWasm, rather than cloning it.
  • Docs: a One document type's layout section in the book's GroveDB structure chapter, and a How a document type is stored section in the evo-sdk README.

In-place changes to shipped generations

  • add_indices_for_index_level_for_contract_operations v2 and the preallocation path now call continuation_contributes_zero(parent_value_tree_type, parent_counts_continuations, sub_level). The function returns exactly what the inlined condition did: !matches!(parent_value_tree_type, TreeType::NormalTree) && (!parent_counts_continuations || sub_level.count_exempt_branch()). level_counts_continuations(level) is the inlined level.ranked_count_grouping() || level.count_propagating().
  • for_known_path_key_empty_tree_contributing_zero_to_parent now matches on zero_contribution_wrapper, a direct transcription of its former match:
    • same arms, same helper for each (NonCounted, NotCountedOrSummed, NotSummed, or the unwrapped insert);
    • same four NotSupported errors, with the same text.
  • update_document_for_contract_operations v1 (the update walker protocol version 14 selects) now calls the same two functions: at its two continuation dispatches (plain and bucketed) and at the four places it tracks whether a level counts its continuations. Each matches!(parent_value_tree_type, TreeType::NormalTree) || (parent_counts_continuations && !level.count_exempt_branch()) is !continuation_contributes_zero(parent_value_tree_type, parent_counts_continuations, level), and each level.ranked_count_grouping() || level.count_propagating() is level_counts_continuations(level).
  • add_indices_for_top_index_level_for_contract_operations v2 and remove_indices_for_top_index_level_for_contract_operations v2 now skip with index_only_level_skips_when_absent(document_type, property_name), which returns exactly the inlined document_type.index_only() && !document_type.required_fields().contains(property_name).
  • These are used by the v2 walkers and the v1 update walker, which only protocol version 14 (unreleased) selects. The refactor cannot change what is written for any input, and the rs-drive document tests, whose index tests insert, update and delete through these paths, pass unchanged.

Before and after

The marketplace example's listing type (byShop over shopId, $createdAt countable; byCategoryPrice; newListings, a daily window stepping hourly over $createdAt, countable; documentsCountable):

  • Before: the structure viewer shows index_property → value → members / next_property, each "one of" several tree kinds. Which kind listing gets is only in the insert code.
  • After: documentTypeLayout(contract, 'listing', v14), printed as a tree:
listing  Tree
├─ PrimaryKey  CountTree
│  └─ <documentId>  Item
├─ $createdAt#86400#3600  Tree  [newListings]
│  └─ <$createdAt window>  CountTree  [newListings]
│     └─ Members  CountTree  [newListings]
│        └─ <documentId>  Reference
├─ category  Tree  [byCategoryPrice]
│  └─ <category>  Tree  [byCategoryPrice]
│     └─ price  Tree  [byCategoryPrice]
│        └─ <price>  Tree  [byCategoryPrice]
│           └─ Members  Tree  [byCategoryPrice]
│              └─ <documentId>  Reference
└─ shopId  Tree  [byShop]
   └─ <shopId>  Tree  [byShop]
      └─ $createdAt  Tree  [byShop]
         └─ <$createdAt>  CountTree  [byShop]
            └─ Members  CountTree  [byShop]
               └─ <documentId>  Reference

An indexOnly type with a ranked, summed index (the Drive test contract's tip), and DPNS's unique name index with its fallback:

tip  Tree
├─ $ownerId  Tree  [byTipperAmount]
│  └─ <$ownerId>  Tree  [byTipperAmount]
│     └─ amount  Tree  [byTipperAmount]
│        └─ <amount>  Tree  [byTipperAmount]
│           └─ Members  Tree  [byTipperAmount]
│              └─ <postId>  Item
└─ postId  ProvableCountProvableSumIndexedTree ranked by count,sum  [byPost]
   └─ <postId>  ProvableCountProvableSumTree  [byPost]
      └─ Members  ProvableCountProvableSumTree  [byPost]
         └─ <$ownerId>  ItemWithSumItem

domain  Tree
├─ PrimaryKey  Tree
│  └─ <documentId>  Item
├─ normalizedParentDomainName  Tree  [parentNameAndLabel]
│  └─ <normalizedParentDomainName>  Tree  [parentNameAndLabel]
│     └─ normalizedLabel  Tree  [parentNameAndLabel]
│        └─ <normalizedLabel>  Tree  [parentNameAndLabel]
│           └─ Unique reference  Reference  [parentNameAndLabel]
│                 (when an indexed value of the document is null: Tree of <documentId> Reference)
└─ records.identity  Tree  [identityId]
   └─ ...

How Has This Been Tested?

  • cargo test -p drive --lib drive::document::layout: 5 tests.
    • should_lay_out_what_drive_writes applies 19 contracts from tests/supporting_files: family (plain, optional fields, countable, with history), dashpay, references, restaurants, trending (with the sibling variant), the Yappr likes (plain and two preallocated variants), the Yappr feed, index-only scalar terminal, tally, tip-jar, and grades (plain, ranked, compound ranked).
    • It inserts 7 random documents per type; two leave out the optional properties of unique indexes, so the null fallback is written. It then walks GroveDB under every document type and compares every element's kind and wrapper with the layout. It also checks the other way: every layer the layout names under a tree Drive wrote must have been written, except where a document may leave it empty (a terminal with nullSearchable: false, a preallocated terminal's entries, a skipIfAbsent level's values). It also requires the fixtures to reach every layer role, at least one wrapper, one ranked tree, one time window, one index entry and one null fallback.
    • Summed properties get small values, because random integers ignore the schema's bounds and overflow a provable sum tree.
    • Mutation checks: making the layout's terminal trees always plain fails the test, with messages like Terminal "Members" ... Drive wrote CountTree where the layout says Tree. Giving indexOnly types a primary key tree fails it with the layout has PrimaryKey "PrimaryKey" but Drive wrote nothing there.
    • should_name_a_node_of_the_structure_description_for_every_layer checks each role's structure_node() against drive_structure().
    • should_store_each_document_of_a_type_with_history_as_a_tree_of_revisions.
    • should_refuse_a_version_that_selects_other_index_walkers: protocol version 13 (v1 walkers) is refused, the latest is not.
    • should_skip_only_an_optional_property_of_an_index_only_type_when_absent: in the Yappr likes contract, the required mark.a and the system $ownerId carry no skip note, the optional mark.b does, and tip (not skipping) has none.
  • cargo test -p drive --lib: 3947 passed, 6 ignored, 0 failed.
  • cargo clippy -p drive --all-targets, cargo clippy -p drive --no-default-features --features verify, and cargo clippy -p wasm-sdk -p wasm-dpp2 --target wasm32-unknown-unknown: clean. cargo fmt: clean.
  • yarn workspace @dashevo/wasm-sdk build, then mocha tests/unit/document-type-layout.spec.ts: 7 passing. The spec covers:
    • the document type and primary key;
    • a time window level, with its grid key and its window, range and step seconds as numbers;
    • a countable terminal and a shared prefix, whose continuation is wrapped in NonCounted;
    • a unique reference with its null fallback;
    • a ranked ProvableCountIndexedTree with a count axis;
    • an indexOnly member key;
    • an unknown type refused.
  • eslint on the new spec: clean.
  • Not run locally: the Karma browser run of the wasm-sdk spec, and drive-abci (it does not use the changed crate-private functions).

Breaking Changes

None.

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 · f3e69c4

  • 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 — this one is beyond the limit; it waits until one merges
  • Build running
  • Approvals
    • files with no dedicated owner — you own it
    • js-wasm-sdk (packages/js-evo-sdk/README.md, packages/wasm-sdk/src/document_type_layout.rs, packages/wasm-sdk/src/lib.rs and 1 more) — shumkov
    • rs-drive — you own it

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

Summary by CodeRabbit

  • New Features
    • Added the documentTypeLayout API, which locally shows how a document type is stored, including its indexes, tree and element types, and conditional layout choices.
    • Added layout documentation and examples.
  • Bug Fixes
    • Improved consistency in how empty index continuation trees contribute to parent counts and sums.

`drive::document::layout::document_type_layout` returns the concrete
GroveDB layout of one document type: the document type tree, the
documents by id (with history when kept), and for each index the property
and value trees down to where it ends, each with the tree or element type
Drive writes, the zero-contribution wrapper a continuation tree gets under
an aggregating value tree, the ranking axes of an indexed tree, the
indexes that use the layer and conditions (a unique index's tree of
members when a value is null, nullSearchable, skipIfAbsent, preallocated,
time windows). Each layer names the node of the structure description it
is an instance of.

The tree types come from the functions the index walkers call, which now
compile under `verify` too (TreeType from grovedb-merk, which grovedb
already depends on in both builds). The wrapper matrix of
`for_known_path_key_empty_tree_contributing_zero_to_parent` and the
continuation condition both walkers inlined are extracted into
`zero_contribution_wrapper` and `continuation_contributes_zero`, shared by
the walkers, the preallocation path and the layout; decisions and error
messages are unchanged. `layout_matches_what_drive_writes` applies 19
contracts covering every index shape, inserts documents and fails on any
element whose kind or wrapper the layout does not predict.

wasm-sdk (and so evo-sdk) exposes it as
`documentTypeLayout(contract, documentTypeName, platformVersion)`.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@github-actions

github-actions Bot commented Sep 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-09-28T20:28:38.302Z

@github-actions github-actions Bot added the waiting-bots Waiting for the review bots to report on this head label Sep 28, 2026
@github-actions github-actions Bot added this to the v4.2.0 milestone Sep 28, 2026
@coderabbitai

coderabbitai Bot commented Sep 28, 2026 •

Copy link
Copy Markdown
Contributor

Review in Change Stack →

Navigate logical layers of code changes, visualize relationships, and explore their blast radius.

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

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

Review profile: CHILL

Plan: Advanced

Run ID: f45de5c1-2374-44e5-b471-92a1d84f5500

📥 Commits

Reviewing files that changed from the base of the PR and between 1464314 and dd60f0b.

📒 Files selected for processing (14)
  • book/src/drive/grovedb-structure.md
  • packages/js-evo-sdk/README.md
  • packages/rs-drive/Cargo.toml
  • packages/rs-drive/src/drive/document/index_level_tree_types.rs
  • packages/rs-drive/src/drive/document/insert/add_indices_for_index_level_for_contract_operations/v2/mod.rs
  • packages/rs-drive/src/drive/document/insert/add_preallocated_index_tree_operations/mod.rs
  • packages/rs-drive/src/drive/document/layout.rs
  • packages/rs-drive/src/drive/document/mod.rs
  • packages/rs-drive/src/drive/document/primary_key_tree_type.rs
  • packages/rs-drive/src/drive/document/ranked_index_tree_type.rs
  • packages/rs-drive/src/fees/op.rs
  • packages/wasm-sdk/src/document_type_layout.rs
  • packages/wasm-sdk/src/lib.rs
  • packages/wasm-sdk/tests/unit/document-type-layout.spec.ts

Included review availability: This review used your included allowance. Your plan provides up to 1 included review per hour; 0 remain after this review.


📝 Walkthrough

Walkthrough

Drive now builds a recursive layout for a document type from its contract and platform version. The layout records tree and element details, keys, wrappers, indexes, and conditional alternatives. The WASM SDK exposes this layout through documentTypeLayout, with Rust and JavaScript tests covering its structure.

Changes

Document Type Layout

Layer / File(s) Summary
Shared continuation and wrapper decisions
packages/rs-drive/Cargo.toml, packages/rs-drive/src/drive/document/..., packages/rs-drive/src/fees/op.rs
Shared helpers select continuation contribution behavior and zero-contribution wrappers. Index insertion, preallocation, and fee operations use these helpers.
Drive layout model and validation
packages/rs-drive/src/drive/document/layout.rs, packages/rs-drive/src/drive/document/mod.rs, book/src/drive/grovedb-structure.md
Drive builds and serializes a recursive document-type layout, including index paths, time-range buckets, wrappers, and alternatives. Tests compare modeled layouts with stored elements. The layout module is available with server or verify.
WASM API and SDK coverage
packages/wasm-sdk/src/document_type_layout.rs, packages/wasm-sdk/src/lib.rs, packages/wasm-sdk/tests/unit/document-type-layout.spec.ts, packages/js-evo-sdk/README.md
The WASM SDK exposes documentTypeLayout and its TypeScript result shape. Unit tests cover layout features and missing document types; the SDK README documents the API.

Priority: ➖ Normal

Estimated code review effort: 4 (Complex) | ~60 minutes

Change: Feature

Sequence Diagram(s)

sequenceDiagram
  participant JavaScriptCaller
  participant WasmDocumentTypeLayout
  participant DriveDocumentTypeLayout
  JavaScriptCaller->>WasmDocumentTypeLayout: contract, document type name, platform version
  WasmDocumentTypeLayout->>DriveDocumentTypeLayout: compute document type layout
  DriveDocumentTypeLayout-->>WasmDocumentTypeLayout: layout model
  WasmDocumentTypeLayout-->>JavaScriptCaller: serialized layout object
Loading

Suggested reviewers: shumkov, pastapastapasta

Merge Risk: ⚪ Minimal · up to dd60f

No actionable issue is established before merge. The verify-only configuration still needs validation when its dependency is available.

Security Architecture Review

Security architecture risk: 🟡 Moderate · up to dd60f

The new layout API does not appear to expose stored documents or grant storage access. A separate change can alter which index trees are written for some document values, so its compatibility across versions needs confirmation before treating the change as storage-neutral.

Retained concerns

  • Medium · security · inferred: The new width check can skip persistent preallocated index trees that the base insertion path would attempt to create. If an accepted contract permits a wider referenced property, identical document insertion across versions may yield different storage state; no version gate is visible in this changed path.
Security review details

Security Blast Radius

  • inferred — The potential state-integrity effect is limited to document inserts using a preallocation binding with a referenced value wider than its referring property. Its reachable contract and deployment scope are not established.

Security Findings and Attack Paths

  • inferred — If an accepted binding allows different property widths, a document author can supply a value within the referenced property's allowance but beyond the referring property's maximum. The head path skips that binding; the base path did not perform this skip. Whether this input is accepted and can produce cross-version state divergence remains unverified.

Trust Boundaries and Controls

  • observed — The layout API converts caller-provided inputs and looks up the requested type before calculating the result. It does not itself authorize access to a store; no independent host resource limit was established by the inspected path.

Resilience and Maintainability Implications

  • observed — The shared continuation helpers are pure predicates, and the inspected writer retains its zero-wrapper and if-not-exists insertion branches with transaction and batch arguments. This counters a separate concern that extracting those predicates changed insertion ordering or authority.

Hardening Proposals

  • proposed — Establish whether accepted bindings can have unequal encoded widths, then compare base and head storage outcomes for such an insert under the intended protocol and rollback rules.
🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 56.86% which is insufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff. Analyzed 51 functions across 11 files. (3 skipped:… 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 describes the main change: computing a document type's GroveDB layout for the SDKs.
Full details: Docstring Coverage

Explanation

Docstring coverage is 56.86% which is insufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff. Analyzed 51 functions across 11 files. (3 skipped: 3 unsupported.)

  • Fix all pre-merge checks with AI
✨ Finishing Touches 💡 1
📝 Generate docstrings 💡
  • Commit to this branch
  • Create a new PR
🧪 Generate unit tests (beta)
  • Commit to this branch
  • Create a new PR

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.

@thepastaclaw

thepastaclaw commented Sep 28, 2026 •

Copy link
Copy Markdown
Collaborator

🕓 Queued for automated review — 1st in line, estimated start in ~25 min (commit f3e69c4)
Estimated review time once started: ~55 min (two-phase automated review; median of recent runs).

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

QuantumExplorer and others added 3 commits September 29, 2026 02:24
The layout's rangeSeconds / stepSeconds / phaseSeconds were u64 values,
which reach JS as BigInts while the TypeScript type says number. Every
valid window fits a u32, so they are emitted as u32 (a float above that).
The wasm-sdk spec checks a time window level's key.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The layout noted "a document that leaves out $ownerId writes nothing" on
an indexOnly type's $ownerId level. The walker skips only when the value
is absent, and a system property never is where it is indexed. The note
now goes on non-system properties the type does not require, as the walker
decides; a test covers a required, an optional and a system first property.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…t value

serde-wasm-bindgen turns a null into undefined, so JS never received the
null the TypeScript type promised for a node without a wrapper or an
alternative. The value now leaves those keys out, and the type marks them
optional.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…test both ways

Review fixes for the document type layout:
- document_type_layout refuses a platform version whose index walkers are
  not v2 (protocol version 13 and earlier pick other trees for some shapes).
- The v1 update walker calls continuation_contributes_zero and
  level_counts_continuations instead of its own copies, and the v2
  top-level insert and delete walkers skip with the new
  index_only_level_skips_when_absent, which the layout's note uses too.
  Each call returns exactly the expression it replaces (consensus
  neutral; these walkers are selected only by protocol version 14).
- The conformance test also fails on a layout layer Drive did not write.
- One tree-type call per level; the unique null fallback no longer repeats
  the terminal's indexes and notes; a redundant flat-index guard dropped.
- ZeroContributionWrapper re-exported from layout; LayoutRole::name and
  LayoutNote::code public.
- wasm-dpp2 DataContractWasm implements AsRef<DataContract>, so the
  binding borrows the contract instead of cloning it.
- Tests renamed to "should ..."; README marks wrapper/alternative optional;
  the book states what the fixtures cover.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

@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.

Approved

@QuantumExplorer
QuantumExplorer merged commit c795f81 into v4.2-dev Sep 28, 2026
26 of 27 checks passed
@QuantumExplorer
QuantumExplorer deleted the feat/drive-document-type-layout branch September 28, 2026 20:31
QuantumExplorer added a commit to dashpay/contract-visualizer that referenced this pull request Sep 28, 2026
dashpay/platform#5153 merged with a review fix: a unique index's null
fallback no longer repeats the terminal's indexes and notes.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
PastaPastaPasta added a commit that referenced this pull request Sep 28, 2026
Pick up #5156 (validate runner candidates using full commit statuses),
#5153 and #5147.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
@PastaPastaPasta PastaPastaPasta mentioned this pull request Sep 28, 2026
2 of 24 tasks
QuantumExplorer added a commit to dashpay/contract-visualizer that referenced this pull request Sep 29, 2026
* docs: say what the example check runs: the parser, not the meta-schema

@dashevo/evo-sdk is built without dpp's validation feature, so
DataContract.fromJSON(json, true, 14) runs the contract parser but not the
document meta-schema or the parser checks gated behind that feature. The
README, the examples registry and the validation script claimed more.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* feat: show a document type's GroveDB layout, computed by Drive

A "GroveDB layout" button in the inspector opens every tree and element
Drive writes for the selected document type: the documents by id (and
revisions), and for each index the property and value trees down to the
[0] where it ends, with each layer's element (count, sum, ranked, ...),
its zero-contribution wrapper, the indexes that use it, conditions (the
null fallback of a unique index, skipIfAbsent, preallocated, time window
overlap) and a link to that kind of layer in the GroveDB structure viewer.

The layout comes from documentTypeLayout in @dashevo/evo-sdk
(dashpay/platform#5153), so it follows Drive's own rules. It is
feature-detected: with an SDK that predates it, the panel says so.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* test: refresh the layout fixtures from the merged documentTypeLayout

dashpay/platform#5153 merged with a review fix: a unique index's null
fallback no longer repeats the terminal's indexes and notes.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
QuantumExplorer added a commit to dashpay/contract-visualizer that referenced this pull request Sep 29, 2026
* docs: say what the example check runs: the parser, not the meta-schema

@dashevo/evo-sdk is built without dpp's validation feature, so
DataContract.fromJSON(json, true, 14) runs the contract parser but not the
document meta-schema or the parser checks gated behind that feature. The
README, the examples registry and the validation script claimed more.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* feat: show a document type's GroveDB layout, computed by Drive

A "GroveDB layout" button in the inspector opens every tree and element
Drive writes for the selected document type: the documents by id (and
revisions), and for each index the property and value trees down to the
[0] where it ends, with each layer's element (count, sum, ranked, ...),
its zero-contribution wrapper, the indexes that use it, conditions (the
null fallback of a unique index, skipIfAbsent, preallocated, time window
overlap) and a link to that kind of layer in the GroveDB structure viewer.

The layout comes from documentTypeLayout in @dashevo/evo-sdk
(dashpay/platform#5153), so it follows Drive's own rules. It is
feature-detected: with an SDK that predates it, the panel says so.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* test: refresh the layout fixtures from the merged documentTypeLayout

dashpay/platform#5153 merged with a review fix: a unique index's null
fallback no longer repeats the terminal's indexes and notes.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* feat: show what a document costs, in Dash and dollars, per index

Selecting a document type shows about what one of its documents costs;
Cost opens the breakdown, computed by Drive (documentCreateCost in
@dashevo/evo-sdk, dashpay/platform#5159): the first document with a set
of index values and a later one with the same values; the storage of
the document itself and of each index on its own (the part it shares
with other indexes, paid once, and its own); prepaid trees and a ttl
type's expiration entry; the processing (exact parts marked, the rest
estimated for a number of stored documents, a key type and a fee
increase); the contract's action fee, token cost and contest fund; and
the refund on delete. "Adjust the document" gives an on/off switch per
optional field and a length per variable-size one; fixed-size fields
need no input.

The Dash price comes from CoinGecko (Coinbase if that fails), kept five
minutes, and can be typed in. Feature-detected: with an SDK that
predates documentCreateCost the inspector says so. The layout and cost
loaders share one local SDK module.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 5.5 <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