Skip to main content

drive/verify/shielded/verify_shielded_nullifiers/
mod.rs

1mod v0;
2
3use crate::drive::shielded::paths::token_shielded_pool_nullifiers_path_vec;
4use crate::drive::Drive;
5use crate::error::drive::DriveError;
6use crate::error::Error;
7use crate::verify::RootHash;
8use dpp::version::PlatformVersion;
9
10impl Drive {
11    /// Verifies a proof for shielded nullifier spend status.
12    #[allow(clippy::type_complexity)]
13    pub fn verify_shielded_nullifiers(
14        proof: &[u8],
15        nullifiers: &[Vec<u8>],
16        verify_subset_of_proof: bool,
17        platform_version: &PlatformVersion,
18    ) -> Result<(RootHash, Vec<(Vec<u8>, bool)>), Error> {
19        match platform_version
20            .drive
21            .methods
22            .verify
23            .shielded
24            .verify_shielded_nullifiers
25        {
26            0 => Self::verify_shielded_nullifiers_v0(
27                proof,
28                nullifiers,
29                verify_subset_of_proof,
30                platform_version,
31            ),
32            version => Err(Error::Drive(DriveError::UnknownVersionMismatch {
33                method: "verify_shielded_nullifiers".to_string(),
34                known_versions: vec![0],
35                received: version,
36            })),
37        }
38    }
39}
40
41impl Drive {
42    /// Verifies a proof of nullifier spent statuses in a TOKEN shielded pool. Same versioning
43    /// as [`Drive::verify_shielded_nullifiers`].
44    ///
45    /// Unlike the credit pool, which every chain that serves these reads already holds, a token
46    /// pool exists only for a token that opted into one, and any 32 bytes a caller supplies name
47    /// a pool that may never have been created. A spend status is only answered for a pool the
48    /// same proof shows the chain holds.
49    #[allow(clippy::type_complexity)]
50    pub fn verify_token_shielded_pool_nullifiers(
51        proof: &[u8],
52        token_id: [u8; 32],
53        nullifiers: &[Vec<u8>],
54        verify_subset_of_proof: bool,
55        platform_version: &PlatformVersion,
56    ) -> Result<(RootHash, Vec<(Vec<u8>, bool)>), Error> {
57        match platform_version
58            .drive
59            .methods
60            .verify
61            .shielded
62            .verify_shielded_nullifiers
63        {
64            0 => {
65                let (root_hash, statuses) = Self::verify_pool_nullifiers_v0(
66                    proof,
67                    token_shielded_pool_nullifiers_path_vec(token_id),
68                    nullifiers,
69                    verify_subset_of_proof,
70                    platform_version,
71                )?;
72
73                Self::verify_token_shielded_pool_exists_v0(
74                    proof,
75                    token_id,
76                    root_hash,
77                    platform_version,
78                )?;
79
80                Ok((root_hash, statuses))
81            }
82            version => Err(Error::Drive(DriveError::UnknownVersionMismatch {
83                method: "verify_token_shielded_pool_nullifiers".to_string(),
84                known_versions: vec![0],
85                received: version,
86            })),
87        }
88    }
89}
90
91#[cfg(test)]
92mod tests {
93    use super::*;
94    use dpp::version::PlatformVersion;
95
96    #[test]
97    fn test_verify_shielded_nullifiers_unknown_version_mismatch() {
98        let mut platform_version = PlatformVersion::latest().clone();
99        platform_version
100            .drive
101            .methods
102            .verify
103            .shielded
104            .verify_shielded_nullifiers = 255;
105
106        let result = Drive::verify_shielded_nullifiers(&[], &[], false, &platform_version);
107
108        assert!(
109            matches!(
110                result,
111                Err(Error::Drive(DriveError::UnknownVersionMismatch { .. }))
112            ),
113            "expected UnknownVersionMismatch, got {:?}",
114            result,
115        );
116    }
117}