Skip to content

fix(wasm-sdk): support binary grove path elements#3657

Merged
shumkov merged 4 commits into
v3.1-devfrom
codex/wasm-sdk-binary-grove-path-elements
May 22, 2026
Merged

fix(wasm-sdk): support binary grove path elements#3657
shumkov merged 4 commits into
v3.1-devfrom
codex/wasm-sdk-binary-grove-path-elements

Conversation

@PastaPastaPasta

@PastaPastaPasta PastaPastaPasta commented May 17, 2026

Copy link
Copy Markdown
Member

Issue being fixed or feature implemented

This PR fixes the wasm/evo-sdk exact-key GroveDB lookup path used by proof-tree exploration.

The underlying DAPI KeysInPath query already accepts bytes, but the public wasm boundary only accepted string[] for path segments and keys. That forced callers with raw proof-tree keys or 32-byte identifiers to represent opaque bytes as JavaScript strings before the query reached Rust. That is unsafe for arbitrary GroveDB keys: strings are text, not byte containers, so bytes such as 0x80 or 0xff cannot be round-tripped through that API shape.

This also improves the returned PathElement shape. Fetching an exact key is not enough for a tree explorer unless the caller can tell whether the result is an item, tree, sum tree, reference, etc., and can keep using raw key/path/value bytes for follow-up lookups.

This PR intentionally does not add arbitrary subtree/range enumeration. PathQuery / SizedQuery still needs a follow-up protocol/server/SDK API beyond this wasm-sdk exact-key binding.

What was done?

  • Updated getPathElements and getPathElementsWithProofInfo to accept Array<string | Uint8Array> for both path segments and keys.
  • Added shared WASM-boundary decoding:
    • Uint8Array path/key segments are copied as raw bytes.
    • path strings keep the existing legacy decimal-u8 behavior, so path segment "96" still decodes to [96].
    • key strings keep existing UTF-8 behavior, so key "96" decodes to [0x39, 0x36]; callers should use Uint8Array for numeric or opaque binary keys.
  • Avoided returning misleading legacy path strings for non-round-trippable binary keys. Callers that need byte-accurate navigation should use pathBytes and key.
  • Made Uint8Array detection more tolerant of cross-realm typed arrays by checking ArrayBuffer.isView plus typed-array constructor name, not only same-realm instanceof.
  • Extended PathElement additively while preserving the existing base64 value getter:
    • key: Uint8Array
    • pathBytes: Uint8Array[]
    • valueBytes?: Uint8Array
    • elementType?: GroveElementType
    • sum?: bigint
    • referenceTarget?: Uint8Array[]
    • referenceTargetError?: string
  • Populated elementType, sum, value bytes, and reference metadata from decoded GroveDB Element variants, including newer wrapper variants on v3.1-dev.
  • Resolved referenceTarget through GroveDB's path_from_reference_path_type helper. If GroveDB rejects a reference path, the failure is surfaced as referenceTargetError instead of silently looking like a non-reference.
  • Kept PathElement.toJSON() JSON-safe: byte fields serialize as base64 strings and sum serializes as a string.
  • Made PathElement.toObject() match the typed getter shape: byte fields are Uint8Array and sum is BigInt.
  • Widened @dashevo/evo-sdk SystemFacade.pathElements / pathElementsWithProof signatures to wasm.GrovePathSegment[], so the new binary capability is exposed through the recommended SDK facade.

How Has This Been Tested?

  • cargo test -p wasm-sdk system::tests --no-default-features --features mocks,all-system-contracts
  • CC_wasm32_unknown_unknown=/opt/homebrew/opt/llvm/bin/clang cargo check -p wasm-sdk --target wasm32-unknown-unknown
  • CC_wasm32_unknown_unknown=/opt/homebrew/opt/llvm/bin/clang npx yarn workspace @dashevo/wasm-sdk build
  • npx yarn workspace @dashevo/wasm-sdk test:unit
  • npx yarn workspace @dashevo/evo-sdk build
  • npx yarn workspace @dashevo/evo-sdk test:unit

This pull request was created by Codex.

Breaking Changes

None. Existing string inputs and the existing base64 PathElement.value getter are preserved. The richer byte/type fields are additive.

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

