1use once_cell::sync::OnceCell;
2use poseidon::hash::{
3 legacy,
4 params::{CODA_SIGNATURE, MAINNET_ZKAPP_BODY, MINA_SIGNATURE_MAINNET, TESTNET_ZKAPP_BODY},
5};
6
7use crate::constants::ConstraintConstants;
8
9#[derive(Debug, Clone)]
11pub enum NetworkId {
12 TESTNET = 0x00,
14
15 MAINNET = 0x01,
17}
18
19#[derive(Debug)]
20pub struct NetworkConfig {
21 pub name: &'static str,
22 pub network_id: NetworkId,
23 pub signature_prefix: &'static poseidon::hash::LazyParam,
24 pub legacy_signature_prefix: &'static poseidon::hash::LazyParam,
25 pub account_update_hash_param: &'static poseidon::hash::LazyParam,
26 pub constraint_system_digests: &'static [[u8; 16]; 3],
27 pub default_peers: Vec<&'static str>,
28 pub circuits_config: &'static CircuitsConfig,
29 pub constraint_constants: &'static ConstraintConstants,
30}
31
32#[derive(Debug)]
33pub struct CircuitsConfig {
34 pub directory_name: &'static str,
35
36 pub step_transaction_gates: &'static str,
37 pub wrap_transaction_gates: &'static str,
38 pub step_merge_gates: &'static str,
39 pub step_blockchain_gates: &'static str,
40 pub wrap_blockchain_gates: &'static str,
41 pub step_transaction_opt_signed_opt_signed_gates: &'static str,
42 pub step_transaction_opt_signed_gates: &'static str,
43 pub step_transaction_proved_gates: &'static str,
44}
45
46static CONFIG: OnceCell<NetworkConfig> = OnceCell::new();
47
48impl NetworkConfig {
49 pub fn global() -> &'static Self {
50 CONFIG.get_or_init(|| {
51 let config = Self::default_config();
52 crate::warn!(
53 crate::log::system_time();
54 kind = "network",
55 message = "no network config initialized, using default config",
56 config = config.name,
57 );
58 config
59 })
60 }
61
62 pub fn init(network_name: &str) -> Result<(), String> {
63 let config = match network_name {
64 "devnet" => Self::devnet_config(),
65 "mainnet" => Self::mainnet_config(),
66 other => Err(format!("Unknown network {other}"))?,
67 };
68
69 CONFIG
70 .set(config)
71 .map_err(|_| "Double network configuration initialization".to_owned())?;
72
73 Ok(())
74 }
75
76 fn default_config() -> Self {
77 Self::devnet_config()
78 }
79
80 fn mainnet_config() -> Self {
81 Self {
82 name: mainnet::NAME,
83 network_id: mainnet::NETWORK_ID,
84 signature_prefix: &MINA_SIGNATURE_MAINNET,
85 legacy_signature_prefix: &legacy::params::MINA_SIGNATURE_MAINNET,
86 account_update_hash_param: &MAINNET_ZKAPP_BODY,
87 constraint_system_digests: &mainnet::CONSTRAINT_SYSTEM_DIGESTS,
88 default_peers: mainnet::default_peers(),
89 circuits_config: &mainnet::CIRCUITS_CONFIG,
90 constraint_constants: &mainnet::CONSTRAINT_CONSTANTS,
91 }
92 }
93
94 fn devnet_config() -> Self {
95 Self {
96 name: devnet::NAME,
97 network_id: devnet::NETWORK_ID,
98 signature_prefix: &CODA_SIGNATURE,
99 legacy_signature_prefix: &legacy::params::CODA_SIGNATURE,
100 account_update_hash_param: &TESTNET_ZKAPP_BODY,
101 constraint_system_digests: &devnet::CONSTRAINT_SYSTEM_DIGESTS,
102 default_peers: devnet::default_peers(),
103 circuits_config: &devnet::CIRCUITS_CONFIG,
104 constraint_constants: &devnet::CONSTRAINT_CONSTANTS,
105 }
106 }
107}
108
109pub mod devnet {
112 use super::{CircuitsConfig, NetworkId};
113 use crate::constants::{ConstraintConstants, ForkConstants};
114 use mina_curves::pasta::Fp;
115
116 pub const NETWORK_ID: NetworkId = NetworkId::TESTNET;
117 pub const NAME: &str = "devnet";
118 pub const SIGNATURE_PREFIX: &str = "CodaSignature";
119 pub const ACCOUNT_UPDATE_HASH_PARAM: &str = "TestnetZkappBody";
120
121 pub const CONSTRAINT_SYSTEM_DIGESTS: [[u8; 16]; 3] = [
122 [
124 0xb8, 0x87, 0x9f, 0x67, 0x7f, 0x62, 0x2a, 0x1d, 0x86, 0x64, 0x80, 0x30, 0x70, 0x1f,
125 0x43, 0xe1,
126 ],
127 [
129 0x3b, 0xf6, 0xbb, 0x8a, 0x97, 0x66, 0x5f, 0xe7, 0xa9, 0xdf, 0x6f, 0xc1, 0x46, 0xe4,
130 0xf9, 0x42,
131 ],
132 [
134 0xd0, 0x24, 0xa9, 0xac, 0x78, 0xd4, 0xc9, 0x3a, 0x88, 0x8b, 0x63, 0xfc, 0x85, 0xee,
135 0xb6, 0x6a,
136 ],
137 ];
138
139 pub const CONSTRAINT_CONSTANTS: ConstraintConstants = ConstraintConstants {
140 sub_windows_per_window: 11,
141 ledger_depth: 35,
142 work_delay: 2,
143 block_window_duration_ms: 180000,
144 transaction_capacity_log_2: 7,
145 pending_coinbase_depth: 5,
146 coinbase_amount: 720000000000,
147 supercharged_coinbase_factor: 1,
148 account_creation_fee: 1000000000,
149 fork: Some(ForkConstants {
154 state_hash: ark_ff::field_new!(
155 Fp,
156 "7908066420535064797069631664846455037440232590837253108938061943122344055350"
157 ),
158 blockchain_length: 296371,
159 global_slot_since_genesis: 445860,
160 }),
161 };
162
163 pub const CIRCUITS_CONFIG: CircuitsConfig = CircuitsConfig {
164 directory_name: "3.0.1devnet",
165
166 step_transaction_gates: "step-step-proving-key-transaction-snark-transaction-0-c33ec5211c07928c87e850a63c6a2079",
167 wrap_transaction_gates:
168 "wrap-wrap-proving-key-transaction-snark-b9a01295c8cc9bda6d12142a581cd305",
169 step_merge_gates:
170 "step-step-proving-key-transaction-snark-merge-1-ba1d52dfdc2dd4d2e61f6c66ff2a5b2f",
171 step_blockchain_gates:
172 "step-step-proving-key-blockchain-snark-step-0-55f640777b6486a6fd3fdbc3fcffcc60",
173 wrap_blockchain_gates:
174 "wrap-wrap-proving-key-blockchain-snark-bbecaf158ca543ec8ac9e7144400e669",
175 step_transaction_opt_signed_opt_signed_gates: "step-step-proving-key-transaction-snark-opt_signed-opt_signed-2-48925e6a97197028e1a7c1ecec09021d",
176 step_transaction_opt_signed_gates:
177 "step-step-proving-key-transaction-snark-opt_signed-3-9eefed16953d2bfa78a257adece02d47",
178 step_transaction_proved_gates:
179 "step-step-proving-key-transaction-snark-proved-4-0cafcbc6dffccddbc82f8c2519c16341",
180 };
181
182 pub fn default_peers() -> Vec<&'static str> {
183 vec![
184 "/dns4/seed-1.devnet.gcp.o1test.net/tcp/10003/p2p/12D3KooWAdgYL6hv18M3iDBdaK1dRygPivSfAfBNDzie6YqydVbs",
185 "/dns4/seed-2.devnet.gcp.o1test.net/tcp/10003/p2p/12D3KooWLjs54xHzVmMmGYb7W5RVibqbwD1co7M2ZMfPgPm7iAag",
186 "/dns4/seed-3.devnet.gcp.o1test.net/tcp/10003/p2p/12D3KooWEiGVAFC7curXWXiGZyMWnZK9h8BKr88U8D5PKV3dXciv",
187 ]
188 }
189}
190
191pub mod mainnet {
192 use super::{CircuitsConfig, NetworkId};
193 use crate::constants::{ConstraintConstants, ForkConstants};
194 use mina_curves::pasta::Fp;
195
196 pub const NETWORK_ID: NetworkId = NetworkId::MAINNET;
197 pub const NAME: &str = "mainnet";
198 pub const SIGNATURE_PREFIX: &str = "MinaSignatureMainnet";
199 pub const ACCOUNT_UPDATE_HASH_PARAM: &str = "MainnetZkappBody";
200
201 pub const CONSTRAINT_SYSTEM_DIGESTS: [[u8; 16]; 3] = [
202 [
204 0xb8, 0x87, 0x9f, 0x67, 0x7f, 0x62, 0x2a, 0x1d, 0x86, 0x64, 0x80, 0x30, 0x70, 0x1f,
205 0x43, 0xe1,
206 ],
207 [
209 0xd3, 0x19, 0x48, 0xe6, 0x61, 0xcc, 0x66, 0x26, 0x75, 0xb0, 0xc0, 0x79, 0x45, 0x8f,
210 0x71, 0x4a,
211 ],
212 [
214 0x14, 0xab, 0x55, 0x62, 0xed, 0x29, 0x2d, 0xe7, 0xa3, 0xde, 0xb9, 0xe1, 0x2f, 0x00,
215 0xae, 0xc0,
216 ],
217 ];
218
219 pub const CONSTRAINT_CONSTANTS: ConstraintConstants = ConstraintConstants {
220 sub_windows_per_window: 11,
221 ledger_depth: 35,
222 work_delay: 2,
223 block_window_duration_ms: 180000,
224 transaction_capacity_log_2: 7,
225 pending_coinbase_depth: 5,
226 coinbase_amount: 720000000000,
227 supercharged_coinbase_factor: 1,
228 account_creation_fee: 1000000000,
229 fork: Some(ForkConstants {
234 state_hash: ark_ff::field_new!(
235 Fp,
236 "24465973112608446515163575794792913472627621028836869800891179577915755065526"
237 ),
238 blockchain_length: 359604,
239 global_slot_since_genesis: 564480,
240 }),
241 };
242
243 pub const CIRCUITS_CONFIG: CircuitsConfig = CircuitsConfig {
244 directory_name: "3.0.0mainnet",
245
246 step_transaction_gates: "step-step-proving-key-transaction-snark-transaction-0-b421ac835a0e73935f3d3569ff87f484",
247 wrap_transaction_gates:
248 "wrap-wrap-proving-key-transaction-snark-93928b62a1803f78b59f698ee4d36e63",
249 step_merge_gates:
250 "step-step-proving-key-transaction-snark-merge-1-ba1d52dfdc2dd4d2e61f6c66ff2a5b2f",
251 step_blockchain_gates:
252 "step-step-proving-key-blockchain-snark-step-0-281a97b76f28a0b850065190cbb892af",
253 wrap_blockchain_gates:
254 "wrap-wrap-proving-key-blockchain-snark-26c8a899619ad2682c077b0fecef87f8",
255 step_transaction_opt_signed_opt_signed_gates: "step-step-proving-key-transaction-snark-opt_signed-opt_signed-2-a84fb2a46cf4f9b58857ea5922f23266",
256 step_transaction_opt_signed_gates:
257 "step-step-proving-key-transaction-snark-opt_signed-3-a7e0f70d44ac6f0dd0afd3478e2b38ac",
258 step_transaction_proved_gates:
259 "step-step-proving-key-transaction-snark-proved-4-7bb3855dfcf14da4b3ffa7091adc0143",
260 };
261
262 pub fn default_peers() -> Vec<&'static str> {
263 vec![
264 "/dns4/mina-mainnet-seed.staketab.com/tcp/10003/p2p/12D3KooWSDTiXcdBVpN12ZqXJ49qCFp8zB1NnovuhZu6A28GLF1J",
265 "/dns4/mina-seed.bitcat365.com/tcp/10001/p2p/12D3KooWQzozNTDKL7MqUh6Nh11GMA4pQhRCAsNTRWxCAzAi4VbE",
266 "/dns4/production-mainnet-libp2p.minaprotocol.network/tcp/10000/p2p/12D3KooWPywsM191KGGNVGiNqN35nyyJg4W2BhhYukF6hP9YBR8q",
267 "/dns4/seed-1.mainnet.gcp.o1test.net/tcp/10003/p2p/12D3KooWCa1d7G3SkRxy846qTvdAFX69NnoYZ32orWVLqJcDVGHW",
268 "/dns4/seed-2.mainnet.gcp.o1test.net/tcp/32002/p2p/12D3KooWK4NfthViCTyLgVQa1WvqDC1NccVxGruCXCZUt3GqvFvn",
269 "/dns4/seed-3.mainnet.gcp.o1test.net/tcp/32003/p2p/12D3KooWNofeYVAJXA3WGg2qCDhs3GEe71kTmKpFQXRbZmCz1Vr7",
270 "/dns4/seed-4.mainnet.gcp.o1test.net/tcp/10003/p2p/12D3KooWEdBiTUQqxp3jeuWaZkwiSNcFxC6d6Tdq7u2Lf2ZD2Q6X",
271 "/dns4/seed-5.mainnet.gcp.o1test.net/tcp/32005/p2p/12D3KooWL1DJTigSwuKQRfQE3p7puFUqfbHjXbZJ9YBWtMNpr3GU",
272 "/dns4/seed-6.mainnet.gcp.o1test.net/tcp/32006/p2p/12D3KooWHGx4u32n42ub7dJNxAcAhwiA1WDq1Zsjn3k7RsS11pE8",
273 "/dns4/seed.minaexplorer.com/tcp/8302/p2p/12D3KooWR7coZtrMHvsgsfiWq2GESYypac3i29LFGp6EpbtjxBiJ",
274 "/dns4/seed.minataur.net/tcp/8302/p2p/12D3KooWNyExDzG8T1BYXHpXQS66kaw3zi6qi5Pg9KD3GEyHW5FF",
275 "/dns4/seed.piconbello.com/tcp/10001/p2p/12D3KooWRFac2AztcTeen2DYNwnTrmVBvwNDsRiFpDVdTkwdFAHP",
276 ]
277 }
278}