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
@shumkov shumkov changed the title feat(wasm-dpp): implement identity create transition feat(dpp): implement identity create transition Dec 15, 2022
@markin-io markin-io closed this Jan 15, 2023
@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 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.

1 participant