Summary by CodeRabbit

  • New Features

    • Grove path queries now accept binary-safe paths/keys (strings or byte arrays) and decode legacy/UTF-8 forms.
    • Path element responses now include byte-backed fields and derived metadata: key bytes, path/value bytes, element type, sum, and reference target (with error info).
    • Proof-enabled path queries updated to return the extended element metadata.
  • Tests

    • Unit tests added/updated to validate decoding rules, binary/base64 mappings, metadata extraction, and error reporting.

Review Change Stack

@github-actions github-actions Bot added this to the v3.1.0 milestone May 17, 2026
@coderabbitai

coderabbitai Bot commented May 17, 2026

Copy link
Copy Markdown
Contributor

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: aad85a6d-71b0-4f74-bbc0-b961dc63398e

📥 Commits

Reviewing files that changed from the base of the PR and between 5cd13f9 and 04bd8f4.

📒 Files selected for processing (2)
  • packages/js-evo-sdk/src/system/facade.ts
  • packages/js-evo-sdk/tests/unit/facades/system.spec.ts

📝 Walkthrough

Walkthrough

WASM SDK system queries now accept binary-safe grove path/key inputs (string or Uint8Array), decode them to raw bytes, and return expanded PathElement objects with byte-backed fields and derived metadata (elementType, sum, referenceTarget) via new JS getters.

Changes

Binary-Safe GroveDB Path Queries

Layer / File(s) Summary
Type definitions and imports
packages/wasm-sdk/src/queries/system.rs
Embedded TypeScript definitions for GrovePathSegment and GroveElementType; updated imports to support element inspection and reference-path utilities.
PathElementWasm data structure and byte conversion
packages/wasm-sdk/src/queries/system.rs
Replaced the simple { path, value } representation with an expanded structure carrying byte-backed fields (key, path_bytes, value_bytes) and derived metadata (element_type, sum, reference_target); implemented decoding of JS GrovePathSegment inputs to raw bytes, base64 encoding for value, element-type and sum extraction, and reference-target path computation.
PathElementWasm JS getters
packages/wasm-sdk/src/queries/system.rs
Added WASM-exported getters to expose key(), pathBytes(), valueBytes(), elementType(), sum(), referenceTarget(), and referenceTargetError() to JavaScript.
Path element query APIs and JS facade
packages/wasm-sdk/src/queries/system.rs, packages/js-evo-sdk/src/system/facade.ts
Updated get_path_elements and get_path_elements_with_proof_info to accept GrovePathSegment[], decode segments/keys into byte vectors, query Grovedb with raw bytes, and construct PathElementWasm results; updated SystemFacade.pathElements and pathElementsWithProof to accept wasm.GrovePathSegment[] and forward them to the wasm SDK.
Tests for decoding and element conversion
packages/wasm-sdk/src/queries/system.rs (tests), packages/wasm-sdk/tests/unit/conversion-simple-types.spec.ts, packages/js-evo-sdk/tests/unit/facades/system.spec.ts
Added unit tests validating JS path/key decoding rules (raw bytes preserved, legacy decimal-string rule), PathElement conversions (base64/valueBytes mapping, element type naming, sum extraction), reference target construction and resolution error reporting, and JS facade argument forwarding assertions.

Sequence Diagram(s)

sequenceDiagram
  participant JS as JS (Facade)
  participant WASM as wasm-sdk
  participant Grovedb as Grovedb
  JS->>WASM: pass GrovePathSegment[] (path, keys)
  WASM->>WASM: decode segments -> byte vectors
  WASM->>Grovedb: query KeysInPath with raw bytes
  Grovedb-->>WASM: Element / proof data
  WASM->>JS: PathElementWasm (with byte fields & metadata)
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

Possibly related PRs

  • dashpay/platform#3656: Changes to element variant formatting and FFI/JSON rendering that align with the PathElement metadata extraction and naming surfaced in this PR.

Suggested labels

ready for final review

Suggested reviewers

  • shumkov
  • QuantumExplorer

Poem

🐰 A rabbit hops through bytes and trees,

