Skip to main content

drive/verify/chained_document/verify_chained_documents_proof/
mod.rs

1mod v0;
2
3use crate::error::drive::DriveError;
4use crate::error::Error;
5use crate::query::{ChainedDocumentsResult, DriveDocumentQuery};
6use crate::verify::RootHash;
7use dpp::version::PlatformVersion;
8
9impl DriveDocumentQuery<'_> {
10    /// Verifies a chained query's single merged proof — this query as the
11    /// inner half plus the single by-id join its
12    /// [`sub_queries`](DriveDocumentQuery::sub_queries) carry — and
13    /// returns `(root_hash, result)`.
14    ///
15    /// The verifier trusts nothing about the join, and needs nothing
16    /// beyond the proof itself: a BOOTSTRAP subset pass runs the inner
17    /// query alone against the merged proof and extracts candidate
18    /// join values from its proven positions; the outer by-ids
19    /// component is derived from those (exactly as the prover derived
20    /// it from its materialization), the merged query is rebuilt, and
21    /// the AUTHORITATIVE full pass verifies the whole composition —
22    /// grovedb enforces the inner page's lifted per-instance limit and
23    /// range completeness — with the proven outer documents required
24    /// to match the proven inner join values exactly. A missing
25    /// referenced document is an invalid proof (`refersTo:
26    /// permanentDocument` targets cannot dangle), and so is an extra
27    /// one; a proof covering only the inner half (an old node serving
28    /// the plain query) fails the full pass whenever the inner page is
29    /// non-empty.
30    ///
31    /// One proof means one root by construction; the caller combines
32    /// the returned root hash with the surrounding tenderdash
33    /// signature — see `rs-drive-proof-verifier` for the canonical
34    /// composition.
35    pub fn verify_chained_documents_proof(
36        &self,
37        proof: &[u8],
38        platform_version: &PlatformVersion,
39    ) -> Result<(RootHash, ChainedDocumentsResult), Error> {
40        match platform_version
41            .drive
42            .methods
43            .verify
44            .chained_document
45            .verify_chained_documents_proof
46        {
47            0 => self.verify_chained_documents_proof_v0(proof, platform_version),
48            version => Err(Error::Drive(DriveError::UnknownVersionMismatch {
49                method: "DriveDocumentQuery::verify_chained_documents_proof".to_string(),
50                known_versions: vec![0],
51                received: version,
52            })),
53        }
54    }
55}
56
57#[cfg(test)]
58mod tests {
59    use super::*;
60    use crate::error::drive::DriveError;
61    use crate::query::DriveDocumentQuery;
62    use dpp::data_contract::accessors::v0::DataContractV0Getters;
63    use dpp::data_contracts::SystemDataContract;
64    use dpp::system_data_contracts::load_system_data_contract;
65
66    #[test]
67    fn test_verify_chained_documents_proof_unknown_version() {
68        let platform_version = dpp::version::PlatformVersion::latest();
69        let contract = load_system_data_contract(SystemDataContract::DPNS, platform_version)
70            .expect("expected to load DPNS contract");
71        let document_type = contract
72            .document_type_for_name("domain")
73            .expect("expected domain document type");
74
75        let mut platform_version = platform_version.clone();
76        platform_version
77            .drive
78            .methods
79            .verify
80            .chained_document
81            .verify_chained_documents_proof = 255;
82
83        let query = DriveDocumentQuery {
84            contract: &contract,
85            document_type,
86            internal_clauses: Default::default(),
87            offset: None,
88            limit: Some(1),
89            order_by: Default::default(),
90            start_at: None,
91            start_at_included: false,
92            block_time_ms: None,
93            resolved_time_ranges: vec![],
94            sub_queries: vec![],
95        }
96        .with_by_id_join("records", document_type);
97
98        let result = query.verify_chained_documents_proof(&[], &platform_version);
99        assert!(matches!(
100            result,
101            Err(Error::Drive(DriveError::UnknownVersionMismatch { method, .. }))
102                if method == "DriveDocumentQuery::verify_chained_documents_proof"
103        ));
104    }
105}