snarkvm_console_network/
lib.rs1#![forbid(unsafe_code)]
17#![allow(clippy::too_many_arguments)]
18#![warn(clippy::cast_possible_truncation)]
19
20#[macro_use]
21extern crate lazy_static;
22
23pub use snarkvm_console_network_environment as environment;
24pub use snarkvm_console_network_environment::*;
25
26mod helpers;
27pub use helpers::*;
28
29mod canary_v0;
30pub use canary_v0::*;
31
32mod consensus_heights;
33pub use consensus_heights::*;
34
35mod mainnet_v0;
36pub use mainnet_v0::*;
37
38mod testnet_v0;
39
40pub use testnet_v0::*;
41
42pub mod prelude {
43 #[cfg(feature = "wasm")]
44 pub use crate::get_or_init_consensus_version_heights;
45 pub use crate::{
46 CANARY_V0_CONSENSUS_VERSION_HEIGHTS,
47 CanaryV0,
48 ConsensusVersion,
49 MAINNET_V0_CONSENSUS_VERSION_HEIGHTS,
50 MainnetV0,
51 Network,
52 TEST_CONSENSUS_VERSION_HEIGHTS,
53 TESTNET_V0_CONSENSUS_VERSION_HEIGHTS,
54 TestnetV0,
55 consensus_config_value,
56 consensus_config_value_by_version,
57 environment::prelude::*,
58 };
59}
60
61pub use crate::environment::prelude::*;
62
63use snarkvm_algorithms::{
64 AlgebraicSponge,
65 crypto_hash::PoseidonSponge,
66 snark::varuna::{CircuitProvingKey, CircuitVerifyingKey, VarunaHidingMode},
67 srs::{UniversalProver, UniversalVerifier},
68};
69use snarkvm_console_algorithms::{BHP512, BHP1024, Poseidon2, Poseidon4};
70use snarkvm_console_collections::merkle_tree::{MerklePath, MerkleTree};
71use snarkvm_console_types::{Field, Group, Scalar};
72use snarkvm_curves::PairingEngine;
73
74use indexmap::IndexMap;
75use std::sync::{Arc, OnceLock};
76
77pub type BHPMerkleTree<N, const DEPTH: u8> = MerkleTree<N, BHP1024<N>, BHP512<N>, DEPTH>;
79pub type PoseidonMerkleTree<N, const DEPTH: u8> = MerkleTree<N, Poseidon4<N>, Poseidon2<N>, DEPTH>;
81
82type Fq<N> = <<N as Environment>::PairingCurve as PairingEngine>::Fq;
84pub type FiatShamir<N> = PoseidonSponge<Fq<N>, 2, 1>;
85pub type FiatShamirParameters<N> = <FiatShamir<N> as AlgebraicSponge<Fq<N>, 2>>::Parameters;
86
87pub(crate) type VarunaProvingKey<N> = CircuitProvingKey<<N as Environment>::PairingCurve, VarunaHidingMode>;
89pub(crate) type VarunaVerifyingKey<N> = CircuitVerifyingKey<<N as Environment>::PairingCurve>;
90
91static CONSENSUS_VERSION_HEIGHTS: OnceLock<[(ConsensusVersion, u32); NUM_CONSENSUS_VERSIONS]> = OnceLock::new();
93
94pub trait Network:
95 'static
96 + Environment
97 + Copy
98 + Clone
99 + Debug
100 + Eq
101 + PartialEq
102 + core::hash::Hash
103 + Serialize
104 + DeserializeOwned
105 + for<'a> Deserialize<'a>
106 + Send
107 + Sync
108{
109 const ID: u16;
111 const NAME: &'static str;
113 const SHORT_NAME: &'static str;
115
116 const INCLUSION_FUNCTION_NAME: &'static str;
118
119 const GENESIS_TIMESTAMP: i64;
121 const GENESIS_COINBASE_TARGET: u64;
123 const GENESIS_PROOF_TARGET: u64;
125 const MAX_SOLUTIONS_AS_POWER_OF_TWO: u8 = 2; const MAX_SOLUTIONS: usize = 1 << Self::MAX_SOLUTIONS_AS_POWER_OF_TWO; const STARTING_SUPPLY: u64 = 1_500_000_000_000_000; const DEPLOYMENT_FEE_MULTIPLIER: u64 = 1_000; const CONSTRUCTOR_FEE_MULTIPLIER: u64 = 100; const EXECUTION_STORAGE_FEE_SCALING_FACTOR: u64 = 5000;
138 const EXECUTION_STORAGE_PENALTY_THRESHOLD: u64 = 5000;
140 const SYNTHESIS_FEE_MULTIPLIER: u64 = 25; const MAX_DEPLOYMENT_VARIABLES: u64 = 1 << 21; const MAX_DEPLOYMENT_CONSTRAINTS: u64 = 1 << 21; const MAX_FEE: u64 = 1_000_000_000_000_000;
148 const TRANSACTION_SPEND_LIMIT: [(ConsensusVersion, u64); 2] =
151 [(ConsensusVersion::V1, 100_000_000), (ConsensusVersion::V10, 4_000_000)];
152 const ARC_0005_COMPUTE_DISCOUNT: u64 = 25;
154
155 const ANCHOR_HEIGHT: u32 = Self::ANCHOR_TIME as u32 / Self::BLOCK_TIME as u32;
157 const ANCHOR_TIME: u16 = 25;
159 const BLOCK_TIME: u16 = 10;
161 const NUM_BLOCKS_PER_EPOCH: u32 = 3600 / Self::BLOCK_TIME as u32; const MAX_DATA_ENTRIES: usize = 32;
166 const MAX_DATA_DEPTH: usize = 32;
169 #[allow(clippy::cast_possible_truncation)]
171 const MAX_DATA_SIZE_IN_FIELDS: u32 = ((128 * 1024 * 8) / Field::<Self>::SIZE_IN_DATA_BITS) as u32;
172
173 const MIN_STRUCT_ENTRIES: usize = 1; const MAX_STRUCT_ENTRIES: usize = Self::MAX_DATA_ENTRIES;
177
178 const MIN_ARRAY_ELEMENTS: usize = 1; const MAX_ARRAY_ELEMENTS: usize = 512;
182
183 const MIN_RECORD_ENTRIES: usize = 1; const MAX_RECORD_ENTRIES: usize = Self::MIN_RECORD_ENTRIES.saturating_add(Self::MAX_DATA_ENTRIES);
187
188 const MAX_PROGRAM_SIZE: usize = 100_000; const MAX_MAPPINGS: usize = 31;
193 const MAX_FUNCTIONS: usize = 31;
195 const MAX_STRUCTS: usize = 10 * Self::MAX_FUNCTIONS;
197 const MAX_RECORDS: usize = 10 * Self::MAX_FUNCTIONS;
199 const MAX_CLOSURES: usize = 2 * Self::MAX_FUNCTIONS;
201 const MAX_OPERANDS: usize = Self::MAX_INPUTS;
203 const MAX_INSTRUCTIONS: usize = u16::MAX as usize;
205 const MAX_COMMANDS: usize = u16::MAX as usize;
207 const MAX_WRITES: u16 = 16;
209 const MAX_POSITIONS: usize = u8::MAX as usize;
211
212 const MAX_INPUTS: usize = 16;
214 const MAX_OUTPUTS: usize = 16;
216
217 const MAX_IMPORTS: usize = 64;
219
220 const MAX_TRANSACTION_SIZE: usize = 128_000; type StateRoot: Bech32ID<Field<Self>>;
226 type BlockHash: Bech32ID<Field<Self>>;
228 type RatificationID: Bech32ID<Field<Self>>;
230 type TransactionID: Bech32ID<Field<Self>>;
232 type TransitionID: Bech32ID<Field<Self>>;
234 type TransmissionChecksum: IntegerType;
236
237 const _CONSENSUS_VERSION_HEIGHTS: [(ConsensusVersion, u32); NUM_CONSENSUS_VERSIONS];
241
242 const MAX_CERTIFICATES: [(ConsensusVersion, u16); 5];
248
249 #[allow(non_snake_case)]
251 #[cfg(not(any(test, feature = "test", feature = "test_consensus_heights")))]
252 fn CONSENSUS_VERSION_HEIGHTS() -> &'static [(ConsensusVersion, u32); NUM_CONSENSUS_VERSIONS] {
253 CONSENSUS_VERSION_HEIGHTS.get_or_init(|| Self::_CONSENSUS_VERSION_HEIGHTS)
255 }
256 #[allow(non_snake_case)]
258 #[cfg(any(test, feature = "test", feature = "test_consensus_heights"))]
259 fn CONSENSUS_VERSION_HEIGHTS() -> &'static [(ConsensusVersion, u32); NUM_CONSENSUS_VERSIONS] {
260 CONSENSUS_VERSION_HEIGHTS.get_or_init(load_test_consensus_heights)
261 }
262
263 #[allow(non_snake_case)]
265 #[cfg(any(test, feature = "test", feature = "test_consensus_heights"))]
266 const TEST_CONSENSUS_VERSION_HEIGHTS: [(ConsensusVersion, u32); NUM_CONSENSUS_VERSIONS] =
267 TEST_CONSENSUS_VERSION_HEIGHTS;
268 #[allow(non_snake_case)]
270 fn CONSENSUS_VERSION(seek_height: u32) -> anyhow::Result<ConsensusVersion> {
271 match Self::CONSENSUS_VERSION_HEIGHTS().binary_search_by(|(_, height)| height.cmp(&seek_height)) {
272 Ok(index) => Ok(Self::CONSENSUS_VERSION_HEIGHTS()[index].0),
274 Err(index) => {
276 if index == 0 {
277 Err(anyhow!("Expected consensus version 1 to exist at height 0."))
278 } else {
279 Ok(Self::CONSENSUS_VERSION_HEIGHTS()[index - 1].0)
281 }
282 }
283 }
284 }
285 #[allow(non_snake_case)]
287 fn CONSENSUS_HEIGHT(version: ConsensusVersion) -> Result<u32> {
288 Ok(Self::CONSENSUS_VERSION_HEIGHTS().get(version as usize - 1).ok_or(anyhow!("Invalid consensus version"))?.1)
289 }
290 #[allow(non_snake_case)]
292 fn LATEST_MAX_CERTIFICATES() -> Result<u16> {
293 Self::MAX_CERTIFICATES.last().map_or(Err(anyhow!("No MAX_CERTIFICATES defined.")), |(_, value)| Ok(*value))
294 }
295
296 #[allow(non_snake_case)]
298 fn INCLUSION_UPGRADE_HEIGHT() -> Result<u32>;
299
300 fn genesis_bytes() -> &'static [u8];
302
303 fn restrictions_list_as_str() -> &'static str;
305
306 fn get_credits_v0_proving_key(function_name: String) -> Result<&'static Arc<VarunaProvingKey<Self>>>;
308
309 fn get_credits_v0_verifying_key(function_name: String) -> Result<&'static Arc<VarunaVerifyingKey<Self>>>;
311
312 fn get_credits_proving_key(function_name: String) -> Result<&'static Arc<VarunaProvingKey<Self>>>;
314
315 fn get_credits_verifying_key(function_name: String) -> Result<&'static Arc<VarunaVerifyingKey<Self>>>;
317
318 #[cfg(not(feature = "wasm"))]
319 fn inclusion_v0_proving_key() -> &'static Arc<VarunaProvingKey<Self>>;
321
322 #[cfg(feature = "wasm")]
323 fn inclusion_v0_proving_key(bytes: Option<Vec<u8>>) -> &'static Arc<VarunaProvingKey<Self>>;
325
326 fn inclusion_v0_verifying_key() -> &'static Arc<VarunaVerifyingKey<Self>>;
328
329 #[cfg(not(feature = "wasm"))]
330 fn inclusion_proving_key() -> &'static Arc<VarunaProvingKey<Self>>;
332
333 #[cfg(feature = "wasm")]
334 fn inclusion_proving_key(bytes: Option<Vec<u8>>) -> &'static Arc<VarunaProvingKey<Self>>;
335
336 fn inclusion_verifying_key() -> &'static Arc<VarunaVerifyingKey<Self>>;
338
339 fn g_powers() -> &'static Vec<Group<Self>>;
341
342 fn g_scalar_multiply(scalar: &Scalar<Self>) -> Group<Self>;
344
345 fn varuna_universal_prover() -> &'static UniversalProver<Self::PairingCurve>;
347
348 fn varuna_universal_verifier() -> &'static UniversalVerifier<Self::PairingCurve>;
350
351 fn varuna_fs_parameters() -> &'static FiatShamirParameters<Self>;
353
354 fn commitment_domain() -> Field<Self>;
356
357 fn encryption_domain() -> Field<Self>;
359
360 fn graph_key_domain() -> Field<Self>;
362
363 fn serial_number_domain() -> Field<Self>;
365
366 fn commit_bhp256(input: &[bool], randomizer: &Scalar<Self>) -> Result<Field<Self>>;
368
369 fn commit_bhp512(input: &[bool], randomizer: &Scalar<Self>) -> Result<Field<Self>>;
371
372 fn commit_bhp768(input: &[bool], randomizer: &Scalar<Self>) -> Result<Field<Self>>;
374
375 fn commit_bhp1024(input: &[bool], randomizer: &Scalar<Self>) -> Result<Field<Self>>;
377
378 fn commit_ped64(input: &[bool], randomizer: &Scalar<Self>) -> Result<Field<Self>>;
380
381 fn commit_ped128(input: &[bool], randomizer: &Scalar<Self>) -> Result<Field<Self>>;
383
384 fn commit_to_group_bhp256(input: &[bool], randomizer: &Scalar<Self>) -> Result<Group<Self>>;
386
387 fn commit_to_group_bhp512(input: &[bool], randomizer: &Scalar<Self>) -> Result<Group<Self>>;
389
390 fn commit_to_group_bhp768(input: &[bool], randomizer: &Scalar<Self>) -> Result<Group<Self>>;
392
393 fn commit_to_group_bhp1024(input: &[bool], randomizer: &Scalar<Self>) -> Result<Group<Self>>;
395
396 fn commit_to_group_ped64(input: &[bool], randomizer: &Scalar<Self>) -> Result<Group<Self>>;
398
399 fn commit_to_group_ped128(input: &[bool], randomizer: &Scalar<Self>) -> Result<Group<Self>>;
401
402 fn hash_bhp256(input: &[bool]) -> Result<Field<Self>>;
404
405 fn hash_bhp512(input: &[bool]) -> Result<Field<Self>>;
407
408 fn hash_bhp768(input: &[bool]) -> Result<Field<Self>>;
410
411 fn hash_bhp1024(input: &[bool]) -> Result<Field<Self>>;
413
414 fn hash_keccak256(input: &[bool]) -> Result<Vec<bool>>;
416
417 fn hash_keccak384(input: &[bool]) -> Result<Vec<bool>>;
419
420 fn hash_keccak512(input: &[bool]) -> Result<Vec<bool>>;
422
423 fn hash_ped64(input: &[bool]) -> Result<Field<Self>>;
425
426 fn hash_ped128(input: &[bool]) -> Result<Field<Self>>;
428
429 fn hash_psd2(input: &[Field<Self>]) -> Result<Field<Self>>;
431
432 fn hash_psd4(input: &[Field<Self>]) -> Result<Field<Self>>;
434
435 fn hash_psd8(input: &[Field<Self>]) -> Result<Field<Self>>;
437
438 fn hash_sha3_256(input: &[bool]) -> Result<Vec<bool>>;
440
441 fn hash_sha3_384(input: &[bool]) -> Result<Vec<bool>>;
443
444 fn hash_sha3_512(input: &[bool]) -> Result<Vec<bool>>;
446
447 fn hash_many_psd2(input: &[Field<Self>], num_outputs: u16) -> Vec<Field<Self>>;
449
450 fn hash_many_psd4(input: &[Field<Self>], num_outputs: u16) -> Vec<Field<Self>>;
452
453 fn hash_many_psd8(input: &[Field<Self>], num_outputs: u16) -> Vec<Field<Self>>;
455
456 fn hash_to_group_bhp256(input: &[bool]) -> Result<Group<Self>>;
458
459 fn hash_to_group_bhp512(input: &[bool]) -> Result<Group<Self>>;
461
462 fn hash_to_group_bhp768(input: &[bool]) -> Result<Group<Self>>;
464
465 fn hash_to_group_bhp1024(input: &[bool]) -> Result<Group<Self>>;
467
468 fn hash_to_group_ped64(input: &[bool]) -> Result<Group<Self>>;
470
471 fn hash_to_group_ped128(input: &[bool]) -> Result<Group<Self>>;
473
474 fn hash_to_group_psd2(input: &[Field<Self>]) -> Result<Group<Self>>;
476
477 fn hash_to_group_psd4(input: &[Field<Self>]) -> Result<Group<Self>>;
479
480 fn hash_to_group_psd8(input: &[Field<Self>]) -> Result<Group<Self>>;
482
483 fn hash_to_scalar_psd2(input: &[Field<Self>]) -> Result<Scalar<Self>>;
485
486 fn hash_to_scalar_psd4(input: &[Field<Self>]) -> Result<Scalar<Self>>;
488
489 fn hash_to_scalar_psd8(input: &[Field<Self>]) -> Result<Scalar<Self>>;
491
492 fn merkle_tree_bhp<const DEPTH: u8>(leaves: &[Vec<bool>]) -> Result<BHPMerkleTree<Self, DEPTH>>;
494
495 fn merkle_tree_psd<const DEPTH: u8>(leaves: &[Vec<Field<Self>>]) -> Result<PoseidonMerkleTree<Self, DEPTH>>;
497
498 #[allow(clippy::ptr_arg)]
500 fn verify_merkle_path_bhp<const DEPTH: u8>(
501 path: &MerklePath<Self, DEPTH>,
502 root: &Field<Self>,
503 leaf: &Vec<bool>,
504 ) -> bool;
505
506 #[allow(clippy::ptr_arg)]
508 fn verify_merkle_path_psd<const DEPTH: u8>(
509 path: &MerklePath<Self, DEPTH>,
510 root: &Field<Self>,
511 leaf: &Vec<Field<Self>>,
512 ) -> bool;
513}
514
515#[cfg(feature = "wasm")]
531pub fn get_or_init_consensus_version_heights(
532 heights: Option<String>,
533) -> [(ConsensusVersion, u32); NUM_CONSENSUS_VERSIONS] {
534 let heights = load_test_consensus_heights_inner(heights);
535 *CONSENSUS_VERSION_HEIGHTS.get_or_init(|| heights)
536}