mithril_common/test_utils/
fake_data.rs

1//! Fake data builders for testing.
2
3use chrono::{DateTime, Utc};
4use semver::Version;
5
6use crate::crypto_helper::{self, ProtocolMultiSignature};
7use crate::entities::{
8    self, AncillaryLocations, BlockNumber, CardanoDatabaseSnapshotArtifactData,
9    CertificateMetadata, CertificateSignature, CompressionAlgorithm, DigestsLocations, Epoch,
10    ImmutablesLocations, LotteryIndex, ProtocolMessage, ProtocolMessagePartKey, SignedEntityType,
11    SingleSignatures, SlotNumber, StakeDistribution, StakeDistributionParty,
12};
13use crate::test_utils::MithrilFixtureBuilder;
14use crate::CardanoNetwork;
15
16use super::fake_keys;
17
18/// Fake network
19pub fn network() -> crate::CardanoNetwork {
20    crate::CardanoNetwork::DevNet(10)
21}
22
23/// Fake Beacon
24pub fn beacon() -> entities::CardanoDbBeacon {
25    let time_point = entities::TimePoint::dummy();
26    entities::CardanoDbBeacon::new(*time_point.epoch, time_point.immutable_file_number)
27}
28
29/// Fake ChainPoint
30pub fn chain_point() -> entities::ChainPoint {
31    entities::ChainPoint {
32        slot_number: SlotNumber(500),
33        block_number: BlockNumber(42),
34        block_hash: "1b69b3202fbe500".to_string(),
35    }
36}
37
38/// Fake ProtocolParameters
39pub fn protocol_parameters() -> entities::ProtocolParameters {
40    let k = 5;
41    let m = 100;
42    let phi_f = 0.65;
43    entities::ProtocolParameters::new(k, m, phi_f)
44}
45
46/// Fake ProtocolInitializer
47pub fn protocol_initializer<S: Into<String>>(
48    seed: S,
49    stake: entities::Stake,
50) -> crypto_helper::ProtocolInitializer {
51    use rand_chacha::ChaCha20Rng;
52    use rand_core::SeedableRng;
53
54    let protocol_parameters = protocol_parameters();
55    let seed: [u8; 32] = format!("{:<032}", seed.into()).as_bytes()[..32]
56        .try_into()
57        .unwrap();
58    let mut rng = ChaCha20Rng::from_seed(seed);
59    let kes_secret_key_path: Option<std::path::PathBuf> = None;
60    let kes_period = Some(0);
61
62    crypto_helper::ProtocolInitializer::setup(
63        protocol_parameters.into(),
64        kes_secret_key_path,
65        kes_period,
66        stake,
67        &mut rng,
68    )
69    .unwrap()
70}
71
72/// Fake Genesis Certificate
73pub fn genesis_certificate<T: Into<String>>(certificate_hash: T) -> entities::Certificate {
74    let multi_signature = fake_keys::genesis_signature()[1].to_string();
75
76    entities::Certificate {
77        previous_hash: String::new(),
78        signature: CertificateSignature::GenesisSignature(multi_signature.try_into().unwrap()),
79        ..certificate(certificate_hash)
80    }
81}
82
83/// Fake Certificate
84pub fn certificate<T: Into<String>>(certificate_hash: T) -> entities::Certificate {
85    let hash = certificate_hash.into();
86
87    // Beacon
88    let beacon = beacon();
89
90    // Protocol parameters
91    let protocol_parameters = protocol_parameters();
92
93    // Signers with stakes
94    let signers: Vec<StakeDistributionParty> = signers_with_stakes(5)
95        .into_iter()
96        .map(|s| s.into())
97        .collect();
98
99    // Certificate metadata
100    let protocol_version = crypto_helper::PROTOCOL_VERSION.to_string();
101    let initiated_at = DateTime::parse_from_rfc3339("2006-01-02T15:04:05Z")
102        .unwrap()
103        .with_timezone(&Utc);
104    let sealed_at = DateTime::parse_from_rfc3339("2006-01-02T15:04:05Z")
105        .unwrap()
106        .with_timezone(&Utc);
107    let metadata = CertificateMetadata::new(
108        network(),
109        protocol_version,
110        protocol_parameters,
111        initiated_at,
112        sealed_at,
113        signers,
114    );
115
116    // Protocol message
117    let next_aggregate_verification_key = fake_keys::aggregate_verification_key()[2].to_owned();
118    let mut protocol_message = ProtocolMessage::new();
119    let snapshot_digest = format!("1{}", beacon.immutable_file_number).repeat(20);
120    protocol_message.set_message_part(ProtocolMessagePartKey::SnapshotDigest, snapshot_digest);
121    protocol_message.set_message_part(
122        ProtocolMessagePartKey::NextAggregateVerificationKey,
123        next_aggregate_verification_key,
124    );
125
126    // Certificate
127    let previous_hash = format!("{hash}0");
128    let aggregate_verification_key = fake_keys::aggregate_verification_key()[1]
129        .try_into()
130        .unwrap();
131    let multi_signature: ProtocolMultiSignature =
132        fake_keys::multi_signature()[0].try_into().unwrap();
133
134    entities::Certificate {
135        hash,
136        previous_hash,
137        epoch: beacon.epoch,
138        metadata,
139        protocol_message,
140        signed_message: "".to_string(),
141        aggregate_verification_key,
142        signature: CertificateSignature::MultiSignature(
143            SignedEntityType::CardanoImmutableFilesFull(beacon),
144            multi_signature,
145        ),
146    }
147}
148
149/// Fake SignersWithStake
150pub fn signers_with_stakes(total: usize) -> Vec<entities::SignerWithStake> {
151    MithrilFixtureBuilder::default()
152        .with_signers(total)
153        .build()
154        .signers_with_stake()
155}
156
157/// Fake Signers
158pub fn signers(total: usize) -> Vec<entities::Signer> {
159    signers_with_stakes(total)
160        .into_iter()
161        .map(|signer| signer.into())
162        .collect::<Vec<entities::Signer>>()
163}
164
165/// Fake SingleSignatures
166pub fn single_signatures(won_indexes: Vec<LotteryIndex>) -> SingleSignatures {
167    let party_id = "party_id".to_string();
168    let signature = fake_keys::single_signature()[0].try_into().unwrap();
169
170    SingleSignatures::new(party_id, signature, won_indexes)
171}
172
173/// Fake Snapshots
174pub fn snapshots(total: u64) -> Vec<entities::Snapshot> {
175    (1..total + 1)
176        .map(|snapshot_id| {
177            let digest = format!("1{snapshot_id}").repeat(20);
178            let mut beacon = beacon();
179            beacon.immutable_file_number += snapshot_id;
180            let certificate_hash = "123".to_string();
181            let size = snapshot_id * 100_000;
182            let ancillary_size = snapshot_id * 10_000;
183            let cardano_node_version = Version::parse("1.0.0").unwrap();
184            let locations = vec![
185                format!("http://{certificate_hash}"),
186                format!("http2://{certificate_hash}"),
187            ];
188            let ancillary_locations = vec![
189                format!("http://ancillary-{certificate_hash}"),
190                format!("http2://ancillary-{certificate_hash}"),
191            ];
192
193            entities::Snapshot {
194                digest,
195                network: network().into(),
196                beacon,
197                size,
198                ancillary_size: Some(ancillary_size),
199                locations,
200                ancillary_locations: Some(ancillary_locations),
201                compression_algorithm: CompressionAlgorithm::Gzip,
202                cardano_node_version: cardano_node_version.to_string(),
203            }
204        })
205        .collect::<Vec<entities::Snapshot>>()
206}
207
208/// Fake Mithril Stake Distribution
209pub fn mithril_stake_distributions(total: u64) -> Vec<entities::MithrilStakeDistribution> {
210    let signers = signers_with_stakes(5);
211
212    (1..total + 1)
213        .map(|epoch_idx| entities::MithrilStakeDistribution {
214            epoch: Epoch(epoch_idx),
215            signers_with_stake: signers.clone(),
216            hash: format!("hash-epoch-{epoch_idx}"),
217            protocol_parameters: protocol_parameters(),
218        })
219        .collect::<Vec<entities::MithrilStakeDistribution>>()
220}
221
222/// Fake Cardano Transactions
223pub fn cardano_transactions_snapshot(total: u64) -> Vec<entities::CardanoTransactionsSnapshot> {
224    (1..total + 1)
225        .map(|idx| {
226            entities::CardanoTransactionsSnapshot::new(
227                format!("merkleroot-{idx}"),
228                BlockNumber(idx),
229            )
230        })
231        .collect()
232}
233
234/// Fake transaction hashes that have valid length & characters
235pub const fn transaction_hashes<'a>() -> [&'a str; 5] {
236    [
237        "c96809e2cecd9e27499a4379094c4e1f7b59d918c96327bd8daf1bf909dae332",
238        "5b8788784af9c414f18fc1e6161005b13b839fd91130b7c109aeba1792feb843",
239        "8b6ae44edf877ff2ac80cf067809d575ab2bad234b668f91e90decde837b154a",
240        "3f6f3c981c89097f62c9b43632875db7a52183ad3061c822d98259d18cd63dcf",
241        "f4fd91dccc25fd63f2caebab3d3452bc4b2944fcc11652214a3e8f1d32b09713",
242    ]
243}
244
245/// Fake Cardano Stake Distributions
246pub fn cardano_stake_distributions(total: u64) -> Vec<entities::CardanoStakeDistribution> {
247    (1..total + 1)
248        .map(|epoch_idx| cardano_stake_distribution(Epoch(epoch_idx)))
249        .collect::<Vec<entities::CardanoStakeDistribution>>()
250}
251
252/// Fake Cardano Stake Distribution
253pub fn cardano_stake_distribution(epoch: Epoch) -> entities::CardanoStakeDistribution {
254    let stake_distribution = StakeDistribution::from([("pool-1".to_string(), 100)]);
255    entities::CardanoStakeDistribution {
256        hash: format!("hash-epoch-{epoch}"),
257        epoch,
258        stake_distribution,
259    }
260}
261
262/// Fake Cardano Database snapshots
263pub fn cardano_database_snapshots(total: u64) -> Vec<entities::CardanoDatabaseSnapshot> {
264    (1..total + 1)
265        .map(|cardano_database_id| {
266            let merkle_root = format!("1{cardano_database_id}").repeat(20);
267            let mut beacon = beacon();
268            beacon.immutable_file_number += cardano_database_id;
269            let total_db_size_uncompressed = cardano_database_id * 100000;
270            let cardano_node_version = Version::parse("1.0.0").unwrap();
271
272            entities::CardanoDatabaseSnapshot::new(
273                merkle_root,
274                CardanoNetwork::DevNet(63),
275                beacon,
276                CardanoDatabaseSnapshotArtifactData {
277                    total_db_size_uncompressed,
278                    digests: DigestsLocations::default(),
279                    immutables: ImmutablesLocations::default(),
280                    ancillary: AncillaryLocations::default(),
281                },
282                &cardano_node_version,
283            )
284        })
285        .collect::<Vec<entities::CardanoDatabaseSnapshot>>()
286}