Skip to content

feat(drive): describe the GroveDB structure as code - #4845

Merged
QuantumExplorer merged 3 commits into
v4.2-devfrom
claude/grovedb-structure-viewer-c313a8
Sep 20, 2026
Merged

QuantumExplorer merged 3 commits into
v4.2-devfrom
claude/grovedb-structure-viewer-c313a8

Conversation

@QuantumExplorer

@QuantumExplorer QuantumExplorer commented Sep 20, 2026 •

Copy link
Copy Markdown
Member

Issue being fixed or feature implemented

Nothing shows the whole GroveDB layout Drive builds. The book draws single subtrees, and the root tree comment in drive/mod.rs had fallen behind (no ContractGroups). There was no machine readable description at all, so nothing could draw the structure or tell what a pull request adds to it.

This is the first of three parts:

  1. This PR: the complete structure declared as Rust in rs-drive, kept honest by tests, exported to packages/rs-drive/grovedb-structure.json.
  2. The viewer, a static site in its own repository that reads that file by git ref: https://dashpay.github.io/grovedb-structure-viewer/ (dashpay/grovedb-structure-viewer).
  3. A follow-up PR: a workflow that comments a viewer link on every pull request that changes the structure (showing what is new), a book chapter, a coding conventions checklist and a PR template line.

What was done?

  • New module drive::structure (packages/rs-drive/src/structure): the node model, a builder, a lint, a conformance walker and the export types. Each area declares its part in a structure.rs beside its paths.rs, from the real key constants (RootTree::Tokens as u8, TOKEN_BALANCES_KEY, IdentityRootStructure::IdentityTreeKeys as u8), so key bytes cannot drift. 215 nodes cover all 18 root trees down to the leaves.
  • A node carries its key (fixed bytes and the constant they come from, or a template such as "identity id, 32 bytes"), the element kinds that can sit there (several when the code chooses, as the document primary key tree does between eight kinds), the first protocol version it exists in, whether it is created with its parent or lazily, what an item holds, reference and recurse targets (index levels repeat to any depth), its source file and its book chapter.
  • The module is compiled for tests and under a new structure feature only (structure = ["server"], not in default). drive-abci does not enable it, so the node never builds it and nothing on the block execution path can depend on it.
  • ElementKind::of maps grovedb::Element with an exhaustive match and no wildcard, so a GroveDB upgrade that adds an element variant fails to compile until the description knows about it.
  • check_conformance walks a real GroveDB layer by layer and reports every element no node describes, every kind mismatch, every node outside its protocol versions and every missing node that should exist with its parent.
  • grovedb-structure.json also records the exact Merk binary tree of every layer whose keys are all fixed (12 layers, the root included). GroveDB does not expose Merk links, but a proof does: the layer is proved with a full range query and the merk proof operations are replayed (grovedb-merk added as a dev-dependency of rs-drive, already in the lockfile). Shapes carry their origin (genesis@14), since the shape depends on insertion order and an upgraded chain can differ.
  • The root tree comment in drive/mod.rs now shows ContractGroups below Versions, as the recorded shape does.
  • initialization::genesis_core_height becomes pub(crate) so the Misc description can use GENESIS_CORE_HEIGHT_KEY.

A change that adds a root tree, a subtree key or a level now fails rs-drive tests until it is described, and describing it changes the JSON, which is what the follow-up workflow keys on.

How Has This Been Tested?

cargo test -p drive --lib structure:: (15 tests):

  • the lint: identifiers unique, reference and recurse targets exist, every source file exists and names the constant a key claims to come from, no two templates of a layer can claim the same element;
  • should_match_initial_structure_for_every_protocol_version: for protocol versions 1 to 14, builds the initial state structure and requires zero violations. This pins every since to what create_initial_state_structure v0 to v4 and the version gates in the withdrawal structure really build;
  • populated fixtures (identities with contract nonces, five contracts with random documents including document and contract history and countable indexes, a token with mint, freeze, pause and price, an active and a closed group action, address balances, a prefunded balance, a proposed version) must conform, and every node must be reached by a fixture or be listed in UNVERIFIED with the reason. The test also fails when a listed node is reached, so the list can only shrink. Still listed: token distributions, contract bound identity keys, key budgets, epoch fields written by block execution, withdrawal and asset lock contents, shielded pool contents, contested votes and contract groups;
  • four walker tests prove it reports an undescribed element, a kind mismatch, a missing node and an element from a later protocol version;
  • the golden file test (UPDATE_GROVEDB_STRUCTURE=1 cargo test -p drive --lib structure::tests rewrites it) and a test that the recorded root shape has DataContractDocuments on top with Identities and Balances below.

