openmina_core/
network.rs

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// From mina-signer, to avoid dependency
10#[derive(Debug, Clone)]
11pub enum NetworkId {
12    /// Id for all testnets
13    TESTNET = 0x00,
14
15    /// Id for mainnet
16    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
109// Network constants
110
111pub 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        // transaction-merge
123        [
124            0xb8, 0x87, 0x9f, 0x67, 0x7f, 0x62, 0x2a, 0x1d, 0x86, 0x64, 0x80, 0x30, 0x70, 0x1f,
125            0x43, 0xe1,
126        ],
127        // transaction-base
128        [
129            0x3b, 0xf6, 0xbb, 0x8a, 0x97, 0x66, 0x5f, 0xe7, 0xa9, 0xdf, 0x6f, 0xc1, 0x46, 0xe4,
130            0xf9, 0x42,
131        ],
132        // blockchain-step
133        [
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        // TODO(tizoc): This should come from the config file, but
150        // it affects the circuits. Since we cannot produce the circuits
151        // ourselves right now, we cannot react to changes in this value,
152        // so it will be hardcoded for now.
153        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            // "/ip4/34.45.167.81/tcp/10003/p2p/12D3KooWAdgYL6hv18M3iDBdaK1dRygPivSfAfBNDzie6YqydVbs",
188            // "/ip4/34.28.194.121/tcp/10003/p2p/12D3KooWLjs54xHzVmMmGYb7W5RVibqbwD1co7M2ZMfPgPm7iAag",
189            // "/ip4/34.44.189.148/tcp/10003/p2p/12D3KooWEiGVAFC7curXWXiGZyMWnZK9h8BKr88U8D5PKV3dXciv",
190        ]
191    }
192}
193
194pub mod mainnet {
195    use super::{CircuitsConfig, NetworkId};
196    use crate::constants::{ConstraintConstants, ForkConstants};
197    use mina_curves::pasta::Fp;
198
199    pub const NETWORK_ID: NetworkId = NetworkId::MAINNET;
200    pub const NAME: &str = "mainnet";
201    pub const SIGNATURE_PREFIX: &str = "MinaSignatureMainnet";
202    pub const ACCOUNT_UPDATE_HASH_PARAM: &str = "MainnetZkappBody";
203
204    pub const CONSTRAINT_SYSTEM_DIGESTS: [[u8; 16]; 3] = [
205        // transaction-merge
206        [
207            0xb8, 0x87, 0x9f, 0x67, 0x7f, 0x62, 0x2a, 0x1d, 0x86, 0x64, 0x80, 0x30, 0x70, 0x1f,
208            0x43, 0xe1,
209        ],
210        // transaction-base
211        [
212            0xd3, 0x19, 0x48, 0xe6, 0x61, 0xcc, 0x66, 0x26, 0x75, 0xb0, 0xc0, 0x79, 0x45, 0x8f,
213            0x71, 0x4a,
214        ],
215        // blockchain-step
216        [
217            0x14, 0xab, 0x55, 0x62, 0xed, 0x29, 0x2d, 0xe7, 0xa3, 0xde, 0xb9, 0xe1, 0x2f, 0x00,
218            0xae, 0xc0,
219        ],
220    ];
221
222    pub const CONSTRAINT_CONSTANTS: ConstraintConstants = ConstraintConstants {
223        sub_windows_per_window: 11,
224        ledger_depth: 35,
225        work_delay: 2,
226        block_window_duration_ms: 180000,
227        transaction_capacity_log_2: 7,
228        pending_coinbase_depth: 5,
229        coinbase_amount: 720000000000,
230        supercharged_coinbase_factor: 1,
231        account_creation_fee: 1000000000,
232        // TODO(tizoc): This should come from the config file, but
233        // it affects the circuits. Since we cannot produce the circuits
234        // ourselves right now, we cannot react to changes in this value,
235        // so it will be hardcoded for now.
236        fork: Some(ForkConstants {
237            state_hash: ark_ff::field_new!(
238                Fp,
239                "24465973112608446515163575794792913472627621028836869800891179577915755065526"
240            ),
241            blockchain_length: 359604,
242            global_slot_since_genesis: 564480,
243        }),
244    };
245
246    pub const CIRCUITS_CONFIG: CircuitsConfig = CircuitsConfig {
247        directory_name: "3.0.0mainnet",
248
249        step_transaction_gates: "step-step-proving-key-transaction-snark-transaction-0-b421ac835a0e73935f3d3569ff87f484",
250        wrap_transaction_gates:
251            "wrap-wrap-proving-key-transaction-snark-93928b62a1803f78b59f698ee4d36e63",
252        step_merge_gates:
253            "step-step-proving-key-transaction-snark-merge-1-ba1d52dfdc2dd4d2e61f6c66ff2a5b2f",
254        step_blockchain_gates:
255            "step-step-proving-key-blockchain-snark-step-0-281a97b76f28a0b850065190cbb892af",
256        wrap_blockchain_gates:
257            "wrap-wrap-proving-key-blockchain-snark-26c8a899619ad2682c077b0fecef87f8",
258        step_transaction_opt_signed_opt_signed_gates: "step-step-proving-key-transaction-snark-opt_signed-opt_signed-2-a84fb2a46cf4f9b58857ea5922f23266",
259        step_transaction_opt_signed_gates:
260            "step-step-proving-key-transaction-snark-opt_signed-3-a7e0f70d44ac6f0dd0afd3478e2b38ac",
261        step_transaction_proved_gates:
262            "step-step-proving-key-transaction-snark-proved-4-7bb3855dfcf14da4b3ffa7091adc0143",
263    };
264
265    pub fn default_peers() -> Vec<&'static str> {
266        vec![
267            // /dns4/mina-seed.etonec.com/tcp/8302/p2p/12D3KooWKQ1YVtqZFzxDmSw8RASCPZpDCQBywnFz76RbrvZCXk5T
268            // /dns4/mina-mainnet-seed.obscura.network/tcp/5002/p2p/12D3KooWFRpU3giZDFjJjwoHSY8kdpv8ktvferGkyQRUHozsXw4X
269            // /dns4/mina-mainnet-seed.staketab.com/tcp/10003/p2p/12D3KooWSDTiXcdBVpN12ZqXJ49qCFp8zB1NnovuhZu6A28GLF1J
270            // /dns4/mina-seed-1.zkvalidator.com/tcp/8302/p2p/12D3KooWSfEfnVCqzpMbmyUmRY3ESEVmJaRcd1EkLbnvvERQxwtu
271            // /dns4/mina-seed.bitcat365.com/tcp/10001/p2p/12D3KooWQzozNTDKL7MqUh6Nh11GMA4pQhRCAsNTRWxCAzAi4VbE
272            // /dns4/production-mainnet-libp2p.minaprotocol.network/tcp/10000/p2p/12D3KooWPywsM191KGGNVGiNqN35nyyJg4W2BhhYukF6hP9YBR8q
273            // /dns4/production-mainnet-libp2p.minaprotocol.network/tcp/10010/p2p/12D3KooWGB6mJ9Ub9qRBDgHhedNXH4FawWjGQGGN2tQKaKa3gK2h
274            // /dns4/production-mainnet-libp2p.minaprotocol.network/tcp/10020/p2p/12D3KooWMvsPx6A1XNa4V8bTbNb6Fh7WHWf92Ezgfxt6UWxiNq5n
275            // /dns4/production-mainnet-libp2p.minaprotocol.network/tcp/10030/p2p/12D3KooW9wL9iaj7qbCTBFspi4gCwdZFCdNRnwkRrdRfe4GBJ978
276            // /dns4/production-mainnet-libp2p.minaprotocol.network/tcp/10040/p2p/12D3KooWL8SFDx6PSzpSLgBtRSK1brjKFqs8EvW2yX9zexQEefAo
277            // /dns4/seed-1.mainnet.gcp.o1test.net/tcp/10003/p2p/12D3KooWCa1d7G3SkRxy846qTvdAFX69NnoYZ32orWVLqJcDVGHW
278            // /dns4/seed-2.mainnet.gcp.o1test.net/tcp/10003/p2p/12D3KooWK4NfthViCTyLgVQa1WvqDC1NccVxGruCXCZUt3GqvFvn
279            // /dns4/seed-4.mainnet.gcp.o1test.net/tcp/10003/p2p/12D3KooWEdBiTUQqxp3jeuWaZkwiSNcFxC6d6Tdq7u2Lf2ZD2Q6X
280            // /dns4/seed-5.mainnet.gcp.o1test.net/tcp/10003/p2p/12D3KooWL1DJTigSwuKQRfQE3p7puFUqfbHjXbZJ9YBWtMNpr3GU
281            // /dns4/seed.minaexplorer.com/tcp/8302/p2p/12D3KooWR7coZtrMHvsgsfiWq2GESYypac3i29LFGp6EpbtjxBiJ
282            // /dns4/seed.minataur.net/tcp/8302/p2p/12D3KooWNyExDzG8T1BYXHpXQS66kaw3zi6qi5Pg9KD3GEyHW5FF
283            // /dns4/seed.piconbello.com/tcp/10001/p2p/12D3KooWRFac2AztcTeen2DYNwnTrmVBvwNDsRiFpDVdTkwdFAHP
284            "/ip4/138.201.11.249/tcp/8302/p2p/12D3KooWKQ1YVtqZFzxDmSw8RASCPZpDCQBywnFz76RbrvZCXk5T",
285            "/ip4/51.178.128.35/tcp/5002/p2p/12D3KooWFRpU3giZDFjJjwoHSY8kdpv8ktvferGkyQRUHozsXw4X",
286            "/ip4/138.201.53.35/tcp/10003/p2p/12D3KooWSDTiXcdBVpN12ZqXJ49qCFp8zB1NnovuhZu6A28GLF1J",
287            "/ip4/37.27.121.141/tcp/8302/p2p/12D3KooWSfEfnVCqzpMbmyUmRY3ESEVmJaRcd1EkLbnvvERQxwtu",
288            "/ip4/94.130.21.18/tcp/10001/p2p/12D3KooWQzozNTDKL7MqUh6Nh11GMA4pQhRCAsNTRWxCAzAi4VbE",
289            "/ip4/44.236.52.227/tcp/10000/p2p/12D3KooWPywsM191KGGNVGiNqN35nyyJg4W2BhhYukF6hP9YBR8q",
290            "/ip4/44.236.52.227/tcp/10010/p2p/12D3KooWGB6mJ9Ub9qRBDgHhedNXH4FawWjGQGGN2tQKaKa3gK2h",
291            "/ip4/44.236.52.227/tcp/10020/p2p/12D3KooWMvsPx6A1XNa4V8bTbNb6Fh7WHWf92Ezgfxt6UWxiNq5n",
292            "/ip4/44.236.52.227/tcp/10030/p2p/12D3KooW9wL9iaj7qbCTBFspi4gCwdZFCdNRnwkRrdRfe4GBJ978",
293            "/ip4/44.236.52.227/tcp/10040/p2p/12D3KooWL8SFDx6PSzpSLgBtRSK1brjKFqs8EvW2yX9zexQEefAo",
294            "/ip4/34.86.219.199/tcp/10003/p2p/12D3KooWCa1d7G3SkRxy846qTvdAFX69NnoYZ32orWVLqJcDVGHW",
295            "/ip4/34.145.137.93/tcp/10003/p2p/12D3KooWK4NfthViCTyLgVQa1WvqDC1NccVxGruCXCZUt3GqvFvn",
296            "/ip4/34.95.19.83/tcp/10003/p2p/12D3KooWEdBiTUQqxp3jeuWaZkwiSNcFxC6d6Tdq7u2Lf2ZD2Q6X",
297            "/ip4/35.203.59.118/tcp/10003/p2p/12D3KooWL1DJTigSwuKQRfQE3p7puFUqfbHjXbZJ9YBWtMNpr3GU",
298            "/ip4/65.21.20.43/tcp/8302/p2p/12D3KooWR7coZtrMHvsgsfiWq2GESYypac3i29LFGp6EpbtjxBiJ",
299            "/ip4/37.27.118.159/tcp/8302/p2p/12D3KooWNyExDzG8T1BYXHpXQS66kaw3zi6qi5Pg9KD3GEyHW5FF",
300            "/ip4/144.76.18.153/tcp/10001/p2p/12D3KooWRFac2AztcTeen2DYNwnTrmVBvwNDsRiFpDVdTkwdFAHP",
301        ]
302    }
303}