mithril_common/test/double/
fake_data.rs

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