Skip to main content

drive/verify/document/verify_proof/
mod.rs

1mod v0;
2
3use crate::error::drive::DriveError;
4use crate::verify::RootHash;
5
6use crate::error::Error;
7use crate::query::DriveDocumentQuery;
8use dpp::document::Document;
9
10use dpp::version::PlatformVersion;
11
12impl DriveDocumentQuery<'_> {
13    /// Verifies a proof for a collection of documents.
14    ///
15    /// This function takes a byte slice representing the serialized proof, verifies it, and returns a tuple consisting of the root hash
16    /// and a vector of deserialized documents.
17    ///
18    /// # Arguments
19    ///
20    /// * `proof` - A byte slice representing the proof to be verified.
21    /// * `platform_version` - The platform version against which to verify the proof.
22    ///
23    /// # Returns
24    ///
25    /// A `Result` containing:
26    /// * A tuple with the root hash and a vector of deserialized `Document`s if the proof is valid.
27    /// * An `Error` variant, in case the proof verification fails or a deserialization error occurs.
28    ///
29    /// # Errors
30    ///
31    /// This function will return an `Error` variant if:
32    /// 1. The proof verification fails.
33    /// 2. A deserialization error occurs when parsing the serialized document(s).
34    pub fn verify_proof(
35        &self,
36        proof: &[u8],
37        platform_version: &PlatformVersion,
38    ) -> Result<(RootHash, Vec<Document>), Error> {
39        self.ensure_no_sub_queries("verify_proof")?;
40        match platform_version.drive.methods.verify.document.verify_proof {
41            0 => self.verify_proof_v0(proof, platform_version),
42            version => Err(Error::Drive(DriveError::UnknownVersionMismatch {
43                method: "verify_proof".to_string(),
44                known_versions: vec![0],
45                received: version,
46            })),
47        }
48    }
49}
50
51#[cfg(test)]
52mod tests {
53    use super::*;
54    use crate::error::drive::DriveError;
55    use dpp::data_contract::accessors::v0::DataContractV0Getters;
56    use dpp::data_contracts::SystemDataContract;
57    use dpp::system_data_contracts::load_system_data_contract;
58
59    #[test]
60    fn test_document_verify_proof_unknown_version() {
61        let platform_version = PlatformVersion::latest();
62        let contract = load_system_data_contract(SystemDataContract::DPNS, platform_version)
63            .expect("expected to load DPNS contract");
64        let document_type = contract
65            .document_type_for_name("domain")
66            .expect("expected domain document type");
67
68        let mut platform_version = platform_version.clone();
69        platform_version.drive.methods.verify.document.verify_proof = 255;
70
71        let query = DriveDocumentQuery {
72            contract: &contract,
73            document_type,
74            internal_clauses: Default::default(),
75            offset: None,
76            limit: None,
77            order_by: Default::default(),
78            start_at: None,
79            start_at_included: false,
80            block_time_ms: None,
81            resolved_time_ranges: vec![],
82            sub_queries: vec![],
83        };
84
85        let result = query.verify_proof(&[], &platform_version);
86
87        assert!(
88            matches!(result, Err(Error::Drive(DriveError::UnknownVersionMismatch { method, known_versions, received }))
89                if method == "verify_proof" && known_versions == vec![0] && received == 255
90            )
91        );
92    }
93}