feat(platform)!: identifier comparisons in propertyConstraints rules (PV14) - #5047
Conversation
…(PV14)
An identifier property may now be compared, by equal or notEqual, with a
base58 identifier constant (`{ "const": "<base58>" }`) or another
identifier property, or listed with `{ "in": [path, ["<base58>", ...]] }`.
Identifiers compare by their 32 bytes, whatever form the document gives
them; one the document leaves out equals none. Ordering, defaults and
comparisons with strings are refused.
parse_property_constraints's is_string_property predicate becomes
property_kind (Text or Identifier), so the property a bare path names
decides what a const or a listed string means. A rule reading an
identifier property was refused before, so every registered rule
evaluates as it did.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
Warning Review limit reachedNext included review available in 56 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 (12)
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 |
|
📖 Book Preview built successfully. Download the preview from the workflow artifacts. Updated at 2026-09-27T09:36:49.484Z |
|
🕓 Queued for automated review — 2nd in line, estimated start in ~15 min (commit d8352a8)
|
Basic explanation
What this does: A
propertyConstraintsrule can now compare identifier properties (32-byte ids of identities, contracts, tokens or documents). They can be compared with fixed ids written in base58, with each other, or against an allowlist:{ "in": ["paymentToken", ["<base58>", "<base58>"]] }. #5042 and #5045 added the same comparisons for strings.Value: Contracts can now state rules like "payment is only in one of these tokens", "a refund goes back to the payer" or "this reference points at that contract", which were impossible before. Until now, a rule naming an identifier property was refused at registration.
Risks: Low. This changes consensus validation, but only in protocol version 14, which is not on mainnet. It only widens what is accepted: every rule that registered before still registers and evaluates the same way.
Issue being fixed or feature implemented
Last of the follow-ups listed with the string comparisons (#5042, #5045, #5046).
What was done?
Grammar
These are the same three forms as for strings, with an identifier property's type deciding what a
conststring means:{ "equal": ["paymentToken", { "const": "<base58>" }] }ornotEqual, with the constant on either side. The constant must decode to exactly 32 bytes, checked at registration.{ "notEqual": ["buyerId", "sellerId"] }, two bare paths that both name identifier properties.{ "in": ["paymentToken", ["<base58>", "<base58>"]] }, two or more distinct identifiers.Before, these were refused on registration with
... reads "paymentToken", which has type identifier, not integer or boolean. Now they register:{ "paymentToken": <token B>, "payerId": P, "refundTo": P }{ "paymentToken": <token C> }paidInAcceptedTokenNotMet{ "payerId": P, "refundTo": Q }refundGoesToPayerNotMetSemantics and checks
Identifier,Bytes32or 32Bytes, the sameto_identifierthatdistinctFromuses).compares identifiers, which only equal and notEqual do), as is comparing an identifier property with a string property.ifAbsentdefault for an identifier is refused (gives an identifier property a default, which identifiers do not take).enumto check against.$ownerIdis not an operand: the writer's id isn't part of the data the rules read, anddistinctFromalready keeps an identifier property apart from the owner. It could be added later by passing the owner id intovalidate_document_properties.Code
property_constraints/mod.rs:IdentifierCompare { comparison, path, value: Identifier },IdentifierCompareProperties { comparison, left, right }andIdentifierIn { path, values: BTreeSet<Identifier> };PropertyRead::Identifier;is_string_propertypredicate becomesproperty_kind: &dyn Fn(&str) -> Option<EqualityKind>(TextorIdentifier), so the property a bare path names decides whether aconstor a listed string is text or a base58 identifier;identifier_comparison,identifier_side,identifier_constant,in_identifier_valuesandidentifier_value.try_from_schema/mod.rs: buildsproperty_kindfrom the parsed types, adds the identifier type check, and adds the hint for an identifier read as a number.DocumentTypeV2,PROPERTY_CONSTRAINTSandSystemLimitsdocs.How Has This Been Tested?
property_constraints/tests.rs:invalues;Identifier,Bytes32andBytesforms, other ids, null, a non-identifier value and missing properties;try_from_schema/v3/property_constraints_tests.rs(theorderschema gainsbuyerIdandsellerId), on both paths:batch/tests/document/property_constraints.rs: theofferfixture gainspayerId,refundToandpaymentTokenwithpaidInAcceptedTokenandrefundGoesToPayer, andshould_compare_identifier_propertiesruns real creates (two refused with 10422, one accepted).cargo test -p dpp --lib(4871 passed),cargo test -p drive-abci --lib property_constraints(16 passed),cargo clippy -p dpp --all-features --all-targets -- -D warnings,cargo clippy -p drive-abci --all-targets -- -D warnings.Breaking Changes
Consensus, protocol version 14 only: contracts may now register rules comparing identifier properties, which earlier 4.2 builds refuse.
parse_property_constraints0 andvalidate_property_constraints0 were introduced in protocol version 14, which is not released on mainnet, so they are extended in place. Every declaration valid before parses and evaluates identically. A comparison becomes an identifier comparison only when a path it names is an identifier property, and a rule reading one was refused before. Aconstbeside a string property still compares strings.Rust API:
parse_property_constraints's third argument is nowproperty_kind: &dyn Fn(&str) -> Option<EqualityKind>(wasis_string_property), andPropertyConstraintgains three variants andPropertyReadone.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 ·
d8352a8/skip-botsproceeds without the ones not yet reported/self-reviewedonce the bots are donejs-wasm-sdk(packages/js-evo-sdk/README.md) — shumkovdpp— you own itrs-drive-abci— you own itWhen every box is checked the
PR Hygienecheck passes and this can merge.