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 pub use crate::{
44 CANARY_V0_CONSENSUS_VERSION_HEIGHTS,
45 ConsensusVersion,
46 MAINNET_V0_CONSENSUS_VERSION_HEIGHTS,
47 Network,
48 TEST_CONSENSUS_VERSION_HEIGHTS,
49 TESTNET_V0_CONSENSUS_VERSION_HEIGHTS,
50 consensus_config_value,
51 environment::prelude::*,
52 };
53}
54
55use crate::environment::prelude::*;
56use snarkvm_algorithms::{
57 AlgebraicSponge,
58 crypto_hash::PoseidonSponge,
59 snark::varuna::{CircuitProvingKey, CircuitVerifyingKey, VarunaHidingMode},
60 srs::{UniversalProver, UniversalVerifier},
61};
62use snarkvm_console_algorithms::{BHP512, BHP1024, Poseidon2, Poseidon4};
63use snarkvm_console_collections::merkle_tree::{MerklePath, MerkleTree};
64use snarkvm_console_types::{Field, Group, Scalar};
65use snarkvm_curves::PairingEngine;
66
67use indexmap::IndexMap;
68use std::sync::{Arc, OnceLock};
69
70pub type BHPMerkleTree<N, const DEPTH: u8> = MerkleTree<N, BHP1024<N>, BHP512<N>, DEPTH>;
72pub type PoseidonMerkleTree<N, const DEPTH: u8> = MerkleTree<N, Poseidon4<N>, Poseidon2<N>, DEPTH>;
74
75type Fq<N> = <<N as Environment>::PairingCurve as PairingEngine>::Fq;
77pub type FiatShamir<N> = PoseidonSponge<Fq<N>, 2, 1>;
78pub type FiatShamirParameters<N> = <FiatShamir<N> as AlgebraicSponge<Fq<N>, 2>>::Parameters;
79
80pub(crate) type VarunaProvingKey<N> = CircuitProvingKey<<N as Environment>::PairingCurve, VarunaHidingMode>;
82pub(crate) type VarunaVerifyingKey<N> = CircuitVerifyingKey<<N as Environment>::PairingCurve>;
83
84static CONSENSUS_VERSION_HEIGHTS: OnceLock<[(ConsensusVersion, u32); NUM_CONSENSUS_VERSIONS]> = OnceLock::new();
86
87pub trait Network:
88 'static
89 + Environment
90 + Copy
91 + Clone
92 + Debug
93 + Eq
94 + PartialEq
95 + core::hash::Hash
96 + Serialize
97 + DeserializeOwned
98 + for<'a> Deserialize<'a>
99 + Send
100 + Sync
101{
102 const ID: u16;
104 const NAME: &'static str;
106 const SHORT_NAME: &'static str;
108
109 const INCLUSION_FUNCTION_NAME: &'static str;
111
112 const GENESIS_TIMESTAMP: i64;
114 const GENESIS_COINBASE_TARGET: u64;
116 const GENESIS_PROOF_TARGET: u64;
118 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;
131 const EXECUTION_STORAGE_PENALTY_THRESHOLD: u64 = 5000;
133 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;
141 const TRANSACTION_SPEND_LIMIT: [(ConsensusVersion, u64); 2] =
144 [(ConsensusVersion::V1, 100_000_000), (ConsensusVersion::V10, 4_000_000)];
145 const ARC_0005_COMPUTE_DISCOUNT: u64 = 25;
147
148 const ANCHOR_HEIGHT: u32 = Self::ANCHOR_TIME as u32 / Self::BLOCK_TIME as u32;
150 const ANCHOR_TIME: u16 = 25;
152 const BLOCK_TIME: u16 = 10;
154 const NUM_BLOCKS_PER_EPOCH: u32 = 3600 / Self::BLOCK_TIME as u32; const MAX_DATA_ENTRIES: usize = 32;
159 const MAX_DATA_DEPTH: usize = 32;
162 #[allow(clippy::cast_possible_truncation)]
164 const MAX_DATA_SIZE_IN_FIELDS: u32 = ((128 * 1024 * 8) / Field::<Self>::SIZE_IN_DATA_BITS) as u32;
165
166 const MIN_STRUCT_ENTRIES: usize = 1; const MAX_STRUCT_ENTRIES: usize = Self::MAX_DATA_ENTRIES;
170
171 const MIN_ARRAY_ELEMENTS: usize = 1; const MAX_ARRAY_ELEMENTS: usize = Self::MAX_DATA_ENTRIES;
175
176 const MIN_RECORD_ENTRIES: usize = 1; const MAX_RECORD_ENTRIES: usize = Self::MIN_RECORD_ENTRIES.saturating_add(Self::MAX_DATA_ENTRIES);
180
181 const MAX_PROGRAM_SIZE: usize = 100_000; const MAX_MAPPINGS: usize = 31;
186 const MAX_FUNCTIONS: usize = 31;
188 const MAX_STRUCTS: usize = 10 * Self::MAX_FUNCTIONS;
190 const MAX_RECORDS: usize = 10 * Self::MAX_FUNCTIONS;
192 const MAX_CLOSURES: usize = 2 * Self::MAX_FUNCTIONS;
194 const MAX_OPERANDS: usize = Self::MAX_INPUTS;
196 const MAX_INSTRUCTIONS: usize = u16::MAX as usize;
198 const MAX_COMMANDS: usize = u16::MAX as usize;
200 const MAX_WRITES: u16 = 16;
202 const MAX_POSITIONS: usize = u8::MAX as usize;
204
205 const MAX_INPUTS: usize = 16;
207 const MAX_OUTPUTS: usize = 16;
209
210 const MAX_IMPORTS: usize = 64;
212
213 const MAX_TRANSACTION_SIZE: usize = 128_000; type StateRoot: Bech32ID<Field<Self>>;
219 type BlockHash: Bech32ID<Field<Self>>;
221 type RatificationID: Bech32ID<Field<Self>>;
223 type TransactionID: Bech32ID<Field<Self>>;
225 type TransitionID: Bech32ID<Field<Self>>;
227 type TransmissionChecksum: IntegerType;
229
230 const _CONSENSUS_VERSION_HEIGHTS: [(ConsensusVersion, u32); NUM_CONSENSUS_VERSIONS];
234
235 const MAX_CERTIFICATES: [(ConsensusVersion, u16); 5];
241
242 #[allow(non_snake_case)]
244 #[cfg(not(any(test, feature = "test", feature = "test_consensus_heights")))]
245 fn CONSENSUS_VERSION_HEIGHTS() -> &'static [(ConsensusVersion, u32); NUM_CONSENSUS_VERSIONS] {
246 CONSENSUS_VERSION_HEIGHTS.get_or_init(|| Self::_CONSENSUS_VERSION_HEIGHTS)
248 }
249 #[allow(non_snake_case)]
251 #[cfg(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(load_test_consensus_heights)
255 }
256
257 #[allow(non_snake_case)]
259 #[cfg(any(test, feature = "test", feature = "test_consensus_heights"))]
260 const TEST_CONSENSUS_VERSION_HEIGHTS: [(ConsensusVersion, u32); NUM_CONSENSUS_VERSIONS] =
261 TEST_CONSENSUS_VERSION_HEIGHTS;
262 #[allow(non_snake_case)]
264 fn CONSENSUS_VERSION(seek_height: u32) -> anyhow::Result<ConsensusVersion> {
265 match Self::CONSENSUS_VERSION_HEIGHTS().binary_search_by(|(_, height)| height.cmp(&seek_height)) {
266 Ok(index) => Ok(Self::CONSENSUS_VERSION_HEIGHTS()[index].0),
268 Err(index) => {
270 if index == 0 {
271 Err(anyhow!("Expected consensus version 1 to exist at height 0."))
272 } else {
273 Ok(Self::CONSENSUS_VERSION_HEIGHTS()[index - 1].0)
275 }
276 }
277 }
278 }
279 #[allow(non_snake_case)]
281 fn CONSENSUS_HEIGHT(version: ConsensusVersion) -> Result<u32> {
282 Ok(Self::CONSENSUS_VERSION_HEIGHTS().get(version as usize - 1).ok_or(anyhow!("Invalid consensus version"))?.1)
283 }
284 #[allow(non_snake_case)]
286 fn LATEST_MAX_CERTIFICATES() -> Result<u16> {
287 Self::MAX_CERTIFICATES.last().map_or(Err(anyhow!("No MAX_CERTIFICATES defined.")), |(_, value)| Ok(*value))
288 }
289
290 #[allow(non_snake_case)]
292 fn INCLUSION_UPGRADE_HEIGHT() -> Result<u32>;
293
294 fn genesis_bytes() -> &'static [u8];
296
297 fn restrictions_list_as_str() -> &'static str;
299
300 fn get_credits_v0_proving_key(function_name: String) -> Result<&'static Arc<VarunaProvingKey<Self>>>;
302
303 fn get_credits_v0_verifying_key(function_name: String) -> Result<&'static Arc<VarunaVerifyingKey<Self>>>;
305
306 fn get_credits_proving_key(function_name: String) -> Result<&'static Arc<VarunaProvingKey<Self>>>;
308
309 fn get_credits_verifying_key(function_name: String) -> Result<&'static Arc<VarunaVerifyingKey<Self>>>;
311
312 fn inclusion_v0_proving_key() -> &'static Arc<VarunaProvingKey<Self>>;
314
315 fn inclusion_v0_verifying_key() -> &'static Arc<VarunaVerifyingKey<Self>>;
317
318 fn inclusion_proving_key() -> &'static Arc<VarunaProvingKey<Self>>;
320
321 fn inclusion_verifying_key() -> &'static Arc<VarunaVerifyingKey<Self>>;
323
324 fn g_powers() -> &'static Vec<Group<Self>>;
326
327 fn g_scalar_multiply(scalar: &Scalar<Self>) -> Group<Self>;
329
330 fn varuna_universal_prover() -> &'static UniversalProver<Self::PairingCurve>;
332
333 fn varuna_universal_verifier() -> &'static UniversalVerifier<Self::PairingCurve>;
335
336 fn varuna_fs_parameters() -> &'static FiatShamirParameters<Self>;
338
339 fn commitment_domain() -> Field<Self>;
341
342 fn encryption_domain() -> Field<Self>;
344
345 fn graph_key_domain() -> Field<Self>;
347
348 fn serial_number_domain() -> Field<Self>;
350
351 fn commit_bhp256(input: &[bool], randomizer: &Scalar<Self>) -> Result<Field<Self>>;
353
354 fn commit_bhp512(input: &[bool], randomizer: &Scalar<Self>) -> Result<Field<Self>>;
356
357 fn commit_bhp768(input: &[bool], randomizer: &Scalar<Self>) -> Result<Field<Self>>;
359
360 fn commit_bhp1024(input: &[bool], randomizer: &Scalar<Self>) -> Result<Field<Self>>;
362
363 fn commit_ped64(input: &[bool], randomizer: &Scalar<Self>) -> Result<Field<Self>>;
365
366 fn commit_ped128(input: &[bool], randomizer: &Scalar<Self>) -> Result<Field<Self>>;
368
369 fn commit_to_group_bhp256(input: &[bool], randomizer: &Scalar<Self>) -> Result<Group<Self>>;
371
372 fn commit_to_group_bhp512(input: &[bool], randomizer: &Scalar<Self>) -> Result<Group<Self>>;
374
375 fn commit_to_group_bhp768(input: &[bool], randomizer: &Scalar<Self>) -> Result<Group<Self>>;
377
378 fn commit_to_group_bhp1024(input: &[bool], randomizer: &Scalar<Self>) -> Result<Group<Self>>;
380
381 fn commit_to_group_ped64(input: &[bool], randomizer: &Scalar<Self>) -> Result<Group<Self>>;
383
384 fn commit_to_group_ped128(input: &[bool], randomizer: &Scalar<Self>) -> Result<Group<Self>>;
386
387 fn hash_bhp256(input: &[bool]) -> Result<Field<Self>>;
389
390 fn hash_bhp512(input: &[bool]) -> Result<Field<Self>>;
392
393 fn hash_bhp768(input: &[bool]) -> Result<Field<Self>>;
395
396 fn hash_bhp1024(input: &[bool]) -> Result<Field<Self>>;
398
399 fn hash_keccak256(input: &[bool]) -> Result<Vec<bool>>;
401
402 fn hash_keccak384(input: &[bool]) -> Result<Vec<bool>>;
404
405 fn hash_keccak512(input: &[bool]) -> Result<Vec<bool>>;
407
408 fn hash_ped64(input: &[bool]) -> Result<Field<Self>>;
410
411 fn hash_ped128(input: &[bool]) -> Result<Field<Self>>;
413
414 fn hash_psd2(input: &[Field<Self>]) -> Result<Field<Self>>;
416
417 fn hash_psd4(input: &[Field<Self>]) -> Result<Field<Self>>;
419
420 fn hash_psd8(input: &[Field<Self>]) -> Result<Field<Self>>;
422
423 fn hash_sha3_256(input: &[bool]) -> Result<Vec<bool>>;
425
426 fn hash_sha3_384(input: &[bool]) -> Result<Vec<bool>>;
428
429 fn hash_sha3_512(input: &[bool]) -> Result<Vec<bool>>;
431
432 fn hash_many_psd2(input: &[Field<Self>], num_outputs: u16) -> Vec<Field<Self>>;
434
435 fn hash_many_psd4(input: &[Field<Self>], num_outputs: u16) -> Vec<Field<Self>>;
437
438 fn hash_many_psd8(input: &[Field<Self>], num_outputs: u16) -> Vec<Field<Self>>;
440
441 fn hash_to_group_bhp256(input: &[bool]) -> Result<Group<Self>>;
443
444 fn hash_to_group_bhp512(input: &[bool]) -> Result<Group<Self>>;
446
447 fn hash_to_group_bhp768(input: &[bool]) -> Result<Group<Self>>;
449
450 fn hash_to_group_bhp1024(input: &[bool]) -> Result<Group<Self>>;
452
453 fn hash_to_group_ped64(input: &[bool]) -> Result<Group<Self>>;
455
456 fn hash_to_group_ped128(input: &[bool]) -> Result<Group<Self>>;
458
459 fn hash_to_group_psd2(input: &[Field<Self>]) -> Result<Group<Self>>;
461
462 fn hash_to_group_psd4(input: &[Field<Self>]) -> Result<Group<Self>>;
464
465 fn hash_to_group_psd8(input: &[Field<Self>]) -> Result<Group<Self>>;
467
468 fn hash_to_scalar_psd2(input: &[Field<Self>]) -> Result<Scalar<Self>>;
470
471 fn hash_to_scalar_psd4(input: &[Field<Self>]) -> Result<Scalar<Self>>;
473
474 fn hash_to_scalar_psd8(input: &[Field<Self>]) -> Result<Scalar<Self>>;
476
477 fn merkle_tree_bhp<const DEPTH: u8>(leaves: &[Vec<bool>]) -> Result<BHPMerkleTree<Self, DEPTH>>;
479
480 fn merkle_tree_psd<const DEPTH: u8>(leaves: &[Vec<Field<Self>>]) -> Result<PoseidonMerkleTree<Self, DEPTH>>;
482
483 #[allow(clippy::ptr_arg)]
485 fn verify_merkle_path_bhp<const DEPTH: u8>(
486 path: &MerklePath<Self, DEPTH>,
487 root: &Field<Self>,
488 leaf: &Vec<bool>,
489 ) -> bool;
490
491 #[allow(clippy::ptr_arg)]
493 fn verify_merkle_path_psd<const DEPTH: u8>(
494 path: &MerklePath<Self, DEPTH>,
495 root: &Field<Self>,
496 leaf: &Vec<Field<Self>>,
497 ) -> bool;
498}