1use crate::config::env::read_string_from_env_then_parse;
2use crate::constants::{MIN_TAPROOT_AMOUNT, NON_EPHEMERAL_ANCHOR_AMOUNT};
3use crate::errors::BridgeError;
4use bitcoin::{Amount, Network};
5use bridge_circuit_host::utils::is_dev_mode;
6use circuits_lib::bridge_circuit::constants::{
7 DEVNET_LC_IMAGE_ID, MAINNET_LC_IMAGE_ID, REGTEST_LC_IMAGE_ID, TESTNET4_LC_IMAGE_ID,
8};
9use eyre::Context;
10use serde::{Deserialize, Serialize};
11use std::fmt::Display;
12use std::fs;
13use std::path::Path;
14use std::str::FromStr;
15
16pub const BLOCKS_PER_HOUR: u16 = 6;
17
18pub const BLOCKS_PER_DAY: u16 = BLOCKS_PER_HOUR * 24;
19
20pub const BLOCKS_PER_WEEK: u16 = BLOCKS_PER_DAY * 7;
21
22pub const WINTERNITZ_LOG_D: u32 = 4;
26
27#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize)]
28#[serde(rename_all = "lowercase")]
29pub enum ProtocolParamsetName {
34 Regtest,
36}
37
38impl FromStr for ProtocolParamsetName {
39 type Err = BridgeError;
40
41 fn from_str(s: &str) -> Result<Self, Self::Err> {
42 match s {
43 "regtest" => Ok(ProtocolParamsetName::Regtest),
44 _ => Err(BridgeError::ConfigError(format!(
45 "Unknown paramset name: {s}"
46 ))),
47 }
48 }
49}
50
51impl Display for ProtocolParamsetName {
52 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
53 match self {
54 ProtocolParamsetName::Regtest => write!(f, "regtest"),
55 }
56 }
57}
58
59impl From<ProtocolParamsetName> for &'static ProtocolParamset {
60 fn from(name: ProtocolParamsetName) -> Self {
61 match name {
62 ProtocolParamsetName::Regtest => ®TEST_PARAMSET,
63 }
64 }
65}
66
67#[derive(Debug, Clone, PartialEq, Eq, Hash, Deserialize, Serialize)]
68pub struct ProtocolParamset {
76 pub network: Network,
78 pub num_round_txs: usize,
80 pub num_kickoffs_per_round: usize,
82 pub num_signed_kickoffs: usize,
85 pub bridge_amount: Amount,
87 pub kickoff_amount: Amount,
89 pub operator_challenge_amount: Amount,
91 pub collateral_funding_amount: Amount,
93 pub kickoff_blockhash_commit_length: u32,
95 pub watchtower_challenge_bytes: usize,
97 pub winternitz_log_d: u32,
100 pub user_takes_after: u16,
102 pub operator_challenge_timeout_timelock: u16,
104 pub operator_challenge_nack_timelock: u16,
106 pub disprove_timeout_timelock: u16,
108 pub assert_timeout_timelock: u16,
110 pub latest_blockhash_timeout_timelock: u16,
112 pub operator_reimburse_timelock: u16,
115 pub watchtower_challenge_timeout_timelock: u16,
117 pub finality_depth: u32,
121 pub start_height: u32,
123 pub genesis_height: u32,
125 pub genesis_chain_state_hash: [u8; 32],
127 pub bridge_nonstandard: bool,
129}
130
131impl ProtocolParamset {
132 pub fn from_toml_file(path: &Path) -> Result<Self, BridgeError> {
133 let contents = fs::read_to_string(path).wrap_err("Failed to read config file")?;
134
135 let paramset: Self = toml::from_str(&contents).wrap_err("Failed to parse TOML")?;
136 if paramset.finality_depth < 1 {
137 return Err(BridgeError::ConfigError(
138 "Finality depth must be at least 1".to_string(),
139 ));
140 }
141
142 Ok(paramset)
143 }
144 pub fn from_env() -> Result<Self, BridgeError> {
145 let config = ProtocolParamset {
146 network: read_string_from_env_then_parse::<Network>("NETWORK")?,
147 num_round_txs: read_string_from_env_then_parse::<usize>("NUM_ROUND_TXS")?,
148 num_kickoffs_per_round: read_string_from_env_then_parse::<usize>(
149 "NUM_KICKOFFS_PER_ROUND",
150 )?,
151 num_signed_kickoffs: read_string_from_env_then_parse::<usize>("NUM_SIGNED_KICKOFFS")?,
152 bridge_amount: Amount::from_sat(read_string_from_env_then_parse::<u64>(
153 "BRIDGE_AMOUNT",
154 )?),
155 kickoff_amount: Amount::from_sat(read_string_from_env_then_parse::<u64>(
156 "KICKOFF_AMOUNT",
157 )?),
158 operator_challenge_amount: Amount::from_sat(read_string_from_env_then_parse::<u64>(
159 "OPERATOR_CHALLENGE_AMOUNT",
160 )?),
161 collateral_funding_amount: Amount::from_sat(read_string_from_env_then_parse::<u64>(
162 "COLLATERAL_FUNDING_AMOUNT",
163 )?),
164 kickoff_blockhash_commit_length: read_string_from_env_then_parse::<u32>(
165 "KICKOFF_BLOCKHASH_COMMIT_LENGTH",
166 )?,
167 watchtower_challenge_bytes: read_string_from_env_then_parse::<usize>(
168 "WATCHTOWER_CHALLENGE_BYTES",
169 )?,
170 winternitz_log_d: read_string_from_env_then_parse::<u32>("WINTERNITZ_LOG_D")?,
171 user_takes_after: read_string_from_env_then_parse::<u16>("USER_TAKES_AFTER")?,
172 operator_challenge_timeout_timelock: read_string_from_env_then_parse::<u16>(
173 "OPERATOR_CHALLENGE_TIMEOUT_TIMELOCK",
174 )?,
175 operator_challenge_nack_timelock: read_string_from_env_then_parse::<u16>(
176 "OPERATOR_CHALLENGE_NACK_TIMELOCK",
177 )?,
178 disprove_timeout_timelock: read_string_from_env_then_parse::<u16>(
179 "DISPROVE_TIMEOUT_TIMELOCK",
180 )?,
181 assert_timeout_timelock: read_string_from_env_then_parse::<u16>(
182 "ASSERT_TIMEOUT_TIMELOCK",
183 )?,
184 operator_reimburse_timelock: read_string_from_env_then_parse::<u16>(
185 "OPERATOR_REIMBURSE_TIMELOCK",
186 )?,
187 watchtower_challenge_timeout_timelock: read_string_from_env_then_parse::<u16>(
188 "WATCHTOWER_CHALLENGE_TIMEOUT_TIMELOCK",
189 )?,
190 finality_depth: read_string_from_env_then_parse::<u32>("FINALITY_DEPTH")?,
191 start_height: read_string_from_env_then_parse::<u32>("START_HEIGHT")?,
192 genesis_height: read_string_from_env_then_parse::<u32>("GENESIS_HEIGHT")?,
193 genesis_chain_state_hash: convert_hex_string_to_bytes(
194 &read_string_from_env_then_parse::<String>("GENESIS_CHAIN_STATE_HASH")?,
195 )?,
196 latest_blockhash_timeout_timelock: read_string_from_env_then_parse::<u16>(
197 "LATEST_BLOCKHASH_TIMEOUT_TIMELOCK",
198 )?,
199 bridge_nonstandard: read_string_from_env_then_parse::<bool>("BRIDGE_NONSTANDARD")?,
200 };
201
202 if config.finality_depth < 1 {
203 return Err(BridgeError::ConfigError(
204 "Finality depth must be at least 1".to_string(),
205 ));
206 }
207
208 Ok(config)
209 }
210
211 pub fn default_utxo_amount(&self) -> Amount {
212 if self.bridge_nonstandard {
213 Amount::from_sat(0)
214 } else {
215 MIN_TAPROOT_AMOUNT
216 }
217 }
218
219 pub fn anchor_amount(&self) -> Amount {
220 if self.bridge_nonstandard {
221 Amount::from_sat(0)
222 } else {
223 NON_EPHEMERAL_ANCHOR_AMOUNT
224 }
225 }
226
227 pub fn is_block_finalized(&self, block_height: u32, chain_tip_height: u32) -> bool {
230 if block_height > chain_tip_height {
231 return false;
232 }
233
234 chain_tip_height - block_height + 1 >= self.finality_depth
235 }
236
237 pub fn bridge_circuit_constant(&self) -> Result<&[u8; 32], BridgeError> {
238 match self.network {
239 Network::Regtest => {
240 if is_dev_mode() {
241 Ok(®TEST_TEST_BRIDGE_CIRCUIT_CONSTANT)
242 } else {
243 Ok(®TEST_BRIDGE_CIRCUIT_CONSTANT)
244 }
245 }
246 Network::Bitcoin => Ok(&MAINNET_BRIDGE_CIRCUIT_CONSTANT),
247 Network::Testnet4 => {
248 if is_dev_mode() {
249 Ok(&TESTNET4_TEST_BRIDGE_CIRCUIT_CONSTANT)
250 } else {
251 Ok(&TESTNET4_BRIDGE_CIRCUIT_CONSTANT)
252 }
253 }
254 Network::Signet => {
255 if is_dev_mode() {
256 Ok(&SIGNET_TEST_BRIDGE_CIRCUIT_CONSTANT)
257 } else {
258 Ok(&SIGNET_BRIDGE_CIRCUIT_CONSTANT)
259 }
260 }
261 _ => Err(BridgeError::UnsupportedNetwork),
262 }
263 }
264
265 pub fn get_lcp_image_id(&self) -> Result<[u8; 32], BridgeError> {
267 Ok(match self.network {
268 bitcoin::Network::Bitcoin => MAINNET_LC_IMAGE_ID,
269 bitcoin::Network::Testnet4 => TESTNET4_LC_IMAGE_ID,
270 bitcoin::Network::Signet => DEVNET_LC_IMAGE_ID,
271 bitcoin::Network::Regtest => REGTEST_LC_IMAGE_ID,
272 _ => return Err(eyre::eyre!("Unsupported Bitcoin network").into()),
273 })
274 }
275
276 pub fn is_regtest(&self) -> bool {
277 self.network == Network::Regtest
278 }
279}
280
281fn convert_hex_string_to_bytes(hex: &str) -> Result<[u8; 32], BridgeError> {
282 let hex_decode = hex::decode(hex).wrap_err("Failed to decode hex string")?;
283 let hex_bytes: [u8; 32] = hex_decode
284 .as_slice()
285 .try_into()
286 .wrap_err("Hex string is not 32 bytes")?;
287 Ok(hex_bytes)
288}
289
290impl Default for ProtocolParamset {
291 fn default() -> Self {
292 REGTEST_PARAMSET
293 }
294}
295impl Default for &'static ProtocolParamset {
296 fn default() -> Self {
297 ®TEST_PARAMSET
298 }
299}
300
301pub const REGTEST_PARAMSET: ProtocolParamset = ProtocolParamset {
302 network: Network::Regtest,
303 num_round_txs: 2,
304 num_kickoffs_per_round: 10,
305 num_signed_kickoffs: 2,
306 bridge_amount: Amount::from_sat(1_000_000_000),
307 kickoff_amount: Amount::from_sat(0),
308 operator_challenge_amount: Amount::from_sat(200_000_000),
309 collateral_funding_amount: Amount::from_sat(99_000_000),
310 watchtower_challenge_bytes: 144,
311 kickoff_blockhash_commit_length: 40,
312 winternitz_log_d: WINTERNITZ_LOG_D,
313 user_takes_after: 200,
314 operator_challenge_timeout_timelock: 4 * BLOCKS_PER_HOUR,
315 operator_challenge_nack_timelock: 4 * BLOCKS_PER_HOUR * 3,
316 disprove_timeout_timelock: 4 * BLOCKS_PER_HOUR * 5,
317 assert_timeout_timelock: 4 * BLOCKS_PER_HOUR * 4,
318 operator_reimburse_timelock: 2,
319 watchtower_challenge_timeout_timelock: 4 * BLOCKS_PER_HOUR * 2,
320 latest_blockhash_timeout_timelock: 4 * BLOCKS_PER_HOUR * 5 / 2,
321 finality_depth: 5, start_height: 190,
323 genesis_height: 0,
324 genesis_chain_state_hash: [
325 95, 115, 2, 173, 22, 200, 189, 158, 242, 243, 190, 0, 200, 25, 154, 134, 249, 224, 186,
326 134, 20, 132, 171, 180, 175, 95, 126, 69, 127, 140, 34, 22,
327 ],
328 bridge_nonstandard: true,
329};
330
331pub const TESTNET4_TEST_PARAMSET: ProtocolParamset = ProtocolParamset {
332 network: Network::Testnet4,
333 num_round_txs: 2,
334 num_kickoffs_per_round: 10,
335 num_signed_kickoffs: 2,
336 bridge_amount: Amount::from_sat(1_000_000),
337 kickoff_amount: Amount::from_sat(0),
338 operator_challenge_amount: Amount::from_sat(200_000),
339 collateral_funding_amount: Amount::from_sat(99_000),
340 watchtower_challenge_bytes: 144,
341 kickoff_blockhash_commit_length: 40,
342 winternitz_log_d: WINTERNITZ_LOG_D,
343 user_takes_after: 200,
344 operator_challenge_timeout_timelock: 4 * BLOCKS_PER_HOUR,
345 operator_challenge_nack_timelock: 4 * BLOCKS_PER_HOUR * 3,
346 disprove_timeout_timelock: 4 * BLOCKS_PER_HOUR * 5,
347 assert_timeout_timelock: 4 * BLOCKS_PER_HOUR * 4,
348 operator_reimburse_timelock: 2,
349 watchtower_challenge_timeout_timelock: 4 * BLOCKS_PER_HOUR * 2,
350 latest_blockhash_timeout_timelock: 4 * BLOCKS_PER_HOUR * 5 / 2,
351 finality_depth: 1,
352 start_height: 92700,
353 genesis_height: 92700,
354 genesis_chain_state_hash: [
355 0xe4, 0xe1, 0x28, 0xa8, 0x99, 0xaf, 0xee, 0xb1, 0x85, 0x5b, 0x4a, 0xb7, 0x2e, 0x4d, 0x88,
356 0x50, 0xab, 0x35, 0x1b, 0xde, 0xf9, 0x4f, 0xc2, 0x78, 0xe8, 0x5c, 0x13, 0x11, 0xe2, 0x72,
357 0xfe, 0x6a,
358 ],
359 bridge_nonstandard: true,
360};
361
362pub const REGTEST_TEST_BRIDGE_CIRCUIT_CONSTANT: [u8; 32] = [
363 114, 212, 219, 106, 251, 50, 248, 9, 2, 194, 84, 239, 229, 92, 195, 40, 218, 21, 55, 242, 230,
364 201, 145, 209, 251, 25, 77, 124, 129, 131, 194, 20,
365];
366
367pub const REGTEST_BRIDGE_CIRCUIT_CONSTANT: [u8; 32] = [
368 233, 84, 200, 234, 120, 196, 185, 119, 174, 126, 140, 238, 189, 210, 149, 97, 161, 4, 229, 219,
369 47, 124, 117, 197, 89, 165, 120, 138, 221, 74, 157, 71,
370];
371
372pub const SIGNET_BRIDGE_CIRCUIT_CONSTANT: [u8; 32] = [
373 73, 219, 48, 6, 223, 104, 179, 207, 180, 104, 112, 231, 210, 2, 0, 47, 87, 166, 183, 168, 211,
374 250, 76, 145, 200, 214, 169, 135, 151, 47, 202, 184,
375];
376
377pub const SIGNET_TEST_BRIDGE_CIRCUIT_CONSTANT: [u8; 32] = [
378 234, 217, 1, 13, 50, 162, 237, 187, 139, 172, 117, 214, 39, 142, 252, 26, 47, 173, 67, 109, 98,
379 47, 59, 121, 185, 133, 184, 164, 241, 44, 113, 58,
380];
381
382pub const MAINNET_BRIDGE_CIRCUIT_CONSTANT: [u8; 32] = [
383 154, 254, 2, 67, 66, 37, 230, 195, 3, 247, 101, 4, 196, 126, 226, 135, 163, 6, 165, 124, 119,
384 3, 143, 171, 85, 55, 9, 250, 45, 12, 140, 64,
385];
386
387pub const TESTNET4_BRIDGE_CIRCUIT_CONSTANT: [u8; 32] = [
388 123, 6, 8, 84, 79, 122, 249, 123, 48, 241, 129, 10, 215, 65, 243, 68, 174, 66, 239, 146, 1, 75,
389 168, 108, 46, 59, 223, 127, 125, 127, 97, 90,
390];
391
392pub const TESTNET4_TEST_BRIDGE_CIRCUIT_CONSTANT: [u8; 32] = [
393 83, 191, 166, 41, 241, 95, 11, 84, 148, 1, 21, 128, 190, 167, 207, 165, 143, 209, 232, 169,
394 211, 120, 188, 115, 219, 48, 108, 224, 129, 254, 54, 214,
395];
396
397#[cfg(test)]
398mod tests {
399 use bridge_circuit_host::{
400 bridge_circuit_host::{
401 MAINNET_BRIDGE_CIRCUIT_ELF, REGTEST_BRIDGE_CIRCUIT_ELF, SIGNET_BRIDGE_CIRCUIT_ELF,
402 SIGNET_BRIDGE_CIRCUIT_ELF_TEST, TESTNET4_BRIDGE_CIRCUIT_ELF,
403 TESTNET4_BRIDGE_CIRCUIT_ELF_TEST,
404 },
405 utils::calculate_succinct_output_prefix,
406 };
407 use circuits_lib::{
408 bridge_circuit::constants::{
409 MAINNET_WORK_ONLY_METHOD_ID, REGTEST_WORK_ONLY_METHOD_ID, SIGNET_WORK_ONLY_METHOD_ID,
410 TESTNET4_WORK_ONLY_METHOD_ID,
411 },
412 common::constants::{
413 MAINNET_HEADER_CHAIN_METHOD_ID, REGTEST_HEADER_CHAIN_METHOD_ID,
414 SIGNET_HEADER_CHAIN_METHOD_ID, TESTNET4_HEADER_CHAIN_METHOD_ID,
415 },
416 };
417 use risc0_zkvm::compute_image_id;
418
419 use bridge_circuit_host::bridge_circuit_host::{
420 MAINNET_HEADER_CHAIN_ELF, MAINNET_WORK_ONLY_ELF, REGTEST_HEADER_CHAIN_ELF,
421 REGTEST_WORK_ONLY_ELF, SIGNET_HEADER_CHAIN_ELF, SIGNET_WORK_ONLY_ELF,
422 TESTNET4_HEADER_CHAIN_ELF, TESTNET4_WORK_ONLY_ELF,
423 };
424
425 use super::*;
426
427 #[test]
428 fn test_regtest_test_bridge_circuit_constant() {
429 let regtest_bridge_elf =
430 include_bytes!("../../../risc0-circuits/elfs/test-regtest-bridge-circuit-guest.bin");
431 let regtest_bridge_circuit_method_id =
432 compute_image_id(regtest_bridge_elf).expect("should compute image id");
433 let calculated_regtest_bridge_circuit_constant =
434 calculate_succinct_output_prefix(regtest_bridge_circuit_method_id.as_bytes());
435
436 let regtest_bridge_circuit_constant = REGTEST_TEST_BRIDGE_CIRCUIT_CONSTANT;
437 assert_eq!(
438 calculated_regtest_bridge_circuit_constant,
439 regtest_bridge_circuit_constant,
440 "You forgot to update regtest-(test) bridge_circuit_constant with the new method id. Please change it in these places: core/src/config/protocol.rs. The expected value is: {:?}, hex format: {:?}",
441 calculated_regtest_bridge_circuit_constant,
442 hex::encode(calculated_regtest_bridge_circuit_constant)
443 );
444 }
445
446 #[test]
447 fn test_regtest_bridge_circuit_constant() {
448 let regtest_bridge_elf = REGTEST_BRIDGE_CIRCUIT_ELF;
449 let regtest_bridge_circuit_method_id =
450 compute_image_id(regtest_bridge_elf).expect("should compute image id");
451 let calculated_regtest_bridge_circuit_constant =
452 calculate_succinct_output_prefix(regtest_bridge_circuit_method_id.as_bytes());
453
454 let regtest_bridge_circuit_constant = REGTEST_BRIDGE_CIRCUIT_CONSTANT;
455 assert_eq!(
456 calculated_regtest_bridge_circuit_constant,
457 regtest_bridge_circuit_constant,
458 "You forgot to update regtest bridge_circuit_constant with the new method id. Please change it in these places: core/src/config/protocol.rs. The expected value is: {:?}, hex format: {:?}",
459 calculated_regtest_bridge_circuit_constant,
460 hex::encode(calculated_regtest_bridge_circuit_constant)
461 );
462 }
463
464 #[test]
465 fn test_mainnet_bridge_circuit_constant() {
466 let mainnet_bridge_elf = MAINNET_BRIDGE_CIRCUIT_ELF;
467 let mainnet_bridge_circuit_method_id =
468 compute_image_id(mainnet_bridge_elf).expect("should compute image id");
469 let calculated_mainnet_bridge_circuit_constant =
470 calculate_succinct_output_prefix(mainnet_bridge_circuit_method_id.as_bytes());
471
472 let mainnet_bridge_circuit_constant = MAINNET_BRIDGE_CIRCUIT_CONSTANT;
473 assert_eq!(
474 calculated_mainnet_bridge_circuit_constant,
475 mainnet_bridge_circuit_constant,
476 "You forgot to update mainnet bridge_circuit_constant with the new method id. Please change it in these places: core/src/config/protocol.rs. The expected value is: {:?}, hex format: {:?}",
477 calculated_mainnet_bridge_circuit_constant,
478 hex::encode(calculated_mainnet_bridge_circuit_constant)
479 );
480 }
481
482 #[test]
483 fn test_testnet4_bridge_circuit_constant() {
484 let testnet4_bridge_elf = TESTNET4_BRIDGE_CIRCUIT_ELF;
485 let testnet4_bridge_circuit_method_id =
486 compute_image_id(testnet4_bridge_elf).expect("should compute image id");
487 let calculated_testnet4_bridge_circuit_constant =
488 calculate_succinct_output_prefix(testnet4_bridge_circuit_method_id.as_bytes());
489
490 let testnet4_bridge_circuit_constant = TESTNET4_BRIDGE_CIRCUIT_CONSTANT;
491 assert_eq!(
492 calculated_testnet4_bridge_circuit_constant,
493 testnet4_bridge_circuit_constant,
494 "You forgot to update testnet4 bridge_circuit_constant with the new method id. Please change it in these places: core/src/config/protocol.rs. The expected value is: {:?}, hex format: {:?}",
495 calculated_testnet4_bridge_circuit_constant,
496 hex::encode(calculated_testnet4_bridge_circuit_constant)
497 );
498 }
499
500 #[test]
501 fn test_testnet4_test_bridge_circuit_constant() {
502 let testnet4_bridge_elf = TESTNET4_BRIDGE_CIRCUIT_ELF_TEST;
503 let testnet4_bridge_circuit_method_id =
504 compute_image_id(testnet4_bridge_elf).expect("should compute image id");
505 let calculated_testnet4_bridge_circuit_constant =
506 calculate_succinct_output_prefix(testnet4_bridge_circuit_method_id.as_bytes());
507
508 let testnet4_bridge_circuit_constant = TESTNET4_TEST_BRIDGE_CIRCUIT_CONSTANT;
509 assert_eq!(
510 calculated_testnet4_bridge_circuit_constant,
511 testnet4_bridge_circuit_constant,
512 "You forgot to update testnet4-test bridge_circuit_constant with the new method id. Please change it in these places: core/src/config/protocol.rs. The expected value is: {:?}, hex format: {:?}",
513 calculated_testnet4_bridge_circuit_constant,
514 hex::encode(calculated_testnet4_bridge_circuit_constant)
515 );
516 }
517
518 #[test]
519 fn test_signet_bridge_circuit_constant() {
520 let signet_bridge_elf = SIGNET_BRIDGE_CIRCUIT_ELF;
521 let signet_bridge_circuit_method_id =
522 compute_image_id(signet_bridge_elf).expect("should compute image id");
523 let calculated_signet_bridge_circuit_constant =
524 calculate_succinct_output_prefix(signet_bridge_circuit_method_id.as_bytes());
525
526 let signet_bridge_circuit_constant = SIGNET_BRIDGE_CIRCUIT_CONSTANT;
527 assert_eq!(
528 calculated_signet_bridge_circuit_constant,
529 signet_bridge_circuit_constant,
530 "You forgot to update signet bridge_circuit_constant with the new method id. Please change it in these places: core/src/config/protocol.rs. The expected value is: {:?}, hex format: {:?}",
531 calculated_signet_bridge_circuit_constant,
532 hex::encode(calculated_signet_bridge_circuit_constant)
533 );
534 }
535
536 #[test]
537 fn test_signet_test_bridge_circuit_constant() {
538 let signet_bridge_elf = SIGNET_BRIDGE_CIRCUIT_ELF_TEST;
539 let signet_bridge_circuit_method_id =
540 compute_image_id(signet_bridge_elf).expect("should compute image id");
541 let calculated_signet_bridge_circuit_constant =
542 calculate_succinct_output_prefix(signet_bridge_circuit_method_id.as_bytes());
543
544 let signet_bridge_circuit_constant = SIGNET_TEST_BRIDGE_CIRCUIT_CONSTANT;
545 assert_eq!(
546 calculated_signet_bridge_circuit_constant,
547 signet_bridge_circuit_constant,
548 "You forgot to update signet-test bridge_circuit_constant with the new method id. Please change it in these places: core/src/config/protocol.rs. The expected value is: {:?}, hex format: {:?}",
549 calculated_signet_bridge_circuit_constant,
550 hex::encode(calculated_signet_bridge_circuit_constant)
551 );
552 }
553
554 #[test]
555 fn test_header_chain_method_ids() {
556 let networks = [
557 (
558 MAINNET_HEADER_CHAIN_ELF,
559 MAINNET_HEADER_CHAIN_METHOD_ID,
560 "mainnet",
561 ),
562 (
563 TESTNET4_HEADER_CHAIN_ELF,
564 TESTNET4_HEADER_CHAIN_METHOD_ID,
565 "testnet4",
566 ),
567 (
568 SIGNET_HEADER_CHAIN_ELF,
569 SIGNET_HEADER_CHAIN_METHOD_ID,
570 "signet",
571 ),
572 (
573 REGTEST_HEADER_CHAIN_ELF,
574 REGTEST_HEADER_CHAIN_METHOD_ID,
575 "regtest",
576 ),
577 ];
578
579 for (elf, method_id, network) in networks.into_iter() {
580 let header_chain_circuit_method_id = compute_image_id(elf);
581 assert_eq!(
582 header_chain_circuit_method_id.expect("should compute image id").as_words(),
583 method_id,
584 "Header chain method ID mismatch for {network}, please update the constant here: circuits-lib/src/common/constants.rs",
585 );
586 }
587 }
588
589 #[test]
590 fn test_work_only_method_ids() {
591 let networks = [
592 (
593 MAINNET_WORK_ONLY_ELF,
594 MAINNET_WORK_ONLY_METHOD_ID,
595 "mainnet",
596 ),
597 (
598 TESTNET4_WORK_ONLY_ELF,
599 TESTNET4_WORK_ONLY_METHOD_ID,
600 "testnet4",
601 ),
602 (SIGNET_WORK_ONLY_ELF, SIGNET_WORK_ONLY_METHOD_ID, "signet"),
603 (
604 REGTEST_WORK_ONLY_ELF,
605 REGTEST_WORK_ONLY_METHOD_ID,
606 "regtest",
607 ),
608 ];
609
610 for (elf, method_id, network) in networks.into_iter() {
611 let work_only_circuit_method_id =
612 compute_image_id(elf).expect("should compute image id");
613 let current_method_id = work_only_circuit_method_id.as_bytes();
614 assert_eq!(
615 current_method_id,
616 method_id,
617 "Work only method ID mismatch for {network}, please update the constant here: circuits-lib/src/bridge_circuit/constants.rs. Hex format of correct value: {:?}",
618 hex::encode(current_method_id)
619 );
620 }
621 }
622}