Strings and Uint8Arrays breeze with ease.
Path elements bloom with sums and types,
References traced through branching pipes.
Hooray — the SDK now speaks in keys!

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 42.86% which is insufficient. The required threshold is 80.00%. 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 accurately summarizes the main change: adding binary path element support to the wasm-sdk. It is specific, concise, and clearly conveys the primary purpose of the changeset.
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.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch codex/wasm-sdk-binary-grove-path-elements

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 and usage tips.

@thepastaclaw

thepastaclaw commented May 17, 2026

Copy link
Copy Markdown
Collaborator

✅ Review complete (commit 3bc6c58)

@thepastaclaw thepastaclaw left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

PR is a sound additive change in wasm-sdk to accept Uint8Array path/key inputs and surface richer element metadata. No blocking consensus or correctness issues in wasm-sdk itself. Three notable correctness/UX concerns: (1) the js-evo-sdk facade still narrows path/keys to string[], so the new binary capability isn't reachable through the recommended TS surface without unsafe casts; (2) the legacy path: Vec<String> field encodes non-printable binary keys as "0x<hex>" strings that do NOT round-trip through decode_path_input/decode_key_input, silently corrupting subsequent grove walks; (3) PathElement's toObject/toJSON (via impl_wasm_serde_conversions!) will serialize the new binary fields as number arrays and sum as a string, diverging from the wasm-bindgen getter shape. Several nitpicks around silent BigInt/reference error swallowing, redundant match arms, an extra Uint8Array copy, the decimal-string heuristic, and thin test coverage of GroveElementType variants.

Reviewed commit: 0165eaf

🟡 7 suggestion(s) | 💬 3 nitpick(s)

1 additional finding

🟡 suggestion: Evo SDK facade still narrows path/keys to `string[]`, blocking binary use from TS callers

packages/js-evo-sdk/src/system/facade.ts (lines 44-53)

wasm-sdk now accepts GrovePathSegment[] (string | Uint8Array) for getPathElements and getPathElementsWithProofInfo, but SystemFacade.pathElements / pathElementsWithProof still declare path: string[], keys: string[]. TypeScript users of js-evo-sdk (the recommended SDK) cannot pass raw binary segments through the supported facade without unsafe casts, so the new binary capability is unreachable from the normal entry point. Widen both signatures to wasm.GrovePathSegment[] and update the proof variant's return type as needed.

💡 Suggested change
  async pathElements(path: wasm.GrovePathSegment[], keys: wasm.GrovePathSegment[]): Promise<wasm.PathElement[]> {
    const w = await this.sdk.getWasmSdkConnected();
    return w.getPathElements(path, keys);
  }

  async pathElementsWithProof(path: wasm.GrovePathSegment[], keys: wasm.GrovePathSegment[]):
    Promise<wasm.ProofMetadataResponseTyped<wasm.PathElement[]>> {
    const w = await this.sdk.getWasmSdkConnected();
    return w.getPathElementsWithProofInfo(path, keys);
  }
🤖 Prompt for all review comments with AI agents
These findings are from an automated code review. Verify each finding against the current code and only fix it if needed.

In `packages/wasm-sdk/src/queries/system.rs`:
- [SUGGESTION] lines 555-568: Legacy `path: Vec<String>` field is non-round-trippable for binary keys
  When a Uint8Array containing non-printable bytes is passed (e.g. `[0x80, 0xff]`), `bytes_to_display` encodes it as the literal string `"0x80ff"` and stores it into `PathElementWasm::path: Vec<String>` exposed via the existing `path` getter. The grove-walking pattern of feeding a returned path segment back into `getPathElements` is broken: `decode_path_input(PathInputValue::String("0x80ff"))` returns the 6 UTF-8 bytes `[0x30,0x78,0x38,0x30,0x66,0x66]`, not the original 2-byte key. The original binary key is silently corrupted into a 6-byte ASCII key, and the next query returns a missing element with no error. Either drop string `path` segments for non-UTF8 keys (return `None`/empty so callers cannot misuse the field), or document explicitly that the legacy `path` field is lossy and `pathBytes`/`key` MUST be used whenever any segment originated from a Uint8Array.
