Skip to main content

dash_sdk/mock/
requests.rs

1use super::MockDashPlatformSdk;
2use dpp::balances::total_single_token_balance::TotalSingleTokenBalance;
3use dpp::bincode::config::standard;
4use dpp::address_funds::PlatformAddress;
5use dpp::data_contract::associated_token::token_perpetual_distribution::reward_distribution_moment::RewardDistributionMoment;
6use dpp::data_contract::group::Group;
7use dpp::group::group_action::GroupAction;
8use dpp::tokens::contract_info::TokenContractInfo;
9use dpp::tokens::info::IdentityTokenInfo;
10use dpp::tokens::status::TokenStatus;
11use dpp::tokens::token_pricing_schedule::TokenPricingSchedule;
12use dpp::{
13    bincode,
14    block::{extended_epoch_info::ExtendedEpochInfo, finalized_epoch_info::FinalizedEpochInfo},
15    dashcore::{hashes::Hash as CoreHash, ProTxHash},
16    document::{serialization_traits::DocumentCborMethodsV0, Document},
17    identifier::Identifier,
18    identity::{identities_contract_keys::IdentitiesContractKeys, IdentityPublicKey},
19    platform_serialization::{platform_encode_to_vec, platform_versioned_decode_from_slice},
20    prelude::{DataContract, Identity},
21    serialization::{
22        PlatformDeserializableWithPotentialValidationFromVersionedStructureUntrusted,
23        PlatformSerializableWithPlatformVersion,
24    },
25    voting::votes::{resource_vote::ResourceVote, Vote},
26};
27use drive::grovedb::Element;
28use drive_proof_verifier::types::identity_keys_remaining_budgets::IdentityKeysRemainingBudgets;
29use drive_proof_verifier::types::contract_groups::{
30    ContractGroupInfo, ContractGroupMembersPage, ContractGroupMembershipsForContract,
31};
32use drive_proof_verifier::types::data_contracts_latest_versions::{
33    DataContractLatestVersion, DataContractsLatestVersions,
34};
35use drive_proof_verifier::types::data_contracts_by_range::DataContractsByRange;
36use drive_proof_verifier::types::evonode_status::EvoNodeStatus;
37use drive_proof_verifier::types::groups::GroupActions;
38use drive_proof_verifier::types::identity_token_balance::{
39    IdentitiesTokenBalances, IdentityTokenBalances,
40};
41use drive_proof_verifier::types::token_info::{IdentitiesTokenInfos, IdentityTokenInfos};
42use drive_proof_verifier::types::token_status::TokenStatuses;
43use drive::grovedb::GroveTrunkQueryResult;
44use drive_proof_verifier::types::{
45    AddressInfo, Contenders, ContestedResources, CurrentQuorumsInfo, ElementFetchRequestItem,
46    IdentityBalanceAndRevision, IndexMap, MasternodeProtocolVote, MostRecentShieldedAnchor,
47    PlatformAddressTrunkState, PrefundedSpecializedBalance, ProposerBlockCounts,
48    RecentAddressBalanceChanges, RecentCompactedAddressBalanceChanges, RetrievedValues,
49    ShieldedAnchors, ShieldedEncryptedNote, ShieldedEncryptedNotes, ShieldedNotesCount,
50    ShieldedNullifierStatus, ShieldedNullifierStatuses, ShieldedPoolState,
51    TokenPreProgrammedDistributions, TotalCreditsInPlatform, VotePollsGroupedByTimestamp, Voters,
52};
53use std::{collections::BTreeMap, hash::Hash};
54
55static BINCODE_CONFIG: bincode::config::Configuration = bincode::config::standard();
56
57/// Trait implemented by objects that can be used in mock expectation responses.
58///
59/// ## Panics
60///
61/// Can panic on errors.
62pub trait MockResponse {
63    /// Serialize the object to save into expectations
64    ///
65    /// ## Panics
66    ///
67    /// Can panic on errors.
68    fn mock_serialize(&self, mock_sdk: &MockDashPlatformSdk) -> Vec<u8>;
69
70    /// Deserialize the object from expectations
71    ///
72    /// ## Panics
73    ///
74    /// Can panic on errors.
75    fn mock_deserialize(mock_sdk: &MockDashPlatformSdk, buf: &[u8]) -> Self
76    where
77        Self: Sized;
78}
79
80impl<T: MockResponse> MockResponse for Option<T> {
81    fn mock_deserialize(mock_sdk: &MockDashPlatformSdk, buf: &[u8]) -> Self
82    where
83        Self: Sized,
84    {
85        if buf.is_empty() {
86            return None;
87        }
88
89        Some(T::mock_deserialize(mock_sdk, buf))
90    }
91    fn mock_serialize(&self, mock_sdk: &MockDashPlatformSdk) -> Vec<u8> {
92        match self {
93            Some(item) => item.mock_serialize(mock_sdk),
94            None => vec![],
95        }
96    }
97}
98
99impl<T: MockResponse> MockResponse for Vec<T> {
100    fn mock_deserialize(mock_sdk: &MockDashPlatformSdk, buf: &[u8]) -> Self
101    where
102        Self: Sized,
103    {
104        let items: Vec<Vec<u8>> = bincode::decode_from_slice(buf, BINCODE_CONFIG)
105            .expect("decode vec of data")
106            .0;
107        items
108            .into_iter()
109            .map(|item| T::mock_deserialize(mock_sdk, &item))
110            .collect()
111    }
112
113    fn mock_serialize(&self, mock_sdk: &MockDashPlatformSdk) -> Vec<u8> {
114        let data: Vec<Vec<u8>> = self
115            .iter()
116            .map(|item| item.mock_serialize(mock_sdk))
117            .collect();
118
119        bincode::encode_to_vec(data, BINCODE_CONFIG).expect("encode vec of data")
120    }
121}
122
123impl<K: Ord + MockResponse, V: MockResponse> MockResponse for BTreeMap<K, V> {
124    fn mock_deserialize(sdk: &MockDashPlatformSdk, buf: &[u8]) -> Self
125    where
126        Self: Sized,
127    {
128        let (data, _): (BTreeMap<Vec<u8>, Vec<u8>>, _) =
129            bincode::decode_from_slice(buf, BINCODE_CONFIG).expect("decode BTreeMap");
130
131        data.into_iter()
132            .map(|(k, v)| (K::mock_deserialize(sdk, &k), V::mock_deserialize(sdk, &v)))
133            .collect()
134    }
135
136    fn mock_serialize(&self, sdk: &MockDashPlatformSdk) -> Vec<u8> {
137        let data: BTreeMap<Vec<u8>, Vec<u8>> = self
138            .iter()
139            .map(|(k, v)| (k.mock_serialize(sdk), v.mock_serialize(sdk)))
140            .collect();
141
142        bincode::encode_to_vec(data, BINCODE_CONFIG).expect("encode BTreeMap")
143    }
144}
145
146impl<K: Hash + Eq + MockResponse, V: MockResponse> MockResponse for IndexMap<K, V> {
147    fn mock_deserialize(sdk: &MockDashPlatformSdk, buf: &[u8]) -> Self
148    where
149        Self: Sized,
150    {
151        let (data, _): (IndexMap<Vec<u8>, Vec<u8>>, _) =
152            bincode::serde::decode_from_slice(buf, BINCODE_CONFIG).expect("decode IndexMap");
153
154        data.into_iter()
155            .map(|(k, v)| (K::mock_deserialize(sdk, &k), V::mock_deserialize(sdk, &v)))
156            .collect()
157    }
158
159    fn mock_serialize(&self, sdk: &MockDashPlatformSdk) -> Vec<u8> {
160        let data: IndexMap<Vec<u8>, Vec<u8>> = self
161            .iter()
162            .map(|(k, v)| (k.mock_serialize(sdk), v.mock_serialize(sdk)))
163            .collect();
164
165        bincode::serde::encode_to_vec(data, BINCODE_CONFIG).expect("encode IndexMap")
166    }
167}
168
169/// Serialize and deserialize the object for mocking using bincode.
170///
171/// Use this macro when the object implements platform serialization.
172macro_rules! impl_mock_response {
173    ($name:ident) => {
174        impl MockResponse for $name {
175            fn mock_serialize(&self, sdk: &MockDashPlatformSdk) -> Vec<u8> {
176                platform_encode_to_vec(self, BINCODE_CONFIG, sdk.version())
177                    .expect(concat!("encode ", stringify!($name)))
178            }
179            fn mock_deserialize(sdk: &MockDashPlatformSdk, buf: &[u8]) -> Self
180            where
181                Self: Sized,
182            {
183                platform_versioned_decode_from_slice(buf, BINCODE_CONFIG, sdk.version())
184                    .expect(concat!("decode ", stringify!($name)))
185            }
186        }
187    };
188}
189
190// FIXME: Seems that DataContract doesn't implement PlatformVersionedDecode + PlatformVersionEncode,
191// so we just use some methods implemented directly on these objects.
192impl MockResponse for DataContract {
193    fn mock_serialize(&self, sdk: &MockDashPlatformSdk) -> Vec<u8> {
194        self.serialize_to_bytes_with_platform_version(sdk.version())
195            .expect("encode data")
196    }
197
198    fn mock_deserialize(sdk: &MockDashPlatformSdk, buf: &[u8]) -> Self
199    where
200        Self: Sized,
201    {
202        DataContract::versioned_deserialize_untrusted(buf, true, sdk.version())
203            .expect("decode data")
204    }
205}
206
207// FIXME: Seems that DataContract doesn't implement PlatformVersionedDecode + PlatformVersionEncode,
208// so we just use some methods implemented directly on these objects.
209impl MockResponse for (DataContract, Vec<u8>) {
210    fn mock_serialize(&self, _sdk: &MockDashPlatformSdk) -> Vec<u8> {
211        self.1.clone()
212    }
213
214    fn mock_deserialize(sdk: &MockDashPlatformSdk, buf: &[u8]) -> Self
215    where
216        Self: Sized,
217    {
218        (
219            DataContract::versioned_deserialize_untrusted(buf, true, sdk.version())
220                .expect("decode data"),
221            buf.to_vec(),
222        )
223    }
224}
225
226// FIXME: Seems that Document doesn't implement PlatformVersionedDecode + PlatformVersionEncode,
227// so we use cbor.
228impl MockResponse for Document {
229    fn mock_serialize(&self, _sdk: &MockDashPlatformSdk) -> Vec<u8> {
230        self.to_cbor().expect("encode data")
231    }
232
233    fn mock_deserialize(sdk: &MockDashPlatformSdk, buf: &[u8]) -> Self
234    where
235        Self: Sized,
236    {
237        Self::from_cbor(buf, None, None, sdk.version()).expect("decode data")
238    }
239}
240
241impl MockResponse for Element {
242    fn mock_serialize(&self, _sdk: &MockDashPlatformSdk) -> Vec<u8> {
243        // Create a bincode configuration
244        let config = standard();
245
246        // Serialize using the specified configuration
247        bincode::encode_to_vec(self, config).expect("Failed to serialize Element")
248    }
249
250    fn mock_deserialize(_sdk: &MockDashPlatformSdk, buf: &[u8]) -> Self
251    where
252        Self: Sized,
253    {
254        // Create a bincode configuration
255        let config = standard();
256
257        // Deserialize using the specified configuration
258        bincode::decode_from_slice(buf, config)
259            .expect("Failed to deserialize Element")
260            .0
261    }
262}
263
264impl MockResponse for drive_proof_verifier::types::IdentityNonceFetcher {
265    fn mock_serialize(&self, _sdk: &MockDashPlatformSdk) -> Vec<u8> {
266        self.0.to_be_bytes().to_vec()
267    }
268
269    fn mock_deserialize(_sdk: &MockDashPlatformSdk, buf: &[u8]) -> Self
270    where
271        Self: Sized,
272    {
273        drive_proof_verifier::types::IdentityNonceFetcher(u64::from_be_bytes(
274            buf.try_into()
275                .expect("identity contract nonce should be should be 8 bytes"),
276        ))
277    }
278}
279
280impl MockResponse for drive_proof_verifier::types::IdentityContractNonceFetcher {
281    fn mock_serialize(&self, _sdk: &MockDashPlatformSdk) -> Vec<u8> {
282        self.0.to_be_bytes().to_vec()
283    }
284
285    fn mock_deserialize(_sdk: &MockDashPlatformSdk, buf: &[u8]) -> Self
286    where
287        Self: Sized,
288    {
289        drive_proof_verifier::types::IdentityContractNonceFetcher(u64::from_be_bytes(
290            buf.try_into()
291                .expect("identity contract nonce should be should be 8 bytes"),
292        ))
293    }
294}
295impl MockResponse for ProTxHash {
296    fn mock_serialize(&self, sdk: &MockDashPlatformSdk) -> Vec<u8> {
297        let data = self.as_raw_hash().as_byte_array();
298        platform_encode_to_vec(data, BINCODE_CONFIG, sdk.version()).expect("encode ProTxHash")
299    }
300    fn mock_deserialize(sdk: &MockDashPlatformSdk, buf: &[u8]) -> Self
301    where
302        Self: Sized,
303    {
304        let data = platform_versioned_decode_from_slice(buf, BINCODE_CONFIG, sdk.version())
305            .expect("decode ProTxHash");
306        ProTxHash::from_raw_hash(CoreHash::from_byte_array(data))
307    }
308}
309
310impl MockResponse for ProposerBlockCounts {
311    fn mock_serialize(&self, sdk: &MockDashPlatformSdk) -> Vec<u8> {
312        self.0.mock_serialize(sdk)
313    }
314
315    fn mock_deserialize(sdk: &MockDashPlatformSdk, buf: &[u8]) -> Self
316    where
317        Self: Sized,
318    {
319        let data = RetrievedValues::<Identifier, u64>::mock_deserialize(sdk, buf);
320        ProposerBlockCounts(data)
321    }
322}
323
324impl MockResponse for DataContractsByRange {
325    fn mock_serialize(&self, sdk: &MockDashPlatformSdk) -> Vec<u8> {
326        self.0.mock_serialize(sdk)
327    }
328
329    fn mock_deserialize(sdk: &MockDashPlatformSdk, buf: &[u8]) -> Self
330    where
331        Self: Sized,
332    {
333        DataContractsByRange(
334            IndexMap::<Identifier, Option<DataContract>>::mock_deserialize(sdk, buf),
335        )
336    }
337}
338
339/// Four big-endian version bytes followed by the optional contract (empty when absent).
340impl MockResponse for DataContractLatestVersion {
341    fn mock_serialize(&self, sdk: &MockDashPlatformSdk) -> Vec<u8> {
342        let mut buf = self.version.to_be_bytes().to_vec();
343        buf.extend(self.data_contract.mock_serialize(sdk));
344        buf
345    }
346
347    fn mock_deserialize(sdk: &MockDashPlatformSdk, buf: &[u8]) -> Self
348    where
349        Self: Sized,
350    {
351        let (version, data_contract) = buf.split_at(4);
352        DataContractLatestVersion {
353            version: u32::from_be_bytes(version.try_into().expect("4 byte version prefix")),
354            data_contract: Option::<DataContract>::mock_deserialize(sdk, data_contract),
355        }
356    }
357}
358
359impl MockResponse for DataContractsLatestVersions {
360    fn mock_serialize(&self, sdk: &MockDashPlatformSdk) -> Vec<u8> {
361        self.0.mock_serialize(sdk)
362    }
363
364    fn mock_deserialize(sdk: &MockDashPlatformSdk, buf: &[u8]) -> Self
365    where
366        Self: Sized,
367    {
368        DataContractsLatestVersions(
369            IndexMap::<Identifier, Option<DataContractLatestVersion>>::mock_deserialize(sdk, buf),
370        )
371    }
372}
373
374impl MockResponse for ContractGroupInfo {
375    fn mock_serialize(&self, _sdk: &MockDashPlatformSdk) -> Vec<u8> {
376        bincode::encode_to_vec(self, BINCODE_CONFIG).expect("encode ContractGroupInfo")
377    }
378
379    fn mock_deserialize(_sdk: &MockDashPlatformSdk, buf: &[u8]) -> Self
380    where
381        Self: Sized,
382    {
383        bincode::decode_from_slice(buf, BINCODE_CONFIG)
384            .expect("decode ContractGroupInfo")
385            .0
386    }
387}
388
389/// One byte for the kind (0 contracts, 1 document types, 2 tokens) followed by the bincode
390/// entries of that kind.
391impl MockResponse for ContractGroupMembersPage {
392    fn mock_serialize(&self, _sdk: &MockDashPlatformSdk) -> Vec<u8> {
393        let (kind, entries) = match self {
394            ContractGroupMembersPage::Contracts(entries) => (
395                0u8,
396                bincode::encode_to_vec(entries, BINCODE_CONFIG).expect("encode member contracts"),
397            ),
398            ContractGroupMembersPage::DocumentTypes(entries) => (
399                1u8,
400                bincode::encode_to_vec(entries, BINCODE_CONFIG)
401                    .expect("encode member document types"),
402            ),
403            ContractGroupMembersPage::Tokens(entries) => (
404                2u8,
405                bincode::encode_to_vec(entries, BINCODE_CONFIG).expect("encode member tokens"),
406            ),
407        };
408        let mut buf = vec![kind];
409        buf.extend(entries);
410        buf
411    }
412
413    fn mock_deserialize(_sdk: &MockDashPlatformSdk, buf: &[u8]) -> Self
414    where
415        Self: Sized,
416    {
417        let (kind, entries) = buf.split_first().expect("members page kind byte");
418        match kind {
419            0 => ContractGroupMembersPage::Contracts(
420                bincode::decode_from_slice(entries, BINCODE_CONFIG)
421                    .expect("decode member contracts")
422                    .0,
423            ),
424            1 => ContractGroupMembersPage::DocumentTypes(
425                bincode::decode_from_slice(entries, BINCODE_CONFIG)
426                    .expect("decode member document types")
427                    .0,
428            ),
429            2 => ContractGroupMembersPage::Tokens(
430                bincode::decode_from_slice(entries, BINCODE_CONFIG)
431                    .expect("decode member tokens")
432                    .0,
433            ),
434            other => panic!("unknown members page kind {other}"),
435        }
436    }
437}
438
439/// The three membership maps, bincode encoded as a tuple.
440impl MockResponse for ContractGroupMembershipsForContract {
441    fn mock_serialize(&self, _sdk: &MockDashPlatformSdk) -> Vec<u8> {
442        bincode::encode_to_vec(
443            (&self.contract, &self.document_types, &self.tokens),
444            BINCODE_CONFIG,
445        )
446        .expect("encode ContractGroupMembershipsForContract")
447    }
448
449    fn mock_deserialize(_sdk: &MockDashPlatformSdk, buf: &[u8]) -> Self
450    where
451        Self: Sized,
452    {
453        let (contract, document_types, tokens) = bincode::decode_from_slice(buf, BINCODE_CONFIG)
454            .expect("decode ContractGroupMembershipsForContract")
455            .0;
456        ContractGroupMembershipsForContract {
457            contract,
458            document_types,
459            tokens,
460        }
461    }
462}
463
464impl MockResponse for IdentityKeysRemainingBudgets {
465    fn mock_serialize(&self, sdk: &MockDashPlatformSdk) -> Vec<u8> {
466        self.0.mock_serialize(sdk)
467    }
468
469    fn mock_deserialize(sdk: &MockDashPlatformSdk, buf: &[u8]) -> Self
470    where
471        Self: Sized,
472    {
473        let map = RetrievedValues::mock_deserialize(sdk, buf);
474        Self(map)
475    }
476}
477
478impl MockResponse for IdentityTokenBalances {
479    fn mock_serialize(&self, sdk: &MockDashPlatformSdk) -> Vec<u8> {
480        self.0.mock_serialize(sdk)
481    }
482
483    fn mock_deserialize(sdk: &MockDashPlatformSdk, buf: &[u8]) -> Self
484    where
485        Self: Sized,
486    {
487        let map = RetrievedValues::mock_deserialize(sdk, buf);
488        Self(map)
489    }
490}
491
492impl MockResponse for IdentitiesTokenBalances {
493    fn mock_serialize(&self, sdk: &MockDashPlatformSdk) -> Vec<u8> {
494        self.0.mock_serialize(sdk)
495    }
496
497    fn mock_deserialize(sdk: &MockDashPlatformSdk, buf: &[u8]) -> Self
498    where
499        Self: Sized,
500    {
501        let map = RetrievedValues::mock_deserialize(sdk, buf);
502        Self(map)
503    }
504}
505
506impl MockResponse for IdentityTokenInfos {
507    fn mock_serialize(&self, sdk: &MockDashPlatformSdk) -> Vec<u8> {
508        // Clone and collect into vector
509        let vec: Vec<(Identifier, Option<IdentityTokenInfo>)> =
510            self.0.iter().map(|(k, v)| (*k, v.clone())).collect();
511
512        // Serialize vector
513        platform_encode_to_vec(vec, BINCODE_CONFIG, sdk.version())
514            .expect(concat!("encode ", stringify!($name)))
515    }
516
517    fn mock_deserialize(sdk: &MockDashPlatformSdk, buf: &[u8]) -> Self
518    where
519        Self: Sized,
520    {
521        // deserialize vector
522        let vec: Vec<(Identifier, Option<IdentityTokenInfo>)> =
523            platform_versioned_decode_from_slice(buf, BINCODE_CONFIG, sdk.version())
524                .expect(concat!("decode ", stringify!($name)));
525
526        Self(RetrievedValues::from_iter(vec))
527    }
528}
529
530impl MockResponse for IdentitiesTokenInfos {
531    fn mock_serialize(&self, sdk: &MockDashPlatformSdk) -> Vec<u8> {
532        // Clone and collect into vector
533        let vec: Vec<(Identifier, Option<IdentityTokenInfo>)> =
534            self.0.iter().map(|(k, v)| (*k, v.clone())).collect();
535
536        // Serialize vector
537        platform_encode_to_vec(vec, BINCODE_CONFIG, sdk.version())
538            .expect(concat!("encode ", stringify!($name)))
539    }
540
541    fn mock_deserialize(sdk: &MockDashPlatformSdk, buf: &[u8]) -> Self
542    where
543        Self: Sized,
544    {
545        // deserialize vector
546        let vec: Vec<(Identifier, Option<IdentityTokenInfo>)> =
547            platform_versioned_decode_from_slice(buf, BINCODE_CONFIG, sdk.version())
548                .expect(concat!("decode ", stringify!($name)));
549
550        Self(RetrievedValues::from_iter(vec))
551    }
552}
553
554impl MockResponse for TokenStatuses {
555    fn mock_serialize(&self, sdk: &MockDashPlatformSdk) -> Vec<u8> {
556        // Clone and collect into vector
557        let vec: Vec<(Identifier, Option<TokenStatus>)> =
558            self.iter().map(|(k, v)| (*k, v.clone())).collect();
559
560        // Serialize vector
561        platform_encode_to_vec(vec, BINCODE_CONFIG, sdk.version())
562            .expect(concat!("encode ", stringify!($name)))
563    }
564
565    fn mock_deserialize(sdk: &MockDashPlatformSdk, buf: &[u8]) -> Self
566    where
567        Self: Sized,
568    {
569        // deserialize vector
570        let vec: Vec<(Identifier, Option<TokenStatus>)> =
571            platform_versioned_decode_from_slice(buf, BINCODE_CONFIG, sdk.version())
572                .expect(concat!("decode ", stringify!($name)));
573
574        RetrievedValues::from_iter(vec)
575    }
576}
577
578impl MockResponse for TokenContractInfo {
579    fn mock_serialize(&self, sdk: &MockDashPlatformSdk) -> Vec<u8> {
580        platform_encode_to_vec(self, BINCODE_CONFIG, sdk.version())
581            .expect("encode TokenContractInfo")
582    }
583
584    fn mock_deserialize(sdk: &MockDashPlatformSdk, buf: &[u8]) -> Self
585    where
586        Self: Sized,
587    {
588        platform_versioned_decode_from_slice(buf, BINCODE_CONFIG, sdk.version())
589            .expect("decode TokenContractInfo")
590    }
591}
592
593impl MockResponse for TotalSingleTokenBalance {
594    fn mock_serialize(&self, _sdk: &MockDashPlatformSdk) -> Vec<u8> {
595        bincode::encode_to_vec(self, BINCODE_CONFIG).expect("encode vec of data")
596    }
597
598    fn mock_deserialize(_sdk: &MockDashPlatformSdk, buf: &[u8]) -> Self
599    where
600        Self: Sized,
601    {
602        bincode::decode_from_slice(buf, BINCODE_CONFIG)
603            .expect("decode vec of data")
604            .0
605    }
606}
607
608impl MockResponse for GroupActions {
609    fn mock_serialize(&self, sdk: &MockDashPlatformSdk) -> Vec<u8> {
610        // Clone and collect into vector
611        let vec: Vec<(Identifier, Option<GroupAction>)> =
612            self.iter().map(|(k, v)| (*k, v.clone())).collect();
613
614        // Serialize vector
615        platform_encode_to_vec(vec, BINCODE_CONFIG, sdk.version())
616            .expect(concat!("encode ", stringify!($name)))
617    }
618
619    fn mock_deserialize(sdk: &MockDashPlatformSdk, buf: &[u8]) -> Self
620    where
621        Self: Sized,
622    {
623        // deserialize vector
624        let vec: Vec<(Identifier, Option<GroupAction>)> =
625            platform_versioned_decode_from_slice(buf, BINCODE_CONFIG, sdk.version())
626                .expect(concat!("decode ", stringify!($name)));
627
628        RetrievedValues::from_iter(vec)
629    }
630}
631
632impl MockResponse for IdentitiesContractKeys {
633    fn mock_serialize(&self, _sdk: &MockDashPlatformSdk) -> Vec<u8> {
634        bincode::encode_to_vec(self, BINCODE_CONFIG).expect("encode IdentitiesContractKeys")
635    }
636
637    fn mock_deserialize(_sdk: &MockDashPlatformSdk, buf: &[u8]) -> Self
638    where
639        Self: Sized,
640    {
641        bincode::decode_from_slice(buf, BINCODE_CONFIG)
642            .expect("decode IdentitiesContractKeys")
643            .0
644    }
645}
646
647impl_mock_response!(Identity);
648impl_mock_response!(IdentityPublicKey);
649impl_mock_response!(Identifier);
650impl_mock_response!(MasternodeProtocolVote);
651impl_mock_response!(ResourceVote);
652impl_mock_response!(u8);
653impl_mock_response!(u16);
654impl_mock_response!(u32);
655impl_mock_response!(u64);
656impl_mock_response!(Vote);
657impl_mock_response!(ExtendedEpochInfo);
658impl_mock_response!(FinalizedEpochInfo);
659impl_mock_response!(ContestedResources);
660impl_mock_response!(IdentityBalanceAndRevision);
661impl_mock_response!(Contenders);
662impl_mock_response!(Voters);
663impl_mock_response!(VotePollsGroupedByTimestamp);
664impl_mock_response!(PrefundedSpecializedBalance);
665impl_mock_response!(TotalCreditsInPlatform);
666impl_mock_response!(ElementFetchRequestItem);
667impl_mock_response!(EvoNodeStatus);
668impl_mock_response!(CurrentQuorumsInfo);
669impl_mock_response!(Group);
670impl_mock_response!(TokenPricingSchedule);
671impl_mock_response!(RewardDistributionMoment);
672impl_mock_response!(TokenPreProgrammedDistributions);
673impl_mock_response!(PlatformAddress);
674impl_mock_response!(AddressInfo);
675impl_mock_response!(RecentAddressBalanceChanges);
676impl_mock_response!(RecentCompactedAddressBalanceChanges);
677impl_mock_response!(ShieldedPoolState);
678impl_mock_response!(ShieldedNotesCount);
679impl_mock_response!(ShieldedAnchors);
680impl_mock_response!(MostRecentShieldedAnchor);
681impl_mock_response!(ShieldedEncryptedNotes);
682impl_mock_response!(ShieldedEncryptedNote);
683impl_mock_response!(ShieldedNullifierStatuses);
684impl_mock_response!(ShieldedNullifierStatus);
685
686/// MockResponse for GroveTrunkQueryResult - panics when called because the Tree type
687/// doesn't support serialization. Address sync operations should not be mocked.
688impl MockResponse for GroveTrunkQueryResult {
689    fn mock_serialize(&self, _sdk: &MockDashPlatformSdk) -> Vec<u8> {
690        unimplemented!("GroveTrunkQueryResult does not support mock serialization - the Tree type is not serializable")
691    }
692
693    fn mock_deserialize(_sdk: &MockDashPlatformSdk, _buf: &[u8]) -> Self
694    where
695        Self: Sized,
696    {
697        unimplemented!("GroveTrunkQueryResult does not support mock deserialization - the Tree type is not serializable")
698    }
699}
700
701/// MockResponse for PlatformAddressTrunkState - panics when called because the underlying
702/// Tree type doesn't support serialization. Address sync operations should not be mocked.
703impl MockResponse for PlatformAddressTrunkState {
704    fn mock_serialize(&self, _sdk: &MockDashPlatformSdk) -> Vec<u8> {
705        unimplemented!("PlatformAddressTrunkState does not support mock serialization - the Tree type is not serializable")
706    }
707
708    fn mock_deserialize(_sdk: &MockDashPlatformSdk, _buf: &[u8]) -> Self
709    where
710        Self: Sized,
711    {
712        unimplemented!("PlatformAddressTrunkState does not support mock deserialization - the Tree type is not serializable")
713    }
714}
715
716impl MockResponse for drive_proof_verifier::DocumentCount {
717    fn mock_serialize(&self, _sdk: &MockDashPlatformSdk) -> Vec<u8> {
718        let bincode_config = standard();
719        bincode::encode_to_vec(self.0, bincode_config).expect("encode DocumentCount")
720    }
721
722    fn mock_deserialize(_sdk: &MockDashPlatformSdk, buf: &[u8]) -> Self
723    where
724        Self: Sized,
725    {
726        let bincode_config = standard();
727        let (count, _): (u64, _) =
728            bincode::decode_from_slice(buf, bincode_config).expect("decode DocumentCount");
729        drive_proof_verifier::DocumentCount(count)
730    }
731}
732
733/// Wire shape for `DocumentSplitCounts` mock round-trip:
734/// `(in_key, key, count)` triples preserving the In dimension
735/// AND the verified-vs-absent count distinction. Shared by
736/// `mock_serialize`/`mock_deserialize` below — single source of
737/// truth so the encode/decode generics align by construction,
738/// and clippy's `type_complexity` lint (CI runs with
739/// `-D warnings`) doesn't fire on the inline form.
740type DocumentSplitCountTriples = Vec<(Option<Vec<u8>>, Vec<u8>, Option<u64>)>;
741
742impl MockResponse for drive_proof_verifier::DocumentSplitCounts {
743    fn mock_serialize(&self, _sdk: &MockDashPlatformSdk) -> Vec<u8> {
744        let bincode_config = standard();
745        // Serialize as `(in_key, key, count)` triples so the In
746        // dimension AND the verified-vs-absent count distinction
747        // both survive the mock roundtrip. Required for compound
748        // (`In + range + distinct`) test fixtures to keep their
749        // `in_key` values, and for GroupByIn-absent-branch
750        // fixtures to keep their `None` counts.
751        let triples: DocumentSplitCountTriples = self
752            .0
753            .iter()
754            .map(|e| (e.in_key.clone(), e.key.clone(), e.count))
755            .collect();
756        bincode::encode_to_vec(triples, bincode_config).expect("encode DocumentSplitCounts")
757    }
758
759    fn mock_deserialize(_sdk: &MockDashPlatformSdk, buf: &[u8]) -> Self
760    where
761        Self: Sized,
762    {
763        let bincode_config = standard();
764        let (triples, _): (DocumentSplitCountTriples, _) =
765            bincode::decode_from_slice(buf, bincode_config).expect("decode DocumentSplitCounts");
766        let entries: Vec<drive_proof_verifier::SplitCountEntry> = triples
767            .into_iter()
768            .map(
769                |(in_key, key, count)| drive_proof_verifier::SplitCountEntry { in_key, key, count },
770            )
771            .collect();
772        drive_proof_verifier::DocumentSplitCounts::from_verified(entries)
773    }
774}
775
776impl MockResponse for drive_proof_verifier::DocumentSum {
777    fn mock_serialize(&self, _sdk: &MockDashPlatformSdk) -> Vec<u8> {
778        let bincode_config = standard();
779        bincode::encode_to_vec(self.0, bincode_config).expect("encode DocumentSum")
780    }
781
782    fn mock_deserialize(_sdk: &MockDashPlatformSdk, buf: &[u8]) -> Self
783    where
784        Self: Sized,
785    {
786        let bincode_config = standard();
787        let (sum, _): (i64, _) =
788            bincode::decode_from_slice(buf, bincode_config).expect("decode DocumentSum");
789        drive_proof_verifier::DocumentSum(sum)
790    }
791}
792
793/// Wire shape for `DocumentSplitSums` mock round-trip. Mirrors
794/// [`DocumentSplitCountTriples`] — preserves the `in_key` axis
795/// and the verified-vs-absent sum distinction (`Option<i64>`)
796/// across the roundtrip.
797type DocumentSplitSumTriples = Vec<(Option<Vec<u8>>, Vec<u8>, Option<i64>)>;
798
799impl MockResponse for drive_proof_verifier::DocumentSplitSums {
800    fn mock_serialize(&self, _sdk: &MockDashPlatformSdk) -> Vec<u8> {
801        let bincode_config = standard();
802        let triples: DocumentSplitSumTriples = self
803            .0
804            .iter()
805            .map(|e| (e.in_key.clone(), e.key.clone(), e.sum))
806            .collect();
807        bincode::encode_to_vec(triples, bincode_config).expect("encode DocumentSplitSums")
808    }
809
810    fn mock_deserialize(_sdk: &MockDashPlatformSdk, buf: &[u8]) -> Self
811    where
812        Self: Sized,
813    {
814        let bincode_config = standard();
815        let (triples, _): (DocumentSplitSumTriples, _) =
816            bincode::decode_from_slice(buf, bincode_config).expect("decode DocumentSplitSums");
817        let entries: Vec<drive_proof_verifier::SplitSumEntry> = triples
818            .into_iter()
819            .map(|(in_key, key, sum)| drive_proof_verifier::SplitSumEntry { in_key, key, sum })
820            .collect();
821        drive_proof_verifier::DocumentSplitSums(entries)
822    }
823}
824
825impl MockResponse for drive_proof_verifier::DocumentAverage {
826    fn mock_serialize(&self, _sdk: &MockDashPlatformSdk) -> Vec<u8> {
827        let bincode_config = standard();
828        bincode::encode_to_vec((self.count, self.sum), bincode_config)
829            .expect("encode DocumentAverage")
830    }
831
832    fn mock_deserialize(_sdk: &MockDashPlatformSdk, buf: &[u8]) -> Self
833    where
834        Self: Sized,
835    {
836        let bincode_config = standard();
837        let ((count, sum), _): ((u64, i64), _) =
838            bincode::decode_from_slice(buf, bincode_config).expect("decode DocumentAverage");
839        drive_proof_verifier::DocumentAverage { count, sum }
840    }
841}
842
843/// Wire shape for `DocumentSplitAverages` mock round-trip. Same
844/// `(in_key, key)` axes as the sum variant, but carries both
845/// `Option<u64>` (count) and `Option<i64>` (sum) so the verified-vs-
846/// absent state of each axis can roundtrip independently.
847type DocumentSplitAverageTuples = Vec<(Option<Vec<u8>>, Vec<u8>, Option<u64>, Option<i64>)>;
848
849impl MockResponse for drive_proof_verifier::DocumentSplitAverages {
850    fn mock_serialize(&self, _sdk: &MockDashPlatformSdk) -> Vec<u8> {
851        let bincode_config = standard();
852        let tuples: DocumentSplitAverageTuples = self
853            .0
854            .iter()
855            .map(|e| (e.in_key.clone(), e.key.clone(), e.count, e.sum))
856            .collect();
857        bincode::encode_to_vec(tuples, bincode_config).expect("encode DocumentSplitAverages")
858    }
859
860    fn mock_deserialize(_sdk: &MockDashPlatformSdk, buf: &[u8]) -> Self
861    where
862        Self: Sized,
863    {
864        let bincode_config = standard();
865        let (tuples, _): (DocumentSplitAverageTuples, _) =
866            bincode::decode_from_slice(buf, bincode_config).expect("decode DocumentSplitAverages");
867        let entries: Vec<drive_proof_verifier::SplitAverageEntry> = tuples
868            .into_iter()
869            .map(
870                |(in_key, key, count, sum)| drive_proof_verifier::SplitAverageEntry {
871                    in_key,
872                    key,
873                    count,
874                    sum,
875                },
876            )
877            .collect();
878        drive_proof_verifier::DocumentSplitAverages(entries)
879    }
880}
881
882/// Wire shape for `DocumentRankedEntries` mock round-trip: the page's
883/// `starting_rank`, then `(group key, axis tag, value)` triples in list
884/// order — **order is the ranking**, so a map-shaped encoding (as used
885/// nowhere here, but as would be the obvious alternative) would destroy
886/// the answer.
887///
888/// `starting_rank` is part of the encoding rather than reconstructed as
889/// `0` on decode, because it is exactly what an offset test needs to
890/// assert: a mock that dropped it would make every expectation look
891/// like an offset-0 query and quietly pass a round-trip that lost the
892/// rank base.
893///
894/// The value is widened to `i128` across all three axes: `Count`
895/// (`u64`) and `Sum` (`i64`) both fit losslessly, and `AvgFixedPoint`
896/// is already an `i128`. One numeric column keeps the tuple flat while
897/// the tag preserves which axis produced it, so a mock expectation
898/// can't quietly turn a count into a sum.
899/// One mock-serialized ranked entry: `(key, axis tag, value, in_key)`.
900type MockRankedEntry = (Vec<u8>, u8, i128, Option<Vec<u8>>);
901type DocumentRankedPage = (u64, Vec<MockRankedEntry>);
902
903const RANKED_TAG_COUNT: u8 = 0;
904const RANKED_TAG_SUM: u8 = 1;
905const RANKED_TAG_AVG: u8 = 2;
906
907impl MockResponse for drive_proof_verifier::DocumentRankedEntries {
908    fn mock_serialize(&self, _sdk: &MockDashPlatformSdk) -> Vec<u8> {
909        let bincode_config = standard();
910        let triples: Vec<MockRankedEntry> = self
911            .entries
912            .iter()
913            .map(|e| match e.value {
914                drive_proof_verifier::RankedEntryValue::Count(count) => (
915                    e.key.clone(),
916                    RANKED_TAG_COUNT,
917                    count as i128,
918                    e.in_key.clone(),
919                ),
920                drive_proof_verifier::RankedEntryValue::Sum(sum) => {
921                    (e.key.clone(), RANKED_TAG_SUM, sum as i128, e.in_key.clone())
922                }
923                drive_proof_verifier::RankedEntryValue::AvgFixedPoint(avg) => {
924                    (e.key.clone(), RANKED_TAG_AVG, avg, e.in_key.clone())
925                }
926            })
927            .collect();
928        let page: DocumentRankedPage = (self.starting_rank, triples);
929        bincode::encode_to_vec(page, bincode_config).expect("encode DocumentRankedEntries")
930    }
931
932    fn mock_deserialize(_sdk: &MockDashPlatformSdk, buf: &[u8]) -> Self
933    where
934        Self: Sized,
935    {
936        let bincode_config = standard();
937        let ((starting_rank, triples), _): (DocumentRankedPage, _) =
938            bincode::decode_from_slice(buf, bincode_config).expect("decode DocumentRankedEntries");
939        let entries: Vec<drive_proof_verifier::RankedEntry> = triples
940            .into_iter()
941            .map(|(key, tag, value, in_key)| {
942                let value = match tag {
943                    RANKED_TAG_COUNT => drive_proof_verifier::RankedEntryValue::Count(
944                        u64::try_from(value).expect("a Count entry round-trips through i128"),
945                    ),
946                    RANKED_TAG_SUM => drive_proof_verifier::RankedEntryValue::Sum(
947                        i64::try_from(value).expect("a Sum entry round-trips through i128"),
948                    ),
949                    RANKED_TAG_AVG => drive_proof_verifier::RankedEntryValue::AvgFixedPoint(value),
950                    other => panic!("unknown ranked axis tag {other} in mock expectation"),
951                };
952                drive_proof_verifier::RankedEntry { in_key, key, value }
953            })
954            .collect();
955        drive_proof_verifier::DocumentRankedEntries {
956            starting_rank,
957            entries,
958        }
959    }
960}
961
962impl MockResponse for drive_proof_verifier::DocumentHavingEntries {
963    /// Rides the ranked page encoding with a starting rank of `0`: a
964    /// having page is the same ordered `(group key, axis tag, value)`
965    /// list, just addressed by value bound instead of by rank, and it
966    /// has no rank base to preserve.
967    fn mock_serialize(&self, sdk: &MockDashPlatformSdk) -> Vec<u8> {
968        drive_proof_verifier::DocumentRankedEntries {
969            starting_rank: 0,
970            entries: self.entries.clone(),
971        }
972        .mock_serialize(sdk)
973    }
974
975    fn mock_deserialize(sdk: &MockDashPlatformSdk, buf: &[u8]) -> Self
976    where
977        Self: Sized,
978    {
979        let page = drive_proof_verifier::DocumentRankedEntries::mock_deserialize(sdk, buf);
980        drive_proof_verifier::DocumentHavingEntries {
981            entries: page.entries,
982        }
983    }
984}
985
986/// Wire shape for `ChainedDocuments` mock round-trip: both halves as
987/// per-document CBOR lists.
988type MockChainedHalves = (Vec<Vec<u8>>, Vec<Vec<u8>>);
989
990impl MockResponse for drive_proof_verifier::ChainedDocuments {
991    /// Both halves as per-document CBOR, bincode-framed as
992    /// `(inner, outer)` — list order IS the answer (inner-proof order,
993    /// outer by first appearance), so a map-shaped encoding would
994    /// destroy it.
995    fn mock_serialize(&self, _sdk: &MockDashPlatformSdk) -> Vec<u8> {
996        let bincode_config = standard();
997        let halves: MockChainedHalves = (
998            self.inner_documents
999                .iter()
1000                .map(|d| d.to_cbor().expect("encode inner document"))
1001                .collect(),
1002            self.outer_documents
1003                .iter()
1004                .map(|d| d.to_cbor().expect("encode outer document"))
1005                .collect(),
1006        );
1007        bincode::encode_to_vec(halves, bincode_config).expect("encode ChainedDocuments")
1008    }
1009
1010    fn mock_deserialize(sdk: &MockDashPlatformSdk, buf: &[u8]) -> Self
1011    where
1012        Self: Sized,
1013    {
1014        let bincode_config = standard();
1015        let ((inner, outer), _): (MockChainedHalves, _) =
1016            bincode::decode_from_slice(buf, bincode_config).expect("decode ChainedDocuments");
1017        let decode = |bufs: Vec<Vec<u8>>| {
1018            bufs.into_iter()
1019                .map(|b| {
1020                    Document::from_cbor(&b, None, None, sdk.version()).expect("decode document")
1021                })
1022                .collect()
1023        };
1024        drive_proof_verifier::ChainedDocuments {
1025            inner_documents: decode(inner),
1026            outer_documents: decode(outer),
1027        }
1028    }
1029}
1030
1031/// Wire shape for one `CompositeDocuments` sub-result mock round-trip:
1032/// `(is_documents, documents, count triples)`, only one side populated.
1033type MockCompositeSubResult = (bool, Vec<Vec<u8>>, DocumentSplitCountTriples);
1034
1035/// Wire shape for `CompositeDocuments` mock round-trip: the page as a
1036/// per-document CBOR list, then one entry per sub-query.
1037type MockCompositeShape = (Vec<Vec<u8>>, Vec<MockCompositeSubResult>);
1038
1039impl MockResponse for drive_proof_verifier::CompositeDocuments {
1040    /// The page and every documents sub-result as per-document CBOR,
1041    /// count sub-results as `(in_key, key, count)` triples, all
1042    /// bincode-framed in request order — list order IS the answer
1043    /// (page order, a join's first-appearance order), so a map-shaped
1044    /// encoding would destroy it.
1045    fn mock_serialize(&self, _sdk: &MockDashPlatformSdk) -> Vec<u8> {
1046        let bincode_config = standard();
1047        let encode = |documents: &[Document]| -> Vec<Vec<u8>> {
1048            documents
1049                .iter()
1050                .map(|d| d.to_cbor().expect("encode document"))
1051                .collect()
1052        };
1053        let shape: MockCompositeShape = (
1054            encode(&self.page_documents),
1055            self.sub_results
1056                .iter()
1057                .map(|result| match result {
1058                    drive_proof_verifier::CompositeSubQueryResult::Documents(documents) => {
1059                        (true, encode(documents), Vec::new())
1060                    }
1061                    drive_proof_verifier::CompositeSubQueryResult::Counts(entries) => (
1062                        false,
1063                        Vec::new(),
1064                        entries
1065                            .iter()
1066                            .map(|e| (e.in_key.clone(), e.key.clone(), e.count))
1067                            .collect(),
1068                    ),
1069                })
1070                .collect(),
1071        );
1072        bincode::encode_to_vec(shape, bincode_config).expect("encode CompositeDocuments")
1073    }
1074
1075    fn mock_deserialize(sdk: &MockDashPlatformSdk, buf: &[u8]) -> Self
1076    where
1077        Self: Sized,
1078    {
1079        let bincode_config = standard();
1080        let ((page, sub_results), _): (MockCompositeShape, _) =
1081            bincode::decode_from_slice(buf, bincode_config).expect("decode CompositeDocuments");
1082        let decode = |bufs: Vec<Vec<u8>>| -> Vec<Document> {
1083            bufs.into_iter()
1084                .map(|b| {
1085                    Document::from_cbor(&b, None, None, sdk.version()).expect("decode document")
1086                })
1087                .collect()
1088        };
1089        drive_proof_verifier::CompositeDocuments {
1090            page_documents: decode(page),
1091            sub_results: sub_results
1092                .into_iter()
1093                .map(|(is_documents, documents, triples)| {
1094                    if is_documents {
1095                        drive_proof_verifier::CompositeSubQueryResult::Documents(decode(documents))
1096                    } else {
1097                        drive_proof_verifier::CompositeSubQueryResult::Counts(
1098                            triples
1099                                .into_iter()
1100                                .map(
1101                                    |(in_key, key, count)| drive_proof_verifier::SplitCountEntry {
1102                                        in_key,
1103                                        key,
1104                                        count,
1105                                    },
1106                                )
1107                                .collect(),
1108                        )
1109                    }
1110                })
1111                .collect(),
1112        }
1113    }
1114}