diff --git a/configuration/src/addresses.rs b/configuration/src/addresses.rs index 4574149d..e7d9f8f0 100644 --- a/configuration/src/addresses.rs +++ b/configuration/src/addresses.rs @@ -85,7 +85,7 @@ fn deny_if_dns_private(host: &str) -> Result<(), AddressesError> { /// Validates configuration URLs with security enforcement. /// Production: HTTPS. Debug: HTTP allowed for localhost/test containers. -fn validate_config_url(raw: &str) -> Result { +pub fn validate_config_url(raw: &str) -> Result { let url = Url::parse(raw).map_err(|_| AddressesError::Toml(format!("Invalid URL: {raw}")))?; let host = url @@ -137,7 +137,8 @@ fn validate_config_url(raw: &str) -> Result { } // Scheme enforcement: HTTPS only in production - if url.scheme() != "https" && !is_development { + let is_production = matches!(run_mode.as_str(), "production"); + if url.scheme() != "https" && is_production { let scheme = url.scheme(); warn!("HTTP not allowed in production, use HTTPS"); return Err(AddressesError::Toml(format!( @@ -170,7 +171,7 @@ pub fn get_addresses() -> &'static Addresses { } } let base = validate_config_url(&settings.configuration_url).expect("Invalid or untrusted configuration URL"); - let url = base.join("addresses").expect("Could not parse addresses server endpoint"); + let url = base.join("configuration/toml/addresses.toml").expect("Could not parse addresses server endpoint"); // Retry logic: wait for deployer to finish and save addresses let max_attempts = 32; let mut wait_time = 2; diff --git a/docker-compose.yml b/docker-compose.yml index 5ea6b09a..ff536946 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -208,7 +208,7 @@ services: stdin_open: true # keep stdin open, so we can print things in docker compose up tty: true # required for logs to print in colour environment: - - NF4_RUN_MODE=${NF4_RUN_MODE:-base_sepolia} + - NF4_RUN_MODE=${NF4_RUN_MODE:-sepolia} - RUST_BACKTRACE=${RUST_BACKTRACE:-0} - NF4_SIGNING_KEY=${PROPOSER_SIGNING_KEY} - NF4_MOCK_PROVER=${NF4_MOCK_PROVER:-false} @@ -564,7 +564,7 @@ services: volumes: # mongodb_client_data: # mongodb_client2_data: - # mongodb_proposer_data: + mongodb_proposer_data: address_data: networks: diff --git a/lib/src/verify_contract.rs b/lib/src/verify_contract.rs index 5d80194c..0d63e4ca 100644 --- a/lib/src/verify_contract.rs +++ b/lib/src/verify_contract.rs @@ -2,14 +2,17 @@ use alloy::{ primitives::{keccak256, Address, B256}, providers::Provider, }; - -use configuration::addresses::Addresses; +use configuration::settings::Settings; use nightfall_bindings::artifacts::{Nightfall, RoundRobin, X509}; use nightfall_bindings::artifacts::{ Nightfall::NightfallInstance, RoundRobin::RoundRobinInstance, X509::X509Instance, }; use serde::Deserialize; use std::path::PathBuf; +use eyre::eyre; +use configuration::addresses::AddressesError; +use configuration::addresses::validate_config_url; +use configuration::addresses::Addresses; #[derive(Deserialize)] struct ContractHashes { @@ -19,17 +22,34 @@ struct ContractHashes { } /// Load deployed contract hashes from file written by deployer -fn load_deployed_hashes() -> eyre::Result<([u8; 32], [u8; 32], [u8; 32])> { +pub async fn load_deployed_hashes() -> eyre::Result<([u8; 32], [u8; 32], [u8; 32])> { let hashes_path = PathBuf::from("/app/configuration/toml/contract_hashes.toml"); + let settings = Settings::new().map_err(|_| AddressesError::Settings)?; - if !hashes_path.exists() { - eyre::bail!( - "Contract hashes file not found. Deployer must run first to generate {:?}", - hashes_path - ); - } - - let content = std::fs::read_to_string(&hashes_path)?; + let content = if hashes_path.exists() { + std::fs::read_to_string(&hashes_path)? + } else { + // Fallback to remote configuration server + let base = validate_config_url(&settings.configuration_url) + .map_err(|e| eyre!("Invalid or untrusted configuration URL: {}", e))?; + + let url = base + .join("configuration/toml/contract_hashes.toml") + .map_err(|e| eyre!("Could not build contract hashes URL: {}", e))?; + + let response = reqwest::get(url.clone()).await + .map_err(|e| eyre!("Failed to fetch contract hashes from {}: {}", url, e))?; + + if !response.status().is_success() { + return Err(eyre!( + "Configuration server returned error {} for {}", + response.status(), + url + )); + } + + response.text().await? + }; let hashes: ContractHashes = toml::from_str(&content)?; let nightfall = hex::decode(&hashes.nightfall_hash) @@ -196,7 +216,7 @@ impl VerifiedContracts

{ ); // Load the expected hashes from the file written by deployer - let (nightfall_hash, round_robin_hash, x509_hash) = load_deployed_hashes()?; + let (nightfall_hash, round_robin_hash, x509_hash) = load_deployed_hashes().await?; // Verify each contract's deployed implementation verify_impl_hash(&provider, addresses.nightfall, &nightfall_hash, "Nightfall").await?; diff --git a/nightfall.toml b/nightfall.toml index 0c848794..90df34d9 100644 --- a/nightfall.toml +++ b/nightfall.toml @@ -3,6 +3,137 @@ # Select a configuration by setting the environment variable NF4_RUN_MODE to the desired section name, e.g. NF4_RUN_MODE="production" # +[sepolia] +signing_key = "" +azure_vault_url = "vault url is not set" +azure_key_name = "key name not set" +log_app_only = true +test_x509_certificates = true +mock_prover = false +genesis_block = 0 +ethereum_client_url = "wss://eth-sepolia.g.alchemy.com/v2/NjACEiAIuOIsZBd7dsIF_" +configuration_url = "http://35.225.105.10:8080" # The name of the proposer config to use can be overridden by env var NF4_PROPOSER_CONFIG + + +[sepolia.network] +chain_id = 11155111 + +[sepolia.nightfall_client] +url = "http://client:3000" +log_level = "info" +wallet_type = "local" +db_url = "mongodb://nf4_db_client:27017" +max_event_listener_attempts = 10 +webhook_url = "http://172.18.0.250:8080/webhook" # The webhook URL for the client to send notifications to the propose +max_queue_size = 1000 + +[sepolia.nightfall_proposer] +url = "http://35.225.105.10:3001" +log_level = "info" +wallet_type = "local" +db_url = "mongodb://nf4_db_proposer:27017" +block_assembly_max_wait_secs = 120 +block_assembly_target_fill_ratio = 0.25 +block_assembly_initial_interval_secs = 15 +max_event_listener_attempts = 10 +block_size = 64 + +[sepolia.verifier] +# VK values that the UUPS provider will initialize with +domain_size = 0x2000000 +num_inputs = 0x1 +# Sigma commitments (G1) +sigma_comms_1 = ["0x224aa1e86aa1f1befc63eb7dca0b5933e01f712d95f3a573d92a66efd4b31f60", "0x25f81419c20cd2459e03611d1a3c9339086697876a38b56351df5cb19a7f11ee"] +sigma_comms_2 = ["0xee3ddea5323d9368ed8ccbf50e47f1307ab2a8df47192678f1a9d6329d38ca7", "0x1a4d3eb6cde54c6c52f103b69e3daa37eb46eca3f2a0960df9ae6f6f2c4da8c9"] +sigma_comms_3 = ["0xed11832565538b32a2be9e70ce9eed6b09fd8dcd82e9af87320d2ab5ea1fe9f", "0x17492bbd308b64f54f6baa250c5b523f6c651f4c22210fecbe9799dcf3088d0f"] +sigma_comms_4 = ["0x12f72ea1e0b638e16534d521629b401b42653a505ce1b65bbf682c86c0e1cf3", "0x1af843eb6d58f88397a60932bf485a0215f59f320bbc53d8b6f2334f4249f0ff"] +sigma_comms_5 = ["0x13842fddc8a50704d9a464ed76b0ad1e2badd8e71a362cea8642bd43f195c9d2", "0x1f7d04850eb0775cdeacc96b4d037e22379a41bbf8ce2eb44025cd3acc8f7b45"] +sigma_comms_6 = ["0xef67b9aed33ca744b467dfe54b10588e85c69dd4e1a0ccc482dac77ca6434f4", "0x135309095418997c1acc374386206df445af8046ec0213f1c36f467629860fac"] +# Selector commitments (G1) +selector_comms_1 = ["0x21cf3183e15d395f472df27276929872fce24077b9c2ef3a2f5edc74d309fa6f", "0x23db370ed5fa8b8c069c4a138ee073ea75bf066c8197093841f337e3b5908d23"] +selector_comms_2 = ["0x21356c841d6d4fa77c776d0592feb7be7a8a5461e64a2f1c0fbf9baa261f28cb", "0x22476ebc7c5f1dbe4ccdac48262e33ee3201e62876b8e0dc6146880a98cd7b19"] +selector_comms_3 = ["0x213a4b0a0e2489ad2f44b7208fb4a72387dd92c68b03cf00fe6b137273fc6bf9", "0x1fbfc0e404f50ddc2f80a8224fa040e6ad87b653bd69692d8da8da69cc66e45e"] +selector_comms_4 = ["0x26500f9857b909578887562a24e5eeb00aa6225c3abc211d6a9948c7ad6d900b", "0x3057a638850f561e457865b2fb18e4883b4137ddaf3866eb14c3f8645244d008"] +selector_comms_5 = ["0x90c2b10408f52a49208558c48f6c9e9f1d9027a6e0714d92cd8edfeedf428b", "0x287202d8457a299381e4ef7fa8870f4187a4a99fe414bda0eb9eb213459b8032"] +selector_comms_6 = ["0x6d4d75f7f9ac52cd3ff6a00dc5432fac71b81c95c10b0b6a0cf6c6ad842f82a", "0x21b1a022d8fa08c5877fc29aae4dd10a0bee624b82ef58d9ca2bd885ecaa773c"] +selector_comms_7 = ["0x14fc4c0d862ac23877c9326b88ab6efbdef47ec62925575f07f83bcf012e2e49", "0x2a3162b250bd3f59ce9c425445447a477ab9017a1a67b056592afdd474d3693f"] +selector_comms_8 = ["0x13e081900816842f9e7b6ec2340c6b434d05d061fc72a7613239ae3674f654ee", "0x2077c4369dbb9ad5e11f8dc5c67cf91d055954043a44ff55c887b7b332e1601a"] +selector_comms_9 = ["0x8f35ec1a09b83fe7a89795eef68a71a73ea69164d17ea74e424c18a27cfd154", "0x2da03fa8184b74751c2cddd462510f77807619b5e0a5cb2269e0c2d34c550042"] +selector_comms_10 = ["0x1c980fee742192d7461f564307a8a0cdd469203d4c239c9daf7734d3e25a57af", "0x2d6c75cfc5991b321572cf1a19e0bbadbcadc790101ba3d45bd7110b8b19bdf4"] +selector_comms_11 = ["0x20e8848cb6a4ce2a70e912a954701aff7cc826fb815cf5aa67dce6cb04289d97", "0x31ada280955d6dd78af6d8d63d6dd4d9397bcc5d8ed4af4beb3c466344c9917"] +selector_comms_12 = ["0x15dcbcddb5b26fb6f446047867f51a44ad686b0f68d4d10e94cad7380dcd07a3", "0x1235790b118ca52b2cab3a983d5c7a1ec67827f6704fb747dfb81cac918c45b4"] +selector_comms_13 = ["0x2ae965fefef7a4b2df802a01cfd6d3a2cef4b4309dcd6716a65c829ec304bf52", "0x281f365e16247924b2bd5d2c6467b31ccc3692693a98cfc67f741c089fc5fb3"] +selector_comms_14 = ["0x2fbe8998140323372ac4b68dc400a176f197b6abfdfac3489e410ea772e0a5fa", "0x5c1c6088a434a9925c9e290bc1fb22f05580a3b28e3fbe5a4cdf1a222525960"] +selector_comms_15 = ["0x2937f3d6c6d90b1641899b0af223b7b4254f79dd37ea9c404a7d2e163b6861b7", "0xcd18a059ce70ff69a92c6f8f3b41e688c685a48d960080a0ff7a08c3b301ceb"] +selector_comms_16 = ["0x23585175e379d41275caee601c012a4ca0183693810bde68d02a85d563a398b3", "0x1a6ea9cb335d3f4bb22fdec28497ba8048bf4d0b73351557b3412ee032cc080c"] +selector_comms_17 = ["0x551412252183d89a4bc0de5fabb821a2ed129c9b49f31d148b5f1150f26e1cf", "0x162f5aa78e941410582b437daa750caf997c0f30b5875a4c0aec153fa691aa16"] +selector_comms_18 = ["0x14fcee171c8bf03b333a70d359b2a668ca28cca1707004d67118e7174a8e0d0d", "0x1719b3e69e1d1d21c0ae93122a1d152fa52cb1e900642f91865219078fedf11b"] +# Scalars +k1 = "0x1" +k2 = "0x2f8dd1f1a7583c42c4e12a44e110404c73ca6c94813f85835da4fb7bb1301d4a" +k3 = "0x1ee678a0470a75a6eaa8fe837060498ba828a3703b311d0f77f010424afeb025" +k4 = "0x2042a587a90c187b0a087c03e29c968b950b1db26d5c82d666905a6895790c0a" +k5 = "0x2e2b91456103698adf57b799969dea1c8f739da5d8d40dd3eb9222db7c81e881" +k6 = "0x1f20f5b0adb417179d42df7ddd4410a330afdb03e5c28949665b55adf7d7922d" +# Commitments (G1) +range_table_comm = ["0x1845622f9012f44d4d9b492a254a360ab98914fda5d90031b0a78009cbae56b8", "0x2da38747c37c85b6815a9ac706a061274eaae8f7cfb4e3c83ad4112ba8dcc18f"] +key_table_comm = ["0x2cd3d4b52c4e81a0230fdc2afb118f488f76df3cbb474e688c21cdee5f1274ff", "0x21889c2f2692386e405ffab0d2241794f4b4431e3265d97f42ee7e77894196db"] +table_dom_sep_comm = ["0x3735500ca623cc3fddb6a85a133599035e252fe10286c214f5ea8d1aff8dd34", "0x1f6fff4e2027f91a1cab2cdf2ba43331f8a2bae93bba9659fbc7a6f25d87740c"] +q_dom_sep_comm = ["0x1926d85f74e52438d6ddb98c5e8c21aebdf9d351b907df73e5c3198708371281", "0x2dfa10125652bdee92111199fcb7a4469cc346e1a2e1c970b266562e07ce377b"] +# Group parameters +size_inv = "0x30644e5aaf0a66b91f8030da595e7d1c6787b9b45fc54c546729acf1ff053609" +group_gen = "0x2a734ebb326341efa19b0361d9130cd47b26b7488dc6d26eeccd4f3eb878331a" +group_gen_inv = "0x27f035bdb21de9525bcd0d50e993ee185f43327bf6a8efc445d2f3cb9550fe47" +# Open key (G1) +open_key_g = ["0x1", "0x2"] +# G2 points +h = ["0x198e9393920d483a7260bfb731fb5d25f1aa493335a9e71297e485b7aef312c2", "0x1800deef121f1e76426a00665e5c4479674322d4f75edadd46debd5cd992f6ed", "0x90689d0585ff075ec9e99ad690c3395bc4b313370b38ef355acdadcd122975b", "0x12c85ea5db8c6deb4aab71808dcb408fe3d1e7690c43d37b4ce6cc0166fa7daa"] +beta_h = ["0x1111", "0x285b1f14edd7e6632340a37dfae9005ff762edcfecfe1c732a7474c0708bef80", "0x219edfceee1723de674f5b2f6fdb69d9e32dd53b15844956a630d3c7cdaa6ed9", "0x2bad9a374aec49d329ec66e8f530f68509313450580c4c17c6db5ddb9bde7fd0"] + +[sepolia.owners] +vk_provider_owner = "0xa0Ee7A142d267C1f36714E4a8F75612F20a79720" # Anvil account (9) +x509_owner = "0xa0Ee7A142d267C1f36714E4a8F75612F20a79720" # Anvil account (9) +verifier_owner = "0xa0Ee7A142d267C1f36714E4a8F75612F20a79720" # Anvil account (9) +round_robin_owner = "0xa0Ee7A142d267C1f36714E4a8F75612F20a79720" # Anvil account (9) +nightfall_owner = "0xa0Ee7A142d267C1f36714E4a8F75612F20a79720" # Anvil account (9) + +[sepolia.nightfall_deployer] +log_level = "info" +default_proposer_address = "0x52A57DD934B864e2f6a4AFE08f94E3068Ff5a420" +default_proposer_url = "http://35.225.105.10:3001" +proposer_stake = 4 +proposer_ding = 3 # how much to fine a proposer for not making a block +proposer_exit_penalty = 2 # how much to fine a proposer for deregister during its turn +proposer_cooling_blocks = 4 # how many blocks before a de-registered proposer can register again +proposer_rotation_blocks = 4 # how many blocks before we rotate proposers +proposer_grace_blocks = 1 # how many blocks of inactivity allowed before anyone can skip the current proposer +[sepolia.nightfall_test] +log_level = "info" + +[sepolia.contracts] +assets = "./blockchain_assets/artifacts" +deployment_file = "./blockchain_assets/logs/deployer.s.sol" +deploy_contracts = true + +[sepolia.contracts.contract_addresses] # Contract addresses for the development network. These are used if deploy_contracts is false and they are not empty +nightfall = "" +round_robin = "" +x509 = "" +verifier = "" + +[sepolia.certificates] +authority_key_identifier = "0xA469FF28BFAB9C4DB09220B24038D6F18EA57F75" +modulus = "0x009DEA9DCA80BFA87C29232B18D6C0072898922A7E7E224A7FF638F61851B5F36392E7FBFDBFF3A0AE409763E2A04CDD3DC692A6DE447391FFE6722456957DD7F031B8D9A7999579F6F4258490AE6E9D629BC40815F689C58037C03B46502243BFD29B02116454453810D160DE1D8C8DDD624B30A25A011185E60BCA9BF71181DD3256112F1EFDBECF19E77AF9640EDE4DB8FF51855E6B490424FC4F5631DD9551D7CD762420E3AFA0B20E6B403A0CB71FA16861F8C591B2BD7BDD564EC6D5A17A932E310876D1D65AF3F3F213D1C49086F32C7C8A0F53750127DF8709F6035688E02E613F1C57A525A21DD83FA27D0622FC0EFC76ABA114194A7FDA1B0879013D0790F3B8D387ACA238FC37135F9BA6BB0C87A972143568B010B62EE8BA71C78202858170F292596AD95DD4FA2DC8E9ABA359B8F511B5F3894906F3FD0A22CA3DEB2E67B2A97CD2B847AC73BE28F69996A4CF51B6FD87B9F932F6049F886AC5A7725755693842DF00795A9D00C76E2C4446BDDA5E595CBE8CDF51E050632DB110D155343188A57F273B4334E5DA5EC556AD3CADC3327268DC0C528FE41F837A393B5B2F76E476CFA64A2A24BA71F5F7078F5360EBF316D4275AB292B031B9CF8787ACB009D3DC5DCD5038C05E1B2225909E596DFE2E968CFAE077FDFF540E3F78FC464966BB19E280DE34F81079B9DCA111904CDC7C5B6FD5CD44A215B0B5A6A9" +exponent = 65537 +extended_key_usages = [ + "0x06082b0601050507030400000000000000000000000000000000000000000000", + "0x06082b0601050507030800000000000000000000000000000000000000000000", +] +certificate_policies = [ + "0x06032d0607000000000000000000000000000000000000000000000000000000", +] +oid_group = 0 + [development] signing_key = "Key not set" #key (0) azure_vault_url = "vault url is not set"