- [SUGGESTION] lines 459-472: `PathElement.toObject()`/`toJSON()` will not produce the advertised JS shape for new binary fields
  `PathElementWasm` opts into `impl_wasm_serde_conversions!`, which routes `toObject`/`toJSON` through serde. The newly added fields (`key: Vec<u8>`, `path_bytes: Vec<Vec<u8>>`, `value_bytes: Option<Vec<u8>>`, `reference_target: Option<Vec<Vec<u8>>>`) have no `#[serde(with = "serde_bytes")]` annotation, so serde will emit them as `number[]` / nested `number[][]`, and `sum` as a string. Callers using `toObject()`/`toJSON()` (including indirect use via `ProofMetadataResponseWasm` serialization helpers) will observe a different shape than the wasm-bindgen getters (`Uint8Array`, `BigInt`). Either annotate the byte fields with `serde_bytes` (and serialize `sum` as a numeric/string variant matching the getter shape), or skip them from the serde representation if the getters are intended to be the only public surface.
- [SUGGESTION] lines 645-660: Reference-resolution errors are silently discarded
  `element_reference_target` uses `path_from_reference_path_type(...).ok()`, so an invalid reference (e.g. `UpstreamRootHeightReference` with `no_of_elements_to_keep > parent_path.len()` returning `ElementError::InvalidInput`) yields `referenceTarget = undefined` — indistinguishable from "this element is not a reference at all." A UI that uses `elementType === "reference"` to decide whether to dereference will be confused. Either log via `tracing::warn!` at this boundary or surface the failure in a separate `referenceTargetError` field so tree-explorer callers can show meaningful feedback.
- [SUGGESTION] lines 550-555: `decode_path_string`'s numeric-string heuristic is silent and lossy for legitimate UTF-8 segments
  Any path string that happens to parse as `u8` (0–255) is coerced to a single byte — so a path segment literally named `"42"` becomes `[42]`, while `"256"` falls through to its 3-byte ASCII form. This asymmetry is now baked into the WASM boundary forever and is invisible to callers who built a JSON-style string path. Add a doc comment on `decode_path_input` describing the behavior, and consider emitting a `tracing::warn!` when the numeric branch fires so callers are nudged toward `Uint8Array` for unambiguous representation.
- [SUGGESTION] lines 568-590: `is_instance_of::<Uint8Array>` fails on cross-realm typed arrays
  The check lowers to JS `instanceof Uint8Array` against the realm hosting the wasm-bindgen glue. A Uint8Array constructed in a different realm (iframe, ServiceWorker, vm context, jest worker) will not satisfy `instanceof` against the wasm module's `globalThis.Uint8Array`, fall through to the `as_string()` branch, fail that, and surface the misleading error `"path[i] must be a string or Uint8Array"` for a value that *is* a Uint8Array. Node's `Buffer` extends the same-realm Uint8Array so it's unaffected; browser callers passing data received via `postMessage` from a worker can hit this. Either duck-type via `ArrayBuffer.isView(value)` (with a name/byteLength probe) or at minimum document the same-realm requirement on `GrovePathSegment`.
- [SUGGESTION] lines 1388-1509: `GroveElementType` enum advertises ~40 variants; tests exercise ~8
  The TS `GroveElementType` union lists every Element variant including newer wrapper-prefixed names (`nonCountedSumTree`, `notSummedBigSumTree`, `commitmentTree`, `mmrTree`, `bulkAppendTree`, `denseAppendOnlyFixedSizeTree`, etc.), but tests only touch `item`, `tree`, `sumTree`, `sumItem`, `reference`, `referenceWithSumItem`, `provableSumTree`, and one nested-wrapper case. The dispatch in `element_type_name` / `non_counted_element_type_name` / `not_summed_element_type_name` / `not_counted_or_summed_element_type_name` has subtle naming rules (e.g. NotSummed prefix only on sum-bearing trees). A table-driven test asserting each variant maps to the exact string in the TS enum would catch typos and drift when grovedb adds Element variants.

In `packages/js-evo-sdk/src/system/facade.ts`:
- [SUGGESTION] lines 44-53: Evo SDK facade still narrows path/keys to `string[]`, blocking binary use from TS callers
  `wasm-sdk` now accepts `GrovePathSegment[]` (`string | Uint8Array`) for `getPathElements` and `getPathElementsWithProofInfo`, but `SystemFacade.pathElements` / `pathElementsWithProof` still declare `path: string[], keys: string[]`. TypeScript users of `js-evo-sdk` (the recommended SDK) cannot pass raw binary segments through the supported facade without unsafe casts, so the new binary capability is unreachable from the normal entry point. Widen both signatures to `wasm.GrovePathSegment[]` and update the proof variant's return type as needed.

