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