From f61421e7e764f4200339cb2716d8e5f93d23e5ef Mon Sep 17 00:00:00 2001 From: yaziciahmet Date: Fri, 13 Dec 2024 15:55:19 +0100 Subject: [PATCH 01/96] Carry guest input read outside of run_sequencer_commitments_in_da_slot --- crates/citrea-stf/src/lib.rs | 4 +-- crates/citrea-stf/src/verifier.rs | 28 ++++++------------- crates/prover-services/src/lib.rs | 6 ++-- crates/prover-services/src/parallel/mod.rs | 24 ++++++++++------ .../src/state_machine/zk/mod.rs | 2 ++ crates/sp1/src/guest.rs | 6 +++- .../src/bin/batch_proof_bitcoin.rs | 14 ++++++---- guests/risc0/batch-proof-mock/Cargo.lock | 1 + guests/risc0/batch-proof-mock/Cargo.toml | 1 + .../src/bin/batch_proof_mock.rs | 15 +++++++--- guests/sp1/batch-prover-bitcoin/Cargo.lock | 15 +++++----- guests/sp1/batch-prover-bitcoin/Cargo.toml | 16 +++++------ guests/sp1/batch-prover-bitcoin/src/main.rs | 14 ++++++---- 13 files changed, 80 insertions(+), 66 deletions(-) diff --git a/crates/citrea-stf/src/lib.rs b/crates/citrea-stf/src/lib.rs index 2f188fa8a..ff87d81d9 100644 --- a/crates/citrea-stf/src/lib.rs +++ b/crates/citrea-stf/src/lib.rs @@ -12,5 +12,5 @@ use sov_rollup_interface::da::DaVerifier; use verifier::StateTransitionVerifier; /// Alias for StateTransitionVerifier. -pub type StfVerifier = - StateTransitionVerifier::Spec, RT>, DA, Vm>; +pub type StfVerifier = + StateTransitionVerifier::Spec, RT>, DA>; diff --git a/crates/citrea-stf/src/verifier.rs b/crates/citrea-stf/src/verifier.rs index b2dcd2a08..2d6214776 100644 --- a/crates/citrea-stf/src/verifier.rs +++ b/crates/citrea-stf/src/verifier.rs @@ -1,45 +1,34 @@ -use std::marker::PhantomData; - use sov_rollup_interface::da::{BlockHeaderTrait, DaNamespace, DaVerifier}; use sov_rollup_interface::stf::{ApplySequencerCommitmentsOutput, StateTransitionFunction}; -use sov_rollup_interface::zk::{BatchProofCircuitInput, BatchProofCircuitOutput, Zkvm, ZkvmGuest}; +use sov_rollup_interface::zk::{BatchProofCircuitInput, BatchProofCircuitOutput}; /// Verifies a state transition -pub struct StateTransitionVerifier +pub struct StateTransitionVerifier where Da: DaVerifier, - Zk: Zkvm, ST: StateTransitionFunction, { app: ST, da_verifier: Da, - phantom: PhantomData, } -impl StateTransitionVerifier +impl StateTransitionVerifier where Da: DaVerifier, - Zk: ZkvmGuest, Stf: StateTransitionFunction, { /// Create a [`StateTransitionVerifier`] pub fn new(app: Stf, da_verifier: Da) -> Self { - Self { - app, - da_verifier, - phantom: Default::default(), - } + Self { app, da_verifier } } /// Verify the next block pub fn run_sequencer_commitments_in_da_slot( &mut self, - zkvm: Zk, + data: BatchProofCircuitInput, pre_state: Stf::PreState, - ) -> Result<(), Da::Error> { + ) -> Result, Da::Error> { println!("Running sequencer commitments in DA slot"); - let data: BatchProofCircuitInput = - zkvm.read_from_host(); if !data.da_block_header_of_commitments.verify_hash() { panic!("Invalid hash of DA block header of commitments"); @@ -88,7 +77,7 @@ where println!("out of apply_soft_confirmations_from_sequencer_commitments"); - let out: BatchProofCircuitOutput = BatchProofCircuitOutput { + let out = BatchProofCircuitOutput { initial_state_root: data.initial_state_root, final_state_root, final_soft_confirmation_hash, @@ -102,7 +91,6 @@ where last_l2_height, }; - zkvm.commit(&out); - Ok(()) + Ok(out) } } diff --git a/crates/prover-services/src/lib.rs b/crates/prover-services/src/lib.rs index a23f701a5..047d152ac 100644 --- a/crates/prover-services/src/lib.rs +++ b/crates/prover-services/src/lib.rs @@ -1,21 +1,19 @@ use citrea_stf::verifier::StateTransitionVerifier; use sov_rollup_interface::services::da::DaService; use sov_rollup_interface::stf::StateTransitionFunction; -use sov_rollup_interface::zk::ZkvmHost; mod parallel; pub use parallel::*; -pub enum ProofGenMode +pub enum ProofGenMode where Da: DaService, - Vm: ZkvmHost, Stf: StateTransitionFunction, { /// Skips proving. Skip, /// The simulator runs the rollup verifier logic without even emulating the zkVM - Simulate(StateTransitionVerifier), + Simulate(StateTransitionVerifier), /// The executor runs the rollup verification logic in the zkVM, but does not actually /// produce a zk proof Execute, diff --git a/crates/prover-services/src/parallel/mod.rs b/crates/prover-services/src/parallel/mod.rs index 7d9423082..763e797ad 100644 --- a/crates/prover-services/src/parallel/mod.rs +++ b/crates/prover-services/src/parallel/mod.rs @@ -7,7 +7,7 @@ use sov_db::ledger_db::LedgerDB; use sov_rollup_interface::da::DaData; use sov_rollup_interface::services::da::DaService; use sov_rollup_interface::stf::StateTransitionFunction; -use sov_rollup_interface::zk::{Proof, ZkvmHost}; +use sov_rollup_interface::zk::{Proof, ZkvmGuest, ZkvmHost}; use sov_stf_runner::ProverService; use tokio::sync::{oneshot, Mutex}; use tracing::{info, warn}; @@ -28,7 +28,7 @@ where { thread_pool: rayon::ThreadPool, - proof_mode: Arc>>, + proof_mode: Arc>>, da_service: Arc, vm: Vm, @@ -49,7 +49,7 @@ where pub fn new( da_service: Arc, vm: Vm, - proof_mode: ProofGenMode, + proof_mode: ProofGenMode, zk_storage: Stf::PreState, thread_pool_size: usize, _ledger_db: LedgerDB, @@ -95,7 +95,7 @@ where pub fn new_from_env( da_service: Arc, vm: Vm, - proof_mode: ProofGenMode, + proof_mode: ProofGenMode, zk_storage: Stf::PreState, _ledger_db: LedgerDB, ) -> anyhow::Result { @@ -247,7 +247,7 @@ fn make_proof( mut vm: Vm, elf: Vec, zk_storage: Stf::PreState, - proof_mode: Arc>>, + proof_mode: Arc>>, ) -> Result where Da: DaService, @@ -258,10 +258,16 @@ where let mut proof_mode = proof_mode.blocking_lock(); match proof_mode.deref_mut() { ProofGenMode::Skip => Ok(Vec::default()), - ProofGenMode::Simulate(ref mut verifier) => verifier - .run_sequencer_commitments_in_da_slot(vm.simulate_with_hints(), zk_storage) - .map(|_| Vec::default()) - .map_err(|e| anyhow::anyhow!("Guest execution must succeed but failed with {:?}", e)), + ProofGenMode::Simulate(ref mut verifier) => { + let guest = vm.simulate_with_hints(); + let data = guest.read_from_host(); + verifier + .run_sequencer_commitments_in_da_slot(data, zk_storage) + .map(|_| Vec::default()) + .map_err(|e| { + anyhow::anyhow!("Guest execution must succeed but failed with {:?}", e) + }) + } // If not skip or simulate, we have to drop the lock manually to allow parallel proving ProofGenMode::Execute => { drop(proof_mode); diff --git a/crates/sovereign-sdk/rollup-interface/src/state_machine/zk/mod.rs b/crates/sovereign-sdk/rollup-interface/src/state_machine/zk/mod.rs index a39c71619..e9461de17 100644 --- a/crates/sovereign-sdk/rollup-interface/src/state_machine/zk/mod.rs +++ b/crates/sovereign-sdk/rollup-interface/src/state_machine/zk/mod.rs @@ -173,8 +173,10 @@ pub struct BatchProofCircuitInput<'txs, StateRoot, Witness, Da: DaSpec, Tx: Clon /// DA block headers the soft confirmations was constructed on. pub da_block_headers_of_soft_confirmations: VecDeque>, /// Sequencer soft confirmation public key. + /// **DO NOT USE THIS FIELD** pub sequencer_public_key: Vec, /// Sequencer DA public_key: Vec, + /// **DO NOT USE THIS FIELD** pub sequencer_da_public_key: Vec, /// The range of sequencer commitments that are being processed. /// The range is inclusive. diff --git a/crates/sp1/src/guest.rs b/crates/sp1/src/guest.rs index 235cb5ee6..20fd5a9e8 100644 --- a/crates/sp1/src/guest.rs +++ b/crates/sp1/src/guest.rs @@ -19,7 +19,7 @@ impl Zkvm for SP1Guest { #[cfg(feature = "native")] type CodeCommitment = crate::host::VerifyingKey; #[cfg(not(feature = "native"))] - type CodeCommitment = (); + type CodeCommitment = [u32; 8]; type Error = anyhow::Error; @@ -36,6 +36,10 @@ impl Zkvm for SP1Guest { ) -> Result { unimplemented!() } + + fn extract_raw_output(_serialized_proof: &[u8]) -> Result, Self::Error> { + unimplemented!() + } } impl ZkvmGuest for SP1Guest { diff --git a/guests/risc0/batch-proof-bitcoin/src/bin/batch_proof_bitcoin.rs b/guests/risc0/batch-proof-bitcoin/src/bin/batch_proof_bitcoin.rs index ca6452321..494e09677 100644 --- a/guests/risc0/batch-proof-bitcoin/src/bin/batch_proof_bitcoin.rs +++ b/guests/risc0/batch-proof-bitcoin/src/bin/batch_proof_bitcoin.rs @@ -8,6 +8,7 @@ use citrea_stf::StfVerifier; use sov_modules_api::default_context::ZkDefaultContext; use sov_modules_stf_blueprint::StfBlueprint; use sov_rollup_interface::da::DaVerifier; +use sov_rollup_interface::zk::ZkvmGuest; use sov_state::ZkStorage; risc0_zkvm::guest::entry!(main); @@ -15,10 +16,9 @@ risc0_zkvm::guest::entry!(main); pub fn main() { let guest = Risc0Guest::new(); let storage = ZkStorage::new(); + let stf = StfBlueprint::new(); - let stf: StfBlueprint> = StfBlueprint::new(); - - let mut stf_verifier = StfVerifier::new( + let mut stf_verifier: StfVerifier<_, ZkDefaultContext, Runtime<_, _>> = StfVerifier::new( stf, BitcoinVerifier::new(RollupParams { to_batch_proof_prefix: TO_BATCH_PROOF_PREFIX.to_vec(), @@ -26,7 +26,11 @@ pub fn main() { }), ); - stf_verifier - .run_sequencer_commitments_in_da_slot(guest, storage) + let data = guest.read_from_host(); + + let out = stf_verifier + .run_sequencer_commitments_in_da_slot(data, storage) .expect("Prover must be honest"); + + guest.commit(&out); } diff --git a/guests/risc0/batch-proof-mock/Cargo.lock b/guests/risc0/batch-proof-mock/Cargo.lock index 76445ed29..3bb439c07 100644 --- a/guests/risc0/batch-proof-mock/Cargo.lock +++ b/guests/risc0/batch-proof-mock/Cargo.lock @@ -562,6 +562,7 @@ dependencies = [ "sov-mock-da", "sov-modules-api", "sov-modules-stf-blueprint", + "sov-rollup-interface", "sov-state", ] diff --git a/guests/risc0/batch-proof-mock/Cargo.toml b/guests/risc0/batch-proof-mock/Cargo.toml index ccd1972be..a0f43bafb 100644 --- a/guests/risc0/batch-proof-mock/Cargo.toml +++ b/guests/risc0/batch-proof-mock/Cargo.toml @@ -17,6 +17,7 @@ citrea-stf = { path = "../../../crates/citrea-stf" } sov-mock-da = { path = "../../../crates/sovereign-sdk/adapters/mock-da", default-features = false } sov-modules-api = { path = "../../../crates/sovereign-sdk/module-system/sov-modules-api", default-features = false } sov-modules-stf-blueprint = { path = "../../../crates/sovereign-sdk/module-system/sov-modules-stf-blueprint" } +sov-rollup-interface = { path = "../../../crates/sovereign-sdk/rollup-interface" } sov-state = { path = "../../../crates/sovereign-sdk/module-system/sov-state" } [features] diff --git a/guests/risc0/batch-proof-mock/src/bin/batch_proof_mock.rs b/guests/risc0/batch-proof-mock/src/bin/batch_proof_mock.rs index 0347a1fda..8a40f8cd5 100644 --- a/guests/risc0/batch-proof-mock/src/bin/batch_proof_mock.rs +++ b/guests/risc0/batch-proof-mock/src/bin/batch_proof_mock.rs @@ -6,18 +6,25 @@ use sov_modules_api::default_context::ZkDefaultContext; use sov_modules_stf_blueprint::StfBlueprint; use citrea_risc0_adapter::guest::Risc0Guest; use sov_state::ZkStorage; +use sov_rollup_interface::zk::ZkvmGuest; risc0_zkvm::guest::entry!(main); pub fn main() { let guest = Risc0Guest::new(); let storage = ZkStorage::new(); + let stf = StfBlueprint::new(); - let stf: StfBlueprint> = StfBlueprint::new(); + let mut stf_verifier: StfVerifier<_, ZkDefaultContext, Runtime<_, _>> = StfVerifier::new( + stf, + MockDaVerifier {} + ); - let mut stf_verifier = StfVerifier::new(stf, MockDaVerifier {}); + let data = guest.read_from_host(); - stf_verifier - .run_sequencer_commitments_in_da_slot(guest, storage) + let out = stf_verifier + .run_sequencer_commitments_in_da_slot(data, storage) .expect("Prover must be honest"); + + guest.commit(&out); } diff --git a/guests/sp1/batch-prover-bitcoin/Cargo.lock b/guests/sp1/batch-prover-bitcoin/Cargo.lock index 38cf158bc..e98bfff4c 100644 --- a/guests/sp1/batch-prover-bitcoin/Cargo.lock +++ b/guests/sp1/batch-prover-bitcoin/Cargo.lock @@ -550,8 +550,10 @@ dependencies = [ "bitcoin", "borsh", "citrea-primitives", + "crypto-bigint", "futures", "hex", + "itertools 0.13.0", "rand", "serde", "serde_json", @@ -702,9 +704,9 @@ dependencies = [ [[package]] name = "brotli" -version = "6.0.0" +version = "7.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "74f7971dbd9326d58187408ab83117d8ac1bb9c17b085fdacd1cf2f598719b6b" +checksum = "cc97b8f16f944bba54f0433f07e30be199b6dc2bd25937444bbad560bcea29bd" dependencies = [ "alloc-no-stdlib", "alloc-stdlib", @@ -806,7 +808,6 @@ dependencies = [ "alloy-eips", "alloy-primitives 0.7.7", "alloy-sol-types", - "anyhow", "borsh", "citrea-primitives", "hex", @@ -2640,7 +2641,6 @@ dependencies = [ name = "soft-confirmation-rule-enforcer" version = "0.5.0-rc.1" dependencies = [ - "anyhow", "borsh", "serde", "sov-modules-api", @@ -2652,7 +2652,6 @@ dependencies = [ name = "sov-accounts" version = "0.5.0-rc.1" dependencies = [ - "anyhow", "borsh", "serde", "sov-modules-api", @@ -2668,6 +2667,7 @@ dependencies = [ "bech32 0.9.1", "borsh", "derive_more 0.99.18", + "digest 0.10.7", "ed25519-dalek", "hex", "jmt", @@ -2716,6 +2716,7 @@ version = "0.5.0-rc.1" dependencies = [ "anyhow", "borsh", + "citrea-primitives", "hex", "itertools 0.13.0", "jmt", @@ -2736,9 +2737,7 @@ dependencies = [ "bytes", "digest 0.10.7", "hex", - "proptest", "serde", - "sha2", "thiserror", ] @@ -2812,7 +2811,7 @@ dependencies = [ [[package]] name = "sp1-lib" version = "3.0.0" -source = "git+https://github.com/succinctlabs/sp1.git?branch=dev#d13675665bff079b6da4f115cb322eadca6bb50e" +source = "git+https://github.com/succinctlabs/sp1.git?branch=dev#aa5d95360403878c947d1e72b84d7f24cc5ce228" dependencies = [ "bincode", "serde", diff --git a/guests/sp1/batch-prover-bitcoin/Cargo.toml b/guests/sp1/batch-prover-bitcoin/Cargo.toml index 2ff03e769..2b86cc9d4 100644 --- a/guests/sp1/batch-prover-bitcoin/Cargo.toml +++ b/guests/sp1/batch-prover-bitcoin/Cargo.toml @@ -7,14 +7,14 @@ edition = "2021" resolver = "2" [dependencies] -bitcoin-da = { path = "../../../../crates/bitcoin-da", default-features = false } -citrea-primitives = { path = "../../../../crates/primitives" } -citrea-sp1 = { path = "../../../../crates/sp1", default-features = false } -citrea-stf = { path = "../../../../crates/citrea-stf" } -sov-modules-api = { path = "../../../../crates/sovereign-sdk/module-system/sov-modules-api", default-features = false } -sov-modules-stf-blueprint = { path = "../../../../crates/sovereign-sdk/module-system/sov-modules-stf-blueprint" } -sov-rollup-interface = { path = "../../../../crates/sovereign-sdk/rollup-interface" } -sov-state = { path = "../../../../crates/sovereign-sdk/module-system/sov-state" } +bitcoin-da = { path = "../../../crates/bitcoin-da", default-features = false } +citrea-primitives = { path = "../../../crates/primitives" } +citrea-sp1 = { path = "../../../crates/sp1", default-features = false } +citrea-stf = { path = "../../../crates/citrea-stf" } +sov-modules-api = { path = "../../../crates/sovereign-sdk/module-system/sov-modules-api", default-features = false } +sov-modules-stf-blueprint = { path = "../../../crates/sovereign-sdk/module-system/sov-modules-stf-blueprint" } +sov-rollup-interface = { path = "../../../crates/sovereign-sdk/rollup-interface" } +sov-state = { path = "../../../crates/sovereign-sdk/module-system/sov-state" } sp1-zkvm = { version = "3.0.0", default-features = false, features = ["lib"] } # Have to put this here to enable features for the patch crate even though we don't use this crate explicitly diff --git a/guests/sp1/batch-prover-bitcoin/src/main.rs b/guests/sp1/batch-prover-bitcoin/src/main.rs index f54ab3ff9..9317fcc0c 100644 --- a/guests/sp1/batch-prover-bitcoin/src/main.rs +++ b/guests/sp1/batch-prover-bitcoin/src/main.rs @@ -10,15 +10,15 @@ use citrea_stf::StfVerifier; use sov_modules_api::default_context::ZkDefaultContext; use sov_modules_stf_blueprint::StfBlueprint; use sov_rollup_interface::da::DaVerifier; +use sov_rollup_interface::zk::ZkvmGuest; use sov_state::ZkStorage; pub fn main() { let guest = SP1Guest::new(); let storage = ZkStorage::new(); + let stf = StfBlueprint::new(); - let stf: StfBlueprint> = StfBlueprint::new(); - - let mut stf_verifier = StfVerifier::new( + let mut stf_verifier: StfVerifier<_, ZkDefaultContext, Runtime<_, _>> = StfVerifier::new( stf, BitcoinVerifier::new(RollupParams { to_batch_proof_prefix: TO_BATCH_PROOF_PREFIX.to_vec(), @@ -26,7 +26,11 @@ pub fn main() { }), ); - stf_verifier - .run_sequencer_commitments_in_da_slot(guest, storage) + let data = guest.read_from_host(); + + let out = stf_verifier + .run_sequencer_commitments_in_da_slot(data, storage) .expect("Prover must be honest"); + + guest.commit(&out); } From 39e90d969f5b18dd6c1c58b208ee447dbe59b431 Mon Sep 17 00:00:00 2001 From: yaziciahmet Date: Fri, 13 Dec 2024 16:11:15 +0100 Subject: [PATCH 02/96] Get light client input as arg in circuit --- crates/light-client-prover/src/circuit.rs | 4 +- crates/light-client-prover/src/tests/mod.rs | 62 +++++-------------- .../src/bin/light_client_proof_bitcoin.rs | 4 +- .../src/bin/light_client_proof_mock.rs | 4 +- 4 files changed, 22 insertions(+), 52 deletions(-) diff --git a/crates/light-client-prover/src/circuit.rs b/crates/light-client-prover/src/circuit.rs index 3e70890c6..8b54f3bc6 100644 --- a/crates/light-client-prover/src/circuit.rs +++ b/crates/light-client-prover/src/circuit.rs @@ -17,10 +17,8 @@ pub enum LightClientVerificationError { pub fn run_circuit( da_verifier: DaV, - guest: &G, + input: LightClientCircuitInput, ) -> Result, LightClientVerificationError> { - let input: LightClientCircuitInput = guest.read_from_host(); - // Extract previous light client proof output let previous_light_client_proof_output = if let Some(journal) = input.previous_light_client_proof_journal { diff --git a/crates/light-client-prover/src/tests/mod.rs b/crates/light-client-prover/src/tests/mod.rs index 59a391505..37b42b2d9 100644 --- a/crates/light-client-prover/src/tests/mod.rs +++ b/crates/light-client-prover/src/tests/mod.rs @@ -30,11 +30,7 @@ fn test_light_client_circuit_valid_da_valid_data() { batch_prover_da_pub_key: [9; 32].to_vec(), }; - let serialized_input = borsh::to_vec(&input).expect("should serialize"); - - let mut guest = MockZkGuest::new(serialized_input); - - let output_1 = run_circuit(da_verifier.clone(), &guest).unwrap(); + let output_1 = run_circuit::<_, MockZkGuest>(da_verifier.clone(), input).unwrap(); // Check that the state transition actually happened assert_eq!(output_1.state_root, [3; 32]); @@ -61,11 +57,7 @@ fn test_light_client_circuit_valid_da_valid_data() { batch_prover_da_pub_key: [9; 32].to_vec(), }; - let serialized_input_2 = borsh::to_vec(&input_2).expect("should serialize"); - - guest.input = serialized_input_2; - - let output_2 = run_circuit(da_verifier, &guest).unwrap(); + let output_2 = run_circuit::<_, MockZkGuest>(da_verifier.clone(), input_2).unwrap(); // Check that the state transition actually happened assert_eq!(output_2.state_root, [5; 32]); @@ -95,11 +87,7 @@ fn test_wrong_order_da_blocks_should_still_work() { batch_prover_da_pub_key: [9; 32].to_vec(), }; - let serialized_input = borsh::to_vec(&input).expect("should serialize"); - - let guest = MockZkGuest::new(serialized_input); - - let output_1 = run_circuit(da_verifier.clone(), &guest).unwrap(); + let output_1 = run_circuit::<_, MockZkGuest>(da_verifier.clone(), input).unwrap(); // Check that the state transition actually happened assert_eq!(output_1.state_root, [3; 32]); @@ -129,11 +117,7 @@ fn create_unchainable_outputs_then_chain_them_on_next_block() { batch_prover_da_pub_key: [9; 32].to_vec(), }; - let serialized_input = borsh::to_vec(&input).expect("should serialize"); - - let mut guest = MockZkGuest::new(serialized_input); - - let output_1 = run_circuit(da_verifier.clone(), &guest).unwrap(); + let output_1 = run_circuit::<_, MockZkGuest>(da_verifier.clone(), input).unwrap(); // Check that the state transition has not happened because we are missing 1->2 assert_eq!(output_1.state_root, [1; 32]); @@ -161,15 +145,17 @@ fn create_unchainable_outputs_then_chain_them_on_next_block() { let input_2 = LightClientCircuitInput:: { previous_light_client_proof_journal: Some(mock_output_1_ser), + light_client_proof_method_id, da_block_header: block_header_2, da_data: vec![blob_1], + inclusion_proof: [1u8; 32], + completeness_proof: (), l2_genesis_state_root: None, - ..input + batch_proof_method_id: light_client_proof_method_id, + batch_prover_da_pub_key: [9; 32].to_vec(), }; - guest.input = borsh::to_vec(&input_2).unwrap(); - - let output_2 = run_circuit(da_verifier, &guest).unwrap(); + let output_2 = run_circuit::<_, MockZkGuest>(da_verifier, input_2).unwrap(); // Check that the state transition actually happened from 1-4 now @@ -200,11 +186,7 @@ fn test_header_chain_proof_height_and_hash() { batch_prover_da_pub_key: [9; 32].to_vec(), }; - let serialized_input = borsh::to_vec(&input).expect("should serialize"); - - let mut guest = MockZkGuest::new(serialized_input); - - let output_1 = run_circuit(da_verifier.clone(), &guest).unwrap(); + let output_1 = run_circuit::<_, MockZkGuest>(da_verifier.clone(), input).unwrap(); // Check that the state transition actually happened assert_eq!(output_1.state_root, [3; 32]); @@ -231,12 +213,8 @@ fn test_header_chain_proof_height_and_hash() { batch_prover_da_pub_key: [9; 32].to_vec(), }; - let serialized_input_2 = borsh::to_vec(&input_2).expect("should serialize"); - - guest.input = serialized_input_2; - // Header chain verification must fail because the l1 block 3 was given before l1 block 2 - let res = run_circuit(da_verifier, &guest); + let res = run_circuit::<_, MockZkGuest>(da_verifier, input_2); assert!(matches!( res, Err(LightClientVerificationError::HeaderChainVerificationFailed) @@ -266,11 +244,7 @@ fn test_unverifiable_batch_proofs() { batch_prover_da_pub_key: [9; 32].to_vec(), }; - let serialized_input = borsh::to_vec(&input).expect("should serialize"); - - let guest = MockZkGuest::new(serialized_input); - - let output_1 = run_circuit(da_verifier.clone(), &guest).unwrap(); + let output_1 = run_circuit::<_, MockZkGuest>(da_verifier.clone(), input).unwrap(); // Check that the state transition actually happened but only for verified batch proof // and assert the unverified is ignored, so it is not even in the unchained outputs @@ -303,11 +277,7 @@ fn test_unverifiable_prev_light_client_proof() { batch_prover_da_pub_key: [9; 32].to_vec(), }; - let serialized_input = borsh::to_vec(&input).expect("should serialize"); - - let mut guest = MockZkGuest::new(serialized_input); - - let output_1 = run_circuit(da_verifier.clone(), &guest).unwrap(); + let output_1 = run_circuit::<_, MockZkGuest>(da_verifier.clone(), input).unwrap(); // Check that the state transition actually happened but only for verified batch proof // and assert the unverified is ignored, so it is not even in the unchained outputs @@ -332,9 +302,7 @@ fn test_unverifiable_prev_light_client_proof() { batch_prover_da_pub_key: [9; 32].to_vec(), }; - guest.input = borsh::to_vec(&input_2).unwrap(); - - let res = run_circuit(da_verifier, &guest); + let res = run_circuit::<_, MockZkGuest>(da_verifier, input_2); assert!(matches!( res, Err(LightClientVerificationError::InvalidPreviousLightClientProof) diff --git a/guests/risc0/light-client-proof-bitcoin/src/bin/light_client_proof_bitcoin.rs b/guests/risc0/light-client-proof-bitcoin/src/bin/light_client_proof_bitcoin.rs index 9bb7bdc9a..234a85cf8 100644 --- a/guests/risc0/light-client-proof-bitcoin/src/bin/light_client_proof_bitcoin.rs +++ b/guests/risc0/light-client-proof-bitcoin/src/bin/light_client_proof_bitcoin.rs @@ -17,7 +17,9 @@ pub fn main() { to_light_client_prefix: TO_LIGHT_CLIENT_PREFIX.to_vec(), }); - let output = run_circuit::(da_verifier, &guest).unwrap(); + let input = guest.read_from_host(); + + let output = run_circuit::(da_verifier, input).unwrap(); guest.commit(&output); } diff --git a/guests/risc0/light-client-proof-mock/src/bin/light_client_proof_mock.rs b/guests/risc0/light-client-proof-mock/src/bin/light_client_proof_mock.rs index ab50e1947..8b9e54bb6 100644 --- a/guests/risc0/light-client-proof-mock/src/bin/light_client_proof_mock.rs +++ b/guests/risc0/light-client-proof-mock/src/bin/light_client_proof_mock.rs @@ -11,7 +11,9 @@ pub fn main() { let da_verifier = MockDaVerifier {}; - let output = run_circuit::(da_verifier, &guest).unwrap(); + let input = guest.read_from_host(); + + let output = run_circuit::(da_verifier, input).unwrap(); guest.commit(&output); } From d9ec09ef9c73dff3b405742d35f014dc69a48320 Mon Sep 17 00:00:00 2001 From: yaziciahmet Date: Fri, 13 Dec 2024 16:18:20 +0100 Subject: [PATCH 03/96] Remove useless generic --- crates/light-client-prover/src/tests/mod.rs | 22 ++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/crates/light-client-prover/src/tests/mod.rs b/crates/light-client-prover/src/tests/mod.rs index 37b42b2d9..018b16ead 100644 --- a/crates/light-client-prover/src/tests/mod.rs +++ b/crates/light-client-prover/src/tests/mod.rs @@ -1,6 +1,6 @@ mod test_utils; -use sov_mock_da::{MockBlockHeader, MockDaSpec, MockDaVerifier}; +use sov_mock_da::{MockBlockHeader, MockDaVerifier}; use sov_mock_zkvm::MockZkGuest; use sov_rollup_interface::zk::LightClientCircuitInput; use test_utils::{create_mock_blob, create_prev_lcp_serialized}; @@ -18,7 +18,7 @@ fn test_light_client_circuit_valid_da_valid_data() { let block_header_1 = MockBlockHeader::from_height(1); - let input = LightClientCircuitInput:: { + let input = LightClientCircuitInput { previous_light_client_proof_journal: None, light_client_proof_method_id, da_block_header: block_header_1, @@ -45,7 +45,7 @@ fn test_light_client_circuit_valid_da_valid_data() { let mock_output_1_serialized = create_prev_lcp_serialized(output_1, true); - let input_2 = LightClientCircuitInput:: { + let input_2 = LightClientCircuitInput { previous_light_client_proof_journal: Some(mock_output_1_serialized), da_block_header: block_header_2, da_data: vec![blob_3, blob_4], @@ -75,7 +75,7 @@ fn test_wrong_order_da_blocks_should_still_work() { let block_header_1 = MockBlockHeader::from_height(1); - let input = LightClientCircuitInput:: { + let input = LightClientCircuitInput { previous_light_client_proof_journal: None, light_client_proof_method_id, da_block_header: block_header_1, @@ -105,7 +105,7 @@ fn create_unchainable_outputs_then_chain_them_on_next_block() { let blob_1 = create_mock_blob([2u8; 32], [3u8; 32], 3, true); let blob_2 = create_mock_blob([3u8; 32], [4u8; 32], 4, true); - let input = LightClientCircuitInput:: { + let input = LightClientCircuitInput { previous_light_client_proof_journal: None, light_client_proof_method_id, da_block_header: block_header_1, @@ -143,7 +143,7 @@ fn create_unchainable_outputs_then_chain_them_on_next_block() { let mock_output_1_ser = create_prev_lcp_serialized(output_1, true); - let input_2 = LightClientCircuitInput:: { + let input_2 = LightClientCircuitInput { previous_light_client_proof_journal: Some(mock_output_1_ser), light_client_proof_method_id, da_block_header: block_header_2, @@ -174,7 +174,7 @@ fn test_header_chain_proof_height_and_hash() { let block_header_1 = MockBlockHeader::from_height(1); - let input = LightClientCircuitInput:: { + let input = LightClientCircuitInput { previous_light_client_proof_journal: None, light_client_proof_method_id, da_block_header: block_header_1, @@ -201,7 +201,7 @@ fn test_header_chain_proof_height_and_hash() { let prev_lcp_out = create_prev_lcp_serialized(output_1, true); - let input_2 = LightClientCircuitInput:: { + let input_2 = LightClientCircuitInput { previous_light_client_proof_journal: Some(prev_lcp_out), da_block_header: block_header_2, da_data: vec![blob_3, blob_4], @@ -232,7 +232,7 @@ fn test_unverifiable_batch_proofs() { let block_header_1 = MockBlockHeader::from_height(1); - let input = LightClientCircuitInput:: { + let input = LightClientCircuitInput { previous_light_client_proof_journal: None, light_client_proof_method_id, da_block_header: block_header_1, @@ -265,7 +265,7 @@ fn test_unverifiable_prev_light_client_proof() { let block_header_1 = MockBlockHeader::from_height(1); - let input = LightClientCircuitInput:: { + let input = LightClientCircuitInput { previous_light_client_proof_journal: None, light_client_proof_method_id, da_block_header: block_header_1, @@ -290,7 +290,7 @@ fn test_unverifiable_prev_light_client_proof() { let prev_lcp_out = create_prev_lcp_serialized(output_1, false); - let input_2 = LightClientCircuitInput:: { + let input_2 = LightClientCircuitInput { previous_light_client_proof_journal: Some(prev_lcp_out), da_block_header: block_header_2, da_data: vec![], From 3de7c07383152d303d62272c2e69e53b7a6a295c Mon Sep 17 00:00:00 2001 From: yaziciahmet Date: Sun, 15 Dec 2024 23:47:54 +0100 Subject: [PATCH 04/96] Add SEQ PUB KEYS and implement Fork str parser --- .../rollup-interface/src/fork/mod.rs | 112 ++++++++++++++++++ .../rollup-interface/src/fork/tests.rs | 36 ++++++ .../rollup-interface/src/spec.rs | 26 ++++ guests/risc0/batch-proof-bitcoin/Cargo.lock | 1 + guests/risc0/batch-proof-bitcoin/Cargo.toml | 1 + .../src/bin/batch_proof_bitcoin.rs | 34 ++++++ 6 files changed, 210 insertions(+) diff --git a/crates/sovereign-sdk/rollup-interface/src/fork/mod.rs b/crates/sovereign-sdk/rollup-interface/src/fork/mod.rs index bd00b1e87..2ab96ce46 100644 --- a/crates/sovereign-sdk/rollup-interface/src/fork/mod.rs +++ b/crates/sovereign-sdk/rollup-interface/src/fork/mod.rs @@ -27,4 +27,116 @@ impl Fork { activation_height, } } + + /// Parses `Fork` from colon separated bytes. + /// Required format is `{spec_id as u8}:{activation_height}`. + /// + /// Example: + /// ``` + /// use sov_rollup_interface::fork::Fork; + /// const FORK: Option = Fork::parse_colon_separated_utf8(b"0:1000"); + /// ``` + pub const fn parse_colon_separated_utf8(bytes: &[u8]) -> Option { + pub const fn is_digit(v: u8) -> bool { + v >= b'0' && v <= b'9' + } + + // Find the index of colon + let mut i = 0; + let colon_idx = loop { + if i == bytes.len() { + return None; + } + if bytes[i] == b':' { + break i; + } + i += 1; + }; + + let (spec_id_bytes, height_bytes) = bytes.split_at(colon_idx); + // Ignore colon + let Some((_, height_bytes)) = height_bytes.split_first() else { + return None; + }; + + if spec_id_bytes.is_empty() || height_bytes.is_empty() { + return None; + } + + // If multiple digits, first digit should not be 0 + if (spec_id_bytes.len() > 1 && spec_id_bytes[0] == b'0') + || (height_bytes.len() > 1 && height_bytes[0] == b'0') + { + return None; + } + + // Largest u8 is 3 digits, largest u64 is 20 digits + if spec_id_bytes.len() > 3 || height_bytes.len() > 20 { + return None; + } + + // Parse spec_id + let mut i = 0; + let mut spec_id: u8 = 0; + while i < spec_id_bytes.len() { + if !is_digit(spec_id_bytes[i]) { + return None; + } + + let digit = spec_id_bytes[i] - b'0'; + let exp = spec_id_bytes.len() - i - 1; + + let Some(multiplier) = 10u8.checked_pow(exp as u32) else { + return None; + }; + let Some(to_add) = digit.checked_mul(multiplier) else { + return None; + }; + + if let Some(new_spec_id) = spec_id.checked_add(to_add) { + spec_id = new_spec_id; + } else { + return None; + } + + i += 1; + } + + let Some(spec_id) = SpecId::from_u8(spec_id) else { + return None; + }; + + // Parse activation_height + let mut i = 0; + let mut height: u64 = 0; + while i < height_bytes.len() { + if !is_digit(height_bytes[i]) { + return None; + } + + let digit = (height_bytes[i] - b'0') as u64; + let exp = height_bytes.len() - i - 1; + + let Some(multiplier) = 10u64.checked_pow(exp as u32) else { + return None; + }; + + let Some(to_add) = digit.checked_mul(multiplier) else { + return None; + }; + + if let Some(new_height) = height.checked_add(to_add) { + height = new_height; + } else { + return None; + } + + i += 1; + } + + Some(Fork { + spec_id, + activation_height: height, + }) + } } diff --git a/crates/sovereign-sdk/rollup-interface/src/fork/tests.rs b/crates/sovereign-sdk/rollup-interface/src/fork/tests.rs index 3bb5da400..d52024273 100644 --- a/crates/sovereign-sdk/rollup-interface/src/fork/tests.rs +++ b/crates/sovereign-sdk/rollup-interface/src/fork/tests.rs @@ -1,3 +1,5 @@ +use core::u64; + use anyhow::anyhow; use super::ForkManager; @@ -62,3 +64,37 @@ fn test_fork_manager_callbacks() { assert_eq!(msg.to_string(), "Called"); } } + +#[test] +fn test_fork_parse_utf8() { + let max64 = u64::MAX.to_string(); + let max64plusone = ((u64::MAX as u128) + 1).to_string(); + + test_success_fork_parse_utf8(b"0:0", 0, 0); + test_success_fork_parse_utf8(b"1:1000", 1, 1000); + test_success_fork_parse_utf8(b"1:1", 1, 1); + test_success_fork_parse_utf8(b"2:1234567890", 2, 1234567890); + test_success_fork_parse_utf8(b"0:110", 0, 110); + test_success_fork_parse_utf8(format!("1:{}", max64).as_bytes(), 1, u64::MAX); + + assert!(matches!(Fork::parse_colon_separated_utf8(b""), None)); + assert!(matches!(Fork::parse_colon_separated_utf8(b":"), None)); + assert!(matches!(Fork::parse_colon_separated_utf8(b":123"), None)); + assert!(matches!(Fork::parse_colon_separated_utf8(b"1:"), None)); + assert!(matches!(Fork::parse_colon_separated_utf8(b"01:123"), None)); + assert!(matches!(Fork::parse_colon_separated_utf8(b"1:01234"), None)); + assert!(matches!(Fork::parse_colon_separated_utf8(b"5:123"), None)); + assert!(matches!(Fork::parse_colon_separated_utf8(b"ab:cd"), None)); + assert!(matches!(Fork::parse_colon_separated_utf8(b"1:123a"), None)); + assert!(matches!(Fork::parse_colon_separated_utf8(b"12345"), None)); + assert!(matches!( + Fork::parse_colon_separated_utf8(format!("1:{}", max64plusone).as_bytes()), + None + )); +} + +fn test_success_fork_parse_utf8(bytes: &[u8], exp_spec: u8, exp_height: u64) { + let fork = Fork::parse_colon_separated_utf8(bytes).unwrap(); + assert_eq!(fork.spec_id, SpecId::from_u8(exp_spec).unwrap()); + assert_eq!(fork.activation_height, exp_height); +} diff --git a/crates/sovereign-sdk/rollup-interface/src/spec.rs b/crates/sovereign-sdk/rollup-interface/src/spec.rs index abce77fe7..f984c990c 100644 --- a/crates/sovereign-sdk/rollup-interface/src/spec.rs +++ b/crates/sovereign-sdk/rollup-interface/src/spec.rs @@ -34,6 +34,18 @@ mod spec { /// 3. Don't use borsh when signing SoftConfirmation's Fork1 = 1, } + + impl SpecId { + /// Const fn to convert u8 to corresponding SpecId. Valid values are + /// 0 and 1. Panics otherwise. + pub const fn from_u8(n: u8) -> Option { + match n { + 0 => Some(SpecId::Genesis), + 1 => Some(SpecId::Fork1), + _ => None, + } + } + } } #[cfg(feature = "testing")] @@ -66,4 +78,18 @@ mod spec { /// Third fork Fork3 = 3, } + + impl SpecId { + /// Const fn to convert u8 to corresponding SpecId. Valid values are + /// 0, 1, 2 and 3. + pub const fn from_u8(n: u8) -> Option { + match n { + 0 => Some(SpecId::Genesis), + 1 => Some(SpecId::Fork1), + 2 => Some(SpecId::Fork2), + 3 => Some(SpecId::Fork3), + _ => None, + } + } + } } diff --git a/guests/risc0/batch-proof-bitcoin/Cargo.lock b/guests/risc0/batch-proof-bitcoin/Cargo.lock index e37628fd4..28093fcd5 100644 --- a/guests/risc0/batch-proof-bitcoin/Cargo.lock +++ b/guests/risc0/batch-proof-bitcoin/Cargo.lock @@ -568,6 +568,7 @@ dependencies = [ "citrea-primitives", "citrea-risc0-adapter", "citrea-stf", + "const-hex", "risc0-zkvm", "risc0-zkvm-platform", "sov-modules-api", diff --git a/guests/risc0/batch-proof-bitcoin/Cargo.toml b/guests/risc0/batch-proof-bitcoin/Cargo.toml index 920816b38..2bbecbec1 100644 --- a/guests/risc0/batch-proof-bitcoin/Cargo.toml +++ b/guests/risc0/batch-proof-bitcoin/Cargo.toml @@ -15,6 +15,7 @@ bitcoin-da = { path = "../../../crates/bitcoin-da", default-features = false } citrea-primitives = { path = "../../../crates/primitives" } citrea-risc0-adapter = { path = "../../../crates/risc0" } citrea-stf = { path = "../../../crates/citrea-stf" } +const-hex = "1" sov-modules-api = { path = "../../../crates/sovereign-sdk/module-system/sov-modules-api", default-features = false } sov-modules-stf-blueprint = { path = "../../../crates/sovereign-sdk/module-system/sov-modules-stf-blueprint" } sov-rollup-interface = { path = "../../../crates/sovereign-sdk/rollup-interface" } diff --git a/guests/risc0/batch-proof-bitcoin/src/bin/batch_proof_bitcoin.rs b/guests/risc0/batch-proof-bitcoin/src/bin/batch_proof_bitcoin.rs index 494e09677..3976529c2 100644 --- a/guests/risc0/batch-proof-bitcoin/src/bin/batch_proof_bitcoin.rs +++ b/guests/risc0/batch-proof-bitcoin/src/bin/batch_proof_bitcoin.rs @@ -6,6 +6,8 @@ use citrea_risc0_adapter::guest::Risc0Guest; use citrea_stf::runtime::Runtime; use citrea_stf::StfVerifier; use sov_modules_api::default_context::ZkDefaultContext; +use sov_modules_api::fork::Fork; +use sov_modules_api::SpecId; use sov_modules_stf_blueprint::StfBlueprint; use sov_rollup_interface::da::DaVerifier; use sov_rollup_interface::zk::ZkvmGuest; @@ -13,6 +15,38 @@ use sov_state::ZkStorage; risc0_zkvm::guest::entry!(main); +const SEQUENCER_PUBLIC_KEY: [u8; 32] = match option_env!("SEQUENCER_PUBLIC_KEY") { + Some(hex_pub_key) => { + match const_hex::const_decode_to_array(hex_pub_key.as_bytes()) { + Ok(pub_key) => pub_key, + Err(_) => panic!("SEQUENCER_PUBLIC_KEY must be valid 32-byte hex string"), + } + } + // TODO: what to do here? + None => [0; 32], +}; + +const SEQUENCER_DA_PUBLIC_KEY: [u8; 33] = match option_env!("SEQUENCER_DA_PUBLIC_KEY") { + Some(hex_pub_key) => { + match const_hex::const_decode_to_array(hex_pub_key.as_bytes()) { + // TODO: maybe verify the first byte? + Ok(pub_key) => pub_key, + Err(_) => panic!("SEQUENCER_DA_PUBLIC_KEY must be valid 33-byte hex string"), + } + } + // TODO: what to do here? + None => [0; 33], +}; + +const FORKS: &[Fork] = match option_env!("FORKS") { + Some(forks_str) => { + let mut forks = [Fork { spec_id: SpecId::Genesis, activation_height: 0 }; 100]; + todo!() + } + // TODO: what to do here? + None => &[], +}; + pub fn main() { let guest = Risc0Guest::new(); let storage = ZkStorage::new(); From 4c2b1821bfcf9c60365a77fff9eeff48c67516fc Mon Sep 17 00:00:00 2001 From: yaziciahmet Date: Sun, 15 Dec 2024 23:50:54 +0100 Subject: [PATCH 05/96] Fmt --- .../rollup-interface/src/fork/tests.rs | 27 ++++++++----------- 1 file changed, 11 insertions(+), 16 deletions(-) diff --git a/crates/sovereign-sdk/rollup-interface/src/fork/tests.rs b/crates/sovereign-sdk/rollup-interface/src/fork/tests.rs index d52024273..24b66a6ea 100644 --- a/crates/sovereign-sdk/rollup-interface/src/fork/tests.rs +++ b/crates/sovereign-sdk/rollup-interface/src/fork/tests.rs @@ -1,5 +1,3 @@ -use core::u64; - use anyhow::anyhow; use super::ForkManager; @@ -77,20 +75,17 @@ fn test_fork_parse_utf8() { test_success_fork_parse_utf8(b"0:110", 0, 110); test_success_fork_parse_utf8(format!("1:{}", max64).as_bytes(), 1, u64::MAX); - assert!(matches!(Fork::parse_colon_separated_utf8(b""), None)); - assert!(matches!(Fork::parse_colon_separated_utf8(b":"), None)); - assert!(matches!(Fork::parse_colon_separated_utf8(b":123"), None)); - assert!(matches!(Fork::parse_colon_separated_utf8(b"1:"), None)); - assert!(matches!(Fork::parse_colon_separated_utf8(b"01:123"), None)); - assert!(matches!(Fork::parse_colon_separated_utf8(b"1:01234"), None)); - assert!(matches!(Fork::parse_colon_separated_utf8(b"5:123"), None)); - assert!(matches!(Fork::parse_colon_separated_utf8(b"ab:cd"), None)); - assert!(matches!(Fork::parse_colon_separated_utf8(b"1:123a"), None)); - assert!(matches!(Fork::parse_colon_separated_utf8(b"12345"), None)); - assert!(matches!( - Fork::parse_colon_separated_utf8(format!("1:{}", max64plusone).as_bytes()), - None - )); + assert!(Fork::parse_colon_separated_utf8(b"").is_none()); + assert!(Fork::parse_colon_separated_utf8(b":").is_none()); + assert!(Fork::parse_colon_separated_utf8(b":123").is_none()); + assert!(Fork::parse_colon_separated_utf8(b"1:").is_none()); + assert!(Fork::parse_colon_separated_utf8(b"01:123").is_none()); + assert!(Fork::parse_colon_separated_utf8(b"1:01234").is_none()); + assert!(Fork::parse_colon_separated_utf8(b"5:123").is_none()); + assert!(Fork::parse_colon_separated_utf8(b"ab:cd").is_none()); + assert!(Fork::parse_colon_separated_utf8(b"1:123a").is_none()); + assert!(Fork::parse_colon_separated_utf8(b"12345").is_none()); + assert!(Fork::parse_colon_separated_utf8(format!("1:{}", max64plusone).as_bytes()).is_none()); } fn test_success_fork_parse_utf8(bytes: &[u8], exp_spec: u8, exp_height: u64) { From af6f754e3f86c0caf174169248b0660efc3e5b13 Mon Sep 17 00:00:00 2001 From: yaziciahmet Date: Sun, 15 Dec 2024 23:51:56 +0100 Subject: [PATCH 06/96] One more fail-test --- crates/sovereign-sdk/rollup-interface/src/fork/tests.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/crates/sovereign-sdk/rollup-interface/src/fork/tests.rs b/crates/sovereign-sdk/rollup-interface/src/fork/tests.rs index 24b66a6ea..bcd219d60 100644 --- a/crates/sovereign-sdk/rollup-interface/src/fork/tests.rs +++ b/crates/sovereign-sdk/rollup-interface/src/fork/tests.rs @@ -81,6 +81,7 @@ fn test_fork_parse_utf8() { assert!(Fork::parse_colon_separated_utf8(b"1:").is_none()); assert!(Fork::parse_colon_separated_utf8(b"01:123").is_none()); assert!(Fork::parse_colon_separated_utf8(b"1:01234").is_none()); + assert!(Fork::parse_colon_separated_utf8(b"256:123").is_none()); assert!(Fork::parse_colon_separated_utf8(b"5:123").is_none()); assert!(Fork::parse_colon_separated_utf8(b"ab:cd").is_none()); assert!(Fork::parse_colon_separated_utf8(b"1:123a").is_none()); From fec0dcfe3796aadf252f0dba2559918f8abc2c83 Mon Sep 17 00:00:00 2001 From: yaziciahmet Date: Mon, 16 Dec 2024 11:47:13 +0100 Subject: [PATCH 07/96] Rename --- .../rollup-interface/src/fork/mod.rs | 4 +-- .../rollup-interface/src/fork/tests.rs | 26 +++++++++---------- 2 files changed, 15 insertions(+), 15 deletions(-) diff --git a/crates/sovereign-sdk/rollup-interface/src/fork/mod.rs b/crates/sovereign-sdk/rollup-interface/src/fork/mod.rs index 2ab96ce46..2393d2a53 100644 --- a/crates/sovereign-sdk/rollup-interface/src/fork/mod.rs +++ b/crates/sovereign-sdk/rollup-interface/src/fork/mod.rs @@ -34,9 +34,9 @@ impl Fork { /// Example: /// ``` /// use sov_rollup_interface::fork::Fork; - /// const FORK: Option = Fork::parse_colon_separated_utf8(b"0:1000"); + /// const FORK: Option = Fork::from_colon_separated_utf8(b"0:1000"); /// ``` - pub const fn parse_colon_separated_utf8(bytes: &[u8]) -> Option { + pub const fn from_colon_separated_utf8(bytes: &[u8]) -> Option { pub const fn is_digit(v: u8) -> bool { v >= b'0' && v <= b'9' } diff --git a/crates/sovereign-sdk/rollup-interface/src/fork/tests.rs b/crates/sovereign-sdk/rollup-interface/src/fork/tests.rs index bcd219d60..2d9539d3a 100644 --- a/crates/sovereign-sdk/rollup-interface/src/fork/tests.rs +++ b/crates/sovereign-sdk/rollup-interface/src/fork/tests.rs @@ -75,22 +75,22 @@ fn test_fork_parse_utf8() { test_success_fork_parse_utf8(b"0:110", 0, 110); test_success_fork_parse_utf8(format!("1:{}", max64).as_bytes(), 1, u64::MAX); - assert!(Fork::parse_colon_separated_utf8(b"").is_none()); - assert!(Fork::parse_colon_separated_utf8(b":").is_none()); - assert!(Fork::parse_colon_separated_utf8(b":123").is_none()); - assert!(Fork::parse_colon_separated_utf8(b"1:").is_none()); - assert!(Fork::parse_colon_separated_utf8(b"01:123").is_none()); - assert!(Fork::parse_colon_separated_utf8(b"1:01234").is_none()); - assert!(Fork::parse_colon_separated_utf8(b"256:123").is_none()); - assert!(Fork::parse_colon_separated_utf8(b"5:123").is_none()); - assert!(Fork::parse_colon_separated_utf8(b"ab:cd").is_none()); - assert!(Fork::parse_colon_separated_utf8(b"1:123a").is_none()); - assert!(Fork::parse_colon_separated_utf8(b"12345").is_none()); - assert!(Fork::parse_colon_separated_utf8(format!("1:{}", max64plusone).as_bytes()).is_none()); + assert!(Fork::from_colon_separated_utf8(b"").is_none()); + assert!(Fork::from_colon_separated_utf8(b":").is_none()); + assert!(Fork::from_colon_separated_utf8(b":123").is_none()); + assert!(Fork::from_colon_separated_utf8(b"1:").is_none()); + assert!(Fork::from_colon_separated_utf8(b"01:123").is_none()); + assert!(Fork::from_colon_separated_utf8(b"1:01234").is_none()); + assert!(Fork::from_colon_separated_utf8(b"256:123").is_none()); + assert!(Fork::from_colon_separated_utf8(b"5:123").is_none()); + assert!(Fork::from_colon_separated_utf8(b"ab:cd").is_none()); + assert!(Fork::from_colon_separated_utf8(b"1:123a").is_none()); + assert!(Fork::from_colon_separated_utf8(b"12345").is_none()); + assert!(Fork::from_colon_separated_utf8(format!("1:{}", max64plusone).as_bytes()).is_none()); } fn test_success_fork_parse_utf8(bytes: &[u8], exp_spec: u8, exp_height: u64) { - let fork = Fork::parse_colon_separated_utf8(bytes).unwrap(); + let fork = Fork::from_colon_separated_utf8(bytes).unwrap(); assert_eq!(fork.spec_id, SpecId::from_u8(exp_spec).unwrap()); assert_eq!(fork.activation_height, exp_height); } From b9ba404710dbb231df70c8a14f691b00d10ce447 Mon Sep 17 00:00:00 2001 From: yaziciahmet Date: Mon, 16 Dec 2024 12:33:45 +0100 Subject: [PATCH 08/96] Init const FORKS --- .../rollup-interface/src/fork/mod.rs | 5 ++++ .../src/bin/batch_proof_bitcoin.rs | 25 ++++++++++++++----- 2 files changed, 24 insertions(+), 6 deletions(-) diff --git a/crates/sovereign-sdk/rollup-interface/src/fork/mod.rs b/crates/sovereign-sdk/rollup-interface/src/fork/mod.rs index 2393d2a53..70bb777cc 100644 --- a/crates/sovereign-sdk/rollup-interface/src/fork/mod.rs +++ b/crates/sovereign-sdk/rollup-interface/src/fork/mod.rs @@ -140,3 +140,8 @@ impl Fork { }) } } + +pub const fn parse_fork_list_utf8(forks_str: &str) -> Option<([Fork; 100], usize)> { + let mut forks = [Fork::new(SpecId::Genesis, 0); 100]; + Some((forks, 1)) +} diff --git a/guests/risc0/batch-proof-bitcoin/src/bin/batch_proof_bitcoin.rs b/guests/risc0/batch-proof-bitcoin/src/bin/batch_proof_bitcoin.rs index 3976529c2..a8886093a 100644 --- a/guests/risc0/batch-proof-bitcoin/src/bin/batch_proof_bitcoin.rs +++ b/guests/risc0/batch-proof-bitcoin/src/bin/batch_proof_bitcoin.rs @@ -6,8 +6,7 @@ use citrea_risc0_adapter::guest::Risc0Guest; use citrea_stf::runtime::Runtime; use citrea_stf::StfVerifier; use sov_modules_api::default_context::ZkDefaultContext; -use sov_modules_api::fork::Fork; -use sov_modules_api::SpecId; +use sov_modules_api::fork::{parse_fork_list_utf8, Fork}; use sov_modules_stf_blueprint::StfBlueprint; use sov_rollup_interface::da::DaVerifier; use sov_rollup_interface::zk::ZkvmGuest; @@ -38,10 +37,24 @@ const SEQUENCER_DA_PUBLIC_KEY: [u8; 33] = match option_env!("SEQUENCER_DA_PUBLIC None => [0; 33], }; -const FORKS: &[Fork] = match option_env!("FORKS") { - Some(forks_str) => { - let mut forks = [Fork { spec_id: SpecId::Genesis, activation_height: 0 }; 100]; - todo!() +// Temporary variable to allow FORKS static reference to be valid +const TEMP_FORKS: Option<([Fork; 100], usize)> = match option_env!("FORKS") { + Some(forks_str) => match parse_fork_list_utf8(forks_str) { + Some((forks, count)) => { + if count == 0 { + panic!("FORKS can not be empty"); + } + Some((forks, count)) + } + None => panic!("FORKS must be valid comma separated list"), + }, + // TODO: what to do here? + None => None, +}; + +const FORKS: &[Fork] = match &TEMP_FORKS { + Some((forks, count)) => { + forks.split_at(*count).0 } // TODO: what to do here? None => &[], From be04c37fdcd61f4d70db1ce24f3046f11abbedfb Mon Sep 17 00:00:00 2001 From: yaziciahmet Date: Mon, 16 Dec 2024 12:41:03 +0100 Subject: [PATCH 09/96] Add doc --- .../rollup-interface/src/fork/mod.rs | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/crates/sovereign-sdk/rollup-interface/src/fork/mod.rs b/crates/sovereign-sdk/rollup-interface/src/fork/mod.rs index 70bb777cc..c1b3a5a0d 100644 --- a/crates/sovereign-sdk/rollup-interface/src/fork/mod.rs +++ b/crates/sovereign-sdk/rollup-interface/src/fork/mod.rs @@ -141,6 +141,22 @@ impl Fork { } } +/// Parse fork list from utf8 string. Format should be `{spec_id as u8}:{activation_height},{spec_id2 as u8}:{activation_height2}`. +/// Since this is a constant fn, it returns a stack allocated array with 100 const size, and a second return value as the count +/// of valid forks within this array +/// +/// Example: +/// ``` +/// use sov_rollup_interface::fork::{parse_fork_list_utf8, Fork}; +/// const FORKS: Option<([Fork; 100], usize)> = parse_fork_list_utf8("0:1000,1:5000,2:100000"); +/// +/// fn main() { +/// let forks: &[Fork] = match &FORKS { +/// Some((forks, count)) => &forks[0..*count], +/// None => &[], +/// }; +/// } +/// ``` pub const fn parse_fork_list_utf8(forks_str: &str) -> Option<([Fork; 100], usize)> { let mut forks = [Fork::new(SpecId::Genesis, 0); 100]; Some((forks, 1)) From 39a4106cbb29e4c5af1bb8b35f2b97337060fa06 Mon Sep 17 00:00:00 2001 From: yaziciahmet Date: Mon, 16 Dec 2024 12:46:02 +0100 Subject: [PATCH 10/96] Lower count to 50 --- .../sovereign-sdk/rollup-interface/src/fork/mod.rs | 12 ++++++++---- .../src/bin/batch_proof_bitcoin.rs | 2 +- 2 files changed, 9 insertions(+), 5 deletions(-) diff --git a/crates/sovereign-sdk/rollup-interface/src/fork/mod.rs b/crates/sovereign-sdk/rollup-interface/src/fork/mod.rs index c1b3a5a0d..b2dc283f6 100644 --- a/crates/sovereign-sdk/rollup-interface/src/fork/mod.rs +++ b/crates/sovereign-sdk/rollup-interface/src/fork/mod.rs @@ -142,13 +142,13 @@ impl Fork { } /// Parse fork list from utf8 string. Format should be `{spec_id as u8}:{activation_height},{spec_id2 as u8}:{activation_height2}`. -/// Since this is a constant fn, it returns a stack allocated array with 100 const size, and a second return value as the count +/// Since this is a constant fn, it returns a stack allocated array with 50 const size, and a second return value as the count /// of valid forks within this array /// /// Example: /// ``` /// use sov_rollup_interface::fork::{parse_fork_list_utf8, Fork}; -/// const FORKS: Option<([Fork; 100], usize)> = parse_fork_list_utf8("0:1000,1:5000,2:100000"); +/// const FORKS: Option<([Fork; 50], usize)> = parse_fork_list_utf8("0:1000,1:5000,2:100000"); /// /// fn main() { /// let forks: &[Fork] = match &FORKS { @@ -157,7 +157,11 @@ impl Fork { /// }; /// } /// ``` -pub const fn parse_fork_list_utf8(forks_str: &str) -> Option<([Fork; 100], usize)> { - let mut forks = [Fork::new(SpecId::Genesis, 0); 100]; +pub const fn parse_fork_list_utf8(forks_str: &str) -> Option<([Fork; 50], usize)> { + if forks_str.is_empty() { + return None; + } + + let mut forks = [Fork::new(SpecId::Genesis, 0); 50]; Some((forks, 1)) } diff --git a/guests/risc0/batch-proof-bitcoin/src/bin/batch_proof_bitcoin.rs b/guests/risc0/batch-proof-bitcoin/src/bin/batch_proof_bitcoin.rs index a8886093a..ae719a704 100644 --- a/guests/risc0/batch-proof-bitcoin/src/bin/batch_proof_bitcoin.rs +++ b/guests/risc0/batch-proof-bitcoin/src/bin/batch_proof_bitcoin.rs @@ -38,7 +38,7 @@ const SEQUENCER_DA_PUBLIC_KEY: [u8; 33] = match option_env!("SEQUENCER_DA_PUBLIC }; // Temporary variable to allow FORKS static reference to be valid -const TEMP_FORKS: Option<([Fork; 100], usize)> = match option_env!("FORKS") { +const TEMP_FORKS: Option<([Fork; 50], usize)> = match option_env!("FORKS") { Some(forks_str) => match parse_fork_list_utf8(forks_str) { Some((forks, count)) => { if count == 0 { From b2e67e3d11d2b0d8a4f55a3a1ebdfab3a119a3db Mon Sep 17 00:00:00 2001 From: yaziciahmet Date: Mon, 16 Dec 2024 12:55:49 +0100 Subject: [PATCH 11/96] Implement fork list parser --- .../rollup-interface/src/fork/mod.rs | 27 ++++++++++++++++++- 1 file changed, 26 insertions(+), 1 deletion(-) diff --git a/crates/sovereign-sdk/rollup-interface/src/fork/mod.rs b/crates/sovereign-sdk/rollup-interface/src/fork/mod.rs index b2dc283f6..695c63155 100644 --- a/crates/sovereign-sdk/rollup-interface/src/fork/mod.rs +++ b/crates/sovereign-sdk/rollup-interface/src/fork/mod.rs @@ -163,5 +163,30 @@ pub const fn parse_fork_list_utf8(forks_str: &str) -> Option<([Fork; 50], usize) } let mut forks = [Fork::new(SpecId::Genesis, 0); 50]; - Some((forks, 1)) + let mut count = 0; + + let mut bytes = forks_str.as_bytes(); + let mut i = 0; + while i < bytes.len() { + if bytes[i] == b',' { + let (fork_utf8, remaining_bytes) = bytes.split_at(i); + + let Some(fork) = Fork::from_colon_separated_utf8(fork_utf8) else { + return None; + }; + + // Ignore comma + let Some((_, remaining_bytes)) = remaining_bytes.split_first() else { + return None; + }; + bytes = remaining_bytes; + + forks[count] = fork; + count += 1; + } + + i += 1; + } + + Some((forks, count)) } From 0036433af2572a37f3fc7c7593037ca2998a6ba5 Mon Sep 17 00:00:00 2001 From: yaziciahmet Date: Mon, 16 Dec 2024 13:01:59 +0100 Subject: [PATCH 12/96] Rename --- .../rollup-interface/src/fork/tests.rs | 23 ++++++++++++------- 1 file changed, 15 insertions(+), 8 deletions(-) diff --git a/crates/sovereign-sdk/rollup-interface/src/fork/tests.rs b/crates/sovereign-sdk/rollup-interface/src/fork/tests.rs index 2d9539d3a..eb3bdad1c 100644 --- a/crates/sovereign-sdk/rollup-interface/src/fork/tests.rs +++ b/crates/sovereign-sdk/rollup-interface/src/fork/tests.rs @@ -1,6 +1,6 @@ use anyhow::anyhow; -use super::ForkManager; +use super::{parse_fork_list_utf8, ForkManager}; use crate::fork::{fork_from_block_number, Fork, ForkMigration}; use crate::spec::SpecId; @@ -68,12 +68,12 @@ fn test_fork_parse_utf8() { let max64 = u64::MAX.to_string(); let max64plusone = ((u64::MAX as u128) + 1).to_string(); - test_success_fork_parse_utf8(b"0:0", 0, 0); - test_success_fork_parse_utf8(b"1:1000", 1, 1000); - test_success_fork_parse_utf8(b"1:1", 1, 1); - test_success_fork_parse_utf8(b"2:1234567890", 2, 1234567890); - test_success_fork_parse_utf8(b"0:110", 0, 110); - test_success_fork_parse_utf8(format!("1:{}", max64).as_bytes(), 1, u64::MAX); + assert_fork_parse_utf8(b"0:0", 0, 0); + assert_fork_parse_utf8(b"1:1000", 1, 1000); + assert_fork_parse_utf8(b"1:1", 1, 1); + assert_fork_parse_utf8(b"2:1234567890", 2, 1234567890); + assert_fork_parse_utf8(b"0:110", 0, 110); + assert_fork_parse_utf8(format!("1:{}", max64).as_bytes(), 1, u64::MAX); assert!(Fork::from_colon_separated_utf8(b"").is_none()); assert!(Fork::from_colon_separated_utf8(b":").is_none()); @@ -89,8 +89,15 @@ fn test_fork_parse_utf8() { assert!(Fork::from_colon_separated_utf8(format!("1:{}", max64plusone).as_bytes()).is_none()); } -fn test_success_fork_parse_utf8(bytes: &[u8], exp_spec: u8, exp_height: u64) { +fn assert_fork_parse_utf8(bytes: &[u8], exp_spec: u8, exp_height: u64) { let fork = Fork::from_colon_separated_utf8(bytes).unwrap(); assert_eq!(fork.spec_id, SpecId::from_u8(exp_spec).unwrap()); assert_eq!(fork.activation_height, exp_height); } + +#[test] +fn test_fork_parse_list() { + assert!(parse_fork_list_utf8("").is_none()); +} + +fn assert_fork_parse_list() {} From 8778b13d378dfb87001bee22db2a9dea6dfbb1a4 Mon Sep 17 00:00:00 2001 From: yaziciahmet Date: Mon, 16 Dec 2024 13:29:24 +0100 Subject: [PATCH 13/96] Fix list parser & add tests --- .../rollup-interface/src/fork/mod.rs | 46 +++++++++++-------- .../rollup-interface/src/fork/tests.rs | 20 +++++++- 2 files changed, 45 insertions(+), 21 deletions(-) diff --git a/crates/sovereign-sdk/rollup-interface/src/fork/mod.rs b/crates/sovereign-sdk/rollup-interface/src/fork/mod.rs index 695c63155..9b6aa18ef 100644 --- a/crates/sovereign-sdk/rollup-interface/src/fork/mod.rs +++ b/crates/sovereign-sdk/rollup-interface/src/fork/mod.rs @@ -158,34 +158,42 @@ impl Fork { /// } /// ``` pub const fn parse_fork_list_utf8(forks_str: &str) -> Option<([Fork; 50], usize)> { - if forks_str.is_empty() { - return None; - } - let mut forks = [Fork::new(SpecId::Genesis, 0); 50]; let mut count = 0; let mut bytes = forks_str.as_bytes(); let mut i = 0; - while i < bytes.len() { - if bytes[i] == b',' { - let (fork_utf8, remaining_bytes) = bytes.split_at(i); + while !bytes.is_empty() && i < bytes.len() { + if bytes[i] != b',' { + i += 1; + continue; + } - let Some(fork) = Fork::from_colon_separated_utf8(fork_utf8) else { - return None; - }; + let (fork_utf8, remaining_bytes) = bytes.split_at(i); - // Ignore comma - let Some((_, remaining_bytes)) = remaining_bytes.split_first() else { - return None; - }; - bytes = remaining_bytes; + let Some(fork) = Fork::from_colon_separated_utf8(fork_utf8) else { + return None; + }; - forks[count] = fork; - count += 1; - } + // Ignore comma + let Some((_, remaining_bytes)) = remaining_bytes.split_first() else { + return None; + }; + bytes = remaining_bytes; + + forks[count] = fork; + count += 1; - i += 1; + i = 0; + } + + // Add the last one + if !bytes.is_empty() { + let Some(fork) = Fork::from_colon_separated_utf8(bytes) else { + return None; + }; + forks[count] = fork; + count += 1; } Some((forks, count)) diff --git a/crates/sovereign-sdk/rollup-interface/src/fork/tests.rs b/crates/sovereign-sdk/rollup-interface/src/fork/tests.rs index eb3bdad1c..8e09161f6 100644 --- a/crates/sovereign-sdk/rollup-interface/src/fork/tests.rs +++ b/crates/sovereign-sdk/rollup-interface/src/fork/tests.rs @@ -97,7 +97,23 @@ fn assert_fork_parse_utf8(bytes: &[u8], exp_spec: u8, exp_height: u64) { #[test] fn test_fork_parse_list() { - assert!(parse_fork_list_utf8("").is_none()); + assert_fork_parse_list("", &[]); + assert_fork_parse_list("0:123", &[(0, 123)]); + assert_fork_parse_list("0:123,1:456", &[(0, 123), (1, 456)]); + assert_fork_parse_list("0:123,1:456,", &[(0, 123), (1, 456)]); + assert_fork_parse_list("0:1,1:2,2:3", &[(0, 1), (1, 2), (2, 3)]); + + assert!(parse_fork_list_utf8("0123").is_none()); + assert!(parse_fork_list_utf8("01:123").is_none()); + assert!(parse_fork_list_utf8("0:123 1:456").is_none()); } -fn assert_fork_parse_list() {} +fn assert_fork_parse_list(s: &str, exp_list: &[(u8, u64)]) { + let (forks, count) = parse_fork_list_utf8(s).unwrap(); + assert_eq!(exp_list.len(), count); + + for (fork, exp_fork) in forks[0..count].iter().zip(exp_list) { + assert_eq!(fork.spec_id as u8, exp_fork.0); + assert_eq!(fork.activation_height, exp_fork.1); + } +} From 3d83afde50cc8e1138eaa6c2349cb53e838775d4 Mon Sep 17 00:00:00 2001 From: yaziciahmet Date: Mon, 16 Dec 2024 13:53:25 +0100 Subject: [PATCH 14/96] Validate fork list on parse --- .../rollup-interface/src/fork/mod.rs | 41 +++++++++++++++---- .../rollup-interface/src/fork/tests.rs | 13 +++--- 2 files changed, 40 insertions(+), 14 deletions(-) diff --git a/crates/sovereign-sdk/rollup-interface/src/fork/mod.rs b/crates/sovereign-sdk/rollup-interface/src/fork/mod.rs index 9b6aa18ef..1c545ab25 100644 --- a/crates/sovereign-sdk/rollup-interface/src/fork/mod.rs +++ b/crates/sovereign-sdk/rollup-interface/src/fork/mod.rs @@ -144,12 +144,12 @@ impl Fork { /// Parse fork list from utf8 string. Format should be `{spec_id as u8}:{activation_height},{spec_id2 as u8}:{activation_height2}`. /// Since this is a constant fn, it returns a stack allocated array with 50 const size, and a second return value as the count /// of valid forks within this array -/// +/// /// Example: /// ``` /// use sov_rollup_interface::fork::{parse_fork_list_utf8, Fork}; /// const FORKS: Option<([Fork; 50], usize)> = parse_fork_list_utf8("0:1000,1:5000,2:100000"); -/// +/// /// fn main() { /// let forks: &[Fork] = match &FORKS { /// Some((forks, count)) => &forks[0..*count], @@ -158,12 +158,16 @@ impl Fork { /// } /// ``` pub const fn parse_fork_list_utf8(forks_str: &str) -> Option<([Fork; 50], usize)> { + if forks_str.is_empty() { + return None; + } + let mut forks = [Fork::new(SpecId::Genesis, 0); 50]; let mut count = 0; let mut bytes = forks_str.as_bytes(); let mut i = 0; - while !bytes.is_empty() && i < bytes.len() { + while i < bytes.len() { if bytes[i] != b',' { i += 1; continue; @@ -188,12 +192,31 @@ pub const fn parse_fork_list_utf8(forks_str: &str) -> Option<([Fork; 50], usize) } // Add the last one - if !bytes.is_empty() { - let Some(fork) = Fork::from_colon_separated_utf8(bytes) else { - return None; - }; - forks[count] = fork; - count += 1; + let Some(fork) = Fork::from_colon_separated_utf8(bytes) else { + return None; + }; + forks[count] = fork; + count += 1; + + // Validate forks + let mut j = 0; + while j < count { + let fork = forks[j]; + if j == 0 { + // Validate genesis fork + if fork.spec_id as u8 != 0 || fork.activation_height != 0 { + return None; + } + } else { + // Validate spec_id increase by 1, and activation height is strictly greater than the previous fork + if (fork.spec_id as u8).wrapping_sub(forks[j - 1].spec_id as u8) != 1 + || fork.activation_height <= forks[j - 1].activation_height + { + return None; + } + } + + j += 1; } Some((forks, count)) diff --git a/crates/sovereign-sdk/rollup-interface/src/fork/tests.rs b/crates/sovereign-sdk/rollup-interface/src/fork/tests.rs index 8e09161f6..8fb35ef07 100644 --- a/crates/sovereign-sdk/rollup-interface/src/fork/tests.rs +++ b/crates/sovereign-sdk/rollup-interface/src/fork/tests.rs @@ -97,15 +97,18 @@ fn assert_fork_parse_utf8(bytes: &[u8], exp_spec: u8, exp_height: u64) { #[test] fn test_fork_parse_list() { - assert_fork_parse_list("", &[]); - assert_fork_parse_list("0:123", &[(0, 123)]); - assert_fork_parse_list("0:123,1:456", &[(0, 123), (1, 456)]); - assert_fork_parse_list("0:123,1:456,", &[(0, 123), (1, 456)]); - assert_fork_parse_list("0:1,1:2,2:3", &[(0, 1), (1, 2), (2, 3)]); + assert_fork_parse_list("0:0", &[(0, 0)]); + assert_fork_parse_list("0:0,1:456", &[(0, 0), (1, 456)]); + assert_fork_parse_list("0:0,1:1,2:2", &[(0, 0), (1, 1), (2, 2)]); + assert!(parse_fork_list_utf8("").is_none()); assert!(parse_fork_list_utf8("0123").is_none()); assert!(parse_fork_list_utf8("01:123").is_none()); assert!(parse_fork_list_utf8("0:123 1:456").is_none()); + assert!(parse_fork_list_utf8("0:123,1:456,").is_none()); + assert!(parse_fork_list_utf8("1:123").is_none()); + assert!(parse_fork_list_utf8("0:0,2:456,1:789").is_none()); + assert!(parse_fork_list_utf8("0:0,1:456,2:123").is_none()); } fn assert_fork_parse_list(s: &str, exp_list: &[(u8, u64)]) { From 9457a0dcc774236b7f9d5363484067b12d24b715 Mon Sep 17 00:00:00 2001 From: yaziciahmet Date: Mon, 16 Dec 2024 14:13:42 +0100 Subject: [PATCH 15/96] Add light client consts --- .../light-client-proof-bitcoin/Cargo.lock | 1 + .../light-client-proof-bitcoin/Cargo.toml | 1 + .../src/bin/light_client_proof_bitcoin.rs | 33 +++++++++++++++++++ 3 files changed, 35 insertions(+) diff --git a/guests/risc0/light-client-proof-bitcoin/Cargo.lock b/guests/risc0/light-client-proof-bitcoin/Cargo.lock index 21c77740d..1d066ebc3 100644 --- a/guests/risc0/light-client-proof-bitcoin/Cargo.lock +++ b/guests/risc0/light-client-proof-bitcoin/Cargo.lock @@ -1644,6 +1644,7 @@ dependencies = [ "citrea-light-client-prover", "citrea-primitives", "citrea-risc0-adapter", + "const-hex", "risc0-zkvm", "risc0-zkvm-platform", "sov-modules-api", diff --git a/guests/risc0/light-client-proof-bitcoin/Cargo.toml b/guests/risc0/light-client-proof-bitcoin/Cargo.toml index d5ac261b7..efbc42ab4 100644 --- a/guests/risc0/light-client-proof-bitcoin/Cargo.toml +++ b/guests/risc0/light-client-proof-bitcoin/Cargo.toml @@ -15,6 +15,7 @@ bitcoin-da = { path = "../../../crates/bitcoin-da", default-features = false } citrea-light-client-prover = { path = "../../../crates/light-client-prover", default-features = false } citrea-primitives = { path = "../../../crates/primitives" } citrea-risc0-adapter = { path = "../../../crates/risc0" } +const-hex = "1" sov-modules-api = { path = "../../../crates/sovereign-sdk/module-system/sov-modules-api", default-features = false } sov-modules-stf-blueprint = { path = "../../../crates/sovereign-sdk/module-system/sov-modules-stf-blueprint" } sov-rollup-interface = { path = "../../../crates/sovereign-sdk/rollup-interface" } diff --git a/guests/risc0/light-client-proof-bitcoin/src/bin/light_client_proof_bitcoin.rs b/guests/risc0/light-client-proof-bitcoin/src/bin/light_client_proof_bitcoin.rs index 234a85cf8..6edff05a3 100644 --- a/guests/risc0/light-client-proof-bitcoin/src/bin/light_client_proof_bitcoin.rs +++ b/guests/risc0/light-client-proof-bitcoin/src/bin/light_client_proof_bitcoin.rs @@ -9,6 +9,39 @@ use sov_rollup_interface::zk::ZkvmGuest; risc0_zkvm::guest::entry!(main); +const L2_GENESIS_ROOT: [u8; 32] = match option_env!("L2_GENESIS_ROOT") { + Some(hex_root) => { + match const_hex::const_decode_to_array(hex_root.as_bytes()) { + Ok(root) => root, + Err(_) => panic!("L2_GENESIS_ROOT must be valid 32-byte hex string"), + } + } + // TODO: what to do here? + None => [0; 32], +}; + +const BATCH_PROOF_METHOD_ID: [u8; 32] = match option_env!("BATCH_PROOF_METHOD_ID") { + Some(hex_method_id) => { + match const_hex::const_decode_to_array(hex_method_id.as_bytes()) { + Ok(method_id) => method_id, + Err(_) => panic!("BATCH_PROOF_METHOD_ID must be valid 32-byte hex string"), + } + } + // TODO: what to do here? + None => [0; 32], +}; + +const BATCH_PROVER_DA_PUBLIC_KEY: [u8; 33] = match option_env!("BATCH_PROVER_DA_PUBLIC_KEY") { + Some(hex_pub_key) => { + match const_hex::const_decode_to_array(hex_pub_key.as_bytes()) { + Ok(pub_key) => pub_key, + Err(_) => panic!("BATCH_PROVER_DA_PUBLIC_KEY must be valid 33-byte hex string"), + } + } + // TODO: what to do here? + None => [0; 33], +}; + pub fn main() { let guest = Risc0Guest::new(); From c9433c6685c7da4af1e45c7a64eece0b9ade634f Mon Sep 17 00:00:00 2001 From: yaziciahmet Date: Mon, 16 Dec 2024 14:16:03 +0100 Subject: [PATCH 16/96] Use specific const-hex v --- guests/risc0/batch-proof-bitcoin/Cargo.toml | 2 +- guests/risc0/light-client-proof-bitcoin/Cargo.toml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/guests/risc0/batch-proof-bitcoin/Cargo.toml b/guests/risc0/batch-proof-bitcoin/Cargo.toml index 2bbecbec1..cc2e3b910 100644 --- a/guests/risc0/batch-proof-bitcoin/Cargo.toml +++ b/guests/risc0/batch-proof-bitcoin/Cargo.toml @@ -15,7 +15,7 @@ bitcoin-da = { path = "../../../crates/bitcoin-da", default-features = false } citrea-primitives = { path = "../../../crates/primitives" } citrea-risc0-adapter = { path = "../../../crates/risc0" } citrea-stf = { path = "../../../crates/citrea-stf" } -const-hex = "1" +const-hex = "1.12" sov-modules-api = { path = "../../../crates/sovereign-sdk/module-system/sov-modules-api", default-features = false } sov-modules-stf-blueprint = { path = "../../../crates/sovereign-sdk/module-system/sov-modules-stf-blueprint" } sov-rollup-interface = { path = "../../../crates/sovereign-sdk/rollup-interface" } diff --git a/guests/risc0/light-client-proof-bitcoin/Cargo.toml b/guests/risc0/light-client-proof-bitcoin/Cargo.toml index efbc42ab4..30f9e8a41 100644 --- a/guests/risc0/light-client-proof-bitcoin/Cargo.toml +++ b/guests/risc0/light-client-proof-bitcoin/Cargo.toml @@ -15,7 +15,7 @@ bitcoin-da = { path = "../../../crates/bitcoin-da", default-features = false } citrea-light-client-prover = { path = "../../../crates/light-client-prover", default-features = false } citrea-primitives = { path = "../../../crates/primitives" } citrea-risc0-adapter = { path = "../../../crates/risc0" } -const-hex = "1" +const-hex = "1.12" sov-modules-api = { path = "../../../crates/sovereign-sdk/module-system/sov-modules-api", default-features = false } sov-modules-stf-blueprint = { path = "../../../crates/sovereign-sdk/module-system/sov-modules-stf-blueprint" } sov-rollup-interface = { path = "../../../crates/sovereign-sdk/rollup-interface" } From f1706d349b96679d5fe8c2058ad4e035f41ce623 Mon Sep 17 00:00:00 2001 From: yaziciahmet Date: Mon, 16 Dec 2024 14:17:07 +0100 Subject: [PATCH 17/96] Update do not use comment --- .../rollup-interface/src/state_machine/zk/mod.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/crates/sovereign-sdk/rollup-interface/src/state_machine/zk/mod.rs b/crates/sovereign-sdk/rollup-interface/src/state_machine/zk/mod.rs index e9461de17..3f2248ade 100644 --- a/crates/sovereign-sdk/rollup-interface/src/state_machine/zk/mod.rs +++ b/crates/sovereign-sdk/rollup-interface/src/state_machine/zk/mod.rs @@ -173,10 +173,10 @@ pub struct BatchProofCircuitInput<'txs, StateRoot, Witness, Da: DaSpec, Tx: Clon /// DA block headers the soft confirmations was constructed on. pub da_block_headers_of_soft_confirmations: VecDeque>, /// Sequencer soft confirmation public key. - /// **DO NOT USE THIS FIELD** + /// **DO NOT USE THIS FIELD IN POST FORK1 GUEST** pub sequencer_public_key: Vec, /// Sequencer DA public_key: Vec, - /// **DO NOT USE THIS FIELD** + /// **DO NOT USE THIS FIELD IN POST FORK1 GUEST** pub sequencer_da_public_key: Vec, /// The range of sequencer commitments that are being processed. /// The range is inclusive. From 6b942a43e5732cbdded38c90405f22af7d4c4414 Mon Sep 17 00:00:00 2001 From: yaziciahmet Date: Mon, 16 Dec 2024 15:05:33 +0100 Subject: [PATCH 18/96] Allow same activation heights for consecutive forks --- crates/sovereign-sdk/rollup-interface/src/fork/mod.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/crates/sovereign-sdk/rollup-interface/src/fork/mod.rs b/crates/sovereign-sdk/rollup-interface/src/fork/mod.rs index 1c545ab25..b5bb7d622 100644 --- a/crates/sovereign-sdk/rollup-interface/src/fork/mod.rs +++ b/crates/sovereign-sdk/rollup-interface/src/fork/mod.rs @@ -210,7 +210,7 @@ pub const fn parse_fork_list_utf8(forks_str: &str) -> Option<([Fork; 50], usize) } else { // Validate spec_id increase by 1, and activation height is strictly greater than the previous fork if (fork.spec_id as u8).wrapping_sub(forks[j - 1].spec_id as u8) != 1 - || fork.activation_height <= forks[j - 1].activation_height + || fork.activation_height < forks[j - 1].activation_height { return None; } From 50d11642d82b8cc13bd1e738083f6c30a9c6046b Mon Sep 17 00:00:00 2001 From: yaziciahmet Date: Mon, 16 Dec 2024 15:31:53 +0100 Subject: [PATCH 19/96] Enforce env variables in guest build --- .../src/bin/batch_proof_bitcoin.rs | 51 ++++++++----------- .../src/bin/light_client_proof_bitcoin.rs | 42 +++++++-------- 2 files changed, 40 insertions(+), 53 deletions(-) diff --git a/guests/risc0/batch-proof-bitcoin/src/bin/batch_proof_bitcoin.rs b/guests/risc0/batch-proof-bitcoin/src/bin/batch_proof_bitcoin.rs index ae719a704..fa0daedc6 100644 --- a/guests/risc0/batch-proof-bitcoin/src/bin/batch_proof_bitcoin.rs +++ b/guests/risc0/batch-proof-bitcoin/src/bin/batch_proof_bitcoin.rs @@ -14,50 +14,43 @@ use sov_state::ZkStorage; risc0_zkvm::guest::entry!(main); -const SEQUENCER_PUBLIC_KEY: [u8; 32] = match option_env!("SEQUENCER_PUBLIC_KEY") { - Some(hex_pub_key) => { - match const_hex::const_decode_to_array(hex_pub_key.as_bytes()) { - Ok(pub_key) => pub_key, - Err(_) => panic!("SEQUENCER_PUBLIC_KEY must be valid 32-byte hex string"), - } +const SEQUENCER_PUBLIC_KEY: [u8; 32] = { + let hex_pub_key = env!("SEQUENCER_PUBLIC_KEY"); + + match const_hex::const_decode_to_array(hex_pub_key.as_bytes()) { + Ok(pub_key) => pub_key, + Err(_) => panic!("SEQUENCER_PUBLIC_KEY must be valid 32-byte hex string"), } - // TODO: what to do here? - None => [0; 32], }; -const SEQUENCER_DA_PUBLIC_KEY: [u8; 33] = match option_env!("SEQUENCER_DA_PUBLIC_KEY") { - Some(hex_pub_key) => { - match const_hex::const_decode_to_array(hex_pub_key.as_bytes()) { - // TODO: maybe verify the first byte? - Ok(pub_key) => pub_key, - Err(_) => panic!("SEQUENCER_DA_PUBLIC_KEY must be valid 33-byte hex string"), - } +const SEQUENCER_DA_PUBLIC_KEY: [u8; 33] = { + let hex_pub_key = env!("SEQUENCER_DA_PUBLIC_KEY"); + + match const_hex::const_decode_to_array(hex_pub_key.as_bytes()) { + // TODO: maybe verify the first byte? + Ok(pub_key) => pub_key, + Err(_) => panic!("SEQUENCER_DA_PUBLIC_KEY must be valid 33-byte hex string"), } - // TODO: what to do here? - None => [0; 33], }; // Temporary variable to allow FORKS static reference to be valid -const TEMP_FORKS: Option<([Fork; 50], usize)> = match option_env!("FORKS") { - Some(forks_str) => match parse_fork_list_utf8(forks_str) { +const TEMP_FORKS: ([Fork; 50], usize) = { + let forks_str = env!("FORKS"); + + match parse_fork_list_utf8(forks_str) { Some((forks, count)) => { if count == 0 { panic!("FORKS can not be empty"); } - Some((forks, count)) + (forks, count) } None => panic!("FORKS must be valid comma separated list"), - }, - // TODO: what to do here? - None => None, + } }; -const FORKS: &[Fork] = match &TEMP_FORKS { - Some((forks, count)) => { - forks.split_at(*count).0 - } - // TODO: what to do here? - None => &[], +const FORKS: &[Fork] = { + let (temp_forks, count) = &TEMP_FORKS; + temp_forks.split_at(*count).0 }; pub fn main() { diff --git a/guests/risc0/light-client-proof-bitcoin/src/bin/light_client_proof_bitcoin.rs b/guests/risc0/light-client-proof-bitcoin/src/bin/light_client_proof_bitcoin.rs index 6edff05a3..b223f0dcf 100644 --- a/guests/risc0/light-client-proof-bitcoin/src/bin/light_client_proof_bitcoin.rs +++ b/guests/risc0/light-client-proof-bitcoin/src/bin/light_client_proof_bitcoin.rs @@ -9,37 +9,31 @@ use sov_rollup_interface::zk::ZkvmGuest; risc0_zkvm::guest::entry!(main); -const L2_GENESIS_ROOT: [u8; 32] = match option_env!("L2_GENESIS_ROOT") { - Some(hex_root) => { - match const_hex::const_decode_to_array(hex_root.as_bytes()) { - Ok(root) => root, - Err(_) => panic!("L2_GENESIS_ROOT must be valid 32-byte hex string"), - } +const L2_GENESIS_ROOT: [u8; 32] = { + let hex_root = env!("L2_GENESIS_ROOT"); + + match const_hex::const_decode_to_array(hex_root.as_bytes()) { + Ok(root) => root, + Err(_) => panic!("L2_GENESIS_ROOT must be valid 32-byte hex string"), } - // TODO: what to do here? - None => [0; 32], }; -const BATCH_PROOF_METHOD_ID: [u8; 32] = match option_env!("BATCH_PROOF_METHOD_ID") { - Some(hex_method_id) => { - match const_hex::const_decode_to_array(hex_method_id.as_bytes()) { - Ok(method_id) => method_id, - Err(_) => panic!("BATCH_PROOF_METHOD_ID must be valid 32-byte hex string"), - } +const BATCH_PROOF_METHOD_ID: [u8; 32] = { + let hex_method_id = env!("BATCH_PROOF_METHOD_ID"); + + match const_hex::const_decode_to_array(hex_method_id.as_bytes()) { + Ok(method_id) => method_id, + Err(_) => panic!("BATCH_PROOF_METHOD_ID must be valid 32-byte hex string"), } - // TODO: what to do here? - None => [0; 32], }; -const BATCH_PROVER_DA_PUBLIC_KEY: [u8; 33] = match option_env!("BATCH_PROVER_DA_PUBLIC_KEY") { - Some(hex_pub_key) => { - match const_hex::const_decode_to_array(hex_pub_key.as_bytes()) { - Ok(pub_key) => pub_key, - Err(_) => panic!("BATCH_PROVER_DA_PUBLIC_KEY must be valid 33-byte hex string"), - } +const BATCH_PROVER_DA_PUBLIC_KEY: [u8; 33] = { + let hex_pub_key = env!("BATCH_PROVER_DA_PUBLIC_KEY"); + + match const_hex::const_decode_to_array(hex_pub_key.as_bytes()) { + Ok(pub_key) => pub_key, + Err(_) => panic!("BATCH_PROVER_DA_PUBLIC_KEY must be valid 33-byte hex string"), } - // TODO: what to do here? - None => [0; 33], }; pub fn main() { From 57222b4114dcfa8992b710073cbb91c731d35112 Mon Sep 17 00:00:00 2001 From: yaziciahmet Date: Mon, 16 Dec 2024 15:39:26 +0100 Subject: [PATCH 20/96] Add env variables to mocks --- guests/risc0/batch-proof-mock/Cargo.lock | 1 + guests/risc0/batch-proof-mock/Cargo.toml | 1 + .../src/bin/batch_proof_mock.rs | 40 +++++++++++++++++++ .../risc0/light-client-proof-mock/Cargo.lock | 1 + .../risc0/light-client-proof-mock/Cargo.toml | 1 + .../src/bin/light_client_proof_mock.rs | 27 +++++++++++++ 6 files changed, 71 insertions(+) diff --git a/guests/risc0/batch-proof-mock/Cargo.lock b/guests/risc0/batch-proof-mock/Cargo.lock index 3bb439c07..7457e2bae 100644 --- a/guests/risc0/batch-proof-mock/Cargo.lock +++ b/guests/risc0/batch-proof-mock/Cargo.lock @@ -557,6 +557,7 @@ dependencies = [ "citrea-primitives", "citrea-risc0-adapter", "citrea-stf", + "const-hex", "risc0-zkvm", "risc0-zkvm-platform", "sov-mock-da", diff --git a/guests/risc0/batch-proof-mock/Cargo.toml b/guests/risc0/batch-proof-mock/Cargo.toml index a0f43bafb..33f468ecb 100644 --- a/guests/risc0/batch-proof-mock/Cargo.toml +++ b/guests/risc0/batch-proof-mock/Cargo.toml @@ -14,6 +14,7 @@ anyhow = "1.0" citrea-primitives = { path = "../../../crates/primitives" } citrea-risc0-adapter = { path = "../../../crates/risc0" } citrea-stf = { path = "../../../crates/citrea-stf" } +const-hex = "1.12" sov-mock-da = { path = "../../../crates/sovereign-sdk/adapters/mock-da", default-features = false } sov-modules-api = { path = "../../../crates/sovereign-sdk/module-system/sov-modules-api", default-features = false } sov-modules-stf-blueprint = { path = "../../../crates/sovereign-sdk/module-system/sov-modules-stf-blueprint" } diff --git a/guests/risc0/batch-proof-mock/src/bin/batch_proof_mock.rs b/guests/risc0/batch-proof-mock/src/bin/batch_proof_mock.rs index 8a40f8cd5..f6c13fb48 100644 --- a/guests/risc0/batch-proof-mock/src/bin/batch_proof_mock.rs +++ b/guests/risc0/batch-proof-mock/src/bin/batch_proof_mock.rs @@ -3,6 +3,7 @@ use citrea_stf::runtime::Runtime; use citrea_stf::StfVerifier; use sov_mock_da::MockDaVerifier; use sov_modules_api::default_context::ZkDefaultContext; +use sov_modules_api::fork::{parse_fork_list_utf8, Fork}; use sov_modules_stf_blueprint::StfBlueprint; use citrea_risc0_adapter::guest::Risc0Guest; use sov_state::ZkStorage; @@ -10,6 +11,45 @@ use sov_rollup_interface::zk::ZkvmGuest; risc0_zkvm::guest::entry!(main); +const SEQUENCER_PUBLIC_KEY: [u8; 32] = { + let hex_pub_key = env!("SEQUENCER_PUBLIC_KEY"); + + match const_hex::const_decode_to_array(hex_pub_key.as_bytes()) { + Ok(pub_key) => pub_key, + Err(_) => panic!("SEQUENCER_PUBLIC_KEY must be valid 32-byte hex string"), + } +}; + +const SEQUENCER_DA_PUBLIC_KEY: [u8; 33] = { + let hex_pub_key = env!("SEQUENCER_DA_PUBLIC_KEY"); + + match const_hex::const_decode_to_array(hex_pub_key.as_bytes()) { + // TODO: maybe verify the first byte? + Ok(pub_key) => pub_key, + Err(_) => panic!("SEQUENCER_DA_PUBLIC_KEY must be valid 33-byte hex string"), + } +}; + +// Temporary variable to allow FORKS static reference to be valid +const TEMP_FORKS: ([Fork; 50], usize) = { + let forks_str = env!("FORKS"); + + match parse_fork_list_utf8(forks_str) { + Some((forks, count)) => { + if count == 0 { + panic!("FORKS can not be empty"); + } + (forks, count) + } + None => panic!("FORKS must be valid comma separated list"), + } +}; + +const FORKS: &[Fork] = { + let (temp_forks, count) = &TEMP_FORKS; + temp_forks.split_at(*count).0 +}; + pub fn main() { let guest = Risc0Guest::new(); let storage = ZkStorage::new(); diff --git a/guests/risc0/light-client-proof-mock/Cargo.lock b/guests/risc0/light-client-proof-mock/Cargo.lock index 71590c375..aecf6f26f 100644 --- a/guests/risc0/light-client-proof-mock/Cargo.lock +++ b/guests/risc0/light-client-proof-mock/Cargo.lock @@ -1448,6 +1448,7 @@ dependencies = [ "citrea-light-client-prover", "citrea-primitives", "citrea-risc0-adapter", + "const-hex", "risc0-zkvm", "risc0-zkvm-platform", "sov-mock-da", diff --git a/guests/risc0/light-client-proof-mock/Cargo.toml b/guests/risc0/light-client-proof-mock/Cargo.toml index 25f76b58e..a6290b451 100644 --- a/guests/risc0/light-client-proof-mock/Cargo.toml +++ b/guests/risc0/light-client-proof-mock/Cargo.toml @@ -16,6 +16,7 @@ sov-mock-da = { path = "../../../crates/sovereign-sdk/adapters/mock-da", default citrea-light-client-prover = { path = "../../../crates/light-client-prover", default-features = false } citrea-primitives = { path = "../../../crates/primitives" } citrea-risc0-adapter = { path = "../../../crates/risc0" } +const-hex = "1.12" sov-modules-api = { path = "../../../crates/sovereign-sdk/module-system/sov-modules-api", default-features = false } sov-modules-stf-blueprint = { path = "../../../crates/sovereign-sdk/module-system/sov-modules-stf-blueprint" } sov-rollup-interface = { path = "../../../crates/sovereign-sdk/rollup-interface" } diff --git a/guests/risc0/light-client-proof-mock/src/bin/light_client_proof_mock.rs b/guests/risc0/light-client-proof-mock/src/bin/light_client_proof_mock.rs index 8b9e54bb6..3671d0845 100644 --- a/guests/risc0/light-client-proof-mock/src/bin/light_client_proof_mock.rs +++ b/guests/risc0/light-client-proof-mock/src/bin/light_client_proof_mock.rs @@ -6,6 +6,33 @@ use sov_rollup_interface::zk::ZkvmGuest; risc0_zkvm::guest::entry!(main); +const L2_GENESIS_ROOT: [u8; 32] = { + let hex_root = env!("L2_GENESIS_ROOT"); + + match const_hex::const_decode_to_array(hex_root.as_bytes()) { + Ok(root) => root, + Err(_) => panic!("L2_GENESIS_ROOT must be valid 32-byte hex string"), + } +}; + +const BATCH_PROOF_METHOD_ID: [u8; 32] = { + let hex_method_id = env!("BATCH_PROOF_METHOD_ID"); + + match const_hex::const_decode_to_array(hex_method_id.as_bytes()) { + Ok(method_id) => method_id, + Err(_) => panic!("BATCH_PROOF_METHOD_ID must be valid 32-byte hex string"), + } +}; + +const BATCH_PROVER_DA_PUBLIC_KEY: [u8; 33] = { + let hex_pub_key = env!("BATCH_PROVER_DA_PUBLIC_KEY"); + + match const_hex::const_decode_to_array(hex_pub_key.as_bytes()) { + Ok(pub_key) => pub_key, + Err(_) => panic!("BATCH_PROVER_DA_PUBLIC_KEY must be valid 33-byte hex string"), + } +}; + pub fn main() { let guest = Risc0Guest::new(); From b07aa3cdf46a031c546c781ca8a6c89185c8ea4f Mon Sep 17 00:00:00 2001 From: yaziciahmet Date: Mon, 16 Dec 2024 17:37:35 +0100 Subject: [PATCH 21/96] Separate fork list verification --- .../rollup-interface/src/fork/mod.rs | 29 ++++++++++++------- 1 file changed, 18 insertions(+), 11 deletions(-) diff --git a/crates/sovereign-sdk/rollup-interface/src/fork/mod.rs b/crates/sovereign-sdk/rollup-interface/src/fork/mod.rs index b5bb7d622..362df5e00 100644 --- a/crates/sovereign-sdk/rollup-interface/src/fork/mod.rs +++ b/crates/sovereign-sdk/rollup-interface/src/fork/mod.rs @@ -198,26 +198,33 @@ pub const fn parse_fork_list_utf8(forks_str: &str) -> Option<([Fork; 50], usize) forks[count] = fork; count += 1; - // Validate forks - let mut j = 0; - while j < count { - let fork = forks[j]; - if j == 0 { + if !verify_forks(&forks, count) { + return None; + } + + Some((forks, count)) +} + +pub const fn verify_forks(forks: &[Fork], count: usize) -> bool { + let mut i = 0; + while i < count { + let fork = forks[i]; + if i == 0 { // Validate genesis fork if fork.spec_id as u8 != 0 || fork.activation_height != 0 { - return None; + return false; } } else { // Validate spec_id increase by 1, and activation height is strictly greater than the previous fork - if (fork.spec_id as u8).wrapping_sub(forks[j - 1].spec_id as u8) != 1 - || fork.activation_height < forks[j - 1].activation_height + if (fork.spec_id as u8).wrapping_sub(forks[i - 1].spec_id as u8) != 1 + || fork.activation_height < forks[i - 1].activation_height { - return None; + return false; } } - j += 1; + i += 1; } - Some((forks, count)) + true } From 4c4a05d9081f17afcf748adb008f78c5ca83a7e0 Mon Sep 17 00:00:00 2001 From: yaziciahmet Date: Mon, 16 Dec 2024 17:39:18 +0100 Subject: [PATCH 22/96] Add doc --- crates/sovereign-sdk/rollup-interface/src/fork/mod.rs | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/crates/sovereign-sdk/rollup-interface/src/fork/mod.rs b/crates/sovereign-sdk/rollup-interface/src/fork/mod.rs index 362df5e00..4cff1e27a 100644 --- a/crates/sovereign-sdk/rollup-interface/src/fork/mod.rs +++ b/crates/sovereign-sdk/rollup-interface/src/fork/mod.rs @@ -205,9 +205,11 @@ pub const fn parse_fork_list_utf8(forks_str: &str) -> Option<([Fork; 50], usize) Some((forks, count)) } -pub const fn verify_forks(forks: &[Fork], count: usize) -> bool { +/// Verifies the order of forks. `size` is needed here due to being in const environment, +/// size of the fork might not be known beforehand. +pub const fn verify_forks(forks: &[Fork], size: usize) -> bool { let mut i = 0; - while i < count { + while i < size { let fork = forks[i]; if i == 0 { // Validate genesis fork From 515d3b8dbc83d2d06643d5052e29de3f2aa8d4d5 Mon Sep 17 00:00:00 2001 From: yaziciahmet Date: Tue, 17 Dec 2024 18:06:56 +0100 Subject: [PATCH 23/96] Allow non-zero start of forks --- crates/sovereign-sdk/rollup-interface/src/fork/mod.rs | 11 +++-------- 1 file changed, 3 insertions(+), 8 deletions(-) diff --git a/crates/sovereign-sdk/rollup-interface/src/fork/mod.rs b/crates/sovereign-sdk/rollup-interface/src/fork/mod.rs index 4cff1e27a..4e9b8aed7 100644 --- a/crates/sovereign-sdk/rollup-interface/src/fork/mod.rs +++ b/crates/sovereign-sdk/rollup-interface/src/fork/mod.rs @@ -210,16 +210,11 @@ pub const fn parse_fork_list_utf8(forks_str: &str) -> Option<([Fork; 50], usize) pub const fn verify_forks(forks: &[Fork], size: usize) -> bool { let mut i = 0; while i < size { - let fork = forks[i]; - if i == 0 { - // Validate genesis fork - if fork.spec_id as u8 != 0 || fork.activation_height != 0 { - return false; - } - } else { + if i != 0 { + let fork = forks[i]; // Validate spec_id increase by 1, and activation height is strictly greater than the previous fork if (fork.spec_id as u8).wrapping_sub(forks[i - 1].spec_id as u8) != 1 - || fork.activation_height < forks[i - 1].activation_height + || fork.activation_height <= forks[i - 1].activation_height { return false; } From da2b66d5cefef7fa12dfb2400509f865ae8d0c8f Mon Sep 17 00:00:00 2001 From: yaziciahmet Date: Tue, 17 Dec 2024 19:32:52 +0100 Subject: [PATCH 24/96] Create Forks wrapper struct --- .../rollup-interface/src/fork/mod.rs | 154 ++++++++++-------- .../rollup-interface/src/fork/tests.rs | 26 +-- 2 files changed, 102 insertions(+), 78 deletions(-) diff --git a/crates/sovereign-sdk/rollup-interface/src/fork/mod.rs b/crates/sovereign-sdk/rollup-interface/src/fork/mod.rs index 4e9b8aed7..4361501d4 100644 --- a/crates/sovereign-sdk/rollup-interface/src/fork/mod.rs +++ b/crates/sovereign-sdk/rollup-interface/src/fork/mod.rs @@ -10,6 +10,81 @@ pub use migration::*; use crate::spec::SpecId; +pub struct Forks { + forks: [Fork; 50], + count: usize, +} + +impl Forks { + /// Parse fork list from utf8 string. Format should be `{spec_id as u8}:{activation_height},{spec_id2 as u8}:{activation_height2}`. + /// Since this is a constant fn, it returns a stack allocated array with 50 const size, and a second return value as the count + /// of valid forks within this array + /// + /// Example: + /// ``` + /// use sov_rollup_interface::fork::{Fork, Forks}; + /// const FORKS: Option = Forks::from_utf8("0:1000,1:5000,2:100000"); + /// + /// fn main() { + /// let forks: &[Fork] = match &FORKS { + /// Some(forks) => forks.inner(), + /// None => &[], + /// }; + /// } + /// ``` + pub const fn from_utf8(forks_str: &str) -> Option { + if forks_str.is_empty() { + return None; + } + + let mut forks = [Fork::new(SpecId::Genesis, 0); 50]; + let mut count = 0; + + let mut bytes = forks_str.as_bytes(); + let mut i = 0; + while i < bytes.len() { + if bytes[i] != b',' { + i += 1; + continue; + } + + let (fork_utf8, remaining_bytes) = bytes.split_at(i); + + let Some(fork) = Fork::from_colon_separated_utf8(fork_utf8) else { + return None; + }; + + // Ignore comma + let Some((_, remaining_bytes)) = remaining_bytes.split_first() else { + return None; + }; + bytes = remaining_bytes; + + forks[count] = fork; + count += 1; + + i = 0; + } + + // Add the last one + let Some(fork) = Fork::from_colon_separated_utf8(bytes) else { + return None; + }; + forks[count] = fork; + count += 1; + + if !verify_forks(&forks, count) { + return None; + } + + Some(Self { forks, count }) + } + + pub const fn inner(&self) -> &[Fork] { + self.forks.split_at(self.count).0 + } +} + /// Fork is a wrapper struct that contains spec id and it's activation height #[derive(Debug, Clone, Copy)] pub struct Fork { @@ -19,6 +94,12 @@ pub struct Fork { pub activation_height: u64, } +impl PartialEq for Fork { + fn eq(&self, other: &Self) -> bool { + self.spec_id == other.spec_id && self.activation_height == other.activation_height + } +} + impl Fork { /// Creates new Fork instance pub const fn new(spec_id: SpecId, activation_height: u64) -> Self { @@ -141,77 +222,18 @@ impl Fork { } } -/// Parse fork list from utf8 string. Format should be `{spec_id as u8}:{activation_height},{spec_id2 as u8}:{activation_height2}`. -/// Since this is a constant fn, it returns a stack allocated array with 50 const size, and a second return value as the count -/// of valid forks within this array -/// -/// Example: -/// ``` -/// use sov_rollup_interface::fork::{parse_fork_list_utf8, Fork}; -/// const FORKS: Option<([Fork; 50], usize)> = parse_fork_list_utf8("0:1000,1:5000,2:100000"); -/// -/// fn main() { -/// let forks: &[Fork] = match &FORKS { -/// Some((forks, count)) => &forks[0..*count], -/// None => &[], -/// }; -/// } -/// ``` -pub const fn parse_fork_list_utf8(forks_str: &str) -> Option<([Fork; 50], usize)> { - if forks_str.is_empty() { - return None; - } - - let mut forks = [Fork::new(SpecId::Genesis, 0); 50]; - let mut count = 0; - - let mut bytes = forks_str.as_bytes(); - let mut i = 0; - while i < bytes.len() { - if bytes[i] != b',' { - i += 1; - continue; - } - - let (fork_utf8, remaining_bytes) = bytes.split_at(i); - - let Some(fork) = Fork::from_colon_separated_utf8(fork_utf8) else { - return None; - }; - - // Ignore comma - let Some((_, remaining_bytes)) = remaining_bytes.split_first() else { - return None; - }; - bytes = remaining_bytes; - - forks[count] = fork; - count += 1; - - i = 0; - } - - // Add the last one - let Some(fork) = Fork::from_colon_separated_utf8(bytes) else { - return None; - }; - forks[count] = fork; - count += 1; - - if !verify_forks(&forks, count) { - return None; - } - - Some((forks, count)) -} - /// Verifies the order of forks. `size` is needed here due to being in const environment, /// size of the fork might not be known beforehand. pub const fn verify_forks(forks: &[Fork], size: usize) -> bool { let mut i = 0; while i < size { - if i != 0 { - let fork = forks[i]; + let fork = forks[i]; + if i == 0 { + // Ensure that the first fork starts from height 0 + if fork.activation_height != 0 { + return false; + } + } else { // Validate spec_id increase by 1, and activation height is strictly greater than the previous fork if (fork.spec_id as u8).wrapping_sub(forks[i - 1].spec_id as u8) != 1 || fork.activation_height <= forks[i - 1].activation_height diff --git a/crates/sovereign-sdk/rollup-interface/src/fork/tests.rs b/crates/sovereign-sdk/rollup-interface/src/fork/tests.rs index 8fb35ef07..ab6c9fefb 100644 --- a/crates/sovereign-sdk/rollup-interface/src/fork/tests.rs +++ b/crates/sovereign-sdk/rollup-interface/src/fork/tests.rs @@ -1,6 +1,6 @@ use anyhow::anyhow; -use super::{parse_fork_list_utf8, ForkManager}; +use super::{Forks, ForkManager}; use crate::fork::{fork_from_block_number, Fork, ForkMigration}; use crate::spec::SpecId; @@ -100,22 +100,24 @@ fn test_fork_parse_list() { assert_fork_parse_list("0:0", &[(0, 0)]); assert_fork_parse_list("0:0,1:456", &[(0, 0), (1, 456)]); assert_fork_parse_list("0:0,1:1,2:2", &[(0, 0), (1, 1), (2, 2)]); + assert_fork_parse_list("1:0,2:123", &[(1, 0), (2, 123)]); - assert!(parse_fork_list_utf8("").is_none()); - assert!(parse_fork_list_utf8("0123").is_none()); - assert!(parse_fork_list_utf8("01:123").is_none()); - assert!(parse_fork_list_utf8("0:123 1:456").is_none()); - assert!(parse_fork_list_utf8("0:123,1:456,").is_none()); - assert!(parse_fork_list_utf8("1:123").is_none()); - assert!(parse_fork_list_utf8("0:0,2:456,1:789").is_none()); - assert!(parse_fork_list_utf8("0:0,1:456,2:123").is_none()); + assert!(Forks::from_utf8("").is_none()); + assert!(Forks::from_utf8("0123").is_none()); + assert!(Forks::from_utf8("01:123").is_none()); + assert!(Forks::from_utf8("0:123,1:456").is_none()); + assert!(Forks::from_utf8("0:0 1:456").is_none()); + assert!(Forks::from_utf8("0:0,1:456,").is_none()); + assert!(Forks::from_utf8("0:0,2:456,1:789").is_none()); + assert!(Forks::from_utf8("0:0,1:456,2:123").is_none()); } fn assert_fork_parse_list(s: &str, exp_list: &[(u8, u64)]) { - let (forks, count) = parse_fork_list_utf8(s).unwrap(); - assert_eq!(exp_list.len(), count); + let forks = Forks::from_utf8(s).unwrap(); + let forks = forks.inner(); + assert_eq!(forks.len(), exp_list.len()); - for (fork, exp_fork) in forks[0..count].iter().zip(exp_list) { + for (fork, exp_fork) in forks.iter().zip(exp_list) { assert_eq!(fork.spec_id as u8, exp_fork.0); assert_eq!(fork.activation_height, exp_fork.1); } From 53f48cecbf2134be4c671fc68b89e0359cb30792 Mon Sep 17 00:00:00 2001 From: yaziciahmet Date: Tue, 17 Dec 2024 19:33:56 +0100 Subject: [PATCH 25/96] Add derive --- crates/sovereign-sdk/rollup-interface/src/fork/mod.rs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/crates/sovereign-sdk/rollup-interface/src/fork/mod.rs b/crates/sovereign-sdk/rollup-interface/src/fork/mod.rs index 4361501d4..a63ecc45d 100644 --- a/crates/sovereign-sdk/rollup-interface/src/fork/mod.rs +++ b/crates/sovereign-sdk/rollup-interface/src/fork/mod.rs @@ -10,6 +10,8 @@ pub use migration::*; use crate::spec::SpecId; +/// Forks is a helper struct fork managing list of forks. +#[derive(Debug, Clone, Copy, PartialEq)] pub struct Forks { forks: [Fork; 50], count: usize, From be23c0328fa2f95ffd598b6262f2131ff8077540 Mon Sep 17 00:00:00 2001 From: yaziciahmet Date: Tue, 17 Dec 2024 19:36:58 +0100 Subject: [PATCH 26/96] Update guests accordingly --- .../src/bin/batch_proof_bitcoin.rs | 18 +++++++----------- .../src/bin/batch_proof_mock.rs | 18 +++++++----------- 2 files changed, 14 insertions(+), 22 deletions(-) diff --git a/guests/risc0/batch-proof-bitcoin/src/bin/batch_proof_bitcoin.rs b/guests/risc0/batch-proof-bitcoin/src/bin/batch_proof_bitcoin.rs index fa0daedc6..b1bfb0820 100644 --- a/guests/risc0/batch-proof-bitcoin/src/bin/batch_proof_bitcoin.rs +++ b/guests/risc0/batch-proof-bitcoin/src/bin/batch_proof_bitcoin.rs @@ -6,7 +6,7 @@ use citrea_risc0_adapter::guest::Risc0Guest; use citrea_stf::runtime::Runtime; use citrea_stf::StfVerifier; use sov_modules_api::default_context::ZkDefaultContext; -use sov_modules_api::fork::{parse_fork_list_utf8, Fork}; +use sov_modules_api::fork::{Fork, Forks}; use sov_modules_stf_blueprint::StfBlueprint; use sov_rollup_interface::da::DaVerifier; use sov_rollup_interface::zk::ZkvmGuest; @@ -34,24 +34,20 @@ const SEQUENCER_DA_PUBLIC_KEY: [u8; 33] = { }; // Temporary variable to allow FORKS static reference to be valid -const TEMP_FORKS: ([Fork; 50], usize) = { +const TEMP_FORKS: Forks = { let forks_str = env!("FORKS"); - match parse_fork_list_utf8(forks_str) { - Some((forks, count)) => { - if count == 0 { - panic!("FORKS can not be empty"); + match Forks::from_utf8(forks_str) { + Some(forks) => { + if forks.inner().len() == 0 { } - (forks, count) + forks } None => panic!("FORKS must be valid comma separated list"), } }; -const FORKS: &[Fork] = { - let (temp_forks, count) = &TEMP_FORKS; - temp_forks.split_at(*count).0 -}; +const FORKS: &[Fork] = TEMP_FORKS.inner(); pub fn main() { let guest = Risc0Guest::new(); diff --git a/guests/risc0/batch-proof-mock/src/bin/batch_proof_mock.rs b/guests/risc0/batch-proof-mock/src/bin/batch_proof_mock.rs index f6c13fb48..f73560199 100644 --- a/guests/risc0/batch-proof-mock/src/bin/batch_proof_mock.rs +++ b/guests/risc0/batch-proof-mock/src/bin/batch_proof_mock.rs @@ -3,7 +3,7 @@ use citrea_stf::runtime::Runtime; use citrea_stf::StfVerifier; use sov_mock_da::MockDaVerifier; use sov_modules_api::default_context::ZkDefaultContext; -use sov_modules_api::fork::{parse_fork_list_utf8, Fork}; +use sov_modules_api::fork::{Fork, Forks}; use sov_modules_stf_blueprint::StfBlueprint; use citrea_risc0_adapter::guest::Risc0Guest; use sov_state::ZkStorage; @@ -31,24 +31,20 @@ const SEQUENCER_DA_PUBLIC_KEY: [u8; 33] = { }; // Temporary variable to allow FORKS static reference to be valid -const TEMP_FORKS: ([Fork; 50], usize) = { +const TEMP_FORKS: Forks = { let forks_str = env!("FORKS"); - match parse_fork_list_utf8(forks_str) { - Some((forks, count)) => { - if count == 0 { - panic!("FORKS can not be empty"); + match Forks::from_utf8(forks_str) { + Some(forks) => { + if forks.inner().len() == 0 { } - (forks, count) + forks } None => panic!("FORKS must be valid comma separated list"), } }; -const FORKS: &[Fork] = { - let (temp_forks, count) = &TEMP_FORKS; - temp_forks.split_at(*count).0 -}; +const FORKS: &[Fork] = TEMP_FORKS.inner(); pub fn main() { let guest = Risc0Guest::new(); From 479e0b43cf642b1df790fb07b24a1f7039c5d920 Mon Sep 17 00:00:00 2001 From: yaziciahmet Date: Tue, 17 Dec 2024 19:50:50 +0100 Subject: [PATCH 27/96] Implement serde for Fork & Forks --- .../rollup-interface/src/fork/mod.rs | 41 ++++++++++++++++++- .../rollup-interface/src/fork/tests.rs | 4 +- 2 files changed, 42 insertions(+), 3 deletions(-) diff --git a/crates/sovereign-sdk/rollup-interface/src/fork/mod.rs b/crates/sovereign-sdk/rollup-interface/src/fork/mod.rs index a63ecc45d..db27a8401 100644 --- a/crates/sovereign-sdk/rollup-interface/src/fork/mod.rs +++ b/crates/sovereign-sdk/rollup-interface/src/fork/mod.rs @@ -7,6 +7,8 @@ mod tests; pub use manager::*; pub use migration::*; +use serde::ser::SerializeSeq; +use serde::{de, Deserialize, Deserializer, Serialize, Serializer}; use crate::spec::SpecId; @@ -87,8 +89,45 @@ impl Forks { } } +impl Serialize for Forks { + fn serialize(&self, serializer: S) -> Result + where + S: Serializer, + { + let inner = self.inner(); + let mut seq = serializer.serialize_seq(Some(inner.len()))?; + for fork in inner { + seq.serialize_element(fork)?; + } + seq.end() + } +} + +impl<'de> Deserialize<'de> for Forks { + fn deserialize(deserializer: D) -> Result + where + D: Deserializer<'de>, + { + // Deserialize a vector of forks + let forks_vec: Vec = Vec::deserialize(deserializer)?; + + if forks_vec.len() > 50 { + return Err(de::Error::custom("Too many forks (max 50 allowed)")); + } + + // Initialize the fixed-size array and count + let mut forks = [Fork::new(SpecId::Genesis, 0); 50]; + let count = forks_vec.len(); + + // Copy the deserialized forks into the fixed array + forks[..count].copy_from_slice(&forks_vec); + + Ok(Forks { forks, count }) + } +} + /// Fork is a wrapper struct that contains spec id and it's activation height -#[derive(Debug, Clone, Copy)] +#[derive(Debug, Clone, Copy, Deserialize, Serialize)] pub struct Fork { /// Spec id for this fork pub spec_id: SpecId, diff --git a/crates/sovereign-sdk/rollup-interface/src/fork/tests.rs b/crates/sovereign-sdk/rollup-interface/src/fork/tests.rs index ab6c9fefb..0f2e0aee4 100644 --- a/crates/sovereign-sdk/rollup-interface/src/fork/tests.rs +++ b/crates/sovereign-sdk/rollup-interface/src/fork/tests.rs @@ -1,6 +1,6 @@ use anyhow::anyhow; -use super::{Forks, ForkManager}; +use super::{ForkManager, Forks}; use crate::fork::{fork_from_block_number, Fork, ForkMigration}; use crate::spec::SpecId; @@ -113,7 +113,7 @@ fn test_fork_parse_list() { } fn assert_fork_parse_list(s: &str, exp_list: &[(u8, u64)]) { - let forks = Forks::from_utf8(s).unwrap(); + let forks = Forks::from_utf8(s).unwrap(); let forks = forks.inner(); assert_eq!(forks.len(), exp_list.len()); From 7c2fda03cbf8de4db5ee69bc7328a83e95e629ca Mon Sep 17 00:00:00 2001 From: yaziciahmet Date: Tue, 17 Dec 2024 20:01:14 +0100 Subject: [PATCH 28/96] Implement Forks::from_slice --- .../rollup-interface/src/fork/mod.rs | 25 ++++++++++++++++++- 1 file changed, 24 insertions(+), 1 deletion(-) diff --git a/crates/sovereign-sdk/rollup-interface/src/fork/mod.rs b/crates/sovereign-sdk/rollup-interface/src/fork/mod.rs index db27a8401..4f1d7d833 100644 --- a/crates/sovereign-sdk/rollup-interface/src/fork/mod.rs +++ b/crates/sovereign-sdk/rollup-interface/src/fork/mod.rs @@ -84,6 +84,20 @@ impl Forks { Some(Self { forks, count }) } + pub fn from_slice(slice: &[Fork]) -> Self { + if slice.len() > 50 { + panic!("Never gonna have 50 forks..."); + } + + let mut forks = [Fork::default(); 50]; + forks[0..slice.len()].copy_from_slice(slice); + + Self { + forks, + count: slice.len(), + } + } + pub const fn inner(&self) -> &[Fork] { self.forks.split_at(self.count).0 } @@ -116,7 +130,7 @@ impl<'de> Deserialize<'de> for Forks { } // Initialize the fixed-size array and count - let mut forks = [Fork::new(SpecId::Genesis, 0); 50]; + let mut forks = [Fork::default(); 50]; let count = forks_vec.len(); // Copy the deserialized forks into the fixed array @@ -141,6 +155,15 @@ impl PartialEq for Fork { } } +impl Default for Fork { + fn default() -> Self { + Self { + spec_id: SpecId::Genesis, + activation_height: 0, + } + } +} + impl Fork { /// Creates new Fork instance pub const fn new(spec_id: SpecId, activation_height: u64) -> Self { From 57fcb976d7d312f4012a66d0fad0e14842f8f772 Mon Sep 17 00:00:00 2001 From: yaziciahmet Date: Tue, 17 Dec 2024 20:12:20 +0100 Subject: [PATCH 29/96] Read forks from rollup config --- bin/citrea/tests/test_helpers/mod.rs | 8 ++++- crates/common/src/config.rs | 30 +++++++++++++++++++ .../rollup-interface/src/fork/mod.rs | 4 +++ .../batch_prover_rollup_config.toml | 4 +++ .../light_client_prover_rollup_config.toml | 4 +++ .../bitcoin-regtest/rollup_config.toml | 4 +++ .../sequencer_rollup_config.toml | 4 +++ resources/configs/devnet/rollup_config.toml | 9 ++++++ .../sequencer_rollup_config.toml | 4 +++ resources/configs/mock/rollup_config.toml | 4 +++ .../configs/mock/sequencer_rollup_config.toml | 4 +++ resources/configs/testnet/rollup_config.toml | 9 ++++++ 12 files changed, 87 insertions(+), 1 deletion(-) diff --git a/bin/citrea/tests/test_helpers/mod.rs b/bin/citrea/tests/test_helpers/mod.rs index 97b451c79..5d66c2d77 100644 --- a/bin/citrea/tests/test_helpers/mod.rs +++ b/bin/citrea/tests/test_helpers/mod.rs @@ -13,7 +13,8 @@ use citrea_primitives::TEST_PRIVATE_KEY; use citrea_stf::genesis_config::GenesisPaths; use sov_mock_da::{MockAddress, MockBlock, MockDaConfig, MockDaService}; use sov_modules_api::default_signature::private_key::DefaultPrivateKey; -use sov_modules_api::PrivateKey; +use sov_modules_api::fork::{Fork, Forks}; +use sov_modules_api::{PrivateKey, SpecId}; use sov_modules_rollup_blueprint::{Network, RollupBlueprint as _}; use sov_rollup_interface::da::{BlobReaderTrait, DaData, SequencerCommitment}; use sov_rollup_interface::services::da::{DaService, SlotData}; @@ -185,6 +186,11 @@ pub fn create_default_rollup_config( db_path: da_path.to_path_buf(), }, telemetry: Default::default(), + forks: Forks::from_slice(&[ + Fork::new(SpecId::Genesis, 0), + Fork::new(SpecId::Fork1, 10000), + Fork::new(SpecId::Fork2, 20000), + ]), } } diff --git a/crates/common/src/config.rs b/crates/common/src/config.rs index 3985b02dd..a30ab566d 100644 --- a/crates/common/src/config.rs +++ b/crates/common/src/config.rs @@ -5,6 +5,7 @@ use std::path::{Path, PathBuf}; use citrea_pruning::PruningConfig; use serde::de::DeserializeOwned; use serde::{Deserialize, Serialize}; +use sov_modules_api::fork::Forks; use sov_stf_runner::ProverGuestRunConfig; pub trait FromEnv: Sized { @@ -215,6 +216,8 @@ pub struct FullNodeConfig { /// Telemetry configuration #[serde(default)] pub telemetry: TelemetryConfig, + /// Fork configuration + pub forks: Forks, } impl FromEnv for FullNodeConfig { @@ -226,6 +229,7 @@ impl FromEnv for FullNodeConfig { da: DaC::from_env()?, public_keys: RollupPublicKeys::from_env()?, telemetry: TelemetryConfig::from_env()?, + forks: Forks::from_env()?, }) } } @@ -295,6 +299,13 @@ impl FromEnv for LightClientProverConfig { } } +impl FromEnv for Forks { + fn from_env() -> anyhow::Result { + let forks = std::env::var("FORKS")?; + Ok(Forks::from_utf8(&forks).ok_or(anyhow::anyhow!("Invalid FORKS env variable"))?) + } +} + /// Reads toml file as a specific type. pub fn from_toml_path, R: DeserializeOwned>(path: P) -> anyhow::Result { let mut contents = String::new(); @@ -433,6 +444,8 @@ impl FromEnv for TelemetryConfig { mod tests { use std::io::Write; + use sov_modules_api::fork::Fork; + use sov_modules_api::SpecId; use tempfile::NamedTempFile; use super::*; @@ -474,6 +487,14 @@ mod tests { [telemetry] bind_host = "0.0.0.0" bind_port = 8001 + + [[forks]] + spec_id = "Genesis" + activation_height = 0 + + [[forks]] + spec_id = "Fork1" + activation_height = 1000 "#.to_owned(); let config_file = create_config_from(&config); @@ -515,6 +536,10 @@ mod tests { bind_host: Some("0.0.0.0".to_owned()), bind_port: Some(8001), }, + forks: Forks::from_slice(&[ + Fork::new(SpecId::Genesis, 0), + Fork::new(SpecId::Fork1, 1000), + ]), }; assert_eq!(config, expected); } @@ -671,6 +696,7 @@ mod tests { std::env::set_var("TELEMETRY_BIND_HOST", "0.0.0.0"); std::env::set_var("TELEMETRY_BIND_PORT", "8082"); + std::env::set_var("FORKS", "0:0,1:1000"); let full_node_config: FullNodeConfig = FullNodeConfig::from_env().unwrap(); @@ -708,6 +734,10 @@ mod tests { bind_host: Some("0.0.0.0".to_owned()), bind_port: Some(8082), }, + forks: Forks::from_slice(&[ + Fork::new(SpecId::Genesis, 0), + Fork::new(SpecId::Fork1, 1000), + ]), }; assert_eq!(full_node_config, expected); } diff --git a/crates/sovereign-sdk/rollup-interface/src/fork/mod.rs b/crates/sovereign-sdk/rollup-interface/src/fork/mod.rs index 4f1d7d833..81c794810 100644 --- a/crates/sovereign-sdk/rollup-interface/src/fork/mod.rs +++ b/crates/sovereign-sdk/rollup-interface/src/fork/mod.rs @@ -136,6 +136,10 @@ impl<'de> Deserialize<'de> for Forks { // Copy the deserialized forks into the fixed array forks[..count].copy_from_slice(&forks_vec); + if !verify_forks(&forks, count) { + return Err(de::Error::custom("Forks are not ordered correctly")); + } + Ok(Forks { forks, count }) } } diff --git a/resources/configs/bitcoin-regtest/batch_prover_rollup_config.toml b/resources/configs/bitcoin-regtest/batch_prover_rollup_config.toml index 3fb9b2619..4af3046ec 100644 --- a/resources/configs/bitcoin-regtest/batch_prover_rollup_config.toml +++ b/resources/configs/bitcoin-regtest/batch_prover_rollup_config.toml @@ -28,3 +28,7 @@ enable_subscriptions = false [runner] sequencer_client_url = "http://0.0.0.0:12345" include_tx_body = false + +[[forks]] +spec_id = "Fork1" +activation_height = 0 diff --git a/resources/configs/bitcoin-regtest/light_client_prover_rollup_config.toml b/resources/configs/bitcoin-regtest/light_client_prover_rollup_config.toml index 2844d258a..93a0d7370 100644 --- a/resources/configs/bitcoin-regtest/light_client_prover_rollup_config.toml +++ b/resources/configs/bitcoin-regtest/light_client_prover_rollup_config.toml @@ -27,3 +27,7 @@ enable_subscriptions = false [runner] sequencer_client_url = "http://0.0.0.0:12345" include_tx_body = false + +[[forks]] +spec_id = "Fork1" +activation_height = 0 diff --git a/resources/configs/bitcoin-regtest/rollup_config.toml b/resources/configs/bitcoin-regtest/rollup_config.toml index b5381546c..2a7258831 100644 --- a/resources/configs/bitcoin-regtest/rollup_config.toml +++ b/resources/configs/bitcoin-regtest/rollup_config.toml @@ -28,3 +28,7 @@ max_subscriptions_per_connection = 100 [runner] sequencer_client_url = "http://0.0.0.0:12345" include_tx_body = false + +[[forks]] +spec_id = "Fork1" +activation_height = 0 diff --git a/resources/configs/bitcoin-regtest/sequencer_rollup_config.toml b/resources/configs/bitcoin-regtest/sequencer_rollup_config.toml index d327bf6a9..f31b823d9 100644 --- a/resources/configs/bitcoin-regtest/sequencer_rollup_config.toml +++ b/resources/configs/bitcoin-regtest/sequencer_rollup_config.toml @@ -25,3 +25,7 @@ bind_host = "127.0.0.1" bind_port = 12345 enable_subscriptions = true max_subscriptions_per_connection = 100 + +[[forks]] +spec_id = "Fork1" +activation_height = 0 diff --git a/resources/configs/devnet/rollup_config.toml b/resources/configs/devnet/rollup_config.toml index 59415479f..a31e3fac1 100644 --- a/resources/configs/devnet/rollup_config.toml +++ b/resources/configs/devnet/rollup_config.toml @@ -28,3 +28,12 @@ max_subscriptions_per_connection = 100 sequencer_client_url = "https://rpc.devnet.citrea.xyz" # set this to true if you want to include soft confirmation tx bodies include_tx_body = false + +[[forks]] +spec_id = "Genesis" +activation_height = 0 + +[[forks]] +spec_id = "Fork1" +# TODO: set this properly +activation_height = 999999999 diff --git a/resources/configs/mock-dockerized/sequencer_rollup_config.toml b/resources/configs/mock-dockerized/sequencer_rollup_config.toml index 94762cb30..787992e25 100644 --- a/resources/configs/mock-dockerized/sequencer_rollup_config.toml +++ b/resources/configs/mock-dockerized/sequencer_rollup_config.toml @@ -19,3 +19,7 @@ bind_port = 8545 max_connections = 10000 enable_subscriptions = true max_subscriptions_per_connection = 100 + +[[forks]] +spec_id = "Fork1" +activation_height = 0 diff --git a/resources/configs/mock/rollup_config.toml b/resources/configs/mock/rollup_config.toml index a19c13be2..f979c0ca8 100644 --- a/resources/configs/mock/rollup_config.toml +++ b/resources/configs/mock/rollup_config.toml @@ -23,3 +23,7 @@ max_subscriptions_per_connection = 100 include_tx_body = false sequencer_client_url = "http://0.0.0.0:12345" # pruning_config.distance = 10 + +[[forks]] +spec_id = "Fork1" +activation_height = 0 diff --git a/resources/configs/mock/sequencer_rollup_config.toml b/resources/configs/mock/sequencer_rollup_config.toml index 4f293dcdc..9ff3ff096 100644 --- a/resources/configs/mock/sequencer_rollup_config.toml +++ b/resources/configs/mock/sequencer_rollup_config.toml @@ -19,3 +19,7 @@ bind_port = 12345 max_connections = 10000 enable_subscriptions = true max_subscriptions_per_connection = 100 + +[[forks]] +spec_id = "Fork1" +activation_height = 0 diff --git a/resources/configs/testnet/rollup_config.toml b/resources/configs/testnet/rollup_config.toml index 78000ec18..44cf6fb46 100644 --- a/resources/configs/testnet/rollup_config.toml +++ b/resources/configs/testnet/rollup_config.toml @@ -61,3 +61,12 @@ include_tx_body = false # this value should be at most equal to `batch_requests_limit` set by the RPC node # being used. # sync_blocks_count = 20 + +[[forks]] +spec_id = "Genesis" +activation_height = 0 + +[[forks]] +spec_id = "Fork1" +# TODO: set this properly +activation_height = 999999999 From ed2756fb54db9d84d9cf3dc7553348b1fd91ab4c Mon Sep 17 00:00:00 2001 From: yaziciahmet Date: Tue, 17 Dec 2024 21:27:12 +0100 Subject: [PATCH 30/96] Add lifetime to ForkManager --- crates/batch-prover/src/runner.rs | 4 ++-- crates/fullnode/src/runner.rs | 4 ++-- crates/sequencer/src/runner.rs | 4 ++-- crates/sovereign-sdk/rollup-interface/src/fork/manager.rs | 8 ++++---- 4 files changed, 10 insertions(+), 10 deletions(-) diff --git a/crates/batch-prover/src/runner.rs b/crates/batch-prover/src/runner.rs index fdc965c8b..a8ad4f01e 100644 --- a/crates/batch-prover/src/runner.rs +++ b/crates/batch-prover/src/runner.rs @@ -73,7 +73,7 @@ where elfs_by_spec: HashMap>, l1_block_cache: Arc>>, sync_blocks_count: u64, - fork_manager: ForkManager, + fork_manager: ForkManager<'static>, soft_confirmation_tx: broadcast::Sender, task_manager: TaskManager<()>, } @@ -106,7 +106,7 @@ where prover_config: BatchProverConfig, code_commitments_by_spec: HashMap, elfs_by_spec: HashMap>, - fork_manager: ForkManager, + fork_manager: ForkManager<'static>, soft_confirmation_tx: broadcast::Sender, task_manager: TaskManager<()>, ) -> Result { diff --git a/crates/fullnode/src/runner.rs b/crates/fullnode/src/runner.rs index e41527885..e3d0248f5 100644 --- a/crates/fullnode/src/runner.rs +++ b/crates/fullnode/src/runner.rs @@ -70,7 +70,7 @@ where code_commitments_by_spec: HashMap, l1_block_cache: Arc>>, sync_blocks_count: u64, - fork_manager: ForkManager, + fork_manager: ForkManager<'static>, soft_confirmation_tx: broadcast::Sender, pruning_config: Option, task_manager: TaskManager<()>, @@ -101,7 +101,7 @@ where mut storage_manager: ProverStorageManager, init_variant: InitVariant, Da::Spec>, code_commitments_by_spec: HashMap, - fork_manager: ForkManager, + fork_manager: ForkManager<'static>, soft_confirmation_tx: broadcast::Sender, task_manager: TaskManager<()>, ) -> Result { diff --git a/crates/sequencer/src/runner.rs b/crates/sequencer/src/runner.rs index 3e65442ea..c68f93575 100644 --- a/crates/sequencer/src/runner.rs +++ b/crates/sequencer/src/runner.rs @@ -92,7 +92,7 @@ where sequencer_pub_key: Vec, sequencer_da_pub_key: Vec, rpc_config: RpcConfig, - fork_manager: ForkManager, + fork_manager: ForkManager<'static>, soft_confirmation_tx: broadcast::Sender, task_manager: TaskManager<()>, } @@ -120,7 +120,7 @@ where public_keys: RollupPublicKeys, ledger_db: DB, rpc_config: RpcConfig, - fork_manager: ForkManager, + fork_manager: ForkManager<'static>, soft_confirmation_tx: broadcast::Sender, task_manager: TaskManager<()>, ) -> anyhow::Result { diff --git a/crates/sovereign-sdk/rollup-interface/src/fork/manager.rs b/crates/sovereign-sdk/rollup-interface/src/fork/manager.rs index 505645d7e..d6a0d3e38 100644 --- a/crates/sovereign-sdk/rollup-interface/src/fork/manager.rs +++ b/crates/sovereign-sdk/rollup-interface/src/fork/manager.rs @@ -4,14 +4,14 @@ use alloc::vec::Vec; use super::{Fork, ForkMigration}; -pub struct ForkManager { - forks: &'static [Fork], +pub struct ForkManager<'a> { + forks: &'a [Fork], active_fork_idx: usize, migration_handlers: Vec>, } -impl ForkManager { - pub fn new(forks: &'static [Fork], current_l2_height: u64) -> Self { +impl<'a> ForkManager<'a> { + pub fn new(forks: &'a [Fork], current_l2_height: u64) -> Self { // FORKS from citrea-primitives are checked at compile time to be sorted. let pos = forks.binary_search_by(|fork| fork.activation_height.cmp(¤t_l2_height)); From 84e0433ccca44264ae7a7160f97a2f2a7686d0e5 Mon Sep 17 00:00:00 2001 From: yaziciahmet Date: Tue, 17 Dec 2024 21:41:00 +0100 Subject: [PATCH 31/96] Separate fork_pos_from_block_number method as a helper --- .../rollup-interface/src/fork/manager.rs | 15 ++------------- .../rollup-interface/src/fork/mod.rs | 19 ++++++++++++++++++- .../rollup-interface/src/fork/tests.rs | 12 ++++++------ 3 files changed, 26 insertions(+), 20 deletions(-) diff --git a/crates/sovereign-sdk/rollup-interface/src/fork/manager.rs b/crates/sovereign-sdk/rollup-interface/src/fork/manager.rs index d6a0d3e38..3845ea9ff 100644 --- a/crates/sovereign-sdk/rollup-interface/src/fork/manager.rs +++ b/crates/sovereign-sdk/rollup-interface/src/fork/manager.rs @@ -2,7 +2,7 @@ use alloc::boxed::Box; use alloc::vec; use alloc::vec::Vec; -use super::{Fork, ForkMigration}; +use super::{fork_pos_from_block_number, Fork, ForkMigration}; pub struct ForkManager<'a> { forks: &'a [Fork], @@ -13,12 +13,7 @@ pub struct ForkManager<'a> { impl<'a> ForkManager<'a> { pub fn new(forks: &'a [Fork], current_l2_height: u64) -> Self { // FORKS from citrea-primitives are checked at compile time to be sorted. - - let pos = forks.binary_search_by(|fork| fork.activation_height.cmp(¤t_l2_height)); - let active_fork_idx = match pos { - Ok(idx) => idx, - Err(idx) => idx.saturating_sub(1), - }; + let active_fork_idx = fork_pos_from_block_number(forks, current_l2_height); Self { forks, @@ -63,9 +58,3 @@ impl<'a> ForkManager<'a> { Ok(()) } } - -/// Simple search for the fork to which a specific block number blongs. -/// This assumes that the list of forks is sorted by block number in ascending fashion. -pub fn fork_from_block_number(forks: &'static [Fork], block_number: u64) -> Fork { - ForkManager::new(forks, block_number).active_fork() -} diff --git a/crates/sovereign-sdk/rollup-interface/src/fork/mod.rs b/crates/sovereign-sdk/rollup-interface/src/fork/mod.rs index 81c794810..b1df21025 100644 --- a/crates/sovereign-sdk/rollup-interface/src/fork/mod.rs +++ b/crates/sovereign-sdk/rollup-interface/src/fork/mod.rs @@ -101,6 +101,12 @@ impl Forks { pub const fn inner(&self) -> &[Fork] { self.forks.split_at(self.count).0 } + + pub fn fork_from_block_number(&self, block_number: u64) -> Fork { + let inner = self.inner(); + let pos = fork_pos_from_block_number(inner, block_number); + inner[pos] + } } impl Serialize for Forks { @@ -292,7 +298,7 @@ impl Fork { /// Verifies the order of forks. `size` is needed here due to being in const environment, /// size of the fork might not be known beforehand. -pub const fn verify_forks(forks: &[Fork], size: usize) -> bool { +pub(crate) const fn verify_forks(forks: &[Fork], size: usize) -> bool { let mut i = 0; while i < size { let fork = forks[i]; @@ -315,3 +321,14 @@ pub const fn verify_forks(forks: &[Fork], size: usize) -> bool { true } + +/// Simple search for the fork to which a specific block number belongs. +/// This assumes that the list of forks is sorted by block number in ascending fashion. +pub(crate) fn fork_pos_from_block_number(forks: &[Fork], block_number: u64) -> usize { + let pos = forks.binary_search_by(|fork| fork.activation_height.cmp(&block_number)); + let active_fork_idx = match pos { + Ok(idx) => idx, + Err(idx) => idx.saturating_sub(1), + }; + active_fork_idx +} diff --git a/crates/sovereign-sdk/rollup-interface/src/fork/tests.rs b/crates/sovereign-sdk/rollup-interface/src/fork/tests.rs index 0f2e0aee4..b9420687e 100644 --- a/crates/sovereign-sdk/rollup-interface/src/fork/tests.rs +++ b/crates/sovereign-sdk/rollup-interface/src/fork/tests.rs @@ -1,21 +1,21 @@ use anyhow::anyhow; use super::{ForkManager, Forks}; -use crate::fork::{fork_from_block_number, Fork, ForkMigration}; +use crate::fork::{fork_pos_from_block_number, Fork, ForkMigration}; use crate::spec::SpecId; #[test] -fn test_fork_from_block_number() { +fn test_fork_pos_from_block_number() { static T_FORKS: &[Fork] = &[ Fork::new(SpecId::Genesis, 0), Fork::new(SpecId::Fork1, 100), Fork::new(SpecId::Fork2, 500), ]; - assert_eq!(fork_from_block_number(T_FORKS, 5).spec_id, SpecId::Genesis); - assert_eq!(fork_from_block_number(T_FORKS, 105).spec_id, SpecId::Fork1); - assert_eq!(fork_from_block_number(T_FORKS, 350).spec_id, SpecId::Fork1); - assert_eq!(fork_from_block_number(T_FORKS, 505).spec_id, SpecId::Fork2); + assert_eq!(fork_pos_from_block_number(T_FORKS, 5), 0); + assert_eq!(fork_pos_from_block_number(T_FORKS, 105), 1); + assert_eq!(fork_pos_from_block_number(T_FORKS, 350), 1); + assert_eq!(fork_pos_from_block_number(T_FORKS, 505), 2); } #[test] From 8d73c8ec2740ff10b2e8b658949f9f4d743e2dff Mon Sep 17 00:00:00 2001 From: yaziciahmet Date: Tue, 17 Dec 2024 22:04:36 +0100 Subject: [PATCH 32/96] Improve verify_forks method --- .../rollup-interface/src/fork/manager.rs | 6 +++-- .../rollup-interface/src/fork/mod.rs | 24 +++++++++++-------- 2 files changed, 18 insertions(+), 12 deletions(-) diff --git a/crates/sovereign-sdk/rollup-interface/src/fork/manager.rs b/crates/sovereign-sdk/rollup-interface/src/fork/manager.rs index 3845ea9ff..d6f34601b 100644 --- a/crates/sovereign-sdk/rollup-interface/src/fork/manager.rs +++ b/crates/sovereign-sdk/rollup-interface/src/fork/manager.rs @@ -2,7 +2,7 @@ use alloc::boxed::Box; use alloc::vec; use alloc::vec::Vec; -use super::{fork_pos_from_block_number, Fork, ForkMigration}; +use super::{fork_pos_from_block_number, verify_forks, Fork, ForkMigration}; pub struct ForkManager<'a> { forks: &'a [Fork], @@ -11,8 +11,10 @@ pub struct ForkManager<'a> { } impl<'a> ForkManager<'a> { + /// Creates new `ForkManager`. Forks are expected to be in ascending order, if not, panics in debug mode. pub fn new(forks: &'a [Fork], current_l2_height: u64) -> Self { - // FORKS from citrea-primitives are checked at compile time to be sorted. + debug_assert!(verify_forks(forks), "Forks must be ordered correctly"); + let active_fork_idx = fork_pos_from_block_number(forks, current_l2_height); Self { diff --git a/crates/sovereign-sdk/rollup-interface/src/fork/mod.rs b/crates/sovereign-sdk/rollup-interface/src/fork/mod.rs index b1df21025..9859a409e 100644 --- a/crates/sovereign-sdk/rollup-interface/src/fork/mod.rs +++ b/crates/sovereign-sdk/rollup-interface/src/fork/mod.rs @@ -77,25 +77,29 @@ impl Forks { forks[count] = fork; count += 1; - if !verify_forks(&forks, count) { + if !verify_forks(forks.split_at(count).0) { return None; } Some(Self { forks, count }) } - pub fn from_slice(slice: &[Fork]) -> Self { + pub fn from_slice(slice: &[Fork]) -> Option { if slice.len() > 50 { panic!("Never gonna have 50 forks..."); } + if !verify_forks(slice) { + return None; + } + let mut forks = [Fork::default(); 50]; forks[0..slice.len()].copy_from_slice(slice); - Self { + Some(Self { forks, count: slice.len(), - } + }) } pub const fn inner(&self) -> &[Fork] { @@ -135,6 +139,10 @@ impl<'de> Deserialize<'de> for Forks { return Err(de::Error::custom("Too many forks (max 50 allowed)")); } + if !verify_forks(&forks_vec) { + return Err(de::Error::custom("Forks are not ordered correctly")); + } + // Initialize the fixed-size array and count let mut forks = [Fork::default(); 50]; let count = forks_vec.len(); @@ -142,10 +150,6 @@ impl<'de> Deserialize<'de> for Forks { // Copy the deserialized forks into the fixed array forks[..count].copy_from_slice(&forks_vec); - if !verify_forks(&forks, count) { - return Err(de::Error::custom("Forks are not ordered correctly")); - } - Ok(Forks { forks, count }) } } @@ -298,9 +302,9 @@ impl Fork { /// Verifies the order of forks. `size` is needed here due to being in const environment, /// size of the fork might not be known beforehand. -pub(crate) const fn verify_forks(forks: &[Fork], size: usize) -> bool { +pub(crate) const fn verify_forks(forks: &[Fork]) -> bool { let mut i = 0; - while i < size { + while i < forks.len() { let fork = forks[i]; if i == 0 { // Ensure that the first fork starts from height 0 From ff3c60c0bc0308dbb1016c9ebfe515e59d5f9a63 Mon Sep 17 00:00:00 2001 From: yaziciahmet Date: Tue, 17 Dec 2024 22:44:27 +0100 Subject: [PATCH 33/96] Make FORKS OnceLock static global --- bin/citrea/src/rollup/mod.rs | 22 ++++- bin/citrea/tests/e2e/mod.rs | 5 +- bin/citrea/tests/test_helpers/mod.rs | 3 +- crates/batch-prover/src/da_block_handler.rs | 7 +- crates/batch-prover/src/proving.rs | 8 +- crates/common/src/config.rs | 6 +- crates/evm/src/evm/conversions.rs | 5 +- crates/evm/src/query.rs | 16 ++-- crates/fullnode/src/da_block_handler.rs | 6 +- .../src/da_block_handler.rs | 7 +- crates/primitives/src/forks.rs | 91 ++++++++++--------- .../sov-modules-stf-blueprint/src/lib.rs | 5 +- 12 files changed, 95 insertions(+), 86 deletions(-) diff --git a/bin/citrea/src/rollup/mod.rs b/bin/citrea/src/rollup/mod.rs index e67bf7395..9c3c8c60c 100644 --- a/bin/citrea/src/rollup/mod.rs +++ b/bin/citrea/src/rollup/mod.rs @@ -7,7 +7,7 @@ use citrea_common::tasks::manager::TaskManager; use citrea_common::{BatchProverConfig, FullNodeConfig, LightClientProverConfig, SequencerConfig}; use citrea_fullnode::CitreaFullnode; use citrea_light_client_prover::runner::{CitreaLightClientProver, LightClientProver}; -use citrea_primitives::forks::FORKS; +use citrea_primitives::forks::{get_forks, set_forks}; use citrea_sequencer::CitreaSequencer; use jsonrpsee::RpcModule; use sov_db::ledger_db::migrations::LedgerDBMigrator; @@ -51,6 +51,9 @@ pub trait CitreaRollupBlueprint: RollupBlueprint { where ::Storage: NativeStorage, { + // Set forks before anything + set_forks(rollup_config.forks.clone()); + let mut task_manager = TaskManager::default(); let da_service = self .create_da_service(&rollup_config, true, &mut task_manager) @@ -125,7 +128,7 @@ pub trait CitreaRollupBlueprint: RollupBlueprint { .map(|(l2_height, _)| l2_height) .unwrap_or(BatchNumber(0)); - let mut fork_manager = ForkManager::new(FORKS, current_l2_height.0); + let mut fork_manager = ForkManager::new(get_forks().inner(), current_l2_height.0); fork_manager.register_handler(Box::new(ledger_db.clone())); let seq = CitreaSequencer::new( @@ -172,6 +175,9 @@ pub trait CitreaRollupBlueprint: RollupBlueprint { where ::Storage: NativeStorage, { + // Set forks before anything + set_forks(rollup_config.forks.clone()); + let mut task_manager = TaskManager::default(); let da_service = self .create_da_service(&rollup_config, false, &mut task_manager) @@ -256,7 +262,7 @@ pub trait CitreaRollupBlueprint: RollupBlueprint { .map(|(l2_height, _)| l2_height) .unwrap_or(BatchNumber(0)); - let mut fork_manager = ForkManager::new(FORKS, current_l2_height.0); + let mut fork_manager = ForkManager::new(get_forks().inner(), current_l2_height.0); fork_manager.register_handler(Box::new(ledger_db.clone())); let runner = CitreaFullnode::new( @@ -304,6 +310,9 @@ pub trait CitreaRollupBlueprint: RollupBlueprint { where ::Storage: NativeStorage, { + // Set forks before anything + set_forks(rollup_config.forks.clone()); + let mut task_manager = TaskManager::default(); let da_service = self .create_da_service(&rollup_config, true, &mut task_manager) @@ -394,7 +403,7 @@ pub trait CitreaRollupBlueprint: RollupBlueprint { .map(|(l2_height, _)| l2_height) .unwrap_or(BatchNumber(0)); - let mut fork_manager = ForkManager::new(FORKS, current_l2_height.0); + let mut fork_manager = ForkManager::new(get_forks().inner(), current_l2_height.0); fork_manager.register_handler(Box::new(ledger_db.clone())); let runner = CitreaBatchProver::new( @@ -428,6 +437,9 @@ pub trait CitreaRollupBlueprint: RollupBlueprint { where ::Storage: NativeStorage, { + // Set forks before anything + set_forks(rollup_config.forks.clone()); + // Migrate before constructing ledger_db instance so that no lock is present. let migrator = LedgerDBMigrator::new( rollup_config.storage.path.as_path(), @@ -484,7 +496,7 @@ pub trait CitreaRollupBlueprint: RollupBlueprint { .map(|(l2_height, _)| l2_height) .unwrap_or(BatchNumber(0)); - let mut fork_manager = ForkManager::new(FORKS, current_l2_height.0); + let mut fork_manager = ForkManager::new(get_forks().inner(), current_l2_height.0); fork_manager.register_handler(Box::new(ledger_db.clone())); let runner = CitreaLightClientProver::new( diff --git a/bin/citrea/tests/e2e/mod.rs b/bin/citrea/tests/e2e/mod.rs index c52251058..3a4b05de6 100644 --- a/bin/citrea/tests/e2e/mod.rs +++ b/bin/citrea/tests/e2e/mod.rs @@ -12,11 +12,10 @@ use std::time::Duration; use citrea_common::{BatchProverConfig, SequencerConfig}; use citrea_evm::smart_contracts::SimpleStorageContract; -use citrea_primitives::forks::FORKS; +use citrea_primitives::forks::fork_from_block_number; use citrea_stf::genesis_config::GenesisPaths; use reth_primitives::{Address, BlockNumberOrTag, U256}; use sov_mock_da::{MockAddress, MockDaService}; -use sov_modules_api::fork::fork_from_block_number; use sov_rollup_interface::rpc::{LastVerifiedBatchProofResponse, SoftConfirmationStatus}; use sov_rollup_interface::services::da::DaService; use sov_rollup_interface::spec::SpecId; @@ -653,7 +652,7 @@ async fn test_offchain_contract_storage() { wait_for_l2_block(&sequencer_client, 10000, Some(Duration::from_secs(300))).await; let seq_height = sequencer_client.eth_block_number().await; - let seq_fork = fork_from_block_number(FORKS, seq_height); + let seq_fork = fork_from_block_number(seq_height); // Assert we are at fork1 assert_eq!(seq_fork.spec_id, SpecId::Fork1); diff --git a/bin/citrea/tests/test_helpers/mod.rs b/bin/citrea/tests/test_helpers/mod.rs index 5d66c2d77..a1f881f17 100644 --- a/bin/citrea/tests/test_helpers/mod.rs +++ b/bin/citrea/tests/test_helpers/mod.rs @@ -190,7 +190,8 @@ pub fn create_default_rollup_config( Fork::new(SpecId::Genesis, 0), Fork::new(SpecId::Fork1, 10000), Fork::new(SpecId::Fork2, 20000), - ]), + ]) + .unwrap(), } } diff --git a/crates/batch-prover/src/da_block_handler.rs b/crates/batch-prover/src/da_block_handler.rs index 047e3a8e4..7ce464588 100644 --- a/crates/batch-prover/src/da_block_handler.rs +++ b/crates/batch-prover/src/da_block_handler.rs @@ -11,14 +11,13 @@ use citrea_common::da::get_da_block_at_height; use citrea_common::utils::merge_state_diffs; use citrea_common::BatchProverConfig; use citrea_primitives::compression::compress_blob; -use citrea_primitives::forks::FORKS; +use citrea_primitives::forks::fork_from_block_number; use citrea_primitives::MAX_TXBODY_SIZE; use rand::Rng; use serde::de::DeserializeOwned; use serde::Serialize; use sov_db::ledger_db::BatchProverLedgerOps; use sov_db::schema::types::{BatchNumber, SlotNumber}; -use sov_modules_api::fork::fork_from_block_number; use sov_modules_api::{DaSpec, StateDiff, Zkvm}; use sov_rollup_interface::da::{BlockHeaderTrait, SequencerCommitment}; use sov_rollup_interface::services::da::{DaService, SlotData}; @@ -442,7 +441,7 @@ pub(crate) fn break_sequencer_commitments_into_groups( .first() .ok_or(anyhow!("No Sequencer commitments found"))? .l2_start_block_number; - let mut current_spec = fork_from_block_number(FORKS, first_block_number).spec_id; + let mut current_spec = fork_from_block_number(first_block_number).spec_id; let mut range = 0usize..=0usize; let mut cumulative_state_diff = StateDiff::new(); @@ -473,7 +472,7 @@ pub(crate) fn break_sequencer_commitments_into_groups( let state_diff_threshold_reached = compressed_state_diff.len() > MAX_TXBODY_SIZE; let commitment_spec = - fork_from_block_number(FORKS, sequencer_commitment.l2_end_block_number).spec_id; + fork_from_block_number(sequencer_commitment.l2_end_block_number).spec_id; if commitment_spec != current_spec || state_diff_threshold_reached { result_range.push(range); diff --git a/crates/batch-prover/src/proving.rs b/crates/batch-prover/src/proving.rs index dda312fd1..ba0054991 100644 --- a/crates/batch-prover/src/proving.rs +++ b/crates/batch-prover/src/proving.rs @@ -7,14 +7,13 @@ use borsh::{BorshDeserialize, BorshSerialize}; use citrea_common::cache::L1BlockCache; use citrea_common::da::extract_sequencer_commitments; use citrea_common::utils::{check_l2_range_exists, filter_out_proven_commitments}; -use citrea_primitives::forks::FORKS; +use citrea_primitives::forks::fork_from_block_number; use serde::de::DeserializeOwned; use serde::{Deserialize, Serialize}; use sov_db::ledger_db::BatchProverLedgerOps; use sov_db::schema::types::{BatchNumber, StoredBatchProof, StoredBatchProofOutput}; use sov_modules_api::{BatchProofCircuitOutput, BlobReaderTrait, SlotData, SpecId, Zkvm}; use sov_rollup_interface::da::{BlockHeaderTrait, DaNamespace, DaSpec, SequencerCommitment}; -use sov_rollup_interface::fork::fork_from_block_number; use sov_rollup_interface::rpc::SoftConfirmationStatus; use sov_rollup_interface::services::da::DaService; use sov_rollup_interface::zk::{BatchProofCircuitInput, Proof, ZkvmHost}; @@ -245,7 +244,7 @@ where .last() .expect("Should have at least 1 commitment") .l2_end_block_number; - let current_spec = fork_from_block_number(FORKS, last_l2_height).spec_id; + let current_spec = fork_from_block_number(last_l2_height).spec_id; let elf = elfs_by_spec .get(¤t_spec) .expect("Every fork should have an elf attached") @@ -328,8 +327,7 @@ where >(&proof) .expect("Proof should be deserializable"); - let last_active_spec_id = - fork_from_block_number(FORKS, circuit_output.last_l2_height).spec_id; + let last_active_spec_id = fork_from_block_number(circuit_output.last_l2_height).spec_id; let code_commitment = code_commitments_by_spec .get(&last_active_spec_id) diff --git a/crates/common/src/config.rs b/crates/common/src/config.rs index a30ab566d..795862408 100644 --- a/crates/common/src/config.rs +++ b/crates/common/src/config.rs @@ -539,7 +539,8 @@ mod tests { forks: Forks::from_slice(&[ Fork::new(SpecId::Genesis, 0), Fork::new(SpecId::Fork1, 1000), - ]), + ]) + .unwrap(), }; assert_eq!(config, expected); } @@ -737,7 +738,8 @@ mod tests { forks: Forks::from_slice(&[ Fork::new(SpecId::Genesis, 0), Fork::new(SpecId::Fork1, 1000), - ]), + ]) + .unwrap(), }; assert_eq!(full_node_config, expected); } diff --git a/crates/evm/src/evm/conversions.rs b/crates/evm/src/evm/conversions.rs index af7989998..d98fe8053 100644 --- a/crates/evm/src/evm/conversions.rs +++ b/crates/evm/src/evm/conversions.rs @@ -130,9 +130,8 @@ impl From for TransactionSignedEcRecovered { pub(crate) fn sealed_block_to_block_env( sealed_header: &reth_primitives::SealedHeader, ) -> revm::primitives::BlockEnv { - use citrea_primitives::forks::FORKS; + use citrea_primitives::forks::fork_from_block_number; use revm::primitives::BlobExcessGasAndPrice; - use sov_modules_api::fork::fork_from_block_number; use crate::citrea_spec_id_to_evm_spec_id; @@ -148,7 +147,7 @@ pub(crate) fn sealed_block_to_block_env( .excess_blob_gas .or_else(|| { if citrea_spec_id_to_evm_spec_id( - fork_from_block_number(FORKS, sealed_header.number).spec_id, + fork_from_block_number(sealed_header.number).spec_id, ) >= SpecId::CANCUN { Some(0) diff --git a/crates/evm/src/query.rs b/crates/evm/src/query.rs index bb3c3f31a..6da2d0dbc 100644 --- a/crates/evm/src/query.rs +++ b/crates/evm/src/query.rs @@ -6,7 +6,7 @@ use alloy_eips::eip2930::AccessListWithGasUsed; use alloy_primitives::Uint; use alloy_rlp::Encodable; use citrea_primitives::basefee::calculate_next_block_base_fee; -use citrea_primitives::forks::FORKS; +use citrea_primitives::forks::fork_from_block_number; use jsonrpsee::core::RpcResult; use reth_primitives::TxKind::{Call, Create}; use reth_primitives::{ @@ -29,7 +29,6 @@ use revm::{Database, DatabaseCommit}; use revm_inspectors::access_list::AccessListInspector; use revm_inspectors::tracing::{TracingInspector, TracingInspectorConfig}; use serde::{Deserialize, Serialize}; -use sov_modules_api::fork::fork_from_block_number; use sov_modules_api::macros::rpc_gen; use sov_modules_api::prelude::*; use sov_modules_api::WorkingSet; @@ -367,7 +366,7 @@ impl Evm { let block_number = self.block_number_for_id(&block_number, working_set)?; let current_spec = - citrea_spec_id_to_evm_spec_id(fork_from_block_number(FORKS, block_number).spec_id); + citrea_spec_id_to_evm_spec_id(fork_from_block_number(block_number).spec_id); self.set_state_to_end_of_evm_block_by_block_id(block_id, working_set)?; @@ -562,7 +561,7 @@ impl Evm { .get(working_set) .expect("EVM chain config should be set"); - let citrea_spec_id = fork_from_block_number(FORKS, block_num).spec_id; + let citrea_spec_id = fork_from_block_number(block_num).spec_id; let evm_spec_id = citrea_spec_id_to_evm_spec_id(citrea_spec_id); let cfg_env = get_cfg_env(cfg, evm_spec_id); @@ -657,7 +656,7 @@ impl Evm { .get(working_set) .expect("EVM chain config should be set"); - let citrea_spec_id = fork_from_block_number(FORKS, block_num).spec_id; + let citrea_spec_id = fork_from_block_number(block_num).spec_id; let evm_spec_id = citrea_spec_id_to_evm_spec_id(citrea_spec_id); let cfg_env = get_cfg_env(cfg, evm_spec_id); @@ -768,8 +767,7 @@ impl Evm { .get(working_set) .expect("EVM chain config should be set"); - let citrea_spec_id = - fork_from_block_number(FORKS, block_env.number.saturating_to()).spec_id; + let citrea_spec_id = fork_from_block_number(block_env.number.saturating_to()).spec_id; let evm_spec_id = citrea_spec_id_to_evm_spec_id(citrea_spec_id); let cfg_env = get_cfg_env(cfg, evm_spec_id); @@ -1196,7 +1194,7 @@ impl Evm { // set state to end of the previous block set_state_to_end_of_evm_block::(block_number - 1, working_set); - let citrea_spec_id = fork_from_block_number(FORKS, block_number).spec_id; + let citrea_spec_id = fork_from_block_number(block_number).spec_id; let evm_spec_id = citrea_spec_id_to_evm_spec_id(citrea_spec_id); let block_env = sealed_block_to_block_env(&sealed_block.header); @@ -1824,7 +1822,7 @@ fn get_pending_block_env( cfg.base_fee_params, )); block_env.blob_excess_gas_and_price = if citrea_spec_id_to_evm_spec_id( - fork_from_block_number(FORKS, block_env.number.saturating_to()).spec_id, + fork_from_block_number(block_env.number.saturating_to()).spec_id, ) >= SpecId::CANCUN { Some(BlobExcessGasAndPrice::new(0)) diff --git a/crates/fullnode/src/da_block_handler.rs b/crates/fullnode/src/da_block_handler.rs index 02880be85..78ce4a08f 100644 --- a/crates/fullnode/src/da_block_handler.rs +++ b/crates/fullnode/src/da_block_handler.rs @@ -10,7 +10,7 @@ use citrea_common::cache::L1BlockCache; use citrea_common::da::{extract_sequencer_commitments, extract_zk_proofs, get_da_block_at_height}; use citrea_common::error::SyncError; use citrea_common::utils::check_l2_range_exists; -use citrea_primitives::forks::FORKS; +use citrea_primitives::forks::fork_from_block_number; use rs_merkle::algorithms::Sha256; use rs_merkle::MerkleTree; use serde::de::DeserializeOwned; @@ -21,7 +21,6 @@ use sov_db::schema::types::{ }; use sov_modules_api::{Context, Zkvm}; use sov_rollup_interface::da::{BlockHeaderTrait, SequencerCommitment}; -use sov_rollup_interface::fork::fork_from_block_number; use sov_rollup_interface::rpc::SoftConfirmationStatus; use sov_rollup_interface::services::da::{DaService, SlotData}; use sov_rollup_interface::spec::SpecId; @@ -313,8 +312,7 @@ where ).into()); } - let last_active_spec_id = - fork_from_block_number(FORKS, batch_proof_output.last_l2_height).spec_id; + let last_active_spec_id = fork_from_block_number(batch_proof_output.last_l2_height).spec_id; let code_commitment = self .code_commitments_by_spec .get(&last_active_spec_id) diff --git a/crates/light-client-prover/src/da_block_handler.rs b/crates/light-client-prover/src/da_block_handler.rs index 0f6cbf0a1..d2d2c07f8 100644 --- a/crates/light-client-prover/src/da_block_handler.rs +++ b/crates/light-client-prover/src/da_block_handler.rs @@ -6,13 +6,12 @@ use borsh::BorshDeserialize; use citrea_common::cache::L1BlockCache; use citrea_common::da::get_da_block_at_height; use citrea_common::LightClientProverConfig; -use citrea_primitives::forks::FORKS; +use citrea_primitives::forks::fork_from_block_number; use jsonrpsee::http_client::HttpClient; use reth_primitives::U64; use sov_db::ledger_db::{LightClientProverLedgerOps, SharedLedgerOps}; use sov_db::schema::types::{SlotNumber, StoredLightClientProofOutput}; use sov_ledger_rpc::LedgerRpcClient; -use sov_modules_api::fork::fork_from_block_number; use sov_modules_api::{BatchProofCircuitOutput, BlobReaderTrait, DaSpec, Zkvm}; use sov_rollup_interface::da::{BlockHeaderTrait, DaDataLightClient, DaNamespace}; use sov_rollup_interface::services::da::{DaService, SlotData}; @@ -169,7 +168,7 @@ where >(&proof) .map_err(|_| anyhow!("Proof should be deserializable"))?; let last_l2_height = batch_proof_output.last_l2_height; - let current_spec = fork_from_block_number(FORKS, last_l2_height).spec_id; + let current_spec = fork_from_block_number(last_l2_height).spec_id; let batch_proof_method_id = self .batch_proof_code_commitments .get(¤t_spec) @@ -231,7 +230,7 @@ where let l2_last_height = l2_last_height.ok_or(anyhow!( "Could not determine the last L2 height for batch proof" ))?; - let current_fork = fork_from_block_number(FORKS, l2_last_height); + let current_fork = fork_from_block_number(l2_last_height); let batch_proof_method_id = self .batch_proof_code_commitments .get(¤t_fork.spec_id) diff --git a/crates/primitives/src/forks.rs b/crates/primitives/src/forks.rs index 34ea70d00..7c021c174 100644 --- a/crates/primitives/src/forks.rs +++ b/crates/primitives/src/forks.rs @@ -1,49 +1,52 @@ -use sov_rollup_interface::fork::Fork; -use sov_rollup_interface::spec::SpecId; +use std::sync::OnceLock; -/// This defines the list of forks which will be activated -/// at specific heights. -#[cfg(not(feature = "testing"))] -pub const FORKS: &[Fork] = &[ - Fork { - spec_id: SpecId::Genesis, - activation_height: 0, - }, - Fork { - spec_id: SpecId::Fork1, - activation_height: 99999999999, // TODO: change this to the correct height once decided - }, - // Examples of how we can define further forks - // Fork { spec_id: SpecId::Fork2, activation_height: 1000 }, -]; +use sov_rollup_interface::fork::{Fork, Forks}; -#[cfg(feature = "testing")] -pub const FORKS: &[Fork] = &[ - Fork { - spec_id: SpecId::Genesis, - activation_height: 0, - }, - Fork { - spec_id: SpecId::Fork1, - activation_height: 10000, - }, - Fork { - spec_id: SpecId::Fork2, - activation_height: 20000, - }, -]; +static FORKS: OnceLock = OnceLock::new(); -const _CHECK_FORKS_ARE_SORTED: () = { - const fn check_forks_are_sorted() { - let mut height = FORKS[0].activation_height; - let mut i = 1; - while i < FORKS.len() { - let fork = FORKS[i]; - let fork_height = fork.activation_height; - assert!(fork_height > height, "FORKS are not sorted!"); - height = fork_height; - i += 1; +/// Set the forks. Must be called once. +pub fn set_forks(forks: Forks) { + FORKS.set(forks).expect("Forks must be set exactly once"); +} + +/// Get forks. Forks need to be set before calling this method if not in testing environment. +/// In testing environment default forks are used. +pub fn get_forks() -> &'static Forks { + match FORKS.get() { + Some(forks) => forks, + None => { + #[cfg(not(feature = "testing"))] + panic!("Forks must be set before accessing"); + + #[cfg(feature = "testing")] + { + use sov_rollup_interface::spec::SpecId; + + set_forks( + Forks::from_slice(&[ + Fork { + spec_id: SpecId::Genesis, + activation_height: 0, + }, + Fork { + spec_id: SpecId::Fork1, + activation_height: 10000, + }, + Fork { + spec_id: SpecId::Fork2, + activation_height: 20000, + }, + ]) + .expect("Forks are ordered"), + ); + FORKS.get().expect("Just set it") + } } } - check_forks_are_sorted() -}; +} + +/// Get fork from the given block number. Forks must be set before calling this method if not in test environment. +/// In test environment default forks are used. +pub fn fork_from_block_number(block_number: u64) -> Fork { + get_forks().fork_from_block_number(block_number) +} diff --git a/crates/sovereign-sdk/module-system/sov-modules-stf-blueprint/src/lib.rs b/crates/sovereign-sdk/module-system/sov-modules-stf-blueprint/src/lib.rs index 9651e15fa..c10c23bc1 100644 --- a/crates/sovereign-sdk/module-system/sov-modules-stf-blueprint/src/lib.rs +++ b/crates/sovereign-sdk/module-system/sov-modules-stf-blueprint/src/lib.rs @@ -2,7 +2,7 @@ #![doc = include_str!("../README.md")] use borsh::BorshDeserialize; -use citrea_primitives::forks::FORKS; +use citrea_primitives::forks::get_forks; use itertools::Itertools; use rs_merkle::algorithms::Sha256; use rs_merkle::MerkleTree; @@ -508,7 +508,8 @@ where let mut previous_batch_hash = soft_confirmations[0][0].prev_hash(); let mut last_commitment_end_height: Option = None; - let mut fork_manager = ForkManager::new(FORKS, sequencer_commitments_range.0 as u64); + let mut fork_manager = + ForkManager::new(get_forks().inner(), sequencer_commitments_range.0 as u64); // should panic if number of sequencer commitments, soft confirmations, slot headers and witnesses don't match for (((sequencer_commitment, soft_confirmations), da_block_headers), witnesses) in From e841a2a83c3c11a606df729770dad0659b9af5e3 Mon Sep 17 00:00:00 2001 From: yaziciahmet Date: Tue, 17 Dec 2024 23:04:31 +0100 Subject: [PATCH 34/96] Check first byte of da public key in compile time --- .../batch-proof-bitcoin/src/bin/batch_proof_bitcoin.rs | 7 ++++++- guests/risc0/batch-proof-mock/src/bin/batch_proof_mock.rs | 7 ++++++- .../src/bin/light_client_proof_bitcoin.rs | 7 ++++++- .../src/bin/light_client_proof_mock.rs | 7 ++++++- 4 files changed, 24 insertions(+), 4 deletions(-) diff --git a/guests/risc0/batch-proof-bitcoin/src/bin/batch_proof_bitcoin.rs b/guests/risc0/batch-proof-bitcoin/src/bin/batch_proof_bitcoin.rs index b1bfb0820..25225d6db 100644 --- a/guests/risc0/batch-proof-bitcoin/src/bin/batch_proof_bitcoin.rs +++ b/guests/risc0/batch-proof-bitcoin/src/bin/batch_proof_bitcoin.rs @@ -28,7 +28,12 @@ const SEQUENCER_DA_PUBLIC_KEY: [u8; 33] = { match const_hex::const_decode_to_array(hex_pub_key.as_bytes()) { // TODO: maybe verify the first byte? - Ok(pub_key) => pub_key, + Ok(pub_key) => { + if pub_key[0] != 2 && pub_key[0] != 3 { + panic!("SEQUENCER_DA_PUBLIC_KEY first byte must be either 02 or 03"); + } + pub_key + }, Err(_) => panic!("SEQUENCER_DA_PUBLIC_KEY must be valid 33-byte hex string"), } }; diff --git a/guests/risc0/batch-proof-mock/src/bin/batch_proof_mock.rs b/guests/risc0/batch-proof-mock/src/bin/batch_proof_mock.rs index f73560199..c6e4f6f1a 100644 --- a/guests/risc0/batch-proof-mock/src/bin/batch_proof_mock.rs +++ b/guests/risc0/batch-proof-mock/src/bin/batch_proof_mock.rs @@ -25,7 +25,12 @@ const SEQUENCER_DA_PUBLIC_KEY: [u8; 33] = { match const_hex::const_decode_to_array(hex_pub_key.as_bytes()) { // TODO: maybe verify the first byte? - Ok(pub_key) => pub_key, + Ok(pub_key) => { + if pub_key[0] != 2 && pub_key[0] != 3 { + panic!("SEQUENCER_DA_PUBLIC_KEY first byte must be either 02 or 03"); + } + pub_key + } Err(_) => panic!("SEQUENCER_DA_PUBLIC_KEY must be valid 33-byte hex string"), } }; diff --git a/guests/risc0/light-client-proof-bitcoin/src/bin/light_client_proof_bitcoin.rs b/guests/risc0/light-client-proof-bitcoin/src/bin/light_client_proof_bitcoin.rs index b223f0dcf..f9797e49d 100644 --- a/guests/risc0/light-client-proof-bitcoin/src/bin/light_client_proof_bitcoin.rs +++ b/guests/risc0/light-client-proof-bitcoin/src/bin/light_client_proof_bitcoin.rs @@ -31,7 +31,12 @@ const BATCH_PROVER_DA_PUBLIC_KEY: [u8; 33] = { let hex_pub_key = env!("BATCH_PROVER_DA_PUBLIC_KEY"); match const_hex::const_decode_to_array(hex_pub_key.as_bytes()) { - Ok(pub_key) => pub_key, + Ok(pub_key) => { + if pub_key[0] != 2 && pub_key[0] != 3 { + panic!("BATCH_PROVER_DA_PUBLIC_KEY first byte must be either 02 or 03"); + } + pub_key + } Err(_) => panic!("BATCH_PROVER_DA_PUBLIC_KEY must be valid 33-byte hex string"), } }; diff --git a/guests/risc0/light-client-proof-mock/src/bin/light_client_proof_mock.rs b/guests/risc0/light-client-proof-mock/src/bin/light_client_proof_mock.rs index 3671d0845..23a5298c7 100644 --- a/guests/risc0/light-client-proof-mock/src/bin/light_client_proof_mock.rs +++ b/guests/risc0/light-client-proof-mock/src/bin/light_client_proof_mock.rs @@ -28,7 +28,12 @@ const BATCH_PROVER_DA_PUBLIC_KEY: [u8; 33] = { let hex_pub_key = env!("BATCH_PROVER_DA_PUBLIC_KEY"); match const_hex::const_decode_to_array(hex_pub_key.as_bytes()) { - Ok(pub_key) => pub_key, + Ok(pub_key) => { + if pub_key[0] != 2 && pub_key[0] != 3 { + panic!("BATCH_PROVER_DA_PUBLIC_KEY first byte must be either 02 or 03"); + } + pub_key + } Err(_) => panic!("BATCH_PROVER_DA_PUBLIC_KEY must be valid 33-byte hex string"), } }; From d9d9d0a23c544b24bcceed6b8d7330ed1da22ee1 Mon Sep 17 00:00:00 2001 From: yaziciahmet Date: Tue, 17 Dec 2024 23:10:44 +0100 Subject: [PATCH 35/96] Update test_helpers according to nightly --- bin/citrea/tests/test_helpers/mod.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/bin/citrea/tests/test_helpers/mod.rs b/bin/citrea/tests/test_helpers/mod.rs index d46d80cbc..50b83e7d7 100644 --- a/bin/citrea/tests/test_helpers/mod.rs +++ b/bin/citrea/tests/test_helpers/mod.rs @@ -191,8 +191,8 @@ pub fn create_default_rollup_config( telemetry: Default::default(), forks: Forks::from_slice(&[ Fork::new(SpecId::Genesis, 0), - Fork::new(SpecId::Fork1, 10000), - Fork::new(SpecId::Fork2, 20000), + Fork::new(SpecId::Fork1, 1000), + Fork::new(SpecId::Fork2, 2000), ]) .unwrap(), } From e6114d9f83256d6c31ec1f5a0743009225a8428f Mon Sep 17 00:00:00 2001 From: yaziciahmet Date: Tue, 17 Dec 2024 23:21:29 +0100 Subject: [PATCH 36/96] Pass forks as arg --- crates/citrea-stf/src/verifier.rs | 3 +++ crates/prover-services/src/parallel/mod.rs | 3 ++- .../sovereign-sdk/full-node/sov-stf-runner/src/mock/mod.rs | 2 ++ .../module-system/sov-modules-stf-blueprint/src/lib.rs | 6 +++--- .../sovereign-sdk/rollup-interface/src/state_machine/stf.rs | 2 ++ .../batch-proof-bitcoin/src/bin/batch_proof_bitcoin.rs | 2 +- guests/risc0/batch-proof-mock/src/bin/batch_proof_mock.rs | 2 +- 7 files changed, 14 insertions(+), 6 deletions(-) diff --git a/crates/citrea-stf/src/verifier.rs b/crates/citrea-stf/src/verifier.rs index 2d6214776..621d7dad8 100644 --- a/crates/citrea-stf/src/verifier.rs +++ b/crates/citrea-stf/src/verifier.rs @@ -1,3 +1,4 @@ +use sov_modules_api::fork::Fork; use sov_rollup_interface::da::{BlockHeaderTrait, DaNamespace, DaVerifier}; use sov_rollup_interface::stf::{ApplySequencerCommitmentsOutput, StateTransitionFunction}; use sov_rollup_interface::zk::{BatchProofCircuitInput, BatchProofCircuitOutput}; @@ -27,6 +28,7 @@ where &mut self, data: BatchProofCircuitInput, pre_state: Stf::PreState, + forks: &[Fork], ) -> Result, Da::Error> { println!("Running sequencer commitments in DA slot"); @@ -73,6 +75,7 @@ where data.da_block_headers_of_soft_confirmations, data.soft_confirmations, data.preproven_commitments.clone(), + forks, ); println!("out of apply_soft_confirmations_from_sequencer_commitments"); diff --git a/crates/prover-services/src/parallel/mod.rs b/crates/prover-services/src/parallel/mod.rs index 763e797ad..a097a364b 100644 --- a/crates/prover-services/src/parallel/mod.rs +++ b/crates/prover-services/src/parallel/mod.rs @@ -2,6 +2,7 @@ use std::ops::DerefMut; use std::sync::Arc; use async_trait::async_trait; +use citrea_primitives::forks::get_forks; use futures::future; use sov_db::ledger_db::LedgerDB; use sov_rollup_interface::da::DaData; @@ -262,7 +263,7 @@ where let guest = vm.simulate_with_hints(); let data = guest.read_from_host(); verifier - .run_sequencer_commitments_in_da_slot(data, zk_storage) + .run_sequencer_commitments_in_da_slot(data, zk_storage, get_forks().inner()) .map(|_| Vec::default()) .map_err(|e| { anyhow::anyhow!("Guest execution must succeed but failed with {:?}", e) diff --git a/crates/sovereign-sdk/full-node/sov-stf-runner/src/mock/mod.rs b/crates/sovereign-sdk/full-node/sov-stf-runner/src/mock/mod.rs index d1bbc262f..9ca38533f 100644 --- a/crates/sovereign-sdk/full-node/sov-stf-runner/src/mock/mod.rs +++ b/crates/sovereign-sdk/full-node/sov-stf-runner/src/mock/mod.rs @@ -1,4 +1,5 @@ use sov_modules_api::default_context::DefaultContext; +use sov_modules_api::fork::Fork; use sov_modules_api::transaction::Transaction; use sov_rollup_interface::da::DaSpec; use sov_rollup_interface::spec::SpecId; @@ -61,6 +62,7 @@ impl StateTransitionFunction for MockStf { Vec>, >, _preproven_commitment_indicies: Vec, + _forks: &[Fork], ) -> ApplySequencerCommitmentsOutput { todo!() } diff --git a/crates/sovereign-sdk/module-system/sov-modules-stf-blueprint/src/lib.rs b/crates/sovereign-sdk/module-system/sov-modules-stf-blueprint/src/lib.rs index c10c23bc1..e1732b06b 100644 --- a/crates/sovereign-sdk/module-system/sov-modules-stf-blueprint/src/lib.rs +++ b/crates/sovereign-sdk/module-system/sov-modules-stf-blueprint/src/lib.rs @@ -2,11 +2,11 @@ #![doc = include_str!("../README.md")] use borsh::BorshDeserialize; -use citrea_primitives::forks::get_forks; use itertools::Itertools; use rs_merkle::algorithms::Sha256; use rs_merkle::MerkleTree; use sov_modules_api::da::BlockHeaderTrait; +use sov_modules_api::fork::Fork; use sov_modules_api::hooks::{ ApplySoftConfirmationHooks, FinalizeHook, HookSoftConfirmationInfo, SlotHooks, TxHooks, }; @@ -438,6 +438,7 @@ where Vec>, >, preproven_commitment_indices: Vec, + forks: &[Fork], ) -> ApplySequencerCommitmentsOutput { let mut state_diff = CumulativeStateDiff::default(); @@ -508,8 +509,7 @@ where let mut previous_batch_hash = soft_confirmations[0][0].prev_hash(); let mut last_commitment_end_height: Option = None; - let mut fork_manager = - ForkManager::new(get_forks().inner(), sequencer_commitments_range.0 as u64); + let mut fork_manager = ForkManager::new(forks, sequencer_commitments_range.0 as u64); // should panic if number of sequencer commitments, soft confirmations, slot headers and witnesses don't match for (((sequencer_commitment, soft_confirmations), da_block_headers), witnesses) in diff --git a/crates/sovereign-sdk/rollup-interface/src/state_machine/stf.rs b/crates/sovereign-sdk/rollup-interface/src/state_machine/stf.rs index da4d54ac3..8c8f69507 100644 --- a/crates/sovereign-sdk/rollup-interface/src/state_machine/stf.rs +++ b/crates/sovereign-sdk/rollup-interface/src/state_machine/stf.rs @@ -16,6 +16,7 @@ use serde::de::DeserializeOwned; use serde::{Deserialize, Serialize}; use crate::da::DaSpec; +use crate::fork::Fork; use crate::soft_confirmation::SignedSoftConfirmation; use crate::spec::SpecId; use crate::zk::CumulativeStateDiff; @@ -229,6 +230,7 @@ pub trait StateTransitionFunction { slot_headers: VecDeque>, soft_confirmations: VecDeque>>, preproven_commitment_indicies: Vec, + forks: &[Fork], ) -> ApplySequencerCommitmentsOutput; } diff --git a/guests/risc0/batch-proof-bitcoin/src/bin/batch_proof_bitcoin.rs b/guests/risc0/batch-proof-bitcoin/src/bin/batch_proof_bitcoin.rs index 25225d6db..5906bd7ce 100644 --- a/guests/risc0/batch-proof-bitcoin/src/bin/batch_proof_bitcoin.rs +++ b/guests/risc0/batch-proof-bitcoin/src/bin/batch_proof_bitcoin.rs @@ -70,7 +70,7 @@ pub fn main() { let data = guest.read_from_host(); let out = stf_verifier - .run_sequencer_commitments_in_da_slot(data, storage) + .run_sequencer_commitments_in_da_slot(data, storage, FORKS) .expect("Prover must be honest"); guest.commit(&out); diff --git a/guests/risc0/batch-proof-mock/src/bin/batch_proof_mock.rs b/guests/risc0/batch-proof-mock/src/bin/batch_proof_mock.rs index c6e4f6f1a..77e8b372c 100644 --- a/guests/risc0/batch-proof-mock/src/bin/batch_proof_mock.rs +++ b/guests/risc0/batch-proof-mock/src/bin/batch_proof_mock.rs @@ -64,7 +64,7 @@ pub fn main() { let data = guest.read_from_host(); let out = stf_verifier - .run_sequencer_commitments_in_da_slot(data, storage) + .run_sequencer_commitments_in_da_slot(data, storage, FORKS) .expect("Prover must be honest"); guest.commit(&out); From aec43788bfdfb5c9b761405a672a15e8a97395c6 Mon Sep 17 00:00:00 2001 From: yaziciahmet Date: Wed, 18 Dec 2024 08:15:19 +0100 Subject: [PATCH 37/96] Have single SpecId --- .../rollup-interface/src/spec.rs | 127 ++++++------------ 1 file changed, 43 insertions(+), 84 deletions(-) diff --git a/crates/sovereign-sdk/rollup-interface/src/spec.rs b/crates/sovereign-sdk/rollup-interface/src/spec.rs index f984c990c..bf303ed88 100644 --- a/crates/sovereign-sdk/rollup-interface/src/spec.rs +++ b/crates/sovereign-sdk/rollup-interface/src/spec.rs @@ -3,93 +3,52 @@ use core::hash::Hash; use borsh::{BorshDeserialize, BorshSerialize}; use serde::{Deserialize, Serialize}; -pub use spec::*; -#[cfg(not(feature = "testing"))] -mod spec { - use super::*; - /// Fork specification - #[derive( - Debug, - Clone, - Copy, - Eq, - PartialEq, - PartialOrd, - Default, - BorshDeserialize, - BorshSerialize, - Serialize, - Deserialize, - Hash, - )] - #[borsh(use_discriminant = true)] - pub enum SpecId { - /// Genesis spec - #[default] - Genesis = 0, - /// First fork activates: - /// 1. the light client proof - /// 2. EVM cancun upgrade (with no kzg precompile) - /// 3. Don't use borsh when signing SoftConfirmation's - Fork1 = 1, - } - - impl SpecId { - /// Const fn to convert u8 to corresponding SpecId. Valid values are - /// 0 and 1. Panics otherwise. - pub const fn from_u8(n: u8) -> Option { - match n { - 0 => Some(SpecId::Genesis), - 1 => Some(SpecId::Fork1), - _ => None, - } - } - } +/// Currently available Citrea fork specs. +#[derive( + Debug, + Clone, + Copy, + Eq, + PartialEq, + PartialOrd, + Default, + BorshDeserialize, + BorshSerialize, + Serialize, + Deserialize, + Hash, +)] +#[borsh(use_discriminant = true)] +pub enum SpecId { + /// Genesis spec + #[default] + Genesis = 0, + /// First fork activates: + /// 1. the light client proof + /// 2. EVM cancun upgrade (with no kzg precompile) + /// 3. Don't use borsh when signing SoftConfirmation's + Fork1 = 1, + /// Fork2 spec + #[cfg(feature = "testing")] + Fork2 = 2, + /// Fork3 spec + #[cfg(feature = "testing")] + Fork3 = 3, } -#[cfg(feature = "testing")] -mod spec { - use super::*; - /// Fork specification - #[derive( - Debug, - Clone, - Copy, - Eq, - PartialEq, - PartialOrd, - Default, - BorshDeserialize, - BorshSerialize, - Serialize, - Deserialize, - Hash, - )] - #[borsh(use_discriminant = true)] - pub enum SpecId { - /// Genesis spec - #[default] - Genesis = 0, - /// First fork - Fork1 = 1, - /// Second fork - Fork2 = 2, - /// Third fork - Fork3 = 3, - } - - impl SpecId { - /// Const fn to convert u8 to corresponding SpecId. Valid values are - /// 0, 1, 2 and 3. - pub const fn from_u8(n: u8) -> Option { - match n { - 0 => Some(SpecId::Genesis), - 1 => Some(SpecId::Fork1), - 2 => Some(SpecId::Fork2), - 3 => Some(SpecId::Fork3), - _ => None, - } +impl SpecId { + /// Const fn to convert u8 to corresponding SpecId. Valid values are + /// 0, 1, 2 and 3. + pub const fn from_u8(n: u8) -> Option { + match n { + 0 => Some(SpecId::Genesis), + 1 => Some(SpecId::Fork1), + #[cfg(feature = "testing")] + 2 => Some(SpecId::Fork2), + #[cfg(feature = "testing")] + 3 => Some(SpecId::Fork3), + _ => None, } } } From 1fb4c64b372eda4124b38242feca3b122f44a75d Mon Sep 17 00:00:00 2001 From: yaziciahmet Date: Wed, 18 Dec 2024 10:20:45 +0100 Subject: [PATCH 38/96] Take sequencer pub keys as arg to batch proof circuit --- bin/citrea/src/rollup/bitcoin.rs | 5 ++- bin/citrea/src/rollup/mock.rs | 16 +++++++-- bin/citrea/src/rollup/mod.rs | 2 ++ crates/batch-prover/tests/prover_tests.rs | 2 ++ crates/citrea-stf/src/verifier.rs | 6 ++-- crates/prover-services/src/parallel/mod.rs | 33 +++++++++++++++++-- .../sov-modules-rollup-blueprint/src/lib.rs | 3 +- .../src/bin/batch_proof_bitcoin.rs | 2 +- .../src/bin/batch_proof_mock.rs | 2 +- 9 files changed, 59 insertions(+), 12 deletions(-) diff --git a/bin/citrea/src/rollup/bitcoin.rs b/bin/citrea/src/rollup/bitcoin.rs index a00aa3e76..a438c3f29 100644 --- a/bin/citrea/src/rollup/bitcoin.rs +++ b/bin/citrea/src/rollup/bitcoin.rs @@ -8,7 +8,7 @@ use bitcoin_da::spec::{BitcoinSpec, RollupParams}; use bitcoin_da::verifier::BitcoinVerifier; use citrea_common::rpc::register_healthcheck_rpc; use citrea_common::tasks::manager::TaskManager; -use citrea_common::FullNodeConfig; +use citrea_common::{FullNodeConfig, RollupPublicKeys}; use citrea_primitives::{TO_BATCH_PROOF_PREFIX, TO_LIGHT_CLIENT_PREFIX}; use citrea_risc0_adapter::host::Risc0BonsaiHost; // use citrea_sp1::host::SP1Host; @@ -261,6 +261,7 @@ impl RollupBlueprint for BitcoinRollup { da_service: &Arc, da_verifier: Self::DaVerifier, ledger_db: LedgerDB, + keys: RollupPublicKeys, ) -> Self::ProverService { let vm = Risc0BonsaiHost::new(ledger_db.clone()); // let vm = SP1Host::new( @@ -287,6 +288,8 @@ impl RollupBlueprint for BitcoinRollup { proof_mode, zk_storage, ledger_db, + keys.sequencer_public_key.clone(), + keys.sequencer_da_pub_key, ) .expect("Should be able to instantiate prover service") } diff --git a/bin/citrea/src/rollup/mock.rs b/bin/citrea/src/rollup/mock.rs index cc6c41367..727673ad8 100644 --- a/bin/citrea/src/rollup/mock.rs +++ b/bin/citrea/src/rollup/mock.rs @@ -4,7 +4,7 @@ use std::sync::Arc; use async_trait::async_trait; use citrea_common::rpc::register_healthcheck_rpc; use citrea_common::tasks::manager::TaskManager; -use citrea_common::FullNodeConfig; +use citrea_common::{FullNodeConfig, RollupPublicKeys}; // use citrea_sp1::host::SP1Host; use citrea_risc0_adapter::host::Risc0BonsaiHost; use citrea_stf::genesis_config::StorageConfig; @@ -138,6 +138,7 @@ impl RollupBlueprint for MockDemoRollup { da_service: &Arc, da_verifier: Self::DaVerifier, ledger_db: LedgerDB, + keys: RollupPublicKeys, ) -> Self::ProverService { let vm = Risc0BonsaiHost::new(ledger_db.clone()); @@ -154,8 +155,17 @@ impl RollupBlueprint for MockDemoRollup { ProverGuestRunConfig::Prove => ProofGenMode::Prove, }; - ParallelProverService::new(da_service.clone(), vm, proof_mode, zk_storage, 1, ledger_db) - .expect("Should be able to instantiate prover service") + ParallelProverService::new( + da_service.clone(), + vm, + proof_mode, + zk_storage, + 1, + ledger_db, + keys.sequencer_public_key.clone(), + keys.sequencer_da_pub_key, + ) + .expect("Should be able to instantiate prover service") } fn create_storage_manager( diff --git a/bin/citrea/src/rollup/mod.rs b/bin/citrea/src/rollup/mod.rs index 4de78947e..255c88e86 100644 --- a/bin/citrea/src/rollup/mod.rs +++ b/bin/citrea/src/rollup/mod.rs @@ -340,6 +340,7 @@ pub trait CitreaRollupBlueprint: RollupBlueprint { &da_service, da_verifier, ledger_db.clone(), + rollup_config.public_keys.clone(), ) .await; @@ -472,6 +473,7 @@ pub trait CitreaRollupBlueprint: RollupBlueprint { &da_service, da_verifier, ledger_db.clone(), + rollup_config.public_keys.clone(), ) .await; diff --git a/crates/batch-prover/tests/prover_tests.rs b/crates/batch-prover/tests/prover_tests.rs index 8e4d48c08..01ebc2169 100644 --- a/crates/batch-prover/tests/prover_tests.rs +++ b/crates/batch-prover/tests/prover_tests.rs @@ -308,6 +308,8 @@ fn make_new_prover(thread_pool_size: usize, da_service: Arc) -> T (), thread_pool_size, ledger_db, + vec![], + vec![], ) .expect("Should be able to instantiate Prover service"), ), diff --git a/crates/citrea-stf/src/verifier.rs b/crates/citrea-stf/src/verifier.rs index 621d7dad8..e41b9466c 100644 --- a/crates/citrea-stf/src/verifier.rs +++ b/crates/citrea-stf/src/verifier.rs @@ -28,6 +28,8 @@ where &mut self, data: BatchProofCircuitInput, pre_state: Stf::PreState, + sequencer_public_key: &[u8], + sequencer_da_public_key: &[u8], forks: &[Fork], ) -> Result, Da::Error> { println!("Running sequencer commitments in DA slot"); @@ -65,8 +67,8 @@ where } = self .app .apply_soft_confirmations_from_sequencer_commitments( - data.sequencer_public_key.as_ref(), - data.sequencer_da_public_key.as_ref(), + sequencer_public_key, + sequencer_da_public_key, &data.initial_state_root, pre_state, data.da_data, diff --git a/crates/prover-services/src/parallel/mod.rs b/crates/prover-services/src/parallel/mod.rs index a097a364b..8dc66f9c6 100644 --- a/crates/prover-services/src/parallel/mod.rs +++ b/crates/prover-services/src/parallel/mod.rs @@ -37,6 +37,8 @@ where _ledger_db: LedgerDB, proof_queue: Arc>>, + sequencer_public_key: Vec, + sequencer_da_public_key: Vec, } impl ParallelProverService @@ -54,6 +56,8 @@ where zk_storage: Stf::PreState, thread_pool_size: usize, _ledger_db: LedgerDB, + sequencer_public_key: Vec, + sequencer_da_public_key: Vec, ) -> anyhow::Result { assert!( thread_pool_size > 0, @@ -88,6 +92,8 @@ where zk_storage, _ledger_db, proof_queue: Arc::new(Mutex::new(vec![])), + sequencer_public_key, + sequencer_da_public_key, }) } @@ -99,6 +105,8 @@ where proof_mode: ProofGenMode, zk_storage: Stf::PreState, _ledger_db: LedgerDB, + sequencer_public_key: Vec, + sequencer_da_public_key: Vec, ) -> anyhow::Result { let thread_pool_size = std::env::var("PARALLEL_PROOF_LIMIT") .expect("PARALLEL_PROOF_LIMIT must be set") @@ -112,6 +120,8 @@ where zk_storage, thread_pool_size, _ledger_db, + sequencer_public_key, + sequencer_da_public_key, ) } @@ -162,6 +172,8 @@ where let mut vm = self.vm.clone(); let zk_storage = self.zk_storage.clone(); let proof_mode = self.proof_mode.clone(); + let sequencer_public_key = self.sequencer_public_key.clone(); + let sequencer_da_public_key = self.sequencer_da_public_key.clone(); vm.add_hint(input); for assumption in assumptions { @@ -170,8 +182,15 @@ where let (tx, rx) = oneshot::channel(); self.thread_pool.spawn(move || { - let proof = - make_proof(vm, elf, zk_storage, proof_mode).expect("Proof creation must not fail"); + let proof = make_proof( + vm, + elf, + zk_storage, + proof_mode, + &sequencer_public_key, + &sequencer_da_public_key, + ) + .expect("Proof creation must not fail"); let _ = tx.send(proof); }); @@ -249,6 +268,8 @@ fn make_proof( elf: Vec, zk_storage: Stf::PreState, proof_mode: Arc>>, + sequencer_public_key: &[u8], + sequencer_da_public_key: &[u8], ) -> Result where Da: DaService, @@ -263,7 +284,13 @@ where let guest = vm.simulate_with_hints(); let data = guest.read_from_host(); verifier - .run_sequencer_commitments_in_da_slot(data, zk_storage, get_forks().inner()) + .run_sequencer_commitments_in_da_slot( + data, + zk_storage, + sequencer_public_key, + sequencer_da_public_key, + get_forks().inner(), + ) .map(|_| Vec::default()) .map_err(|e| { anyhow::anyhow!("Guest execution must succeed but failed with {:?}", e) diff --git a/crates/sovereign-sdk/module-system/sov-modules-rollup-blueprint/src/lib.rs b/crates/sovereign-sdk/module-system/sov-modules-rollup-blueprint/src/lib.rs index cbf82f45c..7afb95a02 100644 --- a/crates/sovereign-sdk/module-system/sov-modules-rollup-blueprint/src/lib.rs +++ b/crates/sovereign-sdk/module-system/sov-modules-rollup-blueprint/src/lib.rs @@ -6,7 +6,7 @@ use std::sync::Arc; use async_trait::async_trait; use citrea_common::tasks::manager::TaskManager; -use citrea_common::FullNodeConfig; +use citrea_common::{FullNodeConfig, RollupPublicKeys}; use derive_more::Display; use sov_db::ledger_db::LedgerDB; use sov_db::rocks_db_config::RocksdbConfig; @@ -141,6 +141,7 @@ pub trait RollupBlueprint: Sized + Send + Sync { da_service: &Arc, da_verifier: Self::DaVerifier, ledger_db: LedgerDB, + keys: RollupPublicKeys, ) -> Self::ProverService; /// Creates instance of [`Self::StorageManager`]. diff --git a/guests/risc0/batch-proof-bitcoin/src/bin/batch_proof_bitcoin.rs b/guests/risc0/batch-proof-bitcoin/src/bin/batch_proof_bitcoin.rs index 5906bd7ce..b9b708cbe 100644 --- a/guests/risc0/batch-proof-bitcoin/src/bin/batch_proof_bitcoin.rs +++ b/guests/risc0/batch-proof-bitcoin/src/bin/batch_proof_bitcoin.rs @@ -70,7 +70,7 @@ pub fn main() { let data = guest.read_from_host(); let out = stf_verifier - .run_sequencer_commitments_in_da_slot(data, storage, FORKS) + .run_sequencer_commitments_in_da_slot(data, storage, &SEQUENCER_PUBLIC_KEY, &SEQUENCER_DA_PUBLIC_KEY, FORKS) .expect("Prover must be honest"); guest.commit(&out); diff --git a/guests/risc0/batch-proof-mock/src/bin/batch_proof_mock.rs b/guests/risc0/batch-proof-mock/src/bin/batch_proof_mock.rs index 77e8b372c..dfbf539d9 100644 --- a/guests/risc0/batch-proof-mock/src/bin/batch_proof_mock.rs +++ b/guests/risc0/batch-proof-mock/src/bin/batch_proof_mock.rs @@ -64,7 +64,7 @@ pub fn main() { let data = guest.read_from_host(); let out = stf_verifier - .run_sequencer_commitments_in_da_slot(data, storage, FORKS) + .run_sequencer_commitments_in_da_slot(data, storage, &SEQUENCER_PUBLIC_KEY, &SEQUENCER_DA_PUBLIC_KEY, FORKS) .expect("Prover must be honest"); guest.commit(&out); From 487c84a72f15a84c511659ab3b245766acd6c3f5 Mon Sep 17 00:00:00 2001 From: yaziciahmet Date: Wed, 18 Dec 2024 10:56:02 +0100 Subject: [PATCH 39/96] Get light client circuit constants as arg --- .../tests/bitcoin_e2e/light_client_test.rs | 19 --- crates/light-client-prover/src/circuit.rs | 23 +-- .../src/da_block_handler.rs | 16 -- crates/light-client-prover/src/tests/mod.rs | 139 +++++++++++++----- .../full-node/db/sov-db/src/schema/types.rs | 3 - .../rollup-interface/src/node/rpc/mod.rs | 3 - .../src/state_machine/zk/mod.rs | 8 - .../light-client-proof-bitcoin/Cargo.lock | 34 +++++ .../light-client-proof-bitcoin/Cargo.toml | 1 + .../src/bin/light_client_proof_bitcoin.rs | 8 +- .../risc0/light-client-proof-mock/Cargo.lock | 34 +++++ .../risc0/light-client-proof-mock/Cargo.toml | 1 + .../src/bin/light_client_proof_mock.rs | 8 +- 13 files changed, 185 insertions(+), 112 deletions(-) diff --git a/bin/citrea/tests/bitcoin_e2e/light_client_test.rs b/bin/citrea/tests/bitcoin_e2e/light_client_test.rs index 5ca293243..979fcaaa1 100644 --- a/bin/citrea/tests/bitcoin_e2e/light_client_test.rs +++ b/bin/citrea/tests/bitcoin_e2e/light_client_test.rs @@ -321,16 +321,6 @@ impl TestCase for LightClientProvingTestMultipleProofs { light_client_proof.light_client_proof_output.last_l2_height ); - // Should always be the same - assert_eq!( - light_client_proof2 - .light_client_proof_output - .l2_genesis_state_root, - light_client_proof - .light_client_proof_output - .l2_genesis_state_root - ); - assert!(light_client_proof2 .light_client_proof_output .unchained_batch_proofs_info @@ -417,15 +407,6 @@ impl TestCase for LightClientProvingTestMultipleProofs { batch_proofs[0].proof_output.final_state_root ); - assert_eq!( - light_client_proof3 - .light_client_proof_output - .l2_genesis_state_root, - light_client_proof - .light_client_proof_output - .l2_genesis_state_root - ); - assert_ne!( light_client_proof3.light_client_proof_output.last_l2_height, light_client_proof.light_client_proof_output.last_l2_height diff --git a/crates/light-client-prover/src/circuit.rs b/crates/light-client-prover/src/circuit.rs index 8b54f3bc6..eb80f3705 100644 --- a/crates/light-client-prover/src/circuit.rs +++ b/crates/light-client-prover/src/circuit.rs @@ -18,6 +18,9 @@ pub enum LightClientVerificationError { pub fn run_circuit( da_verifier: DaV, input: LightClientCircuitInput, + l2_genesis_root: [u8; 32], + batch_proof_method_id: [u32; 8], + batch_prover_da_public_key: &[u8], ) -> Result, LightClientVerificationError> { // Extract previous light client proof output let previous_light_client_proof_output = @@ -55,21 +58,13 @@ pub fn run_circuit( // Mapping from initial state root to final state root and last L2 height let mut initial_to_final = std::collections::BTreeMap::<[u8; 32], ([u8; 32], u64)>::new(); - let (mut last_state_root, mut last_l2_height, l2_genesis_state_root) = + let (mut last_state_root, mut last_l2_height) = previous_light_client_proof_output.as_ref().map_or_else( || { - let r = input - .l2_genesis_state_root - .expect("if no preious proof, genesis must exist"); - (r, 0, r) - }, - |prev_journal| { - ( - prev_journal.state_root, - prev_journal.last_l2_height, - prev_journal.l2_genesis_state_root, - ) + // if no previous proof, we start from genesis state root + (l2_genesis_root, 0) }, + |prev_journal| (prev_journal.state_root, prev_journal.last_l2_height), ); // If we have a previous light client proof, check they can be chained @@ -88,10 +83,9 @@ pub fn run_circuit( } // TODO: Test for multiple assumptions to see if the env::verify function does automatic matching between the journal and the assumption or do we need to verify them in order? // https://github.com/chainwayxyz/citrea/issues/1401 - let batch_proof_method_id = input.batch_proof_method_id; // Parse the batch proof da data for blob in input.da_data { - if blob.sender().as_ref() == input.batch_prover_da_pub_key { + if blob.sender().as_ref() == batch_prover_da_public_key { let data = DaDataLightClient::try_from_slice(blob.verified_data()); if let Ok(data) = data { @@ -157,6 +151,5 @@ pub fn run_circuit( da_prev_11_timestamps: block_updates.prev_11_timestamps, unchained_batch_proofs_info: unchained_outputs, last_l2_height, - l2_genesis_state_root, }) } diff --git a/crates/light-client-prover/src/da_block_handler.rs b/crates/light-client-prover/src/da_block_handler.rs index d2d2c07f8..42c81a8a7 100644 --- a/crates/light-client-prover/src/da_block_handler.rs +++ b/crates/light-client-prover/src/da_block_handler.rs @@ -182,7 +182,6 @@ where } let previous_l1_height = l1_height - 1; let mut light_client_proof_journal = None; - let mut l2_genesis_state_root = None; let l2_last_height = match self .ledger_db .get_light_client_proof_data_by_l1_height(previous_l1_height)? @@ -204,13 +203,6 @@ where // If the prev block is the block before the first processed l1 block // then we don't have a previous light client proof, so just give an info if previous_l1_height == initial_l1_height { - // TODO: Provide genesis state root here to the light client proof circuit input - l2_genesis_state_root = self - .sequencer_client - .get_l2_genesis_state_root() - .await? - .map(|v| v.as_slice().try_into().unwrap()); - tracing::info!( "No previous light client proof found for L1 block: {}", previous_l1_height @@ -231,10 +223,6 @@ where "Could not determine the last L2 height for batch proof" ))?; let current_fork = fork_from_block_number(l2_last_height); - let batch_proof_method_id = self - .batch_proof_code_commitments - .get(¤t_fork.spec_id) - .expect("Fork should have a guest code attached"); let light_client_proof_code_commitment = self .light_client_proof_code_commitments .get(¤t_fork.spec_id) @@ -250,11 +238,8 @@ where inclusion_proof, completeness_proof, da_block_header: l1_block.header().clone(), - batch_prover_da_pub_key: self.batch_prover_da_pub_key.clone(), - batch_proof_method_id: batch_proof_method_id.clone().into(), light_client_proof_method_id: light_client_proof_code_commitment.clone().into(), previous_light_client_proof_journal: light_client_proof_journal, - l2_genesis_state_root, }; let proof = self @@ -281,7 +266,6 @@ where da_prev_11_timestamps: circuit_output.da_prev_11_timestamps, unchained_batch_proofs_info: circuit_output.unchained_batch_proofs_info, last_l2_height: circuit_output.last_l2_height, - l2_genesis_state_root: circuit_output.l2_genesis_state_root, }; self.ledger_db.insert_light_client_proof_data_by_l1_height( diff --git a/crates/light-client-prover/src/tests/mod.rs b/crates/light-client-prover/src/tests/mod.rs index 018b16ead..e2f689f70 100644 --- a/crates/light-client-prover/src/tests/mod.rs +++ b/crates/light-client-prover/src/tests/mod.rs @@ -25,12 +25,19 @@ fn test_light_client_circuit_valid_da_valid_data() { da_data: vec![blob_1, blob_2], inclusion_proof: [1u8; 32], completeness_proof: (), - l2_genesis_state_root: Some([1u8; 32]), - batch_proof_method_id, - batch_prover_da_pub_key: [9; 32].to_vec(), }; - let output_1 = run_circuit::<_, MockZkGuest>(da_verifier.clone(), input).unwrap(); + let l2_genesis_state_root = [1u8; 32]; + let batch_prover_da_pub_key = [9; 32].to_vec(); + + let output_1 = run_circuit::<_, MockZkGuest>( + da_verifier.clone(), + input, + l2_genesis_state_root, + batch_proof_method_id, + &batch_prover_da_pub_key, + ) + .unwrap(); // Check that the state transition actually happened assert_eq!(output_1.state_root, [3; 32]); @@ -52,12 +59,16 @@ fn test_light_client_circuit_valid_da_valid_data() { light_client_proof_method_id, inclusion_proof: [1u8; 32], completeness_proof: (), - l2_genesis_state_root: None, - batch_proof_method_id, - batch_prover_da_pub_key: [9; 32].to_vec(), }; - let output_2 = run_circuit::<_, MockZkGuest>(da_verifier.clone(), input_2).unwrap(); + let output_2 = run_circuit::<_, MockZkGuest>( + da_verifier.clone(), + input_2, + l2_genesis_state_root, + batch_proof_method_id, + &batch_prover_da_pub_key, + ) + .unwrap(); // Check that the state transition actually happened assert_eq!(output_2.state_root, [5; 32]); @@ -68,6 +79,7 @@ fn test_light_client_circuit_valid_da_valid_data() { #[test] fn test_wrong_order_da_blocks_should_still_work() { let light_client_proof_method_id = [1u32; 8]; + let batch_proof_method_id = [1u32; 8]; let da_verifier = MockDaVerifier {}; let blob_1 = create_mock_blob([1u8; 32], [2u8; 32], 2, true); @@ -82,12 +94,19 @@ fn test_wrong_order_da_blocks_should_still_work() { da_data: vec![blob_2, blob_1], inclusion_proof: [1u8; 32], completeness_proof: (), - l2_genesis_state_root: Some([1u8; 32]), - batch_proof_method_id: light_client_proof_method_id, - batch_prover_da_pub_key: [9; 32].to_vec(), }; - let output_1 = run_circuit::<_, MockZkGuest>(da_verifier.clone(), input).unwrap(); + let l2_genesis_state_root = [1u8; 32]; + let batch_prover_da_pub_key = [9; 32].to_vec(); + + let output_1 = run_circuit::<_, MockZkGuest>( + da_verifier.clone(), + input, + l2_genesis_state_root, + batch_proof_method_id, + &batch_prover_da_pub_key, + ) + .unwrap(); // Check that the state transition actually happened assert_eq!(output_1.state_root, [3; 32]); @@ -98,6 +117,7 @@ fn test_wrong_order_da_blocks_should_still_work() { #[test] fn create_unchainable_outputs_then_chain_them_on_next_block() { let light_client_proof_method_id = [1u32; 8]; + let batch_proof_method_id = [1u32; 8]; let da_verifier = MockDaVerifier {}; let block_header_1 = MockBlockHeader::from_height(1); @@ -112,12 +132,19 @@ fn create_unchainable_outputs_then_chain_them_on_next_block() { da_data: vec![blob_2, blob_1], inclusion_proof: [1u8; 32], completeness_proof: (), - l2_genesis_state_root: Some([1u8; 32]), - batch_proof_method_id: light_client_proof_method_id, - batch_prover_da_pub_key: [9; 32].to_vec(), }; - let output_1 = run_circuit::<_, MockZkGuest>(da_verifier.clone(), input).unwrap(); + let l2_genesis_state_root = [1u8; 32]; + let batch_prover_da_pub_key = [9; 32].to_vec(); + + let output_1 = run_circuit::<_, MockZkGuest>( + da_verifier.clone(), + input, + l2_genesis_state_root, + batch_proof_method_id, + &batch_prover_da_pub_key, + ) + .unwrap(); // Check that the state transition has not happened because we are missing 1->2 assert_eq!(output_1.state_root, [1; 32]); @@ -150,12 +177,16 @@ fn create_unchainable_outputs_then_chain_them_on_next_block() { da_data: vec![blob_1], inclusion_proof: [1u8; 32], completeness_proof: (), - l2_genesis_state_root: None, - batch_proof_method_id: light_client_proof_method_id, - batch_prover_da_pub_key: [9; 32].to_vec(), }; - let output_2 = run_circuit::<_, MockZkGuest>(da_verifier, input_2).unwrap(); + let output_2 = run_circuit::<_, MockZkGuest>( + da_verifier.clone(), + input_2, + l2_genesis_state_root, + batch_proof_method_id, + &batch_prover_da_pub_key, + ) + .unwrap(); // Check that the state transition actually happened from 1-4 now @@ -167,6 +198,7 @@ fn create_unchainable_outputs_then_chain_them_on_next_block() { #[test] fn test_header_chain_proof_height_and_hash() { let light_client_proof_method_id = [1u32; 8]; + let batch_proof_method_id = [1u32; 8]; let da_verifier = MockDaVerifier {}; let blob_1 = create_mock_blob([1u8; 32], [2u8; 32], 2, true); @@ -181,12 +213,19 @@ fn test_header_chain_proof_height_and_hash() { da_data: vec![blob_1, blob_2], inclusion_proof: [1u8; 32], completeness_proof: (), - l2_genesis_state_root: Some([1u8; 32]), - batch_proof_method_id: light_client_proof_method_id, - batch_prover_da_pub_key: [9; 32].to_vec(), }; - let output_1 = run_circuit::<_, MockZkGuest>(da_verifier.clone(), input).unwrap(); + let l2_genesis_state_root = [1u8; 32]; + let batch_prover_da_pub_key = [9; 32].to_vec(); + + let output_1 = run_circuit::<_, MockZkGuest>( + da_verifier.clone(), + input, + l2_genesis_state_root, + batch_proof_method_id, + &batch_prover_da_pub_key, + ) + .unwrap(); // Check that the state transition actually happened assert_eq!(output_1.state_root, [3; 32]); @@ -208,13 +247,16 @@ fn test_header_chain_proof_height_and_hash() { light_client_proof_method_id, inclusion_proof: [1u8; 32], completeness_proof: (), - l2_genesis_state_root: None, - batch_proof_method_id: light_client_proof_method_id, - batch_prover_da_pub_key: [9; 32].to_vec(), }; // Header chain verification must fail because the l1 block 3 was given before l1 block 2 - let res = run_circuit::<_, MockZkGuest>(da_verifier, input_2); + let res = run_circuit::<_, MockZkGuest>( + da_verifier, + input_2, + l2_genesis_state_root, + batch_proof_method_id, + &batch_prover_da_pub_key, + ); assert!(matches!( res, Err(LightClientVerificationError::HeaderChainVerificationFailed) @@ -239,12 +281,19 @@ fn test_unverifiable_batch_proofs() { da_data: vec![blob_1, blob_2], inclusion_proof: [1u8; 32], completeness_proof: (), - l2_genesis_state_root: Some([1u8; 32]), - batch_proof_method_id, - batch_prover_da_pub_key: [9; 32].to_vec(), }; - let output_1 = run_circuit::<_, MockZkGuest>(da_verifier.clone(), input).unwrap(); + let l2_genesis_state_root = [1u8; 32]; + let batch_prover_da_pub_key = [9; 32].to_vec(); + + let output_1 = run_circuit::<_, MockZkGuest>( + da_verifier.clone(), + input, + l2_genesis_state_root, + batch_proof_method_id, + &batch_prover_da_pub_key, + ) + .unwrap(); // Check that the state transition actually happened but only for verified batch proof // and assert the unverified is ignored, so it is not even in the unchained outputs @@ -272,12 +321,19 @@ fn test_unverifiable_prev_light_client_proof() { da_data: vec![blob_1, blob_2], inclusion_proof: [1u8; 32], completeness_proof: (), - l2_genesis_state_root: Some([1u8; 32]), - batch_proof_method_id, - batch_prover_da_pub_key: [9; 32].to_vec(), }; - let output_1 = run_circuit::<_, MockZkGuest>(da_verifier.clone(), input).unwrap(); + let l2_genesis_state_root = [1u8; 32]; + let batch_prover_da_pub_key = [9; 32].to_vec(); + + let output_1 = run_circuit::<_, MockZkGuest>( + da_verifier.clone(), + input, + l2_genesis_state_root, + batch_proof_method_id, + &batch_prover_da_pub_key, + ) + .unwrap(); // Check that the state transition actually happened but only for verified batch proof // and assert the unverified is ignored, so it is not even in the unchained outputs @@ -297,12 +353,15 @@ fn test_unverifiable_prev_light_client_proof() { light_client_proof_method_id, inclusion_proof: [1u8; 32], completeness_proof: (), - l2_genesis_state_root: None, - batch_proof_method_id: light_client_proof_method_id, - batch_prover_da_pub_key: [9; 32].to_vec(), }; - let res = run_circuit::<_, MockZkGuest>(da_verifier, input_2); + let res = run_circuit::<_, MockZkGuest>( + da_verifier, + input_2, + l2_genesis_state_root, + light_client_proof_method_id, + &batch_prover_da_pub_key, + ); assert!(matches!( res, Err(LightClientVerificationError::InvalidPreviousLightClientProof) diff --git a/crates/sovereign-sdk/full-node/db/sov-db/src/schema/types.rs b/crates/sovereign-sdk/full-node/db/sov-db/src/schema/types.rs index 390163557..447757588 100644 --- a/crates/sovereign-sdk/full-node/db/sov-db/src/schema/types.rs +++ b/crates/sovereign-sdk/full-node/db/sov-db/src/schema/types.rs @@ -95,8 +95,6 @@ pub struct StoredLightClientProofOutput { pub unchained_batch_proofs_info: Vec, /// Last l2 height after proof. pub last_l2_height: u64, - /// L2 genesis state root. - pub l2_genesis_state_root: [u8; 32], } impl From for LightClientProofOutputRpcResponse { @@ -112,7 +110,6 @@ impl From for LightClientProofOutputRpcResponse { da_prev_11_timestamps: value.da_prev_11_timestamps, unchained_batch_proofs_info: value.unchained_batch_proofs_info, last_l2_height: value.last_l2_height, - l2_genesis_state_root: value.l2_genesis_state_root, } } } diff --git a/crates/sovereign-sdk/rollup-interface/src/node/rpc/mod.rs b/crates/sovereign-sdk/rollup-interface/src/node/rpc/mod.rs index 5d7e18205..3a3c4afbb 100644 --- a/crates/sovereign-sdk/rollup-interface/src/node/rpc/mod.rs +++ b/crates/sovereign-sdk/rollup-interface/src/node/rpc/mod.rs @@ -166,9 +166,6 @@ pub struct LightClientProofOutputRpcResponse { pub unchained_batch_proofs_info: Vec, /// Last l2 height the light client proof verifies pub last_l2_height: u64, - /// Genesis state root of Citrea - #[serde(with = "hex::serde")] - pub l2_genesis_state_root: [u8; 32], } #[derive(Debug, Clone, Serialize, Deserialize)] diff --git a/crates/sovereign-sdk/rollup-interface/src/state_machine/zk/mod.rs b/crates/sovereign-sdk/rollup-interface/src/state_machine/zk/mod.rs index 3f2248ade..90502ccab 100644 --- a/crates/sovereign-sdk/rollup-interface/src/state_machine/zk/mod.rs +++ b/crates/sovereign-sdk/rollup-interface/src/state_machine/zk/mod.rs @@ -236,8 +236,6 @@ pub struct LightClientCircuitOutput { pub unchained_batch_proofs_info: Vec, /// Last l2 height the light client proof verifies pub last_l2_height: u64, - /// Genesis state root of Citrea - pub l2_genesis_state_root: [u8; 32], } /// The input of light client proof @@ -252,15 +250,9 @@ pub struct LightClientCircuitInput { /// DA block header that the batch proofs were found in. pub da_block_header: Da::BlockHeader, - /// Public key of the batch prover - pub batch_prover_da_pub_key: Vec, - /// Batch proof method id - pub batch_proof_method_id: [u32; 8], /// Light client proof method id pub light_client_proof_method_id: [u32; 8], /// Light client proof output /// Optional because the first light client proof doesn't have a previous proof pub previous_light_client_proof_journal: Option>, - /// L2 Genesis state root - pub l2_genesis_state_root: Option<[u8; 32]>, } diff --git a/guests/risc0/light-client-proof-bitcoin/Cargo.lock b/guests/risc0/light-client-proof-bitcoin/Cargo.lock index 1d066ebc3..7891d5e6d 100644 --- a/guests/risc0/light-client-proof-bitcoin/Cargo.lock +++ b/guests/risc0/light-client-proof-bitcoin/Cargo.lock @@ -855,12 +855,39 @@ version = "0.9.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c2459377285ad874054d797f3ccebf984978aa39129f6eafde5cdc8315b612f8" +[[package]] +name = "const_panic" +version = "0.2.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "53857514f72ee4a2b583de67401e3ff63a5472ca4acf289d09a9ea7636dfec17" + [[package]] name = "constant_time_eq" version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7c74b8349d32d297c9134b8c88677813a227df8f779daa29bfc29c183fe3dca6" +[[package]] +name = "constmuck" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f0e253ed9cc2e1bcc63d791dbe28f818fdff4fceb00d2ff1d3eb943574c623f8" +dependencies = [ + "bytemuck", + "constmuck_internal", + "typewit", +] + +[[package]] +name = "constmuck_internal" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d5927bf986ef0398efc2725a986975c1bad3140c883e7bf102f3dec8bcdf0375" +dependencies = [ + "bytemuck", + "const_panic", +] + [[package]] name = "convert_case" version = "0.4.0" @@ -1645,6 +1672,7 @@ dependencies = [ "citrea-primitives", "citrea-risc0-adapter", "const-hex", + "constmuck", "risc0-zkvm", "risc0-zkvm-platform", "sov-modules-api", @@ -3036,6 +3064,12 @@ version = "1.17.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "42ff0bf0c66b8238c6f3b578df37d0b7848e55df8577b3f74f92a69acceeb825" +[[package]] +name = "typewit" +version = "1.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cb77c29baba9e4d3a6182d51fa75e3215c7fd1dab8f4ea9d107c716878e55fc0" + [[package]] name = "ucd-trie" version = "0.1.7" diff --git a/guests/risc0/light-client-proof-bitcoin/Cargo.toml b/guests/risc0/light-client-proof-bitcoin/Cargo.toml index 30f9e8a41..035b16576 100644 --- a/guests/risc0/light-client-proof-bitcoin/Cargo.toml +++ b/guests/risc0/light-client-proof-bitcoin/Cargo.toml @@ -16,6 +16,7 @@ citrea-light-client-prover = { path = "../../../crates/light-client-prover", def citrea-primitives = { path = "../../../crates/primitives" } citrea-risc0-adapter = { path = "../../../crates/risc0" } const-hex = "1.12" +constmuck = "1.1" sov-modules-api = { path = "../../../crates/sovereign-sdk/module-system/sov-modules-api", default-features = false } sov-modules-stf-blueprint = { path = "../../../crates/sovereign-sdk/module-system/sov-modules-stf-blueprint" } sov-rollup-interface = { path = "../../../crates/sovereign-sdk/rollup-interface" } diff --git a/guests/risc0/light-client-proof-bitcoin/src/bin/light_client_proof_bitcoin.rs b/guests/risc0/light-client-proof-bitcoin/src/bin/light_client_proof_bitcoin.rs index f9797e49d..e6697337f 100644 --- a/guests/risc0/light-client-proof-bitcoin/src/bin/light_client_proof_bitcoin.rs +++ b/guests/risc0/light-client-proof-bitcoin/src/bin/light_client_proof_bitcoin.rs @@ -18,11 +18,11 @@ const L2_GENESIS_ROOT: [u8; 32] = { } }; -const BATCH_PROOF_METHOD_ID: [u8; 32] = { +const BATCH_PROOF_METHOD_ID: [u32; 8] = { let hex_method_id = env!("BATCH_PROOF_METHOD_ID"); - match const_hex::const_decode_to_array(hex_method_id.as_bytes()) { - Ok(method_id) => method_id, + match const_hex::const_decode_to_array::<32>(hex_method_id.as_bytes()) { + Ok(method_id) => constmuck::cast(method_id), Err(_) => panic!("BATCH_PROOF_METHOD_ID must be valid 32-byte hex string"), } }; @@ -51,7 +51,7 @@ pub fn main() { let input = guest.read_from_host(); - let output = run_circuit::(da_verifier, input).unwrap(); + let output = run_circuit::(da_verifier, input, L2_GENESIS_ROOT, BATCH_PROOF_METHOD_ID, &BATCH_PROVER_DA_PUBLIC_KEY).unwrap(); guest.commit(&output); } diff --git a/guests/risc0/light-client-proof-mock/Cargo.lock b/guests/risc0/light-client-proof-mock/Cargo.lock index aecf6f26f..f91d1160b 100644 --- a/guests/risc0/light-client-proof-mock/Cargo.lock +++ b/guests/risc0/light-client-proof-mock/Cargo.lock @@ -764,12 +764,39 @@ version = "0.9.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c2459377285ad874054d797f3ccebf984978aa39129f6eafde5cdc8315b612f8" +[[package]] +name = "const_panic" +version = "0.2.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "53857514f72ee4a2b583de67401e3ff63a5472ca4acf289d09a9ea7636dfec17" + [[package]] name = "constant_time_eq" version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7c74b8349d32d297c9134b8c88677813a227df8f779daa29bfc29c183fe3dca6" +[[package]] +name = "constmuck" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f0e253ed9cc2e1bcc63d791dbe28f818fdff4fceb00d2ff1d3eb943574c623f8" +dependencies = [ + "bytemuck", + "constmuck_internal", + "typewit", +] + +[[package]] +name = "constmuck_internal" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d5927bf986ef0398efc2725a986975c1bad3140c883e7bf102f3dec8bcdf0375" +dependencies = [ + "bytemuck", + "const_panic", +] + [[package]] name = "convert_case" version = "0.4.0" @@ -1449,6 +1476,7 @@ dependencies = [ "citrea-primitives", "citrea-risc0-adapter", "const-hex", + "constmuck", "risc0-zkvm", "risc0-zkvm-platform", "sov-mock-da", @@ -2822,6 +2850,12 @@ version = "1.17.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "42ff0bf0c66b8238c6f3b578df37d0b7848e55df8577b3f74f92a69acceeb825" +[[package]] +name = "typewit" +version = "1.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cb77c29baba9e4d3a6182d51fa75e3215c7fd1dab8f4ea9d107c716878e55fc0" + [[package]] name = "ucd-trie" version = "0.1.7" diff --git a/guests/risc0/light-client-proof-mock/Cargo.toml b/guests/risc0/light-client-proof-mock/Cargo.toml index a6290b451..7e14d80b0 100644 --- a/guests/risc0/light-client-proof-mock/Cargo.toml +++ b/guests/risc0/light-client-proof-mock/Cargo.toml @@ -17,6 +17,7 @@ citrea-light-client-prover = { path = "../../../crates/light-client-prover", def citrea-primitives = { path = "../../../crates/primitives" } citrea-risc0-adapter = { path = "../../../crates/risc0" } const-hex = "1.12" +constmuck = "1.1" sov-modules-api = { path = "../../../crates/sovereign-sdk/module-system/sov-modules-api", default-features = false } sov-modules-stf-blueprint = { path = "../../../crates/sovereign-sdk/module-system/sov-modules-stf-blueprint" } sov-rollup-interface = { path = "../../../crates/sovereign-sdk/rollup-interface" } diff --git a/guests/risc0/light-client-proof-mock/src/bin/light_client_proof_mock.rs b/guests/risc0/light-client-proof-mock/src/bin/light_client_proof_mock.rs index 23a5298c7..64068b89b 100644 --- a/guests/risc0/light-client-proof-mock/src/bin/light_client_proof_mock.rs +++ b/guests/risc0/light-client-proof-mock/src/bin/light_client_proof_mock.rs @@ -15,11 +15,11 @@ const L2_GENESIS_ROOT: [u8; 32] = { } }; -const BATCH_PROOF_METHOD_ID: [u8; 32] = { +const BATCH_PROOF_METHOD_ID: [u32; 8] = { let hex_method_id = env!("BATCH_PROOF_METHOD_ID"); - match const_hex::const_decode_to_array(hex_method_id.as_bytes()) { - Ok(method_id) => method_id, + match const_hex::const_decode_to_array::<32>(hex_method_id.as_bytes()) { + Ok(method_id) => constmuck::cast(method_id), Err(_) => panic!("BATCH_PROOF_METHOD_ID must be valid 32-byte hex string"), } }; @@ -45,7 +45,7 @@ pub fn main() { let input = guest.read_from_host(); - let output = run_circuit::(da_verifier, input).unwrap(); + let output = run_circuit::(da_verifier, input, L2_GENESIS_ROOT, BATCH_PROOF_METHOD_ID, &BATCH_PROVER_DA_PUBLIC_KEY).unwrap(); guest.commit(&output); } From 0b69f36260be6182e317470e7ec1c5149dbd37d8 Mon Sep 17 00:00:00 2001 From: yaziciahmet Date: Wed, 18 Dec 2024 11:03:50 +0100 Subject: [PATCH 40/96] Lint --- bin/citrea/src/rollup/mod.rs | 8 ++++---- crates/common/src/config.rs | 2 +- crates/prover-services/src/parallel/mod.rs | 1 + crates/sovereign-sdk/rollup-interface/src/fork/mod.rs | 6 +++--- 4 files changed, 9 insertions(+), 8 deletions(-) diff --git a/bin/citrea/src/rollup/mod.rs b/bin/citrea/src/rollup/mod.rs index 255c88e86..130532458 100644 --- a/bin/citrea/src/rollup/mod.rs +++ b/bin/citrea/src/rollup/mod.rs @@ -52,7 +52,7 @@ pub trait CitreaRollupBlueprint: RollupBlueprint { ::Storage: NativeStorage, { // Set forks before anything - set_forks(rollup_config.forks.clone()); + set_forks(rollup_config.forks); let mut task_manager = TaskManager::default(); let da_service = self @@ -176,7 +176,7 @@ pub trait CitreaRollupBlueprint: RollupBlueprint { ::Storage: NativeStorage, { // Set forks before anything - set_forks(rollup_config.forks.clone()); + set_forks(rollup_config.forks); let mut task_manager = TaskManager::default(); let da_service = self @@ -311,7 +311,7 @@ pub trait CitreaRollupBlueprint: RollupBlueprint { ::Storage: NativeStorage, { // Set forks before anything - set_forks(rollup_config.forks.clone()); + set_forks(rollup_config.forks); let mut task_manager = TaskManager::default(); let da_service = self @@ -445,7 +445,7 @@ pub trait CitreaRollupBlueprint: RollupBlueprint { ::Storage: NativeStorage, { // Set forks before anything - set_forks(rollup_config.forks.clone()); + set_forks(rollup_config.forks); // Migrate before constructing ledger_db instance so that no lock is present. let migrator = LedgerDBMigrator::new( diff --git a/crates/common/src/config.rs b/crates/common/src/config.rs index 404909c62..16a0e378b 100644 --- a/crates/common/src/config.rs +++ b/crates/common/src/config.rs @@ -306,7 +306,7 @@ impl FromEnv for LightClientProverConfig { impl FromEnv for Forks { fn from_env() -> anyhow::Result { let forks = std::env::var("FORKS")?; - Ok(Forks::from_utf8(&forks).ok_or(anyhow::anyhow!("Invalid FORKS env variable"))?) + Forks::from_utf8(&forks).ok_or(anyhow::anyhow!("Invalid FORKS env variable")) } } diff --git a/crates/prover-services/src/parallel/mod.rs b/crates/prover-services/src/parallel/mod.rs index 8dc66f9c6..8246f8e1c 100644 --- a/crates/prover-services/src/parallel/mod.rs +++ b/crates/prover-services/src/parallel/mod.rs @@ -49,6 +49,7 @@ where Stf::PreState: Clone + Send + Sync, { /// Creates a new prover. + #[allow(clippy::too_many_arguments)] pub fn new( da_service: Arc, vm: Vm, diff --git a/crates/sovereign-sdk/rollup-interface/src/fork/mod.rs b/crates/sovereign-sdk/rollup-interface/src/fork/mod.rs index 9859a409e..532da876d 100644 --- a/crates/sovereign-sdk/rollup-interface/src/fork/mod.rs +++ b/crates/sovereign-sdk/rollup-interface/src/fork/mod.rs @@ -330,9 +330,9 @@ pub(crate) const fn verify_forks(forks: &[Fork]) -> bool { /// This assumes that the list of forks is sorted by block number in ascending fashion. pub(crate) fn fork_pos_from_block_number(forks: &[Fork], block_number: u64) -> usize { let pos = forks.binary_search_by(|fork| fork.activation_height.cmp(&block_number)); - let active_fork_idx = match pos { + + match pos { Ok(idx) => idx, Err(idx) => idx.saturating_sub(1), - }; - active_fork_idx + } } From 41b15ddf0c48083f466d03cdbc54ee671ba17dda Mon Sep 17 00:00:00 2001 From: yaziciahmet Date: Wed, 18 Dec 2024 11:20:50 +0100 Subject: [PATCH 41/96] Fix comment --- crates/sovereign-sdk/rollup-interface/src/fork/mod.rs | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/crates/sovereign-sdk/rollup-interface/src/fork/mod.rs b/crates/sovereign-sdk/rollup-interface/src/fork/mod.rs index 532da876d..d16d136b3 100644 --- a/crates/sovereign-sdk/rollup-interface/src/fork/mod.rs +++ b/crates/sovereign-sdk/rollup-interface/src/fork/mod.rs @@ -300,8 +300,7 @@ impl Fork { } } -/// Verifies the order of forks. `size` is needed here due to being in const environment, -/// size of the fork might not be known beforehand. +/// Verifies the order of forks. pub(crate) const fn verify_forks(forks: &[Fork]) -> bool { let mut i = 0; while i < forks.len() { From 69a3f3b00a2c28155adc4bc291fecc9d47135007 Mon Sep 17 00:00:00 2001 From: yaziciahmet Date: Wed, 18 Dec 2024 12:41:50 +0100 Subject: [PATCH 42/96] Match DA public key env key for native and zk --- crates/common/src/config.rs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/crates/common/src/config.rs b/crates/common/src/config.rs index 16a0e378b..00e759c92 100644 --- a/crates/common/src/config.rs +++ b/crates/common/src/config.rs @@ -194,8 +194,8 @@ impl FromEnv for RollupPublicKeys { fn from_env() -> anyhow::Result { Ok(Self { sequencer_public_key: hex::decode(std::env::var("SEQUENCER_PUBLIC_KEY")?)?, - sequencer_da_pub_key: hex::decode(std::env::var("SEQUENCER_DA_PUB_KEY")?)?, - prover_da_pub_key: hex::decode(std::env::var("PROVER_DA_PUB_KEY")?)?, + sequencer_da_pub_key: hex::decode(std::env::var("SEQUENCER_DA_PUBLIC_KEY")?)?, + prover_da_pub_key: hex::decode(std::env::var("PROVER_DA_PUBLIC_KEY")?)?, }) } } @@ -675,10 +675,10 @@ mod tests { "0000000000000000000000000000000000000000000000000000000000000000", ); std::env::set_var( - "SEQUENCER_DA_PUB_KEY", + "SEQUENCER_DA_PUBLIC_KEY", "7777777777777777777777777777777777777777777777777777777777777777", ); - std::env::set_var("PROVER_DA_PUB_KEY", ""); + std::env::set_var("PROVER_DA_PUBLIC_KEY", ""); std::env::set_var("RPC_BIND_HOST", "127.0.0.1"); std::env::set_var("RPC_BIND_PORT", "12345"); From ebd3a8ddb2b1de8035e7cf1a69605de2207b8110 Mon Sep 17 00:00:00 2001 From: yaziciahmet Date: Wed, 18 Dec 2024 13:23:27 +0100 Subject: [PATCH 43/96] Make FORKS constant per environment --- bin/citrea/src/lib.rs | 2 +- bin/citrea/src/main.rs | 3 +- bin/citrea/src/rollup/bitcoin.rs | 2 + bin/citrea/src/rollup/mock.rs | 2 + bin/citrea/src/rollup/mod.rs | 22 ++---- bin/citrea/tests/test_helpers/mod.rs | 3 +- crates/primitives/src/forks.rs | 74 ++++++++++++------- crates/prover-services/src/parallel/mod.rs | 2 +- .../sov-modules-rollup-blueprint/src/lib.rs | 16 +--- .../rollup-interface/src/fork/mod.rs | 2 +- .../sovereign-sdk/rollup-interface/src/lib.rs | 3 + .../rollup-interface/src/network.rs | 21 ++++++ 12 files changed, 90 insertions(+), 62 deletions(-) create mode 100644 crates/sovereign-sdk/rollup-interface/src/network.rs diff --git a/bin/citrea/src/lib.rs b/bin/citrea/src/lib.rs index a661c1153..212c7be71 100644 --- a/bin/citrea/src/lib.rs +++ b/bin/citrea/src/lib.rs @@ -5,7 +5,7 @@ use std::env; use std::str::FromStr; use serde::Serialize; -use sov_modules_rollup_blueprint::Network; +use sov_rollup_interface::Network; use tracing::Level; use tracing_subscriber::layer::SubscriberExt; use tracing_subscriber::util::SubscriberInitExt; diff --git a/bin/citrea/src/main.rs b/bin/citrea/src/main.rs index d6596a0f9..5cb41d89d 100644 --- a/bin/citrea/src/main.rs +++ b/bin/citrea/src/main.rs @@ -17,7 +17,8 @@ use metrics_exporter_prometheus::PrometheusBuilder; use metrics_util::MetricKindMask; use sov_mock_da::MockDaConfig; use sov_modules_api::Spec; -use sov_modules_rollup_blueprint::{Network, RollupBlueprint}; +use sov_modules_rollup_blueprint::RollupBlueprint; +use sov_rollup_interface::Network; use sov_state::storage::NativeStorage; use tracing::{debug, error, info, instrument}; diff --git a/bin/citrea/src/rollup/bitcoin.rs b/bin/citrea/src/rollup/bitcoin.rs index a438c3f29..eee4ca37d 100644 --- a/bin/citrea/src/rollup/bitcoin.rs +++ b/bin/citrea/src/rollup/bitcoin.rs @@ -9,6 +9,7 @@ use bitcoin_da::verifier::BitcoinVerifier; use citrea_common::rpc::register_healthcheck_rpc; use citrea_common::tasks::manager::TaskManager; use citrea_common::{FullNodeConfig, RollupPublicKeys}; +use citrea_primitives::forks::use_network_forks; use citrea_primitives::{TO_BATCH_PROOF_PREFIX, TO_LIGHT_CLIENT_PREFIX}; use citrea_risc0_adapter::host::Risc0BonsaiHost; // use citrea_sp1::host::SP1Host; @@ -64,6 +65,7 @@ impl RollupBlueprint for BitcoinRollup { >; fn new(network: Network) -> Self { + use_network_forks(network); Self { network } } diff --git a/bin/citrea/src/rollup/mock.rs b/bin/citrea/src/rollup/mock.rs index 727673ad8..a4370438f 100644 --- a/bin/citrea/src/rollup/mock.rs +++ b/bin/citrea/src/rollup/mock.rs @@ -5,6 +5,7 @@ use async_trait::async_trait; use citrea_common::rpc::register_healthcheck_rpc; use citrea_common::tasks::manager::TaskManager; use citrea_common::{FullNodeConfig, RollupPublicKeys}; +use citrea_primitives::forks::use_network_forks; // use citrea_sp1::host::SP1Host; use citrea_risc0_adapter::host::Risc0BonsaiHost; use citrea_stf::genesis_config::StorageConfig; @@ -50,6 +51,7 @@ impl RollupBlueprint for MockDemoRollup { >; fn new(network: Network) -> Self { + use_network_forks(network); Self { _network: network } } diff --git a/bin/citrea/src/rollup/mod.rs b/bin/citrea/src/rollup/mod.rs index 130532458..dbc0ab7b6 100644 --- a/bin/citrea/src/rollup/mod.rs +++ b/bin/citrea/src/rollup/mod.rs @@ -7,7 +7,7 @@ use citrea_common::tasks::manager::TaskManager; use citrea_common::{BatchProverConfig, FullNodeConfig, LightClientProverConfig, SequencerConfig}; use citrea_fullnode::CitreaFullnode; use citrea_light_client_prover::runner::CitreaLightClientProver; -use citrea_primitives::forks::{get_forks, set_forks}; +use citrea_primitives::forks::get_forks; use citrea_sequencer::CitreaSequencer; use jsonrpsee::RpcModule; use sov_db::ledger_db::migrations::LedgerDBMigrator; @@ -51,9 +51,6 @@ pub trait CitreaRollupBlueprint: RollupBlueprint { where ::Storage: NativeStorage, { - // Set forks before anything - set_forks(rollup_config.forks); - let mut task_manager = TaskManager::default(); let da_service = self .create_da_service(&rollup_config, true, &mut task_manager) @@ -128,7 +125,7 @@ pub trait CitreaRollupBlueprint: RollupBlueprint { .map(|(l2_height, _)| l2_height) .unwrap_or(BatchNumber(0)); - let mut fork_manager = ForkManager::new(get_forks().inner(), current_l2_height.0); + let mut fork_manager = ForkManager::new(get_forks(), current_l2_height.0); fork_manager.register_handler(Box::new(ledger_db.clone())); let seq = CitreaSequencer::new( @@ -175,9 +172,6 @@ pub trait CitreaRollupBlueprint: RollupBlueprint { where ::Storage: NativeStorage, { - // Set forks before anything - set_forks(rollup_config.forks); - let mut task_manager = TaskManager::default(); let da_service = self .create_da_service(&rollup_config, false, &mut task_manager) @@ -262,7 +256,7 @@ pub trait CitreaRollupBlueprint: RollupBlueprint { .map(|(l2_height, _)| l2_height) .unwrap_or(BatchNumber(0)); - let mut fork_manager = ForkManager::new(get_forks().inner(), current_l2_height.0); + let mut fork_manager = ForkManager::new(get_forks(), current_l2_height.0); fork_manager.register_handler(Box::new(ledger_db.clone())); let runner = CitreaFullnode::new( @@ -310,9 +304,6 @@ pub trait CitreaRollupBlueprint: RollupBlueprint { where ::Storage: NativeStorage, { - // Set forks before anything - set_forks(rollup_config.forks); - let mut task_manager = TaskManager::default(); let da_service = self .create_da_service(&rollup_config, true, &mut task_manager) @@ -404,7 +395,7 @@ pub trait CitreaRollupBlueprint: RollupBlueprint { .map(|(l2_height, _)| l2_height) .unwrap_or(BatchNumber(0)); - let mut fork_manager = ForkManager::new(get_forks().inner(), current_l2_height.0); + let mut fork_manager = ForkManager::new(get_forks(), current_l2_height.0); fork_manager.register_handler(Box::new(ledger_db.clone())); let runner = CitreaBatchProver::new( @@ -444,9 +435,6 @@ pub trait CitreaRollupBlueprint: RollupBlueprint { where ::Storage: NativeStorage, { - // Set forks before anything - set_forks(rollup_config.forks); - // Migrate before constructing ledger_db instance so that no lock is present. let migrator = LedgerDBMigrator::new( rollup_config.storage.path.as_path(), @@ -504,7 +492,7 @@ pub trait CitreaRollupBlueprint: RollupBlueprint { .map(|(l2_height, _)| l2_height) .unwrap_or(BatchNumber(0)); - let mut fork_manager = ForkManager::new(get_forks().inner(), current_l2_height.0); + let mut fork_manager = ForkManager::new(get_forks(), current_l2_height.0); fork_manager.register_handler(Box::new(ledger_db.clone())); let runner = CitreaLightClientProver::new( diff --git a/bin/citrea/tests/test_helpers/mod.rs b/bin/citrea/tests/test_helpers/mod.rs index 50b83e7d7..f88b196a9 100644 --- a/bin/citrea/tests/test_helpers/mod.rs +++ b/bin/citrea/tests/test_helpers/mod.rs @@ -15,10 +15,11 @@ use sov_mock_da::{MockAddress, MockBlock, MockDaConfig, MockDaService}; use sov_modules_api::default_signature::private_key::DefaultPrivateKey; use sov_modules_api::fork::{Fork, Forks}; use sov_modules_api::{PrivateKey, SpecId}; -use sov_modules_rollup_blueprint::{Network, RollupBlueprint as _}; +use sov_modules_rollup_blueprint::RollupBlueprint as _; use sov_rollup_interface::da::{BlobReaderTrait, DaData, SequencerCommitment}; use sov_rollup_interface::services::da::{DaService, SlotData}; use sov_rollup_interface::zk::Proof; +use sov_rollup_interface::Network; use tempfile::TempDir; use tokio::sync::oneshot; use tokio::time::sleep; diff --git a/crates/primitives/src/forks.rs b/crates/primitives/src/forks.rs index 4133de43f..777768506 100644 --- a/crates/primitives/src/forks.rs +++ b/crates/primitives/src/forks.rs @@ -1,17 +1,25 @@ use std::sync::OnceLock; -use sov_rollup_interface::fork::{Fork, Forks}; +use sov_rollup_interface::fork::{fork_pos_from_block_number, Fork}; +use sov_rollup_interface::spec::SpecId; +use sov_rollup_interface::Network; -static FORKS: OnceLock = OnceLock::new(); +static FORKS: OnceLock<&'static [Fork]> = OnceLock::new(); -/// Set the forks. Must be called once. -pub fn set_forks(forks: Forks) { +/// Set forks globally based on the network. Must be called once at the start of the application. +pub fn use_network_forks(network: Network) { + let forks: &[Fork] = match network { + Network::Mainnet => &MAINNET_FORKS, + Network::Testnet => &TESTNET_FORKS, + Network::Devnet => &DEVNET_FORKS, + Network::Nightly => &NIGHTLY_FORKS, + }; FORKS.set(forks).expect("Forks must be set exactly once"); } /// Get forks. Forks need to be set before calling this method if not in testing environment. /// In testing environment default forks are used. -pub fn get_forks() -> &'static Forks { +pub fn get_forks() -> &'static [Fork] { match FORKS.get() { Some(forks) => forks, None => { @@ -20,25 +28,9 @@ pub fn get_forks() -> &'static Forks { #[cfg(feature = "testing")] { - use sov_rollup_interface::spec::SpecId; - - set_forks( - Forks::from_slice(&[ - Fork { - spec_id: SpecId::Genesis, - activation_height: 0, - }, - Fork { - spec_id: SpecId::Fork1, - activation_height: 1000, - }, - Fork { - spec_id: SpecId::Fork2, - activation_height: 2000, - }, - ]) - .expect("Forks are ordered"), - ); + FORKS + .set(&TESTING_FORKS) + .expect("Already checked that it is not set"); FORKS.get().expect("Just set it") } } @@ -48,5 +40,37 @@ pub fn get_forks() -> &'static Forks { /// Get fork from the given block number. Forks must be set before calling this method if not in test environment. /// In test environment default forks are used. pub fn fork_from_block_number(block_number: u64) -> Fork { - get_forks().fork_from_block_number(block_number) + let forks = get_forks(); + let pos = fork_pos_from_block_number(forks, block_number); + forks[pos] } + +const MAINNET_FORKS: [Fork; 1] = [Fork::new(SpecId::Fork1, 0)]; + +const TESTNET_FORKS: [Fork; 2] = [ + Fork::new(SpecId::Genesis, 0), + Fork::new(SpecId::Fork1, 999_999_999), +]; + +const DEVNET_FORKS: [Fork; 2] = [ + Fork::new(SpecId::Genesis, 0), + Fork::new(SpecId::Fork1, 999_999_999), +]; + +const NIGHTLY_FORKS: [Fork; 1] = [Fork::new(SpecId::Fork1, 0)]; + +#[cfg(feature = "testing")] +const TESTING_FORKS: [Fork; 3] = [ + Fork { + spec_id: SpecId::Genesis, + activation_height: 0, + }, + Fork { + spec_id: SpecId::Fork1, + activation_height: 1000, + }, + Fork { + spec_id: SpecId::Fork2, + activation_height: 2000, + }, +]; diff --git a/crates/prover-services/src/parallel/mod.rs b/crates/prover-services/src/parallel/mod.rs index 8246f8e1c..fd299fd84 100644 --- a/crates/prover-services/src/parallel/mod.rs +++ b/crates/prover-services/src/parallel/mod.rs @@ -290,7 +290,7 @@ where zk_storage, sequencer_public_key, sequencer_da_public_key, - get_forks().inner(), + get_forks(), ) .map(|_| Vec::default()) .map_err(|e| { diff --git a/crates/sovereign-sdk/module-system/sov-modules-rollup-blueprint/src/lib.rs b/crates/sovereign-sdk/module-system/sov-modules-rollup-blueprint/src/lib.rs index 7afb95a02..5f019885c 100644 --- a/crates/sovereign-sdk/module-system/sov-modules-rollup-blueprint/src/lib.rs +++ b/crates/sovereign-sdk/module-system/sov-modules-rollup-blueprint/src/lib.rs @@ -7,7 +7,6 @@ use std::sync::Arc; use async_trait::async_trait; use citrea_common::tasks::manager::TaskManager; use citrea_common::{FullNodeConfig, RollupPublicKeys}; -use derive_more::Display; use sov_db::ledger_db::LedgerDB; use sov_db::rocks_db_config::RocksdbConfig; use sov_modules_api::{Context, DaSpec, Spec}; @@ -17,6 +16,7 @@ use sov_rollup_interface::da::DaVerifier; use sov_rollup_interface::services::da::DaService; use sov_rollup_interface::spec::SpecId; use sov_rollup_interface::zk::{Zkvm, ZkvmHost}; +use sov_rollup_interface::Network; use sov_stf_runner::{ProverGuestRunConfig, ProverService}; use tokio::sync::broadcast; @@ -24,20 +24,6 @@ mod runtime_rpc; pub use runtime_rpc::*; -/// The network currently running. -#[derive(Copy, Clone, Default, Debug, Display)] -pub enum Network { - /// Mainnet - #[default] - Mainnet, - /// Testnet - Testnet, - /// Testnet - Devnet, - /// nightly - Nightly, -} - /// This trait defines how to crate all the necessary dependencies required by a rollup. #[async_trait] pub trait RollupBlueprint: Sized + Send + Sync { diff --git a/crates/sovereign-sdk/rollup-interface/src/fork/mod.rs b/crates/sovereign-sdk/rollup-interface/src/fork/mod.rs index d16d136b3..37035cb4d 100644 --- a/crates/sovereign-sdk/rollup-interface/src/fork/mod.rs +++ b/crates/sovereign-sdk/rollup-interface/src/fork/mod.rs @@ -327,7 +327,7 @@ pub(crate) const fn verify_forks(forks: &[Fork]) -> bool { /// Simple search for the fork to which a specific block number belongs. /// This assumes that the list of forks is sorted by block number in ascending fashion. -pub(crate) fn fork_pos_from_block_number(forks: &[Fork], block_number: u64) -> usize { +pub fn fork_pos_from_block_number(forks: &[Fork], block_number: u64) -> usize { let pos = forks.binary_search_by(|fork| fork.activation_height.cmp(&block_number)); match pos { diff --git a/crates/sovereign-sdk/rollup-interface/src/lib.rs b/crates/sovereign-sdk/rollup-interface/src/lib.rs index b5fde562f..2d5e35369 100644 --- a/crates/sovereign-sdk/rollup-interface/src/lib.rs +++ b/crates/sovereign-sdk/rollup-interface/src/lib.rs @@ -17,6 +17,9 @@ pub const CITREA_VERSION: &str = "v0.5.5"; mod state_machine; pub use state_machine::*; +mod network; +pub use network::*; + mod node; #[cfg(not(target_has_atomic = "ptr"))] diff --git a/crates/sovereign-sdk/rollup-interface/src/network.rs b/crates/sovereign-sdk/rollup-interface/src/network.rs new file mode 100644 index 000000000..39b7a6a44 --- /dev/null +++ b/crates/sovereign-sdk/rollup-interface/src/network.rs @@ -0,0 +1,21 @@ +use std::fmt::Display; + +/// The network currently running. +#[derive(Copy, Clone, Default, Debug)] +pub enum Network { + /// Mainnet + #[default] + Mainnet, + /// Testnet + Testnet, + /// Testnet + Devnet, + /// nightly + Nightly, +} + +impl Display for Network { + fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { + write!(f, "{:?}", self) + } +} From cd894309731b2acea71e27a9ecfed3ea9cd25497 Mon Sep 17 00:00:00 2001 From: yaziciahmet Date: Wed, 18 Dec 2024 13:28:37 +0100 Subject: [PATCH 44/96] Remove forks from config --- bin/citrea/tests/test_helpers/mod.rs | 9 +----- crates/common/src/config.rs | 32 ------------------- .../batch_prover_rollup_config.toml | 4 --- .../light_client_prover_rollup_config.toml | 4 --- .../bitcoin-regtest/rollup_config.toml | 4 --- .../sequencer_rollup_config.toml | 4 --- resources/configs/devnet/rollup_config.toml | 9 ------ .../sequencer_rollup_config.toml | 4 --- resources/configs/mock/rollup_config.toml | 4 --- .../configs/mock/sequencer_rollup_config.toml | 4 --- resources/configs/testnet/rollup_config.toml | 9 ------ 11 files changed, 1 insertion(+), 86 deletions(-) diff --git a/bin/citrea/tests/test_helpers/mod.rs b/bin/citrea/tests/test_helpers/mod.rs index f88b196a9..a47220a6c 100644 --- a/bin/citrea/tests/test_helpers/mod.rs +++ b/bin/citrea/tests/test_helpers/mod.rs @@ -13,8 +13,7 @@ use citrea_primitives::TEST_PRIVATE_KEY; use citrea_stf::genesis_config::GenesisPaths; use sov_mock_da::{MockAddress, MockBlock, MockDaConfig, MockDaService}; use sov_modules_api::default_signature::private_key::DefaultPrivateKey; -use sov_modules_api::fork::{Fork, Forks}; -use sov_modules_api::{PrivateKey, SpecId}; +use sov_modules_api::PrivateKey; use sov_modules_rollup_blueprint::RollupBlueprint as _; use sov_rollup_interface::da::{BlobReaderTrait, DaData, SequencerCommitment}; use sov_rollup_interface::services::da::{DaService, SlotData}; @@ -190,12 +189,6 @@ pub fn create_default_rollup_config( db_path: da_path.to_path_buf(), }, telemetry: Default::default(), - forks: Forks::from_slice(&[ - Fork::new(SpecId::Genesis, 0), - Fork::new(SpecId::Fork1, 1000), - Fork::new(SpecId::Fork2, 2000), - ]) - .unwrap(), } } diff --git a/crates/common/src/config.rs b/crates/common/src/config.rs index 00e759c92..9492bb52b 100644 --- a/crates/common/src/config.rs +++ b/crates/common/src/config.rs @@ -5,7 +5,6 @@ use std::path::{Path, PathBuf}; use citrea_pruning::PruningConfig; use serde::de::DeserializeOwned; use serde::{Deserialize, Serialize}; -use sov_modules_api::fork::Forks; use sov_stf_runner::ProverGuestRunConfig; pub trait FromEnv: Sized { @@ -216,8 +215,6 @@ pub struct FullNodeConfig { /// Telemetry configuration #[serde(default)] pub telemetry: TelemetryConfig, - /// Fork configuration - pub forks: Forks, } impl FromEnv for FullNodeConfig { @@ -229,7 +226,6 @@ impl FromEnv for FullNodeConfig { da: DaC::from_env()?, public_keys: RollupPublicKeys::from_env()?, telemetry: TelemetryConfig::from_env()?, - forks: Forks::from_env()?, }) } } @@ -303,13 +299,6 @@ impl FromEnv for LightClientProverConfig { } } -impl FromEnv for Forks { - fn from_env() -> anyhow::Result { - let forks = std::env::var("FORKS")?; - Forks::from_utf8(&forks).ok_or(anyhow::anyhow!("Invalid FORKS env variable")) - } -} - /// Reads toml file as a specific type. pub fn from_toml_path, R: DeserializeOwned>(path: P) -> anyhow::Result { let mut contents = String::new(); @@ -448,8 +437,6 @@ impl FromEnv for TelemetryConfig { mod tests { use std::io::Write; - use sov_modules_api::fork::Fork; - use sov_modules_api::SpecId; use tempfile::NamedTempFile; use super::*; @@ -491,14 +478,6 @@ mod tests { [telemetry] bind_host = "0.0.0.0" bind_port = 8001 - - [[forks]] - spec_id = "Genesis" - activation_height = 0 - - [[forks]] - spec_id = "Fork1" - activation_height = 1000 "#.to_owned(); let config_file = create_config_from(&config); @@ -540,11 +519,6 @@ mod tests { bind_host: Some("0.0.0.0".to_owned()), bind_port: Some(8001), }, - forks: Forks::from_slice(&[ - Fork::new(SpecId::Genesis, 0), - Fork::new(SpecId::Fork1, 1000), - ]) - .unwrap(), }; assert_eq!(config, expected); } @@ -701,7 +675,6 @@ mod tests { std::env::set_var("TELEMETRY_BIND_HOST", "0.0.0.0"); std::env::set_var("TELEMETRY_BIND_PORT", "8082"); - std::env::set_var("FORKS", "0:0,1:1000"); let full_node_config: FullNodeConfig = FullNodeConfig::from_env().unwrap(); @@ -739,11 +712,6 @@ mod tests { bind_host: Some("0.0.0.0".to_owned()), bind_port: Some(8082), }, - forks: Forks::from_slice(&[ - Fork::new(SpecId::Genesis, 0), - Fork::new(SpecId::Fork1, 1000), - ]) - .unwrap(), }; assert_eq!(full_node_config, expected); } diff --git a/resources/configs/bitcoin-regtest/batch_prover_rollup_config.toml b/resources/configs/bitcoin-regtest/batch_prover_rollup_config.toml index 4af3046ec..3fb9b2619 100644 --- a/resources/configs/bitcoin-regtest/batch_prover_rollup_config.toml +++ b/resources/configs/bitcoin-regtest/batch_prover_rollup_config.toml @@ -28,7 +28,3 @@ enable_subscriptions = false [runner] sequencer_client_url = "http://0.0.0.0:12345" include_tx_body = false - -[[forks]] -spec_id = "Fork1" -activation_height = 0 diff --git a/resources/configs/bitcoin-regtest/light_client_prover_rollup_config.toml b/resources/configs/bitcoin-regtest/light_client_prover_rollup_config.toml index 93a0d7370..2844d258a 100644 --- a/resources/configs/bitcoin-regtest/light_client_prover_rollup_config.toml +++ b/resources/configs/bitcoin-regtest/light_client_prover_rollup_config.toml @@ -27,7 +27,3 @@ enable_subscriptions = false [runner] sequencer_client_url = "http://0.0.0.0:12345" include_tx_body = false - -[[forks]] -spec_id = "Fork1" -activation_height = 0 diff --git a/resources/configs/bitcoin-regtest/rollup_config.toml b/resources/configs/bitcoin-regtest/rollup_config.toml index 2a7258831..b5381546c 100644 --- a/resources/configs/bitcoin-regtest/rollup_config.toml +++ b/resources/configs/bitcoin-regtest/rollup_config.toml @@ -28,7 +28,3 @@ max_subscriptions_per_connection = 100 [runner] sequencer_client_url = "http://0.0.0.0:12345" include_tx_body = false - -[[forks]] -spec_id = "Fork1" -activation_height = 0 diff --git a/resources/configs/bitcoin-regtest/sequencer_rollup_config.toml b/resources/configs/bitcoin-regtest/sequencer_rollup_config.toml index f31b823d9..d327bf6a9 100644 --- a/resources/configs/bitcoin-regtest/sequencer_rollup_config.toml +++ b/resources/configs/bitcoin-regtest/sequencer_rollup_config.toml @@ -25,7 +25,3 @@ bind_host = "127.0.0.1" bind_port = 12345 enable_subscriptions = true max_subscriptions_per_connection = 100 - -[[forks]] -spec_id = "Fork1" -activation_height = 0 diff --git a/resources/configs/devnet/rollup_config.toml b/resources/configs/devnet/rollup_config.toml index a31e3fac1..59415479f 100644 --- a/resources/configs/devnet/rollup_config.toml +++ b/resources/configs/devnet/rollup_config.toml @@ -28,12 +28,3 @@ max_subscriptions_per_connection = 100 sequencer_client_url = "https://rpc.devnet.citrea.xyz" # set this to true if you want to include soft confirmation tx bodies include_tx_body = false - -[[forks]] -spec_id = "Genesis" -activation_height = 0 - -[[forks]] -spec_id = "Fork1" -# TODO: set this properly -activation_height = 999999999 diff --git a/resources/configs/mock-dockerized/sequencer_rollup_config.toml b/resources/configs/mock-dockerized/sequencer_rollup_config.toml index 787992e25..94762cb30 100644 --- a/resources/configs/mock-dockerized/sequencer_rollup_config.toml +++ b/resources/configs/mock-dockerized/sequencer_rollup_config.toml @@ -19,7 +19,3 @@ bind_port = 8545 max_connections = 10000 enable_subscriptions = true max_subscriptions_per_connection = 100 - -[[forks]] -spec_id = "Fork1" -activation_height = 0 diff --git a/resources/configs/mock/rollup_config.toml b/resources/configs/mock/rollup_config.toml index f979c0ca8..a19c13be2 100644 --- a/resources/configs/mock/rollup_config.toml +++ b/resources/configs/mock/rollup_config.toml @@ -23,7 +23,3 @@ max_subscriptions_per_connection = 100 include_tx_body = false sequencer_client_url = "http://0.0.0.0:12345" # pruning_config.distance = 10 - -[[forks]] -spec_id = "Fork1" -activation_height = 0 diff --git a/resources/configs/mock/sequencer_rollup_config.toml b/resources/configs/mock/sequencer_rollup_config.toml index 9ff3ff096..4f293dcdc 100644 --- a/resources/configs/mock/sequencer_rollup_config.toml +++ b/resources/configs/mock/sequencer_rollup_config.toml @@ -19,7 +19,3 @@ bind_port = 12345 max_connections = 10000 enable_subscriptions = true max_subscriptions_per_connection = 100 - -[[forks]] -spec_id = "Fork1" -activation_height = 0 diff --git a/resources/configs/testnet/rollup_config.toml b/resources/configs/testnet/rollup_config.toml index 44cf6fb46..78000ec18 100644 --- a/resources/configs/testnet/rollup_config.toml +++ b/resources/configs/testnet/rollup_config.toml @@ -61,12 +61,3 @@ include_tx_body = false # this value should be at most equal to `batch_requests_limit` set by the RPC node # being used. # sync_blocks_count = 20 - -[[forks]] -spec_id = "Genesis" -activation_height = 0 - -[[forks]] -spec_id = "Fork1" -# TODO: set this properly -activation_height = 999999999 From f49bf5715ff100f7aa5fbdca1a6b1d484e0cba1b Mon Sep 17 00:00:00 2001 From: yaziciahmet Date: Wed, 18 Dec 2024 14:50:19 +0100 Subject: [PATCH 45/96] Set everything from CITREA_NETWORK env --- crates/primitives/src/forks.rs | 8 +-- .../rollup-interface/src/network.rs | 35 ++++++++++ .../src/bin/batch_proof_bitcoin.rs | 68 ++++++++++++------- .../src/bin/batch_proof_mock.rs | 45 +++--------- .../src/bin/light_client_proof_bitcoin.rs | 57 +++++++++++++--- .../src/bin/light_client_proof_mock.rs | 37 +++------- 6 files changed, 151 insertions(+), 99 deletions(-) diff --git a/crates/primitives/src/forks.rs b/crates/primitives/src/forks.rs index 777768506..f352db669 100644 --- a/crates/primitives/src/forks.rs +++ b/crates/primitives/src/forks.rs @@ -45,19 +45,19 @@ pub fn fork_from_block_number(block_number: u64) -> Fork { forks[pos] } -const MAINNET_FORKS: [Fork; 1] = [Fork::new(SpecId::Fork1, 0)]; +pub const MAINNET_FORKS: [Fork; 1] = [Fork::new(SpecId::Fork1, 0)]; -const TESTNET_FORKS: [Fork; 2] = [ +pub const TESTNET_FORKS: [Fork; 2] = [ Fork::new(SpecId::Genesis, 0), Fork::new(SpecId::Fork1, 999_999_999), ]; -const DEVNET_FORKS: [Fork; 2] = [ +pub const DEVNET_FORKS: [Fork; 2] = [ Fork::new(SpecId::Genesis, 0), Fork::new(SpecId::Fork1, 999_999_999), ]; -const NIGHTLY_FORKS: [Fork; 1] = [Fork::new(SpecId::Fork1, 0)]; +pub const NIGHTLY_FORKS: [Fork; 1] = [Fork::new(SpecId::Fork1, 0)]; #[cfg(feature = "testing")] const TESTING_FORKS: [Fork; 3] = [ diff --git a/crates/sovereign-sdk/rollup-interface/src/network.rs b/crates/sovereign-sdk/rollup-interface/src/network.rs index 39b7a6a44..060b21ae1 100644 --- a/crates/sovereign-sdk/rollup-interface/src/network.rs +++ b/crates/sovereign-sdk/rollup-interface/src/network.rs @@ -19,3 +19,38 @@ impl Display for Network { write!(f, "{:?}", self) } } + +impl Network { + /// Constant function to get the Network from &str + pub const fn const_from_str(s: &str) -> Option { + const fn const_compare_str(s1: &str, s2: &str) -> bool { + let b1 = s1.as_bytes(); + let b2 = s2.as_bytes(); + if b1.len() != b2.len() { + return false; + } + + let mut i = 0; + while i < b1.len() { + if b1[i] != b2[i] { + return false; + } + i += 1; + } + + true + } + + if const_compare_str(s, "mainnet") { + Some(Network::Mainnet) + } else if const_compare_str(s, "testnet") { + Some(Network::Testnet) + } else if const_compare_str(s, "devnet") { + Some(Network::Devnet) + } else if const_compare_str(s, "nightly") { + Some(Network::Nightly) + } else { + None + } + } +} diff --git a/guests/risc0/batch-proof-bitcoin/src/bin/batch_proof_bitcoin.rs b/guests/risc0/batch-proof-bitcoin/src/bin/batch_proof_bitcoin.rs index b9b708cbe..d3aa23bad 100644 --- a/guests/risc0/batch-proof-bitcoin/src/bin/batch_proof_bitcoin.rs +++ b/guests/risc0/batch-proof-bitcoin/src/bin/batch_proof_bitcoin.rs @@ -1,21 +1,45 @@ #![no_main] + use bitcoin_da::spec::RollupParams; use bitcoin_da::verifier::BitcoinVerifier; +use citrea_primitives::forks::{DEVNET_FORKS, MAINNET_FORKS, NIGHTLY_FORKS, TESTNET_FORKS}; use citrea_primitives::{TO_BATCH_PROOF_PREFIX, TO_LIGHT_CLIENT_PREFIX}; use citrea_risc0_adapter::guest::Risc0Guest; use citrea_stf::runtime::Runtime; use citrea_stf::StfVerifier; use sov_modules_api::default_context::ZkDefaultContext; -use sov_modules_api::fork::{Fork, Forks}; +use sov_modules_api::fork::Fork; use sov_modules_stf_blueprint::StfBlueprint; use sov_rollup_interface::da::DaVerifier; use sov_rollup_interface::zk::ZkvmGuest; +use sov_rollup_interface::Network; use sov_state::ZkStorage; risc0_zkvm::guest::entry!(main); +const NETWORK: Network = match option_env!("CITREA_NETWORK") { + Some(network) => { + match Network::const_from_str(network) { + Some(network) => network, + None => panic!("Invalid CITREA_NETWORK value"), + } + } + None => Network::Nightly, +}; + const SEQUENCER_PUBLIC_KEY: [u8; 32] = { - let hex_pub_key = env!("SEQUENCER_PUBLIC_KEY"); + let hex_pub_key = match NETWORK { + // TODO: Update Mainnet public key when decided + Network::Mainnet => "4682a70af1d3fae53a5a26b682e2e75f7a1de21ad5fc8d61794ca889880d39d1", + Network::Testnet => "4682a70af1d3fae53a5a26b682e2e75f7a1de21ad5fc8d61794ca889880d39d1", + Network::Devnet => "52f41a5076498d1ae8bdfa57d19e91e3c2c94b6de21985d099cd48cfa7aef174", + Network::Nightly => { + match option_env!("SEQUENCER_PUBLIC_KEY") { + Some(hex_pub_key) => hex_pub_key, + None => "204040e364c10f2bec9c1fe500a1cd4c247c89d650a01ed7e82caba867877c21", + } + } + }; match const_hex::const_decode_to_array(hex_pub_key.as_bytes()) { Ok(pub_key) => pub_key, @@ -24,36 +48,32 @@ const SEQUENCER_PUBLIC_KEY: [u8; 32] = { }; const SEQUENCER_DA_PUBLIC_KEY: [u8; 33] = { - let hex_pub_key = env!("SEQUENCER_DA_PUBLIC_KEY"); + let hex_pub_key = match NETWORK { + // TODO: Update Mainnet public key when decided + Network::Mainnet => "03015a7c4d2cc1c771198686e2ebef6fe7004f4136d61f6225b061d1bb9b821b9b", + Network::Testnet => "03015a7c4d2cc1c771198686e2ebef6fe7004f4136d61f6225b061d1bb9b821b9b", + Network::Devnet => "039cd55f9b3dcf306c4d54f66cd7c4b27cc788632cd6fb73d80c99d303c6536486", + Network::Nightly => { + match option_env!("SEQUENCER_DA_PUBLIC_KEY") { + Some(hex_pub_key) => hex_pub_key, + None => "02588d202afcc1ee4ab5254c7847ec25b9a135bbda0f2bc69ee1a714749fd77dc9", + } + } + }; match const_hex::const_decode_to_array(hex_pub_key.as_bytes()) { - // TODO: maybe verify the first byte? - Ok(pub_key) => { - if pub_key[0] != 2 && pub_key[0] != 3 { - panic!("SEQUENCER_DA_PUBLIC_KEY first byte must be either 02 or 03"); - } - pub_key - }, + Ok(pub_key) => pub_key, Err(_) => panic!("SEQUENCER_DA_PUBLIC_KEY must be valid 33-byte hex string"), } }; -// Temporary variable to allow FORKS static reference to be valid -const TEMP_FORKS: Forks = { - let forks_str = env!("FORKS"); - - match Forks::from_utf8(forks_str) { - Some(forks) => { - if forks.inner().len() == 0 { - } - forks - } - None => panic!("FORKS must be valid comma separated list"), - } +const FORKS: &[Fork] = match NETWORK { + Network::Mainnet => &MAINNET_FORKS, + Network::Testnet => &TESTNET_FORKS, + Network::Devnet => &DEVNET_FORKS, + Network::Nightly => &NIGHTLY_FORKS, }; -const FORKS: &[Fork] = TEMP_FORKS.inner(); - pub fn main() { let guest = Risc0Guest::new(); let storage = ZkStorage::new(); diff --git a/guests/risc0/batch-proof-mock/src/bin/batch_proof_mock.rs b/guests/risc0/batch-proof-mock/src/bin/batch_proof_mock.rs index dfbf539d9..7e0609a51 100644 --- a/guests/risc0/batch-proof-mock/src/bin/batch_proof_mock.rs +++ b/guests/risc0/batch-proof-mock/src/bin/batch_proof_mock.rs @@ -1,9 +1,10 @@ #![no_main] +use citrea_primitives::forks::NIGHTLY_FORKS; use citrea_stf::runtime::Runtime; use citrea_stf::StfVerifier; use sov_mock_da::MockDaVerifier; use sov_modules_api::default_context::ZkDefaultContext; -use sov_modules_api::fork::{Fork, Forks}; +use sov_modules_api::fork::Fork; use sov_modules_stf_blueprint::StfBlueprint; use citrea_risc0_adapter::guest::Risc0Guest; use sov_state::ZkStorage; @@ -11,45 +12,17 @@ use sov_rollup_interface::zk::ZkvmGuest; risc0_zkvm::guest::entry!(main); -const SEQUENCER_PUBLIC_KEY: [u8; 32] = { - let hex_pub_key = env!("SEQUENCER_PUBLIC_KEY"); - - match const_hex::const_decode_to_array(hex_pub_key.as_bytes()) { - Ok(pub_key) => pub_key, - Err(_) => panic!("SEQUENCER_PUBLIC_KEY must be valid 32-byte hex string"), - } +const SEQUENCER_PUBLIC_KEY: [u8; 32] = match const_hex::const_decode_to_array(b"204040e364c10f2bec9c1fe500a1cd4c247c89d650a01ed7e82caba867877c21") { + Ok(pub_key) => pub_key, + Err(_) => panic!("Can't happen"), }; -const SEQUENCER_DA_PUBLIC_KEY: [u8; 33] = { - let hex_pub_key = env!("SEQUENCER_DA_PUBLIC_KEY"); - - match const_hex::const_decode_to_array(hex_pub_key.as_bytes()) { - // TODO: maybe verify the first byte? - Ok(pub_key) => { - if pub_key[0] != 2 && pub_key[0] != 3 { - panic!("SEQUENCER_DA_PUBLIC_KEY first byte must be either 02 or 03"); - } - pub_key - } - Err(_) => panic!("SEQUENCER_DA_PUBLIC_KEY must be valid 33-byte hex string"), - } -}; - -// Temporary variable to allow FORKS static reference to be valid -const TEMP_FORKS: Forks = { - let forks_str = env!("FORKS"); - - match Forks::from_utf8(forks_str) { - Some(forks) => { - if forks.inner().len() == 0 { - } - forks - } - None => panic!("FORKS must be valid comma separated list"), - } +const SEQUENCER_DA_PUBLIC_KEY: [u8; 33] = match const_hex::const_decode_to_array(b"02588d202afcc1ee4ab5254c7847ec25b9a135bbda0f2bc69ee1a714749fd77dc9") { + Ok(pub_key) => pub_key, + Err(_) => panic!("Can't happen"), }; -const FORKS: &[Fork] = TEMP_FORKS.inner(); +const FORKS: &[Fork] = &NIGHTLY_FORKS; pub fn main() { let guest = Risc0Guest::new(); diff --git a/guests/risc0/light-client-proof-bitcoin/src/bin/light_client_proof_bitcoin.rs b/guests/risc0/light-client-proof-bitcoin/src/bin/light_client_proof_bitcoin.rs index e6697337f..79e2f6285 100644 --- a/guests/risc0/light-client-proof-bitcoin/src/bin/light_client_proof_bitcoin.rs +++ b/guests/risc0/light-client-proof-bitcoin/src/bin/light_client_proof_bitcoin.rs @@ -6,11 +6,33 @@ use citrea_primitives::{TO_BATCH_PROOF_PREFIX, TO_LIGHT_CLIENT_PREFIX}; use citrea_risc0_adapter::guest::Risc0Guest; use sov_rollup_interface::da::DaVerifier; use sov_rollup_interface::zk::ZkvmGuest; +use sov_rollup_interface::Network; risc0_zkvm::guest::entry!(main); +const NETWORK: Network = match option_env!("CITREA_NETWORK") { + Some(network) => { + match Network::const_from_str(network) { + Some(network) => network, + None => panic!("Invalid CITREA_NETWORK value"), + } + } + None => Network::Nightly, +}; + +// TODO: Find l2 genesis roots of networks const L2_GENESIS_ROOT: [u8; 32] = { - let hex_root = env!("L2_GENESIS_ROOT"); + let hex_root = match NETWORK { + Network::Mainnet => "0000000000000000000000000000000000000000000000000000000000000000", + Network::Testnet => "0000000000000000000000000000000000000000000000000000000000000000", + Network::Devnet => "0000000000000000000000000000000000000000000000000000000000000000", + Network::Nightly => { + match option_env!("L2_GENESIS_ROOT") { + Some(hex_root) => hex_root, + None => "0000000000000000000000000000000000000000000000000000000000000000", + } + } + }; match const_hex::const_decode_to_array(hex_root.as_bytes()) { Ok(root) => root, @@ -18,8 +40,19 @@ const L2_GENESIS_ROOT: [u8; 32] = { } }; +// TODO: Find batch proof method ids of networks const BATCH_PROOF_METHOD_ID: [u32; 8] = { - let hex_method_id = env!("BATCH_PROOF_METHOD_ID"); + let hex_method_id = match NETWORK { + Network::Mainnet => "0000000000000000000000000000000000000000000000000000000000000000", + Network::Testnet => "0000000000000000000000000000000000000000000000000000000000000000", + Network::Devnet => "0000000000000000000000000000000000000000000000000000000000000000", + Network::Nightly => { + match option_env!("BATCH_PROOF_METHOD_ID") { + Some(hex_root) => hex_root, + None => "0000000000000000000000000000000000000000000000000000000000000000", + } + } + }; match const_hex::const_decode_to_array::<32>(hex_method_id.as_bytes()) { Ok(method_id) => constmuck::cast(method_id), @@ -28,15 +61,21 @@ const BATCH_PROOF_METHOD_ID: [u32; 8] = { }; const BATCH_PROVER_DA_PUBLIC_KEY: [u8; 33] = { - let hex_pub_key = env!("BATCH_PROVER_DA_PUBLIC_KEY"); - - match const_hex::const_decode_to_array(hex_pub_key.as_bytes()) { - Ok(pub_key) => { - if pub_key[0] != 2 && pub_key[0] != 3 { - panic!("BATCH_PROVER_DA_PUBLIC_KEY first byte must be either 02 or 03"); + let hex_pub_key = match NETWORK { + // TODO: Update mainnet pub key + Network::Mainnet => "0357d255ab93638a2d880787ebaadfefdfc9bb51a26b4a37e5d588e04e54c60a42", + Network::Testnet => "0357d255ab93638a2d880787ebaadfefdfc9bb51a26b4a37e5d588e04e54c60a42", + Network::Devnet => "03fc6fb2ef68368009c895d2d4351dcca4109ec2f5f327291a0553570ce769f5e5", + Network::Nightly => { + match option_env!("BATCH_PROVER_DA_PUBLIC_KEY") { + Some(hex_pub_key) => hex_pub_key, + None => "03eedab888e45f3bdc3ec9918c491c11e5cf7af0a91f38b97fbc1e135ae4056601", } - pub_key } + }; + + match const_hex::const_decode_to_array(hex_pub_key.as_bytes()) { + Ok(pub_key) => pub_key, Err(_) => panic!("BATCH_PROVER_DA_PUBLIC_KEY must be valid 33-byte hex string"), } }; diff --git a/guests/risc0/light-client-proof-mock/src/bin/light_client_proof_mock.rs b/guests/risc0/light-client-proof-mock/src/bin/light_client_proof_mock.rs index 64068b89b..b87667798 100644 --- a/guests/risc0/light-client-proof-mock/src/bin/light_client_proof_mock.rs +++ b/guests/risc0/light-client-proof-mock/src/bin/light_client_proof_mock.rs @@ -6,36 +6,21 @@ use sov_rollup_interface::zk::ZkvmGuest; risc0_zkvm::guest::entry!(main); -const L2_GENESIS_ROOT: [u8; 32] = { - let hex_root = env!("L2_GENESIS_ROOT"); - - match const_hex::const_decode_to_array(hex_root.as_bytes()) { - Ok(root) => root, - Err(_) => panic!("L2_GENESIS_ROOT must be valid 32-byte hex string"), - } +// TODO: Find l2 genesis root of nightly +const L2_GENESIS_ROOT: [u8; 32] = match const_hex::const_decode_to_array(b"0000000000000000000000000000000000000000000000000000000000000000") { + Ok(root) => root, + Err(_) => panic!("Can't happen"), }; -const BATCH_PROOF_METHOD_ID: [u32; 8] = { - let hex_method_id = env!("BATCH_PROOF_METHOD_ID"); - - match const_hex::const_decode_to_array::<32>(hex_method_id.as_bytes()) { - Ok(method_id) => constmuck::cast(method_id), - Err(_) => panic!("BATCH_PROOF_METHOD_ID must be valid 32-byte hex string"), - } +// TODO: Find batch proof method ids of networks +const BATCH_PROOF_METHOD_ID: [u32; 8] = match const_hex::const_decode_to_array::<32>(b"0000000000000000000000000000000000000000000000000000000000000000") { + Ok(method_id) => constmuck::cast(method_id), + Err(_) => panic!("Can't happen"), }; -const BATCH_PROVER_DA_PUBLIC_KEY: [u8; 33] = { - let hex_pub_key = env!("BATCH_PROVER_DA_PUBLIC_KEY"); - - match const_hex::const_decode_to_array(hex_pub_key.as_bytes()) { - Ok(pub_key) => { - if pub_key[0] != 2 && pub_key[0] != 3 { - panic!("BATCH_PROVER_DA_PUBLIC_KEY first byte must be either 02 or 03"); - } - pub_key - } - Err(_) => panic!("BATCH_PROVER_DA_PUBLIC_KEY must be valid 33-byte hex string"), - } +const BATCH_PROVER_DA_PUBLIC_KEY: [u8; 33] = match const_hex::const_decode_to_array(b"03eedab888e45f3bdc3ec9918c491c11e5cf7af0a91f38b97fbc1e135ae4056601") { + Ok(pub_key) => pub_key, + Err(_) => panic!("Can't happen"), }; pub fn main() { From 539bcee862a5b9cb98456f31f33f42a5d95e5436 Mon Sep 17 00:00:00 2001 From: yaziciahmet Date: Wed, 18 Dec 2024 14:55:53 +0100 Subject: [PATCH 46/96] Remove unused Forks --- .../rollup-interface/src/fork/mod.rs | 257 +----------------- .../rollup-interface/src/fork/tests.rs | 62 +---- 2 files changed, 2 insertions(+), 317 deletions(-) diff --git a/crates/sovereign-sdk/rollup-interface/src/fork/mod.rs b/crates/sovereign-sdk/rollup-interface/src/fork/mod.rs index 37035cb4d..19a6a2c4b 100644 --- a/crates/sovereign-sdk/rollup-interface/src/fork/mod.rs +++ b/crates/sovereign-sdk/rollup-interface/src/fork/mod.rs @@ -7,153 +7,10 @@ mod tests; pub use manager::*; pub use migration::*; -use serde::ser::SerializeSeq; -use serde::{de, Deserialize, Deserializer, Serialize, Serializer}; +use serde::{Deserialize, Serialize}; use crate::spec::SpecId; -/// Forks is a helper struct fork managing list of forks. -#[derive(Debug, Clone, Copy, PartialEq)] -pub struct Forks { - forks: [Fork; 50], - count: usize, -} - -impl Forks { - /// Parse fork list from utf8 string. Format should be `{spec_id as u8}:{activation_height},{spec_id2 as u8}:{activation_height2}`. - /// Since this is a constant fn, it returns a stack allocated array with 50 const size, and a second return value as the count - /// of valid forks within this array - /// - /// Example: - /// ``` - /// use sov_rollup_interface::fork::{Fork, Forks}; - /// const FORKS: Option = Forks::from_utf8("0:1000,1:5000,2:100000"); - /// - /// fn main() { - /// let forks: &[Fork] = match &FORKS { - /// Some(forks) => forks.inner(), - /// None => &[], - /// }; - /// } - /// ``` - pub const fn from_utf8(forks_str: &str) -> Option { - if forks_str.is_empty() { - return None; - } - - let mut forks = [Fork::new(SpecId::Genesis, 0); 50]; - let mut count = 0; - - let mut bytes = forks_str.as_bytes(); - let mut i = 0; - while i < bytes.len() { - if bytes[i] != b',' { - i += 1; - continue; - } - - let (fork_utf8, remaining_bytes) = bytes.split_at(i); - - let Some(fork) = Fork::from_colon_separated_utf8(fork_utf8) else { - return None; - }; - - // Ignore comma - let Some((_, remaining_bytes)) = remaining_bytes.split_first() else { - return None; - }; - bytes = remaining_bytes; - - forks[count] = fork; - count += 1; - - i = 0; - } - - // Add the last one - let Some(fork) = Fork::from_colon_separated_utf8(bytes) else { - return None; - }; - forks[count] = fork; - count += 1; - - if !verify_forks(forks.split_at(count).0) { - return None; - } - - Some(Self { forks, count }) - } - - pub fn from_slice(slice: &[Fork]) -> Option { - if slice.len() > 50 { - panic!("Never gonna have 50 forks..."); - } - - if !verify_forks(slice) { - return None; - } - - let mut forks = [Fork::default(); 50]; - forks[0..slice.len()].copy_from_slice(slice); - - Some(Self { - forks, - count: slice.len(), - }) - } - - pub const fn inner(&self) -> &[Fork] { - self.forks.split_at(self.count).0 - } - - pub fn fork_from_block_number(&self, block_number: u64) -> Fork { - let inner = self.inner(); - let pos = fork_pos_from_block_number(inner, block_number); - inner[pos] - } -} - -impl Serialize for Forks { - fn serialize(&self, serializer: S) -> Result - where - S: Serializer, - { - let inner = self.inner(); - let mut seq = serializer.serialize_seq(Some(inner.len()))?; - for fork in inner { - seq.serialize_element(fork)?; - } - seq.end() - } -} - -impl<'de> Deserialize<'de> for Forks { - fn deserialize(deserializer: D) -> Result - where - D: Deserializer<'de>, - { - // Deserialize a vector of forks - let forks_vec: Vec = Vec::deserialize(deserializer)?; - - if forks_vec.len() > 50 { - return Err(de::Error::custom("Too many forks (max 50 allowed)")); - } - - if !verify_forks(&forks_vec) { - return Err(de::Error::custom("Forks are not ordered correctly")); - } - - // Initialize the fixed-size array and count - let mut forks = [Fork::default(); 50]; - let count = forks_vec.len(); - - // Copy the deserialized forks into the fixed array - forks[..count].copy_from_slice(&forks_vec); - - Ok(Forks { forks, count }) - } -} - /// Fork is a wrapper struct that contains spec id and it's activation height #[derive(Debug, Clone, Copy, Deserialize, Serialize)] pub struct Fork { @@ -186,118 +43,6 @@ impl Fork { activation_height, } } - - /// Parses `Fork` from colon separated bytes. - /// Required format is `{spec_id as u8}:{activation_height}`. - /// - /// Example: - /// ``` - /// use sov_rollup_interface::fork::Fork; - /// const FORK: Option = Fork::from_colon_separated_utf8(b"0:1000"); - /// ``` - pub const fn from_colon_separated_utf8(bytes: &[u8]) -> Option { - pub const fn is_digit(v: u8) -> bool { - v >= b'0' && v <= b'9' - } - - // Find the index of colon - let mut i = 0; - let colon_idx = loop { - if i == bytes.len() { - return None; - } - if bytes[i] == b':' { - break i; - } - i += 1; - }; - - let (spec_id_bytes, height_bytes) = bytes.split_at(colon_idx); - // Ignore colon - let Some((_, height_bytes)) = height_bytes.split_first() else { - return None; - }; - - if spec_id_bytes.is_empty() || height_bytes.is_empty() { - return None; - } - - // If multiple digits, first digit should not be 0 - if (spec_id_bytes.len() > 1 && spec_id_bytes[0] == b'0') - || (height_bytes.len() > 1 && height_bytes[0] == b'0') - { - return None; - } - - // Largest u8 is 3 digits, largest u64 is 20 digits - if spec_id_bytes.len() > 3 || height_bytes.len() > 20 { - return None; - } - - // Parse spec_id - let mut i = 0; - let mut spec_id: u8 = 0; - while i < spec_id_bytes.len() { - if !is_digit(spec_id_bytes[i]) { - return None; - } - - let digit = spec_id_bytes[i] - b'0'; - let exp = spec_id_bytes.len() - i - 1; - - let Some(multiplier) = 10u8.checked_pow(exp as u32) else { - return None; - }; - let Some(to_add) = digit.checked_mul(multiplier) else { - return None; - }; - - if let Some(new_spec_id) = spec_id.checked_add(to_add) { - spec_id = new_spec_id; - } else { - return None; - } - - i += 1; - } - - let Some(spec_id) = SpecId::from_u8(spec_id) else { - return None; - }; - - // Parse activation_height - let mut i = 0; - let mut height: u64 = 0; - while i < height_bytes.len() { - if !is_digit(height_bytes[i]) { - return None; - } - - let digit = (height_bytes[i] - b'0') as u64; - let exp = height_bytes.len() - i - 1; - - let Some(multiplier) = 10u64.checked_pow(exp as u32) else { - return None; - }; - - let Some(to_add) = digit.checked_mul(multiplier) else { - return None; - }; - - if let Some(new_height) = height.checked_add(to_add) { - height = new_height; - } else { - return None; - } - - i += 1; - } - - Some(Fork { - spec_id, - activation_height: height, - }) - } } /// Verifies the order of forks. diff --git a/crates/sovereign-sdk/rollup-interface/src/fork/tests.rs b/crates/sovereign-sdk/rollup-interface/src/fork/tests.rs index b9420687e..1b2b687f2 100644 --- a/crates/sovereign-sdk/rollup-interface/src/fork/tests.rs +++ b/crates/sovereign-sdk/rollup-interface/src/fork/tests.rs @@ -1,6 +1,6 @@ use anyhow::anyhow; -use super::{ForkManager, Forks}; +use super::ForkManager; use crate::fork::{fork_pos_from_block_number, Fork, ForkMigration}; use crate::spec::SpecId; @@ -62,63 +62,3 @@ fn test_fork_manager_callbacks() { assert_eq!(msg.to_string(), "Called"); } } - -#[test] -fn test_fork_parse_utf8() { - let max64 = u64::MAX.to_string(); - let max64plusone = ((u64::MAX as u128) + 1).to_string(); - - assert_fork_parse_utf8(b"0:0", 0, 0); - assert_fork_parse_utf8(b"1:1000", 1, 1000); - assert_fork_parse_utf8(b"1:1", 1, 1); - assert_fork_parse_utf8(b"2:1234567890", 2, 1234567890); - assert_fork_parse_utf8(b"0:110", 0, 110); - assert_fork_parse_utf8(format!("1:{}", max64).as_bytes(), 1, u64::MAX); - - assert!(Fork::from_colon_separated_utf8(b"").is_none()); - assert!(Fork::from_colon_separated_utf8(b":").is_none()); - assert!(Fork::from_colon_separated_utf8(b":123").is_none()); - assert!(Fork::from_colon_separated_utf8(b"1:").is_none()); - assert!(Fork::from_colon_separated_utf8(b"01:123").is_none()); - assert!(Fork::from_colon_separated_utf8(b"1:01234").is_none()); - assert!(Fork::from_colon_separated_utf8(b"256:123").is_none()); - assert!(Fork::from_colon_separated_utf8(b"5:123").is_none()); - assert!(Fork::from_colon_separated_utf8(b"ab:cd").is_none()); - assert!(Fork::from_colon_separated_utf8(b"1:123a").is_none()); - assert!(Fork::from_colon_separated_utf8(b"12345").is_none()); - assert!(Fork::from_colon_separated_utf8(format!("1:{}", max64plusone).as_bytes()).is_none()); -} - -fn assert_fork_parse_utf8(bytes: &[u8], exp_spec: u8, exp_height: u64) { - let fork = Fork::from_colon_separated_utf8(bytes).unwrap(); - assert_eq!(fork.spec_id, SpecId::from_u8(exp_spec).unwrap()); - assert_eq!(fork.activation_height, exp_height); -} - -#[test] -fn test_fork_parse_list() { - assert_fork_parse_list("0:0", &[(0, 0)]); - assert_fork_parse_list("0:0,1:456", &[(0, 0), (1, 456)]); - assert_fork_parse_list("0:0,1:1,2:2", &[(0, 0), (1, 1), (2, 2)]); - assert_fork_parse_list("1:0,2:123", &[(1, 0), (2, 123)]); - - assert!(Forks::from_utf8("").is_none()); - assert!(Forks::from_utf8("0123").is_none()); - assert!(Forks::from_utf8("01:123").is_none()); - assert!(Forks::from_utf8("0:123,1:456").is_none()); - assert!(Forks::from_utf8("0:0 1:456").is_none()); - assert!(Forks::from_utf8("0:0,1:456,").is_none()); - assert!(Forks::from_utf8("0:0,2:456,1:789").is_none()); - assert!(Forks::from_utf8("0:0,1:456,2:123").is_none()); -} - -fn assert_fork_parse_list(s: &str, exp_list: &[(u8, u64)]) { - let forks = Forks::from_utf8(s).unwrap(); - let forks = forks.inner(); - assert_eq!(forks.len(), exp_list.len()); - - for (fork, exp_fork) in forks.iter().zip(exp_list) { - assert_eq!(fork.spec_id as u8, exp_fork.0); - assert_eq!(fork.activation_height, exp_fork.1); - } -} From 8bfd76d8c8e5c5b4d717f28248df2d49239b9e7a Mon Sep 17 00:00:00 2001 From: yaziciahmet Date: Wed, 18 Dec 2024 15:01:08 +0100 Subject: [PATCH 47/96] Check fork ordering in compile time --- crates/primitives/src/forks.rs | 17 ++++++++++++++++- .../rollup-interface/src/fork/mod.rs | 2 +- 2 files changed, 17 insertions(+), 2 deletions(-) diff --git a/crates/primitives/src/forks.rs b/crates/primitives/src/forks.rs index f352db669..45469ff96 100644 --- a/crates/primitives/src/forks.rs +++ b/crates/primitives/src/forks.rs @@ -1,6 +1,6 @@ use std::sync::OnceLock; -use sov_rollup_interface::fork::{fork_pos_from_block_number, Fork}; +use sov_rollup_interface::fork::{fork_pos_from_block_number, verify_forks, Fork}; use sov_rollup_interface::spec::SpecId; use sov_rollup_interface::Network; @@ -74,3 +74,18 @@ const TESTING_FORKS: [Fork; 3] = [ activation_height: 2000, }, ]; + +const _CHECK_FORKS: () = { + if !verify_forks(&MAINNET_FORKS) + || !verify_forks(&TESTNET_FORKS) + || !verify_forks(&DEVNET_FORKS) + || !verify_forks(&NIGHTLY_FORKS) + { + panic!("FORKS order is invalid") + } + + #[cfg(feature = "testing")] + if !verify_forks(&TESTING_FORKS) { + panic!("FORKS order is invalid") + } +}; diff --git a/crates/sovereign-sdk/rollup-interface/src/fork/mod.rs b/crates/sovereign-sdk/rollup-interface/src/fork/mod.rs index 19a6a2c4b..f352bb943 100644 --- a/crates/sovereign-sdk/rollup-interface/src/fork/mod.rs +++ b/crates/sovereign-sdk/rollup-interface/src/fork/mod.rs @@ -46,7 +46,7 @@ impl Fork { } /// Verifies the order of forks. -pub(crate) const fn verify_forks(forks: &[Fork]) -> bool { +pub const fn verify_forks(forks: &[Fork]) -> bool { let mut i = 0; while i < forks.len() { let fork = forks[i]; From fdae8e18148e3421f73c50ca44124aeb339c9656 Mon Sep 17 00:00:00 2001 From: yaziciahmet Date: Wed, 18 Dec 2024 15:16:00 +0100 Subject: [PATCH 48/96] Remove serde from Fork --- crates/sovereign-sdk/rollup-interface/src/fork/mod.rs | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/crates/sovereign-sdk/rollup-interface/src/fork/mod.rs b/crates/sovereign-sdk/rollup-interface/src/fork/mod.rs index f352bb943..c7e03fb9b 100644 --- a/crates/sovereign-sdk/rollup-interface/src/fork/mod.rs +++ b/crates/sovereign-sdk/rollup-interface/src/fork/mod.rs @@ -7,12 +7,11 @@ mod tests; pub use manager::*; pub use migration::*; -use serde::{Deserialize, Serialize}; use crate::spec::SpecId; /// Fork is a wrapper struct that contains spec id and it's activation height -#[derive(Debug, Clone, Copy, Deserialize, Serialize)] +#[derive(Debug, Clone, Copy)] pub struct Fork { /// Spec id for this fork pub spec_id: SpecId, From d755d0ac091cdd170402df10e9b49f4b8ce6e90d Mon Sep 17 00:00:00 2001 From: yaziciahmet Date: Wed, 18 Dec 2024 15:16:28 +0100 Subject: [PATCH 49/96] Newline --- guests/risc0/batch-proof-bitcoin/src/bin/batch_proof_bitcoin.rs | 1 - 1 file changed, 1 deletion(-) diff --git a/guests/risc0/batch-proof-bitcoin/src/bin/batch_proof_bitcoin.rs b/guests/risc0/batch-proof-bitcoin/src/bin/batch_proof_bitcoin.rs index d3aa23bad..b8cc3151a 100644 --- a/guests/risc0/batch-proof-bitcoin/src/bin/batch_proof_bitcoin.rs +++ b/guests/risc0/batch-proof-bitcoin/src/bin/batch_proof_bitcoin.rs @@ -1,5 +1,4 @@ #![no_main] - use bitcoin_da::spec::RollupParams; use bitcoin_da::verifier::BitcoinVerifier; use citrea_primitives::forks::{DEVNET_FORKS, MAINNET_FORKS, NIGHTLY_FORKS, TESTNET_FORKS}; From ded46595a286989694215b8ce025852b12ac4d74 Mon Sep 17 00:00:00 2001 From: yaziciahmet Date: Wed, 18 Dec 2024 15:26:08 +0100 Subject: [PATCH 50/96] Rename sp1 --- .../{batch-prover-bitcoin => batch-proof-bitcoin}/Cargo.lock | 0 .../{batch-prover-bitcoin => batch-proof-bitcoin}/Cargo.toml | 0 .../{batch-prover-bitcoin => batch-proof-bitcoin}/src/main.rs | 0 guests/sp1/build.rs | 2 +- 4 files changed, 1 insertion(+), 1 deletion(-) rename guests/sp1/{batch-prover-bitcoin => batch-proof-bitcoin}/Cargo.lock (100%) rename guests/sp1/{batch-prover-bitcoin => batch-proof-bitcoin}/Cargo.toml (100%) rename guests/sp1/{batch-prover-bitcoin => batch-proof-bitcoin}/src/main.rs (100%) diff --git a/guests/sp1/batch-prover-bitcoin/Cargo.lock b/guests/sp1/batch-proof-bitcoin/Cargo.lock similarity index 100% rename from guests/sp1/batch-prover-bitcoin/Cargo.lock rename to guests/sp1/batch-proof-bitcoin/Cargo.lock diff --git a/guests/sp1/batch-prover-bitcoin/Cargo.toml b/guests/sp1/batch-proof-bitcoin/Cargo.toml similarity index 100% rename from guests/sp1/batch-prover-bitcoin/Cargo.toml rename to guests/sp1/batch-proof-bitcoin/Cargo.toml diff --git a/guests/sp1/batch-prover-bitcoin/src/main.rs b/guests/sp1/batch-proof-bitcoin/src/main.rs similarity index 100% rename from guests/sp1/batch-prover-bitcoin/src/main.rs rename to guests/sp1/batch-proof-bitcoin/src/main.rs diff --git a/guests/sp1/build.rs b/guests/sp1/build.rs index df85c43d8..51b60b30d 100644 --- a/guests/sp1/build.rs +++ b/guests/sp1/build.rs @@ -23,7 +23,7 @@ fn main() { fn build_sp1_guest() { println!("cargo:rerun-if-env-changed=BUILD_SP1_GUEST"); - let bitcoin_program_path = "guests/sp1/batch-prover-bitcoin"; + let bitcoin_program_path = "guests/sp1/batch-proof-bitcoin"; let build_args = sp1_helper::BuildArgs { elf_name: "zkvm-elf".to_string(), From ed94e64f7c94cc26ed1d0621e8062246360c8edb Mon Sep 17 00:00:00 2001 From: yaziciahmet Date: Wed, 18 Dec 2024 15:30:00 +0100 Subject: [PATCH 51/96] Fix sp1 --- guests/sp1/batch-proof-bitcoin/Cargo.lock | 1 + guests/sp1/batch-proof-bitcoin/Cargo.toml | 1 + guests/sp1/batch-proof-bitcoin/src/main.rs | 62 +++++++++++++++++++++- 3 files changed, 63 insertions(+), 1 deletion(-) diff --git a/guests/sp1/batch-proof-bitcoin/Cargo.lock b/guests/sp1/batch-proof-bitcoin/Cargo.lock index e98bfff4c..313b3553b 100644 --- a/guests/sp1/batch-proof-bitcoin/Cargo.lock +++ b/guests/sp1/batch-proof-bitcoin/Cargo.lock @@ -2776,6 +2776,7 @@ dependencies = [ "citrea-primitives", "citrea-sp1", "citrea-stf", + "const-hex", "curve25519-dalek", "sov-modules-api", "sov-modules-stf-blueprint", diff --git a/guests/sp1/batch-proof-bitcoin/Cargo.toml b/guests/sp1/batch-proof-bitcoin/Cargo.toml index 2b86cc9d4..1e0728bb2 100644 --- a/guests/sp1/batch-proof-bitcoin/Cargo.toml +++ b/guests/sp1/batch-proof-bitcoin/Cargo.toml @@ -11,6 +11,7 @@ bitcoin-da = { path = "../../../crates/bitcoin-da", default-features = false } citrea-primitives = { path = "../../../crates/primitives" } citrea-sp1 = { path = "../../../crates/sp1", default-features = false } citrea-stf = { path = "../../../crates/citrea-stf" } +const-hex = "1.12" sov-modules-api = { path = "../../../crates/sovereign-sdk/module-system/sov-modules-api", default-features = false } sov-modules-stf-blueprint = { path = "../../../crates/sovereign-sdk/module-system/sov-modules-stf-blueprint" } sov-rollup-interface = { path = "../../../crates/sovereign-sdk/rollup-interface" } diff --git a/guests/sp1/batch-proof-bitcoin/src/main.rs b/guests/sp1/batch-proof-bitcoin/src/main.rs index 9317fcc0c..2b4a70bc6 100644 --- a/guests/sp1/batch-proof-bitcoin/src/main.rs +++ b/guests/sp1/batch-proof-bitcoin/src/main.rs @@ -3,6 +3,7 @@ sp1_zkvm::entrypoint!(main); use bitcoin_da::spec::RollupParams; use bitcoin_da::verifier::BitcoinVerifier; +use citrea_primitives::forks::{DEVNET_FORKS, MAINNET_FORKS, NIGHTLY_FORKS, TESTNET_FORKS}; use citrea_primitives::{TO_BATCH_PROOF_PREFIX, TO_LIGHT_CLIENT_PREFIX}; use citrea_sp1::guest::SP1Guest; use citrea_stf::runtime::Runtime; @@ -11,8 +12,67 @@ use sov_modules_api::default_context::ZkDefaultContext; use sov_modules_stf_blueprint::StfBlueprint; use sov_rollup_interface::da::DaVerifier; use sov_rollup_interface::zk::ZkvmGuest; +use sov_rollup_interface::Network; use sov_state::ZkStorage; +const NETWORK: Network = match option_env!("CITREA_NETWORK") { + Some(network) => { + match Network::const_from_str(network) { + Some(network) => network, + None => panic!("Invalid CITREA_NETWORK value"), + } + } + None => Network::Nightly, +}; + +const SEQUENCER_PUBLIC_KEY: [u8; 32] = { + let hex_pub_key = match NETWORK { + // TODO: Update Mainnet public key when decided + Network::Mainnet => "4682a70af1d3fae53a5a26b682e2e75f7a1de21ad5fc8d61794ca889880d39d1", + Network::Testnet => "4682a70af1d3fae53a5a26b682e2e75f7a1de21ad5fc8d61794ca889880d39d1", + Network::Devnet => "52f41a5076498d1ae8bdfa57d19e91e3c2c94b6de21985d099cd48cfa7aef174", + Network::Nightly => { + match option_env!("SEQUENCER_PUBLIC_KEY") { + Some(hex_pub_key) => hex_pub_key, + None => "204040e364c10f2bec9c1fe500a1cd4c247c89d650a01ed7e82caba867877c21", + } + } + }; + + match const_hex::const_decode_to_array(hex_pub_key.as_bytes()) { + Ok(pub_key) => pub_key, + Err(_) => panic!("SEQUENCER_PUBLIC_KEY must be valid 32-byte hex string"), + } +}; + +const SEQUENCER_DA_PUBLIC_KEY: [u8; 33] = { + let hex_pub_key = match NETWORK { + // TODO: Update Mainnet public key when decided + Network::Mainnet => "03015a7c4d2cc1c771198686e2ebef6fe7004f4136d61f6225b061d1bb9b821b9b", + Network::Testnet => "03015a7c4d2cc1c771198686e2ebef6fe7004f4136d61f6225b061d1bb9b821b9b", + Network::Devnet => "039cd55f9b3dcf306c4d54f66cd7c4b27cc788632cd6fb73d80c99d303c6536486", + Network::Nightly => { + match option_env!("SEQUENCER_DA_PUBLIC_KEY") { + Some(hex_pub_key) => hex_pub_key, + None => "02588d202afcc1ee4ab5254c7847ec25b9a135bbda0f2bc69ee1a714749fd77dc9", + } + } + }; + + match const_hex::const_decode_to_array(hex_pub_key.as_bytes()) { + Ok(pub_key) => pub_key, + Err(_) => panic!("SEQUENCER_DA_PUBLIC_KEY must be valid 33-byte hex string"), + } +}; + +const FORKS: &[Fork] = match NETWORK { + Network::Mainnet => &MAINNET_FORKS, + Network::Testnet => &TESTNET_FORKS, + Network::Devnet => &DEVNET_FORKS, + Network::Nightly => &NIGHTLY_FORKS, +}; + + pub fn main() { let guest = SP1Guest::new(); let storage = ZkStorage::new(); @@ -29,7 +89,7 @@ pub fn main() { let data = guest.read_from_host(); let out = stf_verifier - .run_sequencer_commitments_in_da_slot(data, storage) + .run_sequencer_commitments_in_da_slot(data, storage, &SEQUENCER_PUBLIC_KEY, &SEQUENCER_DA_PUBLIC_KEY, FORKS) .expect("Prover must be honest"); guest.commit(&out); From 8a24f294103ce9db76306293aa22438e9a1271e7 Mon Sep 17 00:00:00 2001 From: yaziciahmet Date: Wed, 18 Dec 2024 17:08:32 +0100 Subject: [PATCH 52/96] Update guest Dockerfile & Makefile --- guests/risc0/Dockerfile | 4 ++-- guests/risc0/Makefile | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/guests/risc0/Dockerfile b/guests/risc0/Dockerfile index a41e3b3ad..078d569e9 100644 --- a/guests/risc0/Dockerfile +++ b/guests/risc0/Dockerfile @@ -2,7 +2,7 @@ FROM risczero/risc0-guest-builder:r0.1.81.0 AS build WORKDIR /src ARG GUEST_NAME -ARG EXAMPLE_ARG="some-default-value" +ARG CITREA_NETWORK COPY . . @@ -11,7 +11,7 @@ ENV RUSTFLAGS="-C passes=loweratomic -C link-arg=-Ttext=0x00200800 -C link-arg=- ENV CARGO_TARGET_DIR="target" ENV CC_riscv32im_risc0_zkvm_elf="/root/.local/share/cargo-risczero/cpp/bin/riscv32-unknown-elf-gcc" ENV CFLAGS_riscv32im_risc0_zkvm_elf="-march=rv32im -nostdlib" -ENV EXAMPLE_ENV=${EXAMPLE_ARG} +ENV CITREA_NETWORK=${CITREA_NETWORK} RUN cargo +risc0 fetch --locked --target riscv32im-risc0-zkvm-elf --manifest-path ${CARGO_MANIFEST_PATH} RUN cargo +risc0 build --release --locked --target riscv32im-risc0-zkvm-elf --manifest-path ${CARGO_MANIFEST_PATH} diff --git a/guests/risc0/Makefile b/guests/risc0/Makefile index 0f0127d85..c115e5ded 100644 --- a/guests/risc0/Makefile +++ b/guests/risc0/Makefile @@ -21,7 +21,7 @@ batch-proof-bitcoin-docker: --output ./target/riscv-guest/riscv32im-risc0-zkvm-elf/docker \ -f ./guests/risc0/Dockerfile \ --build-arg GUEST_NAME=batch-proof-bitcoin \ - --build-arg EXAMPLE_ARG=some-value \ + --build-arg CITREA_NETWORK=$(CITREA_NETWORK) \ -t batch-proof-bitcoin:latest \ --no-cache \ . && \ @@ -35,7 +35,7 @@ light-client-bitcoin-docker: --output ./target/riscv-guest/riscv32im-risc0-zkvm-elf/docker \ -f ./guests/risc0/Dockerfile \ --build-arg GUEST_NAME=light-client-proof-bitcoin \ - --build-arg EXAMPLE_ARG=some-value \ + --build-arg CITREA_NETWORK=$(CITREA_NETWORK) \ -t light-client-proof-bitcoin:latest \ --no-cache \ . && \ From 4093f54dcf42ade8e944d26850eb0a35032c321e Mon Sep 17 00:00:00 2001 From: yaziciahmet Date: Wed, 18 Dec 2024 17:23:38 +0100 Subject: [PATCH 53/96] Fix udeps --- Cargo.lock | 1 - .../module-system/sov-modules-stf-blueprint/Cargo.toml | 1 - guests/risc0/batch-proof-bitcoin/Cargo.lock | 1 - guests/risc0/batch-proof-mock/Cargo.lock | 1 - guests/risc0/light-client-proof-bitcoin/Cargo.lock | 1 - guests/risc0/light-client-proof-mock/Cargo.lock | 1 - 6 files changed, 6 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 3577e0692..a39a09172 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -7757,7 +7757,6 @@ version = "0.5.0-rc.1" dependencies = [ "anyhow", "borsh", - "citrea-primitives", "hex", "itertools 0.13.0", "jmt", diff --git a/crates/sovereign-sdk/module-system/sov-modules-stf-blueprint/Cargo.toml b/crates/sovereign-sdk/module-system/sov-modules-stf-blueprint/Cargo.toml index bcb643b16..cb251b7a6 100644 --- a/crates/sovereign-sdk/module-system/sov-modules-stf-blueprint/Cargo.toml +++ b/crates/sovereign-sdk/module-system/sov-modules-stf-blueprint/Cargo.toml @@ -23,7 +23,6 @@ serde = { workspace = true, features = ["derive"] } tracing = { workspace = true, optional = true } # Sovereign-SDK deps -citrea-primitives = { path = "../../../primitives", default-features = false } sov-modules-api = { path = "../sov-modules-api", default-features = false } sov-rollup-interface = { path = "../../rollup-interface" } sov-state = { path = "../sov-state" } diff --git a/guests/risc0/batch-proof-bitcoin/Cargo.lock b/guests/risc0/batch-proof-bitcoin/Cargo.lock index 28093fcd5..6617c81ab 100644 --- a/guests/risc0/batch-proof-bitcoin/Cargo.lock +++ b/guests/risc0/batch-proof-bitcoin/Cargo.lock @@ -2999,7 +2999,6 @@ version = "0.5.0-rc.1" dependencies = [ "anyhow", "borsh", - "citrea-primitives", "hex", "itertools 0.13.0", "jmt", diff --git a/guests/risc0/batch-proof-mock/Cargo.lock b/guests/risc0/batch-proof-mock/Cargo.lock index 7457e2bae..5e6a7b001 100644 --- a/guests/risc0/batch-proof-mock/Cargo.lock +++ b/guests/risc0/batch-proof-mock/Cargo.lock @@ -2802,7 +2802,6 @@ version = "0.5.0-rc.1" dependencies = [ "anyhow", "borsh", - "citrea-primitives", "hex", "itertools 0.13.0", "jmt", diff --git a/guests/risc0/light-client-proof-bitcoin/Cargo.lock b/guests/risc0/light-client-proof-bitcoin/Cargo.lock index 7891d5e6d..e7dab1c31 100644 --- a/guests/risc0/light-client-proof-bitcoin/Cargo.lock +++ b/guests/risc0/light-client-proof-bitcoin/Cargo.lock @@ -2795,7 +2795,6 @@ version = "0.5.0-rc.1" dependencies = [ "anyhow", "borsh", - "citrea-primitives", "hex", "itertools 0.13.0", "jmt", diff --git a/guests/risc0/light-client-proof-mock/Cargo.lock b/guests/risc0/light-client-proof-mock/Cargo.lock index f91d1160b..63f78352b 100644 --- a/guests/risc0/light-client-proof-mock/Cargo.lock +++ b/guests/risc0/light-client-proof-mock/Cargo.lock @@ -2581,7 +2581,6 @@ version = "0.5.0-rc.1" dependencies = [ "anyhow", "borsh", - "citrea-primitives", "hex", "itertools 0.13.0", "jmt", From 096a30db816af0498c474e79a4083bd64783b73a Mon Sep 17 00:00:00 2001 From: yaziciahmet Date: Wed, 18 Dec 2024 17:25:23 +0100 Subject: [PATCH 54/96] Fix no-std --- crates/sovereign-sdk/rollup-interface/src/network.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/crates/sovereign-sdk/rollup-interface/src/network.rs b/crates/sovereign-sdk/rollup-interface/src/network.rs index 060b21ae1..04ed1249a 100644 --- a/crates/sovereign-sdk/rollup-interface/src/network.rs +++ b/crates/sovereign-sdk/rollup-interface/src/network.rs @@ -1,4 +1,4 @@ -use std::fmt::Display; +use core::fmt::Display; /// The network currently running. #[derive(Copy, Clone, Default, Debug)] From 76fbb916231e552de918fa29d767e9545c017eec Mon Sep 17 00:00:00 2001 From: yaziciahmet Date: Wed, 18 Dec 2024 17:25:45 +0100 Subject: [PATCH 55/96] Fix comment --- crates/sovereign-sdk/rollup-interface/src/network.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/crates/sovereign-sdk/rollup-interface/src/network.rs b/crates/sovereign-sdk/rollup-interface/src/network.rs index 04ed1249a..537a8473c 100644 --- a/crates/sovereign-sdk/rollup-interface/src/network.rs +++ b/crates/sovereign-sdk/rollup-interface/src/network.rs @@ -8,9 +8,9 @@ pub enum Network { Mainnet, /// Testnet Testnet, - /// Testnet + /// Devnet Devnet, - /// nightly + /// Nightly Nightly, } From ee66672c994b6cae2b1601273c77fdd349c9c8e4 Mon Sep 17 00:00:00 2001 From: yaziciahmet Date: Wed, 18 Dec 2024 17:29:00 +0100 Subject: [PATCH 56/96] Fix no-std warning --- crates/sovereign-sdk/rollup-interface/Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/crates/sovereign-sdk/rollup-interface/Makefile b/crates/sovereign-sdk/rollup-interface/Makefile index 5411c1dc3..54948d530 100644 --- a/crates/sovereign-sdk/rollup-interface/Makefile +++ b/crates/sovereign-sdk/rollup-interface/Makefile @@ -6,5 +6,5 @@ help: ## Display this help message check-no-std: ## Checks that project compiles without std # check bare metal cargo hack check --feature-powerset \ - --exclude-features default,fuzzing,std,native,testing,arbitrary \ + --exclude-features default,std,native,testing,arbitrary \ --target thumbv6m-none-eabi From 9ee5ce075c7c36b1287bd787b7e9bfecdea3d843 Mon Sep 17 00:00:00 2001 From: yaziciahmet Date: Wed, 18 Dec 2024 20:11:13 +0100 Subject: [PATCH 57/96] Remove testing forks --- crates/primitives/src/forks.rs | 30 ++++++------------------------ 1 file changed, 6 insertions(+), 24 deletions(-) diff --git a/crates/primitives/src/forks.rs b/crates/primitives/src/forks.rs index 45469ff96..a67598aea 100644 --- a/crates/primitives/src/forks.rs +++ b/crates/primitives/src/forks.rs @@ -14,7 +14,12 @@ pub fn use_network_forks(network: Network) { Network::Devnet => &DEVNET_FORKS, Network::Nightly => &NIGHTLY_FORKS, }; + + #[cfg(not(feature = "testing"))] FORKS.set(forks).expect("Forks must be set exactly once"); + + #[cfg(feature = "testing")] + let _ = FORKS.set(forks); } /// Get forks. Forks need to be set before calling this method if not in testing environment. @@ -28,9 +33,7 @@ pub fn get_forks() -> &'static [Fork] { #[cfg(feature = "testing")] { - FORKS - .set(&TESTING_FORKS) - .expect("Already checked that it is not set"); + use_network_forks(Network::Nightly); FORKS.get().expect("Just set it") } } @@ -59,22 +62,6 @@ pub const DEVNET_FORKS: [Fork; 2] = [ pub const NIGHTLY_FORKS: [Fork; 1] = [Fork::new(SpecId::Fork1, 0)]; -#[cfg(feature = "testing")] -const TESTING_FORKS: [Fork; 3] = [ - Fork { - spec_id: SpecId::Genesis, - activation_height: 0, - }, - Fork { - spec_id: SpecId::Fork1, - activation_height: 1000, - }, - Fork { - spec_id: SpecId::Fork2, - activation_height: 2000, - }, -]; - const _CHECK_FORKS: () = { if !verify_forks(&MAINNET_FORKS) || !verify_forks(&TESTNET_FORKS) @@ -83,9 +70,4 @@ const _CHECK_FORKS: () = { { panic!("FORKS order is invalid") } - - #[cfg(feature = "testing")] - if !verify_forks(&TESTING_FORKS) { - panic!("FORKS order is invalid") - } }; From b3245e14a60dc70d73afc27570c5575c7022d887 Mon Sep 17 00:00:00 2001 From: yaziciahmet Date: Wed, 18 Dec 2024 22:49:03 +0100 Subject: [PATCH 58/96] Match config env key and guest env keys --- crates/common/src/config.rs | 8 ++++---- .../batch-proof-bitcoin/src/bin/batch_proof_bitcoin.rs | 4 ++-- .../src/bin/light_client_proof_bitcoin.rs | 4 ++-- 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/crates/common/src/config.rs b/crates/common/src/config.rs index 9492bb52b..bf9f39d7a 100644 --- a/crates/common/src/config.rs +++ b/crates/common/src/config.rs @@ -193,8 +193,8 @@ impl FromEnv for RollupPublicKeys { fn from_env() -> anyhow::Result { Ok(Self { sequencer_public_key: hex::decode(std::env::var("SEQUENCER_PUBLIC_KEY")?)?, - sequencer_da_pub_key: hex::decode(std::env::var("SEQUENCER_DA_PUBLIC_KEY")?)?, - prover_da_pub_key: hex::decode(std::env::var("PROVER_DA_PUBLIC_KEY")?)?, + sequencer_da_pub_key: hex::decode(std::env::var("SEQUENCER_DA_PUB_KEY")?)?, + prover_da_pub_key: hex::decode(std::env::var("PROVER_DA_PUB_KEY")?)?, }) } } @@ -649,10 +649,10 @@ mod tests { "0000000000000000000000000000000000000000000000000000000000000000", ); std::env::set_var( - "SEQUENCER_DA_PUBLIC_KEY", + "SEQUENCER_DA_PUB_KEY", "7777777777777777777777777777777777777777777777777777777777777777", ); - std::env::set_var("PROVER_DA_PUBLIC_KEY", ""); + std::env::set_var("PROVER_DA_PUB_KEY", ""); std::env::set_var("RPC_BIND_HOST", "127.0.0.1"); std::env::set_var("RPC_BIND_PORT", "12345"); diff --git a/guests/risc0/batch-proof-bitcoin/src/bin/batch_proof_bitcoin.rs b/guests/risc0/batch-proof-bitcoin/src/bin/batch_proof_bitcoin.rs index b8cc3151a..dcceef293 100644 --- a/guests/risc0/batch-proof-bitcoin/src/bin/batch_proof_bitcoin.rs +++ b/guests/risc0/batch-proof-bitcoin/src/bin/batch_proof_bitcoin.rs @@ -53,7 +53,7 @@ const SEQUENCER_DA_PUBLIC_KEY: [u8; 33] = { Network::Testnet => "03015a7c4d2cc1c771198686e2ebef6fe7004f4136d61f6225b061d1bb9b821b9b", Network::Devnet => "039cd55f9b3dcf306c4d54f66cd7c4b27cc788632cd6fb73d80c99d303c6536486", Network::Nightly => { - match option_env!("SEQUENCER_DA_PUBLIC_KEY") { + match option_env!("SEQUENCER_DA_PUB_KEY") { Some(hex_pub_key) => hex_pub_key, None => "02588d202afcc1ee4ab5254c7847ec25b9a135bbda0f2bc69ee1a714749fd77dc9", } @@ -62,7 +62,7 @@ const SEQUENCER_DA_PUBLIC_KEY: [u8; 33] = { match const_hex::const_decode_to_array(hex_pub_key.as_bytes()) { Ok(pub_key) => pub_key, - Err(_) => panic!("SEQUENCER_DA_PUBLIC_KEY must be valid 33-byte hex string"), + Err(_) => panic!("SEQUENCER_DA_PUB_KEY must be valid 33-byte hex string"), } }; diff --git a/guests/risc0/light-client-proof-bitcoin/src/bin/light_client_proof_bitcoin.rs b/guests/risc0/light-client-proof-bitcoin/src/bin/light_client_proof_bitcoin.rs index 79e2f6285..d7a910765 100644 --- a/guests/risc0/light-client-proof-bitcoin/src/bin/light_client_proof_bitcoin.rs +++ b/guests/risc0/light-client-proof-bitcoin/src/bin/light_client_proof_bitcoin.rs @@ -67,7 +67,7 @@ const BATCH_PROVER_DA_PUBLIC_KEY: [u8; 33] = { Network::Testnet => "0357d255ab93638a2d880787ebaadfefdfc9bb51a26b4a37e5d588e04e54c60a42", Network::Devnet => "03fc6fb2ef68368009c895d2d4351dcca4109ec2f5f327291a0553570ce769f5e5", Network::Nightly => { - match option_env!("BATCH_PROVER_DA_PUBLIC_KEY") { + match option_env!("PROVER_DA_PUB_KEY") { Some(hex_pub_key) => hex_pub_key, None => "03eedab888e45f3bdc3ec9918c491c11e5cf7af0a91f38b97fbc1e135ae4056601", } @@ -76,7 +76,7 @@ const BATCH_PROVER_DA_PUBLIC_KEY: [u8; 33] = { match const_hex::const_decode_to_array(hex_pub_key.as_bytes()) { Ok(pub_key) => pub_key, - Err(_) => panic!("BATCH_PROVER_DA_PUBLIC_KEY must be valid 33-byte hex string"), + Err(_) => panic!("PROVER_DA_PUB_KEY must be valid 33-byte hex string"), } }; From d6dc818cc890a16d9e6558869979a33185b3f598 Mon Sep 17 00:00:00 2001 From: yaziciahmet Date: Wed, 18 Dec 2024 22:52:06 +0100 Subject: [PATCH 59/96] Set mainnet keys to 0 --- .../risc0/batch-proof-bitcoin/src/bin/batch_proof_bitcoin.rs | 4 ++-- .../src/bin/light_client_proof_bitcoin.rs | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/guests/risc0/batch-proof-bitcoin/src/bin/batch_proof_bitcoin.rs b/guests/risc0/batch-proof-bitcoin/src/bin/batch_proof_bitcoin.rs index dcceef293..f8f800c52 100644 --- a/guests/risc0/batch-proof-bitcoin/src/bin/batch_proof_bitcoin.rs +++ b/guests/risc0/batch-proof-bitcoin/src/bin/batch_proof_bitcoin.rs @@ -29,7 +29,7 @@ const NETWORK: Network = match option_env!("CITREA_NETWORK") { const SEQUENCER_PUBLIC_KEY: [u8; 32] = { let hex_pub_key = match NETWORK { // TODO: Update Mainnet public key when decided - Network::Mainnet => "4682a70af1d3fae53a5a26b682e2e75f7a1de21ad5fc8d61794ca889880d39d1", + Network::Mainnet => "0000000000000000000000000000000000000000000000000000000000000000", Network::Testnet => "4682a70af1d3fae53a5a26b682e2e75f7a1de21ad5fc8d61794ca889880d39d1", Network::Devnet => "52f41a5076498d1ae8bdfa57d19e91e3c2c94b6de21985d099cd48cfa7aef174", Network::Nightly => { @@ -49,7 +49,7 @@ const SEQUENCER_PUBLIC_KEY: [u8; 32] = { const SEQUENCER_DA_PUBLIC_KEY: [u8; 33] = { let hex_pub_key = match NETWORK { // TODO: Update Mainnet public key when decided - Network::Mainnet => "03015a7c4d2cc1c771198686e2ebef6fe7004f4136d61f6225b061d1bb9b821b9b", + Network::Mainnet => "030000000000000000000000000000000000000000000000000000000000000000", Network::Testnet => "03015a7c4d2cc1c771198686e2ebef6fe7004f4136d61f6225b061d1bb9b821b9b", Network::Devnet => "039cd55f9b3dcf306c4d54f66cd7c4b27cc788632cd6fb73d80c99d303c6536486", Network::Nightly => { diff --git a/guests/risc0/light-client-proof-bitcoin/src/bin/light_client_proof_bitcoin.rs b/guests/risc0/light-client-proof-bitcoin/src/bin/light_client_proof_bitcoin.rs index d7a910765..1e76d3981 100644 --- a/guests/risc0/light-client-proof-bitcoin/src/bin/light_client_proof_bitcoin.rs +++ b/guests/risc0/light-client-proof-bitcoin/src/bin/light_client_proof_bitcoin.rs @@ -63,7 +63,7 @@ const BATCH_PROOF_METHOD_ID: [u32; 8] = { const BATCH_PROVER_DA_PUBLIC_KEY: [u8; 33] = { let hex_pub_key = match NETWORK { // TODO: Update mainnet pub key - Network::Mainnet => "0357d255ab93638a2d880787ebaadfefdfc9bb51a26b4a37e5d588e04e54c60a42", + Network::Mainnet => "030000000000000000000000000000000000000000000000000000000000000000", Network::Testnet => "0357d255ab93638a2d880787ebaadfefdfc9bb51a26b4a37e5d588e04e54c60a42", Network::Devnet => "03fc6fb2ef68368009c895d2d4351dcca4109ec2f5f327291a0553570ce769f5e5", Network::Nightly => { From 183c256891befc615a6db2adb97b6ef220c6546e Mon Sep 17 00:00:00 2001 From: yaziciahmet Date: Wed, 18 Dec 2024 23:32:53 +0100 Subject: [PATCH 60/96] Add prover da pub key for regtest --- .../bitcoin-regtest/light_client_prover_rollup_config.toml | 2 +- resources/configs/bitcoin-regtest/rollup_config.toml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/resources/configs/bitcoin-regtest/light_client_prover_rollup_config.toml b/resources/configs/bitcoin-regtest/light_client_prover_rollup_config.toml index 2844d258a..5fc2ef64b 100644 --- a/resources/configs/bitcoin-regtest/light_client_prover_rollup_config.toml +++ b/resources/configs/bitcoin-regtest/light_client_prover_rollup_config.toml @@ -1,7 +1,7 @@ [public_keys] sequencer_public_key = "204040e364c10f2bec9c1fe500a1cd4c247c89d650a01ed7e82caba867877c21" sequencer_da_pub_key = "02588d202afcc1ee4ab5254c7847ec25b9a135bbda0f2bc69ee1a714749fd77dc9" -prover_da_pub_key = "" +prover_da_pub_key = "03eedab888e45f3bdc3ec9918c491c11e5cf7af0a91f38b97fbc1e135ae4056601" [da] # fill here diff --git a/resources/configs/bitcoin-regtest/rollup_config.toml b/resources/configs/bitcoin-regtest/rollup_config.toml index b5381546c..b71c64b25 100644 --- a/resources/configs/bitcoin-regtest/rollup_config.toml +++ b/resources/configs/bitcoin-regtest/rollup_config.toml @@ -1,7 +1,7 @@ [public_keys] sequencer_public_key = "204040e364c10f2bec9c1fe500a1cd4c247c89d650a01ed7e82caba867877c21" sequencer_da_pub_key = "02588d202afcc1ee4ab5254c7847ec25b9a135bbda0f2bc69ee1a714749fd77dc9" -prover_da_pub_key = "" +prover_da_pub_key = "03eedab888e45f3bdc3ec9918c491c11e5cf7af0a91f38b97fbc1e135ae4056601" [da] # fill here From bcaaa875b41043232576ecd5a63285e0f3b1bf49 Mon Sep 17 00:00:00 2001 From: yaziciahmet Date: Wed, 18 Dec 2024 23:49:59 +0100 Subject: [PATCH 61/96] Update latest guest spec to be Fork1 --- bin/citrea/src/guests.rs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/bin/citrea/src/guests.rs b/bin/citrea/src/guests.rs index f0fa4db98..14828ba3b 100644 --- a/bin/citrea/src/guests.rs +++ b/bin/citrea/src/guests.rs @@ -19,26 +19,26 @@ lazy_static! { pub(crate) static ref BATCH_PROOF_LATEST_MOCK_GUESTS: HashMap)> = { let mut m = HashMap::new(); - m.insert(SpecId::Genesis, (Digest::new(citrea_risc0::BATCH_PROOF_MOCK_ID), citrea_risc0::BATCH_PROOF_MOCK_ELF.to_vec())); + m.insert(SpecId::Fork1, (Digest::new(citrea_risc0::BATCH_PROOF_MOCK_ID), citrea_risc0::BATCH_PROOF_MOCK_ELF.to_vec())); m }; pub(crate) static ref LIGHT_CLIENT_LATEST_MOCK_GUESTS: HashMap)> = { let mut m = HashMap::new(); - m.insert(SpecId::Genesis, (Digest::new(citrea_risc0::LIGHT_CLIENT_PROOF_MOCK_ID), citrea_risc0::LIGHT_CLIENT_PROOF_MOCK_ELF.to_vec())); + m.insert(SpecId::Fork1, (Digest::new(citrea_risc0::LIGHT_CLIENT_PROOF_MOCK_ID), citrea_risc0::LIGHT_CLIENT_PROOF_MOCK_ELF.to_vec())); m }; /// The following 2 are used as latest guest builds for tests that use Bitcoin DA. pub(crate) static ref BATCH_PROOF_LATEST_BITCOIN_GUESTS: HashMap)> = { let mut m = HashMap::new(); - m.insert(SpecId::Genesis, (Digest::new(citrea_risc0::BATCH_PROOF_BITCOIN_ID), citrea_risc0::BATCH_PROOF_BITCOIN_ELF.to_vec())); + m.insert(SpecId::Fork1, (Digest::new(citrea_risc0::BATCH_PROOF_BITCOIN_ID), citrea_risc0::BATCH_PROOF_BITCOIN_ELF.to_vec())); m }; pub(crate) static ref LIGHT_CLIENT_LATEST_BITCOIN_GUESTS: HashMap)> = { let mut m = HashMap::new(); - m.insert(SpecId::Genesis, (Digest::new(citrea_risc0::LIGHT_CLIENT_PROOF_BITCOIN_ID), citrea_risc0::LIGHT_CLIENT_PROOF_BITCOIN_ELF.to_vec())); + m.insert(SpecId::Fork1, (Digest::new(citrea_risc0::LIGHT_CLIENT_PROOF_BITCOIN_ID), citrea_risc0::LIGHT_CLIENT_PROOF_BITCOIN_ELF.to_vec())); m }; /// Production guests From 952b80cdfb6083fd69d586dd2f55a7ff757b1d7c Mon Sep 17 00:00:00 2001 From: yaziciahmet Date: Thu, 19 Dec 2024 06:57:05 +0100 Subject: [PATCH 62/96] Run tests on Nightly --- bin/citrea/tests/test_helpers/mod.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bin/citrea/tests/test_helpers/mod.rs b/bin/citrea/tests/test_helpers/mod.rs index a47220a6c..8477d5bea 100644 --- a/bin/citrea/tests/test_helpers/mod.rs +++ b/bin/citrea/tests/test_helpers/mod.rs @@ -50,7 +50,7 @@ pub async fn start_rollup( // Fake receipts are receipts without the proof, they only include the journal, which makes them suitable for testing and development std::env::set_var("RISC0_DEV_MODE", "1"); - let mock_demo_rollup = MockDemoRollup::new(Network::Testnet); + let mock_demo_rollup = MockDemoRollup::new(Network::Nightly); if sequencer_config.is_some() && rollup_prover_config.is_some() { panic!("Both sequencer and batch prover config cannot be set at the same time"); From 9fbf3840c4a326c598459e75c264541420720003 Mon Sep 17 00:00:00 2001 From: yaziciahmet Date: Thu, 19 Dec 2024 07:51:43 +0100 Subject: [PATCH 63/96] Match e2e test keys with guest nightly --- bin/citrea/src/rollup/mock.rs | 2 +- bin/citrea/tests/test_helpers/mod.rs | 19 ++- .../adapters/mock-da/src/service.rs | 4 +- .../adapters/mock-da/src/types/address.rs | 128 +++++++++--------- .../adapters/mock-da/src/types/mod.rs | 2 +- .../adapters/mock-da/src/verifier.rs | 2 +- 6 files changed, 83 insertions(+), 74 deletions(-) diff --git a/bin/citrea/src/rollup/mock.rs b/bin/citrea/src/rollup/mock.rs index a4370438f..c01a2452a 100644 --- a/bin/citrea/src/rollup/mock.rs +++ b/bin/citrea/src/rollup/mock.rs @@ -93,7 +93,7 @@ impl RollupBlueprint for MockDemoRollup { _task_manager: &mut TaskManager<()>, ) -> Result, anyhow::Error> { Ok(Arc::new(MockDaService::new( - rollup_config.da.sender_address, + rollup_config.da.sender_address.clone(), &rollup_config.da.db_path, ))) } diff --git a/bin/citrea/tests/test_helpers/mod.rs b/bin/citrea/tests/test_helpers/mod.rs index 8477d5bea..1ce84ff95 100644 --- a/bin/citrea/tests/test_helpers/mod.rs +++ b/bin/citrea/tests/test_helpers/mod.rs @@ -150,14 +150,23 @@ pub fn create_default_rollup_config( da_path: &Path, node_mode: NodeMode, ) -> FullNodeConfig { + let sequencer_da_pub_key = vec![ + 2, 88, 141, 32, 42, 252, 193, 238, 74, 181, 37, 76, 120, 71, 236, 37, 185, 161, 53, 187, + 218, 15, 43, 198, 158, 225, 167, 20, 116, 159, 215, 125, 201, + ]; + let prover_da_pub_key = vec![ + 3, 238, 218, 184, 136, 228, 95, 59, 220, 62, 201, 145, 140, 73, 28, 17, 229, 207, 122, 240, + 169, 31, 56, 185, 127, 188, 30, 19, 90, 228, 5, 102, 1, + ]; + FullNodeConfig { public_keys: RollupPublicKeys { sequencer_public_key: vec![ 32, 64, 64, 227, 100, 193, 15, 43, 236, 156, 31, 229, 0, 161, 205, 76, 36, 124, 137, 214, 80, 160, 30, 215, 232, 44, 171, 168, 103, 135, 124, 33, ], - sequencer_da_pub_key: vec![0; 32], - prover_da_pub_key: vec![0; 32], + sequencer_da_pub_key: sequencer_da_pub_key.clone(), + prover_da_pub_key: prover_da_pub_key.clone(), }, storage: StorageConfig { path: rollup_path.to_path_buf(), @@ -185,7 +194,11 @@ pub fn create_default_rollup_config( NodeMode::SequencerNode => None, }, da: MockDaConfig { - sender_address: MockAddress::from([0; 32]), + sender_address: match node_mode { + NodeMode::SequencerNode => MockAddress::from(sequencer_da_pub_key), + NodeMode::Prover(_) => MockAddress::from(prover_da_pub_key), + _ => MockAddress::new([0; 32]), + }, db_path: da_path.to_path_buf(), }, telemetry: Default::default(), diff --git a/crates/sovereign-sdk/adapters/mock-da/src/service.rs b/crates/sovereign-sdk/adapters/mock-da/src/service.rs index 9080cfdef..df9f92740 100644 --- a/crates/sovereign-sdk/adapters/mock-da/src/service.rs +++ b/crates/sovereign-sdk/adapters/mock-da/src/service.rs @@ -115,7 +115,7 @@ impl MockDaService { /// Get sequencer address pub fn get_sequencer_address(&self) -> MockAddress { - self.sequencer_da_address + self.sequencer_da_address.clone() } /// Change number of wait attempts before giving up on waiting for block @@ -221,7 +221,7 @@ impl MockDaService { let blob = MockBlob::new_with_zkp_proof( blob.to_vec(), zkp_proof, - self.sequencer_da_address, + self.sequencer_da_address.clone(), data_hash, ); let header = MockBlockHeader { diff --git a/crates/sovereign-sdk/adapters/mock-da/src/types/address.rs b/crates/sovereign-sdk/adapters/mock-da/src/types/address.rs index a813f67e6..249206b48 100644 --- a/crates/sovereign-sdk/adapters/mock-da/src/types/address.rs +++ b/crates/sovereign-sdk/adapters/mock-da/src/types/address.rs @@ -1,102 +1,98 @@ +use std::fmt; use std::str::FromStr; +use borsh::{BorshDeserialize, BorshSerialize}; +use serde::{Deserialize, Serialize}; use sov_rollup_interface::{BasicAddress, RollupAddress}; -/// Sequencer DA address used in tests. -pub const MOCK_SEQUENCER_DA_ADDRESS: [u8; 32] = [0u8; 32]; - -/// A mock address type used for testing. Internally, this type is standard 32 byte array. -#[derive( - Debug, PartialEq, Clone, Eq, Copy, Hash, Default, borsh::BorshDeserialize, borsh::BorshSerialize, -)] -pub struct MockAddress { - /// Underlying mock address. - addr: [u8; 32], -} +/// MockAddress is a wrapper around Vec to implement AddressTrait +#[derive(Debug, PartialEq, Clone, Eq, BorshDeserialize, BorshSerialize, Hash)] +pub struct MockAddress(pub Vec); impl MockAddress { - /// Creates a new mock address containing the given bytes. - pub const fn new(addr: [u8; 32]) -> Self { - Self { addr } + /// Create new MockAddress + pub fn new(arr: [u8; 32]) -> Self { + Self(arr.to_vec()) } } -impl serde::Serialize for MockAddress { - fn serialize(&self, serializer: S) -> Result - where - S: serde::Serializer, - { - if serializer.is_human_readable() { - serde::Serialize::serialize(&hex::encode(self.addr), serializer) - } else { - serde::Serialize::serialize(&self.addr, serializer) - } +impl BasicAddress for MockAddress {} +impl RollupAddress for MockAddress {} + +impl FromStr for MockAddress { + type Err = anyhow::Error; + + fn from_str(s: &str) -> Result { + Ok(Self(hex::decode(s)?)) } } -impl<'de> serde::Deserialize<'de> for MockAddress { - fn deserialize(deserializer: D) -> Result - where - D: serde::Deserializer<'de>, - { - if deserializer.is_human_readable() { - let hex_addr: String = serde::Deserialize::deserialize(deserializer)?; - Ok(MockAddress::from_str(&hex_addr).map_err(serde::de::Error::custom)?) - } else { - let addr = <[u8; 32] as serde::Deserialize>::deserialize(deserializer)?; - Ok(MockAddress { addr }) - } +impl fmt::Display for MockAddress { + fn fmt(&self, f: &mut fmt::Formatter) -> core::fmt::Result { + let hash = hex::encode(&self.0); + write!(f, "{hash}") } } -impl FromStr for MockAddress { - type Err = anyhow::Error; - - fn from_str(s: &str) -> Result { - let addr = hex::decode(s).map_err(anyhow::Error::msg)?; - if addr.len() != 32 { - return Err(anyhow::anyhow!("Invalid address length")); - } +impl AsRef<[u8]> for MockAddress { + fn as_ref(&self) -> &[u8] { + self.0.as_ref() + } +} - let mut array = [0; 32]; - array.copy_from_slice(&addr); - Ok(MockAddress { addr: array }) +impl From<[u8; 32]> for MockAddress { + fn from(value: [u8; 32]) -> Self { + Self(value.to_vec()) } } impl<'a> TryFrom<&'a [u8]> for MockAddress { type Error = anyhow::Error; - fn try_from(addr: &'a [u8]) -> Result { - if addr.len() != 32 { - anyhow::bail!("Address must be 32 bytes long"); - } - let mut addr_bytes = [0u8; 32]; - addr_bytes.copy_from_slice(addr); - Ok(Self { addr: addr_bytes }) + fn try_from(value: &'a [u8]) -> Result { + Ok(Self(value.to_vec())) } } -impl AsRef<[u8]> for MockAddress { - fn as_ref(&self) -> &[u8] { - &self.addr +impl From> for MockAddress { + fn from(value: Vec) -> Self { + Self(value) } } -impl From<[u8; 32]> for MockAddress { - fn from(addr: [u8; 32]) -> Self { - MockAddress { addr } +impl Default for MockAddress { + fn default() -> Self { + Self(vec![0; 32]) } } -impl std::fmt::Display for MockAddress { - fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { - write!(f, "{}", hex::encode(self.addr)) +impl Serialize for MockAddress { + fn serialize(&self, serializer: S) -> Result + where + S: serde::Serializer, + { + if serializer.is_human_readable() { + Serialize::serialize(&hex::encode(&self.0), serializer) + } else { + Serialize::serialize(&self.0, serializer) + } } } -impl BasicAddress for MockAddress {} -impl RollupAddress for MockAddress {} +impl<'de> Deserialize<'de> for MockAddress { + fn deserialize(deserializer: D) -> Result + where + D: serde::Deserializer<'de>, + { + if deserializer.is_human_readable() { + let hex_addr: String = Deserialize::deserialize(deserializer)?; + Ok(MockAddress::from_str(&hex_addr).map_err(serde::de::Error::custom)?) + } else { + let addr = as Deserialize>::deserialize(deserializer)?; + Ok(MockAddress(addr)) + } + } +} #[cfg(test)] mod tests { @@ -104,7 +100,7 @@ mod tests { #[test] fn test_mock_address_string() { - let addr = MockAddress { addr: [3u8; 32] }; + let addr = MockAddress::from([3; 32]); let s = addr.to_string(); let recovered_addr = s.parse::().unwrap(); assert_eq!(addr, recovered_addr); diff --git a/crates/sovereign-sdk/adapters/mock-da/src/types/mod.rs b/crates/sovereign-sdk/adapters/mock-da/src/types/mod.rs index c6e86ea0f..61641b31d 100644 --- a/crates/sovereign-sdk/adapters/mock-da/src/types/mod.rs +++ b/crates/sovereign-sdk/adapters/mock-da/src/types/mod.rs @@ -4,7 +4,7 @@ use std::fmt::{Debug, Formatter}; use std::hash::Hasher; use std::path::PathBuf; -pub use address::{MockAddress, MOCK_SEQUENCER_DA_ADDRESS}; +pub use address::MockAddress; use borsh::{BorshDeserialize, BorshSerialize}; use serde::{Deserialize, Serialize}; use sov_rollup_interface::da::{BlockHashTrait, BlockHeaderTrait, CountedBufReader, Time}; diff --git a/crates/sovereign-sdk/adapters/mock-da/src/verifier.rs b/crates/sovereign-sdk/adapters/mock-da/src/verifier.rs index fb4fddb93..b731c435b 100644 --- a/crates/sovereign-sdk/adapters/mock-da/src/verifier.rs +++ b/crates/sovereign-sdk/adapters/mock-da/src/verifier.rs @@ -11,7 +11,7 @@ impl BlobReaderTrait for MockBlob { type Address = MockAddress; fn sender(&self) -> Self::Address { - self.address + self.address.clone() } fn hash(&self) -> [u8; 32] { From 1905fdd98c09dbff27e21d5771bedebdd6b3438e Mon Sep 17 00:00:00 2001 From: yaziciahmet Date: Thu, 19 Dec 2024 11:53:02 +0100 Subject: [PATCH 64/96] Set genesis state roots --- .../src/bin/light_client_proof_bitcoin.rs | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/guests/risc0/light-client-proof-bitcoin/src/bin/light_client_proof_bitcoin.rs b/guests/risc0/light-client-proof-bitcoin/src/bin/light_client_proof_bitcoin.rs index 1e76d3981..687f32395 100644 --- a/guests/risc0/light-client-proof-bitcoin/src/bin/light_client_proof_bitcoin.rs +++ b/guests/risc0/light-client-proof-bitcoin/src/bin/light_client_proof_bitcoin.rs @@ -20,16 +20,15 @@ const NETWORK: Network = match option_env!("CITREA_NETWORK") { None => Network::Nightly, }; -// TODO: Find l2 genesis roots of networks const L2_GENESIS_ROOT: [u8; 32] = { let hex_root = match NETWORK { Network::Mainnet => "0000000000000000000000000000000000000000000000000000000000000000", - Network::Testnet => "0000000000000000000000000000000000000000000000000000000000000000", - Network::Devnet => "0000000000000000000000000000000000000000000000000000000000000000", + Network::Testnet => "05183faf24857f0fa6d4a7738fe5ef14b7ebe88be0f66e6f87f461485554d531", + Network::Devnet => "c23eb4eec08765750400f6e98567ef1977dc86334318f5424b7783c4080c0a36", Network::Nightly => { match option_env!("L2_GENESIS_ROOT") { Some(hex_root) => hex_root, - None => "0000000000000000000000000000000000000000000000000000000000000000", + None => "dacb59b0ff5d16985a8418235133eee37758a3ac1b76ab6d1f87c6df20e4d4da", } } }; From 0d9196c84bc24787544aded1d159fa5a332b15dc Mon Sep 17 00:00:00 2001 From: yaziciahmet Date: Thu, 19 Dec 2024 12:12:13 +0100 Subject: [PATCH 65/96] Remove todo --- guests/risc0/batch-proof-bitcoin/src/bin/batch_proof_bitcoin.rs | 2 -- .../src/bin/light_client_proof_bitcoin.rs | 1 - guests/sp1/batch-proof-bitcoin/src/main.rs | 2 -- 3 files changed, 5 deletions(-) diff --git a/guests/risc0/batch-proof-bitcoin/src/bin/batch_proof_bitcoin.rs b/guests/risc0/batch-proof-bitcoin/src/bin/batch_proof_bitcoin.rs index f8f800c52..271e4290f 100644 --- a/guests/risc0/batch-proof-bitcoin/src/bin/batch_proof_bitcoin.rs +++ b/guests/risc0/batch-proof-bitcoin/src/bin/batch_proof_bitcoin.rs @@ -28,7 +28,6 @@ const NETWORK: Network = match option_env!("CITREA_NETWORK") { const SEQUENCER_PUBLIC_KEY: [u8; 32] = { let hex_pub_key = match NETWORK { - // TODO: Update Mainnet public key when decided Network::Mainnet => "0000000000000000000000000000000000000000000000000000000000000000", Network::Testnet => "4682a70af1d3fae53a5a26b682e2e75f7a1de21ad5fc8d61794ca889880d39d1", Network::Devnet => "52f41a5076498d1ae8bdfa57d19e91e3c2c94b6de21985d099cd48cfa7aef174", @@ -48,7 +47,6 @@ const SEQUENCER_PUBLIC_KEY: [u8; 32] = { const SEQUENCER_DA_PUBLIC_KEY: [u8; 33] = { let hex_pub_key = match NETWORK { - // TODO: Update Mainnet public key when decided Network::Mainnet => "030000000000000000000000000000000000000000000000000000000000000000", Network::Testnet => "03015a7c4d2cc1c771198686e2ebef6fe7004f4136d61f6225b061d1bb9b821b9b", Network::Devnet => "039cd55f9b3dcf306c4d54f66cd7c4b27cc788632cd6fb73d80c99d303c6536486", diff --git a/guests/risc0/light-client-proof-bitcoin/src/bin/light_client_proof_bitcoin.rs b/guests/risc0/light-client-proof-bitcoin/src/bin/light_client_proof_bitcoin.rs index 687f32395..a4ed1ac74 100644 --- a/guests/risc0/light-client-proof-bitcoin/src/bin/light_client_proof_bitcoin.rs +++ b/guests/risc0/light-client-proof-bitcoin/src/bin/light_client_proof_bitcoin.rs @@ -61,7 +61,6 @@ const BATCH_PROOF_METHOD_ID: [u32; 8] = { const BATCH_PROVER_DA_PUBLIC_KEY: [u8; 33] = { let hex_pub_key = match NETWORK { - // TODO: Update mainnet pub key Network::Mainnet => "030000000000000000000000000000000000000000000000000000000000000000", Network::Testnet => "0357d255ab93638a2d880787ebaadfefdfc9bb51a26b4a37e5d588e04e54c60a42", Network::Devnet => "03fc6fb2ef68368009c895d2d4351dcca4109ec2f5f327291a0553570ce769f5e5", diff --git a/guests/sp1/batch-proof-bitcoin/src/main.rs b/guests/sp1/batch-proof-bitcoin/src/main.rs index 2b4a70bc6..a4a83e9e2 100644 --- a/guests/sp1/batch-proof-bitcoin/src/main.rs +++ b/guests/sp1/batch-proof-bitcoin/src/main.rs @@ -27,7 +27,6 @@ const NETWORK: Network = match option_env!("CITREA_NETWORK") { const SEQUENCER_PUBLIC_KEY: [u8; 32] = { let hex_pub_key = match NETWORK { - // TODO: Update Mainnet public key when decided Network::Mainnet => "4682a70af1d3fae53a5a26b682e2e75f7a1de21ad5fc8d61794ca889880d39d1", Network::Testnet => "4682a70af1d3fae53a5a26b682e2e75f7a1de21ad5fc8d61794ca889880d39d1", Network::Devnet => "52f41a5076498d1ae8bdfa57d19e91e3c2c94b6de21985d099cd48cfa7aef174", @@ -47,7 +46,6 @@ const SEQUENCER_PUBLIC_KEY: [u8; 32] = { const SEQUENCER_DA_PUBLIC_KEY: [u8; 33] = { let hex_pub_key = match NETWORK { - // TODO: Update Mainnet public key when decided Network::Mainnet => "03015a7c4d2cc1c771198686e2ebef6fe7004f4136d61f6225b061d1bb9b821b9b", Network::Testnet => "03015a7c4d2cc1c771198686e2ebef6fe7004f4136d61f6225b061d1bb9b821b9b", Network::Devnet => "039cd55f9b3dcf306c4d54f66cd7c4b27cc788632cd6fb73d80c99d303c6536486", From e6e0bc69a043ee5e091610cb6e60aa4de331ac8a Mon Sep 17 00:00:00 2001 From: yaziciahmet Date: Thu, 19 Dec 2024 12:37:16 +0100 Subject: [PATCH 66/96] Set mock configs to be same with regtest --- .../mock/batch_prover_rollup_config.toml | 25 +++++++++++++++++++ resources/configs/mock/rollup_config.toml | 5 ++-- .../configs/mock/sequencer_rollup_config.toml | 4 +-- 3 files changed, 29 insertions(+), 5 deletions(-) create mode 100644 resources/configs/mock/batch_prover_rollup_config.toml diff --git a/resources/configs/mock/batch_prover_rollup_config.toml b/resources/configs/mock/batch_prover_rollup_config.toml new file mode 100644 index 000000000..1a7d42f2d --- /dev/null +++ b/resources/configs/mock/batch_prover_rollup_config.toml @@ -0,0 +1,25 @@ +[public_keys] +sequencer_public_key = "204040e364c10f2bec9c1fe500a1cd4c247c89d650a01ed7e82caba867877c21" +sequencer_da_pub_key = "02588d202afcc1ee4ab5254c7847ec25b9a135bbda0f2bc69ee1a714749fd77dc9" +prover_da_pub_key = "03eedab888e45f3bdc3ec9918c491c11e5cf7af0a91f38b97fbc1e135ae4056601" + +[da] +sender_address = "03eedab888e45f3bdc3ec9918c491c11e5cf7af0a91f38b97fbc1e135ae4056601" +db_path = "resources/dbs/da-db" + +[storage] +# The path to the rollup's data directory. Paths that do not begin with `/` are interpreted as relative paths. +path = "resources/dbs/full-node-db" +db_max_open_files = 5000 + +[rpc] +# the host and port to bind the rpc server for +bind_host = "127.0.0.1" +bind_port = 12346 +enable_subscriptions = true +max_subscriptions_per_connection = 100 + +[runner] +include_tx_body = false +sequencer_client_url = "http://0.0.0.0:12345" +# pruning_config.distance = 10 diff --git a/resources/configs/mock/rollup_config.toml b/resources/configs/mock/rollup_config.toml index a19c13be2..2cf4ad573 100644 --- a/resources/configs/mock/rollup_config.toml +++ b/resources/configs/mock/rollup_config.toml @@ -1,10 +1,9 @@ [public_keys] sequencer_public_key = "204040e364c10f2bec9c1fe500a1cd4c247c89d650a01ed7e82caba867877c21" -sequencer_da_pub_key = "0000000000000000000000000000000000000000000000000000000000000000" -prover_da_pub_key = "" +sequencer_da_pub_key = "02588d202afcc1ee4ab5254c7847ec25b9a135bbda0f2bc69ee1a714749fd77dc9" +prover_da_pub_key = "03eedab888e45f3bdc3ec9918c491c11e5cf7af0a91f38b97fbc1e135ae4056601" [da] -sender_address = "0000000000000000000000000000000000000000000000000000000000000000" db_path = "resources/dbs/da-db" [storage] diff --git a/resources/configs/mock/sequencer_rollup_config.toml b/resources/configs/mock/sequencer_rollup_config.toml index 4f293dcdc..6349202a3 100644 --- a/resources/configs/mock/sequencer_rollup_config.toml +++ b/resources/configs/mock/sequencer_rollup_config.toml @@ -1,10 +1,10 @@ [public_keys] sequencer_public_key = "204040e364c10f2bec9c1fe500a1cd4c247c89d650a01ed7e82caba867877c21" -sequencer_da_pub_key = "0000000000000000000000000000000000000000000000000000000000000000" +sequencer_da_pub_key = "02588d202afcc1ee4ab5254c7847ec25b9a135bbda0f2bc69ee1a714749fd77dc9" prover_da_pub_key = "" [da] -sender_address = "0000000000000000000000000000000000000000000000000000000000000000" +sender_address = "02588d202afcc1ee4ab5254c7847ec25b9a135bbda0f2bc69ee1a714749fd77dc9" db_path = "resources/dbs/da-db" [storage] From 48630e1aee1780b76a07b8aaacc89214cd855347 Mon Sep 17 00:00:00 2001 From: yaziciahmet Date: Thu, 19 Dec 2024 12:46:14 +0100 Subject: [PATCH 67/96] Set l2 genesis root for mock proof --- .../light-client-proof-mock/src/bin/light_client_proof_mock.rs | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/guests/risc0/light-client-proof-mock/src/bin/light_client_proof_mock.rs b/guests/risc0/light-client-proof-mock/src/bin/light_client_proof_mock.rs index b87667798..d3c57e00a 100644 --- a/guests/risc0/light-client-proof-mock/src/bin/light_client_proof_mock.rs +++ b/guests/risc0/light-client-proof-mock/src/bin/light_client_proof_mock.rs @@ -6,8 +6,7 @@ use sov_rollup_interface::zk::ZkvmGuest; risc0_zkvm::guest::entry!(main); -// TODO: Find l2 genesis root of nightly -const L2_GENESIS_ROOT: [u8; 32] = match const_hex::const_decode_to_array(b"0000000000000000000000000000000000000000000000000000000000000000") { +const L2_GENESIS_ROOT: [u8; 32] = match const_hex::const_decode_to_array(b"dacb59b0ff5d16985a8418235133eee37758a3ac1b76ab6d1f87c6df20e4d4da") { Ok(root) => root, Err(_) => panic!("Can't happen"), }; From 93f0557e1462fa4493968dd45e0322fc36b94e42 Mon Sep 17 00:00:00 2001 From: yaziciahmet Date: Thu, 19 Dec 2024 13:23:29 +0100 Subject: [PATCH 68/96] Remove Simulate proof mode --- bin/citrea/src/rollup/bitcoin.rs | 33 +----- bin/citrea/src/rollup/mock.rs | 33 +----- bin/citrea/src/rollup/mod.rs | 19 +-- crates/batch-prover/tests/prover_tests.rs | 8 +- crates/prover-services/src/lib.rs | 13 +-- crates/prover-services/src/parallel/mod.rs | 108 +++--------------- .../sov-stf-runner/src/prover_service/mod.rs | 3 - .../sov-modules-rollup-blueprint/src/lib.rs | 4 +- 8 files changed, 33 insertions(+), 188 deletions(-) diff --git a/bin/citrea/src/rollup/bitcoin.rs b/bin/citrea/src/rollup/bitcoin.rs index eee4ca37d..b080bcb75 100644 --- a/bin/citrea/src/rollup/bitcoin.rs +++ b/bin/citrea/src/rollup/bitcoin.rs @@ -8,24 +8,22 @@ use bitcoin_da::spec::{BitcoinSpec, RollupParams}; use bitcoin_da::verifier::BitcoinVerifier; use citrea_common::rpc::register_healthcheck_rpc; use citrea_common::tasks::manager::TaskManager; -use citrea_common::{FullNodeConfig, RollupPublicKeys}; +use citrea_common::FullNodeConfig; use citrea_primitives::forks::use_network_forks; use citrea_primitives::{TO_BATCH_PROOF_PREFIX, TO_LIGHT_CLIENT_PREFIX}; use citrea_risc0_adapter::host::Risc0BonsaiHost; // use citrea_sp1::host::SP1Host; use citrea_stf::genesis_config::StorageConfig; use citrea_stf::runtime::Runtime; -use citrea_stf::verifier::StateTransitionVerifier; use prover_services::{ParallelProverService, ProofGenMode}; use sov_db::ledger_db::LedgerDB; use sov_modules_api::default_context::{DefaultContext, ZkDefaultContext}; use sov_modules_api::{Address, SpecId, Zkvm}; use sov_modules_rollup_blueprint::RollupBlueprint; -use sov_modules_stf_blueprint::StfBlueprint; use sov_prover_storage_manager::{ProverStorageManager, SnapshotManager}; use sov_rollup_interface::da::DaVerifier; use sov_rollup_interface::services::da::SenderWithNotifier; -use sov_state::{ProverStorage, ZkStorage}; +use sov_state::ProverStorage; use sov_stf_runner::ProverGuestRunConfig; use tokio::sync::broadcast; use tokio::sync::mpsc::unbounded_channel; @@ -58,11 +56,7 @@ impl RollupBlueprint for BitcoinRollup { type ZkRuntime = Runtime; type NativeRuntime = Runtime; - type ProverService = ParallelProverService< - Self::DaService, - Self::Vm, - StfBlueprint, - >; + type ProverService = ParallelProverService; fn new(network: Network) -> Self { use_network_forks(network); @@ -261,9 +255,7 @@ impl RollupBlueprint for BitcoinRollup { &self, proving_mode: ProverGuestRunConfig, da_service: &Arc, - da_verifier: Self::DaVerifier, ledger_db: LedgerDB, - keys: RollupPublicKeys, ) -> Self::ProverService { let vm = Risc0BonsaiHost::new(ledger_db.clone()); // let vm = SP1Host::new( @@ -271,28 +263,13 @@ impl RollupBlueprint for BitcoinRollup { // ledger_db.clone(), // ); - let zk_stf = StfBlueprint::new(); - let zk_storage = ZkStorage::new(); - let proof_mode = match proving_mode { ProverGuestRunConfig::Skip => ProofGenMode::Skip, - ProverGuestRunConfig::Simulate => { - let stf_verifier = StateTransitionVerifier::new(zk_stf, da_verifier); - ProofGenMode::Simulate(stf_verifier) - } ProverGuestRunConfig::Execute => ProofGenMode::Execute, ProverGuestRunConfig::Prove => ProofGenMode::Prove, }; - ParallelProverService::new_from_env( - da_service.clone(), - vm, - proof_mode, - zk_storage, - ledger_db, - keys.sequencer_public_key.clone(), - keys.sequencer_da_pub_key, - ) - .expect("Should be able to instantiate prover service") + ParallelProverService::new_from_env(da_service.clone(), vm, proof_mode, ledger_db) + .expect("Should be able to instantiate prover service") } } diff --git a/bin/citrea/src/rollup/mock.rs b/bin/citrea/src/rollup/mock.rs index c01a2452a..f6244a24a 100644 --- a/bin/citrea/src/rollup/mock.rs +++ b/bin/citrea/src/rollup/mock.rs @@ -4,22 +4,19 @@ use std::sync::Arc; use async_trait::async_trait; use citrea_common::rpc::register_healthcheck_rpc; use citrea_common::tasks::manager::TaskManager; -use citrea_common::{FullNodeConfig, RollupPublicKeys}; +use citrea_common::FullNodeConfig; use citrea_primitives::forks::use_network_forks; // use citrea_sp1::host::SP1Host; use citrea_risc0_adapter::host::Risc0BonsaiHost; use citrea_stf::genesis_config::StorageConfig; use citrea_stf::runtime::Runtime; -use citrea_stf::verifier::StateTransitionVerifier; use prover_services::{ParallelProverService, ProofGenMode}; use sov_db::ledger_db::LedgerDB; use sov_mock_da::{MockDaConfig, MockDaService, MockDaSpec, MockDaVerifier}; use sov_modules_api::default_context::{DefaultContext, ZkDefaultContext}; use sov_modules_api::{Address, Spec, SpecId, Zkvm}; use sov_modules_rollup_blueprint::RollupBlueprint; -use sov_modules_stf_blueprint::StfBlueprint; use sov_prover_storage_manager::ProverStorageManager; -use sov_state::ZkStorage; use sov_stf_runner::ProverGuestRunConfig; use tokio::sync::broadcast; @@ -44,11 +41,7 @@ impl RollupBlueprint for MockDemoRollup { type NativeContext = DefaultContext; type ZkRuntime = Runtime; type NativeRuntime = Runtime; - type ProverService = ParallelProverService< - Self::DaService, - Self::Vm, - StfBlueprint, - >; + type ProverService = ParallelProverService; fn new(network: Network) -> Self { use_network_forks(network); @@ -138,36 +131,18 @@ impl RollupBlueprint for MockDemoRollup { &self, proving_mode: ProverGuestRunConfig, da_service: &Arc, - da_verifier: Self::DaVerifier, ledger_db: LedgerDB, - keys: RollupPublicKeys, ) -> Self::ProverService { let vm = Risc0BonsaiHost::new(ledger_db.clone()); - let zk_stf = StfBlueprint::new(); - let zk_storage = ZkStorage::new(); - let proof_mode = match proving_mode { ProverGuestRunConfig::Skip => ProofGenMode::Skip, - ProverGuestRunConfig::Simulate => { - let stf_verifier = StateTransitionVerifier::new(zk_stf, da_verifier); - ProofGenMode::Simulate(stf_verifier) - } ProverGuestRunConfig::Execute => ProofGenMode::Execute, ProverGuestRunConfig::Prove => ProofGenMode::Prove, }; - ParallelProverService::new( - da_service.clone(), - vm, - proof_mode, - zk_storage, - 1, - ledger_db, - keys.sequencer_public_key.clone(), - keys.sequencer_da_pub_key, - ) - .expect("Should be able to instantiate prover service") + ParallelProverService::new(da_service.clone(), vm, proof_mode, 1, ledger_db) + .expect("Should be able to instantiate prover service") } fn create_storage_manager( diff --git a/bin/citrea/src/rollup/mod.rs b/bin/citrea/src/rollup/mod.rs index dbc0ab7b6..9a31b6944 100644 --- a/bin/citrea/src/rollup/mod.rs +++ b/bin/citrea/src/rollup/mod.rs @@ -309,8 +309,6 @@ pub trait CitreaRollupBlueprint: RollupBlueprint { .create_da_service(&rollup_config, true, &mut task_manager) .await?; - let da_verifier = self.create_da_verifier(); - // Migrate before constructing ledger_db instance so that no lock is present. let migrator = LedgerDBMigrator::new( rollup_config.storage.path.as_path(), @@ -326,13 +324,7 @@ pub trait CitreaRollupBlueprint: RollupBlueprint { let ledger_db = self.create_ledger_db(&rocksdb_config); let prover_service = self - .create_prover_service( - prover_config.proving_mode, - &da_service, - da_verifier, - ledger_db.clone(), - rollup_config.public_keys.clone(), - ) + .create_prover_service(prover_config.proving_mode, &da_service, ledger_db.clone()) .await; // TODO: Double check what kind of storage needed here. @@ -446,7 +438,6 @@ pub trait CitreaRollupBlueprint: RollupBlueprint { let da_service = self .create_da_service(&rollup_config, true, &mut task_manager) .await?; - let da_verifier = self.create_da_verifier(); let rocksdb_config = RocksdbConfig::new( rollup_config.storage.path.as_path(), @@ -456,13 +447,7 @@ pub trait CitreaRollupBlueprint: RollupBlueprint { let ledger_db = self.create_ledger_db(&rocksdb_config); let prover_service = self - .create_prover_service( - prover_config.proving_mode, - &da_service, - da_verifier, - ledger_db.clone(), - rollup_config.public_keys.clone(), - ) + .create_prover_service(prover_config.proving_mode, &da_service, ledger_db.clone()) .await; // TODO: Double check what kind of storage needed here. diff --git a/crates/batch-prover/tests/prover_tests.rs b/crates/batch-prover/tests/prover_tests.rs index 01ebc2169..0cc6ff093 100644 --- a/crates/batch-prover/tests/prover_tests.rs +++ b/crates/batch-prover/tests/prover_tests.rs @@ -9,7 +9,6 @@ use sov_mock_da::{MockAddress, MockBlockHeader, MockDaService, MockDaSpec, MockH use sov_mock_zkvm::MockZkvm; use sov_rollup_interface::da::Time; use sov_rollup_interface::zk::{BatchProofCircuitInput, Proof, ZkvmHost}; -use sov_stf_runner::mock::MockStf; use sov_stf_runner::ProverService; use tokio::sync::oneshot; @@ -289,7 +288,7 @@ async fn test_multiple_parallel_proof_run() { } struct TestProver { - prover_service: Arc>, + prover_service: Arc>, vm: MockZkvm, } @@ -305,11 +304,8 @@ fn make_new_prover(thread_pool_size: usize, da_service: Arc) -> T da_service, vm.clone(), proof_mode, - (), thread_pool_size, ledger_db, - vec![], - vec![], ) .expect("Should be able to instantiate Prover service"), ), @@ -346,7 +342,7 @@ fn make_transition_data( } async fn spawn_prove( - prover_service: Arc>, + prover_service: Arc>, ) -> oneshot::Receiver> { let (tx, rx) = oneshot::channel(); tokio::spawn(async move { diff --git a/crates/prover-services/src/lib.rs b/crates/prover-services/src/lib.rs index 047d152ac..9a115f655 100644 --- a/crates/prover-services/src/lib.rs +++ b/crates/prover-services/src/lib.rs @@ -1,19 +1,10 @@ -use citrea_stf::verifier::StateTransitionVerifier; -use sov_rollup_interface::services::da::DaService; -use sov_rollup_interface::stf::StateTransitionFunction; - mod parallel; pub use parallel::*; -pub enum ProofGenMode -where - Da: DaService, - Stf: StateTransitionFunction, -{ +#[derive(Debug, Clone, Copy)] +pub enum ProofGenMode { /// Skips proving. Skip, - /// The simulator runs the rollup verifier logic without even emulating the zkVM - Simulate(StateTransitionVerifier), /// The executor runs the rollup verification logic in the zkVM, but does not actually /// produce a zk proof Execute, diff --git a/crates/prover-services/src/parallel/mod.rs b/crates/prover-services/src/parallel/mod.rs index fd299fd84..d08dc3dd7 100644 --- a/crates/prover-services/src/parallel/mod.rs +++ b/crates/prover-services/src/parallel/mod.rs @@ -1,14 +1,11 @@ -use std::ops::DerefMut; use std::sync::Arc; use async_trait::async_trait; -use citrea_primitives::forks::get_forks; use futures::future; use sov_db::ledger_db::LedgerDB; use sov_rollup_interface::da::DaData; use sov_rollup_interface::services::da::DaService; -use sov_rollup_interface::stf::StateTransitionFunction; -use sov_rollup_interface::zk::{Proof, ZkvmGuest, ZkvmHost}; +use sov_rollup_interface::zk::{Proof, ZkvmHost}; use sov_stf_runner::ProverService; use tokio::sync::{oneshot, Mutex}; use tracing::{info, warn}; @@ -20,45 +17,34 @@ pub(crate) type Assumptions = Vec>; pub(crate) type ProofData = (Input, Assumptions); /// Prover service that generates proofs in parallel. -pub struct ParallelProverService +pub struct ParallelProverService where Da: DaService, Vm: ZkvmHost + 'static, - Stf: StateTransitionFunction + Send + Sync + 'static, - Stf::PreState: Clone + Send + Sync + 'static, { thread_pool: rayon::ThreadPool, - proof_mode: Arc>>, + proof_mode: ProofGenMode, da_service: Arc, vm: Vm, - zk_storage: Stf::PreState, _ledger_db: LedgerDB, proof_queue: Arc>>, - sequencer_public_key: Vec, - sequencer_da_public_key: Vec, } -impl ParallelProverService +impl ParallelProverService where Da: DaService, Vm: ZkvmHost, - Stf: StateTransitionFunction + Send + Sync, - Stf::PreState: Clone + Send + Sync, { /// Creates a new prover. - #[allow(clippy::too_many_arguments)] pub fn new( da_service: Arc, vm: Vm, - proof_mode: ProofGenMode, - zk_storage: Stf::PreState, + proof_mode: ProofGenMode, thread_pool_size: usize, _ledger_db: LedgerDB, - sequencer_public_key: Vec, - sequencer_da_public_key: Vec, ) -> anyhow::Result { assert!( thread_pool_size > 0, @@ -69,9 +55,6 @@ where ProofGenMode::Skip => { tracing::info!("Prover is configured to skip proving"); } - ProofGenMode::Simulate(_) => { - tracing::info!("Prover is configured to simulate proving"); - } ProofGenMode::Execute => { tracing::info!("Prover is configured to execute proving"); } @@ -87,14 +70,11 @@ where Ok(Self { thread_pool, - proof_mode: Arc::new(Mutex::new(proof_mode)), + proof_mode, da_service, vm, - zk_storage, _ledger_db, proof_queue: Arc::new(Mutex::new(vec![])), - sequencer_public_key, - sequencer_da_public_key, }) } @@ -103,27 +83,15 @@ where pub fn new_from_env( da_service: Arc, vm: Vm, - proof_mode: ProofGenMode, - zk_storage: Stf::PreState, + proof_mode: ProofGenMode, _ledger_db: LedgerDB, - sequencer_public_key: Vec, - sequencer_da_public_key: Vec, ) -> anyhow::Result { let thread_pool_size = std::env::var("PARALLEL_PROOF_LIMIT") .expect("PARALLEL_PROOF_LIMIT must be set") .parse::() .expect("PARALLEL_PROOF_LIMIT must be valid unsigned number"); - Self::new( - da_service, - vm, - proof_mode, - zk_storage, - thread_pool_size, - _ledger_db, - sequencer_public_key, - sequencer_da_public_key, - ) + Self::new(da_service, vm, proof_mode, thread_pool_size, _ledger_db) } async fn prove_all(&self, elf: Vec, proof_queue: Vec) -> Vec { @@ -171,10 +139,7 @@ where async fn prove_one(&self, elf: Vec, (input, assumptions): ProofData) -> Proof { let mut vm = self.vm.clone(); - let zk_storage = self.zk_storage.clone(); - let proof_mode = self.proof_mode.clone(); - let sequencer_public_key = self.sequencer_public_key.clone(); - let sequencer_da_public_key = self.sequencer_da_public_key.clone(); + let proof_mode = self.proof_mode; vm.add_hint(input); for assumption in assumptions { @@ -183,15 +148,7 @@ where let (tx, rx) = oneshot::channel(); self.thread_pool.spawn(move || { - let proof = make_proof( - vm, - elf, - zk_storage, - proof_mode, - &sequencer_public_key, - &sequencer_da_public_key, - ) - .expect("Proof creation must not fail"); + let proof = make_proof(vm, elf, proof_mode).expect("Proof creation must not fail"); let _ = tx.send(proof); }); @@ -208,12 +165,10 @@ where } #[async_trait] -impl ProverService for ParallelProverService +impl ProverService for ParallelProverService where Da: DaService, Vm: ZkvmHost, - Stf: StateTransitionFunction + Send + Sync, - Stf::PreState: Clone + Send + Sync, { type DaService = Da; @@ -224,7 +179,7 @@ where async fn prove(&self, elf: Vec) -> anyhow::Result> { let mut proof_queue = self.proof_queue.lock().await; - if let ProofGenMode::Skip = *self.proof_mode.lock().await { + if let ProofGenMode::Skip = self.proof_mode { tracing::debug!("Skipped proving {} proofs", proof_queue.len()); proof_queue.clear(); return Ok(vec![]); @@ -264,47 +219,18 @@ where } } -fn make_proof( +fn make_proof( mut vm: Vm, elf: Vec, - zk_storage: Stf::PreState, - proof_mode: Arc>>, - sequencer_public_key: &[u8], - sequencer_da_public_key: &[u8], + proof_mode: ProofGenMode, ) -> Result where - Da: DaService, Vm: ZkvmHost, - Stf: StateTransitionFunction + Send + Sync, - Stf::PreState: Send + Sync, { - let mut proof_mode = proof_mode.blocking_lock(); - match proof_mode.deref_mut() { + match proof_mode { ProofGenMode::Skip => Ok(Vec::default()), - ProofGenMode::Simulate(ref mut verifier) => { - let guest = vm.simulate_with_hints(); - let data = guest.read_from_host(); - verifier - .run_sequencer_commitments_in_da_slot( - data, - zk_storage, - sequencer_public_key, - sequencer_da_public_key, - get_forks(), - ) - .map(|_| Vec::default()) - .map_err(|e| { - anyhow::anyhow!("Guest execution must succeed but failed with {:?}", e) - }) - } // If not skip or simulate, we have to drop the lock manually to allow parallel proving - ProofGenMode::Execute => { - drop(proof_mode); - vm.run(elf, false) - } - ProofGenMode::Prove => { - drop(proof_mode); - vm.run(elf, true) - } + ProofGenMode::Execute => vm.run(elf, false), + ProofGenMode::Prove => vm.run(elf, true), } } diff --git a/crates/sovereign-sdk/full-node/sov-stf-runner/src/prover_service/mod.rs b/crates/sovereign-sdk/full-node/sov-stf-runner/src/prover_service/mod.rs index 224418904..071198776 100644 --- a/crates/sovereign-sdk/full-node/sov-stf-runner/src/prover_service/mod.rs +++ b/crates/sovereign-sdk/full-node/sov-stf-runner/src/prover_service/mod.rs @@ -10,8 +10,6 @@ use thiserror::Error; pub enum ProverGuestRunConfig { /// Skip proving. Skip, - /// Run the rollup verification logic inside the current process. - Simulate, /// Run the rollup verifier in a zkVM executor. Execute, /// Run the rollup verifier and create a SNARK of execution. @@ -26,7 +24,6 @@ impl<'de> Deserialize<'de> for ProverGuestRunConfig { let s = ::deserialize(deserializer)?; match s.as_str() { "skip" => Ok(ProverGuestRunConfig::Skip), - "simulate" => Ok(ProverGuestRunConfig::Simulate), "execute" => Ok(ProverGuestRunConfig::Execute), "prove" => Ok(ProverGuestRunConfig::Prove), _ => Err(serde::de::Error::custom("invalid prover guest run config")), diff --git a/crates/sovereign-sdk/module-system/sov-modules-rollup-blueprint/src/lib.rs b/crates/sovereign-sdk/module-system/sov-modules-rollup-blueprint/src/lib.rs index 5f019885c..10c244f4f 100644 --- a/crates/sovereign-sdk/module-system/sov-modules-rollup-blueprint/src/lib.rs +++ b/crates/sovereign-sdk/module-system/sov-modules-rollup-blueprint/src/lib.rs @@ -6,7 +6,7 @@ use std::sync::Arc; use async_trait::async_trait; use citrea_common::tasks::manager::TaskManager; -use citrea_common::{FullNodeConfig, RollupPublicKeys}; +use citrea_common::FullNodeConfig; use sov_db::ledger_db::LedgerDB; use sov_db::rocks_db_config::RocksdbConfig; use sov_modules_api::{Context, DaSpec, Spec}; @@ -125,9 +125,7 @@ pub trait RollupBlueprint: Sized + Send + Sync { &self, proving_mode: ProverGuestRunConfig, da_service: &Arc, - da_verifier: Self::DaVerifier, ledger_db: LedgerDB, - keys: RollupPublicKeys, ) -> Self::ProverService; /// Creates instance of [`Self::StorageManager`]. From 287a27dfa2c36d03a1512d5fcbba3f0d199793b9 Mon Sep 17 00:00:00 2001 From: yaziciahmet Date: Thu, 19 Dec 2024 14:01:10 +0100 Subject: [PATCH 69/96] Fix udeps --- Cargo.lock | 4 ---- crates/batch-prover/Cargo.toml | 1 - crates/prover-services/Cargo.toml | 7 ------- 3 files changed, 12 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index b237c1fc0..bfeea3fc1 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1865,7 +1865,6 @@ dependencies = [ "borsh", "citrea-common", "citrea-primitives", - "citrea-stf", "futures", "hex", "jsonrpsee", @@ -5467,8 +5466,6 @@ dependencies = [ "async-trait", "bincode", "borsh", - "citrea-primitives", - "citrea-stf", "futures", "hex", "jsonrpsee", @@ -5476,7 +5473,6 @@ dependencies = [ "parking_lot", "rand", "rayon", - "rs_merkle", "serde", "sha2", "sov-db", diff --git a/crates/batch-prover/Cargo.toml b/crates/batch-prover/Cargo.toml index 137b1d6bb..91bfe5c17 100644 --- a/crates/batch-prover/Cargo.toml +++ b/crates/batch-prover/Cargo.toml @@ -51,7 +51,6 @@ sha2 = { workspace = true } tempfile = { workspace = true } citrea-primitives = { path = "../primitives", features = ["testing"] } -citrea-stf = { path = "../citrea-stf", features = ["native"] } prover-services = { path = "../prover-services" } sov-mock-da = { path = "../sovereign-sdk/adapters/mock-da", features = ["native"] } sov-mock-zkvm = { path = "../sovereign-sdk/adapters/mock-zkvm" } diff --git a/crates/prover-services/Cargo.toml b/crates/prover-services/Cargo.toml index 5fa4f737d..e87bba960 100644 --- a/crates/prover-services/Cargo.toml +++ b/crates/prover-services/Cargo.toml @@ -9,10 +9,6 @@ publish.workspace = true repository.workspace = true [dependencies] -# Citrea Deps -citrea-primitives = { path = "../primitives" } -citrea-stf = { path = "../citrea-stf" } - # Sov SDK deps sov-db = { path = "../sovereign-sdk/full-node/db/sov-db" } sov-modules-api = { path = "../sovereign-sdk/module-system/sov-modules-api", default-features = false } @@ -31,7 +27,6 @@ num_cpus = { workspace = true } parking_lot = { workspace = true } rand = { workspace = true } rayon = { workspace = true } -rs_merkle = { workspace = true } serde = { workspace = true } tokio = { workspace = true } tokio-util = { workspace = true } @@ -43,5 +38,3 @@ sha2 = { workspace = true } tempfile = { workspace = true } sov-stf-runner = { path = "../sovereign-sdk/full-node/sov-stf-runner", features = ["mock"] } - -citrea-stf = { path = "../citrea-stf", features = ["native"] } From abd9da4a7eea5cf5faba88453d66f8401358f24e Mon Sep 17 00:00:00 2001 From: yaziciahmet Date: Thu, 19 Dec 2024 14:06:11 +0100 Subject: [PATCH 70/96] Add sender_address back to rollup --- resources/configs/mock/rollup_config.toml | 1 + 1 file changed, 1 insertion(+) diff --git a/resources/configs/mock/rollup_config.toml b/resources/configs/mock/rollup_config.toml index 2cf4ad573..a9e0e1881 100644 --- a/resources/configs/mock/rollup_config.toml +++ b/resources/configs/mock/rollup_config.toml @@ -4,6 +4,7 @@ sequencer_da_pub_key = "02588d202afcc1ee4ab5254c7847ec25b9a135bbda0f2bc69ee1a714 prover_da_pub_key = "03eedab888e45f3bdc3ec9918c491c11e5cf7af0a91f38b97fbc1e135ae4056601" [da] +sender_address = "02588d202afcc1ee4ab5254c7847ec25b9a135bbda0f2bc69ee1a714749fd77dc9" db_path = "resources/dbs/da-db" [storage] From d76e286703c34444304ebf80f53bea51e95ada64 Mon Sep 17 00:00:00 2001 From: yaziciahmet Date: Thu, 19 Dec 2024 14:29:47 +0100 Subject: [PATCH 71/96] Add todo --- .../src/bin/light_client_proof_bitcoin.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/guests/risc0/light-client-proof-bitcoin/src/bin/light_client_proof_bitcoin.rs b/guests/risc0/light-client-proof-bitcoin/src/bin/light_client_proof_bitcoin.rs index a4ed1ac74..0e411db03 100644 --- a/guests/risc0/light-client-proof-bitcoin/src/bin/light_client_proof_bitcoin.rs +++ b/guests/risc0/light-client-proof-bitcoin/src/bin/light_client_proof_bitcoin.rs @@ -23,6 +23,7 @@ const NETWORK: Network = match option_env!("CITREA_NETWORK") { const L2_GENESIS_ROOT: [u8; 32] = { let hex_root = match NETWORK { Network::Mainnet => "0000000000000000000000000000000000000000000000000000000000000000", + // TODO: Update this after finding out the first batch prover output of the next release Network::Testnet => "05183faf24857f0fa6d4a7738fe5ef14b7ebe88be0f66e6f87f461485554d531", Network::Devnet => "c23eb4eec08765750400f6e98567ef1977dc86334318f5424b7783c4080c0a36", Network::Nightly => { From e0d7d56ccdcab306d64e2b1f7ce088310bdc71bc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ahmet=20Yaz=C4=B1c=C4=B1?= <75089142+yaziciahmet@users.noreply.github.com> Date: Thu, 19 Dec 2024 15:42:55 +0100 Subject: [PATCH 72/96] Update crates/sovereign-sdk/rollup-interface/src/network.rs Co-authored-by: jfldde <168934971+jfldde@users.noreply.github.com> --- .../rollup-interface/src/network.rs | 35 ++++--------------- 1 file changed, 6 insertions(+), 29 deletions(-) diff --git a/crates/sovereign-sdk/rollup-interface/src/network.rs b/crates/sovereign-sdk/rollup-interface/src/network.rs index 537a8473c..4cbcba6bc 100644 --- a/crates/sovereign-sdk/rollup-interface/src/network.rs +++ b/crates/sovereign-sdk/rollup-interface/src/network.rs @@ -21,36 +21,13 @@ impl Display for Network { } impl Network { - /// Constant function to get the Network from &str pub const fn const_from_str(s: &str) -> Option { - const fn const_compare_str(s1: &str, s2: &str) -> bool { - let b1 = s1.as_bytes(); - let b2 = s2.as_bytes(); - if b1.len() != b2.len() { - return false; - } - - let mut i = 0; - while i < b1.len() { - if b1[i] != b2[i] { - return false; - } - i += 1; - } - - true - } - - if const_compare_str(s, "mainnet") { - Some(Network::Mainnet) - } else if const_compare_str(s, "testnet") { - Some(Network::Testnet) - } else if const_compare_str(s, "devnet") { - Some(Network::Devnet) - } else if const_compare_str(s, "nightly") { - Some(Network::Nightly) - } else { - None + match s.as_bytes() { + b"mainnet" => Some(Network::Mainnet), + b"testnet" => Some(Network::Testnet), + b"devnet" => Some(Network::Devnet), + b"nightly" => Some(Network::Nightly), + _ => None, } } } From e70101866273a2e2e0cc24e232703e403ea81f08 Mon Sep 17 00:00:00 2001 From: yaziciahmet Date: Thu, 19 Dec 2024 21:14:18 +0100 Subject: [PATCH 73/96] Fix CANCUN related test --- crates/evm/src/tests/queries/estimate_gas_tests.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/crates/evm/src/tests/queries/estimate_gas_tests.rs b/crates/evm/src/tests/queries/estimate_gas_tests.rs index bfbeb2578..7d2a59120 100644 --- a/crates/evm/src/tests/queries/estimate_gas_tests.rs +++ b/crates/evm/src/tests/queries/estimate_gas_tests.rs @@ -94,7 +94,7 @@ fn test_tx_request_fields_gas() { ); assert_eq!( contract_diff_size.unwrap(), - serde_json::from_value::(json![{"gas":"0x6601","l1DiffSize":"0x60"}]) + serde_json::from_value::(json![{"gas":"0x6601","l1DiffSize":"0x1f"}]) .unwrap() ); @@ -110,7 +110,7 @@ fn test_tx_request_fields_gas() { ); assert_eq!( contract_diff_size.unwrap(), - serde_json::from_value::(json![{"gas":"0x6601","l1DiffSize":"0x60"}]) + serde_json::from_value::(json![{"gas":"0x6601","l1DiffSize":"0x1f"}]) .unwrap() ); From 9ee8551e8c8b3e9c3a1d9a2d64fc170b5da68c0c Mon Sep 17 00:00:00 2001 From: yaziciahmet Date: Thu, 19 Dec 2024 22:43:26 +0100 Subject: [PATCH 74/96] Match citrea-e2e pub keys --- Cargo.lock | 2 +- Cargo.toml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 97bb9f42c..9b318fdac 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1930,7 +1930,7 @@ dependencies = [ [[package]] name = "citrea-e2e" version = "0.1.0" -source = "git+https://github.com/chainwayxyz/citrea-e2e?rev=51a4d19#51a4d1958ead4021115bd81ac9aa1b1fcf6f7e0c" +source = "git+https://github.com/chainwayxyz/citrea-e2e?rev=6a87ce3#6a87ce3f3576392451a10fa1a52d678befc1eba6" dependencies = [ "anyhow", "async-trait", diff --git a/Cargo.toml b/Cargo.toml index cba031550..71b4e3b84 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -155,7 +155,7 @@ alloy-eips = { version = "0.4.2", default-features = false } alloy-consensus = { version = "0.4.2", default-features = false, features = ["serde", "serde-bincode-compat"] } alloy-network = { version = "0.4.2", default-features = false } -citrea-e2e = { git = "https://github.com/chainwayxyz/citrea-e2e", rev = "51a4d19" } +citrea-e2e = { git = "https://github.com/chainwayxyz/citrea-e2e", rev = "6a87ce3" } [patch.crates-io] bitcoincore-rpc = { version = "0.18.0", git = "https://github.com/chainwayxyz/rust-bitcoincore-rpc.git", rev = "ca3cfa2" } From 5080e80cbe8829c74b7e4e61ae4485b98e31dc81 Mon Sep 17 00:00:00 2001 From: yaziciahmet Date: Fri, 20 Dec 2024 09:40:02 +0100 Subject: [PATCH 75/96] Separate batch and light client guests --- Cargo.lock | 24 ++++-- bin/citrea/Cargo.toml | 10 ++- bin/citrea/src/guests.rs | 32 +++++++- guests/risc0/{ => batch-proof}/Cargo.toml | 8 +- .../bitcoin}/Cargo.lock | 0 .../bitcoin}/Cargo.toml | 16 ++-- .../bitcoin}/src/bin/batch_proof_bitcoin.rs | 0 guests/risc0/batch-proof/build.rs | 75 +++++++++++++++++++ .../mock}/Cargo.lock | 0 .../mock}/Cargo.toml | 16 ++-- .../mock}/src/bin/batch_proof_mock.rs | 0 guests/risc0/{ => batch-proof}/src/lib.rs | 0 guests/risc0/light-client-proof/Cargo.toml | 20 +++++ .../bitcoin}/Cargo.lock | 0 .../bitcoin}/Cargo.toml | 16 ++-- .../src/bin/light_client_proof_bitcoin.rs | 0 .../risc0/{ => light-client-proof}/build.rs | 6 -- .../mock}/Cargo.lock | 0 .../mock}/Cargo.toml | 16 ++-- .../mock}/src/bin/light_client_proof_mock.rs | 0 guests/risc0/light-client-proof/src/lib.rs | 1 + 21 files changed, 183 insertions(+), 57 deletions(-) rename guests/risc0/{ => batch-proof}/Cargo.toml (66%) rename guests/risc0/{batch-proof-bitcoin => batch-proof/bitcoin}/Cargo.lock (100%) rename guests/risc0/{batch-proof-bitcoin => batch-proof/bitcoin}/Cargo.toml (58%) rename guests/risc0/{batch-proof-bitcoin => batch-proof/bitcoin}/src/bin/batch_proof_bitcoin.rs (100%) create mode 100644 guests/risc0/batch-proof/build.rs rename guests/risc0/{batch-proof-mock => batch-proof/mock}/Cargo.lock (100%) rename guests/risc0/{batch-proof-mock => batch-proof/mock}/Cargo.toml (57%) rename guests/risc0/{batch-proof-mock => batch-proof/mock}/src/bin/batch_proof_mock.rs (100%) rename guests/risc0/{ => batch-proof}/src/lib.rs (100%) create mode 100644 guests/risc0/light-client-proof/Cargo.toml rename guests/risc0/{light-client-proof-bitcoin => light-client-proof/bitcoin}/Cargo.lock (100%) rename guests/risc0/{light-client-proof-bitcoin => light-client-proof/bitcoin}/Cargo.toml (57%) rename guests/risc0/{light-client-proof-bitcoin => light-client-proof/bitcoin}/src/bin/light_client_proof_bitcoin.rs (100%) rename guests/risc0/{ => light-client-proof}/build.rs (87%) rename guests/risc0/{light-client-proof-mock => light-client-proof/mock}/Cargo.lock (100%) rename guests/risc0/{light-client-proof-mock => light-client-proof/mock}/Cargo.toml (53%) rename guests/risc0/{light-client-proof-mock => light-client-proof/mock}/src/bin/light_client_proof_mock.rs (100%) create mode 100644 guests/risc0/light-client-proof/src/lib.rs diff --git a/Cargo.lock b/Cargo.lock index 9b318fdac..84371bff0 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1809,6 +1809,8 @@ dependencies = [ "citrea-light-client-prover", "citrea-primitives", "citrea-risc0-adapter", + "citrea-risc0-batch-proof", + "citrea-risc0-light-client", "citrea-sequencer", "citrea-stf", "clap", @@ -1827,7 +1829,6 @@ dependencies = [ "reth-primitives", "reth-transaction-pool", "revm", - "risc0", "risc0-binfmt", "rs_merkle", "rustc_version_runtime", @@ -2118,6 +2119,20 @@ dependencies = [ "tracing", ] +[[package]] +name = "citrea-risc0-batch-proof" +version = "0.5.0-rc.1" +dependencies = [ + "risc0-build", +] + +[[package]] +name = "citrea-risc0-light-client" +version = "0.5.0-rc.1" +dependencies = [ + "risc0-build", +] + [[package]] name = "citrea-sequencer" version = "0.5.0-rc.1" @@ -7128,13 +7143,6 @@ dependencies = [ "digest 0.10.7", ] -[[package]] -name = "risc0" -version = "0.5.0-rc.1" -dependencies = [ - "risc0-build", -] - [[package]] name = "risc0-binfmt" version = "1.1.3" diff --git a/bin/citrea/Cargo.toml b/bin/citrea/Cargo.toml index f78e815a9..13213e6da 100644 --- a/bin/citrea/Cargo.toml +++ b/bin/citrea/Cargo.toml @@ -19,8 +19,9 @@ citrea-common = { path = "../../crates/common" } citrea-fullnode = { path = "../../crates/fullnode" } citrea-light-client-prover = { path = "../../crates/light-client-prover", features = ["native"] } citrea-primitives = { path = "../../crates/primitives" } -citrea-risc0 = { package = "risc0", path = "../../guests/risc0" } citrea-risc0-adapter = { path = "../../crates/risc0", features = ["native"] } +citrea-risc0-batch-proof = { path = "../../guests/risc0/batch-proof" } +citrea-risc0-light-client = { path = "../../guests/risc0/light-client-proof" } citrea-sequencer = { path = "../../crates/sequencer" } # citrea-sp1 = { path = "../../crates/sp1", features = ["native"] } citrea-stf = { path = "../../crates/citrea-stf", features = ["native"] } @@ -102,7 +103,12 @@ sp1-helper = { version = "3.0.0", default-features = false } [features] default = [] # Deviate from convention by making the "native" feature active by default. This aligns with how this package is meant to be used (as a binary first, library second). -testing = ["citrea-primitives/testing", "citrea-risc0/testing", "sov-rollup-interface/testing"] +testing = [ + "citrea-primitives/testing", + "citrea-risc0-batch-proof/testing", + "citrea-risc0-light-client/testing", + "sov-rollup-interface/testing", +] [[bin]] name = "citrea" diff --git a/bin/citrea/src/guests.rs b/bin/citrea/src/guests.rs index 14828ba3b..d4ccd9199 100644 --- a/bin/citrea/src/guests.rs +++ b/bin/citrea/src/guests.rs @@ -19,26 +19,50 @@ lazy_static! { pub(crate) static ref BATCH_PROOF_LATEST_MOCK_GUESTS: HashMap)> = { let mut m = HashMap::new(); - m.insert(SpecId::Fork1, (Digest::new(citrea_risc0::BATCH_PROOF_MOCK_ID), citrea_risc0::BATCH_PROOF_MOCK_ELF.to_vec())); + m.insert( + SpecId::Fork1, + ( + Digest::new(citrea_risc0_batch_proof::BATCH_PROOF_MOCK_ID), + citrea_risc0_batch_proof::BATCH_PROOF_MOCK_ELF.to_vec(), + ), + ); m }; pub(crate) static ref LIGHT_CLIENT_LATEST_MOCK_GUESTS: HashMap)> = { let mut m = HashMap::new(); - m.insert(SpecId::Fork1, (Digest::new(citrea_risc0::LIGHT_CLIENT_PROOF_MOCK_ID), citrea_risc0::LIGHT_CLIENT_PROOF_MOCK_ELF.to_vec())); + m.insert( + SpecId::Fork1, + ( + Digest::new(citrea_risc0_light_client::LIGHT_CLIENT_PROOF_MOCK_ID), + citrea_risc0_light_client::LIGHT_CLIENT_PROOF_MOCK_ELF.to_vec(), + ) + ); m }; /// The following 2 are used as latest guest builds for tests that use Bitcoin DA. pub(crate) static ref BATCH_PROOF_LATEST_BITCOIN_GUESTS: HashMap)> = { let mut m = HashMap::new(); - m.insert(SpecId::Fork1, (Digest::new(citrea_risc0::BATCH_PROOF_BITCOIN_ID), citrea_risc0::BATCH_PROOF_BITCOIN_ELF.to_vec())); + m.insert( + SpecId::Fork1, + ( + Digest::new(citrea_risc0_batch_proof::BATCH_PROOF_BITCOIN_ID), + citrea_risc0_batch_proof::BATCH_PROOF_BITCOIN_ELF.to_vec(), + ) + ); m }; pub(crate) static ref LIGHT_CLIENT_LATEST_BITCOIN_GUESTS: HashMap)> = { let mut m = HashMap::new(); - m.insert(SpecId::Fork1, (Digest::new(citrea_risc0::LIGHT_CLIENT_PROOF_BITCOIN_ID), citrea_risc0::LIGHT_CLIENT_PROOF_BITCOIN_ELF.to_vec())); + m.insert( + SpecId::Fork1, + ( + Digest::new(citrea_risc0_light_client::LIGHT_CLIENT_PROOF_BITCOIN_ID), + citrea_risc0_light_client::LIGHT_CLIENT_PROOF_BITCOIN_ELF.to_vec(), + ) + ); m }; /// Production guests diff --git a/guests/risc0/Cargo.toml b/guests/risc0/batch-proof/Cargo.toml similarity index 66% rename from guests/risc0/Cargo.toml rename to guests/risc0/batch-proof/Cargo.toml index fbc6c312d..dbc912bae 100644 --- a/guests/risc0/Cargo.toml +++ b/guests/risc0/batch-proof/Cargo.toml @@ -1,5 +1,5 @@ [package] -name = "risc0" +name = "citrea-risc0-batch-proof" version = "0.5.0-rc.1" edition = "2021" license = "MIT OR Apache-2.0" @@ -11,10 +11,8 @@ risc0-build = { workspace = true } [package.metadata.risc0] methods = [ - "batch-proof-bitcoin", - "batch-proof-mock", - "light-client-proof-bitcoin", - "light-client-proof-mock", + "bitcoin", + "mock", ] [features] diff --git a/guests/risc0/batch-proof-bitcoin/Cargo.lock b/guests/risc0/batch-proof/bitcoin/Cargo.lock similarity index 100% rename from guests/risc0/batch-proof-bitcoin/Cargo.lock rename to guests/risc0/batch-proof/bitcoin/Cargo.lock diff --git a/guests/risc0/batch-proof-bitcoin/Cargo.toml b/guests/risc0/batch-proof/bitcoin/Cargo.toml similarity index 58% rename from guests/risc0/batch-proof-bitcoin/Cargo.toml rename to guests/risc0/batch-proof/bitcoin/Cargo.toml index b6a79db22..e93a0f0fc 100644 --- a/guests/risc0/batch-proof-bitcoin/Cargo.toml +++ b/guests/risc0/batch-proof/bitcoin/Cargo.toml @@ -11,15 +11,15 @@ risc0-zkvm = { version = "1.1.3", default-features = false } risc0-zkvm-platform = { version = "1.1.3" } anyhow = "1.0.68" -bitcoin-da = { path = "../../../crates/bitcoin-da", default-features = false } -citrea-primitives = { path = "../../../crates/primitives" } -citrea-risc0-adapter = { path = "../../../crates/risc0" } -citrea-stf = { path = "../../../crates/citrea-stf" } +bitcoin-da = { path = "../../../../crates/bitcoin-da", default-features = false } +citrea-primitives = { path = "../../../../crates/primitives" } +citrea-risc0-adapter = { path = "../../../../crates/risc0" } +citrea-stf = { path = "../../../../crates/citrea-stf" } const-hex = "1.12" -sov-modules-api = { path = "../../../crates/sovereign-sdk/module-system/sov-modules-api", default-features = false } -sov-modules-stf-blueprint = { path = "../../../crates/sovereign-sdk/module-system/sov-modules-stf-blueprint" } -sov-rollup-interface = { path = "../../../crates/sovereign-sdk/rollup-interface" } -sov-state = { path = "../../../crates/sovereign-sdk/module-system/sov-state" } +sov-modules-api = { path = "../../../../crates/sovereign-sdk/module-system/sov-modules-api", default-features = false } +sov-modules-stf-blueprint = { path = "../../../../crates/sovereign-sdk/module-system/sov-modules-stf-blueprint" } +sov-rollup-interface = { path = "../../../../crates/sovereign-sdk/rollup-interface" } +sov-state = { path = "../../../../crates/sovereign-sdk/module-system/sov-state" } [features] testing = ["citrea-primitives/testing"] diff --git a/guests/risc0/batch-proof-bitcoin/src/bin/batch_proof_bitcoin.rs b/guests/risc0/batch-proof/bitcoin/src/bin/batch_proof_bitcoin.rs similarity index 100% rename from guests/risc0/batch-proof-bitcoin/src/bin/batch_proof_bitcoin.rs rename to guests/risc0/batch-proof/bitcoin/src/bin/batch_proof_bitcoin.rs diff --git a/guests/risc0/batch-proof/build.rs b/guests/risc0/batch-proof/build.rs new file mode 100644 index 000000000..9167a2506 --- /dev/null +++ b/guests/risc0/batch-proof/build.rs @@ -0,0 +1,75 @@ +use std::collections::HashMap; + +use risc0_build::{embed_methods_with_options, DockerOptions, GuestOptions}; + +fn main() { + println!("cargo:rerun-if-env-changed=SKIP_GUEST_BUILD"); + println!("cargo:rerun-if-env-changed=REPR_GUEST_BUILD"); + println!("cargo:rerun-if-env-changed=OUT_DIR"); + + match std::env::var("SKIP_GUEST_BUILD") { + Ok(value) => match value.as_str() { + "1" | "true" => { + println!("cargo:warning=Skipping guest build"); + let out_dir = std::env::var_os("OUT_DIR").unwrap(); + let out_dir = std::path::Path::new(&out_dir); + let methods_path = out_dir.join("methods.rs"); + + let elf = r#" + pub const BATCH_PROOF_BITCOIN_ELF: &[u8] = &[]; + pub const BATCH_PROOF_BITCOIN_ID: [u32; 8] = [0u32; 8]; + pub const BATCH_PROOF_MOCK_ELF: &[u8] = &[]; + pub const BATCH_PROOF_MOCK_ID: [u32; 8] = [0u32; 8]; + "#; + + return std::fs::write(methods_path, elf).expect("Failed to write mock rollup elf"); + } + "0" | "false" => { + println!("cargo:warning=Performing guest build"); + } + _ => { + println!("cargo:warning=Invalid value for SKIP_GUEST_BUILD: '{}'. Expected '0', '1', 'true', or 'false'. Defaulting to performing guest build.", value); + } + }, + Err(std::env::VarError::NotPresent) => { + println!( + "cargo:warning=SKIP_GUEST_BUILD not set. Defaulting to performing guest build." + ); + } + Err(std::env::VarError::NotUnicode(_)) => { + println!("cargo:warning=SKIP_GUEST_BUILD contains invalid Unicode. Defaulting to performing guest build."); + } + } + let guest_pkg_to_options = get_guest_options(); + embed_methods_with_options(guest_pkg_to_options); +} + +fn get_guest_options() -> HashMap<&'static str, risc0_build::GuestOptions> { + let mut guest_pkg_to_options = HashMap::new(); + + let mut features = Vec::new(); + + if std::env::var("CARGO_FEATURE_TESTING").is_ok() { + features.push("testing".to_string()); + } + + let use_docker = if std::env::var("REPR_GUEST_BUILD").is_ok() { + let this_package_dir = std::env!("CARGO_MANIFEST_DIR"); + let root_dir = format!("{this_package_dir}/../../"); + Some(DockerOptions { + root_dir: Some(root_dir.into()), + }) + } else { + println!("cargo:warning=Guest code is not built in docker"); + None + }; + + let opts = GuestOptions { + features, + use_docker, + }; + + guest_pkg_to_options.insert("batch-proof-bitcoin", opts.clone()); + guest_pkg_to_options.insert("batch-proof-mock", opts.clone()); + guest_pkg_to_options +} diff --git a/guests/risc0/batch-proof-mock/Cargo.lock b/guests/risc0/batch-proof/mock/Cargo.lock similarity index 100% rename from guests/risc0/batch-proof-mock/Cargo.lock rename to guests/risc0/batch-proof/mock/Cargo.lock diff --git a/guests/risc0/batch-proof-mock/Cargo.toml b/guests/risc0/batch-proof/mock/Cargo.toml similarity index 57% rename from guests/risc0/batch-proof-mock/Cargo.toml rename to guests/risc0/batch-proof/mock/Cargo.toml index 08a412b50..dfd623d16 100644 --- a/guests/risc0/batch-proof-mock/Cargo.toml +++ b/guests/risc0/batch-proof/mock/Cargo.toml @@ -11,15 +11,15 @@ risc0-zkvm = { version = "1.1.3", default-features = false } risc0-zkvm-platform = { version = "1.1.3" } anyhow = "1.0" -citrea-primitives = { path = "../../../crates/primitives" } -citrea-risc0-adapter = { path = "../../../crates/risc0" } -citrea-stf = { path = "../../../crates/citrea-stf" } +citrea-primitives = { path = "../../../../crates/primitives" } +citrea-risc0-adapter = { path = "../../../../crates/risc0" } +citrea-stf = { path = "../../../../crates/citrea-stf" } const-hex = "1.12" -sov-mock-da = { path = "../../../crates/sovereign-sdk/adapters/mock-da", default-features = false } -sov-modules-api = { path = "../../../crates/sovereign-sdk/module-system/sov-modules-api", default-features = false } -sov-modules-stf-blueprint = { path = "../../../crates/sovereign-sdk/module-system/sov-modules-stf-blueprint" } -sov-rollup-interface = { path = "../../../crates/sovereign-sdk/rollup-interface" } -sov-state = { path = "../../../crates/sovereign-sdk/module-system/sov-state" } +sov-mock-da = { path = "../../../../crates/sovereign-sdk/adapters/mock-da", default-features = false } +sov-modules-api = { path = "../../../../crates/sovereign-sdk/module-system/sov-modules-api", default-features = false } +sov-modules-stf-blueprint = { path = "../../../../crates/sovereign-sdk/module-system/sov-modules-stf-blueprint" } +sov-rollup-interface = { path = "../../../../crates/sovereign-sdk/rollup-interface" } +sov-state = { path = "../../../../crates/sovereign-sdk/module-system/sov-state" } [features] testing = ["citrea-primitives/testing"] diff --git a/guests/risc0/batch-proof-mock/src/bin/batch_proof_mock.rs b/guests/risc0/batch-proof/mock/src/bin/batch_proof_mock.rs similarity index 100% rename from guests/risc0/batch-proof-mock/src/bin/batch_proof_mock.rs rename to guests/risc0/batch-proof/mock/src/bin/batch_proof_mock.rs diff --git a/guests/risc0/src/lib.rs b/guests/risc0/batch-proof/src/lib.rs similarity index 100% rename from guests/risc0/src/lib.rs rename to guests/risc0/batch-proof/src/lib.rs diff --git a/guests/risc0/light-client-proof/Cargo.toml b/guests/risc0/light-client-proof/Cargo.toml new file mode 100644 index 000000000..ed168f461 --- /dev/null +++ b/guests/risc0/light-client-proof/Cargo.toml @@ -0,0 +1,20 @@ +[package] +name = "citrea-risc0-light-client" +version = "0.5.0-rc.1" +edition = "2021" +license = "MIT OR Apache-2.0" +publish = false +resolver = "2" + +[build-dependencies] +risc0-build = { workspace = true } + +[package.metadata.risc0] +methods = [ + "bitcoin", + "mock", +] + +[features] +bench = [] +testing = [] diff --git a/guests/risc0/light-client-proof-bitcoin/Cargo.lock b/guests/risc0/light-client-proof/bitcoin/Cargo.lock similarity index 100% rename from guests/risc0/light-client-proof-bitcoin/Cargo.lock rename to guests/risc0/light-client-proof/bitcoin/Cargo.lock diff --git a/guests/risc0/light-client-proof-bitcoin/Cargo.toml b/guests/risc0/light-client-proof/bitcoin/Cargo.toml similarity index 57% rename from guests/risc0/light-client-proof-bitcoin/Cargo.toml rename to guests/risc0/light-client-proof/bitcoin/Cargo.toml index a603b6097..7b6687d6c 100644 --- a/guests/risc0/light-client-proof-bitcoin/Cargo.toml +++ b/guests/risc0/light-client-proof/bitcoin/Cargo.toml @@ -11,16 +11,16 @@ risc0-zkvm = { version = "1.1.3", default-features = false } risc0-zkvm-platform = { version = "1.1.3" } anyhow = "1.0.68" -bitcoin-da = { path = "../../../crates/bitcoin-da", default-features = false } -citrea-light-client-prover = { path = "../../../crates/light-client-prover", default-features = false } -citrea-primitives = { path = "../../../crates/primitives" } -citrea-risc0-adapter = { path = "../../../crates/risc0" } +bitcoin-da = { path = "../../../../crates/bitcoin-da", default-features = false } +citrea-light-client-prover = { path = "../../../../crates/light-client-prover", default-features = false } +citrea-primitives = { path = "../../../../crates/primitives" } +citrea-risc0-adapter = { path = "../../../../crates/risc0" } const-hex = "1.12" constmuck = "1.1" -sov-modules-api = { path = "../../../crates/sovereign-sdk/module-system/sov-modules-api", default-features = false } -sov-modules-stf-blueprint = { path = "../../../crates/sovereign-sdk/module-system/sov-modules-stf-blueprint" } -sov-rollup-interface = { path = "../../../crates/sovereign-sdk/rollup-interface" } -sov-state = { path = "../../../crates/sovereign-sdk/module-system/sov-state" } +sov-modules-api = { path = "../../../../crates/sovereign-sdk/module-system/sov-modules-api", default-features = false } +sov-modules-stf-blueprint = { path = "../../../../crates/sovereign-sdk/module-system/sov-modules-stf-blueprint" } +sov-rollup-interface = { path = "../../../../crates/sovereign-sdk/rollup-interface" } +sov-state = { path = "../../../../crates/sovereign-sdk/module-system/sov-state" } [features] testing = ["citrea-primitives/testing"] diff --git a/guests/risc0/light-client-proof-bitcoin/src/bin/light_client_proof_bitcoin.rs b/guests/risc0/light-client-proof/bitcoin/src/bin/light_client_proof_bitcoin.rs similarity index 100% rename from guests/risc0/light-client-proof-bitcoin/src/bin/light_client_proof_bitcoin.rs rename to guests/risc0/light-client-proof/bitcoin/src/bin/light_client_proof_bitcoin.rs diff --git a/guests/risc0/build.rs b/guests/risc0/light-client-proof/build.rs similarity index 87% rename from guests/risc0/build.rs rename to guests/risc0/light-client-proof/build.rs index 163238bf0..5927eadaf 100644 --- a/guests/risc0/build.rs +++ b/guests/risc0/light-client-proof/build.rs @@ -16,10 +16,6 @@ fn main() { let methods_path = out_dir.join("methods.rs"); let elf = r#" - pub const BATCH_PROOF_BITCOIN_ELF: &[u8] = &[]; - pub const BATCH_PROOF_BITCOIN_ID: [u32; 8] = [0u32; 8]; - pub const BATCH_PROOF_MOCK_ELF: &[u8] = &[]; - pub const BATCH_PROOF_MOCK_ID: [u32; 8] = [0u32; 8]; pub const LIGHT_CLIENT_PROOF_BITCOIN_ELF: &[u8] = &[]; pub const LIGHT_CLIENT_PROOF_BITCOIN_ID: [u32; 8] = [0u32; 8]; pub const LIGHT_CLIENT_PROOF_MOCK_ELF: &[u8] = &[]; @@ -73,8 +69,6 @@ fn get_guest_options() -> HashMap<&'static str, risc0_build::GuestOptions> { use_docker, }; - guest_pkg_to_options.insert("batch-proof-bitcoin", opts.clone()); - guest_pkg_to_options.insert("batch-proof-mock", opts.clone()); guest_pkg_to_options.insert("light-client-proof-bitcoin", opts.clone()); guest_pkg_to_options.insert("light-client-proof-mock", opts); guest_pkg_to_options diff --git a/guests/risc0/light-client-proof-mock/Cargo.lock b/guests/risc0/light-client-proof/mock/Cargo.lock similarity index 100% rename from guests/risc0/light-client-proof-mock/Cargo.lock rename to guests/risc0/light-client-proof/mock/Cargo.lock diff --git a/guests/risc0/light-client-proof-mock/Cargo.toml b/guests/risc0/light-client-proof/mock/Cargo.toml similarity index 53% rename from guests/risc0/light-client-proof-mock/Cargo.toml rename to guests/risc0/light-client-proof/mock/Cargo.toml index a67d8999c..40a7ee675 100644 --- a/guests/risc0/light-client-proof-mock/Cargo.toml +++ b/guests/risc0/light-client-proof/mock/Cargo.toml @@ -11,17 +11,17 @@ risc0-zkvm = { version = "1.1.3", default-features = false } risc0-zkvm-platform = { version = "1.1.3" } anyhow = "1.0.68" -sov-mock-da = { path = "../../../crates/sovereign-sdk/adapters/mock-da", default-features = false } +sov-mock-da = { path = "../../../../crates/sovereign-sdk/adapters/mock-da", default-features = false } -citrea-light-client-prover = { path = "../../../crates/light-client-prover", default-features = false } -citrea-primitives = { path = "../../../crates/primitives" } -citrea-risc0-adapter = { path = "../../../crates/risc0" } +citrea-light-client-prover = { path = "../../../../crates/light-client-prover", default-features = false } +citrea-primitives = { path = "../../../../crates/primitives" } +citrea-risc0-adapter = { path = "../../../../crates/risc0" } const-hex = "1.12" constmuck = "1.1" -sov-modules-api = { path = "../../../crates/sovereign-sdk/module-system/sov-modules-api", default-features = false } -sov-modules-stf-blueprint = { path = "../../../crates/sovereign-sdk/module-system/sov-modules-stf-blueprint" } -sov-rollup-interface = { path = "../../../crates/sovereign-sdk/rollup-interface" } -sov-state = { path = "../../../crates/sovereign-sdk/module-system/sov-state" } +sov-modules-api = { path = "../../../../crates/sovereign-sdk/module-system/sov-modules-api", default-features = false } +sov-modules-stf-blueprint = { path = "../../../../crates/sovereign-sdk/module-system/sov-modules-stf-blueprint" } +sov-rollup-interface = { path = "../../../../crates/sovereign-sdk/rollup-interface" } +sov-state = { path = "../../../../crates/sovereign-sdk/module-system/sov-state" } [features] testing = ["citrea-primitives/testing"] diff --git a/guests/risc0/light-client-proof-mock/src/bin/light_client_proof_mock.rs b/guests/risc0/light-client-proof/mock/src/bin/light_client_proof_mock.rs similarity index 100% rename from guests/risc0/light-client-proof-mock/src/bin/light_client_proof_mock.rs rename to guests/risc0/light-client-proof/mock/src/bin/light_client_proof_mock.rs diff --git a/guests/risc0/light-client-proof/src/lib.rs b/guests/risc0/light-client-proof/src/lib.rs new file mode 100644 index 000000000..1bdb3085f --- /dev/null +++ b/guests/risc0/light-client-proof/src/lib.rs @@ -0,0 +1 @@ +include!(concat!(env!("OUT_DIR"), "/methods.rs")); From 82f24b50b1177c6277fe24a014fecdca27ec6398 Mon Sep 17 00:00:00 2001 From: yaziciahmet Date: Fri, 20 Dec 2024 10:06:02 +0100 Subject: [PATCH 76/96] Update docker and make file --- guests/risc0/Dockerfile | 4 ++-- guests/risc0/Makefile | 8 ++++---- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/guests/risc0/Dockerfile b/guests/risc0/Dockerfile index 078d569e9..e6714df53 100644 --- a/guests/risc0/Dockerfile +++ b/guests/risc0/Dockerfile @@ -6,7 +6,7 @@ ARG CITREA_NETWORK COPY . . -ENV CARGO_MANIFEST_PATH="guests/risc0/${GUEST_NAME}/Cargo.toml" +ENV CARGO_MANIFEST_PATH="guests/risc0/${GUEST_NAME}/bitcoin/Cargo.toml" ENV RUSTFLAGS="-C passes=loweratomic -C link-arg=-Ttext=0x00200800 -C link-arg=--fatal-warnings" ENV CARGO_TARGET_DIR="target" ENV CC_riscv32im_risc0_zkvm_elf="/root/.local/share/cargo-risczero/cpp/bin/riscv32-unknown-elf-gcc" @@ -21,4 +21,4 @@ FROM scratch AS export ARG GUEST_NAME -COPY --from=build /src/target/riscv32im-risc0-zkvm-elf/release /${GUEST_NAME} +COPY --from=build /src/target/riscv32im-risc0-zkvm-elf/release "/${GUEST_NAME}-bitcoin" diff --git a/guests/risc0/Makefile b/guests/risc0/Makefile index c115e5ded..52876c368 100644 --- a/guests/risc0/Makefile +++ b/guests/risc0/Makefile @@ -6,12 +6,12 @@ all: batch-proof-bitcoin light-client-bitcoin .PHONY: batch-proof-bitcoin batch-proof-bitcoin: cd ../../ && \ - cargo risczero build --manifest-path guests/risc0/batch-proof-bitcoin/Cargo.toml + cargo risczero build --manifest-path guests/risc0/batch-proof/bitcoin/Cargo.toml .PHONY: light-client-bitcoin light-client-bitcoin: cd ../../ && \ - cargo risczero build --manifest-path guests/risc0/light-client-proof-bitcoin/Cargo.toml + cargo risczero build --manifest-path guests/risc0/light-client-proof/bitcoin/Cargo.toml .PHONY: batch-proof-bitcoin-docker batch-proof-bitcoin-docker: @@ -20,7 +20,7 @@ batch-proof-bitcoin-docker: --platform linux/amd64 \ --output ./target/riscv-guest/riscv32im-risc0-zkvm-elf/docker \ -f ./guests/risc0/Dockerfile \ - --build-arg GUEST_NAME=batch-proof-bitcoin \ + --build-arg GUEST_NAME=batch-proof \ --build-arg CITREA_NETWORK=$(CITREA_NETWORK) \ -t batch-proof-bitcoin:latest \ --no-cache \ @@ -34,7 +34,7 @@ light-client-bitcoin-docker: --platform linux/amd64 \ --output ./target/riscv-guest/riscv32im-risc0-zkvm-elf/docker \ -f ./guests/risc0/Dockerfile \ - --build-arg GUEST_NAME=light-client-proof-bitcoin \ + --build-arg GUEST_NAME=light-client-proof \ --build-arg CITREA_NETWORK=$(CITREA_NETWORK) \ -t light-client-proof-bitcoin:latest \ --no-cache \ From c8264a528b4c0e7c8451f068a1c5f9449e7612a2 Mon Sep 17 00:00:00 2001 From: yaziciahmet Date: Fri, 20 Dec 2024 13:18:10 +0100 Subject: [PATCH 77/96] Use batch proof method id from build in light client --- .../light-client-proof/bitcoin/Cargo.lock | 312 ++++++++++++++++++ .../light-client-proof/bitcoin/Cargo.toml | 3 +- .../src/bin/light_client_proof_bitcoin.rs | 17 +- .../risc0/light-client-proof/mock/Cargo.lock | 312 ++++++++++++++++++ .../risc0/light-client-proof/mock/Cargo.toml | 3 +- .../mock/src/bin/light_client_proof_mock.rs | 6 +- 6 files changed, 640 insertions(+), 13 deletions(-) diff --git a/guests/risc0/light-client-proof/bitcoin/Cargo.lock b/guests/risc0/light-client-proof/bitcoin/Cargo.lock index b2907267c..0f699a5ce 100644 --- a/guests/risc0/light-client-proof/bitcoin/Cargo.lock +++ b/guests/risc0/light-client-proof/bitcoin/Cargo.lock @@ -558,6 +558,38 @@ version = "1.7.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "428d9aa8fbc0670b7b8d6030a7fadd0f86151cae55e4dbbece15f3780a3dfaf3" +[[package]] +name = "camino" +version = "1.1.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8b96ec4966b5813e2c0507c1f86115c8c5abaadc3980879c3424042a02fd1ad3" +dependencies = [ + "serde", +] + +[[package]] +name = "cargo-platform" +version = "0.1.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e35af189006b9c0f00a064685c727031e3ed2d8020f7ba284d78cc2671bd36ea" +dependencies = [ + "serde", +] + +[[package]] +name = "cargo_metadata" +version = "0.18.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2d886547e41f740c616ae73108f6eb70afe6d940c7bc697cb30f13daec073037" +dependencies = [ + "camino", + "cargo-platform", + "semver", + "serde", + "serde_json", + "thiserror", +] + [[package]] name = "cc" version = "1.1.25" @@ -613,6 +645,13 @@ dependencies = [ "tracing", ] +[[package]] +name = "citrea-risc0-batch-proof" +version = "0.5.0-rc.1" +dependencies = [ + "risc0-build", +] + [[package]] name = "const-hex" version = "1.13.1" @@ -818,6 +857,33 @@ dependencies = [ "subtle", ] +[[package]] +name = "dirs" +version = "5.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "44c45a9d03d6676652bcb5e724c7e988de1acad23a711b5217ab9cbecbec2225" +dependencies = [ + "dirs-sys", +] + +[[package]] +name = "dirs-sys" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "520f05a5cbd335fae5a99ff7a6ab8627577660ee5cfd6a94a6a929b52ff0321c" +dependencies = [ + "libc", + "option-ext", + "redox_users", + "windows-sys 0.48.0", +] + +[[package]] +name = "docker-generate" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ccf673e0848ef09fa4aeeba78e681cf651c0c7d35f76ee38cec8e55bc32fa111" + [[package]] name = "downcast-rs" version = "1.2.1" @@ -870,6 +936,22 @@ version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5443807d6dff69373d433ab9ef5378ad8df50ca6298caf15de6e52e24aaf54d5" +[[package]] +name = "errno" +version = "0.3.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "33d852cb9b869c2a9b3df2f71a3074817f01e1844f839a144f5fcef059a4eb5d" +dependencies = [ + "libc", + "windows-sys 0.59.0", +] + +[[package]] +name = "fastrand" +version = "2.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "37909eebbb50d72f9059c3b6d82c0463f2ff062c9e95845c43a6c9c0355411be" + [[package]] name = "fiat-crypto" version = "0.2.9" @@ -1178,6 +1260,16 @@ version = "0.2.8" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4ec2a862134d2a7d32d7983ddcdd1c4923530833c9f2ea1a44fc5fa473989058" +[[package]] +name = "libredox" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c0ff37bd590ca25063e35af745c343cb7a0271906fb7b37e4813e8f79f00268d" +dependencies = [ + "bitflags 2.6.0", + "libc", +] + [[package]] name = "light-client-proof-bitcoin" version = "0.5.0-rc.1" @@ -1187,6 +1279,7 @@ dependencies = [ "citrea-light-client-prover", "citrea-primitives", "citrea-risc0-adapter", + "citrea-risc0-batch-proof", "const-hex", "constmuck", "risc0-zkvm", @@ -1197,6 +1290,12 @@ dependencies = [ "sov-state", ] +[[package]] +name = "linux-raw-sys" +version = "0.4.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "78b3ae25bc7c8c38cec158d1f2757ee79e9b3740fbc7ccf0e59e4b08d793fa89" + [[package]] name = "log" version = "0.4.22" @@ -1294,6 +1393,12 @@ version = "1.20.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1261fe7e33c73b354eab43b1273a57c8f967d0391e80353e51f764ac02cf6775" +[[package]] +name = "option-ext" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "04744f49eae99ab78e0d5c0b603ab218f515ea8cfe5a456d7629ad883a3b6e7d" + [[package]] name = "paste" version = "1.0.15" @@ -1455,6 +1560,17 @@ dependencies = [ "rand_core", ] +[[package]] +name = "redox_users" +version = "0.4.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ba009ff324d1fc1b900bd1fdb31564febe58a8ccc8a6fdbb93b543d33b13ca43" +dependencies = [ + "getrandom", + "libredox", + "thiserror", +] + [[package]] name = "regex-syntax" version = "0.8.5" @@ -1486,6 +1602,25 @@ dependencies = [ "tracing", ] +[[package]] +name = "risc0-build" +version = "1.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dc684382e24a8c91331040c33f1c789c755a5c1b0b8a32fefc1730ca36dd7072" +dependencies = [ + "anyhow", + "cargo_metadata", + "dirs", + "docker-generate", + "hex", + "risc0-binfmt", + "risc0-zkp", + "risc0-zkvm-platform", + "serde", + "serde_json", + "tempfile", +] + [[package]] name = "risc0-circuit-recursion" version = "1.1.3" @@ -1658,6 +1793,19 @@ dependencies = [ "semver", ] +[[package]] +name = "rustix" +version = "0.38.37" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8acb788b847c24f28525660c4d7758620a7210875711f79e7f663cc152726811" +dependencies = [ + "bitflags 2.6.0", + "errno", + "libc", + "linux-raw-sys", + "windows-sys 0.52.0", +] + [[package]] name = "ryu" version = "1.0.18" @@ -1712,6 +1860,9 @@ name = "semver" version = "1.0.23" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "61697e0a1c7e512e84a621326239844a24d8207b4669b41bc18b32ea5cbf988b" +dependencies = [ + "serde", +] [[package]] name = "serde" @@ -1931,6 +2082,19 @@ dependencies = [ "syn 2.0.87", ] +[[package]] +name = "tempfile" +version = "3.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f0f2c9fc62d0beef6951ccffd757e241266a2c833136efbe35af6cd2567dca5b" +dependencies = [ + "cfg-if", + "fastrand", + "once_cell", + "rustix", + "windows-sys 0.59.0", +] + [[package]] name = "thiserror" version = "1.0.64" @@ -2067,6 +2231,154 @@ version = "0.11.0+wasi-snapshot-preview1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" +[[package]] +name = "windows-sys" +version = "0.48.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "677d2418bec65e3338edb076e806bc1ec15693c5d0104683f2efe857f61056a9" +dependencies = [ + "windows-targets 0.48.5", +] + +[[package]] +name = "windows-sys" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d" +dependencies = [ + "windows-targets 0.52.6", +] + +[[package]] +name = "windows-sys" +version = "0.59.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e38bc4d79ed67fd075bcc251a1c39b32a1776bbe92e5bef1f0bf1f8c531853b" +dependencies = [ + "windows-targets 0.52.6", +] + +[[package]] +name = "windows-targets" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9a2fa6e2155d7247be68c096456083145c183cbbbc2764150dda45a87197940c" +dependencies = [ + "windows_aarch64_gnullvm 0.48.5", + "windows_aarch64_msvc 0.48.5", + "windows_i686_gnu 0.48.5", + "windows_i686_msvc 0.48.5", + "windows_x86_64_gnu 0.48.5", + "windows_x86_64_gnullvm 0.48.5", + "windows_x86_64_msvc 0.48.5", +] + +[[package]] +name = "windows-targets" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9b724f72796e036ab90c1021d4780d4d3d648aca59e491e6b98e725b84e99973" +dependencies = [ + "windows_aarch64_gnullvm 0.52.6", + "windows_aarch64_msvc 0.52.6", + "windows_i686_gnu 0.52.6", + "windows_i686_gnullvm", + "windows_i686_msvc 0.52.6", + "windows_x86_64_gnu 0.52.6", + "windows_x86_64_gnullvm 0.52.6", + "windows_x86_64_msvc 0.52.6", +] + +[[package]] +name = "windows_aarch64_gnullvm" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2b38e32f0abccf9987a4e3079dfb67dcd799fb61361e53e2882c3cbaf0d905d8" + +[[package]] +name = "windows_aarch64_gnullvm" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3" + +[[package]] +name = "windows_aarch64_msvc" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dc35310971f3b2dbbf3f0690a219f40e2d9afcf64f9ab7cc1be722937c26b4bc" + +[[package]] +name = "windows_aarch64_msvc" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469" + +[[package]] +name = "windows_i686_gnu" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a75915e7def60c94dcef72200b9a8e58e5091744960da64ec734a6c6e9b3743e" + +[[package]] +name = "windows_i686_gnu" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8e9b5ad5ab802e97eb8e295ac6720e509ee4c243f69d781394014ebfe8bbfa0b" + +[[package]] +name = "windows_i686_gnullvm" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0eee52d38c090b3caa76c563b86c3a4bd71ef1a819287c19d586d7334ae8ed66" + +[[package]] +name = "windows_i686_msvc" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8f55c233f70c4b27f66c523580f78f1004e8b5a8b659e05a4eb49d4166cca406" + +[[package]] +name = "windows_i686_msvc" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66" + +[[package]] +name = "windows_x86_64_gnu" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "53d40abd2583d23e4718fddf1ebec84dbff8381c07cae67ff7768bbf19c6718e" + +[[package]] +name = "windows_x86_64_gnu" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78" + +[[package]] +name = "windows_x86_64_gnullvm" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0b7b52767868a23d5bab768e390dc5f5c55825b6d30b86c844ff2dc7414044cc" + +[[package]] +name = "windows_x86_64_gnullvm" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d" + +[[package]] +name = "windows_x86_64_msvc" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ed94fce61571a4006852b7389a063ab983c02eb1bb37b47f8272ce92d06d9538" + +[[package]] +name = "windows_x86_64_msvc" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec" + [[package]] name = "winnow" version = "0.6.20" diff --git a/guests/risc0/light-client-proof/bitcoin/Cargo.toml b/guests/risc0/light-client-proof/bitcoin/Cargo.toml index 7b6687d6c..b9376cae0 100644 --- a/guests/risc0/light-client-proof/bitcoin/Cargo.toml +++ b/guests/risc0/light-client-proof/bitcoin/Cargo.toml @@ -15,6 +15,7 @@ bitcoin-da = { path = "../../../../crates/bitcoin-da", default-features = false citrea-light-client-prover = { path = "../../../../crates/light-client-prover", default-features = false } citrea-primitives = { path = "../../../../crates/primitives" } citrea-risc0-adapter = { path = "../../../../crates/risc0" } +citrea-risc0-batch-proof = { path = "../../batch-proof" } const-hex = "1.12" constmuck = "1.1" sov-modules-api = { path = "../../../../crates/sovereign-sdk/module-system/sov-modules-api", default-features = false } @@ -23,7 +24,7 @@ sov-rollup-interface = { path = "../../../../crates/sovereign-sdk/rollup-interfa sov-state = { path = "../../../../crates/sovereign-sdk/module-system/sov-state" } [features] -testing = ["citrea-primitives/testing"] +testing = ["citrea-primitives/testing", "citrea-risc0-batch-proof/testing"] [patch.crates-io] sha2 = { git = "https://github.com/risc0/RustCrypto-hashes", tag = "sha2-v0.10.8-risczero.0" } diff --git a/guests/risc0/light-client-proof/bitcoin/src/bin/light_client_proof_bitcoin.rs b/guests/risc0/light-client-proof/bitcoin/src/bin/light_client_proof_bitcoin.rs index 0e411db03..dac874bf0 100644 --- a/guests/risc0/light-client-proof/bitcoin/src/bin/light_client_proof_bitcoin.rs +++ b/guests/risc0/light-client-proof/bitcoin/src/bin/light_client_proof_bitcoin.rs @@ -40,23 +40,28 @@ const L2_GENESIS_ROOT: [u8; 32] = { } }; -// TODO: Find batch proof method ids of networks const BATCH_PROOF_METHOD_ID: [u32; 8] = { + // TODO: Don't forget to always update devnet, testnet, mainnet method ids just before release let hex_method_id = match NETWORK { Network::Mainnet => "0000000000000000000000000000000000000000000000000000000000000000", Network::Testnet => "0000000000000000000000000000000000000000000000000000000000000000", Network::Devnet => "0000000000000000000000000000000000000000000000000000000000000000", Network::Nightly => { match option_env!("BATCH_PROOF_METHOD_ID") { - Some(hex_root) => hex_root, - None => "0000000000000000000000000000000000000000000000000000000000000000", + Some(hex_method_id) => hex_method_id, + None => "", } } }; - match const_hex::const_decode_to_array::<32>(hex_method_id.as_bytes()) { - Ok(method_id) => constmuck::cast(method_id), - Err(_) => panic!("BATCH_PROOF_METHOD_ID must be valid 32-byte hex string"), + // Use default nightly batch proof method_id + if hex_method_id.is_empty() { + citrea_risc0_batch_proof::BATCH_PROOF_BITCOIN_ID + } else { + match const_hex::const_decode_to_array::<32>(hex_method_id.as_bytes()) { + Ok(method_id) => constmuck::cast(method_id), + Err(_) => panic!("BATCH_PROOF_METHOD_ID must be valid 32-byte hex string"), + } } }; diff --git a/guests/risc0/light-client-proof/mock/Cargo.lock b/guests/risc0/light-client-proof/mock/Cargo.lock index be2f614cd..f46282c44 100644 --- a/guests/risc0/light-client-proof/mock/Cargo.lock +++ b/guests/risc0/light-client-proof/mock/Cargo.lock @@ -470,6 +470,38 @@ dependencies = [ "serde", ] +[[package]] +name = "camino" +version = "1.1.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8b96ec4966b5813e2c0507c1f86115c8c5abaadc3980879c3424042a02fd1ad3" +dependencies = [ + "serde", +] + +[[package]] +name = "cargo-platform" +version = "0.1.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e35af189006b9c0f00a064685c727031e3ed2d8020f7ba284d78cc2671bd36ea" +dependencies = [ + "serde", +] + +[[package]] +name = "cargo_metadata" +version = "0.18.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2d886547e41f740c616ae73108f6eb70afe6d940c7bc697cb30f13daec073037" +dependencies = [ + "camino", + "cargo-platform", + "semver", + "serde", + "serde_json", + "thiserror", +] + [[package]] name = "cc" version = "1.1.25" @@ -525,6 +557,13 @@ dependencies = [ "tracing", ] +[[package]] +name = "citrea-risc0-batch-proof" +version = "0.5.0-rc.1" +dependencies = [ + "risc0-build", +] + [[package]] name = "const-hex" version = "1.13.1" @@ -729,6 +768,33 @@ dependencies = [ "subtle", ] +[[package]] +name = "dirs" +version = "5.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "44c45a9d03d6676652bcb5e724c7e988de1acad23a711b5217ab9cbecbec2225" +dependencies = [ + "dirs-sys", +] + +[[package]] +name = "dirs-sys" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "520f05a5cbd335fae5a99ff7a6ab8627577660ee5cfd6a94a6a929b52ff0321c" +dependencies = [ + "libc", + "option-ext", + "redox_users", + "windows-sys 0.48.0", +] + +[[package]] +name = "docker-generate" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ccf673e0848ef09fa4aeeba78e681cf651c0c7d35f76ee38cec8e55bc32fa111" + [[package]] name = "downcast-rs" version = "1.2.1" @@ -781,6 +847,22 @@ version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5443807d6dff69373d433ab9ef5378ad8df50ca6298caf15de6e52e24aaf54d5" +[[package]] +name = "errno" +version = "0.3.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "33d852cb9b869c2a9b3df2f71a3074817f01e1844f839a144f5fcef059a4eb5d" +dependencies = [ + "libc", + "windows-sys 0.59.0", +] + +[[package]] +name = "fastrand" +version = "2.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "37909eebbb50d72f9059c3b6d82c0463f2ff062c9e95845c43a6c9c0355411be" + [[package]] name = "fiat-crypto" version = "0.2.9" @@ -985,6 +1067,16 @@ version = "0.2.8" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4ec2a862134d2a7d32d7983ddcdd1c4923530833c9f2ea1a44fc5fa473989058" +[[package]] +name = "libredox" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c0ff37bd590ca25063e35af745c343cb7a0271906fb7b37e4813e8f79f00268d" +dependencies = [ + "bitflags 2.6.0", + "libc", +] + [[package]] name = "light-client-proof-mock" version = "0.5.0-rc.1" @@ -993,6 +1085,7 @@ dependencies = [ "citrea-light-client-prover", "citrea-primitives", "citrea-risc0-adapter", + "citrea-risc0-batch-proof", "const-hex", "constmuck", "risc0-zkvm", @@ -1004,6 +1097,12 @@ dependencies = [ "sov-state", ] +[[package]] +name = "linux-raw-sys" +version = "0.4.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "78b3ae25bc7c8c38cec158d1f2757ee79e9b3740fbc7ccf0e59e4b08d793fa89" + [[package]] name = "log" version = "0.4.22" @@ -1101,6 +1200,12 @@ version = "1.20.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1261fe7e33c73b354eab43b1273a57c8f967d0391e80353e51f764ac02cf6775" +[[package]] +name = "option-ext" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "04744f49eae99ab78e0d5c0b603ab218f515ea8cfe5a456d7629ad883a3b6e7d" + [[package]] name = "paste" version = "1.0.15" @@ -1256,6 +1361,17 @@ dependencies = [ "rand_core", ] +[[package]] +name = "redox_users" +version = "0.4.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ba009ff324d1fc1b900bd1fdb31564febe58a8ccc8a6fdbb93b543d33b13ca43" +dependencies = [ + "getrandom", + "libredox", + "thiserror", +] + [[package]] name = "regex-syntax" version = "0.8.5" @@ -1287,6 +1403,25 @@ dependencies = [ "tracing", ] +[[package]] +name = "risc0-build" +version = "1.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dc684382e24a8c91331040c33f1c789c755a5c1b0b8a32fefc1730ca36dd7072" +dependencies = [ + "anyhow", + "cargo_metadata", + "dirs", + "docker-generate", + "hex", + "risc0-binfmt", + "risc0-zkp", + "risc0-zkvm-platform", + "serde", + "serde_json", + "tempfile", +] + [[package]] name = "risc0-circuit-recursion" version = "1.1.3" @@ -1459,6 +1594,19 @@ dependencies = [ "semver", ] +[[package]] +name = "rustix" +version = "0.38.37" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8acb788b847c24f28525660c4d7758620a7210875711f79e7f663cc152726811" +dependencies = [ + "bitflags 2.6.0", + "errno", + "libc", + "linux-raw-sys", + "windows-sys 0.52.0", +] + [[package]] name = "ryu" version = "1.0.18" @@ -1494,6 +1642,9 @@ name = "semver" version = "1.0.23" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "61697e0a1c7e512e84a621326239844a24d8207b4669b41bc18b32ea5cbf988b" +dependencies = [ + "serde", +] [[package]] name = "serde" @@ -1719,6 +1870,19 @@ dependencies = [ "syn 2.0.87", ] +[[package]] +name = "tempfile" +version = "3.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f0f2c9fc62d0beef6951ccffd757e241266a2c833136efbe35af6cd2567dca5b" +dependencies = [ + "cfg-if", + "fastrand", + "once_cell", + "rustix", + "windows-sys 0.59.0", +] + [[package]] name = "thiserror" version = "1.0.64" @@ -1855,6 +2019,154 @@ version = "0.11.0+wasi-snapshot-preview1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" +[[package]] +name = "windows-sys" +version = "0.48.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "677d2418bec65e3338edb076e806bc1ec15693c5d0104683f2efe857f61056a9" +dependencies = [ + "windows-targets 0.48.5", +] + +[[package]] +name = "windows-sys" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d" +dependencies = [ + "windows-targets 0.52.6", +] + +[[package]] +name = "windows-sys" +version = "0.59.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e38bc4d79ed67fd075bcc251a1c39b32a1776bbe92e5bef1f0bf1f8c531853b" +dependencies = [ + "windows-targets 0.52.6", +] + +[[package]] +name = "windows-targets" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9a2fa6e2155d7247be68c096456083145c183cbbbc2764150dda45a87197940c" +dependencies = [ + "windows_aarch64_gnullvm 0.48.5", + "windows_aarch64_msvc 0.48.5", + "windows_i686_gnu 0.48.5", + "windows_i686_msvc 0.48.5", + "windows_x86_64_gnu 0.48.5", + "windows_x86_64_gnullvm 0.48.5", + "windows_x86_64_msvc 0.48.5", +] + +[[package]] +name = "windows-targets" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9b724f72796e036ab90c1021d4780d4d3d648aca59e491e6b98e725b84e99973" +dependencies = [ + "windows_aarch64_gnullvm 0.52.6", + "windows_aarch64_msvc 0.52.6", + "windows_i686_gnu 0.52.6", + "windows_i686_gnullvm", + "windows_i686_msvc 0.52.6", + "windows_x86_64_gnu 0.52.6", + "windows_x86_64_gnullvm 0.52.6", + "windows_x86_64_msvc 0.52.6", +] + +[[package]] +name = "windows_aarch64_gnullvm" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2b38e32f0abccf9987a4e3079dfb67dcd799fb61361e53e2882c3cbaf0d905d8" + +[[package]] +name = "windows_aarch64_gnullvm" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3" + +[[package]] +name = "windows_aarch64_msvc" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dc35310971f3b2dbbf3f0690a219f40e2d9afcf64f9ab7cc1be722937c26b4bc" + +[[package]] +name = "windows_aarch64_msvc" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469" + +[[package]] +name = "windows_i686_gnu" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a75915e7def60c94dcef72200b9a8e58e5091744960da64ec734a6c6e9b3743e" + +[[package]] +name = "windows_i686_gnu" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8e9b5ad5ab802e97eb8e295ac6720e509ee4c243f69d781394014ebfe8bbfa0b" + +[[package]] +name = "windows_i686_gnullvm" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0eee52d38c090b3caa76c563b86c3a4bd71ef1a819287c19d586d7334ae8ed66" + +[[package]] +name = "windows_i686_msvc" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8f55c233f70c4b27f66c523580f78f1004e8b5a8b659e05a4eb49d4166cca406" + +[[package]] +name = "windows_i686_msvc" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66" + +[[package]] +name = "windows_x86_64_gnu" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "53d40abd2583d23e4718fddf1ebec84dbff8381c07cae67ff7768bbf19c6718e" + +[[package]] +name = "windows_x86_64_gnu" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78" + +[[package]] +name = "windows_x86_64_gnullvm" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0b7b52767868a23d5bab768e390dc5f5c55825b6d30b86c844ff2dc7414044cc" + +[[package]] +name = "windows_x86_64_gnullvm" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d" + +[[package]] +name = "windows_x86_64_msvc" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ed94fce61571a4006852b7389a063ab983c02eb1bb37b47f8272ce92d06d9538" + +[[package]] +name = "windows_x86_64_msvc" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec" + [[package]] name = "winnow" version = "0.6.20" diff --git a/guests/risc0/light-client-proof/mock/Cargo.toml b/guests/risc0/light-client-proof/mock/Cargo.toml index 40a7ee675..2d538687b 100644 --- a/guests/risc0/light-client-proof/mock/Cargo.toml +++ b/guests/risc0/light-client-proof/mock/Cargo.toml @@ -16,6 +16,7 @@ sov-mock-da = { path = "../../../../crates/sovereign-sdk/adapters/mock-da", defa citrea-light-client-prover = { path = "../../../../crates/light-client-prover", default-features = false } citrea-primitives = { path = "../../../../crates/primitives" } citrea-risc0-adapter = { path = "../../../../crates/risc0" } +citrea-risc0-batch-proof = { path = "../../batch-proof" } const-hex = "1.12" constmuck = "1.1" sov-modules-api = { path = "../../../../crates/sovereign-sdk/module-system/sov-modules-api", default-features = false } @@ -24,7 +25,7 @@ sov-rollup-interface = { path = "../../../../crates/sovereign-sdk/rollup-interfa sov-state = { path = "../../../../crates/sovereign-sdk/module-system/sov-state" } [features] -testing = ["citrea-primitives/testing"] +testing = ["citrea-primitives/testing", "citrea-risc0-batch-proof/testing"] [patch.crates-io] sha2 = { git = "https://github.com/risc0/RustCrypto-hashes", tag = "sha2-v0.10.8-risczero.0" } diff --git a/guests/risc0/light-client-proof/mock/src/bin/light_client_proof_mock.rs b/guests/risc0/light-client-proof/mock/src/bin/light_client_proof_mock.rs index d3c57e00a..3bdf1f9d7 100644 --- a/guests/risc0/light-client-proof/mock/src/bin/light_client_proof_mock.rs +++ b/guests/risc0/light-client-proof/mock/src/bin/light_client_proof_mock.rs @@ -11,11 +11,7 @@ const L2_GENESIS_ROOT: [u8; 32] = match const_hex::const_decode_to_array(b"dacb5 Err(_) => panic!("Can't happen"), }; -// TODO: Find batch proof method ids of networks -const BATCH_PROOF_METHOD_ID: [u32; 8] = match const_hex::const_decode_to_array::<32>(b"0000000000000000000000000000000000000000000000000000000000000000") { - Ok(method_id) => constmuck::cast(method_id), - Err(_) => panic!("Can't happen"), -}; +const BATCH_PROOF_METHOD_ID: [u32; 8] = citrea_risc0_batch_proof::BATCH_PROOF_MOCK_ID; const BATCH_PROVER_DA_PUBLIC_KEY: [u8; 33] = match const_hex::const_decode_to_array(b"03eedab888e45f3bdc3ec9918c491c11e5cf7af0a91f38b97fbc1e135ae4056601") { Ok(pub_key) => pub_key, From 4ba939997d30a5a879fa207c5a2a66af7f3503b9 Mon Sep 17 00:00:00 2001 From: yaziciahmet Date: Fri, 20 Dec 2024 14:20:51 +0100 Subject: [PATCH 78/96] Update build-release --- .github/workflows/checks.yml | 14 +++++++------- Makefile | 6 +----- guests/risc0/Makefile | 13 ------------- 3 files changed, 8 insertions(+), 25 deletions(-) diff --git a/.github/workflows/checks.yml b/.github/workflows/checks.yml index c1b96f8cf..c829f6387 100644 --- a/.github/workflows/checks.yml +++ b/.github/workflows/checks.yml @@ -98,7 +98,7 @@ jobs: - name: Build citrea run: make build-release env: - REPR_GUEST_BUILD: 1 + CITREA_NETWORK: nightly - name: Upload artifact uses: actions/upload-artifact@v4 @@ -267,9 +267,9 @@ jobs: run: npm install - name: Run uniswap tests run: | - RUST_LOG=off ./target/release/citrea --da-layer mock --rollup-config-path resources/configs/mock/sequencer_rollup_config.toml --sequencer resources/configs/mock/sequencer_config.toml --genesis-paths resources/genesis/mock/ & + RUST_LOG=off ./target/release/citrea --da-layer mock --rollup-config-path resources/configs/mock/sequencer_rollup_config.toml --sequencer resources/configs/mock/sequencer_config.toml --genesis-paths resources/genesis/mock/ --dev & sleep 2 - RUST_LOG=off ./target/release/citrea --rollup-config-path resources/configs/mock/rollup_config.toml --genesis-paths resources/genesis/mock/ & + RUST_LOG=off ./target/release/citrea --rollup-config-path resources/configs/mock/rollup_config.toml --genesis-paths resources/genesis/mock/ --dev & sleep 2 cd ./bin/citrea/tests/evm/uniswap npx hardhat run --network citrea scripts/01_deploy.js @@ -310,9 +310,9 @@ jobs: run: pip install -r requirements.txt - name: Run web3.py tests run: | - RUST_LOG=off ./target/release/citrea --da-layer mock --rollup-config-path resources/configs/mock/sequencer_rollup_config.toml --sequencer resources/configs/mock/sequencer_config.toml --genesis-paths resources/genesis/mock/ & + RUST_LOG=off ./target/release/citrea --da-layer mock --rollup-config-path resources/configs/mock/sequencer_rollup_config.toml --sequencer resources/configs/mock/sequencer_config.toml --genesis-paths resources/genesis/mock/ --dev & sleep 2 - RUST_LOG=off ./target/release/citrea --da-layer mock --rollup-config-path resources/configs/mock/rollup_config.toml --genesis-paths resources/genesis/mock/ & + RUST_LOG=off ./target/release/citrea --da-layer mock --rollup-config-path resources/configs/mock/rollup_config.toml --genesis-paths resources/genesis/mock/ --dev & sleep 2 cd ./bin/citrea/tests/evm/web3_py python test.py @@ -338,9 +338,9 @@ jobs: run: npm install - name: Run ethers_js tests run: | - RUST_LOG=off ./target/release/citrea --da-layer mock --rollup-config-path resources/configs/mock/sequencer_rollup_config.toml --sequencer resources/configs/mock/sequencer_config.toml --genesis-paths resources/genesis/mock/ & + RUST_LOG=off ./target/release/citrea --da-layer mock --rollup-config-path resources/configs/mock/sequencer_rollup_config.toml --sequencer resources/configs/mock/sequencer_config.toml --genesis-paths resources/genesis/mock/ --dev & sleep 2 - RUST_LOG=off ./target/release/citrea --da-layer mock --rollup-config-path resources/configs/mock/rollup_config.toml --genesis-paths resources/genesis/mock/ & + RUST_LOG=off ./target/release/citrea --da-layer mock --rollup-config-path resources/configs/mock/rollup_config.toml --genesis-paths resources/genesis/mock/ --dev & sleep 2 cd ./bin/citrea/tests/evm/ethers_js npm install diff --git a/Makefile b/Makefile index 0225ab27d..88c283c65 100644 --- a/Makefile +++ b/Makefile @@ -11,10 +11,6 @@ LIGHT_OUT_PATH := resources/guests/risc0/ help: ## Display this help message @awk 'BEGIN {FS = ":.*?## "} /^[a-zA-Z_-]+:.*?## / {printf "\033[36m%-30s\033[0m %s\n", $$1, $$2}' $(MAKEFILE_LIST) -.PHONY: build-risc0 -build-risc0: - $(MAKE) -j 2 -C guests/risc0 all - .PHONY: build-risc0-docker build-risc0-docker: $(MAKE) -C guests/risc0 batch-proof-bitcoin-docker OUT_PATH=$(BATCH_OUT_PATH) @@ -32,7 +28,7 @@ build: ## Build the project build-test: ## Build the project @cargo build $(TEST_FEATURES) -build-release: build-risc0 build-sp1 ## Build the project in release mode +build-release: build-risc0-docker build-sp1 ## Build the project in release mode @cargo build --release clean: ## Cleans compiled diff --git a/guests/risc0/Makefile b/guests/risc0/Makefile index 52876c368..ecf8dd769 100644 --- a/guests/risc0/Makefile +++ b/guests/risc0/Makefile @@ -1,18 +1,5 @@ OUT_PATH := resources/guests/risc0/ -.PHONY: all -all: batch-proof-bitcoin light-client-bitcoin - -.PHONY: batch-proof-bitcoin -batch-proof-bitcoin: - cd ../../ && \ - cargo risczero build --manifest-path guests/risc0/batch-proof/bitcoin/Cargo.toml - -.PHONY: light-client-bitcoin -light-client-bitcoin: - cd ../../ && \ - cargo risczero build --manifest-path guests/risc0/light-client-proof/bitcoin/Cargo.toml - .PHONY: batch-proof-bitcoin-docker batch-proof-bitcoin-docker: cd ../../ && \ From b9a02174a2e4cba129ffff9b339b3377381f132c Mon Sep 17 00:00:00 2001 From: yaziciahmet Date: Fri, 20 Dec 2024 15:17:21 +0100 Subject: [PATCH 79/96] Use input public key for output --- crates/citrea-stf/src/verifier.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/crates/citrea-stf/src/verifier.rs b/crates/citrea-stf/src/verifier.rs index e41b9466c..6ec2ffdb7 100644 --- a/crates/citrea-stf/src/verifier.rs +++ b/crates/citrea-stf/src/verifier.rs @@ -89,8 +89,8 @@ where state_diff, prev_soft_confirmation_hash: data.prev_soft_confirmation_hash, da_slot_hash: data.da_block_header_of_commitments.hash(), - sequencer_public_key: data.sequencer_public_key, - sequencer_da_public_key: data.sequencer_da_public_key, + sequencer_public_key: sequencer_public_key.to_vec(), + sequencer_da_public_key: sequencer_da_public_key.to_vec(), sequencer_commitments_range: data.sequencer_commitments_range, preproven_commitments: data.preproven_commitments, last_l2_height, From 5eb7228665707b1893e1f7509e5963922788736a Mon Sep 17 00:00:00 2001 From: yaziciahmet Date: Fri, 20 Dec 2024 15:23:44 +0100 Subject: [PATCH 80/96] Attempt to make preproven commitments test faster --- .../tests/bitcoin_e2e/batch_prover_test.rs | 21 +++++++++++++++---- 1 file changed, 17 insertions(+), 4 deletions(-) diff --git a/bin/citrea/tests/bitcoin_e2e/batch_prover_test.rs b/bin/citrea/tests/bitcoin_e2e/batch_prover_test.rs index cd0797981..1d70e07fb 100644 --- a/bin/citrea/tests/bitcoin_e2e/batch_prover_test.rs +++ b/bin/citrea/tests/bitcoin_e2e/batch_prover_test.rs @@ -147,6 +147,13 @@ impl TestCase for SkipPreprovenCommitmentsTest { } } + fn sequencer_config() -> SequencerConfig { + SequencerConfig { + min_soft_confirmations_per_commitment: 1, + ..Default::default() + } + } + async fn run_test(&mut self, f: &mut TestFramework) -> Result<()> { let da = f.bitcoin_nodes.get(0).unwrap(); let sequencer = f.sequencer.as_ref().unwrap(); @@ -164,13 +171,19 @@ impl TestCase for SkipPreprovenCommitmentsTest { node_password: da_config.rpc_password.clone(), network: bitcoin::Network::Regtest, da_private_key: Some( - // This is the private key used by the sequencer. // This is because the prover has a check to make sure that the commitment was // submitted by the sequencer and NOT any other key. Which means that arbitrary keys // CANNOT submit preproven commitments. // Using the sequencer DA private key means that we simulate the fact that the sequencer // somehow resubmitted the same commitment. - "045FFC81A3C1FDB3AF1359DBF2D114B0B3EFBF7F29CC9C5DA01267AA39D2C78D".to_owned(), + sequencer + .config() + .rollup + .da + .da_private_key + .as_ref() + .unwrap() + .clone(), ), tx_backup_dir: Self::test_config() .dir @@ -197,8 +210,8 @@ impl TestCase for SkipPreprovenCommitmentsTest { self.task_manager .spawn(|tk| bitcoin_da_service.clone().run_da_queue(rx, tk)); - // Generate 1 FINALIZED DA block. - da.generate(1 + FINALITY_DEPTH).await?; + // Generate FINALIZED DA block. + da.generate(FINALITY_DEPTH).await?; let min_soft_confirmations_per_commitment = sequencer.min_soft_confirmations_per_commitment(); From 82fff6570475f89fe97d306f20747fa8364a0960 Mon Sep 17 00:00:00 2001 From: yaziciahmet Date: Fri, 20 Dec 2024 15:55:15 +0100 Subject: [PATCH 81/96] Add env variable to release.yml workflow && rerun build on env change --- .github/workflows/release.yml | 3 ++- guests/risc0/batch-proof/build.rs | 5 +++++ guests/risc0/light-client-proof/build.rs | 6 ++++++ 3 files changed, 13 insertions(+), 1 deletion(-) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index d97a7faf0..51c57a599 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -40,7 +40,8 @@ jobs: - name: Build Project env: - REPR_GUEST_BUILD: 1 + # TODO: make this dynamic somehow + CITREA_NETWORK: testnet run: | cargo build --release diff --git a/guests/risc0/batch-proof/build.rs b/guests/risc0/batch-proof/build.rs index 9167a2506..8fac0a5bb 100644 --- a/guests/risc0/batch-proof/build.rs +++ b/guests/risc0/batch-proof/build.rs @@ -3,9 +3,14 @@ use std::collections::HashMap; use risc0_build::{embed_methods_with_options, DockerOptions, GuestOptions}; fn main() { + // Build environment variables println!("cargo:rerun-if-env-changed=SKIP_GUEST_BUILD"); println!("cargo:rerun-if-env-changed=REPR_GUEST_BUILD"); println!("cargo:rerun-if-env-changed=OUT_DIR"); + // Compile time constant environment variables + println!("cargo:rerun-if-env-changed=CITREA_NETWORK"); + println!("cargo:rerun-if-env-changed=SEQUENCER_PUBLIC_KEY"); + println!("cargo:rerun-if-env-changed=SEQUENCER_DA_PUB_KEY"); match std::env::var("SKIP_GUEST_BUILD") { Ok(value) => match value.as_str() { diff --git a/guests/risc0/light-client-proof/build.rs b/guests/risc0/light-client-proof/build.rs index 5927eadaf..023624f2a 100644 --- a/guests/risc0/light-client-proof/build.rs +++ b/guests/risc0/light-client-proof/build.rs @@ -3,9 +3,15 @@ use std::collections::HashMap; use risc0_build::{embed_methods_with_options, DockerOptions, GuestOptions}; fn main() { + // Build environment variables println!("cargo:rerun-if-env-changed=SKIP_GUEST_BUILD"); println!("cargo:rerun-if-env-changed=REPR_GUEST_BUILD"); println!("cargo:rerun-if-env-changed=OUT_DIR"); + // Compile time constant environment variables + println!("cargo:rerun-if-env-changed=CITREA_NETWORK"); + println!("cargo:rerun-if-env-changed=L2_GENESIS_ROOT"); + println!("cargo:rerun-if-env-changed=BATCH_PROOF_METHOD_ID"); + println!("cargo:rerun-if-env-changed=PROVER_DA_PUB_KEY"); match std::env::var("SKIP_GUEST_BUILD") { Ok(value) => match value.as_str() { From 6d5bd92deed9e8add668ac1de269b8fb6e8c5e18 Mon Sep 17 00:00:00 2001 From: yaziciahmet Date: Fri, 20 Dec 2024 16:32:13 +0100 Subject: [PATCH 82/96] SKIP_GUEST_BUILD in release.yml --- .github/workflows/release.yml | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 51c57a599..055f926a4 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -40,8 +40,7 @@ jobs: - name: Build Project env: - # TODO: make this dynamic somehow - CITREA_NETWORK: testnet + SKIP_GUEST_BUILD: 1 run: | cargo build --release @@ -77,7 +76,7 @@ jobs: github_token: ${{ secrets.GITHUB_TOKEN }} - name: Build Project env: - REPR_GUEST_BUILD: 1 + SKIP_GUEST_BUILD: 1 run: | source $HOME/.cargo/env cargo build --release From 54876c3d573559f57ccfa18aaae01e21b3a2bd1c Mon Sep 17 00:00:00 2001 From: yaziciahmet Date: Fri, 20 Dec 2024 19:18:59 +0100 Subject: [PATCH 83/96] Add genesis to fork1 l1 diff size change test --- .../src/tests/queries/estimate_gas_tests.rs | 281 +++++++++++++++++- crates/primitives/src/forks.rs | 3 + 2 files changed, 282 insertions(+), 2 deletions(-) diff --git a/crates/evm/src/tests/queries/estimate_gas_tests.rs b/crates/evm/src/tests/queries/estimate_gas_tests.rs index 7d2a59120..865e0e7c6 100644 --- a/crates/evm/src/tests/queries/estimate_gas_tests.rs +++ b/crates/evm/src/tests/queries/estimate_gas_tests.rs @@ -3,12 +3,15 @@ use std::str::FromStr; use alloy_eips::eip2930::{AccessList, AccessListItem, AccessListWithGasUsed}; use alloy_primitives::{address, b256, Address, TxKind, U256}; use alloy_rpc_types::{TransactionInput, TransactionRequest}; +use citrea_primitives::forks::FORKS; use jsonrpsee::core::RpcResult; use reth_primitives::BlockNumberOrTag; use reth_rpc_eth_types::RpcInvalidTransactionError; use serde_json::json; use sov_modules_api::default_context::DefaultContext; -use sov_modules_api::{Spec, WorkingSet}; +use sov_modules_api::fork::Fork; +use sov_modules_api::hooks::HookSoftConfirmationInfo; +use sov_modules_api::{Spec, SpecId, WorkingSet}; use crate::query::MIN_TRANSACTION_GAS; use crate::smart_contracts::{CallerContract, SimpleStorageContract}; @@ -51,7 +54,281 @@ fn test_payable_contract_value() { } #[test] -fn test_tx_request_fields_gas() { +fn test_tx_request_fields_gas_genesis_to_fork1() { + static F: &[Fork] = &[Fork::new(SpecId::Genesis, 0), Fork::new(SpecId::Fork1, 2)]; + FORKS.set(F).unwrap(); + + let (mut evm, mut working_set, signer) = init_evm_single_block(); + + let block = evm.block_number(&mut working_set).unwrap(); + dbg!(block); + + let tx_req_contract_call = TransactionRequest { + from: Some(signer.address()), + to: Some(TxKind::Call(address!( + "819c5497b157177315e1204f52e588b393771719" + ))), + gas: Some(10000000), + gas_price: Some(100), + max_fee_per_gas: None, + max_priority_fee_per_gas: None, + value: None, + input: TransactionInput { + input: None, + data: None, + }, + nonce: Some(1u64), + chain_id: Some(1u64), + access_list: None, + max_fee_per_blob_gas: None, + blob_versioned_hashes: None, + transaction_type: None, + sidecar: None, + authorization_list: None, + }; + + let result_contract_call = evm.eth_estimate_gas( + tx_req_contract_call.clone(), + Some(BlockNumberOrTag::Latest), + &mut working_set, + ); + assert_eq!( + result_contract_call.unwrap(), + U256::from_str("0x6602").unwrap() + ); + let contract_diff_size = evm.eth_estimate_diff_size( + tx_req_contract_call.clone(), + Some(BlockNumberOrTag::Latest), + &mut working_set, + ); + assert_eq!( + contract_diff_size.unwrap(), + serde_json::from_value::(json![{"gas":"0x6601","l1DiffSize":"0x60"}]) + .unwrap() + ); + + let tx_req_no_gas = TransactionRequest { + gas: None, + ..tx_req_contract_call.clone() + }; + + let contract_diff_size = evm.eth_estimate_diff_size( + tx_req_no_gas.clone(), + Some(BlockNumberOrTag::Latest), + &mut working_set, + ); + assert_eq!( + contract_diff_size.unwrap(), + serde_json::from_value::(json![{"gas":"0x6601","l1DiffSize":"0x60"}]) + .unwrap() + ); + + let tx_req_no_sender = TransactionRequest { + from: None, + nonce: None, + ..tx_req_contract_call.clone() + }; + + let result_no_sender = evm.eth_estimate_gas( + tx_req_no_sender, + Some(BlockNumberOrTag::Latest), + &mut working_set, + ); + assert_eq!(result_no_sender.unwrap(), U256::from_str("0x6602").unwrap()); + working_set.unset_archival_version(); + + let tx_req_no_recipient = TransactionRequest { + to: None, + ..tx_req_contract_call.clone() + }; + + let result_no_recipient = evm.eth_estimate_gas( + tx_req_no_recipient, + Some(BlockNumberOrTag::Latest), + &mut working_set, + ); + assert_eq!( + result_no_recipient.unwrap(), + U256::from_str("0xd0ad").unwrap() + ); + working_set.unset_archival_version(); + + let tx_req_no_gas = TransactionRequest { + gas: None, + ..tx_req_contract_call.clone() + }; + + let result_no_gas = evm.eth_estimate_gas( + tx_req_no_gas, + Some(BlockNumberOrTag::Latest), + &mut working_set, + ); + assert_eq!(result_no_gas.unwrap(), U256::from_str("0x6602").unwrap()); + working_set.unset_archival_version(); + + let tx_req_no_gas_price = TransactionRequest { + gas_price: None, + ..tx_req_contract_call.clone() + }; + + let result_no_gas_price = evm.eth_estimate_gas( + tx_req_no_gas_price, + Some(BlockNumberOrTag::Latest), + &mut working_set, + ); + assert_eq!( + result_no_gas_price.unwrap(), + U256::from_str("0x6602").unwrap() + ); + working_set.unset_archival_version(); + + let tx_req_no_chain_id = TransactionRequest { + chain_id: None, + ..tx_req_contract_call.clone() + }; + + let result_no_chain_id = evm.eth_estimate_gas( + tx_req_no_chain_id, + Some(BlockNumberOrTag::Latest), + &mut working_set, + ); + assert_eq!( + result_no_chain_id.unwrap(), + U256::from_str("0x6602").unwrap() + ); + working_set.unset_archival_version(); + + let tx_req_invalid_chain_id = TransactionRequest { + chain_id: Some(3u64), + ..tx_req_contract_call.clone() + }; + + let result_invalid_chain_id = evm.eth_estimate_gas( + tx_req_invalid_chain_id, + Some(BlockNumberOrTag::Latest), + &mut working_set, + ); + assert_eq!( + result_invalid_chain_id, + Err(RpcInvalidTransactionError::InvalidChainId.into()) + ); + working_set.unset_archival_version(); + + // We don't have EIP-4844 now, so this is just to see if it's working. + let tx_req_no_blob_versioned_hashes = TransactionRequest { + blob_versioned_hashes: None, + ..tx_req_contract_call.clone() + }; + + let result_no_blob_versioned_hashes = evm.eth_estimate_gas( + tx_req_no_blob_versioned_hashes, + Some(BlockNumberOrTag::Latest), + &mut working_set, + ); + assert_eq!( + result_no_blob_versioned_hashes.unwrap(), + U256::from_str("0x6602").unwrap() + ); + working_set.unset_archival_version(); + + let no_access_list_req = TransactionRequest { + access_list: None, + ..tx_req_contract_call.clone() + }; + + let create_no_access_list_test = evm.create_access_list( + no_access_list_req, + Some(BlockNumberOrTag::Latest), + &mut working_set, + ); + + assert_eq!( + create_no_access_list_test.unwrap(), + AccessListWithGasUsed { + access_list: AccessList(vec![AccessListItem { + address: address!("819c5497b157177315e1204f52e588b393771719"), + storage_keys: vec![b256!( + "d17c80a661d193357ea7c5311e029471883989438c7bcae8362437311a764685" + )] + }]), + gas_used: U256::from_str("0x6e67").unwrap() + } + ); + + let access_list_req = TransactionRequest { + access_list: Some(AccessList(vec![AccessListItem { + address: address!("819c5497b157177315e1204f52e588b393771719"), + storage_keys: vec![b256!( + "d17c80a661d193357ea7c5311e029471883989438c7bcae8362437311a764685" + )], + }])), + ..tx_req_contract_call.clone() + }; + + let access_list_gas_test = evm.eth_estimate_gas( + access_list_req.clone(), + Some(BlockNumberOrTag::Latest), + &mut working_set, + ); + + // Wrong access punishment. + assert_eq!( + access_list_gas_test.unwrap(), + U256::from_str("0x6e67").unwrap() + ); + + let already_formed_list = evm.create_access_list( + access_list_req, + Some(BlockNumberOrTag::Latest), + &mut working_set, + ); + + assert_eq!( + already_formed_list.unwrap(), + AccessListWithGasUsed { + access_list: AccessList(vec![AccessListItem { + address: address!("819c5497b157177315e1204f52e588b393771719"), + storage_keys: vec![b256!( + "d17c80a661d193357ea7c5311e029471883989438c7bcae8362437311a764685" + )] + }]), + gas_used: U256::from_str("0x6e67").unwrap() + } + ); + + // Produce 1 block to go to Fork1 + let soft_confirmation_info = HookSoftConfirmationInfo { + l2_height: 2, + da_slot_hash: [1u8; 32], + da_slot_height: 1, + da_slot_txs_commitment: [42u8; 32], + pre_state_root: [0u8; 32].to_vec(), + current_spec: SpecId::Fork1, + pub_key: vec![], + deposit_data: vec![], + l1_fee_rate: 1, + timestamp: 0, + }; + evm.begin_soft_confirmation_hook(&soft_confirmation_info, &mut working_set); + evm.end_soft_confirmation_hook(&soft_confirmation_info, &mut working_set); + evm.finalize_hook(&[2u8; 32].into(), &mut working_set.accessory_state()); + + let contract_diff_size = evm.eth_estimate_diff_size( + tx_req_contract_call.clone(), + Some(BlockNumberOrTag::Latest), + &mut working_set, + ); + // Check if l1DiffSize is calculated with its compress rate, + // as it should be in Fork1 + assert_eq!( + contract_diff_size.unwrap(), + serde_json::from_value::(json![{"gas":"0x6601","l1DiffSize":"0x1f"}]) + .unwrap() + ); +} + +#[test] +fn test_tx_request_fields_gas_fork1() { let (evm, mut working_set, signer) = init_evm_single_block(); let tx_req_contract_call = TransactionRequest { diff --git a/crates/primitives/src/forks.rs b/crates/primitives/src/forks.rs index a67598aea..807f1f9ad 100644 --- a/crates/primitives/src/forks.rs +++ b/crates/primitives/src/forks.rs @@ -4,7 +4,10 @@ use sov_rollup_interface::fork::{fork_pos_from_block_number, verify_forks, Fork} use sov_rollup_interface::spec::SpecId; use sov_rollup_interface::Network; +#[cfg(not(feature = "testing"))] static FORKS: OnceLock<&'static [Fork]> = OnceLock::new(); +#[cfg(feature = "testing")] +pub static FORKS: OnceLock<&'static [Fork]> = OnceLock::new(); /// Set forks globally based on the network. Must be called once at the start of the application. pub fn use_network_forks(network: Network) { From 8233e7744ebec758f64988935fdc7d9abe8c4dd1 Mon Sep 17 00:00:00 2001 From: yaziciahmet Date: Fri, 20 Dec 2024 21:26:56 +0100 Subject: [PATCH 84/96] Remove test --- .../src/tests/queries/estimate_gas_tests.rs | 279 +----------------- crates/primitives/src/forks.rs | 3 - 2 files changed, 1 insertion(+), 281 deletions(-) diff --git a/crates/evm/src/tests/queries/estimate_gas_tests.rs b/crates/evm/src/tests/queries/estimate_gas_tests.rs index 865e0e7c6..814468a56 100644 --- a/crates/evm/src/tests/queries/estimate_gas_tests.rs +++ b/crates/evm/src/tests/queries/estimate_gas_tests.rs @@ -3,15 +3,12 @@ use std::str::FromStr; use alloy_eips::eip2930::{AccessList, AccessListItem, AccessListWithGasUsed}; use alloy_primitives::{address, b256, Address, TxKind, U256}; use alloy_rpc_types::{TransactionInput, TransactionRequest}; -use citrea_primitives::forks::FORKS; use jsonrpsee::core::RpcResult; use reth_primitives::BlockNumberOrTag; use reth_rpc_eth_types::RpcInvalidTransactionError; use serde_json::json; use sov_modules_api::default_context::DefaultContext; -use sov_modules_api::fork::Fork; -use sov_modules_api::hooks::HookSoftConfirmationInfo; -use sov_modules_api::{Spec, SpecId, WorkingSet}; +use sov_modules_api::{Spec, WorkingSet}; use crate::query::MIN_TRANSACTION_GAS; use crate::smart_contracts::{CallerContract, SimpleStorageContract}; @@ -53,280 +50,6 @@ fn test_payable_contract_value() { assert_eq!(result.unwrap(), U256::from_str("0xab13").unwrap()); } -#[test] -fn test_tx_request_fields_gas_genesis_to_fork1() { - static F: &[Fork] = &[Fork::new(SpecId::Genesis, 0), Fork::new(SpecId::Fork1, 2)]; - FORKS.set(F).unwrap(); - - let (mut evm, mut working_set, signer) = init_evm_single_block(); - - let block = evm.block_number(&mut working_set).unwrap(); - dbg!(block); - - let tx_req_contract_call = TransactionRequest { - from: Some(signer.address()), - to: Some(TxKind::Call(address!( - "819c5497b157177315e1204f52e588b393771719" - ))), - gas: Some(10000000), - gas_price: Some(100), - max_fee_per_gas: None, - max_priority_fee_per_gas: None, - value: None, - input: TransactionInput { - input: None, - data: None, - }, - nonce: Some(1u64), - chain_id: Some(1u64), - access_list: None, - max_fee_per_blob_gas: None, - blob_versioned_hashes: None, - transaction_type: None, - sidecar: None, - authorization_list: None, - }; - - let result_contract_call = evm.eth_estimate_gas( - tx_req_contract_call.clone(), - Some(BlockNumberOrTag::Latest), - &mut working_set, - ); - assert_eq!( - result_contract_call.unwrap(), - U256::from_str("0x6602").unwrap() - ); - let contract_diff_size = evm.eth_estimate_diff_size( - tx_req_contract_call.clone(), - Some(BlockNumberOrTag::Latest), - &mut working_set, - ); - assert_eq!( - contract_diff_size.unwrap(), - serde_json::from_value::(json![{"gas":"0x6601","l1DiffSize":"0x60"}]) - .unwrap() - ); - - let tx_req_no_gas = TransactionRequest { - gas: None, - ..tx_req_contract_call.clone() - }; - - let contract_diff_size = evm.eth_estimate_diff_size( - tx_req_no_gas.clone(), - Some(BlockNumberOrTag::Latest), - &mut working_set, - ); - assert_eq!( - contract_diff_size.unwrap(), - serde_json::from_value::(json![{"gas":"0x6601","l1DiffSize":"0x60"}]) - .unwrap() - ); - - let tx_req_no_sender = TransactionRequest { - from: None, - nonce: None, - ..tx_req_contract_call.clone() - }; - - let result_no_sender = evm.eth_estimate_gas( - tx_req_no_sender, - Some(BlockNumberOrTag::Latest), - &mut working_set, - ); - assert_eq!(result_no_sender.unwrap(), U256::from_str("0x6602").unwrap()); - working_set.unset_archival_version(); - - let tx_req_no_recipient = TransactionRequest { - to: None, - ..tx_req_contract_call.clone() - }; - - let result_no_recipient = evm.eth_estimate_gas( - tx_req_no_recipient, - Some(BlockNumberOrTag::Latest), - &mut working_set, - ); - assert_eq!( - result_no_recipient.unwrap(), - U256::from_str("0xd0ad").unwrap() - ); - working_set.unset_archival_version(); - - let tx_req_no_gas = TransactionRequest { - gas: None, - ..tx_req_contract_call.clone() - }; - - let result_no_gas = evm.eth_estimate_gas( - tx_req_no_gas, - Some(BlockNumberOrTag::Latest), - &mut working_set, - ); - assert_eq!(result_no_gas.unwrap(), U256::from_str("0x6602").unwrap()); - working_set.unset_archival_version(); - - let tx_req_no_gas_price = TransactionRequest { - gas_price: None, - ..tx_req_contract_call.clone() - }; - - let result_no_gas_price = evm.eth_estimate_gas( - tx_req_no_gas_price, - Some(BlockNumberOrTag::Latest), - &mut working_set, - ); - assert_eq!( - result_no_gas_price.unwrap(), - U256::from_str("0x6602").unwrap() - ); - working_set.unset_archival_version(); - - let tx_req_no_chain_id = TransactionRequest { - chain_id: None, - ..tx_req_contract_call.clone() - }; - - let result_no_chain_id = evm.eth_estimate_gas( - tx_req_no_chain_id, - Some(BlockNumberOrTag::Latest), - &mut working_set, - ); - assert_eq!( - result_no_chain_id.unwrap(), - U256::from_str("0x6602").unwrap() - ); - working_set.unset_archival_version(); - - let tx_req_invalid_chain_id = TransactionRequest { - chain_id: Some(3u64), - ..tx_req_contract_call.clone() - }; - - let result_invalid_chain_id = evm.eth_estimate_gas( - tx_req_invalid_chain_id, - Some(BlockNumberOrTag::Latest), - &mut working_set, - ); - assert_eq!( - result_invalid_chain_id, - Err(RpcInvalidTransactionError::InvalidChainId.into()) - ); - working_set.unset_archival_version(); - - // We don't have EIP-4844 now, so this is just to see if it's working. - let tx_req_no_blob_versioned_hashes = TransactionRequest { - blob_versioned_hashes: None, - ..tx_req_contract_call.clone() - }; - - let result_no_blob_versioned_hashes = evm.eth_estimate_gas( - tx_req_no_blob_versioned_hashes, - Some(BlockNumberOrTag::Latest), - &mut working_set, - ); - assert_eq!( - result_no_blob_versioned_hashes.unwrap(), - U256::from_str("0x6602").unwrap() - ); - working_set.unset_archival_version(); - - let no_access_list_req = TransactionRequest { - access_list: None, - ..tx_req_contract_call.clone() - }; - - let create_no_access_list_test = evm.create_access_list( - no_access_list_req, - Some(BlockNumberOrTag::Latest), - &mut working_set, - ); - - assert_eq!( - create_no_access_list_test.unwrap(), - AccessListWithGasUsed { - access_list: AccessList(vec![AccessListItem { - address: address!("819c5497b157177315e1204f52e588b393771719"), - storage_keys: vec![b256!( - "d17c80a661d193357ea7c5311e029471883989438c7bcae8362437311a764685" - )] - }]), - gas_used: U256::from_str("0x6e67").unwrap() - } - ); - - let access_list_req = TransactionRequest { - access_list: Some(AccessList(vec![AccessListItem { - address: address!("819c5497b157177315e1204f52e588b393771719"), - storage_keys: vec![b256!( - "d17c80a661d193357ea7c5311e029471883989438c7bcae8362437311a764685" - )], - }])), - ..tx_req_contract_call.clone() - }; - - let access_list_gas_test = evm.eth_estimate_gas( - access_list_req.clone(), - Some(BlockNumberOrTag::Latest), - &mut working_set, - ); - - // Wrong access punishment. - assert_eq!( - access_list_gas_test.unwrap(), - U256::from_str("0x6e67").unwrap() - ); - - let already_formed_list = evm.create_access_list( - access_list_req, - Some(BlockNumberOrTag::Latest), - &mut working_set, - ); - - assert_eq!( - already_formed_list.unwrap(), - AccessListWithGasUsed { - access_list: AccessList(vec![AccessListItem { - address: address!("819c5497b157177315e1204f52e588b393771719"), - storage_keys: vec![b256!( - "d17c80a661d193357ea7c5311e029471883989438c7bcae8362437311a764685" - )] - }]), - gas_used: U256::from_str("0x6e67").unwrap() - } - ); - - // Produce 1 block to go to Fork1 - let soft_confirmation_info = HookSoftConfirmationInfo { - l2_height: 2, - da_slot_hash: [1u8; 32], - da_slot_height: 1, - da_slot_txs_commitment: [42u8; 32], - pre_state_root: [0u8; 32].to_vec(), - current_spec: SpecId::Fork1, - pub_key: vec![], - deposit_data: vec![], - l1_fee_rate: 1, - timestamp: 0, - }; - evm.begin_soft_confirmation_hook(&soft_confirmation_info, &mut working_set); - evm.end_soft_confirmation_hook(&soft_confirmation_info, &mut working_set); - evm.finalize_hook(&[2u8; 32].into(), &mut working_set.accessory_state()); - - let contract_diff_size = evm.eth_estimate_diff_size( - tx_req_contract_call.clone(), - Some(BlockNumberOrTag::Latest), - &mut working_set, - ); - // Check if l1DiffSize is calculated with its compress rate, - // as it should be in Fork1 - assert_eq!( - contract_diff_size.unwrap(), - serde_json::from_value::(json![{"gas":"0x6601","l1DiffSize":"0x1f"}]) - .unwrap() - ); -} - #[test] fn test_tx_request_fields_gas_fork1() { let (evm, mut working_set, signer) = init_evm_single_block(); diff --git a/crates/primitives/src/forks.rs b/crates/primitives/src/forks.rs index 807f1f9ad..a67598aea 100644 --- a/crates/primitives/src/forks.rs +++ b/crates/primitives/src/forks.rs @@ -4,10 +4,7 @@ use sov_rollup_interface::fork::{fork_pos_from_block_number, verify_forks, Fork} use sov_rollup_interface::spec::SpecId; use sov_rollup_interface::Network; -#[cfg(not(feature = "testing"))] static FORKS: OnceLock<&'static [Fork]> = OnceLock::new(); -#[cfg(feature = "testing")] -pub static FORKS: OnceLock<&'static [Fork]> = OnceLock::new(); /// Set forks globally based on the network. Must be called once at the start of the application. pub fn use_network_forks(network: Network) { From 1803b5353cb2a270fe9f130b4b7ae1c02c52dc6e Mon Sep 17 00:00:00 2001 From: yaziciahmet Date: Fri, 20 Dec 2024 21:40:21 +0100 Subject: [PATCH 85/96] Make default evm in tests Fork1 --- crates/evm/src/tests/queries/log_tests.rs | 18 +++++++++--------- crates/evm/src/tests/utils.rs | 2 +- 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/crates/evm/src/tests/queries/log_tests.rs b/crates/evm/src/tests/queries/log_tests.rs index 69bc08edc..f1135ac90 100644 --- a/crates/evm/src/tests/queries/log_tests.rs +++ b/crates/evm/src/tests/queries/log_tests.rs @@ -79,7 +79,7 @@ fn log_filter_test_at_block_hash() { da_slot_height: 1, da_slot_txs_commitment: [42u8; 32], pre_state_root: [10u8; 32].to_vec(), - current_spec: SpecId::Genesis, + current_spec: SpecId::Fork1, pub_key: vec![], deposit_data: vec![], l1_fee_rate, @@ -89,7 +89,7 @@ fn log_filter_test_at_block_hash() { { let sender_address = generate_address::("sender"); - let context = C::new(sender_address, l2_height, SpecId::Genesis, l1_fee_rate); + let context = C::new(sender_address, l2_height, SpecId::Fork1, l1_fee_rate); // deploy logs contract // call the contract function @@ -288,7 +288,7 @@ fn log_filter_test_with_range() { da_slot_height: 1, da_slot_txs_commitment: [42u8; 32], pre_state_root: [10u8; 32].to_vec(), - current_spec: SpecId::Genesis, + current_spec: SpecId::Fork1, pub_key: vec![], deposit_data: vec![], l1_fee_rate, @@ -298,7 +298,7 @@ fn log_filter_test_with_range() { { let sender_address = generate_address::("sender"); - let context = C::new(sender_address, l2_height, SpecId::Genesis, l1_fee_rate); + let context = C::new(sender_address, l2_height, SpecId::Fork1, l1_fee_rate); // deploy selfdestruct contract // call the contract function @@ -350,7 +350,7 @@ fn log_filter_test_with_range() { da_slot_height: 1, da_slot_txs_commitment: [42u8; 32], pre_state_root: [99u8; 32].to_vec(), - current_spec: SpecId::Genesis, + current_spec: SpecId::Fork1, pub_key: vec![], deposit_data: vec![], l1_fee_rate, @@ -360,7 +360,7 @@ fn log_filter_test_with_range() { { let sender_address = generate_address::("sender"); - let context = C::new(sender_address, l2_height, SpecId::Genesis, l1_fee_rate); + let context = C::new(sender_address, l2_height, SpecId::Fork1, l1_fee_rate); // call the contract function evm.call( CallMessage { @@ -414,7 +414,7 @@ fn test_log_limits() { da_slot_height: 1, da_slot_txs_commitment: [42u8; 32], pre_state_root: [10u8; 32].to_vec(), - current_spec: SpecId::Genesis, + current_spec: SpecId::Fork1, pub_key: vec![], deposit_data: vec![], l1_fee_rate, @@ -424,7 +424,7 @@ fn test_log_limits() { { let sender_address = generate_address::("sender"); - let context = C::new(sender_address, l2_height, SpecId::Genesis, l1_fee_rate); + let context = C::new(sender_address, l2_height, SpecId::Fork1, l1_fee_rate); // deploy logs contract let mut rlp_transactions = vec![create_contract_message( @@ -515,7 +515,7 @@ fn test_log_limits() { da_slot_height: 1, da_slot_txs_commitment: [42u8; 32], pre_state_root: [99u8; 32].to_vec(), - current_spec: SpecId::Genesis, + current_spec: SpecId::Fork1, pub_key: vec![], deposit_data: vec![], l1_fee_rate, diff --git a/crates/evm/src/tests/utils.rs b/crates/evm/src/tests/utils.rs index 38761e33b..36810dcc8 100644 --- a/crates/evm/src/tests/utils.rs +++ b/crates/evm/src/tests/utils.rs @@ -70,7 +70,7 @@ pub(crate) fn get_evm(config: &EvmConfig) -> (Evm, WorkingSet<::St da_slot_height: 1, da_slot_txs_commitment: [2u8; 32], pre_state_root: root.to_vec(), - current_spec: SovSpecId::Genesis, + current_spec: SovSpecId::Fork1, pub_key: vec![], deposit_data: vec![], l1_fee_rate: 0, From 05cb5dce9416c39069c1d1e3beb8358a81220295 Mon Sep 17 00:00:00 2001 From: yaziciahmet Date: Fri, 20 Dec 2024 21:49:11 +0100 Subject: [PATCH 86/96] Fix most sys tx tests --- crates/evm/src/tests/sys_tx_tests.rs | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/crates/evm/src/tests/sys_tx_tests.rs b/crates/evm/src/tests/sys_tx_tests.rs index e43531036..ad84e93d1 100644 --- a/crates/evm/src/tests/sys_tx_tests.rs +++ b/crates/evm/src/tests/sys_tx_tests.rs @@ -292,7 +292,7 @@ fn test_sys_tx_gas_usage_effect_on_block_gas_limit() { let mut l2_height = 2; let sender_address = generate_address::("sender"); - let context = C::new(sender_address, l2_height, SpecId::Genesis, l1_fee_rate); + let context = C::new(sender_address, l2_height, SpecId::Fork1, l1_fee_rate); let soft_confirmation_info = HookSoftConfirmationInfo { l2_height, @@ -300,7 +300,7 @@ fn test_sys_tx_gas_usage_effect_on_block_gas_limit() { da_slot_height: 1, da_slot_txs_commitment: [42u8; 32], pre_state_root: [10u8; 32].to_vec(), - current_spec: SpecId::Genesis, + current_spec: SpecId::Fork1, pub_key: vec![], deposit_data: vec![], l1_fee_rate: 1, @@ -335,7 +335,7 @@ fn test_sys_tx_gas_usage_effect_on_block_gas_limit() { da_slot_height: 2, da_slot_txs_commitment: [43u8; 32], pre_state_root: [10u8; 32].to_vec(), - current_spec: SpecId::Genesis, + current_spec: SpecId::Fork1, pub_key: vec![], deposit_data: vec![], l1_fee_rate, @@ -343,7 +343,7 @@ fn test_sys_tx_gas_usage_effect_on_block_gas_limit() { }; evm.begin_soft_confirmation_hook(&soft_confirmation_info, &mut working_set); { - let context = C::new(sender_address, l2_height, SpecId::Genesis, l1_fee_rate); + let context = C::new(sender_address, l2_height, SpecId::Fork1, l1_fee_rate); let pending_cumulative_from_sum: u128 = evm .pending_transactions @@ -411,7 +411,7 @@ fn test_sys_tx_gas_usage_effect_on_block_gas_limit() { da_slot_height: 2, da_slot_txs_commitment: [43u8; 32], pre_state_root: [10u8; 32].to_vec(), - current_spec: SpecId::Genesis, + current_spec: SpecId::Fork1, pub_key: vec![], deposit_data: vec![], l1_fee_rate, @@ -419,7 +419,7 @@ fn test_sys_tx_gas_usage_effect_on_block_gas_limit() { }; evm.begin_soft_confirmation_hook(&soft_confirmation_info, &mut working_set); { - let context = C::new(sender_address, l2_height, SpecId::Genesis, l1_fee_rate); + let context = C::new(sender_address, l2_height, SpecId::Fork1, l1_fee_rate); let pending_cumulative_from_sum: u128 = evm .pending_transactions @@ -511,7 +511,7 @@ fn test_bridge() { 188, 45, 73, 146, 108, 41, 125, 77, 133, 86, 235, 104, ], pre_state_root: [1u8; 32].to_vec(), - current_spec: SpecId::Genesis, + current_spec: SpecId::Fork1, pub_key: vec![], deposit_data: vec![[ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, @@ -621,7 +621,7 @@ fn test_upgrade_light_client() { let l2_height = 2; let sender_address = generate_address::("sender"); - let context = C::new(sender_address, l2_height, SpecId::Genesis, l1_fee_rate); + let context = C::new(sender_address, l2_height, SpecId::Fork1, l1_fee_rate); let soft_confirmation_info = HookSoftConfirmationInfo { l2_height, @@ -629,7 +629,7 @@ fn test_upgrade_light_client() { da_slot_height: 1, da_slot_txs_commitment: [42u8; 32], pre_state_root: [10u8; 32].to_vec(), - current_spec: SpecId::Genesis, + current_spec: SpecId::Fork1, pub_key: vec![], deposit_data: vec![], l1_fee_rate, @@ -747,7 +747,7 @@ fn test_change_upgrade_owner() { let l1_fee_rate = 1; let mut l2_height = 2; let sender_address = generate_address::("sender"); - let context = C::new(sender_address, l2_height, SpecId::Genesis, l1_fee_rate); + let context = C::new(sender_address, l2_height, SpecId::Fork1, l1_fee_rate); let soft_confirmation_info = HookSoftConfirmationInfo { l2_height, @@ -755,7 +755,7 @@ fn test_change_upgrade_owner() { da_slot_height: 1, da_slot_txs_commitment: [42u8; 32], pre_state_root: [10u8; 32].to_vec(), - current_spec: SpecId::Genesis, + current_spec: SpecId::Fork1, pub_key: vec![], deposit_data: vec![], l1_fee_rate, @@ -786,7 +786,7 @@ fn test_change_upgrade_owner() { evm.finalize_hook(&[99u8; 32].into(), &mut working_set.accessory_state()); l2_height += 1; - let context = C::new(sender_address, l2_height, SpecId::Genesis, l1_fee_rate); + let context = C::new(sender_address, l2_height, SpecId::Fork1, l1_fee_rate); let soft_confirmation_info = HookSoftConfirmationInfo { l2_height, @@ -794,7 +794,7 @@ fn test_change_upgrade_owner() { da_slot_height: 1, da_slot_txs_commitment: [42u8; 32], pre_state_root: [10u8; 32].to_vec(), - current_spec: SpecId::Genesis, + current_spec: SpecId::Fork1, pub_key: vec![], deposit_data: vec![], l1_fee_rate, From daef7bd2934314b4d23a3e4081ce6d41f798c23e Mon Sep 17 00:00:00 2001 From: yaziciahmet Date: Fri, 20 Dec 2024 22:02:31 +0100 Subject: [PATCH 87/96] Fix all sys tx tests --- crates/evm/src/tests/sys_tx_tests.rs | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/crates/evm/src/tests/sys_tx_tests.rs b/crates/evm/src/tests/sys_tx_tests.rs index ad84e93d1..c1bad1f2a 100644 --- a/crates/evm/src/tests/sys_tx_tests.rs +++ b/crates/evm/src/tests/sys_tx_tests.rs @@ -51,7 +51,7 @@ fn test_sys_bitcoin_light_client() { }, gas_used: 50751, log_index_start: 0, - l1_diff_size: 255, + l1_diff_size: 53, }, Receipt { // BitcoinLightClient::setBlockInfo(U256, U256) receipt: reth_primitives::Receipt { @@ -70,7 +70,7 @@ fn test_sys_bitcoin_light_client() { }, gas_used: 80620, log_index_start: 0, - l1_diff_size: 561, + l1_diff_size: 94, }, Receipt { receipt: reth_primitives::Receipt { @@ -96,7 +96,7 @@ fn test_sys_bitcoin_light_client() { }, gas_used: 169150, log_index_start: 1, - l1_diff_size: 1019, + l1_diff_size: 154, } ] ); @@ -158,7 +158,7 @@ fn test_sys_bitcoin_light_client() { da_slot_height: 2, da_slot_txs_commitment: [3u8; 32], pre_state_root: [10u8; 32].to_vec(), - current_spec: SpecId::Genesis, + current_spec: SpecId::Fork1, pub_key: vec![], deposit_data: vec![], l1_fee_rate, @@ -170,7 +170,7 @@ fn test_sys_bitcoin_light_client() { { let sender_address = generate_address::("sender"); - let context = C::new(sender_address, l2_height, SpecId::Genesis, l1_fee_rate); + let context = C::new(sender_address, l2_height, SpecId::Fork1, l1_fee_rate); let deploy_message = create_contract_message_with_fee( &dev_signer, @@ -222,7 +222,7 @@ fn test_sys_bitcoin_light_client() { }, gas_used: 80620, log_index_start: 0, - l1_diff_size: 561, + l1_diff_size: 94, }, Receipt { receipt: reth_primitives::Receipt { @@ -233,7 +233,7 @@ fn test_sys_bitcoin_light_client() { }, gas_used: 114235, log_index_start: 1, - l1_diff_size: 479, + l1_diff_size: 52, }, ] ); @@ -241,7 +241,7 @@ fn test_sys_bitcoin_light_client() { let l1_fee_vault = evm.accounts.get(&L1_FEE_VAULT, &mut working_set).unwrap(); assert_eq!(base_fee_vault.balance, U256::from(114235u64 * 10000000)); - assert_eq!(l1_fee_vault.balance, U256::from(479 + L1_FEE_OVERHEAD)); + assert_eq!(l1_fee_vault.balance, U256::from(52 + L1_FEE_OVERHEAD)); let hash = evm .get_call( From 1036e860abda30e87d5e318c48bbde57dd04bbfb Mon Sep 17 00:00:00 2001 From: yaziciahmet Date: Fri, 20 Dec 2024 22:09:31 +0100 Subject: [PATCH 88/96] Fix most hooks tests --- crates/evm/src/tests/hooks_tests.rs | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/crates/evm/src/tests/hooks_tests.rs b/crates/evm/src/tests/hooks_tests.rs index ef1c76c6f..ef765387d 100644 --- a/crates/evm/src/tests/hooks_tests.rs +++ b/crates/evm/src/tests/hooks_tests.rs @@ -6,7 +6,7 @@ use reth_primitives::{ Header, Signature, TransactionSigned, TransactionSignedNoHash, EMPTY_OMMER_ROOT_HASH, KECCAK_EMPTY, }; -use revm::primitives::BlockEnv; +use revm::primitives::{BlobExcessGasAndPrice, BlockEnv}; use sov_modules_api::hooks::HookSoftConfirmationInfo; use sov_modules_api::{StateMapAccessor, StateValueAccessor, StateVecAccessor}; use sov_rollup_interface::spec::SpecId; @@ -34,7 +34,7 @@ fn begin_soft_confirmation_hook_creates_pending_block() { da_slot_height: 1, da_slot_txs_commitment: [42u8; 32], pre_state_root: [10u8; 32].to_vec(), - current_spec: SpecId::Genesis, + current_spec: SpecId::Fork1, pub_key: vec![], deposit_data: vec![], l1_fee_rate, @@ -52,7 +52,7 @@ fn begin_soft_confirmation_hook_creates_pending_block() { basefee: U256::from(767816299), gas_limit: U256::from(config.block_gas_limit), difficulty: U256::ZERO, - blob_excess_gas_and_price: None + blob_excess_gas_and_price: Some(BlobExcessGasAndPrice::new(0)) } ); } @@ -74,7 +74,7 @@ fn end_soft_confirmation_hook_sets_head() { da_slot_height: 1, da_slot_txs_commitment: txs_commitment.into(), pre_state_root: pre_state_root.to_vec(), - current_spec: SpecId::Genesis, + current_spec: SpecId::Fork1, pub_key: vec![], deposit_data: vec![], l1_fee_rate, @@ -149,7 +149,7 @@ fn end_soft_confirmation_hook_moves_transactions_and_receipts() { da_slot_height: 1, da_slot_txs_commitment: [42u8; 32], pre_state_root: [10u8; 32].to_vec(), - current_spec: SpecId::Genesis, + current_spec: SpecId::Fork1, pub_key: vec![], deposit_data: vec![], l1_fee_rate, @@ -272,7 +272,7 @@ fn finalize_hook_creates_final_block() { da_slot_height: 1, da_slot_txs_commitment: txs_commitment.into(), pre_state_root: root.to_vec(), - current_spec: SpecId::Genesis, + current_spec: SpecId::Fork1, pub_key: vec![], deposit_data: vec![], l1_fee_rate, @@ -301,7 +301,7 @@ fn finalize_hook_creates_final_block() { da_slot_height: 1, da_slot_txs_commitment: txs_commitment.into(), pre_state_root: root_hash.to_vec(), - current_spec: SpecId::Genesis, + current_spec: SpecId::Fork1, pub_key: vec![], deposit_data: vec![], l1_fee_rate, @@ -340,8 +340,8 @@ fn finalize_hook_creates_final_block() { nonce: B64::ZERO, base_fee_per_gas: Some(767816299), extra_data: Bytes::default(), - blob_gas_used: None, - excess_blob_gas: None, + blob_gas_used: Some(0), + excess_blob_gas: Some(0), parent_beacon_block_root: None, requests_root: None, }; @@ -390,7 +390,7 @@ fn begin_soft_confirmation_hook_appends_last_block_hashes() { da_slot_height: 1, da_slot_txs_commitment: txs_commitment.into(), pre_state_root: root.to_vec(), - current_spec: SpecId::Genesis, + current_spec: SpecId::Fork1, pub_key: vec![], deposit_data: vec![], l1_fee_rate, @@ -433,7 +433,7 @@ fn begin_soft_confirmation_hook_appends_last_block_hashes() { da_slot_height: 1, da_slot_txs_commitment: random_32_bytes, pre_state_root: random_32_bytes.to_vec(), - current_spec: SpecId::Genesis, + current_spec: SpecId::Fork1, pub_key: vec![], deposit_data: vec![], l1_fee_rate, @@ -457,7 +457,7 @@ fn begin_soft_confirmation_hook_appends_last_block_hashes() { da_slot_height: 1, da_slot_txs_commitment: random_32_bytes, pre_state_root: random_32_bytes.to_vec(), - current_spec: SpecId::Genesis, + current_spec: SpecId::Fork1, pub_key: vec![], deposit_data: vec![], l1_fee_rate, From d6d9d0f8d63a7d8aea806bd21d8ac6b9a76eb0b7 Mon Sep 17 00:00:00 2001 From: yaziciahmet Date: Fri, 20 Dec 2024 22:13:53 +0100 Subject: [PATCH 89/96] Fix all hooks tests --- crates/evm/src/tests/hooks_tests.rs | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/crates/evm/src/tests/hooks_tests.rs b/crates/evm/src/tests/hooks_tests.rs index ef765387d..0ac382f9b 100644 --- a/crates/evm/src/tests/hooks_tests.rs +++ b/crates/evm/src/tests/hooks_tests.rs @@ -90,7 +90,7 @@ fn end_soft_confirmation_hook_sets_head() { .push(create_pending_transaction(2, 1)); evm.end_soft_confirmation_hook(&soft_confirmation_info, &mut working_set); - let head = evm.head.get(&mut working_set).unwrap(); + let head = evm.head_rlp.get(&mut working_set).unwrap(); let pending_head = evm .pending_head .get(&mut working_set.accessory_state()) @@ -100,9 +100,9 @@ fn end_soft_confirmation_hook_sets_head() { assert_eq!( head, Block { - header: crate::primitive_types::DoNotUseHeader { + header: alloy_consensus::Header { parent_hash: B256::from(hex!( - "42b2df14615729c49a449b8f42c1a9eb4b9b62fb6a70464eabfa362cd1d20f75" + "cddac53c8ce67726f9d2c51cdfca6af78e24e836ffbc614e878a59d89fcd7738" )), ommers_hash: EMPTY_OMMER_ROOT_HASH, @@ -122,11 +122,11 @@ fn end_soft_confirmation_hook_sets_head() { gas_used: 200u64, timestamp: 54, mix_hash: *DA_ROOT_HASH, - nonce: 0, + nonce: 0u64.into(), base_fee_per_gas: Some(767816299), extra_data: Bytes::default(), - blob_gas_used: None, - excess_blob_gas: None, + blob_gas_used: Some(0), + excess_blob_gas: Some(0), parent_beacon_block_root: None, requests_root: None, }, From 29fc600576b9727d467c360c0f38acdc8bd1d9d6 Mon Sep 17 00:00:00 2001 From: yaziciahmet Date: Fri, 20 Dec 2024 22:14:26 +0100 Subject: [PATCH 90/96] Fix all genesis tests --- crates/evm/src/tests/genesis_tests.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/crates/evm/src/tests/genesis_tests.rs b/crates/evm/src/tests/genesis_tests.rs index a5e949c2d..7f296e065 100644 --- a/crates/evm/src/tests/genesis_tests.rs +++ b/crates/evm/src/tests/genesis_tests.rs @@ -164,7 +164,7 @@ fn genesis_block() { #[test] fn genesis_head() { let (evm, mut working_set) = get_evm(&get_evm_test_config()); - let head = evm.head.get(&mut working_set).unwrap(); + let head = evm.head_rlp.get(&mut working_set).unwrap(); assert_eq!(head.header.parent_hash, *GENESIS_HASH); let genesis_block = evm .blocks From a67259e97e2fd268ba0806eada471bfa61ab09fa Mon Sep 17 00:00:00 2001 From: yaziciahmet Date: Fri, 20 Dec 2024 23:27:05 +0100 Subject: [PATCH 91/96] Fix all call tests --- crates/evm/src/tests/call_tests.rs | 230 ++++++++++------------------- crates/evm/src/tests/utils.rs | 7 +- crates/primitives/src/forks.rs | 5 + 3 files changed, 93 insertions(+), 149 deletions(-) diff --git a/crates/evm/src/tests/call_tests.rs b/crates/evm/src/tests/call_tests.rs index 926bcf0e0..ad4fdaf26 100644 --- a/crates/evm/src/tests/call_tests.rs +++ b/crates/evm/src/tests/call_tests.rs @@ -4,6 +4,7 @@ use std::str::FromStr; use alloy_eips::BlockId; use alloy_primitives::{address, b256, Address, Bytes, TxKind, B256, U64}; use alloy_rpc_types::{BlockOverrides, TransactionInput, TransactionRequest}; +use citrea_primitives::forks::set_test_forks; use citrea_primitives::MIN_BASE_FEE_PER_GAS; use reth_primitives::constants::ETHEREUM_BLOCK_GAS_LIMIT; use reth_primitives::{BlockNumberOrTag, Log, LogData}; @@ -11,6 +12,7 @@ use revm::primitives::SpecId::SHANGHAI; use revm::primitives::{hex, KECCAK_EMPTY, U256}; use revm::Database; use sov_modules_api::default_context::DefaultContext; +use sov_modules_api::fork::Fork; use sov_modules_api::hooks::HookSoftConfirmationInfo; use sov_modules_api::utils::generate_address; use sov_modules_api::{ @@ -21,16 +23,14 @@ use sov_rollup_interface::spec::SpecId as SovSpecId; use crate::call::CallMessage; use crate::evm::primitive_types::Receipt; use crate::evm::DbAccount; -use crate::handler::{BROTLI_COMPRESSION_PERCENTAGE, L1_FEE_OVERHEAD}; +use crate::handler::L1_FEE_OVERHEAD; use crate::smart_contracts::{ BlockHashContract, InfiniteLoopContract, LogsContract, SelfDestructorContract, SimpleStorageContract, TestContract, }; use crate::tests::test_signer::TestSigner; use crate::tests::utils::{ - config_push_contracts, create_contract_message, create_contract_message_with_fee, - create_contract_message_with_fee_and_gas_limit, create_contract_transaction, get_evm, - get_evm_config, get_evm_config_starting_base_fee, publish_event_message, set_arg_message, + config_push_contracts, create_contract_message, create_contract_message_with_fee, create_contract_message_with_fee_and_gas_limit, create_contract_transaction, get_evm, get_evm_config, get_evm_config_starting_base_fee, get_evm_with_spec, publish_event_message, set_arg_message }; use crate::tests::DEFAULT_CHAIN_ID; use crate::{ @@ -69,7 +69,7 @@ fn call_multiple_test() { da_slot_height: 1, da_slot_txs_commitment: [42u8; 32], pre_state_root: [10u8; 32].to_vec(), - current_spec: SovSpecId::Genesis, + current_spec: SovSpecId::Fork1, pub_key: vec![], deposit_data: vec![], l1_fee_rate, @@ -82,7 +82,7 @@ fn call_multiple_test() { { let sender_address = generate_address::("sender"); - let context = C::new(sender_address, l2_height, SovSpecId::Genesis, l1_fee_rate); + let context = C::new(sender_address, l2_height, SovSpecId::Fork1, l1_fee_rate); let transactions: Vec = vec![ create_contract_transaction(&dev_signer1, 0, SimpleStorageContract::default()), @@ -138,8 +138,8 @@ fn call_multiple_test() { logs: vec![] }, gas_used: 50751, - log_index_start: 0, - l1_diff_size: 255 + log_index_start: 0, + l1_diff_size: 53 }, Receipt { receipt: reth_primitives::Receipt { @@ -155,9 +155,9 @@ fn call_multiple_test() { ).unwrap() } ]}, - gas_used: 80620, - log_index_start: 0, - l1_diff_size: 561 + gas_used: 80620, + log_index_start: 0, + l1_diff_size: 94 }, Receipt { receipt: reth_primitives::Receipt{ @@ -183,7 +183,7 @@ fn call_multiple_test() { }, gas_used: 169150, log_index_start: 1, - l1_diff_size: 1019 + l1_diff_size: 154 }, Receipt { receipt: reth_primitives::Receipt { @@ -200,13 +200,13 @@ fn call_multiple_test() { }, gas_used: 80620, log_index_start: 0, - l1_diff_size: 561 + l1_diff_size: 94 }, - Receipt { receipt: reth_primitives::Receipt { tx_type: reth_primitives::TxType::Eip1559, success: true, cumulative_gas_used: 213563, logs: vec![] }, gas_used: 132943, log_index_start: 1, l1_diff_size: 567 }, - Receipt { receipt: reth_primitives::Receipt { tx_type: reth_primitives::TxType::Eip1559, success: true, cumulative_gas_used: 257293, logs: vec![] }, gas_used: 43730, log_index_start: 1, l1_diff_size: 255 }, - Receipt { receipt: reth_primitives::Receipt { tx_type: reth_primitives::TxType::Eip1559, success: true, cumulative_gas_used: 283923, logs: vec![] }, gas_used: 26630, log_index_start: 1, l1_diff_size: 255 }, + Receipt { receipt: reth_primitives::Receipt { tx_type: reth_primitives::TxType::Eip1559, success: true, cumulative_gas_used: 213563, logs: vec![] }, gas_used: 132943, log_index_start: 1, l1_diff_size: 52 }, + Receipt { receipt: reth_primitives::Receipt { tx_type: reth_primitives::TxType::Eip1559, success: true, cumulative_gas_used: 257293, logs: vec![] }, gas_used: 43730, log_index_start: 1, l1_diff_size: 53 }, + Receipt { receipt: reth_primitives::Receipt { tx_type: reth_primitives::TxType::Eip1559, success: true, cumulative_gas_used: 283923, logs: vec![] }, gas_used: 26630, log_index_start: 1, l1_diff_size: 53 }, Receipt { receipt: reth_primitives::Receipt { tx_type: reth_primitives::TxType::Eip1559, success: true, cumulative_gas_used: 310553, logs: vec![] }, - gas_used: 26630, log_index_start: 1, l1_diff_size: 255 }] + gas_used: 26630, log_index_start: 1, l1_diff_size: 53 }] ); // checkout esad/fix-block-env-bug branch let tx = evm @@ -236,7 +236,7 @@ fn call_test() { da_slot_height: 1, da_slot_txs_commitment: [42u8; 32], pre_state_root: [10u8; 32].to_vec(), - current_spec: SovSpecId::Genesis, + current_spec: SovSpecId::Fork1, pub_key: vec![], deposit_data: vec![], l1_fee_rate, @@ -248,7 +248,7 @@ fn call_test() { let set_arg = 999; { let sender_address = generate_address::("sender"); - let context = C::new(sender_address, l2_height, SovSpecId::Genesis, l1_fee_rate); + let context = C::new(sender_address, l2_height, SovSpecId::Fork1, l1_fee_rate); let rlp_transactions = vec![ create_contract_message(&dev_signer, 0, SimpleStorageContract::default()), @@ -285,7 +285,7 @@ fn call_test() { }, gas_used: 50751, log_index_start: 0, - l1_diff_size: 255 + l1_diff_size: 53 }, Receipt { receipt: reth_primitives::Receipt { @@ -304,7 +304,7 @@ fn call_test() { }, gas_used: 80620, log_index_start: 0, - l1_diff_size: 561 + l1_diff_size: 94 }, Receipt { receipt: reth_primitives::Receipt { @@ -330,7 +330,7 @@ fn call_test() { }, gas_used: 169150, log_index_start: 1, - l1_diff_size: 1019 + l1_diff_size: 154 }, Receipt { receipt: reth_primitives::Receipt { @@ -349,7 +349,7 @@ fn call_test() { }, gas_used: 80620, log_index_start: 0, - l1_diff_size: 561 + l1_diff_size: 94 }, Receipt { receipt: reth_primitives::Receipt { @@ -360,7 +360,7 @@ fn call_test() { }, gas_used: 132943, log_index_start: 1, - l1_diff_size: 567 + l1_diff_size: 52 }, Receipt { receipt: reth_primitives::Receipt { @@ -371,7 +371,7 @@ fn call_test() { }, gas_used: 43730, log_index_start: 1, - l1_diff_size: 255 + l1_diff_size: 53 }] ); } @@ -393,7 +393,7 @@ fn failed_transaction_test() { da_slot_height: 1, da_slot_txs_commitment: [42u8; 32], pre_state_root: [10u8; 32].to_vec(), - current_spec: SovSpecId::Genesis, + current_spec: SovSpecId::Fork1, pub_key: vec![], deposit_data: vec![], l1_fee_rate, @@ -403,7 +403,7 @@ fn failed_transaction_test() { evm.begin_soft_confirmation_hook(&soft_confirmation_info, working_set); { let sender_address = generate_address::("sender"); - let context = C::new(sender_address, l2_height, SovSpecId::Genesis, l1_fee_rate); + let context = C::new(sender_address, l2_height, SovSpecId::Fork1, l1_fee_rate); let rlp_transactions = vec![create_contract_message( &dev_signer, 0, @@ -443,7 +443,7 @@ fn failed_transaction_test() { }, gas_used: 50751, log_index_start: 0, - l1_diff_size: 255 + l1_diff_size: 53 }, Receipt { receipt: reth_primitives::Receipt{ @@ -462,7 +462,7 @@ fn failed_transaction_test() { }, gas_used: 80620, log_index_start: 0, - l1_diff_size: 561 + l1_diff_size: 94 }, Receipt { receipt: reth_primitives::Receipt { @@ -486,7 +486,7 @@ fn failed_transaction_test() { }, gas_used: 169150, log_index_start: 1, - l1_diff_size: 1019 + l1_diff_size: 154 }, Receipt { receipt: reth_primitives::Receipt { @@ -505,7 +505,7 @@ fn failed_transaction_test() { }, gas_used: 80620, log_index_start: 0, - l1_diff_size: 561 + l1_diff_size: 94 } ] ); @@ -518,6 +518,12 @@ fn failed_transaction_test() { // test self destruct behaviour before cancun and after cancun #[test] fn self_destruct_test() { + static F: &[Fork] = &[ + Fork::new(SovSpecId::Genesis, 0), + Fork::new(SovSpecId::Fork1, 4), + ]; + set_test_forks(F); + let contract_balance: u64 = 1000000000000000; // address used in selfdestruct @@ -526,7 +532,7 @@ fn self_destruct_test() { let (config, dev_signer, contract_addr) = get_evm_config(U256::from_str("100000000000000000000").unwrap(), None); - let (mut evm, mut working_set) = get_evm(&config); + let (mut evm, mut working_set) = get_evm_with_spec(&config, SovSpecId::Genesis); let l1_fee_rate = 0; let mut l2_height = 2; @@ -813,7 +819,7 @@ fn test_block_hash_in_evm() { da_slot_height: 1, da_slot_txs_commitment: [42u8; 32], pre_state_root: [10u8; 32].to_vec(), - current_spec: SovSpecId::Genesis, + current_spec: SovSpecId::Fork1, pub_key: vec![], deposit_data: vec![], l1_fee_rate, @@ -823,7 +829,7 @@ fn test_block_hash_in_evm() { evm.begin_soft_confirmation_hook(&soft_confirmation_info, &mut working_set); { let sender_address = generate_address::("sender"); - let context = C::new(sender_address, l2_height, SovSpecId::Genesis, l1_fee_rate); + let context = C::new(sender_address, l2_height, SovSpecId::Fork1, l1_fee_rate); let deploy_message = create_contract_message(&dev_signer, 0, BlockHashContract::default()); @@ -850,7 +856,7 @@ fn test_block_hash_in_evm() { da_slot_height: 1, da_slot_txs_commitment: [42u8; 32], pre_state_root: [99u8; 32].to_vec(), - current_spec: SovSpecId::Genesis, + current_spec: SovSpecId::Fork1, pub_key: vec![], deposit_data: vec![], l1_fee_rate, @@ -961,7 +967,7 @@ fn test_block_gas_limit() { da_slot_height: 1, da_slot_txs_commitment: [42u8; 32], pre_state_root: [10u8; 32].to_vec(), - current_spec: SovSpecId::Genesis, + current_spec: SovSpecId::Fork1, pub_key: vec![], deposit_data: vec![], l1_fee_rate, @@ -971,7 +977,7 @@ fn test_block_gas_limit() { evm.begin_soft_confirmation_hook(&soft_confirmation_info, &mut working_set); { let sender_address = generate_address::("sender"); - let context = C::new(sender_address, l2_height, SovSpecId::Genesis, l1_fee_rate); + let context = C::new(sender_address, l2_height, SovSpecId::Fork1, l1_fee_rate); // deploy logs contract let mut rlp_transactions = vec![create_contract_message( @@ -1026,7 +1032,7 @@ fn test_block_gas_limit() { da_slot_height: 1, da_slot_txs_commitment: [42u8; 32], pre_state_root: [10u8; 32].to_vec(), - current_spec: SovSpecId::Genesis, + current_spec: SovSpecId::Fork1, pub_key: vec![], deposit_data: vec![], l1_fee_rate, @@ -1036,7 +1042,7 @@ fn test_block_gas_limit() { evm.begin_soft_confirmation_hook(&soft_confirmation_info, &mut working_set); { let sender_address = generate_address::("sender"); - let context = C::new(sender_address, l2_height, SovSpecId::Genesis, l1_fee_rate); + let context = C::new(sender_address, l2_height, SovSpecId::Fork1, l1_fee_rate); // deploy logs contract let mut rlp_transactions = vec![create_contract_message( @@ -1182,7 +1188,7 @@ fn test_l1_fee_success() { da_slot_height: 1, da_slot_txs_commitment: [42u8; 32], pre_state_root: [10u8; 32].to_vec(), - current_spec: SovSpecId::Genesis, + current_spec: SovSpecId::Fork1, pub_key: vec![], deposit_data: vec![], l1_fee_rate, @@ -1193,7 +1199,7 @@ fn test_l1_fee_success() { { let sender_address = generate_address::("sender"); - let context = C::new(sender_address, 2, SovSpecId::Genesis, l1_fee_rate); + let context = C::new(sender_address, 2, SovSpecId::Fork1, l1_fee_rate); let deploy_message = create_contract_message_with_priority_fee( &dev_signer, @@ -1248,7 +1254,7 @@ fn test_l1_fee_success() { }, gas_used: 50751, log_index_start: 0, - l1_diff_size: 255 + l1_diff_size: 53, }, Receipt { receipt: reth_primitives::Receipt { @@ -1267,7 +1273,7 @@ fn test_l1_fee_success() { }, gas_used: 80620, log_index_start: 0, - l1_diff_size: 561 + l1_diff_size: 94 }, Receipt { receipt: reth_primitives::Receipt { @@ -1292,7 +1298,7 @@ fn test_l1_fee_success() { }, gas_used: 169150, log_index_start: 1, - l1_diff_size: 1019 + l1_diff_size: 154 }, Receipt { receipt: reth_primitives::Receipt { @@ -1310,7 +1316,7 @@ fn test_l1_fee_success() { }, gas_used: 80620, log_index_start: 0, - l1_diff_size: 561 + l1_diff_size: 94, }, Receipt { receipt: reth_primitives::Receipt { @@ -1321,7 +1327,7 @@ fn test_l1_fee_success() { }, gas_used: 114235, log_index_start: 1, - l1_diff_size: 479 + l1_diff_size: 52 } ] ) @@ -1339,11 +1345,11 @@ fn test_l1_fee_success() { ); run_tx( 1, - U256::from(100000000000000u64 - gas_fee_paid * 10000001 - 479 - L1_FEE_OVERHEAD as u64), + U256::from(100000000000000u64 - gas_fee_paid * 10000001 - 52 - L1_FEE_OVERHEAD as u64), // priority fee goes to coinbase U256::from(gas_fee_paid), U256::from(gas_fee_paid * 10000000), - U256::from(479 + L1_FEE_OVERHEAD as u64), + U256::from(52 + L1_FEE_OVERHEAD as u64), ); } @@ -1366,7 +1372,7 @@ fn test_l1_fee_not_enough_funds() { da_slot_height: 1, da_slot_txs_commitment: [42u8; 32], pre_state_root: [10u8; 32].to_vec(), - current_spec: SovSpecId::Genesis, + current_spec: SovSpecId::Fork1, pub_key: vec![], deposit_data: vec![], l1_fee_rate, @@ -1377,7 +1383,7 @@ fn test_l1_fee_not_enough_funds() { { let sender_address = generate_address::("sender"); - let context = C::new(sender_address, l2_height, SovSpecId::Genesis, l1_fee_rate); + let context = C::new(sender_address, l2_height, SovSpecId::Fork1, l1_fee_rate); let deploy_message = create_contract_message_with_fee_and_gas_limit( &dev_signer, @@ -1416,7 +1422,7 @@ fn test_l1_fee_not_enough_funds() { }, gas_used: 50751, log_index_start: 0, - l1_diff_size: 255 + l1_diff_size: 53 }, Receipt { receipt: reth_primitives::Receipt { @@ -1435,7 +1441,7 @@ fn test_l1_fee_not_enough_funds() { }, gas_used: 80620, log_index_start: 0, - l1_diff_size: 561 + l1_diff_size: 94 }, Receipt { receipt: reth_primitives::Receipt { @@ -1461,7 +1467,7 @@ fn test_l1_fee_not_enough_funds() { }, gas_used: 169150, log_index_start: 1, - l1_diff_size: 1019 + l1_diff_size: 154 } ] ); @@ -1499,7 +1505,7 @@ fn test_l1_fee_halt() { da_slot_height: 1, da_slot_txs_commitment: [42u8; 32], pre_state_root: [10u8; 32].to_vec(), - current_spec: SovSpecId::Genesis, + current_spec: SovSpecId::Fork1, pub_key: vec![], deposit_data: vec![], l1_fee_rate, @@ -1510,7 +1516,7 @@ fn test_l1_fee_halt() { { let sender_address = generate_address::("sender"); - let context = C::new(sender_address, l2_height, SovSpecId::Genesis, l1_fee_rate); + let context = C::new(sender_address, l2_height, SovSpecId::Fork1, l1_fee_rate); let deploy_message = create_contract_message_with_fee( &dev_signer, @@ -1557,7 +1563,7 @@ fn test_l1_fee_halt() { }, gas_used: 50751, log_index_start: 0, - l1_diff_size: 255 + l1_diff_size: 53 }, Receipt { receipt: reth_primitives::Receipt { @@ -1576,7 +1582,7 @@ fn test_l1_fee_halt() { }, gas_used: 80620, log_index_start: 0, - l1_diff_size: 561 + l1_diff_size: 94 }, Receipt { receipt: reth_primitives::Receipt { @@ -1602,7 +1608,7 @@ fn test_l1_fee_halt() { }, gas_used: 169150, log_index_start: 1, - l1_diff_size: 1019 + l1_diff_size: 154 }, Receipt { receipt: reth_primitives::Receipt { @@ -1621,7 +1627,7 @@ fn test_l1_fee_halt() { }, gas_used: 80620, log_index_start: 0, - l1_diff_size: 561 + l1_diff_size: 94 }, Receipt { receipt: reth_primitives::Receipt { @@ -1632,7 +1638,7 @@ fn test_l1_fee_halt() { }, gas_used: 106947, log_index_start: 1, - l1_diff_size: 447 + l1_diff_size: 52 }, Receipt { receipt: reth_primitives::Receipt @@ -1643,7 +1649,7 @@ fn test_l1_fee_halt() { }, gas_used: 1000000, log_index_start: 1, - l1_diff_size: 96 + l1_diff_size: 31 } ] ); @@ -1654,8 +1660,8 @@ fn test_l1_fee_halt() { .unwrap(); let expenses = 1106947_u64 * 10000000 + // evm gas - 447 + // l1 contract deploy fee - 96 + // l1 contract call fee + 52 + // l1 contract deploy fee + 31 + // l1 contract call fee 2 * L1_FEE_OVERHEAD as u64; // l1 fee overhead *2 assert_eq!( db_account.balance, @@ -1670,7 +1676,7 @@ fn test_l1_fee_halt() { assert_eq!(base_fee_vault.balance, U256::from(1106947_u64 * 10000000)); assert_eq!( l1_fee_vault.balance, - U256::from(447 + 96 + 2 * L1_FEE_OVERHEAD as u64) + U256::from(52 + 31 + 2 * L1_FEE_OVERHEAD as u64) ); } @@ -1688,7 +1694,7 @@ fn test_l1_fee_compression_discount() { da_slot_height: 1, da_slot_txs_commitment: [42u8; 32], pre_state_root: [10u8; 32].to_vec(), - current_spec: SovSpecId::Genesis, + current_spec: SovSpecId::Fork1, pub_key: vec![], deposit_data: vec![], l1_fee_rate, @@ -1698,7 +1704,7 @@ fn test_l1_fee_compression_discount() { evm.begin_soft_confirmation_hook(&soft_confirmation_info, &mut working_set); { let sender_address = generate_address::("sender"); - let context = C::new(sender_address, 2, SovSpecId::Genesis, l1_fee_rate); + let context = C::new(sender_address, 2, SovSpecId::Fork1, l1_fee_rate); let call_tx = dev_signer .sign_default_transaction_with_priority_fee( TxKind::Call(Address::random()), @@ -1735,102 +1741,30 @@ fn test_l1_fee_compression_discount() { assert_eq!(config.coinbase, PRIORITY_FEE_VAULT); let gas_fee_paid = 21000; - let tx1_diff_size = 140; + let tx1_diff_size = 46; - let mut expected_db_balance = U256::from( + let expected_db_balance = U256::from( 100000000000000u64 - 1000 - gas_fee_paid * 10000001 - tx1_diff_size - L1_FEE_OVERHEAD as u64, ); - let mut expected_base_fee_vault_balance = U256::from(gas_fee_paid * 10000000); - let mut expected_coinbase_balance = U256::from(gas_fee_paid); - let mut expected_l1_fee_vault_balance = U256::from(tx1_diff_size + L1_FEE_OVERHEAD as u64); - - assert_eq!(db_account.balance, expected_db_balance); - assert_eq!(base_fee_vault.balance, expected_base_fee_vault_balance); - assert_eq!(coinbase_account.balance, expected_coinbase_balance); - assert_eq!(l1_fee_vault.balance, expected_l1_fee_vault_balance); - - // Set up the next transaction with the fork 1 activated - let soft_confirmation_info = HookSoftConfirmationInfo { - l2_height: 3, - da_slot_hash: [5u8; 32], - da_slot_height: 1, - da_slot_txs_commitment: [42u8; 32], - pre_state_root: [99u8; 32].to_vec(), - current_spec: SovSpecId::Fork1, // Compression discount is enabled - pub_key: vec![], - deposit_data: vec![], - l1_fee_rate, - timestamp: 0, - }; - - evm.begin_soft_confirmation_hook(&soft_confirmation_info, &mut working_set); - { - let sender_address = generate_address::("sender"); - let context = C::new(sender_address, 3, SovSpecId::Fork1, l1_fee_rate); - let simple_tx = dev_signer - .sign_default_transaction_with_priority_fee( - TxKind::Call(Address::random()), - vec![], - 1, - 1000, - 20000000, - 1, - ) - .unwrap(); - evm.call( - CallMessage { - txs: vec![simple_tx], - }, - &context, - &mut working_set, - ) - .unwrap(); - } - evm.end_soft_confirmation_hook(&soft_confirmation_info, &mut working_set); - evm.finalize_hook(&[98u8; 32].into(), &mut working_set.accessory_state()); - - let db_account = evm - .accounts - .get(&dev_signer.address(), &mut working_set) - .unwrap(); - let base_fee_vault = evm.accounts.get(&BASE_FEE_VAULT, &mut working_set).unwrap(); - let l1_fee_vault = evm.accounts.get(&L1_FEE_VAULT, &mut working_set).unwrap(); - - let coinbase_account = evm - .accounts - .get(&config.coinbase, &mut working_set) - .unwrap(); - - // gas fee remains the same - let tx2_diff_size = 46; - - expected_db_balance -= - U256::from(gas_fee_paid * 10000001 + 1000 + tx2_diff_size + L1_FEE_OVERHEAD as u64); - expected_base_fee_vault_balance += U256::from(gas_fee_paid * 10000000); - expected_coinbase_balance += U256::from(gas_fee_paid); - expected_l1_fee_vault_balance += U256::from(tx2_diff_size + L1_FEE_OVERHEAD as u64); + let expected_base_fee_vault_balance = U256::from(gas_fee_paid * 10000000); + let expected_coinbase_balance = U256::from(gas_fee_paid); + let expected_l1_fee_vault_balance = U256::from(tx1_diff_size + L1_FEE_OVERHEAD as u64); assert_eq!(db_account.balance, expected_db_balance); assert_eq!(base_fee_vault.balance, expected_base_fee_vault_balance); assert_eq!(coinbase_account.balance, expected_coinbase_balance); assert_eq!(l1_fee_vault.balance, expected_l1_fee_vault_balance); - // assert comression discount - assert_eq!( - tx1_diff_size * BROTLI_COMPRESSION_PERCENTAGE as u64 / 100, - tx2_diff_size - ); - assert_eq!( evm.receipts .iter(&mut working_set.accessory_state()) .map(|r| r.l1_diff_size) .collect::>(), - [255, 561, 1019, 561, tx1_diff_size, tx2_diff_size] + [53, 94, 154, 94, tx1_diff_size] ); } @@ -1849,7 +1783,7 @@ fn test_call_with_block_overrides() { da_slot_height: 1, da_slot_txs_commitment: [42u8; 32], pre_state_root: [10u8; 32].to_vec(), - current_spec: SovSpecId::Genesis, + current_spec: SovSpecId::Fork1, pub_key: vec![], deposit_data: vec![], l1_fee_rate, @@ -1860,7 +1794,7 @@ fn test_call_with_block_overrides() { let sender_address = generate_address::("sender"); evm.begin_soft_confirmation_hook(&soft_confirmation_info, &mut working_set); { - let context = C::new(sender_address, l2_height, SovSpecId::Genesis, l1_fee_rate); + let context = C::new(sender_address, l2_height, SovSpecId::Fork1, l1_fee_rate); let deploy_message = create_contract_message(&dev_signer, 0, BlockHashContract::default()); @@ -1886,7 +1820,7 @@ fn test_call_with_block_overrides() { da_slot_height: 1, da_slot_txs_commitment: [42u8; 32], pre_state_root: [99u8; 32].to_vec(), - current_spec: SovSpecId::Genesis, + current_spec: SovSpecId::Fork1, pub_key: vec![], deposit_data: vec![], l1_fee_rate, @@ -1988,7 +1922,7 @@ fn test_blob_tx() { let sender_address = generate_address::("sender"); evm.begin_soft_confirmation_hook(&soft_confirmation_info, &mut working_set); { - let context = C::new(sender_address, l2_height, SovSpecId::Genesis, l1_fee_rate); + let context = C::new(sender_address, l2_height, SovSpecId::Fork1, l1_fee_rate); let blob_message = dev_signer .sign_blob_transaction(Address::ZERO, vec![B256::random()], 0) diff --git a/crates/evm/src/tests/utils.rs b/crates/evm/src/tests/utils.rs index 36810dcc8..28924ba42 100644 --- a/crates/evm/src/tests/utils.rs +++ b/crates/evm/src/tests/utils.rs @@ -52,7 +52,12 @@ pub(crate) fn get_evm_with_storage( ); (evm, working_set, prover_storage) } + pub(crate) fn get_evm(config: &EvmConfig) -> (Evm, WorkingSet<::Storage>) { + get_evm_with_spec(config, SovSpecId::Fork1) +} + +pub(crate) fn get_evm_with_spec(config: &EvmConfig, spec_id: SovSpecId) -> (Evm, WorkingSet<::Storage>) { let tmpdir = tempfile::tempdir().unwrap(); let storage = new_orphan_storage(tmpdir.path()).unwrap(); let mut working_set = WorkingSet::new(storage.clone()); @@ -70,7 +75,7 @@ pub(crate) fn get_evm(config: &EvmConfig) -> (Evm, WorkingSet<::St da_slot_height: 1, da_slot_txs_commitment: [2u8; 32], pre_state_root: root.to_vec(), - current_spec: SovSpecId::Fork1, + current_spec: spec_id, pub_key: vec![], deposit_data: vec![], l1_fee_rate: 0, diff --git a/crates/primitives/src/forks.rs b/crates/primitives/src/forks.rs index a67598aea..dc53ea389 100644 --- a/crates/primitives/src/forks.rs +++ b/crates/primitives/src/forks.rs @@ -71,3 +71,8 @@ const _CHECK_FORKS: () = { panic!("FORKS order is invalid") } }; + +#[cfg(feature = "testing")] +pub fn set_test_forks(forks: &'static [Fork]) { + FORKS.set(forks).unwrap() +} From 78588eea3dfba976ebe6237dce2b31926d0b56b3 Mon Sep 17 00:00:00 2001 From: yaziciahmet Date: Fri, 20 Dec 2024 23:30:13 +0100 Subject: [PATCH 92/96] Remove unnecessary fork setting --- crates/evm/src/tests/call_tests.rs | 8 -------- 1 file changed, 8 deletions(-) diff --git a/crates/evm/src/tests/call_tests.rs b/crates/evm/src/tests/call_tests.rs index ad4fdaf26..ff08f6967 100644 --- a/crates/evm/src/tests/call_tests.rs +++ b/crates/evm/src/tests/call_tests.rs @@ -4,7 +4,6 @@ use std::str::FromStr; use alloy_eips::BlockId; use alloy_primitives::{address, b256, Address, Bytes, TxKind, B256, U64}; use alloy_rpc_types::{BlockOverrides, TransactionInput, TransactionRequest}; -use citrea_primitives::forks::set_test_forks; use citrea_primitives::MIN_BASE_FEE_PER_GAS; use reth_primitives::constants::ETHEREUM_BLOCK_GAS_LIMIT; use reth_primitives::{BlockNumberOrTag, Log, LogData}; @@ -12,7 +11,6 @@ use revm::primitives::SpecId::SHANGHAI; use revm::primitives::{hex, KECCAK_EMPTY, U256}; use revm::Database; use sov_modules_api::default_context::DefaultContext; -use sov_modules_api::fork::Fork; use sov_modules_api::hooks::HookSoftConfirmationInfo; use sov_modules_api::utils::generate_address; use sov_modules_api::{ @@ -518,12 +516,6 @@ fn failed_transaction_test() { // test self destruct behaviour before cancun and after cancun #[test] fn self_destruct_test() { - static F: &[Fork] = &[ - Fork::new(SovSpecId::Genesis, 0), - Fork::new(SovSpecId::Fork1, 4), - ]; - set_test_forks(F); - let contract_balance: u64 = 1000000000000000; // address used in selfdestruct From 31303bdd249d004bf395da491656316ac2be1b18 Mon Sep 17 00:00:00 2001 From: yaziciahmet Date: Fri, 20 Dec 2024 23:33:08 +0100 Subject: [PATCH 93/96] Fix fork tests --- crates/evm/src/tests/fork_tests.rs | 10 +++++----- crates/primitives/src/forks.rs | 5 ----- 2 files changed, 5 insertions(+), 10 deletions(-) diff --git a/crates/evm/src/tests/fork_tests.rs b/crates/evm/src/tests/fork_tests.rs index f117f5b8c..818596de7 100644 --- a/crates/evm/src/tests/fork_tests.rs +++ b/crates/evm/src/tests/fork_tests.rs @@ -17,7 +17,7 @@ use crate::smart_contracts::{ SelfdestructingConstructorContract, SimpleStorageContract, TransientStorageContract, }; use crate::tests::test_signer::TestSigner; -use crate::tests::utils::{create_contract_message, get_evm, get_evm_config, set_arg_message}; +use crate::tests::utils::{create_contract_message, get_evm, get_evm_config, get_evm_with_spec, set_arg_message}; use crate::RlpEvmTransaction; type C = DefaultContext; @@ -82,7 +82,7 @@ fn test_cancun_transient_storage_activation() { let (config, dev_signer, contract_addr) = get_evm_config(U256::from_str("100000000000000000000").unwrap(), None); - let (mut evm, mut working_set) = get_evm(&config); + let (mut evm, mut working_set) = get_evm_with_spec(&config, SovSpecId::Genesis); let l1_fee_rate = 0; let mut l2_height = 2; @@ -238,7 +238,7 @@ fn test_cancun_mcopy_activation() { let (config, dev_signer, contract_addr) = get_evm_config(U256::from_str("100000000000000000000").unwrap(), None); - let (mut evm, mut working_set) = get_evm(&config); + let (mut evm, mut working_set) = get_evm_with_spec(&config, SovSpecId::Genesis); let l1_fee_rate = 0; let mut l2_height = 2; @@ -439,7 +439,7 @@ fn test_blob_base_fee_should_return_1() { let (config, dev_signer, contract_addr) = get_evm_config(U256::from_str("100000000000000000000").unwrap(), None); - let (mut evm, mut working_set) = get_evm(&config); + let (mut evm, mut working_set) = get_evm_with_spec(&config, SovSpecId::Genesis); let l1_fee_rate = 0; let mut l2_height = 2; @@ -674,7 +674,7 @@ fn test_offchain_contract_storage_evm() { let (config, dev_signer, contract_addr) = get_evm_config(U256::from_str("100000000000000000000").unwrap(), None); - let (mut evm, mut working_set) = get_evm(&config); + let (mut evm, mut working_set) = get_evm_with_spec(&config, SovSpecId::Genesis); let l1_fee_rate = 0; let mut l2_height = 2; diff --git a/crates/primitives/src/forks.rs b/crates/primitives/src/forks.rs index dc53ea389..a67598aea 100644 --- a/crates/primitives/src/forks.rs +++ b/crates/primitives/src/forks.rs @@ -71,8 +71,3 @@ const _CHECK_FORKS: () = { panic!("FORKS order is invalid") } }; - -#[cfg(feature = "testing")] -pub fn set_test_forks(forks: &'static [Fork]) { - FORKS.set(forks).unwrap() -} From 17921714c396b9019ad4272d6ba153af4860f04c Mon Sep 17 00:00:00 2001 From: yaziciahmet Date: Fri, 20 Dec 2024 23:36:00 +0100 Subject: [PATCH 94/96] Lint --- crates/evm/src/tests/call_tests.rs | 9 ++++++--- crates/evm/src/tests/fork_tests.rs | 4 +++- crates/evm/src/tests/hooks_tests.rs | 2 +- crates/evm/src/tests/utils.rs | 5 ++++- 4 files changed, 14 insertions(+), 6 deletions(-) diff --git a/crates/evm/src/tests/call_tests.rs b/crates/evm/src/tests/call_tests.rs index ff08f6967..650814b3a 100644 --- a/crates/evm/src/tests/call_tests.rs +++ b/crates/evm/src/tests/call_tests.rs @@ -28,7 +28,10 @@ use crate::smart_contracts::{ }; use crate::tests::test_signer::TestSigner; use crate::tests::utils::{ - config_push_contracts, create_contract_message, create_contract_message_with_fee, create_contract_message_with_fee_and_gas_limit, create_contract_transaction, get_evm, get_evm_config, get_evm_config_starting_base_fee, get_evm_with_spec, publish_event_message, set_arg_message + config_push_contracts, create_contract_message, create_contract_message_with_fee, + create_contract_message_with_fee_and_gas_limit, create_contract_transaction, get_evm, + get_evm_config, get_evm_config_starting_base_fee, get_evm_with_spec, publish_event_message, + set_arg_message, }; use crate::tests::DEFAULT_CHAIN_ID; use crate::{ @@ -1246,7 +1249,7 @@ fn test_l1_fee_success() { }, gas_used: 50751, log_index_start: 0, - l1_diff_size: 53, + l1_diff_size: 53, }, Receipt { receipt: reth_primitives::Receipt { @@ -1319,7 +1322,7 @@ fn test_l1_fee_success() { }, gas_used: 114235, log_index_start: 1, - l1_diff_size: 52 + l1_diff_size: 52, } ] ) diff --git a/crates/evm/src/tests/fork_tests.rs b/crates/evm/src/tests/fork_tests.rs index 818596de7..0f79562cf 100644 --- a/crates/evm/src/tests/fork_tests.rs +++ b/crates/evm/src/tests/fork_tests.rs @@ -17,7 +17,9 @@ use crate::smart_contracts::{ SelfdestructingConstructorContract, SimpleStorageContract, TransientStorageContract, }; use crate::tests::test_signer::TestSigner; -use crate::tests::utils::{create_contract_message, get_evm, get_evm_config, get_evm_with_spec, set_arg_message}; +use crate::tests::utils::{ + create_contract_message, get_evm, get_evm_config, get_evm_with_spec, set_arg_message, +}; use crate::RlpEvmTransaction; type C = DefaultContext; diff --git a/crates/evm/src/tests/hooks_tests.rs b/crates/evm/src/tests/hooks_tests.rs index 0ac382f9b..d895ce622 100644 --- a/crates/evm/src/tests/hooks_tests.rs +++ b/crates/evm/src/tests/hooks_tests.rs @@ -96,7 +96,7 @@ fn end_soft_confirmation_hook_sets_head() { .get(&mut working_set.accessory_state()) .unwrap(); - assert_eq!(head, pending_head.into()); + assert_eq!(head, pending_head); assert_eq!( head, Block { diff --git a/crates/evm/src/tests/utils.rs b/crates/evm/src/tests/utils.rs index 28924ba42..1ba486428 100644 --- a/crates/evm/src/tests/utils.rs +++ b/crates/evm/src/tests/utils.rs @@ -57,7 +57,10 @@ pub(crate) fn get_evm(config: &EvmConfig) -> (Evm, WorkingSet<::St get_evm_with_spec(config, SovSpecId::Fork1) } -pub(crate) fn get_evm_with_spec(config: &EvmConfig, spec_id: SovSpecId) -> (Evm, WorkingSet<::Storage>) { +pub(crate) fn get_evm_with_spec( + config: &EvmConfig, + spec_id: SovSpecId, +) -> (Evm, WorkingSet<::Storage>) { let tmpdir = tempfile::tempdir().unwrap(); let storage = new_orphan_storage(tmpdir.path()).unwrap(); let mut working_set = WorkingSet::new(storage.clone()); From 5ecdb1c34bc2d82a2f9000022d64994ee8450c2d Mon Sep 17 00:00:00 2001 From: yaziciahmet Date: Fri, 20 Dec 2024 23:50:49 +0100 Subject: [PATCH 95/96] Recover l1 fee compression discount --- crates/evm/src/tests/call_tests.rs | 92 ++++++++++++++++++++++++++---- 1 file changed, 82 insertions(+), 10 deletions(-) diff --git a/crates/evm/src/tests/call_tests.rs b/crates/evm/src/tests/call_tests.rs index 650814b3a..2c56c5ea0 100644 --- a/crates/evm/src/tests/call_tests.rs +++ b/crates/evm/src/tests/call_tests.rs @@ -21,7 +21,7 @@ use sov_rollup_interface::spec::SpecId as SovSpecId; use crate::call::CallMessage; use crate::evm::primitive_types::Receipt; use crate::evm::DbAccount; -use crate::handler::L1_FEE_OVERHEAD; +use crate::handler::{BROTLI_COMPRESSION_PERCENTAGE, L1_FEE_OVERHEAD}; use crate::smart_contracts::{ BlockHashContract, InfiniteLoopContract, LogsContract, SelfDestructorContract, SimpleStorageContract, TestContract, @@ -1680,7 +1680,7 @@ fn test_l1_fee_compression_discount() { let (config, dev_signer, _) = get_evm_config_starting_base_fee(U256::from_str("100000000000000").unwrap(), None, 1); - let (mut evm, mut working_set) = get_evm(&config); + let (mut evm, mut working_set) = get_evm_with_spec(&config, SovSpecId::Genesis); let l1_fee_rate = 1; let soft_confirmation_info = HookSoftConfirmationInfo { @@ -1689,7 +1689,7 @@ fn test_l1_fee_compression_discount() { da_slot_height: 1, da_slot_txs_commitment: [42u8; 32], pre_state_root: [10u8; 32].to_vec(), - current_spec: SovSpecId::Fork1, + current_spec: SovSpecId::Genesis, pub_key: vec![], deposit_data: vec![], l1_fee_rate, @@ -1699,7 +1699,7 @@ fn test_l1_fee_compression_discount() { evm.begin_soft_confirmation_hook(&soft_confirmation_info, &mut working_set); { let sender_address = generate_address::("sender"); - let context = C::new(sender_address, 2, SovSpecId::Fork1, l1_fee_rate); + let context = C::new(sender_address, 2, SovSpecId::Genesis, l1_fee_rate); let call_tx = dev_signer .sign_default_transaction_with_priority_fee( TxKind::Call(Address::random()), @@ -1736,30 +1736,102 @@ fn test_l1_fee_compression_discount() { assert_eq!(config.coinbase, PRIORITY_FEE_VAULT); let gas_fee_paid = 21000; - let tx1_diff_size = 46; + let tx1_diff_size = 140; - let expected_db_balance = U256::from( + let mut expected_db_balance = U256::from( 100000000000000u64 - 1000 - gas_fee_paid * 10000001 - tx1_diff_size - L1_FEE_OVERHEAD as u64, ); - let expected_base_fee_vault_balance = U256::from(gas_fee_paid * 10000000); - let expected_coinbase_balance = U256::from(gas_fee_paid); - let expected_l1_fee_vault_balance = U256::from(tx1_diff_size + L1_FEE_OVERHEAD as u64); + let mut expected_base_fee_vault_balance = U256::from(gas_fee_paid * 10000000); + let mut expected_coinbase_balance = U256::from(gas_fee_paid); + let mut expected_l1_fee_vault_balance = U256::from(tx1_diff_size + L1_FEE_OVERHEAD as u64); assert_eq!(db_account.balance, expected_db_balance); assert_eq!(base_fee_vault.balance, expected_base_fee_vault_balance); assert_eq!(coinbase_account.balance, expected_coinbase_balance); assert_eq!(l1_fee_vault.balance, expected_l1_fee_vault_balance); + // Set up the next transaction with the fork 1 activated + let soft_confirmation_info = HookSoftConfirmationInfo { + l2_height: 3, + da_slot_hash: [5u8; 32], + da_slot_height: 1, + da_slot_txs_commitment: [42u8; 32], + pre_state_root: [99u8; 32].to_vec(), + current_spec: SovSpecId::Fork1, // Compression discount is enabled + pub_key: vec![], + deposit_data: vec![], + l1_fee_rate, + timestamp: 0, + }; + + evm.begin_soft_confirmation_hook(&soft_confirmation_info, &mut working_set); + { + let sender_address = generate_address::("sender"); + let context = C::new(sender_address, 3, SovSpecId::Fork1, l1_fee_rate); + let simple_tx = dev_signer + .sign_default_transaction_with_priority_fee( + TxKind::Call(Address::random()), + vec![], + 1, + 1000, + 20000000, + 1, + ) + .unwrap(); + evm.call( + CallMessage { + txs: vec![simple_tx], + }, + &context, + &mut working_set, + ) + .unwrap(); + } + evm.end_soft_confirmation_hook(&soft_confirmation_info, &mut working_set); + evm.finalize_hook(&[98u8; 32].into(), &mut working_set.accessory_state()); + + let db_account = evm + .accounts + .get(&dev_signer.address(), &mut working_set) + .unwrap(); + let base_fee_vault = evm.accounts.get(&BASE_FEE_VAULT, &mut working_set).unwrap(); + let l1_fee_vault = evm.accounts.get(&L1_FEE_VAULT, &mut working_set).unwrap(); + + let coinbase_account = evm + .accounts + .get(&config.coinbase, &mut working_set) + .unwrap(); + + // gas fee remains the same + let tx2_diff_size = 46; + + expected_db_balance -= + U256::from(gas_fee_paid * 10000001 + 1000 + tx2_diff_size + L1_FEE_OVERHEAD as u64); + expected_base_fee_vault_balance += U256::from(gas_fee_paid * 10000000); + expected_coinbase_balance += U256::from(gas_fee_paid); + expected_l1_fee_vault_balance += U256::from(tx2_diff_size + L1_FEE_OVERHEAD as u64); + + assert_eq!(db_account.balance, expected_db_balance); + assert_eq!(base_fee_vault.balance, expected_base_fee_vault_balance); + assert_eq!(coinbase_account.balance, expected_coinbase_balance); + assert_eq!(l1_fee_vault.balance, expected_l1_fee_vault_balance); + + // assert comression discount + assert_eq!( + tx1_diff_size * BROTLI_COMPRESSION_PERCENTAGE as u64 / 100, + tx2_diff_size + ); + assert_eq!( evm.receipts .iter(&mut working_set.accessory_state()) .map(|r| r.l1_diff_size) .collect::>(), - [53, 94, 154, 94, tx1_diff_size] + [255, 561, 1019, 561, tx1_diff_size, tx2_diff_size] ); } From 443b7edea71b8a8d3e5385fe8a4032b74ffcf1ad Mon Sep 17 00:00:00 2001 From: yaziciahmet Date: Sat, 21 Dec 2024 20:20:23 +0100 Subject: [PATCH 96/96] Lint --- bin/citrea/src/rollup/bitcoin.rs | 2 +- bin/citrea/src/rollup/mod.rs | 14 ++++++++++++-- crates/prover-services/src/parallel/mod.rs | 4 +--- 3 files changed, 14 insertions(+), 6 deletions(-) diff --git a/bin/citrea/src/rollup/bitcoin.rs b/bin/citrea/src/rollup/bitcoin.rs index c044a67d2..6a6c4232c 100644 --- a/bin/citrea/src/rollup/bitcoin.rs +++ b/bin/citrea/src/rollup/bitcoin.rs @@ -25,8 +25,8 @@ use sov_rollup_interface::da::DaVerifier; use sov_rollup_interface::services::da::SenderWithNotifier; use sov_state::ProverStorage; use sov_stf_runner::ProverGuestRunConfig; -use tokio::sync::mpsc::unbounded_channel; use tokio::sync::broadcast; +use tokio::sync::mpsc::unbounded_channel; use tracing::instrument; use crate::guests::{ diff --git a/bin/citrea/src/rollup/mod.rs b/bin/citrea/src/rollup/mod.rs index 1da12d8be..8e36c8f91 100644 --- a/bin/citrea/src/rollup/mod.rs +++ b/bin/citrea/src/rollup/mod.rs @@ -324,7 +324,12 @@ pub trait CitreaRollupBlueprint: RollupBlueprint { let ledger_db = self.create_ledger_db(&rocksdb_config); let prover_service = self - .create_prover_service(prover_config.proving_mode, &da_service, ledger_db.clone(), prover_config.proof_sampling_number) + .create_prover_service( + prover_config.proving_mode, + &da_service, + ledger_db.clone(), + prover_config.proof_sampling_number, + ) .await; // TODO: Double check what kind of storage needed here. @@ -446,7 +451,12 @@ pub trait CitreaRollupBlueprint: RollupBlueprint { let ledger_db = self.create_ledger_db(&rocksdb_config); let prover_service = self - .create_prover_service(prover_config.proving_mode, &da_service, ledger_db.clone(), prover_config.proof_sampling_number) + .create_prover_service( + prover_config.proving_mode, + &da_service, + ledger_db.clone(), + prover_config.proof_sampling_number, + ) .await; // TODO: Double check what kind of storage needed here. diff --git a/crates/prover-services/src/parallel/mod.rs b/crates/prover-services/src/parallel/mod.rs index 5d1c89265..30eae50b8 100644 --- a/crates/prover-services/src/parallel/mod.rs +++ b/crates/prover-services/src/parallel/mod.rs @@ -239,9 +239,7 @@ where { match proof_mode { ProofGenMode::Skip => Ok(Vec::default()), - ProofGenMode::Execute => { - vm.run(elf, false) - } + ProofGenMode::Execute => vm.run(elf, false), ProofGenMode::ProveWithSampling => { // `make_proof` is called with a probability in this case. // When it's called, we have to produce a real proof.