Skip to main content

dash_platform_queries/documents/
document_count.rs

1//! `FromProof` + `Fetch` for [`DocumentCount`] — the single-row
2//! aggregate count view of the unified `getDocuments` endpoint.
3//!
4//! Callers build a [`DocumentQuery`] with
5//! `.with_select(Select::Count)`, optionally adding a
6//! `with_where(...)` clause; whatever the request shape, this
7//! impl returns a single `u64` (the aggregate count). Per-shape
8//! proof dispatch lives in
9//! [`super::count_proof_helpers::verify_count_query`] — this
10//! impl just sums the verified entries the helper returns.
11//!
12//! Empty entries (e.g. a verifier that emitted `None` for a
13//! queried-but-absent branch) contribute 0 to the sum via
14//! `filter_map(|e| e.count)`.
15//!
16//! A `containsAny` over several elements of a typed array is refused, even
17//! grouped by the array: summed, a document holding two of the elements would
18//! count twice. [`drive_proof_verifier::DocumentSplitCounts`] keeps one count
19//! per element.
20
21use crate::documents::count_proof_helpers::{
22    assert_select_is_count, check_count_request, verify_count_query,
23};
24use crate::documents::document_query::DocumentQuery;
25use dapi_grpc::platform::v0::{GetDocumentsResponse, Proof, ResponseMetadata};
26use dash_context_provider::ContextProvider;
27use dpp::dashcore::Network;
28use dpp::version::PlatformVersion;
29use drive_proof_verifier::{DocumentCount, FromProof};
30
31impl FromProof<DocumentQuery> for DocumentCount {
32    type Request = DocumentQuery;
33    type Response = GetDocumentsResponse;
34
35    /// One total adds up every verified entry, so the verifier refuses a `containsAny`
36    /// that reads several elements of a typed array even grouped by the array, which
37    /// the server answers with one total per element.
38    fn check_request(
39        request: &Self::Request,
40        platform_version: &PlatformVersion,
41    ) -> Result<(), drive_proof_verifier::Error> {
42        check_count_request(request, true, platform_version)
43    }
44
45    fn maybe_from_proof_with_metadata<'a, I: Into<Self::Request>, O: Into<Self::Response>>(
46        request: I,
47        response: O,
48        _network: Network,
49        platform_version: &PlatformVersion,
50        provider: &'a dyn ContextProvider,
51    ) -> Result<(Option<Self>, ResponseMetadata, Proof), drive_proof_verifier::Error>
52    where
53        Self: 'a,
54    {
55        let request: Self::Request = request.into();
56        assert_select_is_count(&request)?;
57        let response: Self::Response = response.into();
58        let (entries, mtd, proof) =
59            verify_count_query(request, response, true, platform_version, provider)?;
60        let count = entries
61            .map(|es| es.iter().filter_map(|e| e.count).sum::<u64>())
62            .map(DocumentCount);
63        Ok((count, mtd, proof))
64    }
65}