Comment thread packages/wasm-sdk/src/queries/system.rs
Comment thread packages/wasm-sdk/src/queries/system.rs
Comment thread packages/wasm-sdk/src/queries/system.rs
Comment thread packages/wasm-sdk/src/queries/system.rs
Comment thread packages/wasm-sdk/src/queries/system.rs
Comment thread packages/wasm-sdk/src/queries/system.rs
Comment thread packages/wasm-sdk/src/queries/system.rs
Comment thread packages/wasm-sdk/src/queries/system.rs Outdated
Comment thread packages/wasm-sdk/src/queries/system.rs
@PastaPastaPasta PastaPastaPasta force-pushed the codex/wasm-sdk-binary-grove-path-elements branch 3 times, most recently from 5cd13f9 to fb78197 Compare May 18, 2026 17:15
@codecov

codecov Bot commented May 18, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 87.17%. Comparing base (7b48e43) to head (04bd8f4).
⚠️ Report is 2 commits behind head on v3.1-dev.

Additional details and impacted files
@@            Coverage Diff            @@
##           v3.1-dev    #3657   +/-   ##
=========================================
  Coverage     87.17%   87.17%           
=========================================
  Files          2601     2601           
  Lines        318160   318160           
=========================================
+ Hits         277370   277371    +1     
+ Misses        40790    40789    -1     
Components Coverage Δ
dpp 87.68% <ø> (+<0.01%) ⬆️
drive 85.95% <ø> (ø)
drive-abci 89.68% <ø> (ø)
sdk ∅ <ø> (∅)
dapi-client ∅ <ø> (∅)
platform-version ∅ <ø> (∅)
platform-value 92.17% <ø> (ø)
platform-wallet ∅ <ø> (∅)
drive-proof-verifier 49.16% <ø> (ø)
🚀 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.

@PastaPastaPasta PastaPastaPasta force-pushed the codex/wasm-sdk-binary-grove-path-elements branch 2 times, most recently from 68cc9f4 to aaf11a0 Compare May 18, 2026 17:28

@thepastaclaw thepastaclaw left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

Client-side wasm-sdk surface widening to accept Uint8Array path/key segments and richer PathElement metadata. No consensus, proof, or DPP code touched. One real compatibility regression in legacy path rendering for byte-form keys whose UTF-8 representation parses as a decimal u8 (e.g. "0"–"255"), plus two FFI nitpicks (cross-realm Buffer rejection, double-copy of Uint8Array inputs).

Reviewed commit: aaf11a0

🟡 1 suggestion(s) | 💬 2 nitpick(s)

🤖 Prompt for all review comments with AI agents
These findings are from an automated code review. Verify each finding against the current code and only fix it if needed.

In `packages/wasm-sdk/src/queries/system.rs`:
- [SUGGESTION] lines 732-743: Byte-form keys whose UTF-8 parses as a decimal u8 lose their legacy `path` string
  `decode_key_input` for `PathInputValue::Bytes` delegates to `bytes_to_round_trippable_path_display` (lines 819-831), which checks round-trippability with `decode_path_string_silent` — the *path* string decoder that treats decimal strings in the u8 range as a single byte. Keys are documented as plain UTF-8, not legacy decimal-u8 segments, so for any key whose bytes are the UTF-8 of a decimal in 0..=255 the check fails: bytes `[0x39, 0x36]` decode to `"96"`, `decode_path_string_silent("96")` returns `[0x60]`, which mismatches the original bytes, and `legacy_path_segment` becomes `None`. The same key passed as the string `"96"` keeps `legacy_path_segment = Some("96")`, so `PathElement.path` (lines 485, 509) is emitted as `[]` for the byte form but `["96"]` for the string form. Callers that migrate to `Uint8Array` for safety but still rely on the legacy `path` field regress for any UTF-8 key that happens to be a small-integer literal. Use a key-specific round-trip rule (e.g. `std::str::from_utf8(bytes).ok().map(str::to_owned)`) instead of reusing the path-segment decoder.

