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_moderation::{
30    ContractDocumentRemoval, ContractDocumentRemovalEntry, ContractDocumentRemovals,
31    ContractDocumentRestoration, ContractFeePotLastClaim, ContractFeePotState, ContractFeePots, ContractModerationActionCounts, ContractModerationEntries,
32    ContractModerationEntry, ContractModerationListStatus,
33    ContractModerationListStatuses, ContractModerationReason, ContractTeamAction,
34    ContractTeamActionEntry, ContractTeamActionSigners, ContractTeamActions, ContractWarning,
35};
36use drive_proof_verifier::types::contract_groups::{
37    ContractGroupInfo, ContractGroupMembersPage, ContractGroupMembershipsForContract,
38};
39use drive_proof_verifier::types::data_contracts_latest_versions::{
40    DataContractLatestVersion, DataContractsLatestVersions,
41};
42use drive_proof_verifier::types::data_contracts_by_range::DataContractsByRange;
43use drive_proof_verifier::types::evonode_status::EvoNodeStatus;
44use drive_proof_verifier::types::groups::GroupActions;
45use drive_proof_verifier::types::identity_token_balance::{
46    IdentitiesTokenBalances, IdentityTokenBalances,
47};
48use drive_proof_verifier::types::token_info::{IdentitiesTokenInfos, IdentityTokenInfos};
49use drive_proof_verifier::types::token_status::TokenStatuses;
50use drive::grovedb::GroveTrunkQueryResult;
51use drive_proof_verifier::types::{
52    AddressInfo, Contenders, ContestedResources, CurrentQuorumsInfo, ElementFetchRequestItem,
53    IdentityBalanceAndRevision, IndexMap, MasternodeProtocolVote, MostRecentShieldedAnchor,
54    PlatformAddressTrunkState, PrefundedSpecializedBalance, ProposerBlockCounts,
55    RecentAddressBalanceChanges, RecentCompactedAddressBalanceChanges, RetrievedValues,
56    ShieldedAnchors, ShieldedEncryptedNote, ShieldedEncryptedNotes, ShieldedNotesCount,
57    ShieldedNullifierStatus, ShieldedNullifierStatuses, ShieldedPoolState,
58    TokenPreProgrammedDistributions, TotalCreditsInPlatform, VotePollsGroupedByTimestamp, Voters,
59};
60use std::{collections::BTreeMap, hash::Hash};
61
62static BINCODE_CONFIG: bincode::config::Configuration = bincode::config::standard();
63
64/// Trait implemented by objects that can be used in mock expectation responses.
65///
66/// ## Panics
67///
68/// Can panic on errors.
69pub trait MockResponse {
70    /// Serialize the object to save into expectations
71    ///
72    /// ## Panics
73    ///
74    /// Can panic on errors.
75    fn mock_serialize(&self, mock_sdk: &MockDashPlatformSdk) -> Vec<u8>;
76
77    /// Deserialize the object from expectations
78    ///
79    /// ## Panics
80    ///
81    /// Can panic on errors.
82    fn mock_deserialize(mock_sdk: &MockDashPlatformSdk, buf: &[u8]) -> Self
83    where
84        Self: Sized;
85}
86
87impl<T: MockResponse> MockResponse for Option<T> {
88    fn mock_deserialize(mock_sdk: &MockDashPlatformSdk, buf: &[u8]) -> Self
89    where
90        Self: Sized,
91    {
92        if buf.is_empty() {
93            return None;
94        }
95
96        Some(T::mock_deserialize(mock_sdk, buf))
97    }
98    fn mock_serialize(&self, mock_sdk: &MockDashPlatformSdk) -> Vec<u8> {
99        match self {
100            Some(item) => item.mock_serialize(mock_sdk),
101            None => vec![],
102        }
103    }
104}
105
106impl<T: MockResponse> MockResponse for Vec<T> {
107    fn mock_deserialize(mock_sdk: &MockDashPlatformSdk, buf: &[u8]) -> Self
108    where
109        Self: Sized,
110    {
111        let items: Vec<Vec<u8>> = bincode::decode_from_slice(buf, BINCODE_CONFIG)
112            .expect("decode vec of data")
113            .0;
114        items
115            .into_iter()
116            .map(|item| T::mock_deserialize(mock_sdk, &item))
117            .collect()
118    }
119
120    fn mock_serialize(&self, mock_sdk: &MockDashPlatformSdk) -> Vec<u8> {
121        let data: Vec<Vec<u8>> = self
122            .iter()
123            .map(|item| item.mock_serialize(mock_sdk))
124            .collect();
125
126        bincode::encode_to_vec(data, BINCODE_CONFIG).expect("encode vec of data")
127    }
128}
129
130impl<K: Ord + MockResponse, V: MockResponse> MockResponse for BTreeMap<K, V> {
131    fn mock_deserialize(sdk: &MockDashPlatformSdk, buf: &[u8]) -> Self
132    where
133        Self: Sized,
134    {
135        let (data, _): (BTreeMap<Vec<u8>, Vec<u8>>, _) =
136            bincode::decode_from_slice(buf, BINCODE_CONFIG).expect("decode BTreeMap");
137
138        data.into_iter()
139            .map(|(k, v)| (K::mock_deserialize(sdk, &k), V::mock_deserialize(sdk, &v)))
140            .collect()
141    }
142
143    fn mock_serialize(&self, sdk: &MockDashPlatformSdk) -> Vec<u8> {
144        let data: BTreeMap<Vec<u8>, Vec<u8>> = self
145            .iter()
146            .map(|(k, v)| (k.mock_serialize(sdk), v.mock_serialize(sdk)))
147            .collect();
148
149        bincode::encode_to_vec(data, BINCODE_CONFIG).expect("encode BTreeMap")
150    }
151}
152
153impl<K: Hash + Eq + MockResponse, V: MockResponse> MockResponse for IndexMap<K, V> {
154    fn mock_deserialize(sdk: &MockDashPlatformSdk, buf: &[u8]) -> Self
155    where
156        Self: Sized,
157    {
158        let (data, _): (IndexMap<Vec<u8>, Vec<u8>>, _) =
159            bincode::serde::decode_from_slice(buf, BINCODE_CONFIG).expect("decode IndexMap");
160
161        data.into_iter()
162            .map(|(k, v)| (K::mock_deserialize(sdk, &k), V::mock_deserialize(sdk, &v)))
163            .collect()
164    }
165
166    fn mock_serialize(&self, sdk: &MockDashPlatformSdk) -> Vec<u8> {
167        let data: IndexMap<Vec<u8>, Vec<u8>> = self
168            .iter()
169            .map(|(k, v)| (k.mock_serialize(sdk), v.mock_serialize(sdk)))
170            .collect();
171
172        bincode::serde::encode_to_vec(data, BINCODE_CONFIG).expect("encode IndexMap")
173    }
174}
175
176/// Serialize and deserialize the object for mocking using bincode.
177///
178/// Use this macro when the object implements platform serialization.
179macro_rules! impl_mock_response {
180    ($name:ident) => {
181        impl MockResponse for $name {
182            fn mock_serialize(&self, sdk: &MockDashPlatformSdk) -> Vec<u8> {
183                platform_encode_to_vec(self, BINCODE_CONFIG, sdk.version())
184                    .expect(concat!("encode ", stringify!($name)))
185            }
186            fn mock_deserialize(sdk: &MockDashPlatformSdk, buf: &[u8]) -> Self
187            where
188                Self: Sized,
189            {
190                platform_versioned_decode_from_slice(buf, BINCODE_CONFIG, sdk.version())
191                    .expect(concat!("decode ", stringify!($name)))
192            }
193        }
194    };
195}
196
197// FIXME: Seems that DataContract doesn't implement PlatformVersionedDecode + PlatformVersionEncode,
198// so we just use some methods implemented directly on these objects.
199impl MockResponse for DataContract {
200    fn mock_serialize(&self, sdk: &MockDashPlatformSdk) -> Vec<u8> {
201        self.serialize_to_bytes_with_platform_version(sdk.version())
202            .expect("encode data")
203    }
204
205    fn mock_deserialize(sdk: &MockDashPlatformSdk, buf: &[u8]) -> Self
206    where
207        Self: Sized,
208    {
209        DataContract::versioned_deserialize_untrusted(buf, true, sdk.version())
210            .expect("decode data")
211    }
212}
213
214// FIXME: Seems that DataContract doesn't implement PlatformVersionedDecode + PlatformVersionEncode,
215// so we just use some methods implemented directly on these objects.
216impl MockResponse for (DataContract, Vec<u8>) {
217    fn mock_serialize(&self, _sdk: &MockDashPlatformSdk) -> Vec<u8> {
218        self.1.clone()
219    }
220
221    fn mock_deserialize(sdk: &MockDashPlatformSdk, buf: &[u8]) -> Self
222    where
223        Self: Sized,
224    {
225        (
226            DataContract::versioned_deserialize_untrusted(buf, true, sdk.version())
227                .expect("decode data"),
228            buf.to_vec(),
229        )
230    }
231}
232
233// FIXME: Seems that Document doesn't implement PlatformVersionedDecode + PlatformVersionEncode,
234// so we use cbor.
235impl MockResponse for Document {
236    fn mock_serialize(&self, _sdk: &MockDashPlatformSdk) -> Vec<u8> {
237        self.to_cbor().expect("encode data")
238    }
239
240    fn mock_deserialize(sdk: &MockDashPlatformSdk, buf: &[u8]) -> Self
241    where
242        Self: Sized,
243    {
244        Self::from_cbor(buf, None, None, sdk.version()).expect("decode data")
245    }
246}
247
248impl MockResponse for Element {
249    fn mock_serialize(&self, _sdk: &MockDashPlatformSdk) -> Vec<u8> {
250        // Create a bincode configuration
251        let config = standard();
252
253        // Serialize using the specified configuration
254        bincode::encode_to_vec(self, config).expect("Failed to serialize Element")
255    }
256
257    fn mock_deserialize(_sdk: &MockDashPlatformSdk, buf: &[u8]) -> Self
258    where
259        Self: Sized,
260    {
261        // Create a bincode configuration
262        let config = standard();
263
264        // Deserialize using the specified configuration
265        bincode::decode_from_slice(buf, config)
266            .expect("Failed to deserialize Element")
267            .0
268    }
269}
270
271impl MockResponse for drive_proof_verifier::types::IdentityNonceFetcher {
272    fn mock_serialize(&self, _sdk: &MockDashPlatformSdk) -> Vec<u8> {
273        self.0.to_be_bytes().to_vec()
274    }
275
276    fn mock_deserialize(_sdk: &MockDashPlatformSdk, buf: &[u8]) -> Self
277    where
278        Self: Sized,
279    {
280        drive_proof_verifier::types::IdentityNonceFetcher(u64::from_be_bytes(
281            buf.try_into()
282                .expect("identity contract nonce should be should be 8 bytes"),
283        ))
284    }
285}
286
287impl MockResponse for drive_proof_verifier::types::IdentityContractNonceFetcher {
288    fn mock_serialize(&self, _sdk: &MockDashPlatformSdk) -> Vec<u8> {
289        self.0.to_be_bytes().to_vec()
290    }
291
292    fn mock_deserialize(_sdk: &MockDashPlatformSdk, buf: &[u8]) -> Self
293    where
294        Self: Sized,
295    {
296        drive_proof_verifier::types::IdentityContractNonceFetcher(u64::from_be_bytes(
297            buf.try_into()
298                .expect("identity contract nonce should be should be 8 bytes"),
299        ))
300    }
301}
302impl MockResponse for ProTxHash {
303    fn mock_serialize(&self, sdk: &MockDashPlatformSdk) -> Vec<u8> {
304        let data = self.as_raw_hash().as_byte_array();
305        platform_encode_to_vec(data, BINCODE_CONFIG, sdk.version()).expect("encode ProTxHash")
306    }
307    fn mock_deserialize(sdk: &MockDashPlatformSdk, buf: &[u8]) -> Self
308    where
309        Self: Sized,
310    {
311        let data = platform_versioned_decode_from_slice(buf, BINCODE_CONFIG, sdk.version())
312            .expect("decode ProTxHash");
313        ProTxHash::from_raw_hash(CoreHash::from_byte_array(data))
314    }
315}
316
317impl MockResponse for ProposerBlockCounts {
318    fn mock_serialize(&self, sdk: &MockDashPlatformSdk) -> Vec<u8> {
319        self.0.mock_serialize(sdk)
320    }
321
322    fn mock_deserialize(sdk: &MockDashPlatformSdk, buf: &[u8]) -> Self
323    where
324        Self: Sized,
325    {
326        let data = RetrievedValues::<Identifier, u64>::mock_deserialize(sdk, buf);
327        ProposerBlockCounts(data)
328    }
329}
330
331impl MockResponse for DataContractsByRange {
332    fn mock_serialize(&self, sdk: &MockDashPlatformSdk) -> Vec<u8> {
333        self.0.mock_serialize(sdk)
334    }
335
336    fn mock_deserialize(sdk: &MockDashPlatformSdk, buf: &[u8]) -> Self
337    where
338        Self: Sized,
339    {
340        DataContractsByRange(
341            IndexMap::<Identifier, Option<DataContract>>::mock_deserialize(sdk, buf),
342        )
343    }
344}
345
346/// Four big-endian version bytes followed by the optional contract (empty when absent).
347impl MockResponse for DataContractLatestVersion {
348    fn mock_serialize(&self, sdk: &MockDashPlatformSdk) -> Vec<u8> {
349        let mut buf = self.version.to_be_bytes().to_vec();
350        buf.extend(self.data_contract.mock_serialize(sdk));
351        buf
352    }
353
354    fn mock_deserialize(sdk: &MockDashPlatformSdk, buf: &[u8]) -> Self
355    where
356        Self: Sized,
357    {
358        let (version, data_contract) = buf.split_at(4);
359        DataContractLatestVersion {
360            version: u32::from_be_bytes(version.try_into().expect("4 byte version prefix")),
361            data_contract: Option::<DataContract>::mock_deserialize(sdk, data_contract),
362        }
363    }
364}
365
366impl MockResponse for DataContractsLatestVersions {
367    fn mock_serialize(&self, sdk: &MockDashPlatformSdk) -> Vec<u8> {
368        self.0.mock_serialize(sdk)
369    }
370
371    fn mock_deserialize(sdk: &MockDashPlatformSdk, buf: &[u8]) -> Self
372    where
373        Self: Sized,
374    {
375        DataContractsLatestVersions(
376            IndexMap::<Identifier, Option<DataContractLatestVersion>>::mock_deserialize(sdk, buf),
377        )
378    }
379}
380
381impl MockResponse for ContractGroupInfo {
382    fn mock_serialize(&self, _sdk: &MockDashPlatformSdk) -> Vec<u8> {
383        bincode::encode_to_vec(self, BINCODE_CONFIG).expect("encode ContractGroupInfo")
384    }
385
386    fn mock_deserialize(_sdk: &MockDashPlatformSdk, buf: &[u8]) -> Self
387    where
388        Self: Sized,
389    {
390        bincode::decode_from_slice(buf, BINCODE_CONFIG)
391            .expect("decode ContractGroupInfo")
392            .0
393    }
394}
395
396/// One byte for the kind (0 contracts, 1 document types, 2 tokens) followed by the bincode
397/// entries of that kind.
398impl MockResponse for ContractModerationListStatuses {
399    fn mock_serialize(&self, _sdk: &MockDashPlatformSdk) -> Vec<u8> {
400        bincode::encode_to_vec(&self.0, BINCODE_CONFIG)
401            .expect("encode ContractModerationListStatuses")
402    }
403
404    fn mock_deserialize(_sdk: &MockDashPlatformSdk, buf: &[u8]) -> Self
405    where
406        Self: Sized,
407    {
408        let (statuses, _): (Vec<ContractModerationListStatus>, usize) =
409            bincode::decode_from_slice(buf, BINCODE_CONFIG)
410                .expect("decode ContractModerationListStatuses");
411        ContractModerationListStatuses(statuses)
412    }
413}
414
415impl MockResponse for ContractFeePots {
416    fn mock_serialize(&self, _sdk: &MockDashPlatformSdk) -> Vec<u8> {
417        let pots: [(u64, Option<ContractFeePotLastClaim>); 2] = [
418            (self.owner.credits, self.owner.last_claim),
419            (self.moderators.credits, self.moderators.last_claim),
420        ];
421        bincode::encode_to_vec(pots, BINCODE_CONFIG).expect("encode ContractFeePots")
422    }
423
424    fn mock_deserialize(_sdk: &MockDashPlatformSdk, buf: &[u8]) -> Self
425    where
426        Self: Sized,
427    {
428        let ([owner, moderators], _): ([(u64, Option<ContractFeePotLastClaim>); 2], usize) =
429            bincode::decode_from_slice(buf, BINCODE_CONFIG).expect("decode ContractFeePots");
430        let pot = |(credits, last_claim)| ContractFeePotState {
431            credits,
432            last_claim,
433        };
434        ContractFeePots {
435            owner: pot(owner),
436            moderators: pot(moderators),
437        }
438    }
439}
440
441/// One moderation list entry as a fixture holds it: the identity, the suspension end, the
442/// reason and the warnings. `ContractModerationEntry` has no bincode encoding of its own.
443type EncodedContractModerationEntry = (
444    Identifier,
445    Option<u64>,
446    ContractModerationReason,
447    Vec<ContractWarning>,
448);
449
450impl MockResponse for ContractModerationEntries {
451    fn mock_serialize(&self, _sdk: &MockDashPlatformSdk) -> Vec<u8> {
452        let entries: Vec<EncodedContractModerationEntry> = self
453            .entries()
454            .iter()
455            .map(|entry| {
456                (
457                    entry.identity_id,
458                    entry.until,
459                    entry.reason.clone(),
460                    entry.warnings.clone(),
461                )
462            })
463            .collect();
464        bincode::encode_to_vec(entries, BINCODE_CONFIG).expect("encode ContractModerationEntries")
465    }
466
467    fn mock_deserialize(_sdk: &MockDashPlatformSdk, buf: &[u8]) -> Self
468    where
469        Self: Sized,
470    {
471        let (entries, _): (Vec<EncodedContractModerationEntry>, _) =
472            bincode::decode_from_slice(buf, BINCODE_CONFIG)
473                .expect("decode ContractModerationEntries");
474        ContractModerationEntries(
475            entries
476                .into_iter()
477                .map(
478                    |(identity_id, until, reason, warnings)| ContractModerationEntry {
479                        identity_id,
480                        until,
481                        reason,
482                        warnings,
483                    },
484                )
485                .collect(),
486        )
487    }
488}
489
490/// One removal record as a fixture holds it: the document id, its owner, the moderator, when
491/// the removal happened, why, what the document hashed to, who restored it and when if anyone
492/// did, and the values it keeps of the document.
493type EncodedContractDocumentRemoval = (
494    Identifier,
495    Identifier,
496    Identifier,
497    u64,
498    ContractModerationReason,
499    [u8; 32],
500    Option<(Identifier, u64)>,
501    Vec<u8>,
502);
503
504/// One removal record in its mock wire shape.
505fn encode_removal_entry(entry: &ContractDocumentRemovalEntry) -> EncodedContractDocumentRemoval {
506    (
507        entry.document_id,
508        entry.removal.document_owner_id,
509        entry.removal.moderator_id,
510        entry.removal.removed_at,
511        entry.removal.reason.clone(),
512        entry.removal.document_hash,
513        entry
514            .removal
515            .restoration
516            .as_ref()
517            .map(|restoration| (restoration.moderator_id, restoration.restored_at)),
518        entry.removal.kept_fields.clone(),
519    )
520}
521
522/// One removal record back from its mock wire shape.
523fn decode_removal_entry(
524    (
525        document_id,
526        document_owner_id,
527        moderator_id,
528        removed_at,
529        reason,
530        document_hash,
531        restoration,
532        kept_fields,
533    ): EncodedContractDocumentRemoval,
534) -> ContractDocumentRemovalEntry {
535    ContractDocumentRemovalEntry {
536        document_id,
537        removal: ContractDocumentRemoval {
538            document_owner_id,
539            moderator_id,
540            reason,
541            removed_at,
542            document_hash,
543            restoration: restoration.map(|(moderator_id, restored_at)| {
544                ContractDocumentRestoration {
545                    moderator_id,
546                    restored_at,
547                }
548            }),
549            kept_fields,
550        },
551    }
552}
553
554impl MockResponse for ContractDocumentRemovals {
555    fn mock_serialize(&self, _sdk: &MockDashPlatformSdk) -> Vec<u8> {
556        let removals: Vec<EncodedContractDocumentRemoval> =
557            self.removals().iter().map(encode_removal_entry).collect();
558        bincode::encode_to_vec(removals, BINCODE_CONFIG).expect("encode ContractDocumentRemovals")
559    }
560
561    fn mock_deserialize(_sdk: &MockDashPlatformSdk, buf: &[u8]) -> Self
562    where
563        Self: Sized,
564    {
565        let (removals, _): (Vec<EncodedContractDocumentRemoval>, _) =
566            bincode::decode_from_slice(buf, BINCODE_CONFIG)
567                .expect("decode ContractDocumentRemovals");
568        ContractDocumentRemovals(removals.into_iter().map(decode_removal_entry).collect())
569    }
570}
571
572impl MockResponse for ContractTeamActions {
573    fn mock_serialize(&self, _sdk: &MockDashPlatformSdk) -> Vec<u8> {
574        // An action has a bincode encoding of its own; the action id is the key it is stored
575        // under, and the approval count the sum of its approvals.
576        let actions: Vec<(Identifier, ContractTeamAction, u32)> = self
577            .actions()
578            .iter()
579            .map(|entry| (entry.action_id, entry.action.clone(), entry.approval_count))
580            .collect();
581        bincode::encode_to_vec(actions, BINCODE_CONFIG).expect("encode ContractTeamActions")
582    }
583
584    fn mock_deserialize(_sdk: &MockDashPlatformSdk, buf: &[u8]) -> Self
585    where
586        Self: Sized,
587    {
588        let (actions, _): (Vec<(Identifier, ContractTeamAction, u32)>, _) =
589            bincode::decode_from_slice(buf, BINCODE_CONFIG).expect("decode ContractTeamActions");
590        ContractTeamActions(
591            actions
592                .into_iter()
593                .map(
594                    |(action_id, action, approval_count)| ContractTeamActionEntry {
595                        action_id,
596                        action,
597                        approval_count,
598                    },
599                )
600                .collect(),
601        )
602    }
603}
604
605impl MockResponse for ContractTeamActionSigners {
606    fn mock_serialize(&self, _sdk: &MockDashPlatformSdk) -> Vec<u8> {
607        bincode::encode_to_vec(self.signers(), BINCODE_CONFIG)
608            .expect("encode ContractTeamActionSigners")
609    }
610
611    fn mock_deserialize(_sdk: &MockDashPlatformSdk, buf: &[u8]) -> Self
612    where
613        Self: Sized,
614    {
615        let (signers, _): (Vec<Identifier>, _) = bincode::decode_from_slice(buf, BINCODE_CONFIG)
616            .expect("decode ContractTeamActionSigners");
617        ContractTeamActionSigners(signers)
618    }
619}
620
621impl MockResponse for ContractModerationActionCounts {
622    fn mock_serialize(&self, _sdk: &MockDashPlatformSdk) -> Vec<u8> {
623        let counts: Vec<(Identifier, u32)> = self
624            .counts()
625            .iter()
626            .map(|(identity_id, count)| (*identity_id, *count))
627            .collect();
628        bincode::encode_to_vec(counts, BINCODE_CONFIG)
629            .expect("encode ContractModerationActionCounts")
630    }
631
632    fn mock_deserialize(_sdk: &MockDashPlatformSdk, buf: &[u8]) -> Self
633    where
634        Self: Sized,
635    {
636        let (counts, _): (Vec<(Identifier, u32)>, _) =
637            bincode::decode_from_slice(buf, BINCODE_CONFIG)
638                .expect("decode ContractModerationActionCounts");
639        ContractModerationActionCounts(counts.into_iter().collect())
640    }
641}
642
643impl MockResponse for ContractGroupMembersPage {
644    fn mock_serialize(&self, _sdk: &MockDashPlatformSdk) -> Vec<u8> {
645        let (kind, entries) = match self {
646            ContractGroupMembersPage::Contracts(entries) => (
647                0u8,
648                bincode::encode_to_vec(entries, BINCODE_CONFIG).expect("encode member contracts"),
649            ),
650            ContractGroupMembersPage::DocumentTypes(entries) => (
651                1u8,
652                bincode::encode_to_vec(entries, BINCODE_CONFIG)
653                    .expect("encode member document types"),
654            ),
655            ContractGroupMembersPage::Tokens(entries) => (
656                2u8,
657                bincode::encode_to_vec(entries, BINCODE_CONFIG).expect("encode member tokens"),
658            ),
659        };
660        let mut buf = vec![kind];
661        buf.extend(entries);
662        buf
663    }
664
665    fn mock_deserialize(_sdk: &MockDashPlatformSdk, buf: &[u8]) -> Self
666    where
667        Self: Sized,
668    {
669        let (kind, entries) = buf.split_first().expect("members page kind byte");
670        match kind {
671            0 => ContractGroupMembersPage::Contracts(
672                bincode::decode_from_slice(entries, BINCODE_CONFIG)
673                    .expect("decode member contracts")
674                    .0,
675            ),
676            1 => ContractGroupMembersPage::DocumentTypes(
677                bincode::decode_from_slice(entries, BINCODE_CONFIG)
678                    .expect("decode member document types")
679                    .0,
680            ),
681            2 => ContractGroupMembersPage::Tokens(
682                bincode::decode_from_slice(entries, BINCODE_CONFIG)
683                    .expect("decode member tokens")
684                    .0,
685            ),
686            other => panic!("unknown members page kind {other}"),
687        }
688    }
689}
690
691/// The three membership maps, bincode encoded as a tuple.
692impl MockResponse for ContractGroupMembershipsForContract {
693    fn mock_serialize(&self, _sdk: &MockDashPlatformSdk) -> Vec<u8> {
694        bincode::encode_to_vec(
695            (&self.contract, &self.document_types, &self.tokens),
696            BINCODE_CONFIG,
697        )
698        .expect("encode ContractGroupMembershipsForContract")
699    }
700
701    fn mock_deserialize(_sdk: &MockDashPlatformSdk, buf: &[u8]) -> Self
702    where
703        Self: Sized,
704    {
705        let (contract, document_types, tokens) = bincode::decode_from_slice(buf, BINCODE_CONFIG)
706            .expect("decode ContractGroupMembershipsForContract")
707            .0;
708        ContractGroupMembershipsForContract {
709            contract,
710            document_types,
711            tokens,
712        }
713    }
714}
715
716impl MockResponse for IdentityKeysRemainingBudgets {
717    fn mock_serialize(&self, sdk: &MockDashPlatformSdk) -> Vec<u8> {
718        self.0.mock_serialize(sdk)
719    }
720
721    fn mock_deserialize(sdk: &MockDashPlatformSdk, buf: &[u8]) -> Self
722    where
723        Self: Sized,
724    {
725        let map = RetrievedValues::mock_deserialize(sdk, buf);
726        Self(map)
727    }
728}
729
730impl MockResponse for IdentityTokenBalances {
731    fn mock_serialize(&self, sdk: &MockDashPlatformSdk) -> Vec<u8> {
732        self.0.mock_serialize(sdk)
733    }
734
735    fn mock_deserialize(sdk: &MockDashPlatformSdk, buf: &[u8]) -> Self
736    where
737        Self: Sized,
738    {
739        let map = RetrievedValues::mock_deserialize(sdk, buf);
740        Self(map)
741    }
742}
743
744impl MockResponse for IdentitiesTokenBalances {
745    fn mock_serialize(&self, sdk: &MockDashPlatformSdk) -> Vec<u8> {
746        self.0.mock_serialize(sdk)
747    }
748
749    fn mock_deserialize(sdk: &MockDashPlatformSdk, buf: &[u8]) -> Self
750    where
751        Self: Sized,
752    {
753        let map = RetrievedValues::mock_deserialize(sdk, buf);
754        Self(map)
755    }
756}
757
758impl MockResponse for IdentityTokenInfos {
759    fn mock_serialize(&self, sdk: &MockDashPlatformSdk) -> Vec<u8> {
760        // Clone and collect into vector
761        let vec: Vec<(Identifier, Option<IdentityTokenInfo>)> =
762            self.0.iter().map(|(k, v)| (*k, v.clone())).collect();
763
764        // Serialize vector
765        platform_encode_to_vec(vec, BINCODE_CONFIG, sdk.version())
766            .expect(concat!("encode ", stringify!($name)))
767    }
768
769    fn mock_deserialize(sdk: &MockDashPlatformSdk, buf: &[u8]) -> Self
770    where
771        Self: Sized,
772    {
773        // deserialize vector
774        let vec: Vec<(Identifier, Option<IdentityTokenInfo>)> =
775            platform_versioned_decode_from_slice(buf, BINCODE_CONFIG, sdk.version())
776                .expect(concat!("decode ", stringify!($name)));
777
778        Self(RetrievedValues::from_iter(vec))
779    }
780}
781
782impl MockResponse for IdentitiesTokenInfos {
783    fn mock_serialize(&self, sdk: &MockDashPlatformSdk) -> Vec<u8> {
784        // Clone and collect into vector
785        let vec: Vec<(Identifier, Option<IdentityTokenInfo>)> =
786            self.0.iter().map(|(k, v)| (*k, v.clone())).collect();
787
788        // Serialize vector
789        platform_encode_to_vec(vec, BINCODE_CONFIG, sdk.version())
790            .expect(concat!("encode ", stringify!($name)))
791    }
792
793    fn mock_deserialize(sdk: &MockDashPlatformSdk, buf: &[u8]) -> Self
794    where
795        Self: Sized,
796    {
797        // deserialize vector
798        let vec: Vec<(Identifier, Option<IdentityTokenInfo>)> =
799            platform_versioned_decode_from_slice(buf, BINCODE_CONFIG, sdk.version())
800                .expect(concat!("decode ", stringify!($name)));
801
802        Self(RetrievedValues::from_iter(vec))
803    }
804}
805
806impl MockResponse for TokenStatuses {
807    fn mock_serialize(&self, sdk: &MockDashPlatformSdk) -> Vec<u8> {
808        // Clone and collect into vector
809        let vec: Vec<(Identifier, Option<TokenStatus>)> =
810            self.iter().map(|(k, v)| (*k, v.clone())).collect();
811
812        // Serialize vector
813        platform_encode_to_vec(vec, BINCODE_CONFIG, sdk.version())
814            .expect(concat!("encode ", stringify!($name)))
815    }
816
817    fn mock_deserialize(sdk: &MockDashPlatformSdk, buf: &[u8]) -> Self
818    where
819        Self: Sized,
820    {
821        // deserialize vector
822        let vec: Vec<(Identifier, Option<TokenStatus>)> =
823            platform_versioned_decode_from_slice(buf, BINCODE_CONFIG, sdk.version())
824                .expect(concat!("decode ", stringify!($name)));
825
826        RetrievedValues::from_iter(vec)
827    }
828}
829
830impl MockResponse for TokenContractInfo {
831    fn mock_serialize(&self, sdk: &MockDashPlatformSdk) -> Vec<u8> {
832        platform_encode_to_vec(self, BINCODE_CONFIG, sdk.version())
833            .expect("encode TokenContractInfo")
834    }
835
836    fn mock_deserialize(sdk: &MockDashPlatformSdk, buf: &[u8]) -> Self
837    where
838        Self: Sized,
839    {
840        platform_versioned_decode_from_slice(buf, BINCODE_CONFIG, sdk.version())
841            .expect("decode TokenContractInfo")
842    }
843}
844
845impl MockResponse for TotalSingleTokenBalance {
846    fn mock_serialize(&self, _sdk: &MockDashPlatformSdk) -> Vec<u8> {
847        bincode::encode_to_vec(self, BINCODE_CONFIG).expect("encode vec of data")
848    }
849
850    fn mock_deserialize(_sdk: &MockDashPlatformSdk, buf: &[u8]) -> Self
851    where
852        Self: Sized,
853    {
854        bincode::decode_from_slice(buf, BINCODE_CONFIG)
855            .expect("decode vec of data")
856            .0
857    }
858}
859
860impl MockResponse for GroupActions {
861    fn mock_serialize(&self, sdk: &MockDashPlatformSdk) -> Vec<u8> {
862        // Clone and collect into vector
863        let vec: Vec<(Identifier, Option<GroupAction>)> =
864            self.iter().map(|(k, v)| (*k, v.clone())).collect();
865
866        // Serialize vector
867        platform_encode_to_vec(vec, BINCODE_CONFIG, sdk.version())
868            .expect(concat!("encode ", stringify!($name)))
869    }
870
871    fn mock_deserialize(sdk: &MockDashPlatformSdk, buf: &[u8]) -> Self
872    where
873        Self: Sized,
874    {
875        // deserialize vector
876        let vec: Vec<(Identifier, Option<GroupAction>)> =
877            platform_versioned_decode_from_slice(buf, BINCODE_CONFIG, sdk.version())
878                .expect(concat!("decode ", stringify!($name)));
879
880        RetrievedValues::from_iter(vec)
881    }
882}
883
884impl MockResponse for IdentitiesContractKeys {
885    fn mock_serialize(&self, _sdk: &MockDashPlatformSdk) -> Vec<u8> {
886        bincode::encode_to_vec(self, BINCODE_CONFIG).expect("encode IdentitiesContractKeys")
887    }
888
889    fn mock_deserialize(_sdk: &MockDashPlatformSdk, buf: &[u8]) -> Self
890    where
891        Self: Sized,
892    {
893        bincode::decode_from_slice(buf, BINCODE_CONFIG)
894            .expect("decode IdentitiesContractKeys")
895            .0
896    }
897}
898
899impl_mock_response!(Identity);
900impl_mock_response!(IdentityPublicKey);
901impl_mock_response!(Identifier);
902impl_mock_response!(MasternodeProtocolVote);
903impl_mock_response!(ResourceVote);
904impl_mock_response!(u8);
905impl_mock_response!(u16);
906impl_mock_response!(u32);
907impl_mock_response!(u64);
908impl_mock_response!(Vote);
909impl_mock_response!(ExtendedEpochInfo);
910impl_mock_response!(FinalizedEpochInfo);
911impl_mock_response!(ContestedResources);
912impl_mock_response!(IdentityBalanceAndRevision);
913impl_mock_response!(Contenders);
914impl_mock_response!(Voters);
915impl_mock_response!(VotePollsGroupedByTimestamp);
916impl_mock_response!(PrefundedSpecializedBalance);
917impl_mock_response!(TotalCreditsInPlatform);
918impl_mock_response!(ElementFetchRequestItem);
919impl_mock_response!(EvoNodeStatus);
920impl_mock_response!(CurrentQuorumsInfo);
921impl_mock_response!(Group);
922impl_mock_response!(TokenPricingSchedule);
923impl_mock_response!(RewardDistributionMoment);
924impl_mock_response!(TokenPreProgrammedDistributions);
925impl_mock_response!(PlatformAddress);
926impl_mock_response!(AddressInfo);
927impl_mock_response!(RecentAddressBalanceChanges);
928impl_mock_response!(RecentCompactedAddressBalanceChanges);
929impl_mock_response!(ShieldedPoolState);
930impl_mock_response!(ShieldedNotesCount);
931impl_mock_response!(ShieldedAnchors);
932impl_mock_response!(MostRecentShieldedAnchor);
933impl_mock_response!(ShieldedEncryptedNotes);
934impl_mock_response!(ShieldedEncryptedNote);
935impl_mock_response!(ShieldedNullifierStatuses);
936impl_mock_response!(ShieldedNullifierStatus);
937
938/// MockResponse for GroveTrunkQueryResult - panics when called because the Tree type
939/// doesn't support serialization. Address sync operations should not be mocked.
940impl MockResponse for GroveTrunkQueryResult {
941    fn mock_serialize(&self, _sdk: &MockDashPlatformSdk) -> Vec<u8> {
942        unimplemented!("GroveTrunkQueryResult does not support mock serialization - the Tree type is not serializable")
943    }
944
945    fn mock_deserialize(_sdk: &MockDashPlatformSdk, _buf: &[u8]) -> Self
946    where
947        Self: Sized,
948    {
949        unimplemented!("GroveTrunkQueryResult does not support mock deserialization - the Tree type is not serializable")
950    }
951}
952
953/// MockResponse for PlatformAddressTrunkState - panics when called because the underlying
954/// Tree type doesn't support serialization. Address sync operations should not be mocked.
955impl MockResponse for PlatformAddressTrunkState {
956    fn mock_serialize(&self, _sdk: &MockDashPlatformSdk) -> Vec<u8> {
957        unimplemented!("PlatformAddressTrunkState does not support mock serialization - the Tree type is not serializable")
958    }
959
960    fn mock_deserialize(_sdk: &MockDashPlatformSdk, _buf: &[u8]) -> Self
961    where
962        Self: Sized,
963    {
964        unimplemented!("PlatformAddressTrunkState does not support mock deserialization - the Tree type is not serializable")
965    }
966}
967
968impl MockResponse for drive_proof_verifier::DocumentCount {
969    fn mock_serialize(&self, _sdk: &MockDashPlatformSdk) -> Vec<u8> {
970        let bincode_config = standard();
971        bincode::encode_to_vec(self.0, bincode_config).expect("encode DocumentCount")
972    }
973
974    fn mock_deserialize(_sdk: &MockDashPlatformSdk, buf: &[u8]) -> Self
975    where
976        Self: Sized,
977    {
978        let bincode_config = standard();
979        let (count, _): (u64, _) =
980            bincode::decode_from_slice(buf, bincode_config).expect("decode DocumentCount");
981        drive_proof_verifier::DocumentCount(count)
982    }
983}
984
985/// Wire shape for `DocumentSplitCounts` mock round-trip:
986/// `(in_key, key, count)` triples preserving the In dimension
987/// AND the verified-vs-absent count distinction. Shared by
988/// `mock_serialize`/`mock_deserialize` below — single source of
989/// truth so the encode/decode generics align by construction,
990/// and clippy's `type_complexity` lint (CI runs with
991/// `-D warnings`) doesn't fire on the inline form.
992type DocumentSplitCountTriples = Vec<(Option<Vec<u8>>, Vec<u8>, Option<u64>)>;
993
994impl MockResponse for drive_proof_verifier::DocumentSplitCounts {
995    fn mock_serialize(&self, _sdk: &MockDashPlatformSdk) -> Vec<u8> {
996        let bincode_config = standard();
997        // Serialize as `(in_key, key, count)` triples so the In
998        // dimension AND the verified-vs-absent count distinction
999        // both survive the mock roundtrip. Required for compound
1000        // (`In + range + distinct`) test fixtures to keep their
1001        // `in_key` values, and for GroupByIn-absent-branch
1002        // fixtures to keep their `None` counts.
1003        let triples: DocumentSplitCountTriples = self
1004            .0
1005            .iter()
1006            .map(|e| (e.in_key.clone(), e.key.clone(), e.count))
1007            .collect();
1008        bincode::encode_to_vec(triples, bincode_config).expect("encode DocumentSplitCounts")
1009    }
1010
1011    fn mock_deserialize(_sdk: &MockDashPlatformSdk, buf: &[u8]) -> Self
1012    where
1013        Self: Sized,
1014    {
1015        let bincode_config = standard();
1016        let (triples, _): (DocumentSplitCountTriples, _) =
1017            bincode::decode_from_slice(buf, bincode_config).expect("decode DocumentSplitCounts");
1018        let entries: Vec<drive_proof_verifier::SplitCountEntry> = triples
1019            .into_iter()
1020            .map(
1021                |(in_key, key, count)| drive_proof_verifier::SplitCountEntry { in_key, key, count },
1022            )
1023            .collect();
1024        drive_proof_verifier::DocumentSplitCounts::from_verified(entries)
1025    }
1026}
1027
1028impl MockResponse for drive_proof_verifier::DocumentSum {
1029    fn mock_serialize(&self, _sdk: &MockDashPlatformSdk) -> Vec<u8> {
1030        let bincode_config = standard();
1031        bincode::encode_to_vec(self.0, bincode_config).expect("encode DocumentSum")
1032    }
1033
1034    fn mock_deserialize(_sdk: &MockDashPlatformSdk, buf: &[u8]) -> Self
1035    where
1036        Self: Sized,
1037    {
1038        let bincode_config = standard();
1039        let (sum, _): (i64, _) =
1040            bincode::decode_from_slice(buf, bincode_config).expect("decode DocumentSum");
1041        drive_proof_verifier::DocumentSum(sum)
1042    }
1043}
1044
1045/// Wire shape for `DocumentSplitSums` mock round-trip. Mirrors
1046/// [`DocumentSplitCountTriples`] — preserves the `in_key` axis
1047/// and the verified-vs-absent sum distinction (`Option<i64>`)
1048/// across the roundtrip.
1049type DocumentSplitSumTriples = Vec<(Option<Vec<u8>>, Vec<u8>, Option<i64>)>;
1050
1051impl MockResponse for drive_proof_verifier::DocumentSplitSums {
1052    fn mock_serialize(&self, _sdk: &MockDashPlatformSdk) -> Vec<u8> {
1053        let bincode_config = standard();
1054        let triples: DocumentSplitSumTriples = self
1055            .0
1056            .iter()
1057            .map(|e| (e.in_key.clone(), e.key.clone(), e.sum))
1058            .collect();
1059        bincode::encode_to_vec(triples, bincode_config).expect("encode DocumentSplitSums")
1060    }
1061
1062    fn mock_deserialize(_sdk: &MockDashPlatformSdk, buf: &[u8]) -> Self
1063    where
1064        Self: Sized,
1065    {
1066        let bincode_config = standard();
1067        let (triples, _): (DocumentSplitSumTriples, _) =
1068            bincode::decode_from_slice(buf, bincode_config).expect("decode DocumentSplitSums");
1069        let entries: Vec<drive_proof_verifier::SplitSumEntry> = triples
1070            .into_iter()
1071            .map(|(in_key, key, sum)| drive_proof_verifier::SplitSumEntry { in_key, key, sum })
1072            .collect();
1073        drive_proof_verifier::DocumentSplitSums(entries)
1074    }
1075}
1076
1077impl MockResponse for drive_proof_verifier::DocumentAverage {
1078    fn mock_serialize(&self, _sdk: &MockDashPlatformSdk) -> Vec<u8> {
1079        let bincode_config = standard();
1080        bincode::encode_to_vec((self.count, self.sum), bincode_config)
1081            .expect("encode DocumentAverage")
1082    }
1083
1084    fn mock_deserialize(_sdk: &MockDashPlatformSdk, buf: &[u8]) -> Self
1085    where
1086        Self: Sized,
1087    {
1088        let bincode_config = standard();
1089        let ((count, sum), _): ((u64, i64), _) =
1090            bincode::decode_from_slice(buf, bincode_config).expect("decode DocumentAverage");
1091        drive_proof_verifier::DocumentAverage { count, sum }
1092    }
1093}
1094
1095/// Wire shape for `DocumentSplitAverages` mock round-trip. Same
1096/// `(in_key, key)` axes as the sum variant, but carries both
1097/// `Option<u64>` (count) and `Option<i64>` (sum) so the verified-vs-
1098/// absent state of each axis can roundtrip independently.
1099type DocumentSplitAverageTuples = Vec<(Option<Vec<u8>>, Vec<u8>, Option<u64>, Option<i64>)>;
1100
1101impl MockResponse for drive_proof_verifier::DocumentSplitAverages {
1102    fn mock_serialize(&self, _sdk: &MockDashPlatformSdk) -> Vec<u8> {
1103        let bincode_config = standard();
1104        let tuples: DocumentSplitAverageTuples = self
1105            .0
1106            .iter()
1107            .map(|e| (e.in_key.clone(), e.key.clone(), e.count, e.sum))
1108            .collect();
1109        bincode::encode_to_vec(tuples, bincode_config).expect("encode DocumentSplitAverages")
1110    }
1111
1112    fn mock_deserialize(_sdk: &MockDashPlatformSdk, buf: &[u8]) -> Self
1113    where
1114        Self: Sized,
1115    {
1116        let bincode_config = standard();
1117        let (tuples, _): (DocumentSplitAverageTuples, _) =
1118            bincode::decode_from_slice(buf, bincode_config).expect("decode DocumentSplitAverages");
1119        let entries: Vec<drive_proof_verifier::SplitAverageEntry> = tuples
1120            .into_iter()
1121            .map(
1122                |(in_key, key, count, sum)| drive_proof_verifier::SplitAverageEntry {
1123                    in_key,
1124                    key,
1125                    count,
1126                    sum,
1127                },
1128            )
1129            .collect();
1130        drive_proof_verifier::DocumentSplitAverages(entries)
1131    }
1132}
1133
1134/// Wire shape for `DocumentRankedEntries` mock round-trip: the page's
1135/// `starting_rank`, then `(group key, axis tag, value)` triples in list
1136/// order — **order is the ranking**, so a map-shaped encoding (as used
1137/// nowhere here, but as would be the obvious alternative) would destroy
1138/// the answer.
1139///
1140/// `starting_rank` is part of the encoding rather than reconstructed as
1141/// `0` on decode, because it is exactly what an offset test needs to
1142/// assert: a mock that dropped it would make every expectation look
1143/// like an offset-0 query and quietly pass a round-trip that lost the
1144/// rank base.
1145///
1146/// The value is widened to `i128` across all three axes: `Count`
1147/// (`u64`) and `Sum` (`i64`) both fit losslessly, and `AvgFixedPoint`
1148/// is already an `i128`. One numeric column keeps the tuple flat while
1149/// the tag preserves which axis produced it, so a mock expectation
1150/// can't quietly turn a count into a sum.
1151/// One mock-serialized ranked entry: `(key, axis tag, value, in_key)`.
1152type MockRankedEntry = (Vec<u8>, u8, i128, Option<Vec<u8>>);
1153type DocumentRankedPage = (u64, Vec<MockRankedEntry>);
1154
1155const RANKED_TAG_COUNT: u8 = 0;
1156const RANKED_TAG_SUM: u8 = 1;
1157const RANKED_TAG_AVG: u8 = 2;
1158
1159impl MockResponse for drive_proof_verifier::DocumentRankedEntries {
1160    fn mock_serialize(&self, _sdk: &MockDashPlatformSdk) -> Vec<u8> {
1161        let bincode_config = standard();
1162        let triples: Vec<MockRankedEntry> = self
1163            .entries
1164            .iter()
1165            .map(|e| match e.value {
1166                drive_proof_verifier::RankedEntryValue::Count(count) => (
1167                    e.key.clone(),
1168                    RANKED_TAG_COUNT,
1169                    count as i128,
1170                    e.in_key.clone(),
1171                ),
1172                drive_proof_verifier::RankedEntryValue::Sum(sum) => {
1173                    (e.key.clone(), RANKED_TAG_SUM, sum as i128, e.in_key.clone())
1174                }
1175                drive_proof_verifier::RankedEntryValue::AvgFixedPoint(avg) => {
1176                    (e.key.clone(), RANKED_TAG_AVG, avg, e.in_key.clone())
1177                }
1178            })
1179            .collect();
1180        let page: DocumentRankedPage = (self.starting_rank, triples);
1181        bincode::encode_to_vec(page, bincode_config).expect("encode DocumentRankedEntries")
1182    }
1183
1184    fn mock_deserialize(_sdk: &MockDashPlatformSdk, buf: &[u8]) -> Self
1185    where
1186        Self: Sized,
1187    {
1188        let bincode_config = standard();
1189        let ((starting_rank, triples), _): (DocumentRankedPage, _) =
1190            bincode::decode_from_slice(buf, bincode_config).expect("decode DocumentRankedEntries");
1191        let entries: Vec<drive_proof_verifier::RankedEntry> = triples
1192            .into_iter()
1193            .map(|(key, tag, value, in_key)| {
1194                let value = match tag {
1195                    RANKED_TAG_COUNT => drive_proof_verifier::RankedEntryValue::Count(
1196                        u64::try_from(value).expect("a Count entry round-trips through i128"),
1197                    ),
1198                    RANKED_TAG_SUM => drive_proof_verifier::RankedEntryValue::Sum(
1199                        i64::try_from(value).expect("a Sum entry round-trips through i128"),
1200                    ),
1201                    RANKED_TAG_AVG => drive_proof_verifier::RankedEntryValue::AvgFixedPoint(value),
1202                    other => panic!("unknown ranked axis tag {other} in mock expectation"),
1203                };
1204                drive_proof_verifier::RankedEntry { in_key, key, value }
1205            })
1206            .collect();
1207        drive_proof_verifier::DocumentRankedEntries {
1208            starting_rank,
1209            entries,
1210        }
1211    }
1212}
1213
1214impl MockResponse for drive_proof_verifier::DocumentHavingEntries {
1215    /// Rides the ranked page encoding with a starting rank of `0`: a
1216    /// having page is the same ordered `(group key, axis tag, value)`
1217    /// list, just addressed by value bound instead of by rank, and it
1218    /// has no rank base to preserve.
1219    fn mock_serialize(&self, sdk: &MockDashPlatformSdk) -> Vec<u8> {
1220        drive_proof_verifier::DocumentRankedEntries {
1221            starting_rank: 0,
1222            entries: self.entries.clone(),
1223        }
1224        .mock_serialize(sdk)
1225    }
1226
1227    fn mock_deserialize(sdk: &MockDashPlatformSdk, buf: &[u8]) -> Self
1228    where
1229        Self: Sized,
1230    {
1231        let page = drive_proof_verifier::DocumentRankedEntries::mock_deserialize(sdk, buf);
1232        drive_proof_verifier::DocumentHavingEntries {
1233            entries: page.entries,
1234        }
1235    }
1236}
1237
1238/// Wire shape for `ChainedDocuments` mock round-trip: both halves as
1239/// per-document CBOR lists.
1240type MockChainedHalves = (
1241    Vec<Vec<u8>>,
1242    Vec<Vec<u8>>,
1243    Vec<[u8; 32]>,
1244    Vec<EncodedContractDocumentRemoval>,
1245);
1246
1247impl MockResponse for drive_proof_verifier::ChainedDocuments {
1248    /// Both halves as per-document CBOR, bincode-framed as
1249    /// `(inner, outer)` — list order IS the answer (inner-proof order,
1250    /// outer by first appearance), so a map-shaped encoding would
1251    /// destroy it.
1252    fn mock_serialize(&self, _sdk: &MockDashPlatformSdk) -> Vec<u8> {
1253        let bincode_config = standard();
1254        let halves: MockChainedHalves = (
1255            self.inner_documents
1256                .iter()
1257                .map(|d| d.to_cbor().expect("encode inner document"))
1258                .collect(),
1259            self.outer_documents
1260                .iter()
1261                .map(|d| d.to_cbor().expect("encode outer document"))
1262                .collect(),
1263            self.missing_outer_ids
1264                .iter()
1265                .map(|id| id.to_buffer())
1266                .collect(),
1267            self.removed_outer_documents
1268                .iter()
1269                .map(encode_removal_entry)
1270                .collect(),
1271        );
1272        bincode::encode_to_vec(halves, bincode_config).expect("encode ChainedDocuments")
1273    }
1274
1275    fn mock_deserialize(sdk: &MockDashPlatformSdk, buf: &[u8]) -> Self
1276    where
1277        Self: Sized,
1278    {
1279        let bincode_config = standard();
1280        let ((inner, outer, missing, removed), _): (MockChainedHalves, _) =
1281            bincode::decode_from_slice(buf, bincode_config).expect("decode ChainedDocuments");
1282        let decode = |bufs: Vec<Vec<u8>>| {
1283            bufs.into_iter()
1284                .map(|b| {
1285                    Document::from_cbor(&b, None, None, sdk.version()).expect("decode document")
1286                })
1287                .collect()
1288        };
1289        drive_proof_verifier::ChainedDocuments {
1290            inner_documents: decode(inner),
1291            outer_documents: decode(outer),
1292            missing_outer_ids: missing.into_iter().map(Identifier::from).collect(),
1293            removed_outer_documents: removed.into_iter().map(decode_removal_entry).collect(),
1294        }
1295    }
1296}
1297
1298/// Wire shape for one `CompositeDocuments` sub-result mock round-trip:
1299/// `(is_documents, documents, count triples)`, only one side populated.
1300type MockCompositeSubResult = (bool, Vec<Vec<u8>>, DocumentSplitCountTriples);
1301
1302/// Wire shape for `CompositeDocuments` mock round-trip: the page as a
1303/// per-document CBOR list, then one entry per sub-query.
1304type MockCompositeShape = (
1305    Vec<Vec<u8>>,
1306    Vec<MockCompositeSubResult>,
1307    Vec<Vec<[u8; 32]>>,
1308    Vec<Vec<EncodedContractDocumentRemoval>>,
1309);
1310
1311impl MockResponse for drive_proof_verifier::CompositeDocuments {
1312    /// The page and every documents sub-result as per-document CBOR,
1313    /// count sub-results as `(in_key, key, count)` triples, all
1314    /// bincode-framed in request order — list order IS the answer
1315    /// (page order, a join's first-appearance order), so a map-shaped
1316    /// encoding would destroy it.
1317    fn mock_serialize(&self, _sdk: &MockDashPlatformSdk) -> Vec<u8> {
1318        let bincode_config = standard();
1319        let encode = |documents: &[Document]| -> Vec<Vec<u8>> {
1320            documents
1321                .iter()
1322                .map(|d| d.to_cbor().expect("encode document"))
1323                .collect()
1324        };
1325        let shape: MockCompositeShape = (
1326            encode(&self.page_documents),
1327            self.sub_results
1328                .iter()
1329                .map(|result| match result {
1330                    drive_proof_verifier::CompositeSubQueryResult::Documents(documents) => {
1331                        (true, encode(documents), Vec::new())
1332                    }
1333                    drive_proof_verifier::CompositeSubQueryResult::Counts(entries) => (
1334                        false,
1335                        Vec::new(),
1336                        entries
1337                            .iter()
1338                            .map(|e| (e.in_key.clone(), e.key.clone(), e.count))
1339                            .collect(),
1340                    ),
1341                })
1342                .collect(),
1343            self.sub_result_missing_ids
1344                .iter()
1345                .map(|ids| ids.iter().map(|id| id.to_buffer()).collect())
1346                .collect(),
1347            self.sub_result_removals
1348                .iter()
1349                .map(|removals| removals.iter().map(encode_removal_entry).collect())
1350                .collect(),
1351        );
1352        bincode::encode_to_vec(shape, bincode_config).expect("encode CompositeDocuments")
1353    }
1354
1355    fn mock_deserialize(sdk: &MockDashPlatformSdk, buf: &[u8]) -> Self
1356    where
1357        Self: Sized,
1358    {
1359        let bincode_config = standard();
1360        let ((page, sub_results, missing_ids, removals), _): (MockCompositeShape, _) =
1361            bincode::decode_from_slice(buf, bincode_config).expect("decode CompositeDocuments");
1362        let decode = |bufs: Vec<Vec<u8>>| -> Vec<Document> {
1363            bufs.into_iter()
1364                .map(|b| {
1365                    Document::from_cbor(&b, None, None, sdk.version()).expect("decode document")
1366                })
1367                .collect()
1368        };
1369        drive_proof_verifier::CompositeDocuments {
1370            page_documents: decode(page),
1371            sub_results: sub_results
1372                .into_iter()
1373                .map(|(is_documents, documents, triples)| {
1374                    if is_documents {
1375                        drive_proof_verifier::CompositeSubQueryResult::Documents(decode(documents))
1376                    } else {
1377                        drive_proof_verifier::CompositeSubQueryResult::Counts(
1378                            triples
1379                                .into_iter()
1380                                .map(
1381                                    |(in_key, key, count)| drive_proof_verifier::SplitCountEntry {
1382                                        in_key,
1383                                        key,
1384                                        count,
1385                                    },
1386                                )
1387                                .collect(),
1388                        )
1389                    }
1390                })
1391                .collect(),
1392            sub_result_missing_ids: missing_ids
1393                .into_iter()
1394                .map(|ids| ids.into_iter().map(Identifier::from).collect())
1395                .collect(),
1396            sub_result_removals: removals
1397                .into_iter()
1398                .map(|removals| removals.into_iter().map(decode_removal_entry).collect())
1399                .collect(),
1400        }
1401    }
1402}