mithril_common/test/double/
dummies.rs

1use chrono::{DateTime, Utc};
2
3use crate::test::double::{Dummy, fake_data, fake_keys};
4
5mod entities {
6    use crate::crypto_helper::MKTreeStoreInMemory;
7    use crate::entities::*;
8    use crate::test::entities_extensions::CardanoTransactionsSetProofTestExtension;
9
10    use super::*;
11
12    impl Dummy for ChainPoint {
13        /// Return a dummy [ChainPoint] (test-only).
14        fn dummy() -> Self {
15            Self {
16                slot_number: SlotNumber(100),
17                block_number: BlockNumber(0),
18                block_hash: "block_hash-50".to_string(),
19            }
20        }
21    }
22
23    impl Dummy for CardanoTransactionsSetProof {
24        /// Return a dummy [CardanoTransactionsSetProof] (test-only).
25        fn dummy() -> Self {
26            let leaves = vec![
27                (BlockNumber(0), "tx-1".to_string()),
28                (BlockNumber(1), "tx-2".to_string()),
29                (BlockNumber(1), "tx-3".to_string()),
30                (BlockNumber(10), "tx-4".to_string()),
31                (BlockNumber(20), "tx-5".to_string()),
32                (BlockNumber(22), "tx-6".to_string()),
33            ];
34
35            Self::from_leaves::<MKTreeStoreInMemory>(&leaves).unwrap()
36        }
37    }
38
39    impl Dummy for SignedEntityConfig {
40        /// Return a dummy [SignedEntityConfig] (test-only).
41        fn dummy() -> Self {
42            Self {
43                allowed_discriminants: SignedEntityTypeDiscriminants::all(),
44                cardano_transactions_signing_config: Some(CardanoTransactionsSigningConfig::dummy()),
45            }
46        }
47    }
48
49    impl Dummy for CardanoTransactionsSigningConfig {
50        /// Return a dummy [CardanoTransactionsSigningConfig] (test-only).
51        fn dummy() -> Self {
52            Self {
53                security_parameter: BlockNumber(0),
54                step: BlockNumber(15),
55            }
56        }
57    }
58
59    impl Dummy for SignedEntityType {
60        /// Return a dummy [SignedEntityType] (test-only).
61        fn dummy() -> Self {
62            Self::MithrilStakeDistribution(Epoch(5))
63        }
64    }
65
66    impl Dummy for SupportedEra {
67        /// Return a dummy [SupportedEra] (test-only).
68        fn dummy() -> Self {
69            Self::eras().first().unwrap().to_owned()
70        }
71    }
72
73    impl Dummy for TimePoint {
74        /// Return a dummy [TimePoint] (test-only).
75        fn dummy() -> Self {
76            Self::new(10, 100, ChainPoint::dummy())
77        }
78    }
79
80    impl Dummy for ClientError {
81        /// Return a dummy [ClientError] (test-only).
82        fn dummy() -> Self {
83            Self::new("error", "error message")
84        }
85    }
86
87    impl Dummy for ServerError {
88        /// Return a dummy [ServerError] (test-only).
89        fn dummy() -> Self {
90            Self::new("error")
91        }
92    }
93}
94
95mod messages {
96    use std::collections::BTreeSet;
97
98    use chrono::Duration;
99
100    use mithril_stm::AggregateSignatureType;
101
102    use crate::entities::{
103        AncillaryLocation, BlockNumber, CardanoDbBeacon, CardanoTransactionsSetProof,
104        CardanoTransactionsSigningConfig, CompressionAlgorithm, DigestLocation, Epoch,
105        ImmutablesLocation, MultiFilesUri, ProtocolMessage, ProtocolMessagePartKey,
106        ProtocolParameters, SignedEntityType, SignedEntityTypeDiscriminants, StakeDistribution,
107        StakeDistributionParty, SupportedEra, TemplateUri,
108    };
109    use crate::messages::*;
110
111    use super::*;
112
113    impl Dummy for CardanoTransactionsSetProofMessagePart {
114        /// Return a dummy [CardanoTransactionsSetProofMessagePart] (test-only).
115        fn dummy() -> Self {
116            CardanoTransactionsSetProof::dummy().try_into().unwrap()
117        }
118    }
119
120    impl Dummy for CertificateMetadataMessagePart {
121        /// Return a dummy [CertificateMetadataMessagePart] (test-only).
122        fn dummy() -> Self {
123            let initiated_at = DateTime::parse_from_rfc3339("2024-02-12T13:11:47Z")
124                .unwrap()
125                .with_timezone(&Utc);
126
127            Self {
128                network: "testnet".to_string(),
129                protocol_version: "0.1.0".to_string(),
130                protocol_parameters: ProtocolParameters::new(1000, 100, 0.123),
131                initiated_at,
132                sealed_at: initiated_at + Duration::try_seconds(100).unwrap(),
133                signers: vec![
134                    StakeDistributionParty {
135                        party_id: "1".to_string(),
136                        stake: 10,
137                    },
138                    StakeDistributionParty {
139                        party_id: "2".to_string(),
140                        stake: 20,
141                    },
142                ],
143            }
144        }
145    }
146
147    impl Dummy for SignerWithStakeMessagePart {
148        /// Return a dummy [SignerWithStakeMessagePart] (test-only).
149        fn dummy() -> Self {
150            Self {
151                party_id: "pool1m8crhnqj5k2kyszf5j2scshupystyxc887zdfrpzh6ty6eun4fx".to_string(),
152                verification_key: fake_keys::signer_verification_key()[0].to_string(),
153                verification_key_signature: Some(
154                    fake_keys::signer_verification_key_signature()[0].to_string(),
155                ),
156                operational_certificate: Some(fake_keys::operational_certificate()[0].to_string()),
157                kes_period: Some(6),
158                stake: 234,
159            }
160        }
161    }
162
163    impl Dummy for SignerMessagePart {
164        /// Return a dummy [SignerMessagePart] (test-only).
165        fn dummy() -> Self {
166            Self {
167                party_id: "pool1m8crhnqj5k2kyszf5j2scshupystyxc887zdfrpzh6ty6eun4fx".to_string(),
168                verification_key: fake_keys::signer_verification_key()[0].to_string(),
169                verification_key_signature: Some(
170                    fake_keys::signer_verification_key_signature()[0].to_string(),
171                ),
172                operational_certificate: Some(fake_keys::operational_certificate()[0].to_string()),
173                kes_period: Some(6),
174            }
175        }
176    }
177
178    impl Dummy for AggregatorFeaturesMessage {
179        /// Return a dummy [AggregatorFeaturesMessage] (test-only).
180        fn dummy() -> Self {
181            AggregatorFeaturesMessage {
182                open_api_version: "0.0.1".to_string(),
183                documentation_url: "https://example.com".to_string(),
184                capabilities: AggregatorCapabilities {
185                    signed_entity_types: BTreeSet::from([
186                        SignedEntityTypeDiscriminants::MithrilStakeDistribution,
187                    ]),
188                    aggregate_signature_type: AggregateSignatureType::Concatenation,
189                    cardano_transactions_prover: None,
190                },
191            }
192        }
193    }
194
195    impl Dummy for AggregatorStatusMessage {
196        /// Return a dummy [AggregatorStatusMessage] (test-only).
197        fn dummy() -> Self {
198            AggregatorStatusMessage {
199                epoch: Epoch(10),
200                cardano_era: "conway".to_string(),
201                cardano_network: "devnet".to_string(),
202                mithril_era: SupportedEra::Pythagoras,
203                cardano_node_version: "10.4.1".to_string(),
204                aggregator_node_version: "0.6.24".to_string(),
205                protocol_parameters: ProtocolParameters::new(1000, 100, 0.123),
206                next_protocol_parameters: ProtocolParameters::new(2000, 200, 0.321),
207                total_signers: 10,
208                total_next_signers: 15,
209                total_stakes_signers: 100_000,
210                total_next_stakes_signers: 150_000,
211                total_cardano_spo: 100,
212                total_cardano_stake: 1_000_000,
213            }
214        }
215    }
216
217    impl Dummy for CardanoDatabaseSnapshotMessage {
218        /// Return a dummy [CardanoDatabaseSnapshotMessage] (test-only).
219        fn dummy() -> Self {
220            Self {
221                hash: "d4071d518a3ace0f6c04a9c0745b9e9560e3e2af1b373bafc4e0398423e9abfb"
222                    .to_string(),
223                merkle_root: "c8224920b9f5ad7377594eb8a15f34f08eb3103cc5241d57cafc5638403ec7c6"
224                    .to_string(),
225                network: "preview".to_string(),
226                beacon: CardanoDbBeacon {
227                    epoch: Epoch(123),
228                    immutable_file_number: 2345,
229                },
230                certificate_hash:
231                    "f6c01b373bafc4e039844071d5da3ace4a9c0745b9e9560e3e2af01823e9abfb".to_string(),
232                total_db_size_uncompressed: 800796318,
233                created_at: DateTime::parse_from_rfc3339("2023-01-19T13:43:05.618857482Z")
234                    .unwrap()
235                    .with_timezone(&Utc),
236                digests: DigestsMessagePart {
237                    size_uncompressed: 1024,
238                    locations: vec![DigestLocation::Aggregator {
239                        uri: "https://host-1/digest-1".to_string(),
240                    }],
241                },
242                immutables: ImmutablesMessagePart {
243                    average_size_uncompressed: 512,
244                    locations: vec![
245                        ImmutablesLocation::CloudStorage {
246                            uri: MultiFilesUri::Template(TemplateUri(
247                                "https://host-1/immutables-2".to_string(),
248                            )),
249                            compression_algorithm: Some(CompressionAlgorithm::Gzip),
250                        },
251                        ImmutablesLocation::CloudStorage {
252                            uri: MultiFilesUri::Template(TemplateUri(
253                                "https://host-2/immutables-2".to_string(),
254                            )),
255                            compression_algorithm: Some(CompressionAlgorithm::Gzip),
256                        },
257                    ],
258                },
259                ancillary: AncillaryMessagePart {
260                    size_uncompressed: 2048,
261                    locations: vec![AncillaryLocation::CloudStorage {
262                        uri: "https://host-1/ancillary-3".to_string(),
263                        compression_algorithm: Some(CompressionAlgorithm::Gzip),
264                    }],
265                },
266                cardano_node_version: "0.0.1".to_string(),
267            }
268        }
269    }
270
271    impl Dummy for CardanoDatabaseDigestListItemMessage {
272        /// Return a dummy [CardanoDatabaseDigestListItemMessage] (test-only).
273        fn dummy() -> Self {
274            Self {
275                immutable_file_name: "06685.chunk".to_string(),
276                digest: "0af556ab2620dd9363bf76963a231abe8948a500ea6be31b131d87907ab09b1e"
277                    .to_string(),
278            }
279        }
280    }
281
282    impl Dummy for CardanoDatabaseImmutableFilesRestoredMessage {
283        /// Return a dummy [CardanoDatabaseImmutableFilesRestoredMessage] (test-only).
284        fn dummy() -> Self {
285            Self {
286                nb_immutable_files: 34,
287            }
288        }
289    }
290
291    impl Dummy for CardanoDatabaseSnapshotListItemMessage {
292        /// Return a dummy [CardanoDatabaseSnapshotListItemMessage] (test-only).
293        fn dummy() -> Self {
294            Self {
295                hash: "d4071d518a3ace0f6c04a9c0745b9e9560e3e2af1b373bafc4e0398423e9abfb"
296                    .to_string(),
297                merkle_root: "c8224920b9f5ad7377594eb8a15f34f08eb3103cc5241d57cafc5638403ec7c6"
298                    .to_string(),
299                beacon: CardanoDbBeacon {
300                    epoch: Epoch(123),
301                    immutable_file_number: 2345,
302                },
303                certificate_hash:
304                    "f6c01b373bafc4e039844071d5da3ace4a9c0745b9e9560e3e2af01823e9abfb".to_string(),
305                total_db_size_uncompressed: 800796318,
306                created_at: DateTime::parse_from_rfc3339("2023-01-19T13:43:05.618857482Z")
307                    .unwrap()
308                    .with_timezone(&Utc),
309                cardano_node_version: "0.0.1".to_string(),
310            }
311        }
312    }
313
314    impl Dummy for CardanoStakeDistributionMessage {
315        /// Return a dummy [CardanoStakeDistributionMessage] (test-only).
316        fn dummy() -> Self {
317            Self {
318                epoch: Epoch(1),
319                hash: "hash-123".to_string(),
320                certificate_hash: "cert-hash-123".to_string(),
321                stake_distribution: StakeDistribution::from([("pool-123".to_string(), 1000)]),
322                created_at: DateTime::parse_from_rfc3339("2024-07-29T16:15:05.618857482Z")
323                    .unwrap()
324                    .with_timezone(&Utc),
325            }
326        }
327    }
328
329    impl Dummy for CardanoStakeDistributionListItemMessage {
330        /// Return a dummy [CardanoStakeDistributionListItemMessage] (test-only).
331        fn dummy() -> Self {
332            Self {
333                epoch: Epoch(1),
334                hash: "hash-123".to_string(),
335                certificate_hash: "certificate-hash-123".to_string(),
336                created_at: DateTime::parse_from_rfc3339("2024-07-29T16:15:05.618857482Z")
337                    .unwrap()
338                    .with_timezone(&Utc),
339            }
340        }
341    }
342
343    impl Dummy for CardanoTransactionSnapshotMessage {
344        /// Return a dummy [CertificateMessage] (test-only).
345        fn dummy() -> Self {
346            Self {
347                merkle_root: "mkroot-123".to_string(),
348                epoch: Epoch(10),
349                block_number: BlockNumber(100),
350                hash: "hash-123".to_string(),
351                certificate_hash: "cert-hash-123".to_string(),
352                created_at: DateTime::parse_from_rfc3339("2023-01-19T13:43:05.618857482Z")
353                    .unwrap()
354                    .with_timezone(&Utc),
355            }
356        }
357    }
358
359    impl Dummy for CardanoTransactionSnapshotListItemMessage {
360        /// Return a dummy [CertificateMessage] (test-only).
361        fn dummy() -> Self {
362            Self {
363                merkle_root: "mkroot-123".to_string(),
364                epoch: Epoch(10),
365                block_number: BlockNumber(100),
366                hash: "hash-123".to_string(),
367                certificate_hash: "cert-hash-123".to_string(),
368                created_at: DateTime::parse_from_rfc3339("2023-01-19T13:43:05.618857482Z")
369                    .unwrap()
370                    .with_timezone(&Utc),
371            }
372        }
373    }
374
375    impl Dummy for CertificateMessage {
376        /// Return a dummy [CertificateMessage] (test-only).
377        fn dummy() -> Self {
378            let mut protocol_message = ProtocolMessage::new();
379            protocol_message.set_message_part(
380                ProtocolMessagePartKey::SnapshotDigest,
381                "snapshot-digest-123".to_string(),
382            );
383            protocol_message.set_message_part(
384                ProtocolMessagePartKey::NextAggregateVerificationKey,
385                fake_keys::aggregate_verification_key()[1].to_owned(),
386            );
387            let epoch = Epoch(10);
388
389            Self {
390                hash: "hash".to_string(),
391                previous_hash: "previous_hash".to_string(),
392                epoch,
393                signed_entity_type: SignedEntityType::MithrilStakeDistribution(epoch),
394                metadata: CertificateMetadataMessagePart::dummy(),
395                protocol_message: protocol_message.clone(),
396                signed_message: "signed_message".to_string(),
397                aggregate_verification_key: fake_keys::aggregate_verification_key()[0].to_owned(),
398                multi_signature: fake_keys::multi_signature()[0].to_owned(),
399                genesis_signature: String::new(),
400            }
401        }
402    }
403
404    impl Dummy for CertificateListItemMessage {
405        /// Return a dummy [CertificateListItemMessage] (test-only).
406        fn dummy() -> Self {
407            let mut protocol_message = ProtocolMessage::new();
408            protocol_message.set_message_part(
409                ProtocolMessagePartKey::SnapshotDigest,
410                "snapshot-digest-123".to_string(),
411            );
412            protocol_message.set_message_part(
413                ProtocolMessagePartKey::NextAggregateVerificationKey,
414                "next-avk-123".to_string(),
415            );
416            let epoch = Epoch(10);
417
418            Self {
419                hash: "hash".to_string(),
420                previous_hash: "previous_hash".to_string(),
421                epoch,
422                signed_entity_type: SignedEntityType::MithrilStakeDistribution(epoch),
423                metadata: CertificateListItemMessageMetadata {
424                    network: "testnet".to_string(),
425                    protocol_version: "0.1.0".to_string(),
426                    protocol_parameters: ProtocolParameters::new(1000, 100, 0.123),
427                    initiated_at: DateTime::parse_from_rfc3339("2024-02-12T13:11:47Z")
428                        .unwrap()
429                        .with_timezone(&Utc),
430                    sealed_at: DateTime::parse_from_rfc3339("2024-02-12T13:12:57Z")
431                        .unwrap()
432                        .with_timezone(&Utc),
433                    total_signers: 2,
434                },
435                protocol_message: protocol_message.clone(),
436                signed_message: "signed_message".to_string(),
437                aggregate_verification_key: "aggregate_verification_key".to_string(),
438            }
439        }
440    }
441
442    impl Dummy for EpochSettingsMessage {
443        /// Return a dummy [EpochSettingsMessage] (test-only).
444        fn dummy() -> Self {
445            #[allow(deprecated)]
446            Self {
447                epoch: Epoch(10),
448                signer_registration_protocol_parameters: Some(ProtocolParameters {
449                    k: 5,
450                    m: 100,
451                    phi_f: 0.65,
452                }),
453                current_signers: [SignerMessagePart::dummy()].to_vec(),
454                next_signers: [SignerMessagePart::dummy()].to_vec(),
455                cardano_transactions_signing_config: Some(CardanoTransactionsSigningConfig::dummy()),
456            }
457        }
458    }
459
460    impl Dummy for ProtocolConfigurationMessage {
461        /// Return a dummy [ProtocolConfigurationMessage] (test-only).
462        fn dummy() -> Self {
463            Self {
464                protocol_parameters: ProtocolParameters {
465                    k: 5,
466                    m: 100,
467                    phi_f: 0.65,
468                },
469                cardano_transactions_signing_config: Some(CardanoTransactionsSigningConfig::dummy()),
470                available_signed_entity_types: SignedEntityTypeDiscriminants::all(),
471            }
472        }
473    }
474
475    impl Dummy for MithrilStakeDistributionMessage {
476        /// Return a dummy [MithrilStakeDistributionMessage] (test-only).
477        fn dummy() -> Self {
478            Self {
479                epoch: Epoch(1),
480                signers_with_stake: vec![SignerWithStakeMessagePart::dummy()],
481                hash: "hash-123".to_string(),
482                certificate_hash: "cert-hash-123".to_string(),
483                created_at: DateTime::parse_from_rfc3339("2023-01-19T13:43:05.618857482Z")
484                    .unwrap()
485                    .with_timezone(&Utc),
486                protocol_parameters: fake_data::protocol_parameters(),
487            }
488        }
489    }
490
491    impl Dummy for MithrilStakeDistributionListItemMessage {
492        /// Return a dummy [MithrilStakeDistributionListItemMessage] (test-only).
493        fn dummy() -> Self {
494            Self {
495                epoch: Epoch(1),
496                hash: "hash-123".to_string(),
497                certificate_hash: "certificate-hash-123".to_string(),
498                created_at: DateTime::parse_from_rfc3339("2023-01-19T13:43:05.618857482Z")
499                    .unwrap()
500                    .with_timezone(&Utc),
501            }
502        }
503    }
504
505    impl Dummy for RegisterSignatureMessageHttp {
506        /// Return a dummy [RegisterSignatureMessageHttp] (test-only).
507        fn dummy() -> Self {
508            use crate::entities::Epoch;
509            Self {
510                signed_entity_type: SignedEntityType::MithrilStakeDistribution(Epoch(5)),
511                party_id: "party_id".to_string(),
512                signature: fake_keys::single_signature()[0].to_string(),
513                won_indexes: vec![1, 3],
514                signed_message: "6a7e737c312972d2346b65ac3075696e04286d046dddaf8004121e3d5e27cc0d"
515                    .to_string(),
516            }
517        }
518    }
519
520    impl Dummy for RegisterSignatureMessageDmq {
521        /// Return a dummy [RegisterSignatureMessageDmq] (test-only).
522        fn dummy() -> Self {
523            use crate::entities::Epoch;
524            Self {
525                signed_entity_type: SignedEntityType::MithrilStakeDistribution(Epoch(5)),
526                signature: fake_keys::single_signature()[0].try_into().unwrap(),
527            }
528        }
529    }
530
531    impl Dummy for RegisterSignerMessage {
532        /// Return a dummy [RegisterSignerMessage] (test-only).
533        fn dummy() -> Self {
534            Self {
535                epoch: Epoch(1),
536                party_id: "pool1m8crhnqj5k2kyszf5j2scshupystyxc887zdfrpzh6ty6eun4fx".to_string(),
537                verification_key: fake_keys::signer_verification_key()[0].to_string(),
538                verification_key_signature: Some(
539                    fake_keys::signer_verification_key_signature()[0].to_string(),
540                ),
541                operational_certificate: Some(fake_keys::operational_certificate()[0].to_string()),
542                kes_period: Some(6),
543            }
544        }
545    }
546
547    impl Dummy for SnapshotMessage {
548        /// Return a dummy [SnapshotMessage] (test-only).
549        fn dummy() -> Self {
550            Self {
551                digest: "0b9f5ad7f33cc523775c82249294eb8a1541d54f08eb3107cafc5638403ec7c6"
552                    .to_string(),
553                network: "preview".to_string(),
554                beacon: CardanoDbBeacon {
555                    epoch: Epoch(86),
556                    immutable_file_number: 1728,
557                },
558                certificate_hash:
559                    "d5daf6c03ace4a9c074e951844075b9b373bafc4e039160e3e2af01823e9abfb".to_string(),
560                size: 807803196,
561                ancillary_size: Some(123456789),
562                created_at: DateTime::parse_from_rfc3339("2023-01-19T13:43:05.618857482Z")
563                    .unwrap()
564                    .with_timezone(&Utc),
565                locations: vec!["https://host/certificate.tar.gz".to_string()],
566                ancillary_locations: Some(vec!["https://host/ancillary.tar.gz".to_string()]),
567                compression_algorithm: CompressionAlgorithm::Gzip,
568                cardano_node_version: "0.0.1".to_string(),
569            }
570        }
571    }
572
573    impl Dummy for SnapshotDownloadMessage {
574        /// Return a dummy [SnapshotDownloadMessage] (test-only).
575        fn dummy() -> Self {
576            Self {
577                digest: "0b9f5ad7f33cc523775c82249294eb8a1541d54f08eb3107cafc5638403ec7c6"
578                    .to_string(),
579                network: "preview".to_string(),
580                beacon: CardanoDbBeacon {
581                    epoch: Epoch(86),
582                    immutable_file_number: 1728,
583                },
584                size: 807803196,
585                ancillary_size: Some(123456789),
586                locations: vec!["https://host/certificate.tar.gz".to_string()],
587                ancillary_locations: Some(vec!["https://host/ancillary.tar.gz".to_string()]),
588                compression_algorithm: CompressionAlgorithm::Gzip,
589                cardano_node_version: "0.0.1".to_string(),
590            }
591        }
592    }
593
594    impl Dummy for SnapshotListItemMessage {
595        /// Return a dummy [SnapshotListItemMessage] (test-only).
596        fn dummy() -> Self {
597            Self {
598                digest: "0b9f5ad7f33cc523775c82249294eb8a1541d54f08eb3107cafc5638403ec7c6"
599                    .to_string(),
600                network: "preview".to_string(),
601                beacon: CardanoDbBeacon {
602                    epoch: Epoch(86),
603                    immutable_file_number: 1728,
604                },
605                certificate_hash:
606                    "d5daf6c03ace4a9c074e951844075b9b373bafc4e039160e3e2af01823e9abfb".to_string(),
607                size: 807803196,
608                ancillary_size: Some(123456789),
609                created_at: DateTime::parse_from_rfc3339("2023-01-19T13:43:05.618857482Z")
610                    .unwrap()
611                    .with_timezone(&Utc),
612                locations: vec!["https://host/certificate.tar.gz".to_string()],
613                ancillary_locations: Some(vec!["https://host/ancillary.tar.gz".to_string()]),
614                compression_algorithm: CompressionAlgorithm::default(),
615                cardano_node_version: "0.0.1".to_string(),
616            }
617        }
618    }
619}
620
621mod signable_builder {
622    use crate::entities::{
623        CardanoDbBeacon, CardanoStakeDistribution, CardanoTransactionsSnapshot, Epoch,
624        MithrilStakeDistribution, SignedEntityType, Snapshot,
625    };
626    use crate::signable_builder::SignedEntity;
627
628    use super::*;
629
630    impl Dummy for SignedEntity<Snapshot> {
631        /// Create a dummy [SignedEntity] for [Snapshot] entity
632        fn dummy() -> Self {
633            SignedEntity {
634                signed_entity_id: "snapshot-id-123".to_string(),
635                signed_entity_type: SignedEntityType::CardanoImmutableFilesFull(
636                    CardanoDbBeacon::default(),
637                ),
638                certificate_id: "certificate-hash-123".to_string(),
639                artifact: fake_data::snapshot(1),
640                created_at: DateTime::parse_from_rfc3339("2023-01-19T13:43:05.618857482Z")
641                    .unwrap()
642                    .with_timezone(&Utc),
643            }
644        }
645    }
646
647    impl Dummy for SignedEntity<MithrilStakeDistribution> {
648        /// Create a dummy [SignedEntity] for [MithrilStakeDistribution] entity
649        fn dummy() -> Self {
650            SignedEntity {
651                signed_entity_id: "mithril-stake-distribution-id-123".to_string(),
652                signed_entity_type: SignedEntityType::MithrilStakeDistribution(Epoch(1)),
653                certificate_id: "certificate-hash-123".to_string(),
654                artifact: fake_data::mithril_stake_distribution(
655                    Epoch(1),
656                    fake_data::signers_with_stakes(5),
657                ),
658                created_at: DateTime::parse_from_rfc3339("2023-01-19T13:43:05.618857482Z")
659                    .unwrap()
660                    .with_timezone(&Utc),
661            }
662        }
663    }
664
665    impl Dummy for SignedEntity<CardanoTransactionsSnapshot> {
666        /// Create a dummy [SignedEntity] for [CardanoTransactionsSnapshot] entity
667        fn dummy() -> Self {
668            let block_number = crate::entities::BlockNumber(50);
669            SignedEntity {
670                signed_entity_id: "snapshot-id-123".to_string(),
671                signed_entity_type: SignedEntityType::CardanoTransactions(Epoch(5), block_number),
672                certificate_id: "certificate-hash-123".to_string(),
673                artifact: CardanoTransactionsSnapshot::new("mkroot123".to_string(), block_number),
674                created_at: DateTime::parse_from_rfc3339("2023-01-19T13:43:05.618857482Z")
675                    .unwrap()
676                    .with_timezone(&Utc),
677            }
678        }
679    }
680
681    impl Dummy for SignedEntity<CardanoStakeDistribution> {
682        /// Create a dummy [SignedEntity] for [CardanoStakeDistribution] entity
683        fn dummy() -> Self {
684            SignedEntity {
685                signed_entity_id: "cardano-stake-distribution-id-123".to_string(),
686                signed_entity_type: SignedEntityType::CardanoStakeDistribution(Epoch(1)),
687                certificate_id: "certificate-hash-123".to_string(),
688                artifact: fake_data::cardano_stake_distribution(Epoch(1)),
689                created_at: DateTime::parse_from_rfc3339("2024-07-29T16:15:05.618857482Z")
690                    .unwrap()
691                    .with_timezone(&Utc),
692            }
693        }
694    }
695}