Comment thread packages/wasm-sdk/src/queries/system.rs
Comment thread packages/wasm-sdk/src/queries/system.rs
Comment thread packages/wasm-sdk/src/queries/system.rs Outdated
@PastaPastaPasta PastaPastaPasta force-pushed the codex/wasm-sdk-binary-grove-path-elements branch from aaf11a0 to 3bc6c58 Compare May 18, 2026 19:06

@thepastaclaw thepastaclaw left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

Prior substantive findings are resolved on this head. Remaining items are minor: a backward-compat regression in legacy path rendering for valid non-ASCII UTF-8 segments, plus four small nitpicks (cross-realm Node Buffer rejection, double-copy of incoming Uint8Array, silently swallowed BigInt error in the sum getter, and a dead/redundant wrapper arm in two element-name helpers).

Reviewed commit: 3bc6c58

🟡 1 suggestion(s) | 💬 4 nitpick(s)

🤖 Prompt for all review comments with AI agents
These findings are from an automated code review. Verify each finding against the current code and only fix it if needed.

In `packages/wasm-sdk/src/queries/system.rs`:
- [SUGGESTION] lines 819-843: Legacy `path` is dropped for valid non-ASCII UTF-8 segments that would round-trip via the string API
  `bytes_to_round_trippable_path_display` and `bytes_to_round_trippable_key_display` require every byte to be `is_ascii_graphic()` (or space). That is stricter than the round-trip rules actually used on this boundary. `decode_key_input(PathInputValue::String(value))` uses `value.as_bytes()`, so *any* valid UTF-8 key round-trips through the legacy string API. `decode_path_string()` falls back to UTF-8 bytes for anything that does not parse as a decimal `u8`, so any non-decimal valid UTF-8 path segment also round-trips. As written, callers that switch from `string` to `Uint8Array` for an input like `"café"` (or any other non-ASCII UTF-8 segment) get `path: []` back even though the byte sequence is safely representable. Loosen the filter to UTF-8 + (for paths) the existing `decode_path_string_silent` round-trip check; for keys, drop the ASCII-only condition entirely.

Comment thread packages/wasm-sdk/src/queries/system.rs Outdated
Comment thread packages/wasm-sdk/src/queries/system.rs
Comment thread packages/wasm-sdk/src/queries/system.rs
Comment thread packages/wasm-sdk/src/queries/system.rs
Comment thread packages/wasm-sdk/src/queries/system.rs Outdated
PastaPastaPasta added a commit that referenced this pull request May 20, 2026
The legacy-display fallback for binary grove path inputs was gated on every byte being ASCII-graphic-or-space, which dropped perfectly valid round-trip cases. For keys, decode_key_input(String) just calls value.as_bytes(), so any valid UTF-8 trivially round-trips; for paths, the existing decode_path_string_silent equality check is the real correctness guarantee. Loosen both filters so callers that switch from string to Uint8Array inputs like "café" still get the human-readable legacy path segment instead of an empty path.

Addresses CodeRabbit review on PR #3657.
PastaPastaPasta added a commit that referenced this pull request May 20, 2026
- Accept cross-realm Node Buffer in is_uint8_array_value by also matching constructor.name === "Buffer".

- Skip the redundant JS-side Uint8Array allocation when decoding path/key segments by reinterpreting the already-verified JsValue via unchecked_ref.

- Drop the dead wrapper arm in not_summed_/not_counted_or_summed_element_type_name; the catch-all already dispatches wrappers correctly through element_type_name.

- Surface BigInt construction failures in the sum getter via expect() instead of silently producing undefined, so a future invariant violation is visible.

Addresses CodeRabbit review nits on PR #3657.

@thepastaclaw thepastaclaw left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

All six agent reviews (general, security, FFI from both Claude and Codex) converge on zero findings at head bfd640e. All five prior findings from 3bc6c58 are confirmed FIXED: UTF-8 round-trip for legacy path display, cross-realm Buffer acceptance, redundant Uint8Array copy removal via unchecked_ref, dead wrapper match arms removed in not_summed_/not_counted_or_summed_ helpers, and the sum getter's silent BigInt error replaced with .expect(). The latest delta is scoped to the wasm-sdk JS/WASM boundary (no consensus, proof, or server-side code touched) and introduces no new correctness, security, or boundary issues.

