@dashevo/dapi-grpc 3.1.0-dev.1 → 3.1.0-dev.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +0 -2
- package/Cargo.toml +1 -1
- package/README.md +0 -1
- package/build.rs +75 -8
- package/clients/drive/v0/nodejs/drive_pbjs.js +53499 -36752
- package/clients/platform/v0/nodejs/platform_pbjs.js +53499 -36752
- package/clients/platform/v0/nodejs/platform_protoc.js +44924 -28778
- package/clients/platform/v0/web/platform_pb.d.ts +2626 -444
- package/clients/platform/v0/web/platform_pb.js +44924 -28778
- package/clients/platform/v0/web/platform_pb_service.d.ts +171 -0
- package/clients/platform/v0/web/platform_pb_service.js +360 -0
- package/package.json +3 -3
- package/protos/platform/v0/platform.proto +924 -2
- package/src/mock/serde_mockable.rs +1 -1
|
@@ -7,6 +7,7 @@ package org.dash.platform.dapi.v0;
|
|
|
7
7
|
import "google/protobuf/timestamp.proto";
|
|
8
8
|
|
|
9
9
|
service Platform {
|
|
10
|
+
// @sdk-ignore: Write-only endpoint, not a query
|
|
10
11
|
rpc broadcastStateTransition(BroadcastStateTransitionRequest)
|
|
11
12
|
returns (BroadcastStateTransitionResponse);
|
|
12
13
|
rpc getIdentity(GetIdentityRequest) returns (GetIdentityResponse);
|
|
@@ -42,6 +43,7 @@ service Platform {
|
|
|
42
43
|
returns (GetIdentityByNonUniquePublicKeyHashResponse);
|
|
43
44
|
rpc waitForStateTransitionResult(WaitForStateTransitionResultRequest)
|
|
44
45
|
returns (WaitForStateTransitionResultResponse);
|
|
46
|
+
// @sdk-ignore: Consensus params fetched via Tenderdash RPC
|
|
45
47
|
rpc getConsensusParams(GetConsensusParamsRequest)
|
|
46
48
|
returns (GetConsensusParamsResponse);
|
|
47
49
|
rpc getProtocolVersionUpgradeState(GetProtocolVersionUpgradeStateRequest)
|
|
@@ -116,6 +118,24 @@ service Platform {
|
|
|
116
118
|
returns (GetRecentAddressBalanceChangesResponse);
|
|
117
119
|
rpc getRecentCompactedAddressBalanceChanges(GetRecentCompactedAddressBalanceChangesRequest)
|
|
118
120
|
returns (GetRecentCompactedAddressBalanceChangesResponse);
|
|
121
|
+
rpc getShieldedEncryptedNotes(GetShieldedEncryptedNotesRequest)
|
|
122
|
+
returns (GetShieldedEncryptedNotesResponse);
|
|
123
|
+
rpc getShieldedAnchors(GetShieldedAnchorsRequest)
|
|
124
|
+
returns (GetShieldedAnchorsResponse);
|
|
125
|
+
rpc getMostRecentShieldedAnchor(GetMostRecentShieldedAnchorRequest)
|
|
126
|
+
returns (GetMostRecentShieldedAnchorResponse);
|
|
127
|
+
rpc getShieldedPoolState(GetShieldedPoolStateRequest)
|
|
128
|
+
returns (GetShieldedPoolStateResponse);
|
|
129
|
+
rpc getShieldedNullifiers(GetShieldedNullifiersRequest)
|
|
130
|
+
returns (GetShieldedNullifiersResponse);
|
|
131
|
+
rpc getNullifiersTrunkState(GetNullifiersTrunkStateRequest)
|
|
132
|
+
returns (GetNullifiersTrunkStateResponse);
|
|
133
|
+
rpc getNullifiersBranchState(GetNullifiersBranchStateRequest)
|
|
134
|
+
returns (GetNullifiersBranchStateResponse);
|
|
135
|
+
rpc getRecentNullifierChanges(GetRecentNullifierChangesRequest)
|
|
136
|
+
returns (GetRecentNullifierChangesResponse);
|
|
137
|
+
rpc getRecentCompactedNullifierChanges(GetRecentCompactedNullifierChangesRequest)
|
|
138
|
+
returns (GetRecentCompactedNullifierChangesResponse);
|
|
119
139
|
}
|
|
120
140
|
|
|
121
141
|
// Proof message includes cryptographic proofs for validating responses
|
|
@@ -557,6 +577,221 @@ message GetDataContractHistoryResponse {
|
|
|
557
577
|
}
|
|
558
578
|
|
|
559
579
|
message GetDocumentsRequest {
|
|
580
|
+
// Comparison operator for a single `WhereClause`. Wire values
|
|
581
|
+
// mirror `drive::query::WhereOperator` 1:1; the server maps the
|
|
582
|
+
// enum discriminant directly without re-parsing operator strings.
|
|
583
|
+
//
|
|
584
|
+
// `BETWEEN*` operators expect the right-hand operand to be a
|
|
585
|
+
// 2-element `DocumentFieldValue.list` carrying `[lower, upper]`;
|
|
586
|
+
// `IN` expects a `list` of candidate values; all other operators
|
|
587
|
+
// expect a scalar `DocumentFieldValue` matching the indexed
|
|
588
|
+
// field's type.
|
|
589
|
+
enum WhereOperator {
|
|
590
|
+
EQUAL = 0;
|
|
591
|
+
GREATER_THAN = 1;
|
|
592
|
+
GREATER_THAN_OR_EQUALS = 2;
|
|
593
|
+
LESS_THAN = 3;
|
|
594
|
+
LESS_THAN_OR_EQUALS = 4;
|
|
595
|
+
BETWEEN = 5;
|
|
596
|
+
BETWEEN_EXCLUDE_BOUNDS = 6;
|
|
597
|
+
BETWEEN_EXCLUDE_LEFT = 7;
|
|
598
|
+
BETWEEN_EXCLUDE_RIGHT = 8;
|
|
599
|
+
IN = 9;
|
|
600
|
+
STARTS_WITH = 10;
|
|
601
|
+
}
|
|
602
|
+
|
|
603
|
+
// Tagged scalar (or list) operand for a `WhereClause`. The
|
|
604
|
+
// variant the caller picks names the wire-level primitive type
|
|
605
|
+
// only — the **document type's schema** is the source of truth
|
|
606
|
+
// for the indexed field's actual type, and the server coerces
|
|
607
|
+
// each variant through the schema-driven
|
|
608
|
+
// `document_type.serialize_value_for_key(field, value, …)` path
|
|
609
|
+
// (the same path the CBOR-shaped v0 request flows through). That
|
|
610
|
+
// means:
|
|
611
|
+
//
|
|
612
|
+
// - Identifier-typed fields accept either a `bytes_value` (raw
|
|
613
|
+
// 32 bytes) **or** a `text` (base58-encoded). The schema
|
|
614
|
+
// decides; callers don't need a dedicated identifier variant.
|
|
615
|
+
// - Fixed-width byte fields (e.g. `Bytes20`/`Bytes36`) accept
|
|
616
|
+
// `bytes_value` of the appropriate length; the schema
|
|
617
|
+
// validates the size.
|
|
618
|
+
// - Numeric fields accept the closest-fit signed (`int64_value`)
|
|
619
|
+
// or unsigned (`uint64_value`) variant; the schema coerces to
|
|
620
|
+
// the indexed type (`u8` … `u64`/`i8` … `i64`/`u128`/`i128`).
|
|
621
|
+
// - String / bool fields accept `text` / `bool_value`.
|
|
622
|
+
//
|
|
623
|
+
// The `null_value` variant is the typed-wire equivalent of a CBOR
|
|
624
|
+
// `null` operand on the v0 path. Callers should NOT use it for
|
|
625
|
+
// "no clause" — empty where-clauses are still expressed by
|
|
626
|
+
// leaving `GetDocumentsRequestV1.where_clauses` empty. It exists
|
|
627
|
+
// for clauses that legitimately compare against `null` (e.g.
|
|
628
|
+
// queries on schema-nullable index entries from the v0 wire that
|
|
629
|
+
// round-trip through the v1 surface).
|
|
630
|
+
message DocumentFieldValue {
|
|
631
|
+
// Recursive list — operand for `IN` (candidate values) and
|
|
632
|
+
// `BETWEEN*` (exactly 2 values `[lower, upper]`). Nested
|
|
633
|
+
// `list` is structurally allowed but every supported document
|
|
634
|
+
// index value-type is currently scalar, so callers should not
|
|
635
|
+
// need to nest.
|
|
636
|
+
message ValueList { repeated DocumentFieldValue values = 1; }
|
|
637
|
+
|
|
638
|
+
oneof variant {
|
|
639
|
+
bool bool_value = 1;
|
|
640
|
+
sint64 int64_value = 2 [jstype = JS_STRING];
|
|
641
|
+
uint64 uint64_value = 3 [jstype = JS_STRING];
|
|
642
|
+
double double_value = 4;
|
|
643
|
+
string text = 5;
|
|
644
|
+
bytes bytes_value = 6;
|
|
645
|
+
ValueList list = 7;
|
|
646
|
+
// `bool` payload is a placeholder — only the discriminant
|
|
647
|
+
// matters. Picking the variant means "this operand is null";
|
|
648
|
+
// the bool value itself is ignored on the server.
|
|
649
|
+
bool null_value = 8;
|
|
650
|
+
}
|
|
651
|
+
}
|
|
652
|
+
|
|
653
|
+
// Single `field <op> value` clause. The server reassembles a
|
|
654
|
+
// `Vec<WhereClause>` from the request's `where_clauses` field,
|
|
655
|
+
// runs the same `WhereClause::group_clauses` validator (rejects
|
|
656
|
+
// duplicate / conflicting same-field clauses) and the same
|
|
657
|
+
// `> AND <` → `between*` canonicalizer the CBOR-shaped path uses,
|
|
658
|
+
// then hands the structured clauses to the executor. Wire
|
|
659
|
+
// semantics are identical to v0's CBOR `[field, op, value]`
|
|
660
|
+
// triples — only the envelope differs.
|
|
661
|
+
message WhereClause {
|
|
662
|
+
string field = 1;
|
|
663
|
+
WhereOperator operator = 2;
|
|
664
|
+
DocumentFieldValue value = 3;
|
|
665
|
+
}
|
|
666
|
+
|
|
667
|
+
// Per-group aggregate operand for the left side of a
|
|
668
|
+
// `HavingClause`. Only the per-group aggregates live here:
|
|
669
|
+
// `MIN` / `MAX` / `TOP` / `BOTTOM` are **cross-group** ranking
|
|
670
|
+
// primitives and appear on the right side via `HavingRanking`.
|
|
671
|
+
//
|
|
672
|
+
// **Field semantics by function**:
|
|
673
|
+
// - `COUNT`: empty `field` means `COUNT(*)` (group cardinality);
|
|
674
|
+
// non-empty `field` means `COUNT(field)` (count of non-null
|
|
675
|
+
// values of `field` in the group).
|
|
676
|
+
// - `SUM` / `AVG`: `field` is required.
|
|
677
|
+
message HavingAggregate {
|
|
678
|
+
enum Function {
|
|
679
|
+
COUNT = 0;
|
|
680
|
+
SUM = 1;
|
|
681
|
+
AVG = 2;
|
|
682
|
+
}
|
|
683
|
+
Function function = 1;
|
|
684
|
+
// Required for every function except `COUNT`; for `COUNT` an
|
|
685
|
+
// empty `field` means `COUNT(*)`.
|
|
686
|
+
string field = 2;
|
|
687
|
+
}
|
|
688
|
+
|
|
689
|
+
// Cross-group ranking primitive on the right side of a
|
|
690
|
+
// `HavingClause`. The ranking is computed over the set of
|
|
691
|
+
// group-aggregate results (one per `GROUP BY` row), so
|
|
692
|
+
// `HAVING COUNT(*) EQ MAX` selects groups whose count equals
|
|
693
|
+
// the maximum count across all groups, and
|
|
694
|
+
// `HAVING COUNT(*) IN TOP(5)` selects groups whose count is
|
|
695
|
+
// among the five largest. Concise way to express top-N /
|
|
696
|
+
// bottom-N selection without window functions or
|
|
697
|
+
// `ORDER BY` + `LIMIT`.
|
|
698
|
+
//
|
|
699
|
+
// **Operator compatibility**:
|
|
700
|
+
// - Scalar operators (`=`, `!=`, `<`, `<=`, `>`, `>=`) work
|
|
701
|
+
// with `MIN` / `MAX`. `TOP` / `BOTTOM` with scalar operators
|
|
702
|
+
// only make sense when `n=1` (the single largest / smallest);
|
|
703
|
+
// evaluation rejects other combinations as ambiguous.
|
|
704
|
+
// - `IN` works with `TOP(n)` / `BOTTOM(n)` for set membership.
|
|
705
|
+
// - `BETWEEN*` doesn't compose meaningfully with rankings and
|
|
706
|
+
// is rejected at evaluation time.
|
|
707
|
+
message HavingRanking {
|
|
708
|
+
enum Kind {
|
|
709
|
+
MIN = 0;
|
|
710
|
+
MAX = 1;
|
|
711
|
+
TOP = 2;
|
|
712
|
+
BOTTOM = 3;
|
|
713
|
+
}
|
|
714
|
+
Kind kind = 1;
|
|
715
|
+
// N-th rank for `TOP` / `BOTTOM` (1-indexed: `n=1` is the
|
|
716
|
+
// single largest / smallest). Required for those two kinds;
|
|
717
|
+
// must be unset for `MIN` / `MAX`. The wire allows setting
|
|
718
|
+
// it on `MIN` / `MAX` for forward compatibility, but
|
|
719
|
+
// evaluation rejects it as a malformed ranking.
|
|
720
|
+
optional uint64 n = 2 [jstype = JS_STRING];
|
|
721
|
+
}
|
|
722
|
+
|
|
723
|
+
// Single `HAVING <aggregate> <op> <right>` clause. Multiple
|
|
724
|
+
// entries in `GetDocumentsRequestV1.having` combine with
|
|
725
|
+
// implicit AND — same semantics as multiple `where_clauses`
|
|
726
|
+
// entries. `HAVING COUNT(*) > 5 AND SUM(amount) > 100` is two
|
|
727
|
+
// `HavingClause` rows, not a tree.
|
|
728
|
+
//
|
|
729
|
+
// The operator set mirrors `WhereOperator` minus `STARTS_WITH`
|
|
730
|
+
// (prefix matching has no natural meaning against a scalar
|
|
731
|
+
// aggregate result, even a string-typed one). `BETWEEN*` and
|
|
732
|
+
// `IN` operand semantics match `WhereOperator`: `BETWEEN*`
|
|
733
|
+
// expects a 2-element `DocumentFieldValue.list` carrying
|
|
734
|
+
// `[lower, upper]`, and `IN` expects a `list` of candidate
|
|
735
|
+
// values (or a ranking set via `right.ranking`).
|
|
736
|
+
//
|
|
737
|
+
// The `right` oneof carries either a concrete
|
|
738
|
+
// `DocumentFieldValue` (literal comparison target) or a
|
|
739
|
+
// `HavingRanking` (cross-group reference). Exactly one is set;
|
|
740
|
+
// the wire rejects an unset `right`.
|
|
741
|
+
message HavingClause {
|
|
742
|
+
enum Operator {
|
|
743
|
+
EQUAL = 0;
|
|
744
|
+
NOT_EQUAL = 1;
|
|
745
|
+
GREATER_THAN = 2;
|
|
746
|
+
GREATER_THAN_OR_EQUALS = 3;
|
|
747
|
+
LESS_THAN = 4;
|
|
748
|
+
LESS_THAN_OR_EQUALS = 5;
|
|
749
|
+
BETWEEN = 6;
|
|
750
|
+
BETWEEN_EXCLUDE_BOUNDS = 7;
|
|
751
|
+
BETWEEN_EXCLUDE_LEFT = 8;
|
|
752
|
+
BETWEEN_EXCLUDE_RIGHT = 9;
|
|
753
|
+
IN = 10;
|
|
754
|
+
}
|
|
755
|
+
HavingAggregate aggregate = 1;
|
|
756
|
+
Operator operator = 2;
|
|
757
|
+
oneof right {
|
|
758
|
+
DocumentFieldValue value = 3;
|
|
759
|
+
HavingRanking ranking = 4;
|
|
760
|
+
}
|
|
761
|
+
}
|
|
762
|
+
|
|
763
|
+
// Single `ORDER BY field <direction>` clause. Multi-field
|
|
764
|
+
// ordering is expressed by repeating this message at the
|
|
765
|
+
// request level (`repeated OrderClause order_by = 4`), matching
|
|
766
|
+
// SQL's `ORDER BY a ASC, b DESC` shape.
|
|
767
|
+
// Single ORDER BY entry. Multi-entry ordering is expressed by
|
|
768
|
+
// repeating this message at the request level.
|
|
769
|
+
//
|
|
770
|
+
// The `target` oneof carries either a plain field name
|
|
771
|
+
// (`ORDER BY field`) or an aggregate function applied to a
|
|
772
|
+
// field (`ORDER BY COUNT(*)`, `ORDER BY SUM(amount)`) — the
|
|
773
|
+
// latter sorts per-group result rows produced by `GROUP BY`,
|
|
774
|
+
// useful with `LIMIT` for top-N / bottom-N selection at the
|
|
775
|
+
// routing layer (overlapping `HavingRanking::Top` / `Bottom`
|
|
776
|
+
// but more general because the ranking field can be any
|
|
777
|
+
// aggregate, not just count).
|
|
778
|
+
//
|
|
779
|
+
// **Aggregate target currently rejected** with
|
|
780
|
+
// `Unsupported("ORDER BY on aggregate is not yet implemented")`.
|
|
781
|
+
// The wire surface is shipped now so callers can encode the
|
|
782
|
+
// shape ahead of server support landing.
|
|
783
|
+
message OrderClause {
|
|
784
|
+
oneof target {
|
|
785
|
+
// Plain field name. Today's evaluated form.
|
|
786
|
+
string field = 1;
|
|
787
|
+
// Aggregate function applied to a field, sorted by the
|
|
788
|
+
// per-group result. `function = DOCUMENTS` is invalid
|
|
789
|
+
// here — DOCUMENTS isn't an aggregate.
|
|
790
|
+
HavingAggregate aggregate = 3;
|
|
791
|
+
}
|
|
792
|
+
bool ascending = 2;
|
|
793
|
+
}
|
|
794
|
+
|
|
560
795
|
message GetDocumentsRequestV0 {
|
|
561
796
|
bytes data_contract_id =
|
|
562
797
|
1; // The ID of the data contract containing the documents
|
|
@@ -572,7 +807,281 @@ message GetDocumentsRequest {
|
|
|
572
807
|
}
|
|
573
808
|
bool prove = 8; // Flag to request a proof as the response
|
|
574
809
|
}
|
|
575
|
-
|
|
810
|
+
|
|
811
|
+
// SQL-shaped successor to v0 that unifies `getDocuments` and
|
|
812
|
+
// `getDocumentsCount` under a single request type with a typed
|
|
813
|
+
// `select` projection and optional `group_by` / `having` clauses.
|
|
814
|
+
//
|
|
815
|
+
// Mode is determined by `select` × `group_by` × `having`:
|
|
816
|
+
//
|
|
817
|
+
// * `select = DOCUMENTS, group_by = []`: return matched documents
|
|
818
|
+
// (identical semantics to v0).
|
|
819
|
+
// * `select = COUNT, group_by = []`: return a single aggregate
|
|
820
|
+
// count. With an `In` clause the server fans out per-In via
|
|
821
|
+
// `query_aggregate_count` and sums (O(|In| × log n), see
|
|
822
|
+
// `RangeNoProof`'s compound-summed path); with a range clause
|
|
823
|
+
// it uses `AggregateCountOnRange`.
|
|
824
|
+
// * `select = COUNT, group_by = [<field>]`: return per-group
|
|
825
|
+
// `CountEntry` rows. Only supported when the grouping field
|
|
826
|
+
// matches an `In`-constrained or range-constrained where clause;
|
|
827
|
+
// other shapes return `Unsupported` (see supported-shape table
|
|
828
|
+
// below).
|
|
829
|
+
//
|
|
830
|
+
// `having` is wire-reserved for a future server capability. Any
|
|
831
|
+
// non-empty `having` list currently returns
|
|
832
|
+
// `Unsupported("HAVING clause is not yet implemented")`
|
|
833
|
+
// regardless of `select` / `group_by`. The wire shape is
|
|
834
|
+
// `repeated WhereClause` so when execution lands the surface is
|
|
835
|
+
// already typed end-to-end and callers don't need to re-encode.
|
|
836
|
+
//
|
|
837
|
+
// **Supported shapes** (everything else rejects with a typed
|
|
838
|
+
// `QuerySyntaxError::Unsupported` so callers can detect un-wired
|
|
839
|
+
// capabilities without parsing prose). Bullets are kept
|
|
840
|
+
// single-line so the generated Rust doc comments don't trip
|
|
841
|
+
// rustdoc's `list_item_without_indent` lint on continuation
|
|
842
|
+
// lines.
|
|
843
|
+
//
|
|
844
|
+
// `select=DOCUMENTS, group_by=[]`: any where shape v0 supports.
|
|
845
|
+
//
|
|
846
|
+
// `select=COUNT, group_by=[]`:
|
|
847
|
+
// - empty where → `documentsCountable: true` doctype.
|
|
848
|
+
// - `==` only → `countable: true` index covering the fields.
|
|
849
|
+
// - one `In` → `countable: true` index covering the fields (per-In aggregate fan-out).
|
|
850
|
+
// - one range → `rangeCountable: true` index.
|
|
851
|
+
// - one `In` + one range → `rangeCountable: true` compound index (per-In aggregate fan-out on no-proof; rejected on prove because the aggregate proof primitive can't fork).
|
|
852
|
+
//
|
|
853
|
+
// `select=COUNT, group_by=[g]`:
|
|
854
|
+
// - g is the In clause's field → `countable: true` index, grouped by g (PerInValue on no-proof, CountTree element proof per In branch on prove).
|
|
855
|
+
// - g is the range clause's field → `rangeCountable: true` index, grouped by g (RangeDistinct on no-proof, distinct range proof on prove).
|
|
856
|
+
//
|
|
857
|
+
// `select=COUNT, group_by=[a, b]`:
|
|
858
|
+
// - a is the In field AND b is the range field, in that order → existing compound distinct shape; entries carry both `in_key` (= a's value) and `key` (= b's value).
|
|
859
|
+
//
|
|
860
|
+
// **Rejected shapes** (return `Unsupported`):
|
|
861
|
+
// - any non-empty `having` (always — pending future server capability).
|
|
862
|
+
// - `select=DOCUMENTS` with non-empty `group_by`.
|
|
863
|
+
// - `select=COUNT` with `group_by` on a field that is not constrained by an `In` or range where clause.
|
|
864
|
+
// - `select=COUNT` with `group_by.len() > 2`.
|
|
865
|
+
// - `select=COUNT` with 2-field `group_by` that does not match the `(in_field, range_field)` shape above.
|
|
866
|
+
//
|
|
867
|
+
// **Absent-from-tree branches on `In`-grouped queries**: when
|
|
868
|
+
// `select=COUNT, group_by=[in_field]` and an `In` value has no
|
|
869
|
+
// matching documents, the underlying merk index has nothing to
|
|
870
|
+
// emit (zero-count branches aren't materialized as CountTree
|
|
871
|
+
// elements), so the wire `CountEntries.entries` list contains
|
|
872
|
+
// only the In values that exist.
|
|
873
|
+
//
|
|
874
|
+
// The SDK's proof decoder surfaces this by **omission**, not by
|
|
875
|
+
// a sentinel `count` value: the current point-lookup path query
|
|
876
|
+
// doesn't set `absence_proofs_for_non_existing_searched_keys:
|
|
877
|
+
// true`, so grovedb's `verify_query` silently drops absent-Key
|
|
878
|
+
// branches from the verified elements stream. The drive-side
|
|
879
|
+
// verifier (`verify_point_lookup_count_proof`) therefore emits
|
|
880
|
+
// one `SplitCountEntry` per **present** In branch and the SDK
|
|
881
|
+
// wraps those into `CountEntry`. Callers that need to detect
|
|
882
|
+
// "queried but absent" diff their request's In array against
|
|
883
|
+
// the returned entries by `key` (each entry's `key` is the
|
|
884
|
+
// serialized In value, recoverable via
|
|
885
|
+
// `document_type.serialize_value_for_key(in_field, v, …)`).
|
|
886
|
+
// `SplitCountEntry::count`'s `Option<u64>` and the `None`
|
|
887
|
+
// variant exist for a future absence-proof variant; today the
|
|
888
|
+
// wire `CountEntry.count` is plain `uint64`.
|
|
889
|
+
//
|
|
890
|
+
// For range-grouped queries the walker only emits keys that
|
|
891
|
+
// exist in the index, which IS SQL-conformant; no equivalent
|
|
892
|
+
// reconstruction step because the range itself is unbounded and
|
|
893
|
+
// the caller has no explicit "expected keys" list to compare
|
|
894
|
+
// against.
|
|
895
|
+
message GetDocumentsRequestV1 {
|
|
896
|
+
// Projection over the matched row set. `(function, field)`
|
|
897
|
+
// pair — analogous to `HavingAggregate`'s shape but with an
|
|
898
|
+
// additional `DOCUMENTS` variant for the row-fetch path.
|
|
899
|
+
//
|
|
900
|
+
// Determines what the response carries:
|
|
901
|
+
// - `DOCUMENTS`: `ResultData.documents` (matched rows;
|
|
902
|
+
// `field` must be empty).
|
|
903
|
+
// - `COUNT`: `ResultData.counts` carrying row counts. Empty
|
|
904
|
+
// `field` is `COUNT(*)` (group cardinality); non-empty is
|
|
905
|
+
// `COUNT(field)` (non-null `field` values).
|
|
906
|
+
// - `SUM` / `AVG`: `ResultData` carrying numeric
|
|
907
|
+
// aggregate(s); `field` is required and must be a
|
|
908
|
+
// numeric-typed schema field.
|
|
909
|
+
//
|
|
910
|
+
// Single-aggregate vs per-group response shape comes from
|
|
911
|
+
// `group_by` (empty → single, non-empty → per-group entries) —
|
|
912
|
+
// same rule as today's `COUNT` routing.
|
|
913
|
+
//
|
|
914
|
+
// **Server capability today**: `DOCUMENTS`, `COUNT(*)` (empty
|
|
915
|
+
// `field`), `SUM(<field>)`, and `AVG(<field>)` are evaluated
|
|
916
|
+
// end-to-end (no-proof and proof paths route through the drive
|
|
917
|
+
// count / sum / average dispatchers). `COUNT(<field>)` (non-null
|
|
918
|
+
// value counting on a specific field), `MIN(<field>)`, and
|
|
919
|
+
// `MAX(<field>)` are wire-stable but rejected at routing time
|
|
920
|
+
// with `Unsupported("SELECT … is not yet implemented")` so the
|
|
921
|
+
// surface is shipped first and execution lands later without
|
|
922
|
+
// another version bump. MIN/MAX in particular wait on a grovedb
|
|
923
|
+
// primitive — there's no min/max aggregate on count or sum
|
|
924
|
+
// trees today, and the order-by-then-LIMIT-1 emulation has the
|
|
925
|
+
// wrong proof shape for the cryptographic verifier.
|
|
926
|
+
message Select {
|
|
927
|
+
enum Function {
|
|
928
|
+
DOCUMENTS = 0;
|
|
929
|
+
COUNT = 1;
|
|
930
|
+
SUM = 2;
|
|
931
|
+
AVG = 3;
|
|
932
|
+
// Per-group MIN / MAX — `SELECT MIN(field) GROUP BY
|
|
933
|
+
// category` returns the smallest `field` value in each
|
|
934
|
+
// category. Semantically distinct from
|
|
935
|
+
// `HavingRanking::Min` / `Max` (which are cross-group
|
|
936
|
+
// meta-aggregates over group results). MIN/MAX here
|
|
937
|
+
// operate over the row values within each group, the
|
|
938
|
+
// same way `SUM` and `AVG` do.
|
|
939
|
+
MIN = 4;
|
|
940
|
+
MAX = 5;
|
|
941
|
+
}
|
|
942
|
+
Function function = 1;
|
|
943
|
+
// Field the projection function is applied to. See the
|
|
944
|
+
// message-level docstring for the per-function requirement
|
|
945
|
+
// (empty for `DOCUMENTS`, optional for `COUNT`, required
|
|
946
|
+
// for `SUM` / `AVG` / `MIN` / `MAX`).
|
|
947
|
+
string field = 2;
|
|
948
|
+
}
|
|
949
|
+
|
|
950
|
+
bytes data_contract_id = 1; // The data contract owning the documents
|
|
951
|
+
string document_type = 2; // Document type within the contract
|
|
952
|
+
// Structured where clauses. Empty list = no `WHERE` filter
|
|
953
|
+
// (return all matching rows under the document type / contract).
|
|
954
|
+
// See top-level `WhereClause` for shape semantics.
|
|
955
|
+
repeated WhereClause where_clauses = 3;
|
|
956
|
+
// Structured order_by clauses. Empty list = no explicit
|
|
957
|
+
// ordering (server applies the index's natural order). Multiple
|
|
958
|
+
// entries express SQL's `ORDER BY a ASC, b DESC, …` shape; the
|
|
959
|
+
// first entry's direction also governs split-mode entry
|
|
960
|
+
// ordering on `select=COUNT` paths.
|
|
961
|
+
repeated OrderClause order_by = 4;
|
|
962
|
+
// Maximum number of rows to return.
|
|
963
|
+
//
|
|
964
|
+
// **Wire semantics on the `optional uint32` field**: `None`
|
|
965
|
+
// (unset) requests the server's default; `Some(N)` with `N > 0`
|
|
966
|
+
// requests an explicit cap of `N`. `Some(0)` is **rejected with
|
|
967
|
+
// `InvalidLimit` across every SELECT mode** — zero-cap is
|
|
968
|
+
// structurally meaningless and the legacy v0 `uint32`-with-0-as-
|
|
969
|
+
// sentinel mapping doesn't extend to `optional uint32` (the
|
|
970
|
+
// whole point of switching is that `None` carries "unset"
|
|
971
|
+
// explicitly). Callers must send `None` for "use server default."
|
|
972
|
+
//
|
|
973
|
+
// Per-mode behavior of `Some(N > 0)`:
|
|
974
|
+
// - `select=DOCUMENTS`: matched-document cap (same as v0).
|
|
975
|
+
// - `select=COUNT, group_by=[]`: **rejected with `InvalidLimit`
|
|
976
|
+
// when set**. Aggregate count is a single row by construction
|
|
977
|
+
// — a limit would either be redundant (≥ 1) or silently
|
|
978
|
+
// mislead callers if the dispatcher's per-In fan-out honored
|
|
979
|
+
// it and returned a partial sum disguised as a total. Omit
|
|
980
|
+
// `limit` for aggregate count.
|
|
981
|
+
// - `select=COUNT, group_by=[in_field]`: **rejected with
|
|
982
|
+
// `InvalidLimit` when set**. The In array is already capped
|
|
983
|
+
// at 100 entries by `WhereClause::in_values()`, so the
|
|
984
|
+
// result is bounded by construction; a separate `limit`
|
|
985
|
+
// would either be redundant or silently truncate the proof
|
|
986
|
+
// to fewer In branches than the caller asked for (the
|
|
987
|
+
// PointLookupProof shape can't represent a partial-In
|
|
988
|
+
// selection in its `SizedQuery`). Narrow the In array
|
|
989
|
+
// directly to reduce the result set.
|
|
990
|
+
// - `select=COUNT, group_by=[range_field]`: entries cap on
|
|
991
|
+
// the distinct-range walk.
|
|
992
|
+
// - `select=COUNT, group_by=[in_field, range_field]`: global
|
|
993
|
+
// cap over the emitted `(in_key, key)` lex stream — NOT
|
|
994
|
+
// per-In-branch. The compound walk pushes one
|
|
995
|
+
// `SizedQuery::limit` over the combined tuple stream, so a
|
|
996
|
+
// request with `|In| = 3` and `limit = 5` returns at most
|
|
997
|
+
// 5 entries total across all In branches (ordered by
|
|
998
|
+
// `(in_key, key)`, direction from the first `order_by`
|
|
999
|
+
// clause).
|
|
1000
|
+
// Both range-grouped variants share the same validate-don't-
|
|
1001
|
+
// clamp policy on prove paths — `limit > max_query_limit`
|
|
1002
|
+
// returns `InvalidLimit` rather than silent clamping (see
|
|
1003
|
+
// `RangeDistinctProof`'s contract; unset falls back to the
|
|
1004
|
+
// SDK-shared `DEFAULT_QUERY_LIMIT` compile-time constant so
|
|
1005
|
+
// proof bytes are deterministic across operators).
|
|
1006
|
+
optional uint32 limit = 5;
|
|
1007
|
+
|
|
1008
|
+
// Pagination cursor. Valid only for `select=DOCUMENTS`. The
|
|
1009
|
+
// count surface (`select=COUNT`) rejects cursors entirely:
|
|
1010
|
+
// aggregate counts have no concept of "start," and per-group
|
|
1011
|
+
// entry paginators would need a new merk walk that doesn't
|
|
1012
|
+
// exist yet — callers paginate counts by narrowing the
|
|
1013
|
+
// where-clause range itself instead.
|
|
1014
|
+
oneof start {
|
|
1015
|
+
bytes start_after = 6;
|
|
1016
|
+
bytes start_at = 7;
|
|
1017
|
+
}
|
|
1018
|
+
|
|
1019
|
+
bool prove = 8; // Request a grovedb proof instead of raw rows
|
|
1020
|
+
|
|
1021
|
+
// SQL `SELECT` projection list. Multiple entries express
|
|
1022
|
+
// `SELECT f1(a), f2(b), …` — one row per group carrying a
|
|
1023
|
+
// parallel list of aggregate values in the response.
|
|
1024
|
+
//
|
|
1025
|
+
// Empty list defaults to a single `documents()` projection
|
|
1026
|
+
// for v0-style document fetch — callers that don't opt into
|
|
1027
|
+
// the SQL-shaped surface get plain row semantics.
|
|
1028
|
+
//
|
|
1029
|
+
// **Currently rejected when `selects.len() > 1`** with
|
|
1030
|
+
// `Unsupported("multi-projection SELECT is not yet
|
|
1031
|
+
// implemented")`. The single-projection cases `DOCUMENTS`,
|
|
1032
|
+
// `COUNT(*)`, `SUM(<field>)`, and `AVG(<field>)` are evaluated
|
|
1033
|
+
// end-to-end today and route through the drive count / sum /
|
|
1034
|
+
// average dispatchers (see the `GetDocumentsResponseV1`
|
|
1035
|
+
// docstring for the wire-shape table). `COUNT(<field>)`,
|
|
1036
|
+
// `MIN(<field>)`, and `MAX(<field>)` remain rejected at the
|
|
1037
|
+
// per-function gate — see the `Select` message-level docstring
|
|
1038
|
+
// for the rationale (no grovedb min/max primitive; COUNT(field)
|
|
1039
|
+
// needs a non-null counter walk that doesn't exist yet). When
|
|
1040
|
+
// multi-projection lands the response shape gains a parallel
|
|
1041
|
+
// `repeated AggregateValue values` field, so caller code
|
|
1042
|
+
// structured around `repeated Select` doesn't need to be
|
|
1043
|
+
// rewritten when it does.
|
|
1044
|
+
repeated Select selects = 9;
|
|
1045
|
+
|
|
1046
|
+
// SQL `GROUP BY` field names, in left-to-right order. Empty =
|
|
1047
|
+
// no explicit grouping (aggregate for `select=COUNT`). See the
|
|
1048
|
+
// message-level docstring for the supported-shape table.
|
|
1049
|
+
repeated string group_by = 10;
|
|
1050
|
+
|
|
1051
|
+
// SQL `HAVING` clauses — aggregate filters that apply to the
|
|
1052
|
+
// grouped rows produced by `select=COUNT, group_by=[…]`. The
|
|
1053
|
+
// wire shape is `HavingClause`, not `WhereClause`, because
|
|
1054
|
+
// HAVING evaluates against per-group aggregates
|
|
1055
|
+
// (`COUNT`/`SUM`/`AVG`/`MIN`/`MAX`/`TOP`/`BOTTOM`) rather than
|
|
1056
|
+
// row field values. Multiple entries combine with implicit
|
|
1057
|
+
// AND. See `HavingClause` / `HavingAggregate` for the
|
|
1058
|
+
// operator and aggregate-function catalogs.
|
|
1059
|
+
//
|
|
1060
|
+
// **Always rejected when non-empty** today with
|
|
1061
|
+
// `Unsupported("HAVING clause is not yet implemented")`. The
|
|
1062
|
+
// wire shape is shipped now so the future server capability
|
|
1063
|
+
// can land without another version bump — and so callers can
|
|
1064
|
+
// construct full `HAVING COUNT(*) > 5 AND SUM(amount) > 100`
|
|
1065
|
+
// requests in their builders even before the server evaluates
|
|
1066
|
+
// them.
|
|
1067
|
+
repeated HavingClause having = 11;
|
|
1068
|
+
|
|
1069
|
+
// Row-based pagination offset, on top of the cursor-based
|
|
1070
|
+
// `start_after` / `start_at` pagination. `OFFSET N` skips the
|
|
1071
|
+
// first `N` matching rows before applying `limit`. Currently
|
|
1072
|
+
// **always rejected when non-`None`** with
|
|
1073
|
+
// `Unsupported("OFFSET pagination is not yet implemented")`
|
|
1074
|
+
// — the wire surface is shipped now so callers can encode it
|
|
1075
|
+
// ahead of server support landing without another version
|
|
1076
|
+
// bump. Cursor pagination via `start_after` / `start_at`
|
|
1077
|
+
// remains the supported way to page through results.
|
|
1078
|
+
optional uint32 offset = 12;
|
|
1079
|
+
}
|
|
1080
|
+
|
|
1081
|
+
oneof version {
|
|
1082
|
+
GetDocumentsRequestV0 v0 = 1;
|
|
1083
|
+
GetDocumentsRequestV1 v1 = 2;
|
|
1084
|
+
}
|
|
576
1085
|
}
|
|
577
1086
|
|
|
578
1087
|
message GetDocumentsResponse {
|
|
@@ -588,7 +1097,207 @@ message GetDocumentsResponse {
|
|
|
588
1097
|
}
|
|
589
1098
|
ResponseMetadata metadata = 3; // Metadata about the blockchain state
|
|
590
1099
|
}
|
|
591
|
-
|
|
1100
|
+
|
|
1101
|
+
// v1 response. Two-variant outer `oneof` mirrors every other
|
|
1102
|
+
// `Get*Response`: a non-proof result at position 1, the proof at
|
|
1103
|
+
// position 2. The non-proof result is itself a `oneof` because
|
|
1104
|
+
// a single v1 request can produce either matched documents (for
|
|
1105
|
+
// `select=DOCUMENTS`) or count results (for `select=COUNT`) —
|
|
1106
|
+
// wrapping them in an inner `ResultData` keeps the outer shape
|
|
1107
|
+
// canonical without flattening to a three-variant oneof.
|
|
1108
|
+
//
|
|
1109
|
+
// Wire shape by `request.select` × `group_by` × `prove`:
|
|
1110
|
+
// - `select=DOCUMENTS` (no prove) → `result.data.documents`.
|
|
1111
|
+
// - `select=COUNT, group_by=[]` (no prove) → `result.data.counts.aggregate_count`.
|
|
1112
|
+
// - `select=COUNT, group_by=[…]` (no prove) → `result.data.counts.entries`.
|
|
1113
|
+
// - `select=SUM, group_by=[]` (no prove) → `result.data.sums.aggregate_sum`.
|
|
1114
|
+
// - `select=SUM, group_by=[…]` (no prove) → `result.data.sums.entries`.
|
|
1115
|
+
// - `select=AVG, group_by=[]` (no prove) → `result.data.averages.aggregate_average`.
|
|
1116
|
+
// - `select=AVG, group_by=[…]` (no prove) → `result.data.averages.entries`.
|
|
1117
|
+
// - any select (prove) → `result.proof`.
|
|
1118
|
+
//
|
|
1119
|
+
// **SUM / AVG status**: all four shapes above are wired
|
|
1120
|
+
// end-to-end on the drive dispatcher (no-proof and proof paths
|
|
1121
|
+
// both terminate at grovedb's aggregate-sum / sum-tree-walk
|
|
1122
|
+
// primitives, not at a `NotYetImplemented` stub). The four
|
|
1123
|
+
// resolved-mode tables (`compute_aggregate_mode_and_check_limit_v0`,
|
|
1124
|
+
// `detect_count_mode`, `detect_sum_mode`, AVG mirror) decide which
|
|
1125
|
+
// executor to run from the (mode × range × group_by × prove)
|
|
1126
|
+
// tuple; the executors compose count and sum walks for AVG so
|
|
1127
|
+
// there's no separate average primitive on the grovedb side.
|
|
1128
|
+
// Routing details live in
|
|
1129
|
+
// `packages/rs-drive/src/query/drive_document_{sum,average}_query/`.
|
|
1130
|
+
//
|
|
1131
|
+
// `CountResults` / `CountEntry` / `CountEntries` are nested in
|
|
1132
|
+
// `GetDocumentsResponseV1` rather than re-exported from a
|
|
1133
|
+
// top-level message — the v0 `getDocumentsCount` endpoint that
|
|
1134
|
+
// previously owned them has been removed in this version (it
|
|
1135
|
+
// shipped briefly in #3623 and never had stable callers); v1 is
|
|
1136
|
+
// the single home for the count wire types.
|
|
1137
|
+
message GetDocumentsResponseV1 {
|
|
1138
|
+
// Documents result variant — matches the v0 `Documents`
|
|
1139
|
+
// message field-for-field (kept distinct so v1 doesn't reach
|
|
1140
|
+
// into v0's namespace once v0 is eventually retired).
|
|
1141
|
+
message Documents {
|
|
1142
|
+
repeated bytes documents = 1;
|
|
1143
|
+
}
|
|
1144
|
+
|
|
1145
|
+
// A single per-key entry. Carries `in_key` for compound
|
|
1146
|
+
// queries (`In` on a prefix property of a `range_countable`
|
|
1147
|
+
// index plus a range clause on the terminator) where each
|
|
1148
|
+
// entry is keyed by both the In-fork's prefix value (`in_key`)
|
|
1149
|
+
// and the terminator value (`key`). Cross-fork aggregation is
|
|
1150
|
+
// intentionally NOT done server-side — callers get the
|
|
1151
|
+
// unmerged per-`(in_key, key)` view and can reduce client-side
|
|
1152
|
+
// if they want a flat histogram.
|
|
1153
|
+
message CountEntry {
|
|
1154
|
+
optional bytes in_key = 1;
|
|
1155
|
+
bytes key = 2;
|
|
1156
|
+
// `jstype = JS_STRING` so JS/Web clients receive a string
|
|
1157
|
+
// and don't round counts > 2^53−1 to the nearest
|
|
1158
|
+
// representable Number.
|
|
1159
|
+
uint64 count = 3 [jstype = JS_STRING];
|
|
1160
|
+
}
|
|
1161
|
+
|
|
1162
|
+
message CountEntries {
|
|
1163
|
+
repeated CountEntry entries = 1;
|
|
1164
|
+
}
|
|
1165
|
+
|
|
1166
|
+
// Non-proof count result. Shape is mode-dependent and made
|
|
1167
|
+
// explicit on the wire via the inner `variant` oneof:
|
|
1168
|
+
// * `aggregate_count`: `select=COUNT, group_by=[]` —
|
|
1169
|
+
// single u64 with no per-key breakdown.
|
|
1170
|
+
// * `entries`: `select=COUNT, group_by=[…]` — one
|
|
1171
|
+
// CountEntry per distinct group, in serialized-key order
|
|
1172
|
+
// (subject to the first `order_by` clause's direction and
|
|
1173
|
+
// `limit`).
|
|
1174
|
+
message CountResults {
|
|
1175
|
+
oneof variant {
|
|
1176
|
+
uint64 aggregate_count = 1 [jstype = JS_STRING];
|
|
1177
|
+
CountEntries entries = 2;
|
|
1178
|
+
}
|
|
1179
|
+
}
|
|
1180
|
+
|
|
1181
|
+
// Sum-side analog of `CountEntry` — one per matched key for
|
|
1182
|
+
// `select=SUM, group_by=[...]` queries. `in_key` carries the
|
|
1183
|
+
// outer prefix value for compound `(In, range)` shapes; `key`
|
|
1184
|
+
// carries the terminator value. `sum` is signed because grovedb's
|
|
1185
|
+
// SumTree values are `i64` and sums can in principle be negative
|
|
1186
|
+
// (deliberate i64-overflow signaling — see the sum-tree book
|
|
1187
|
+
// chapter's "Signed `i64` overflow" note). For tip-jar-style
|
|
1188
|
+
// non-negative sums this stays >= 0 in practice.
|
|
1189
|
+
message SumEntry {
|
|
1190
|
+
optional bytes in_key = 1;
|
|
1191
|
+
bytes key = 2;
|
|
1192
|
+
// `jstype = JS_STRING` so JS/Web clients receive a string
|
|
1193
|
+
// and don't round large sums to the nearest Number.
|
|
1194
|
+
sint64 sum = 3 [jstype = JS_STRING];
|
|
1195
|
+
}
|
|
1196
|
+
|
|
1197
|
+
message SumEntries {
|
|
1198
|
+
repeated SumEntry entries = 1;
|
|
1199
|
+
}
|
|
1200
|
+
|
|
1201
|
+
// Non-proof sum result. Same shape as `CountResults` for the
|
|
1202
|
+
// sum surface — the variants mirror count's:
|
|
1203
|
+
// * `aggregate_sum`: `select=SUM, group_by=[]` — single signed
|
|
1204
|
+
// sum with no per-key breakdown.
|
|
1205
|
+
// * `entries`: `select=SUM, group_by=[…]` — one SumEntry per
|
|
1206
|
+
// distinct group.
|
|
1207
|
+
message SumResults {
|
|
1208
|
+
oneof variant {
|
|
1209
|
+
sint64 aggregate_sum = 1 [jstype = JS_STRING];
|
|
1210
|
+
SumEntries entries = 2;
|
|
1211
|
+
}
|
|
1212
|
+
}
|
|
1213
|
+
|
|
1214
|
+
// Average-side analog of `SumEntry` — one per matched key for
|
|
1215
|
+
// `select=AVG, group_by=[…]` queries. Each entry carries BOTH
|
|
1216
|
+
// the count and the sum for its group; the client divides
|
|
1217
|
+
// `sum / count` to compute the actual average.
|
|
1218
|
+
//
|
|
1219
|
+
// Why no `average` field on the wire? Returning the (count, sum)
|
|
1220
|
+
// pair preserves full precision and lets the client pick the
|
|
1221
|
+
// representation it wants (integer-truncated division, floating-
|
|
1222
|
+
// point, decimal). Returning a single pre-computed `average`
|
|
1223
|
+
// would force the server to choose, and any choice loses
|
|
1224
|
+
// information for callers that wanted a different one.
|
|
1225
|
+
//
|
|
1226
|
+
// This shape is produced by grovedb's `AggregateCountAndSumOnRange`
|
|
1227
|
+
// primitive (one root-hash-committed traversal returning both
|
|
1228
|
+
// metrics) which lands as part of grovedb PR 670 alongside the
|
|
1229
|
+
// PCPS (`ProvableCountProvableSumTree`) tree element.
|
|
1230
|
+
message AverageEntry {
|
|
1231
|
+
optional bytes in_key = 1;
|
|
1232
|
+
bytes key = 2;
|
|
1233
|
+
// `jstype = JS_STRING` on both fields so JS/Web clients receive
|
|
1234
|
+
// strings and don't lose precision on counts/sums exceeding
|
|
1235
|
+
// `Number.MAX_SAFE_INTEGER`.
|
|
1236
|
+
uint64 count = 3 [jstype = JS_STRING];
|
|
1237
|
+
sint64 sum = 4 [jstype = JS_STRING];
|
|
1238
|
+
}
|
|
1239
|
+
|
|
1240
|
+
message AverageEntries {
|
|
1241
|
+
repeated AverageEntry entries = 1;
|
|
1242
|
+
}
|
|
1243
|
+
|
|
1244
|
+
// Aggregate average across all matched documents (no group_by).
|
|
1245
|
+
// Same `(count, sum)` shape as a single entry — the client
|
|
1246
|
+
// computes `avg = sum / count` itself.
|
|
1247
|
+
message AverageAggregate {
|
|
1248
|
+
uint64 count = 1 [jstype = JS_STRING];
|
|
1249
|
+
sint64 sum = 2 [jstype = JS_STRING];
|
|
1250
|
+
}
|
|
1251
|
+
|
|
1252
|
+
// Non-proof average result. Same outer shape as
|
|
1253
|
+
// `CountResults` / `SumResults`; the variants mirror them:
|
|
1254
|
+
// * `aggregate_average`: `select=AVG, group_by=[]` — single
|
|
1255
|
+
// `(count, sum)` pair with no per-key breakdown.
|
|
1256
|
+
// * `entries`: `select=AVG, group_by=[…]` — one AverageEntry
|
|
1257
|
+
// per distinct group, each carrying its own `(count, sum)`.
|
|
1258
|
+
message AverageResults {
|
|
1259
|
+
oneof variant {
|
|
1260
|
+
AverageAggregate aggregate_average = 1;
|
|
1261
|
+
AverageEntries entries = 2;
|
|
1262
|
+
}
|
|
1263
|
+
}
|
|
1264
|
+
|
|
1265
|
+
// Non-proof result wrapper. The outer `oneof result` switches
|
|
1266
|
+
// between this and `proof`; this inner oneof switches between
|
|
1267
|
+
// the four non-proof shapes the v1 surface can return.
|
|
1268
|
+
message ResultData {
|
|
1269
|
+
oneof variant {
|
|
1270
|
+
Documents documents = 1;
|
|
1271
|
+
CountResults counts = 2;
|
|
1272
|
+
// Sum-aggregate result. Routed when the request's
|
|
1273
|
+
// `select.function == SUM` and the dispatcher's
|
|
1274
|
+
// [`DriveDocumentSumQuery`] (in rs-drive) returns a
|
|
1275
|
+
// non-proof variant. The schema field name (`sums`) parallels
|
|
1276
|
+
// `counts` above; field numbers stay 1/2/3/4 per the proto-
|
|
1277
|
+
// wire-stability rule (additions only, never renumbers).
|
|
1278
|
+
SumResults sums = 3;
|
|
1279
|
+
// Average-aggregate result. Routed when the request's
|
|
1280
|
+
// `select.function == AVG`. The dispatcher returns the
|
|
1281
|
+
// `(count, sum)` pair grovedb's `AggregateCountAndSumOnRange`
|
|
1282
|
+
// primitive produces in one root-hash-committed traversal;
|
|
1283
|
+
// the client divides to obtain the actual average. See
|
|
1284
|
+
// `book/src/drive/average-index-examples.md` for the design
|
|
1285
|
+
// and the grades-contract worked example.
|
|
1286
|
+
AverageResults averages = 4;
|
|
1287
|
+
}
|
|
1288
|
+
}
|
|
1289
|
+
|
|
1290
|
+
oneof result {
|
|
1291
|
+
ResultData data = 1;
|
|
1292
|
+
Proof proof = 2;
|
|
1293
|
+
}
|
|
1294
|
+
ResponseMetadata metadata = 3;
|
|
1295
|
+
}
|
|
1296
|
+
|
|
1297
|
+
oneof version {
|
|
1298
|
+
GetDocumentsResponseV0 v0 = 1;
|
|
1299
|
+
GetDocumentsResponseV1 v1 = 2;
|
|
1300
|
+
}
|
|
592
1301
|
}
|
|
593
1302
|
|
|
594
1303
|
message GetIdentityByPublicKeyHashRequest {
|
|
@@ -2057,6 +2766,11 @@ message GetRecentAddressBalanceChangesRequest {
|
|
|
2057
2766
|
message GetRecentAddressBalanceChangesRequestV0 {
|
|
2058
2767
|
uint64 start_height = 1 [ jstype = JS_STRING ];
|
|
2059
2768
|
bool prove = 2;
|
|
2769
|
+
// When true, use exclusive start (RangeAfter) instead of inclusive start
|
|
2770
|
+
// (RangeFrom). The start_height key becomes a boundary node in the proof
|
|
2771
|
+
// rather than a result element, enabling compaction detection via
|
|
2772
|
+
// key_exists_as_boundary.
|
|
2773
|
+
bool start_height_exclusive = 3;
|
|
2060
2774
|
}
|
|
2061
2775
|
oneof version { GetRecentAddressBalanceChangesRequestV0 v0 = 1; }
|
|
2062
2776
|
}
|
|
@@ -2125,3 +2839,211 @@ message GetRecentCompactedAddressBalanceChangesResponse {
|
|
|
2125
2839
|
}
|
|
2126
2840
|
oneof version { GetRecentCompactedAddressBalanceChangesResponseV0 v0 = 1; }
|
|
2127
2841
|
}
|
|
2842
|
+
|
|
2843
|
+
// --- Shielded Pool Queries ---
|
|
2844
|
+
|
|
2845
|
+
message GetShieldedEncryptedNotesRequest {
|
|
2846
|
+
message GetShieldedEncryptedNotesRequestV0 {
|
|
2847
|
+
uint64 start_index = 1;
|
|
2848
|
+
uint32 count = 2;
|
|
2849
|
+
bool prove = 3;
|
|
2850
|
+
}
|
|
2851
|
+
oneof version { GetShieldedEncryptedNotesRequestV0 v0 = 1; }
|
|
2852
|
+
}
|
|
2853
|
+
|
|
2854
|
+
message GetShieldedEncryptedNotesResponse {
|
|
2855
|
+
message GetShieldedEncryptedNotesResponseV0 {
|
|
2856
|
+
message EncryptedNote {
|
|
2857
|
+
bytes nullifier = 1; // 32-byte nullifier (needed for Rho derivation in trial decryption)
|
|
2858
|
+
bytes cmx = 2; // 32-byte extracted note commitment
|
|
2859
|
+
bytes encrypted_note = 3; // encrypted note payload (epk + enc_ciphertext + out_ciphertext)
|
|
2860
|
+
}
|
|
2861
|
+
message EncryptedNotes {
|
|
2862
|
+
repeated EncryptedNote entries = 1;
|
|
2863
|
+
}
|
|
2864
|
+
oneof result {
|
|
2865
|
+
EncryptedNotes encrypted_notes = 1;
|
|
2866
|
+
Proof proof = 2;
|
|
2867
|
+
}
|
|
2868
|
+
ResponseMetadata metadata = 3;
|
|
2869
|
+
}
|
|
2870
|
+
oneof version { GetShieldedEncryptedNotesResponseV0 v0 = 1; }
|
|
2871
|
+
}
|
|
2872
|
+
|
|
2873
|
+
message GetShieldedAnchorsRequest {
|
|
2874
|
+
message GetShieldedAnchorsRequestV0 {
|
|
2875
|
+
bool prove = 1;
|
|
2876
|
+
}
|
|
2877
|
+
oneof version { GetShieldedAnchorsRequestV0 v0 = 1; }
|
|
2878
|
+
}
|
|
2879
|
+
|
|
2880
|
+
message GetShieldedAnchorsResponse {
|
|
2881
|
+
message GetShieldedAnchorsResponseV0 {
|
|
2882
|
+
message Anchors {
|
|
2883
|
+
repeated bytes anchors = 1;
|
|
2884
|
+
}
|
|
2885
|
+
oneof result {
|
|
2886
|
+
Anchors anchors = 1;
|
|
2887
|
+
Proof proof = 2;
|
|
2888
|
+
}
|
|
2889
|
+
ResponseMetadata metadata = 3;
|
|
2890
|
+
}
|
|
2891
|
+
oneof version { GetShieldedAnchorsResponseV0 v0 = 1; }
|
|
2892
|
+
}
|
|
2893
|
+
|
|
2894
|
+
message GetMostRecentShieldedAnchorRequest {
|
|
2895
|
+
message GetMostRecentShieldedAnchorRequestV0 {
|
|
2896
|
+
bool prove = 1;
|
|
2897
|
+
}
|
|
2898
|
+
oneof version { GetMostRecentShieldedAnchorRequestV0 v0 = 1; }
|
|
2899
|
+
}
|
|
2900
|
+
|
|
2901
|
+
message GetMostRecentShieldedAnchorResponse {
|
|
2902
|
+
message GetMostRecentShieldedAnchorResponseV0 {
|
|
2903
|
+
oneof result {
|
|
2904
|
+
bytes anchor = 1;
|
|
2905
|
+
Proof proof = 2;
|
|
2906
|
+
}
|
|
2907
|
+
ResponseMetadata metadata = 3;
|
|
2908
|
+
}
|
|
2909
|
+
oneof version { GetMostRecentShieldedAnchorResponseV0 v0 = 1; }
|
|
2910
|
+
}
|
|
2911
|
+
|
|
2912
|
+
message GetShieldedPoolStateRequest {
|
|
2913
|
+
message GetShieldedPoolStateRequestV0 {
|
|
2914
|
+
bool prove = 1;
|
|
2915
|
+
}
|
|
2916
|
+
oneof version { GetShieldedPoolStateRequestV0 v0 = 1; }
|
|
2917
|
+
}
|
|
2918
|
+
|
|
2919
|
+
message GetShieldedPoolStateResponse {
|
|
2920
|
+
message GetShieldedPoolStateResponseV0 {
|
|
2921
|
+
oneof result {
|
|
2922
|
+
uint64 total_balance = 1 [jstype = JS_STRING];
|
|
2923
|
+
Proof proof = 2;
|
|
2924
|
+
}
|
|
2925
|
+
ResponseMetadata metadata = 3;
|
|
2926
|
+
}
|
|
2927
|
+
oneof version { GetShieldedPoolStateResponseV0 v0 = 1; }
|
|
2928
|
+
}
|
|
2929
|
+
|
|
2930
|
+
message GetShieldedNullifiersRequest {
|
|
2931
|
+
message GetShieldedNullifiersRequestV0 {
|
|
2932
|
+
repeated bytes nullifiers = 1;
|
|
2933
|
+
bool prove = 2;
|
|
2934
|
+
}
|
|
2935
|
+
oneof version { GetShieldedNullifiersRequestV0 v0 = 1; }
|
|
2936
|
+
}
|
|
2937
|
+
|
|
2938
|
+
message GetShieldedNullifiersResponse {
|
|
2939
|
+
message GetShieldedNullifiersResponseV0 {
|
|
2940
|
+
message NullifierStatus {
|
|
2941
|
+
bytes nullifier = 1;
|
|
2942
|
+
bool is_spent = 2;
|
|
2943
|
+
}
|
|
2944
|
+
message NullifierStatuses {
|
|
2945
|
+
repeated NullifierStatus entries = 1;
|
|
2946
|
+
}
|
|
2947
|
+
oneof result {
|
|
2948
|
+
NullifierStatuses nullifier_statuses = 1;
|
|
2949
|
+
Proof proof = 2;
|
|
2950
|
+
}
|
|
2951
|
+
ResponseMetadata metadata = 3;
|
|
2952
|
+
}
|
|
2953
|
+
oneof version { GetShieldedNullifiersResponseV0 v0 = 1; }
|
|
2954
|
+
}
|
|
2955
|
+
|
|
2956
|
+
message GetNullifiersTrunkStateRequest {
|
|
2957
|
+
message GetNullifiersTrunkStateRequestV0 {
|
|
2958
|
+
uint32 pool_type = 1; // ShieldedPoolType enum value (0=credit, 1=main token, 2=individual token)
|
|
2959
|
+
bytes pool_identifier = 2; // 32-byte Identifier, required for pool_type=2
|
|
2960
|
+
}
|
|
2961
|
+
oneof version { GetNullifiersTrunkStateRequestV0 v0 = 1; }
|
|
2962
|
+
}
|
|
2963
|
+
|
|
2964
|
+
message GetNullifiersTrunkStateResponse {
|
|
2965
|
+
message GetNullifiersTrunkStateResponseV0 {
|
|
2966
|
+
Proof proof = 2;
|
|
2967
|
+
ResponseMetadata metadata = 3;
|
|
2968
|
+
}
|
|
2969
|
+
oneof version { GetNullifiersTrunkStateResponseV0 v0 = 1; }
|
|
2970
|
+
}
|
|
2971
|
+
|
|
2972
|
+
message GetNullifiersBranchStateRequest {
|
|
2973
|
+
message GetNullifiersBranchStateRequestV0 {
|
|
2974
|
+
uint32 pool_type = 1;
|
|
2975
|
+
bytes pool_identifier = 2;
|
|
2976
|
+
bytes key = 3;
|
|
2977
|
+
uint32 depth = 4;
|
|
2978
|
+
uint64 checkpoint_height = 5;
|
|
2979
|
+
}
|
|
2980
|
+
oneof version { GetNullifiersBranchStateRequestV0 v0 = 1; }
|
|
2981
|
+
}
|
|
2982
|
+
|
|
2983
|
+
message GetNullifiersBranchStateResponse {
|
|
2984
|
+
message GetNullifiersBranchStateResponseV0 {
|
|
2985
|
+
bytes merk_proof = 2;
|
|
2986
|
+
}
|
|
2987
|
+
oneof version { GetNullifiersBranchStateResponseV0 v0 = 1; }
|
|
2988
|
+
}
|
|
2989
|
+
|
|
2990
|
+
// --- Recent Nullifier Changes ---
|
|
2991
|
+
|
|
2992
|
+
message BlockNullifierChanges {
|
|
2993
|
+
uint64 block_height = 1 [ jstype = JS_STRING ];
|
|
2994
|
+
repeated bytes nullifiers = 2; // Each is 32 bytes
|
|
2995
|
+
}
|
|
2996
|
+
|
|
2997
|
+
message NullifierUpdateEntries {
|
|
2998
|
+
repeated BlockNullifierChanges block_changes = 1;
|
|
2999
|
+
}
|
|
3000
|
+
|
|
3001
|
+
message GetRecentNullifierChangesRequest {
|
|
3002
|
+
message GetRecentNullifierChangesRequestV0 {
|
|
3003
|
+
uint64 start_height = 1 [ jstype = JS_STRING ];
|
|
3004
|
+
bool prove = 2;
|
|
3005
|
+
}
|
|
3006
|
+
oneof version { GetRecentNullifierChangesRequestV0 v0 = 1; }
|
|
3007
|
+
}
|
|
3008
|
+
|
|
3009
|
+
message GetRecentNullifierChangesResponse {
|
|
3010
|
+
message GetRecentNullifierChangesResponseV0 {
|
|
3011
|
+
oneof result {
|
|
3012
|
+
NullifierUpdateEntries nullifier_update_entries = 1;
|
|
3013
|
+
Proof proof = 2;
|
|
3014
|
+
}
|
|
3015
|
+
ResponseMetadata metadata = 3;
|
|
3016
|
+
}
|
|
3017
|
+
oneof version { GetRecentNullifierChangesResponseV0 v0 = 1; }
|
|
3018
|
+
}
|
|
3019
|
+
|
|
3020
|
+
// --- Compacted Nullifier Changes ---
|
|
3021
|
+
|
|
3022
|
+
message CompactedBlockNullifierChanges {
|
|
3023
|
+
uint64 start_block_height = 1 [ jstype = JS_STRING ];
|
|
3024
|
+
uint64 end_block_height = 2 [ jstype = JS_STRING ];
|
|
3025
|
+
repeated bytes nullifiers = 3; // Each is 32 bytes
|
|
3026
|
+
}
|
|
3027
|
+
|
|
3028
|
+
message CompactedNullifierUpdateEntries {
|
|
3029
|
+
repeated CompactedBlockNullifierChanges compacted_block_changes = 1;
|
|
3030
|
+
}
|
|
3031
|
+
|
|
3032
|
+
message GetRecentCompactedNullifierChangesRequest {
|
|
3033
|
+
message GetRecentCompactedNullifierChangesRequestV0 {
|
|
3034
|
+
uint64 start_block_height = 1 [ jstype = JS_STRING ];
|
|
3035
|
+
bool prove = 2;
|
|
3036
|
+
}
|
|
3037
|
+
oneof version { GetRecentCompactedNullifierChangesRequestV0 v0 = 1; }
|
|
3038
|
+
}
|
|
3039
|
+
|
|
3040
|
+
message GetRecentCompactedNullifierChangesResponse {
|
|
3041
|
+
message GetRecentCompactedNullifierChangesResponseV0 {
|
|
3042
|
+
oneof result {
|
|
3043
|
+
CompactedNullifierUpdateEntries compacted_nullifier_update_entries = 1;
|
|
3044
|
+
Proof proof = 2;
|
|
3045
|
+
}
|
|
3046
|
+
ResponseMetadata metadata = 3;
|
|
3047
|
+
}
|
|
3048
|
+
oneof version { GetRecentCompactedNullifierChangesResponseV0 v0 = 1; }
|
|
3049
|
+
}
|