Also: cargo clippy -p drive --all-targets clean, cargo check -p drive --features structure, --no-default-features --features server and --no-default-features --features verify.

Breaking Changes

None. No consensus code changes; the new module is not compiled into the node.

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

🤖 Generated with Claude Code

Summary by CodeRabbit

  • New Features

    • Added a structured description of Drive storage, covering identities, contracts, documents, tokens, balances, voting, withdrawals, and other data areas.
    • Added tools to inspect storage layouts, export structure metadata, and identify tree-layer shapes.
    • Added validation for storage conformance, metadata consistency, protocol-version compatibility, and source references.
  • Tests

    • Added comprehensive checks for structure definitions, generated documentation, protocol compatibility, and representative Drive data.

Nothing showed the whole GroveDB layout Drive builds: the book draws
single subtrees and the root tree comment in drive/mod.rs had fallen
behind (no ContractGroups). This adds a description of every level, from
the 18 root trees down to the leaves, declared in Rust from the real key
constants and kept honest by tests.

- `drive::structure` holds the node model, a builder, a lint, a
  conformance walker and the JSON export types. Each area declares its
  part in a `structure.rs` beside its `paths.rs`. The module is compiled
  for tests and under the new `structure` feature only, so the node never
  builds it.
- A node carries its key (fixed bytes and the constant they come from, or
  a template such as "identity id, 32 bytes"), the element kinds that can
  sit there, the first protocol version it exists in, whether it is created
  with its parent, what an item holds, reference and recursion targets,
  its source file and book chapter.
- The conformance walker reads a real GroveDB layer by layer and reports
  every element no node describes, every kind mismatch, every node outside
  its protocol versions and every missing node. Tests run it on the initial
  state structure of every protocol version and on populated fixtures
  (identities, contracts with documents and history, tokens, group actions,
  address balances). A coverage gate lists the nodes no fixture reaches
  yet; the list can only shrink.
- `packages/rs-drive/grovedb-structure.json` is the serialized description
  the GroveDB structure viewer reads by git ref. A test fails when it is
  stale; `UPDATE_GROVEDB_STRUCTURE=1 cargo test -p drive --lib
  structure::tests` rewrites it.
- The JSON also records the exact Merk binary tree of layers whose keys are
  all fixed, rebuilt by replaying the proof of a full range query
  (`grovedb-merk` as a dev-dependency). The root tree comment now shows
  ContractGroups below Versions, as the recorded shape does.

`initialization::genesis_core_height` becomes `pub(crate)` so the Misc
description can use `GENESIS_CORE_HEIGHT_KEY`.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
@github-actions github-actions Bot added this to the v4.2.0 milestone Sep 20, 2026
@github-actions

github-actions Bot commented Sep 20, 2026 •

Copy link
Copy Markdown
Contributor

PR Hygiene

State: waiting-bots · commit e035450dacfa46329ad6eb3c51bb84560af1d1db

  • coderabbitai has not reported for the current head
  • thepastaclaw has not reported for the current head

Self-review is an author attestation that you have read the diff:
/self-reviewed — covers everything pushed so far; post it again after a new push.

This check passes when the policy is satisfied; the repository decides whether merging requires it.

@coderabbitai

coderabbitai Bot commented Sep 20, 2026 •

Copy link
Copy Markdown
Contributor

Review Change StackReview Change Stack

Warning

Review limit reached

Next included review available in 25 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: 1baf8658-0a25-408c-ad97-652bb988a26b

📥 Commits

Reviewing files that changed from the base of the PR and between 4f7a2e1 and e035450.