The legacy-display fallback for binary grove path inputs was gated on every byte being ASCII-graphic-or-space, which dropped perfectly valid round-trip cases. For keys, decode_key_input(String) just calls value.as_bytes(), so any valid UTF-8 trivially round-trips; for paths, the existing decode_path_string_silent equality check is the real correctness guarantee. Loosen both filters so callers that switch from string to Uint8Array inputs like "café" still get the human-readable legacy path segment instead of an empty path.

Addresses CodeRabbit review on PR #3657.
- Accept cross-realm Node Buffer in is_uint8_array_value by also matching constructor.name === "Buffer".

- Skip the redundant JS-side Uint8Array allocation when decoding path/key segments by reinterpreting the already-verified JsValue via unchecked_ref.

- Drop the dead wrapper arm in not_summed_/not_counted_or_summed_element_type_name; the catch-all already dispatches wrappers correctly through element_type_name.

- Surface BigInt construction failures in the sum getter via expect() instead of silently producing undefined, so a future invariant violation is visible.

Addresses CodeRabbit review nits on PR #3657.
Latest v3.1-dev brought in a new grovedb Element variant ProvableCountProvableSumTree. Add it to element_sum (it carries a sum) and to every element_type_name dispatcher, plus the GroveElementType TS union, so PathElement keeps reporting an element type instead of failing exhaustiveness checks.
@PastaPastaPasta PastaPastaPasta force-pushed the codex/wasm-sdk-binary-grove-path-elements branch from bfd640e to 04bd8f4 Compare May 20, 2026 21:09

@thepastaclaw thepastaclaw left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

Cumulative review of PR #3657 at 04bd8f4. The PR is scoped to wasm-sdk grove path-element surface plus the js-evo-sdk facade. The latest delta (bfd640e..04bd8f4) is a single additive commit registering Element::ProvableCountProvableSumTree in element_sum and the four element_type_name dispatchers, with matching TS union strings. No carried-forward prior findings remain open. The only new finding worth posting is a test-coverage gap: the table-driven element-type regression test added earlier in this PR was not extended to cover the new variant. The codex-ffi-engineer finding about Swift dropping DriveInternalError is dropped — that code lives outside this PR's diff (rs-sdk-ffi/src/error.rs and swift-sdk/SDK.swift are not modified here).

💬 1 nitpick(s)

NITPICK: Extend the element-type regression test to cover ProvableCountProvableSumTree

packages/wasm-sdk/src/queries/system.rs (line ?)

The latest commit adds Element::ProvableCountProvableSumTree handling to element_sum (line 869), element_type_name (line 917), and all three wrapper dispatchers — non_counted_element_type_name (943), not_summed_element_type_name (963), and not_counted_or_summed_element_type_name (977) — exposing four new GroveElementType TS strings. The should_map_supported_grovedb_element_types table was added earlier in this PR specifically to pin the dispatcher↔TS-union mapping, but it does not include a row for the new variant or any of its wrapper-prefixed names. A future typo or refactor in any of the four new branches will silently slip past the test. Add at least one case for the base variant, and ideally one wrapped form, to restore the invariant the table-driven test was designed to enforce.

            (
                Element::ProvableCountProvableSumTree(None, 1, 2, None),
                "provableCountProvableSumTree",
            ),
            (
                Element::NonCounted(Box::new(Element::ProvableCountProvableSumTree(
                    None, 1, 2, None,
                ))),
                "nonCountedProvableCountProvableSumTree",
            ),
            (
                Element::NotSummed(Box::new(Element::ProvableCountProvableSumTree(
                    None, 1, 2, None,
                ))),
                "notSummedProvableCountProvableSumTree",
            ),
            (
                Element::NotCountedOrSummed(Box::new(Element::ProvableCountProvableSumTree(
                    None, 1, 2, None,
                ))),
                "notCountedOrSummedProvableCountProvableSumTree",
            ),

@shumkov shumkov merged commit 67066e4 into v3.1-dev May 22, 2026
24 checks passed
@shumkov shumkov deleted the codex/wasm-sdk-binary-grove-path-elements branch May 22, 2026 05:41
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.

3 participants