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