📒 Files selected for processing (22)
  • packages/rs-drive/grovedb-structure.json
  • packages/rs-drive/src/drive/address_funds/structure.rs
  • packages/rs-drive/src/drive/asset_lock/structure.rs
  • packages/rs-drive/src/drive/balances/structure.rs
  • packages/rs-drive/src/drive/contract/structure.rs
  • packages/rs-drive/src/drive/contract_groups/structure.rs
  • packages/rs-drive/src/drive/credit_pools/structure.rs
  • packages/rs-drive/src/drive/document/structure.rs
  • packages/rs-drive/src/drive/group/structure.rs
  • packages/rs-drive/src/drive/identity/structure.rs
  • packages/rs-drive/src/drive/identity/withdrawals/structure.rs
  • packages/rs-drive/src/drive/prefunded_specialized_balances/structure.rs
  • packages/rs-drive/src/drive/protocol_upgrade/structure.rs
  • packages/rs-drive/src/drive/saved_block_transactions/structure.rs
  • packages/rs-drive/src/drive/shielded/structure.rs
  • packages/rs-drive/src/drive/system/structure.rs
  • packages/rs-drive/src/drive/tokens/structure.rs
  • packages/rs-drive/src/drive/votes/structure.rs
  • packages/rs-drive/src/structure/builder.rs
  • packages/rs-drive/src/structure/conformance.rs
  • packages/rs-drive/src/structure/mod.rs
  • packages/rs-drive/src/structure/tests.rs

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: c73d5ff0-f17f-4f3c-a8ea-4b36fcae96f6

📥 Commits

Reviewing files that changed from the base of the PR and between 6def218 and 4f7a2e1.

