drive_proof_verifier/proof/
token_pre_programmed_distributions.rs1use crate::error::MapGroveDbError;
2use crate::verify::verify_tenderdash_proof;
3use crate::{types::TokenPreProgrammedDistributions, ContextProvider, Error};
4use dapi_grpc::platform::v0::{
5 get_token_pre_programmed_distributions_request, GetTokenPreProgrammedDistributionsRequest,
6 GetTokenPreProgrammedDistributionsResponse, Proof, ResponseMetadata,
7};
8use dapi_grpc::platform::VersionedGrpcResponse;
9use dpp::dashcore::Network;
10use dpp::prelude::Identifier;
11use dpp::version::PlatformVersion;
12use drive::drive::tokens::distribution::queries::QueryPreProgrammedDistributionStartAt;
13use drive::drive::Drive;
14
15use super::FromProof;
16
17impl FromProof<GetTokenPreProgrammedDistributionsRequest> for TokenPreProgrammedDistributions {
18 type Request = GetTokenPreProgrammedDistributionsRequest;
19 type Response = GetTokenPreProgrammedDistributionsResponse;
20
21 fn maybe_from_proof_with_metadata<'a, I: Into<Self::Request>, O: Into<Self::Response>>(
22 request: I,
23 response: O,
24 _network: Network,
25 platform_version: &PlatformVersion,
26 provider: &'a dyn ContextProvider,
27 ) -> Result<(Option<Self>, ResponseMetadata, Proof), Error>
28 where
29 Self: Sized + 'a,
30 {
31 let request: Self::Request = request.into();
32 let response: Self::Response = response.into();
33
34 let get_token_pre_programmed_distributions_request::Version::V0(req_v0) =
35 request.version.ok_or(Error::EmptyVersion)?;
36
37 let token_id: [u8; 32] =
38 req_v0
39 .token_id
40 .as_slice()
41 .try_into()
42 .map_err(|_| Error::RequestError {
43 error: "token_id must be 32 bytes".into(),
44 })?;
45
46 let start_at = match req_v0.start_at_info {
47 Some(start_at_info) => {
48 let start_at_recipient = match start_at_info.start_recipient {
49 Some(recipient_bytes) => {
50 let recipient_id =
51 Identifier::from_bytes(&recipient_bytes).map_err(|_| {
52 Error::RequestError {
53 error: "start_recipient must be 32 bytes".into(),
54 }
55 })?;
56 let included = start_at_info.start_recipient_included.unwrap_or(true);
58 Some((recipient_id, included))
59 }
60 None => None,
61 };
62
63 Some(QueryPreProgrammedDistributionStartAt {
64 start_at_time: start_at_info.start_time_ms,
65 start_at_recipient,
66 })
67 }
68 None => None,
69 };
70
71 let limit = req_v0
72 .limit
73 .map(|l| {
74 u16::try_from(l).map_err(|_| Error::RequestError {
75 error: "limit exceeds u16::MAX".into(),
76 })
77 })
78 .transpose()?;
79
80 let metadata = response
81 .metadata()
82 .or(Err(Error::EmptyResponseMetadata))?
83 .clone();
84
85 let proof = response.proof_owned().or(Err(Error::NoProofInResult))?;
86
87 let (root_hash, result): ([u8; 32], TokenPreProgrammedDistributions) =
88 Drive::verify_token_pre_programmed_distributions(
89 &proof.grovedb_proof,
90 token_id,
91 start_at,
92 limit,
93 false,
94 platform_version,
95 )
96 .map_drive_error(&proof, &metadata)?;
97
98 verify_tenderdash_proof(&proof, &metadata, &root_hash, provider)?;
99
100 if result.0.is_empty() {
101 Ok((None, metadata, proof))
102 } else {
103 Ok((Some(result), metadata, proof))
104 }
105 }
106}