Skip to content

feat(dpp): implement identity create transition - #663

Closed
markin-io wants to merge 19 commits into
v0.24-devfrom
feat/implement_identity_create_st
Closed

feat(dpp): implement identity create transition#663
markin-io wants to merge 19 commits into
v0.24-devfrom
feat/implement_identity_create_st

Conversation

@markin-io

Copy link
Copy Markdown
Contributor

Issue being fixed or feature implemented

What was done?

How Has This Been Tested?

Breaking Changes

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 made corresponding changes to the documentation

For repository code-owners and collaborators only

  • I have assigned this pull request to a milestone

@markin-io
markin-io marked this pull request as draft December 12, 2022 16:52
@shumkovshumkov changed the title feat(wasm-dpp): implement identity create transitionfeat(dpp): implement identity create transitionDec 15, 2022
@shumkov
shumkov deleted the feat/implement_identity_create_st branch May 10, 2023 10:04
QuantumExplorer added a commit that referenced this pull request May 15, 2026
…+ bench probe
Pulls in dashpay/grovedb#663 ("feat(grovedb,query): allow AggregateCountOnRange
as carrier subquery"), merge commit 87554188ad — bumps every pinned
`grovedb*` dep across the workspace from a917d92d to 87554188.
The new grovedb APIs:
- `Query::validate_carrier_aggregate_count_on_range`
- `Query::validate_leaf_aggregate_count_on_range`
- `GroveDb::query_aggregate_count_per_key`
- `GroveDb::verify_aggregate_count_query_per_key`
These unblock the chapter 30 G7 shape (`brand IN[...] AND color > floor` with
`group_by = [brand]`) at the grovedb layer. Drive wire-up is the next step
(lift mode_detection.rs:140 rejection + new path-query builder + new
DocumentCountMode variant + per-key verifier wrapper).
This commit also adds `probe_carrier_acor` to document_count_worst_case bench
as a feasibility smoke test against the existing 100 000-row widget fixture:
[carrier-acor] no-proof entries (2):
("brand_000", 499)
("brand_001", 499)
[carrier-acor] proof bytes: 4332 B
[carrier-acor] verified root_hash: 0x62ee7348f4d28dd9d7cf86a6c725fa8276...
[carrier-acor] verified entries (2):
("brand_000", 499)
("brand_001", 499)
4 332 B for k=2, matching the complexity estimate documented in chapter 30
(`O(k · (log B + log C'))`) and ~17 % smaller than the concatenated-leaf-ACOR
alternative.
Verification:
- cargo check --workspace clean
- cargo test -p drive --lib drive_document_count_query → 45 tests passing
- cargo test -p drive --lib verify → 240 tests passing
- All chapter 29 / chapter 30 proof sizes (585 / 1041 / 1327 / 1911 / 1102 /
1381 / 2072 / 2656 B for Q1..Q8) unchanged — bump is purely additive
- Carrier-ACOR end-to-end: query → prove → verify all round-trip with root
hash matching the chapter's known 0x62ee7348... fixture root
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
QuantumExplorer added a commit that referenced this pull request May 15, 2026
…r range)
Lifts the `mode_detection.rs:140` rejection for the `GroupByIn + In + range +
prove` case, now that grovedb PR #663 exposes `AggregateCountOnRange` as a
carrier subquery under outer `Keys`. The new shape returns one
`(in_key, u64)` per resolved In branch in a single proof:
brand IN ["brand_000", "brand_001"] AND color > "color_00000500"
group_by = [brand] → Entries([("brand_000", 499), ("brand_001", 499)])
Proof(4 332 bytes), median 255.9 µs
Drive-side wire-up
- New `DocumentCountMode::RangeAggregateCarrierProof` variant.
- `mode_detection::detect_mode`: rejection lifted for `CountMode::GroupByIn`
carrying `(In + range)`; routes to the new mode. Aggregate-mode `In +
range + prove` still rejected (no group_by means caller asks for a
single sum, which carrier-ACOR can't safely produce without verifier
trust in the SDK's summation).
- New `DriveDocumentCountQuery::carrier_aggregate_count_path_query` builder
in `path_query.rs` — outer Keys per In value, subquery_path through the
index's middle properties (`==` clauses) plus the terminator name,
subquery is `Query::new_aggregate_count_on_range(range_item)`. Mirrors
the In-fan-out pattern from `distinct_count_path_query` but with the
carrier-ACOR subquery composition.
- New executor `Drive::execute_document_count_range_aggregate_carrier_proof`
in `executors/range_aggregate_carrier_proof.rs`, plus inner
`DriveDocumentCountQuery::execute_carrier_aggregate_count_with_proof`
in `execute_range_count.rs`.
- New verifier `DriveDocumentCountQuery::verify_carrier_aggregate_count_proof`
(`v0`) wrapping `GroveDb::verify_aggregate_count_query_per_key`. Returns
`(RootHash, Vec<(Vec<u8>, u64)>)`.
- Added the new method version to
`DriveVerifyDocumentCountMethodVersions` (defaults to `0` in `v1.rs`).
- Dispatcher arm in `drive_dispatcher.rs` matches the new mode and
returns `DocumentCountResponse::Proof(...)`.
Bench
- Matrix entry `[brand] / where=brand IN[2] AND color > floor` flipped
from rejected ("no — single-field GROUP BY with both `In` and range")
to allowed ("yes (RangeAggregateCarrierProof — carrier ACOR per In
branch)") with `prove: Proof(4 332 bytes)`.
- New `query_g7_brand_in_color_gt_grouped_by_brand` criterion bench —
10 samples × 9 295 iters, median 255.87 µs (~4× Q8's 71 µs because
it's two parallel Q8-shaped descents).
- New `G7` case in `display_group_by_proofs` emits the full 186-line
carrier-ACOR proof verbatim as `[gproof] G7 [brand] / where=...`.
Chapter 30 (`book/src/drive/count-index-group-by-examples.md`)
- G7 added to the navigation table (`O(k · (log B + log C'))`, 255.9 µs,
4 332 B, `Entries(2 groups, sum = 998)`).
- New "G7 — Carrier `In` + Range, Grouped By `brand`" section with the
same template as G1..G6: path query, verified payload, proof size,
proof display (schematic + interactive visualizer link), narrative,
conceptual flowchart, per-layer (Layer-5+) merk-tree diagram.
- "Group-By Shapes That Are Not Allowed" section's bucket #4 removed
(the "incoming" placeholder), replaced with a historical note
pointing forward to G7.
Tests + verification
- `cargo test -p drive --lib drive_document_count_query` → 45 passing
- `cargo test -p drive --lib verify` → 240 passing
- All chapter 29 / chapter 30 documented proof sizes (Q1..Q8, G3..G6)
unchanged — wire-up is purely additive on top of grovedb PR #663.
- mdBook builds clean.
Closes (in this PR): chapter 30 G7 placeholder.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
QuantumExplorer added a commit that referenced this pull request May 15, 2026
Adds `probe_carrier_acor_range_outer` — the natural extension of
`probe_carrier_acor` from `outer In` to `outer Range`. Confirms the
grovedb feature works for our widget fixture:
[carrier-acor-range] probing: widget/brand RangeAfter(brand_050..)
subquery_path=color
subquery=AggregateCountOnRange(RangeAfter(color_00000500..))
[carrier-acor-range] no-proof entries (49):
("brand_051", 499) … ("brand_099", 499)
[carrier-acor-range] proof bytes: 84576 B
[carrier-acor-range] verified root_hash: 0x62ee7348… (matches chapter fixture)
[carrier-acor-range] verified entries (49):
("brand_051", 499) … ("brand_099", 499)
Findings worth recording:
1. The outer-Range carrier-ACOR shape WORKS at the grovedb layer
(grovedb PR #663's `validate_carrier_aggregate_count_accepts_range_outer_items`
covers this). The widget fixture's 49 brands > "brand_050" each
carry the expected per-brand count of 499 colors > "color_00000500"
(the bench's fixture has 1 doc per (brand, color) pair).
2. **`SizedQuery::limit` is rejected on any ACOR-bearing query**
(carrier or leaf) — grovedb's validator returns
`InvalidQuery("AggregateCountOnRange queries may not set SizedQuery::limit")`.
So "limit the outer Range walk to N matches" can't be expressed
today; this probe walks the full 49 brands and pays the resulting
~83 KB proof size. The natural drive-level workaround is to
compute an explicit upper bound for the outer Range from the
requested limit (e.g. rewrite `brand > X` with `limit = 20` to
`brand > X AND brand <= caller_supplied_or_precomputed_Y`) — but
that pushes the upper-bound responsibility to the caller or
requires an extra grovedb read.
3. Drive doesn't wire this through yet: `mode_detection::detect_mode`
rejects ≥2 range clauses up front ("count query supports at most
one range where-clause"), independent of the limit issue. The
shape is logged here as future work for chapter 30; lifting it
requires both the multi-range-rejection in mode_detection AND a
grovedb-level extension to support `SizedQuery::limit` on carrier
ACOR (or a drive-level upper-bound computation).
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
QuantumExplorer added a commit that referenced this pull request May 15, 2026
Targets grovedb PR #664 head (4e20c338) — the follow-up to PR #663 that
relaxes the leaf-strict `SizedQuery::limit` rule for carrier ACOR queries.
The new shape unblocks the `Q8`-with-outer-range case:
brand > "brand_050" AND color > "color_00000500"
group_by = [brand]
limit = 20
→ Entries([("brand_051", 499), …, ("brand_070", 499)])
Proof(35 122 bytes), median 1.07 ms
The proof bytes scale linearly with `limit`: 20 outer matches × ~1 700 B
per per-brand ACOR boundary walk ≈ 35 KB, matching the per-In slope
established by Q8 vs G7.
Drive-side wire-up extending the existing `RangeAggregateCarrierProof`
mode:
- `mode_detection`: lifts `range_count > 1` for the specific shape
(CountMode::GroupByRange + prove + exactly two range clauses on
distinct fields + no In). Routes to the existing
`DocumentCountMode::RangeAggregateCarrierProof` arm.
- `path_query::carrier_aggregate_count_path_query`: generalized to
accept either an `In` clause (G7 shape) OR a range clause (G8
shape) at the carrier position. The terminator's range becomes
the inner ACOR `QueryItem`. Builder now takes `limit: Option<u16>`
and threads it to `SizedQuery::new`.
- `execute_carrier_aggregate_count_with_proof`: accepts `limit`,
passes through to the builder.
- `Drive::execute_document_count_range_aggregate_carrier_proof`:
accepts `limit`, plumbs through.
- `drive_dispatcher`: extracts `request.limit`, validates against
`max_query_limit` (same validate-don't-clamp policy as
`RangeDistinctProof`), passes through.
- `verify_carrier_aggregate_count_proof[_v0]`: accepts `limit`,
rebuilds the same `PathQuery` byte-for-byte.
- `index_picker::find_range_countable_index_for_where_clauses`:
extended to accept the two-range case — finds an index whose
first property carries one range (the outer carrier) and whose
terminator carries the other (the inner ACOR). Single-range case
is unchanged.
- `drive_dispatcher::where_clauses_from_value`: catches the system-
wide parser's `MultipleRangeClauses` error for count queries.
Structural validation lives in `detect_mode`; the regular-query
parser's "all ranges must be on same field" rule was rejecting
the G8 shape upstream.
Bench:
- Matrix entry `[brand] / where=brand > floor AND color > floor
(limit 20)` flipped from rejected to `Proof(35 122 bytes)`.
- New `query_g8_brand_gt_color_gt_grouped_by_brand_limit_20`
criterion bench — 10 samples × 5 060 iters, median 1.07 ms
(~4× G7's 256 µs because the outer walk is 10× longer).
- New `G8` case in `display_group_by_proofs`.
- `probe_carrier_acor_range_outer` now uses `limit = 20` (was
unbounded in the previous commit's feasibility probe). Proof
shrinks from ~83 KB to 35 122 B.
Chapter 30:
- G8 row in the nav table (`O(L · (log B + log C'))`, 1 072 µs,
35 122 B, `Entries(20 groups, sum = 9 980)`).
- New "G8 — Carrier outer Range + Range, Grouped By `brand`"
section with the same template as G1..G7: path query, verified
payload, schematic proof display + interactive visualizer link,
conceptual flowchart, per-layer (Layer-5+) merk-tree diagram.
- Complexity variables note extends `k` (|IN|) with `L` (the
caller's `limit` for the Range-outer carrier shape).
Tests + verification:
- cargo test -p drive --lib drive_document_count_query → 45 passing
- cargo test -p drive --lib verify → 240 passing
- All previously documented proof sizes unchanged (Q1..Q8 / G3..G7
byte-identical to before)
- G8 end-to-end via the dispatcher matches the standalone grovedb-
level probe (35 122 B; root hash 0x62ee7348… matches chapter
fixture)
- mdBook builds clean
The grovedb rev points at PR #664's open head (4e20c338); will be
rebased to the merge commit once the PR lands.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
QuantumExplorer added a commit that referenced this pull request May 16, 2026
- v1 wire: add `DocumentFieldValue.null_value` variant so the
typed surface can carry `null` operands the v0 CBOR shape
supports (previously dropped). Conversions on both sides
(rs-drive-abci `value_from_proto`, rs-sdk `value_to_proto`)
+ the test-only `pv` helper handle the variant.
- v1 routing: allow `group_by=[in_field]` and `group_by=[range_field]`
alongside the other constraint — drive's `detect_mode` picks
`RangeAggregateCarrierProof` (grovedb #663) on the prove path
and `RangeNoProof` / `RangeDistinctProof` on the no-prove path.
Both produce entries that match the caller's single-field
GROUP BY. The two `reject_*` tests become `accept_*` tests.
- v0 abci handler: propagate `order_by` clause-parse errors
instead of silently dropping malformed components.
- rs-drive `from_decomposed_values`: same tightening for the
legacy CBOR `order_by` parse path — malformed clauses now
reject the request rather than silently producing partial /
default ordering.
- drive_dispatcher: fix `validate_and_canonicalize_where_clauses`
docstring to accurately describe validation-only behavior on
the worktree base (no `> AND <` → `between*` merge step).
- rs-sdk: destructure `dapi_request` in `TryFrom<DocumentQuery>`
to drop the per-field `.clone()` calls.
- tests `pv` helper: narrow its docstring to the explicit subset
of `Value` variants it handles, with a panic on others.
Regenerated dapi-grpc bindings: 8 files (web / nodejs / objc /
python) pick up the new `null_value` field.
Tests: 54 abci document_query + 48 drive count tests passing.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Sign up for freeto 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.

1 participant

@markin-io