feat(sdk): propertyConstraints discovery and pre-check in the JS SDK - #5051
Conversation
wasm-dpp2's DataContract gains documentTypePropertyConstraints(name), the documentPropertyConstraints map getter, and checkDocumentPropertyConstraints(document): the first rule a Document breaks, evaluated with the Rust code consensus runs (properties plus the owner for $ownerId), or undefined. TypeScript types spell out the full rule grammar (comparisons, arithmetic, ifAbsent, in, const, $ownerId, present/absent, anyOf/allOf/not) and the violation kinds. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
Warning Review limit reachedNext included review available in 33 minutes. View limit detailsLimit 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. Review configuration: ⚙️ Run configurationConfiguration used: Repository: dashpay/platform/.coderabbit.yaml Review profile: CHILL Plan: Advanced Run ID: 📒 Files selected for processing (5)
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. Comment |
|
✅ Final review complete — no blockers (commit fab5826) · triage: normal |
thepastaclaw
left a comment
There was a problem hiding this comment.
Final validation — Phase 1 + Phase 2
Verified the supplied findings against fab5826. One concrete discovery bug remains: valid large integer literals cause both new discovery APIs to throw, confirmed by source tracing and a runtime probe against the available WASM bundle. This is a non-consensus SDK correctness issue, classified as a suggestion under the project's severity policy; the other observations do not establish additional actionable defects.
🟡 1 suggestion(s)
Review provenance
Source: reviewer 1: muse-spark-1.3-contributor (agent: phase1-reviewer, role: general); reviewer 2: muse-spark-1.3-contributor (agent: phase1-reviewer, role: architecture-layering); reviewer 3: muse-spark-1.3-contributor (agent: phase1-reviewer, role: ffi-engineer); reviewer 4: muse-spark-1.3-contributor (agent: phase1-reviewer, role: rust-quality); reviewer 5: gpt-6-astra (agent: phase2-reviewer, role: general); reviewer 6: gpt-6-astra (agent: phase2-reviewer, role: architecture-layering); reviewer 7: gpt-6-astra (agent: phase2-reviewer, role: ffi-engineer); reviewer 8: gpt-6-astra (agent: phase2-reviewer, role: rust-quality); final verifier: gpt-6-astra (agent: astra-verifier, role: final-verifier)
- Triage:
normalbygpt-6-astra(effort low) — The additive SDK APIs introduce nontrivial Rust/WASM bindings, rule discovery, typed document pre-checking, and TypeScript grammar definitions across 648 lines, but reuse the existing evaluator without changing consensus rules or another critical surface. - Phase 1 reviewers:
muse-spark-1.3-contributor— general (completed, effort xhigh); agentphase1-reviewer,muse-spark-1.3-contributor— architecture-layering (completed, effort xhigh); agentphase1-reviewer,muse-spark-1.3-contributor— ffi-engineer (completed, effort xhigh); agentphase1-reviewer,muse-spark-1.3-contributor— rust-quality (completed, effort xhigh); agentphase1-reviewer - Phase 1 model:
muse-spark-1.3-contributor— not quota-gated; passed overgemini-3.8-flash-high(antigravity below 15% reserve: weekly 13% left, 5h 100% left),glm-5.3-flash(not used above high effort; tier asks max) - Fresh verifier:
gpt-6-astra— final-verifier; agentastra-verifier - Phase 2 reviewers:
gpt-6-astra— general (completed, effort high); agentphase2-reviewer,gpt-6-astra— architecture-layering (completed, effort high); agentphase2-reviewer,gpt-6-astra— ffi-engineer (completed, effort high); agentphase2-reviewer,gpt-6-astra— rust-quality (completed, effort high); agentphase2-reviewer
🤖 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-dpp2/src/data_contract/document_type_property_constraints.rs`:
- [SUGGESTION] packages/wasm-dpp2/src/data_contract/document_type_property_constraints.rs:214: Preserve large integer literals when serializing discovered rules
A fully validated PV14 contract can declare `{ lessThan: ['price', 9007199254740993n] }`, and its document pre-check succeeds, but both `documentTypePropertyConstraints('offer')` and `documentPropertyConstraints` throw `9007199254740993 can't be represented as a JavaScript number`. The constructor accepts BigInt through `platform_value_from_object`, whereas this discovery path converts the declaration through `serde_json::Value` and `Serializer::json_compatible()`, which rejects integers outside JavaScript's safe range. Consequently, one valid literal prevents discovery of the entire document type or contract. Serialize rule literals losslessly, using bigint for integers outside the safe range, update the exported numeric TypeScript operands accordingly, and add regression coverage for both discovery APIs, including large comparison literals, defaults, and membership values.
|
Your move: thepastaclaw left review threads unresolved; resolve them. |
…gint Discovery converted each declared rule through serde_json and the JSON-compatible serializer, which throws on an integer past Number.MAX_SAFE_INTEGER, so one such literal (a comparison, an ifAbsent default or an `in` value) made documentTypePropertyConstraints and documentPropertyConstraints throw for the whole type or contract. Rules now convert directly: an integer is a number while it is exact in JavaScript and a bigint past that. The TypeScript operand types admit bigint. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Basic explanation
What this does: The JavaScript SDK (
wasm-dpp2, re-exported byjs-evo-sdk) can now list a document type'spropertyConstraintsrules and check a document against them before sending it. The check runs the same Rust code consensus runs, so every operator added in #5036 through #5048 works with no JS reimplementation.Value: An app can tell a user "this offer breaks rule
discountBelowPrice" before broadcasting, instead of paying for a transition consensus refuses with error 10422. It can also show which rules a type declares without hand-parsing the contract's raw JSON. TypeScript types spell out the full rule grammar.Risks: Low. The change is additive: three new
DataContractmembers and TypeScript types. Nothing changes in consensus, Drive or the existing JS API.Issue being fixed or feature implemented
The
propertyConstraintsseries (#4962, then #5036 through #5048) gave consensus a rich rule language, but the SDKs only exposed the 10422 error code. This is the first of three SDK PRs: JS/WASM here, with Swift (and the iOS example app) and Kotlin (and the Android example app) to follow, both calling the Rust evaluator rather than reimplementing it. It follows the patterndistinctFrom(#4917) and typed arrays (#4922) set forwasm-dpp2.What was done?
New module
wasm-dpp2/src/data_contract/document_type_property_constraints.rs, and threeDataContractmembers:checkDocumentPropertyConstraints: evaluates the rules withPropertyConstraint::violation(properties, Some(owner)), the function consensus calls on a create or replace. It takes aDocumentrather than a plain object so that integers, identifiers and the owner arrive typed as consensus sees them. It checks the rules only, not the JSON schema. It throws for a document of another contract or an unknown document type.readsandreadsOwnercome fromPropertyConstraint::property_readsandreads_owner.readsOwnertells an app that a transfer or purchase is judged against the rule too.numberwhile it is exact in JavaScript and abigintpastNumber.MAX_SAFE_INTEGER(a comparison, anifAbsentdefault or aninvalue), so one large literal never hides a type's rules.PropertyConstraintExpression,PropertyConstraintEqualityOperand,PropertyConstraintCondition,PropertyConstraintReadKind,DocumentPropertyConstraint,PropertyConstraintViolationKindandDocumentPropertyConstraintViolation. They cover every operator: comparisons, arithmetic,ifAbsent(integer and string defaults),in(integers, strings, base58 identifiers),const,$ownerId,present/absent, andanyOf/allOf/not.How Has This Been Tested?
wasm-dpp2/tests/unit/DocumentPropertyConstraints.spec.ts(11 tests):readsOwner(integer, stringconst,present,absent, identifier and$ownerId, arithmetic,in);Number.MAX_SAFE_INTEGER(comparison, negativeifAbsentdefault,invalue) reported exactly asbigintby both discovery APIs;NotMet,DivisionByZero),$ownerIdread from the document's owner, a type without rules, and a foreign-contract or unknown-type document throwing.wasm-dpp2(yarn workspace @dashevo/wasm-dpp2 build). The new spec passes (11), and the whole wasm-dpp2 mocha suite passes: 1338, 7 pending (karma/browser run left to CI).cargo clippy -p wasm-dpp2 --all-targets -- -D warnings, native and--target wasm32-unknown-unknown, andeslinton the spec.Breaking Changes
None. Additive JS API only.
Checklist:
structure.rs, regeneratedgrovedb-structure.json, and checked the structure viewer link posted on this pull requestFor repository code-owners and collaborators only
🤖 Generated with Claude Code
PR Hygiene ·
fab5826/self-reviewedonce the bots are donejs-wasm-sdk(packages/js-evo-sdk/README.md) — shumkovWhen every box is checked the
PR Hygienecheck passes and this can merge.