⛔ Files ignored due to path filters (1)
  • Cargo.lock is excluded by !**/*.lock
📒 Files selected for processing (49)
  • Cargo.toml
  • packages/rs-drive/Cargo.toml
  • packages/rs-drive/grovedb-structure.json
  • packages/rs-drive/src/drive/address_funds/mod.rs
  • packages/rs-drive/src/drive/address_funds/structure.rs
  • packages/rs-drive/src/drive/asset_lock/mod.rs
  • packages/rs-drive/src/drive/asset_lock/structure.rs
  • packages/rs-drive/src/drive/balances/mod.rs
  • packages/rs-drive/src/drive/balances/structure.rs
  • packages/rs-drive/src/drive/contract/mod.rs
  • packages/rs-drive/src/drive/contract/structure.rs
  • packages/rs-drive/src/drive/contract_groups/mod.rs
  • packages/rs-drive/src/drive/contract_groups/structure.rs
  • packages/rs-drive/src/drive/credit_pools/mod.rs
  • packages/rs-drive/src/drive/credit_pools/structure.rs
  • packages/rs-drive/src/drive/document/mod.rs
  • packages/rs-drive/src/drive/document/structure.rs
  • packages/rs-drive/src/drive/group/mod.rs
  • packages/rs-drive/src/drive/group/structure.rs
  • packages/rs-drive/src/drive/identity/mod.rs
  • packages/rs-drive/src/drive/identity/structure.rs
  • packages/rs-drive/src/drive/identity/withdrawals/mod.rs
  • packages/rs-drive/src/drive/identity/withdrawals/structure.rs
  • packages/rs-drive/src/drive/initialization/mod.rs
  • packages/rs-drive/src/drive/mod.rs
  • packages/rs-drive/src/drive/prefunded_specialized_balances/mod.rs
  • packages/rs-drive/src/drive/prefunded_specialized_balances/structure.rs
  • packages/rs-drive/src/drive/protocol_upgrade/mod.rs
  • packages/rs-drive/src/drive/protocol_upgrade/structure.rs
  • packages/rs-drive/src/drive/saved_block_transactions/mod.rs
  • packages/rs-drive/src/drive/saved_block_transactions/structure.rs
  • packages/rs-drive/src/drive/shielded/mod.rs
  • packages/rs-drive/src/drive/shielded/structure.rs
  • packages/rs-drive/src/drive/structure.rs
  • packages/rs-drive/src/drive/system/mod.rs
  • packages/rs-drive/src/drive/system/structure.rs
  • packages/rs-drive/src/drive/tokens/mod.rs
  • packages/rs-drive/src/drive/tokens/structure.rs
  • packages/rs-drive/src/drive/votes/mod.rs
  • packages/rs-drive/src/drive/votes/structure.rs
  • packages/rs-drive/src/lib.rs
  • packages/rs-drive/src/structure/builder.rs
  • packages/rs-drive/src/structure/conformance.rs
  • packages/rs-drive/src/structure/export.rs
  • packages/rs-drive/src/structure/kinds.rs
  • packages/rs-drive/src/structure/lint.rs
  • packages/rs-drive/src/structure/mod.rs
  • packages/rs-drive/src/structure/shape.rs
  • packages/rs-drive/src/structure/tests.rs

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


📝 Walkthrough

Walkthrough

Changes

The PR adds a feature-gated GroveDB structure model for Drive. It describes storage trees, validates declarations and live elements, replays fixed-key Merk layers, exports structure metadata, and tests conformance across protocol versions and populated fixtures.

Drive structure model

Layer / File(s) Summary
Structure contracts and builders
packages/rs-drive/src/structure/..., packages/rs-drive/Cargo.toml, Cargo.toml
The crate adds structure node types, key matchers, element-kind metadata, builder methods, serialized document types, and the structure feature.
Drive storage descriptions
packages/rs-drive/src/drive/...
Feature-gated builders describe storage trees for identities, contracts, documents, tokens, balances, votes, withdrawals, pools, and other Drive areas. root_structure() assembles these descriptions.
Structure validation and layer shapes
packages/rs-drive/src/structure/conformance.rs, packages/rs-drive/src/structure/lint.rs, packages/rs-drive/src/structure/shape.rs
The PR adds declaration linting, GroveDB conformance checks, and proof-based extraction of fixed-key Merk layer shapes.
Structure synchronization tests
packages/rs-drive/src/structure/tests.rs
Tests cover linting, protocol versions, exported JSON synchronization, violation reporting, populated fixtures, and structure-node coverage.

Priority: ➖ Normal

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

Change: Feature

Sequence Diagram(s)

sequenceDiagram
  participant StructureTests
  participant Drive
  participant GroveDB
  participant StructureNode
  participant ConformanceReport
  StructureTests->>Drive: build structure fixtures
  StructureTests->>StructureNode: obtain drive_structure()
  StructureTests->>GroveDB: create and inspect storage
  StructureTests->>ConformanceReport: run check_conformance()
  ConformanceReport->>StructureNode: resolve keys and validate elements
  ConformanceReport-->>StructureTests: return violations and visited nodes
Loading
🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 75.51% which is insufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff. Analyzed 98 functions across 46 files. (2 skipped:… Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly and concisely describes the main change: adding a code-based description of the GroveDB structure.
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.
Full details: Docstring Coverage

Explanation

Docstring coverage is 75.51% which is insufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff. Analyzed 98 functions across 46 files. (2 skipped: 2 unsupported.)

✨ 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 20, 2026 •

Copy link
Copy Markdown
Collaborator

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

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

@codecov

codecov Bot commented Sep 20, 2026 •

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 87.47795% with 355 lines in your changes missing coverage. Please review.
✅ Project coverage is 76.13%. Comparing base (7e43d43) to head (e035450).
⚠️ Report is 3 commits behind head on v4.2-dev.

Files with missing lines Patch % Lines
packages/rs-drive/src/structure/conformance.rs 62.67% 78 Missing ⚠️
packages/rs-drive/src/structure/lint.rs 68.25% 40 Missing ⚠️
packages/rs-drive/src/drive/identity/structure.rs 87.17% 39 Missing ⚠️
packages/rs-drive/src/drive/votes/structure.rs 89.51% 28 Missing ⚠️
...kages/rs-drive/src/drive/credit_pools/structure.rs 88.20% 23 Missing ⚠️
packages/rs-drive/src/structure/builder.rs 88.10% 22 Missing ⚠️
packages/rs-drive/src/drive/tokens/structure.rs 92.92% 21 Missing ⚠️
packages/rs-drive/src/structure/kinds.rs 62.22% 17 Missing ⚠️
packages/rs-drive/src/drive/document/structure.rs 90.79% 15 Missing ⚠️
...es/rs-drive/src/drive/contract_groups/structure.rs 93.85% 11 Missing ⚠️
... and 13 more
Additional details and impacted files
@@              Coverage Diff              @@
##           v4.2-dev    #4845       +/-   ##
=============================================
- Coverage     88.06%   76.13%   -11.93%     
=============================================
  Files          2980     3006       +26     
  Lines        389888   440822    +50934     
=============================================
- Hits         343348   335621     -7727     
- Misses        46540   105201    +58661     
Components Coverage Δ
dpp 73.77% <ø> (-16.09%) ⬇️
drive 77.80% <87.47%> (-9.37%) ⬇️
drive-abci 76.58% <ø> (-12.89%) ⬇️
sdk ∅ <ø> (∅)
dapi-client ∅ <ø> (∅)
platform-version ∅ <ø> (∅)
platform-value 86.29% <ø> (-6.69%) ⬇️
platform-wallet ∅ <ø> (∅)
drive-proof-verifier 25.16% <ø> (-12.63%) ⬇️
🚀 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 and others added 2 commits September 20, 2026 10:57
… values

Two ways a valid state failed the structure conformance check.

An epoch's storage fee item is created with the epoch tree and deleted
when the epoch is paid out, while the tree stays. The description could
only say "created with its parent", so a paid epoch reported the item as
missing. Presence gains a third state, `UntilDeleted`, which the walker
does not require. The proposers tree and the processing fee item, already
lazy, now say that payout deletes them too.

Below a contested index a 32 byte key is a contender's identity id at the
last level and an index value at the levels before it. The walker chose a
template by key length and kind alone, read such a value as a contender,
and then reported the poll's own keys below it as undescribed. Where
several templates accept a key and list the element's kind, the walker now
tries each and keeps the one whose description fits what is below the
element. The contender's description no longer documents the limitation.

Fixtures for both: an epoch while it runs and after payout, and two DPNS
contests, one with a 32 byte label. The contest fixture fails without the
lookahead with the violations from the review. They also reach the epoch
start fields, the proposers and the whole active poll layout, which leave
the UNVERIFIED list; the poll layout written from reading the insert code
turned out right.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
rustfmt gives up on a whole method chain when one string in it does not
fit the line, so the description files were left as written, with chains
on one line. Long descriptions now use line continuations and one long
identifier became a constant, which lets rustfmt lay the chains out.

No text changes: grovedb-structure.json is the same.

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

Copy link
Copy Markdown
Member Author

Both findings from the review at 4f7a2e1a8e are real. Fixed in b9746d8.

1. Paid epochs. add_mark_as_paid_operations deletes the epoch's storage fee item (with the proposers tree and the processing fee item) and keeps the epoch tree, so pools.epoch.storage_fees cannot be "created with its parent" and required forever. Presence gains a third state, UntilDeleted, which the walker does not require; the two lazy siblings now say that payout deletes them. New fixture: an epoch while it runs, then after payout, both must conform.

2. 32 byte contested index values. Key length cannot tell an index value from a contender one level up, and I had documented that in the node instead of fixing it. Where several templates accept a key and list the element's kind, the walker now tries each and keeps the one whose description fits what is below the element: a contender has [0] and [1] below it, an index value has the poll's 32 byte keys or the next value. New fixture: two DPNS contests, one with a 32 byte label. Without the lookahead it fails with the same violations as in the review (the three poll keys and the contender reported as undescribed under ...value.contender, plus contender.document and contender.votes missing); with it, it passes.

The two fixtures also reach the epoch start fields, the proposers and the whole active poll layout, so those leave the UNVERIFIED list. The poll layout had been written from reading the insert code and turned out right.

e035450 is formatting only: rustfmt had been skipping the description files because of over-long string literals. grovedb-structure.json is unchanged by it.

@QuantumExplorer
QuantumExplorer merged commit 38bbd30 into v4.2-dev Sep 20, 2026
17 of 18 checks passed
@QuantumExplorer
QuantumExplorer deleted the claude/grovedb-structure-viewer-c313a8 branch September 20, 2026 04:06
QuantumExplorer added a commit that referenced this pull request Sep 20, 2026
…anlist-suspension-b6a28a

Describes the contract's other tree (the version item, the banlist and the
suspension list) in the GroveDB structure that #4845 introduced, with a fixture
that reaches the moderation lists, and regenerates grovedb-structure.json.

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

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants