diff --git a/.github/workflows/run-benchmark-natively.yml b/.github/workflows/run-benchmark-natively.yml new file mode 100644 index 000000000..8a5e3562e --- /dev/null +++ b/.github/workflows/run-benchmark-natively.yml @@ -0,0 +1,12 @@ +name: Run benchmark natively + +on: + workflow_dispatch: + +jobs: + benchmark: + name: Benchmark RISCV kernel natively + uses: ./.github/workflows/run-benchmark-job.yml + with: + run-natively: true + job-name: "Benchmark RISCV kernel natively" diff --git a/.github/workflows/run-benchmark.yml b/.github/workflows/run-benchmark.yml new file mode 100644 index 000000000..aaf7c4e6f --- /dev/null +++ b/.github/workflows/run-benchmark.yml @@ -0,0 +1,17 @@ +name: Run benchmark + +on: + workflow_dispatch: + +jobs: + build_riscv_kernel: + name: Build RISCV kernel + uses: ./.github/workflows/build-riscv-kernel.yml + + benchmark: + name: Benchmark RISCV kernel + needs: [build_riscv_kernel] + uses: ./.github/workflows/run-benchmark-job.yml + with: + run-natively: false + job-name: "Benchmark RISCV kernel" diff --git a/Cargo.lock b/Cargo.lock index 90c3b9a1c..49cdfb569 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3507,6 +3507,7 @@ dependencies = [ "rust-embed", "serde", "serde_json", + "sha2 0.10.9", "tempfile", "tezos-smart-rollup", "tezos-smart-rollup-installer", diff --git a/crates/jstzd/Cargo.toml b/crates/jstzd/Cargo.toml index e65657b22..09ee65f65 100644 --- a/crates/jstzd/Cargo.toml +++ b/crates/jstzd/Cargo.toml @@ -16,6 +16,7 @@ clap.workspace = true console.workspace = true futures.workspace = true futures-util.workspace = true +hex.workspace = true http.workspace = true indicatif.workspace = true jstz_crypto = { path = "../jstz_crypto" } @@ -38,6 +39,7 @@ anyhow.workspace = true bincode.workspace = true hex.workspace = true serde_json.workspace = true +sha2 = "0.10" tempfile.workspace = true tezos_crypto_rs.workspace = true tezos-smart-rollup.workspace = true diff --git a/crates/jstzd/build.rs b/crates/jstzd/build.rs index 38a4c1c8f..e813852d0 100644 --- a/crates/jstzd/build.rs +++ b/crates/jstzd/build.rs @@ -22,6 +22,9 @@ include!("build_config.rs"); /// The jstz kernel path used to generate the rollup installer / preimages. /// generated by running `make build build-jstzd-kernel` const JSTZ_KERNEL_PATH: &str = "./resources/jstz_rollup/jstz_kernel.wasm"; +/// The RISC-V kernel executable path for origination +const JSTZ_RISCV_KERNEL_PATH: &str = + "./resources/jstz_rollup/lightweight-kernel-executable"; const JSTZ_PARAMETERS_TY_PATH: &str = "./resources/jstz_rollup/parameters_ty.json"; /// Generated file that contains path getter functions const JSTZ_ROLLUP_PATH: &str = "jstz_rollup_path.rs"; @@ -38,16 +41,19 @@ const ROLLUP_OPERATOR_BOOTSTRAP_ACCOUNT_ALIAS: &str = "rollup_operator"; /// - parameters_ty.json: JSON file containing parameter types /// /// Files generated: -/// - kernel_installer.hex: Hex-encoded kernel installer binary -/// - preimages/: Directory containing kernel preimages +/// - kernel_installer.hex: Hex-encoded kernel installer binary (for WASM bootstrap - legacy) +/// - preimages/: Directory containing kernel preimages (for WASM bootstrap - legacy) /// - jstz_rollup_path.rs: Generated Rust code with path getters /// /// The generated jstz_rollup_path.rs provides the following functions: -/// - kernel_installer_path(): Path to the kernel installer hex file +/// - kernel_installer_path(): Path to the kernel installer hex file (legacy) /// - parameters_ty_path(): Path to the parameters type JSON file -/// - preimages_path(): Path to the preimages directory +/// - preimages_path(): Path to the preimages directory (legacy) +/// - riscv_kernel_path(): Path to the RISC-V kernel executable +/// - riscv_kernel_checksum(): SHA256 checksum of the RISC-V kernel fn main() { println!("cargo:rerun-if-changed={JSTZ_KERNEL_PATH}"); + println!("cargo:rerun-if-changed={JSTZ_RISCV_KERNEL_PATH}"); println!("cargo:rerun-if-changed={JSTZ_PARAMETERS_TY_PATH}"); println!("cargo:rerun-if-changed={BOOTSTRAP_ACCOUNT_PATH}"); @@ -60,7 +66,7 @@ fn main() { // 2. Validate built-in bootstrap accounts stored in the resource file let bootstrap_accounts = validate_builtin_bootstrap_accounts(); - // 3. Create preimages directory and the kernel installer in OUT_DIR + // 3. Create preimages directory and the kernel installer in OUT_DIR (legacy WASM support) let preimages_dir = out_dir.join("preimages"); fs::create_dir_all(&preimages_dir).expect("Failed to create preimages directory"); let injector_pk = bootstrap_accounts @@ -74,12 +80,16 @@ fn main() { ) .expect("Failed to make kernel installer"); - // 4. Save hex-encoded kernel installer to OUT_DIR + // 4. Save hex-encoded kernel installer to OUT_DIR (legacy WASM support) fs::write(out_dir.join("kernel_installer.hex"), kernel_installer) .expect("Failed to write kernel_installer.hex"); - // 5. Generate path getter code in OUT_DIR - generate_code(&out_dir); + // 5. Compute RISC-V kernel checksum + let riscv_kernel_checksum = compute_sha256(Path::new(JSTZ_RISCV_KERNEL_PATH)) + .expect("Failed to compute RISC-V kernel checksum"); + + // 6. Generate path getter code in OUT_DIR + generate_code(&out_dir, &riscv_kernel_checksum); println!( "cargo:warning=Build script output directory: {}", @@ -168,10 +178,12 @@ fn make_kernel_installer( /// Generates Rust code for path getters to access files in OUT_DIR /// /// Generates the following functions: -/// - kernel_installer_path(): Path to the kernel installer hex file +/// - kernel_installer_path(): Path to the kernel installer hex file (legacy) /// - parameters_ty_path(): Path to the parameters type JSON file -/// - preimages_path(): Path to the preimages directory -fn generate_code(out_dir: &Path) { +/// - preimages_path(): Path to the preimages directory (legacy) +/// - riscv_kernel_path(): Path to the RISC-V kernel executable +/// - riscv_kernel_checksum(): SHA256 checksum of the RISC-V kernel +fn generate_code(out_dir: &Path, riscv_kernel_checksum: &str) { let mut code = String::new(); code.push_str(&generate_path_getter_code( out_dir, @@ -189,6 +201,29 @@ fn generate_code(out_dir: &Path) { "preimages", )); + // Generate RISC-V kernel path getter + let manifest_dir = env::var("CARGO_MANIFEST_DIR").unwrap(); + let riscv_kernel_absolute_path = PathBuf::from(&manifest_dir) + .join(JSTZ_RISCV_KERNEL_PATH) + .canonicalize() + .expect("Failed to canonicalize RISC-V kernel path"); + + code.push_str(&format!( + r#" + const RISCV_KERNEL_PATH: &str = "{}"; + pub fn riscv_kernel_path() -> std::path::PathBuf {{ + std::path::PathBuf::from(RISCV_KERNEL_PATH) + }} + + const RISCV_KERNEL_CHECKSUM: &str = "{}"; + pub fn riscv_kernel_checksum() -> &'static str {{ + RISCV_KERNEL_CHECKSUM + }} + "#, + riscv_kernel_absolute_path.display(), + riscv_kernel_checksum + )); + fs::write(out_dir.join(JSTZ_ROLLUP_PATH), code).expect("Failed to write paths.rs"); } @@ -228,6 +263,23 @@ fn generate_path_getter_code(out_dir: &Path, fn_name: &str, path_suffix: &str) - ) } +/// Computes SHA256 checksum of a file +fn compute_sha256(path: &Path) -> Result { + use sha2::{Digest, Sha256}; + + if !path.exists() { + return Err(anyhow::anyhow!( + "RISC-V kernel file not found: {}", + path.display() + )); + } + + let content = fs::read(path)?; + let mut hasher = Sha256::new(); + hasher.update(&content); + Ok(format!("{:x}", hasher.finalize())) +} + fn validate_builtin_bootstrap_accounts() -> HashMap { let bytes = fs::read(BOOTSTRAP_ACCOUNT_PATH).expect("failed to read bootstrap account file"); diff --git a/crates/jstzd/resources/jstz_rollup/lightweight-kernel-executable b/crates/jstzd/resources/jstz_rollup/lightweight-kernel-executable new file mode 100755 index 000000000..aaf6b67f3 Binary files /dev/null and b/crates/jstzd/resources/jstz_rollup/lightweight-kernel-executable differ diff --git a/crates/jstzd/resources/jstz_rollup/lightweight-kernel-executable.elf b/crates/jstzd/resources/jstz_rollup/lightweight-kernel-executable.elf new file mode 100755 index 000000000..aaf6b67f3 Binary files /dev/null and b/crates/jstzd/resources/jstz_rollup/lightweight-kernel-executable.elf differ diff --git a/crates/jstzd/src/config.rs b/crates/jstzd/src/config.rs index 0aed02508..558066d51 100644 --- a/crates/jstzd/src/config.rs +++ b/crates/jstzd/src/config.rs @@ -163,11 +163,14 @@ pub async fn build_config(mut config: Config) -> Result<(u16, JstzdConfig)> { rollup_builder.set_operator(ROLLUP_OPERATOR_ACCOUNT_ALIAS.to_string()); } if !rollup_builder.has_boot_sector_file() { - rollup_builder = rollup_builder - .set_boot_sector_file(jstz_rollup_path::kernel_installer_path()); + // Set a dummy path to satisfy the builder - won't be used for RISC-V rollups + // since we pass None when spawning (kernel comes from origination) + rollup_builder = + rollup_builder.set_boot_sector_file(jstz_rollup_path::riscv_kernel_path()); } let octez_rollup_config = rollup_builder + .set_pvm_kind(SmartRollupPvmKind::Riscv) .set_data_dir(RollupDataDir::TempWithPreImages { preimages_dir: jstz_rollup_path::preimages_path(), }) @@ -396,11 +399,21 @@ async fn build_protocol_params( accounts.push(account); } + let kernel_path = jstz_rollup_path::riscv_kernel_path(); + let kernel_checksum = jstz_rollup_path::riscv_kernel_checksum(); + + // Format: kernel:: + let kernel = format!("kernel:{}:{}", kernel_path.display(), kernel_checksum); + println!("kernel: {}", kernel); + + // No longer bootstrap the rollup - it will be originated instead builder .set_bootstrap_smart_rollups([BootstrapSmartRollup::new( JSTZ_ROLLUP_ADDRESS, - SmartRollupPvmKind::Wasm, - &tokio::fs::read_to_string(jstz_rollup_path::kernel_installer_path()).await?, + SmartRollupPvmKind::Riscv, + &hex::encode(&kernel), + //hex::encode(&tokio::fs::read(jstz_rollup_path::riscv_kernel_path()).await?) + // .as_str(), serde_json::from_slice( &BootstrapRollupFile::get("parameters_ty.json") .ok_or(anyhow::anyhow!("file not found"))? diff --git a/crates/jstzd/src/task/jstzd.rs b/crates/jstzd/src/task/jstzd.rs index 3e830b9a8..e7b4b8a16 100644 --- a/crates/jstzd/src/task/jstzd.rs +++ b/crates/jstzd/src/task/jstzd.rs @@ -144,7 +144,7 @@ impl JstzdConfig { impl Task for Jstzd { type Config = JstzdConfig; - async fn spawn(config: Self::Config) -> Result { + async fn spawn(mut config: Self::Config) -> Result { let octez_node = OctezNode::spawn(config.octez_node_config.clone()).await?; let octez_client = OctezClient::new(config.octez_client_config.clone()); Self::wait_for_node(&octez_node).await?; @@ -162,9 +162,30 @@ impl Task for Jstzd { .await?; Self::activate_protocol(&octez_client, &config.protocol_params).await?; let baker = OctezBaker::spawn(config.baker_config.clone()).await?; - Self::wait_for_block_level(&config.octez_node_config.rpc_endpoint, 3).await?; + //Self::wait_for_block_level(&config.octez_node_config.rpc_endpoint, 3).await?; + + // Originate the RISC-V rollup and update the config with the new address + /*let rollup_address = Self::originate_rollup(&octez_client).await?; + config.octez_rollup_config = + config.octez_rollup_config.with_address(rollup_address);*/ + + // Wait a couple blocks for the origination to be included + println!("\nā³ Waiting for rollup origination to be included..."); + Self::wait_for_block_level(&config.octez_node_config.rpc_endpoint, 5).await?; + println!(" āœ… Rollup origination included!"); + + println!( + "\nšŸ”§ Starting rollup node (connecting to {})...", + config.octez_node_config.rpc_endpoint + ); let rollup = OctezRollup::spawn(config.octez_rollup_config.clone()).await?; + Self::wait_for_rollup(&rollup).await?; + // Give the rollup node a moment to start, but don't wait for full health check + // It will catch up and sync in the background + println!(" ā³ Waiting for rollup node to start..."); + sleep(Duration::from_secs(5)).await; + println!(" āœ… Rollup node started (will sync in background)!"); let jstz_node = match config.jstz_node_config { Some(config) => Some(JstzNode::spawn(config.clone()).await?.into_shared()), None => None, @@ -291,14 +312,56 @@ impl Jstzd { .await } + /// Originate the RISC-V smart rollup + /// + /// This function originates a RISC-V kernel using the octez client. + /// The kernel path format is: kernel:: + /// + /// The kernel path and checksum are computed at build time from the + /// lightweight-kernel-executable in resources/jstz_rollup/ + async fn originate_rollup( + octez_client: &OctezClient, + ) -> Result { + use crate::jstz_rollup_path; + + let kernel_path = jstz_rollup_path::riscv_kernel_path(); + let kernel_checksum = jstz_rollup_path::riscv_kernel_checksum(); + + // Format: kernel:: + let kernel = format!("kernel:{}:{}", kernel_path.display(), kernel_checksum); + + println!("Originating RISC-V smart rollup..."); + println!(" Kernel path: {}", kernel_path.display()); + println!(" Kernel checksum: {}", kernel_checksum); + + let rollup_address = octez_client + .originate_smart_rollup( + "jstz_rollup", + ROLLUP_OPERATOR_ACCOUNT_ALIAS, + "riscv", + "string", + &kernel, + Some(999999.0), + ) + .await?; + + println!("Smart rollup originated with address: {}", rollup_address); + Ok(rollup_address) + } + async fn wait_for_node(octez_node: &OctezNode) -> Result<()> { - let ready = retry(10, 1000, || async { - Ok(octez_node.health_check().await.unwrap_or(false)) + let ready = retry(30, 1000, || async { + let health = octez_node.health_check().await.unwrap_or(false); + if !health { + print!("."); + stdout().flush().ok(); + } + Ok(health) }) .await; if !ready { return Err(anyhow::anyhow!( - "octez node is still not ready after retries" + "octez node is still not ready after 30 retries" )); } Ok(()) @@ -306,7 +369,7 @@ impl Jstzd { /// Wait for the baker to bake at least `level` blocks. async fn wait_for_block_level(node_endpoint: &Endpoint, level: i64) -> Result<()> { - let ready = retry(10, 1000, || async { + let ready = retry(100, 1000, || async { get_block_level(&node_endpoint.to_string()) .await .map(|l| l >= level) @@ -319,13 +382,22 @@ impl Jstzd { } async fn wait_for_rollup(rollup: &OctezRollup) -> Result<()> { - let ready = retry(20, 1000, || async { - Ok(rollup.health_check().await.unwrap_or(false)) + println!( + " Waiting for rollup node to become ready (this may take a minute)..." + ); + let ready = retry(60, 2000, || async { + let health = rollup.health_check().await.unwrap_or(false); + if !health { + print!("."); + stdout().flush().ok(); + } + Ok(health) }) .await; + println!(); // newline after dots if !ready { return Err(anyhow::anyhow!( - "rollup node is still not ready after retries" + "rollup node is still not ready after 60 retries (2 minutes). Check the rollup log file for details." )); } Ok(()) @@ -469,6 +541,8 @@ impl JstzdServer { // 60 seconds for _ in 0..120 { let (overall_result, individual_results) = jstzd.health_check_inner().await; + println!("overall_result: {:?}", overall_result); + println!("individual_results: {:?}", individual_results); jstzd_healthy = overall_result.unwrap_or_default(); let latest_progress = collect_progress(individual_results); update_progress_bar(progress_bar.as_ref(), latest_progress); diff --git a/crates/jstzd/tests/sandbox-params.json b/crates/jstzd/tests/sandbox-params.json index b8852e8b1..f4a254b71 100644 --- a/crates/jstzd/tests/sandbox-params.json +++ b/crates/jstzd/tests/sandbox-params.json @@ -88,7 +88,9 @@ "consensus_rights_delay": 2, "blocks_preservation_cycles": 1, "delegate_parameters_activation_delay": 2, - "tolerated_inactivity_period": 2, + "tolerated_inactivity_period_high": 12, + "tolerated_inactivity_period_low": 1, + "tolerated_inactivity_period_threshold": 10, "blocks_per_cycle": 8, "blocks_per_commitment": 4, "nonce_revelation_threshold": 4, @@ -163,7 +165,7 @@ "dal_attested_slots_validity_lag": 241920 }, "smart_rollup_private_enable": true, - "smart_rollup_riscv_pvm_enable": false, + "smart_rollup_riscv_pvm_enable": true, "zk_rollup_enable": false, "zk_rollup_origination_size": 4000, "zk_rollup_min_pending_to_process": 10, diff --git a/crates/octez/resources/protocol_parameters/sandbox/ProtoALphaALphaALphaALphaALphaALphaALphaALphaDdp3zK b/crates/octez/resources/protocol_parameters/sandbox/ProtoALphaALphaALphaALphaALphaALphaALphaALphaDdp3zK index a2b59507f..d3cacc83f 100644 --- a/crates/octez/resources/protocol_parameters/sandbox/ProtoALphaALphaALphaALphaALphaALphaALphaALphaDdp3zK +++ b/crates/octez/resources/protocol_parameters/sandbox/ProtoALphaALphaALphaALphaALphaALphaALphaALphaDdp3zK @@ -1,18 +1,20 @@ { - "consensus_rights_delay": 2, + "consensus_rights_delay": 1, "blocks_preservation_cycles": 1, - "delegate_parameters_activation_delay": 3, - "tolerated_inactivity_period": 2, - "blocks_per_cycle": 900, + "delegate_parameters_activation_delay": 2, + "tolerated_inactivity_period_high": 12, + "tolerated_inactivity_period_low": 1, + "tolerated_inactivity_period_threshold": 10, + "blocks_per_cycle": 8, "blocks_per_commitment": 4, "nonce_revelation_threshold": 4, - "cycles_per_voting_period": 1, + "cycles_per_voting_period": 8, "hard_gas_limit_per_operation": "1040000", - "hard_gas_limit_per_block": "1386666", - "proof_of_work_threshold": "-1", + "hard_gas_limit_per_block": "1040000", + "proof_of_work_threshold": "4611686018427387903", "minimal_stake": "6000000000", "minimal_frozen_stake": "600000000", - "vdf_difficulty": "10000000", + "vdf_difficulty": "50000", "origination_size": 257, "issuance_weights": { "base_total_issued_per_minute": "85007812", @@ -29,17 +31,17 @@ "quorum_max": 7000, "min_proposal_quorum": 500, "liquidity_baking_subsidy": "5000000", - "liquidity_baking_toggle_ema_threshold": 100000, - "max_operations_time_to_live": 60, + "liquidity_baking_toggle_ema_threshold": 1000000000, + "max_operations_time_to_live": 8, "minimal_block_delay": "1", "delay_increment_per_round": "1", - "consensus_committee_size": 7000, - "consensus_threshold_size": 4667, + "consensus_committee_size": 256, + "consensus_threshold_size": 0, "minimal_participation_ratio": { "numerator": 2, "denominator": 3 }, - "limit_of_delegation_over_baking": 9, + "limit_of_delegation_over_baking": 19, "percentage_of_frozen_deposits_slashed_per_double_baking": 500, "max_slashing_per_block": 10000, "max_slashing_threshold": { @@ -48,37 +50,37 @@ }, "testnet_dictator": "tz1Xf8zdT3DbAX9cHw3c3CXh79rc4nK4gCe8", "cache_script_size": 100000000, - "cache_stake_distribution_cycles": 5, - "cache_sampler_state_cycles": 5, + "cache_stake_distribution_cycles": 4, + "cache_sampler_state_cycles": 4, "dal_parametric": { "feature_enable": true, "incentives_enable": true, - "number_of_slots": 32, + "number_of_slots": 16, "attestation_lag": 8, "attestation_threshold": 66, "minimal_participation_ratio": { - "numerator": "16", - "denominator": "25" + "numerator": "64", + "denominator": "100" }, "rewards_ratio": { "numerator": "1", "denominator": "10" }, "traps_fraction": { - "numerator": "1", - "denominator": "2000" + "numerator": "5", + "denominator": "10000" }, "redundancy_factor": 8, "page_size": 3967, "slot_size": 126944, - "number_of_shards": 512 + "number_of_shards": 256 }, "smart_rollup_arith_pvm_enable": true, "smart_rollup_origination_size": 6314, "smart_rollup_challenge_window_in_blocks": 16, - "smart_rollup_stake_amount": "32000000", + "smart_rollup_stake_amount": "10000000000", "smart_rollup_commitment_period_in_blocks": 8, - "smart_rollup_max_lookahead_in_blocks": 46875, + "smart_rollup_max_lookahead_in_blocks": 2592000, "smart_rollup_max_active_outbox_levels": 31500, "smart_rollup_max_outbox_messages_per_level": 100, "smart_rollup_number_of_sections_in_dissection": 32, @@ -96,7 +98,7 @@ }, "smart_rollup_private_enable": true, "smart_rollup_riscv_pvm_enable": true, - "zk_rollup_enable": true, + "zk_rollup_enable": false, "zk_rollup_origination_size": 4000, "zk_rollup_min_pending_to_process": 10, "zk_rollup_max_ticket_payload_size": 2048, @@ -136,7 +138,7 @@ } }, "direct_ticket_spending_enable": false, - "aggregate_attestation": false, - "allow_tz4_delegate_enable": false, + "aggregate_attestation": true, + "allow_tz4_delegate_enable": true, "all_bakers_attest_activation_level": 1 } diff --git a/crates/octez/src/async/client.rs b/crates/octez/src/async/client.rs index 3bb17d018..8390ca53a 100644 --- a/crates/octez/src/async/client.rs +++ b/crates/octez/src/async/client.rs @@ -628,6 +628,65 @@ impl OctezClient { let output = self.spawn_and_wait_command(args).await?; Ok((parse_block_hash(&output)?, parse_operation_hash(&output)?)) } + + /// Originate a smart rollup + /// + /// # Arguments + /// * `name` - Alias for the rollup + /// * `src` - Source account that will pay for the origination + /// * `kind` - PVM kind (e.g., "wasm_2_0_0", "riscv") + /// * `r#type` - Parameter type (e.g., "string", "unit") + /// * `kernel` - Kernel to use. Format: "kernel::" for RISC-V or hex string for WASM + /// * `burn_cap` - Optional burn cap (defaults to 999) + /// + /// # Returns + /// The smart rollup address (sr1...) + pub async fn originate_smart_rollup( + &self, + name: &str, + src: &str, + kind: &str, + r#type: &str, + kernel: &str, + burn_cap: Option, + ) -> Result { + let burn_cap_str = burn_cap.map(|v| v.to_string()).unwrap_or("999".to_string()); + + // Resolve the source alias to its actual address for the whitelist + let src_address = self.show_address(src, false).await?; + let whitelist = format!("[\"{}\"]", src_address.hash); + + let args = vec![ + "originate", + "smart", + "rollup", + name, + "from", + src, + "of", + "kind", + kind, + "of", + "type", + r#type, + "with", + "kernel", + kernel, + "--burn-cap", + &burn_cap_str, + "--force", + "--whitelist", + &whitelist, + ]; + + let output = self.spawn_and_wait_command(args).await?; + + let operation_hash = parse_operation_hash(&output)?; + // Wait for the operation to be included + self.wait_for(&operation_hash, None, None).await?; + + parse_rollup_address(&output) + } } fn parse_regex(pattern_str: &str, output: &str) -> Result { @@ -663,6 +722,11 @@ fn parse_block_hash(output: &str) -> Result { Ok(BlockHash::from_base58_check(&raw_block_hash)?) } +fn parse_rollup_address(output: &str) -> Result { + let raw_rollup_hash = parse_regex("Address: (sr1[1-9A-HJ-NP-Za-km-z]{33})", output)?; + Ok(SmartRollupHash::from_base58_check(&raw_rollup_hash)?) +} + #[cfg(test)] mod test { use crate::r#async::node_config::OctezNodeConfigBuilder; diff --git a/crates/octez/src/async/rollup.rs b/crates/octez/src/async/rollup.rs index 7e905d756..a2498026a 100644 --- a/crates/octez/src/async/rollup.rs +++ b/crates/octez/src/async/rollup.rs @@ -167,6 +167,11 @@ impl OctezRollupConfigBuilder { self } + pub fn set_pvm_kind(mut self, pvm_kind: SmartRollupPvmKind) -> Self { + self.pvm_kind = Some(pvm_kind); + self + } + // Getter methods to check if fields are set pub fn has_octez_client_base_dir(&self) -> bool { self.octez_client_base_dir.is_some() @@ -199,7 +204,7 @@ impl OctezRollupConfigBuilder { octez_node_endpoint: self .octez_node_endpoint .ok_or_else(|| anyhow::anyhow!("octez_node_endpoint is required"))?, - pvm_kind: self.pvm_kind.unwrap_or(SmartRollupPvmKind::Wasm), + pvm_kind: self.pvm_kind.clone().unwrap_or(SmartRollupPvmKind::Wasm), data_dir: self.data_dir.unwrap_or(RollupDataDir::Temp), address: self .address @@ -207,9 +212,16 @@ impl OctezRollupConfigBuilder { operator: self .operator .ok_or_else(|| anyhow::anyhow!("operator is required"))?, - boot_sector_file: self - .boot_sector_file - .ok_or_else(|| anyhow::anyhow!("boot_sector_file is required"))?, + boot_sector_file: match self.pvm_kind.unwrap_or(SmartRollupPvmKind::Wasm) { + SmartRollupPvmKind::Wasm => self.boot_sector_file.ok_or_else(|| { + anyhow::anyhow!("boot_sector_file is required for WASM rollups") + })?, + SmartRollupPvmKind::Riscv => self.boot_sector_file.unwrap_or_else(|| { + // For RISC-V rollups, boot sector file is optional since kernel is embedded in origination + // Use a dummy path that won't be used + PathBuf::from("/dev/null") + }), + }, rpc_endpoint: self.rpc_endpoint.unwrap_or_else(|| { let port = unused_port(); let uri = Uri::from_str(&format!("127.0.0.1:{port}")).unwrap(); @@ -260,6 +272,14 @@ impl fmt::Display for HistoryMode { } } +impl OctezRollupConfig { + /// Create a new config with a different rollup address + pub fn with_address(mut self, address: SmartRollupHash) -> Self { + self.address = address; + self + } +} + pub struct OctezRollup { binary_path: PathBuf, /// Path to the directory where the rollup state & kernel preimages are stored @@ -300,8 +320,8 @@ impl OctezRollup { "--base-dir", &self.octez_client_base_dir.to_string_lossy(), ]) - .stdout(Stdio::from(self.log_file.as_file().try_clone()?)) - .stderr(Stdio::from(self.log_file.as_file().try_clone()?)); + .stdout(Stdio::inherit()) + .stderr(Stdio::inherit()); Ok(command) } @@ -344,6 +364,19 @@ impl OctezRollup { &kernel_debug_file.to_string_lossy(), ]); } + + // Print command and log file location for debugging + println!("šŸ”§ Starting octez-smart-rollup-node..."); + println!(" Command: {:?}", command.as_std()); + println!(" Log file: {}", self.log_file.as_ref()); + println!(" Data dir: {}", self.data_dir.to_string_lossy()); + println!( + " RPC endpoint: {}:{}", + self.rpc_endpoint.host(), + self.rpc_endpoint.port() + ); + println!(); + Ok(command.spawn()?) } } diff --git a/flake.lock b/flake.lock index 21a4655d4..13385db34 100644 --- a/flake.lock +++ b/flake.lock @@ -100,17 +100,17 @@ ] }, "locked": { - "lastModified": 1740505579, - "narHash": "sha256-Gf83zujQlUWJVu8UFweDB+NBefCQ6dlOKX5FAs68eQk=", + "lastModified": 1756359221, + "narHash": "sha256-U0lonhSK/7u5SGJYzenr/4Xm6AMY7bcxJ9d+X6/k1+I=", "owner": "tezos", "repo": "tezos", - "rev": "f1704a0580f70c48451cf0beef0a93bf10f536a9", + "rev": "51117ed39f82ab60edd6fe4f6d63094605bb22c7", "type": "gitlab" }, "original": { "owner": "tezos", - "ref": "octez-v22.0-rc1", "repo": "tezos", + "rev": "51117ed39f82ab60edd6fe4f6d63094605bb22c7", "type": "gitlab" } }, @@ -141,11 +141,11 @@ "opam-repository": { "flake": false, "locked": { - "lastModified": 1738066957, - "narHash": "sha256-zUOPhbEsAJprwvanDVDT3DSV1ioUjuGxMVYCYlzfd2E=", + "lastModified": 1755781987, + "narHash": "sha256-W/19uUKf7NdcN5wYvGucT5uKYI7wbutdOqm8q1MKHHk=", "owner": "ocaml", "repo": "opam-repository", - "rev": "aa131f3eda80ed7121debe7582faaf50448bc105", + "rev": "e933f68540530644f7ada1411a300dfe5b6da63d", "type": "github" }, "original": { diff --git a/flake.nix b/flake.nix index 40c4d67e5..e056637a4 100644 --- a/flake.nix +++ b/flake.nix @@ -38,7 +38,7 @@ octezPackages = { inputs.nixpkgs.follows = "nixpkgs"; - url = "gitlab:tezos/tezos/octez-v22.0-rc1"; + url = "gitlab:tezos/tezos/51117ed39f82ab60edd6fe4f6d63094605bb22c7"; inputs.flake-utils.follows = "flake-utils"; inputs.rust-overlay.follows = "rust-overlay"; inputs.opam-nix-integration.follows = "opam-nix-integration"; @@ -72,8 +72,8 @@ patches = (old.patches or []) ++ [ - ./nix/patches/octez/0001-fix-octez-rust-deps-for-nix.patch - ./nix/patches/octez/0002-allow-floats-in-wasm-rollup.patch + # ./nix/patches/octez/0001-fix-octez-rust-deps-for-nix.patch + # ./nix/patches/octez/0002-allow-floats-in-wasm-rollup.patch ]; # Network access for fetching cargo dependencies is disabled in sandboxed @@ -130,8 +130,7 @@ octez-client octez-node octez-smart-rollup-node - octez-smart-rollup-wasm-debugger - octez-baker-PsQuebec + octez-baker-PtSeouLo octez-baker-PsRiotum octez-baker-alpha ''; diff --git a/scripts/debug-simple/1-start-node.sh b/scripts/debug-simple/1-start-node.sh new file mode 100755 index 000000000..df326ea85 --- /dev/null +++ b/scripts/debug-simple/1-start-node.sh @@ -0,0 +1,27 @@ +#!/bin/bash +set -e + +BASE_DIR="/tmp/jstz-debug-$(date +%s)" +mkdir -p "$BASE_DIR/node" "$BASE_DIR/client" + +cat >/tmp/jstz-debug-env.sh </dev/null 2>&1; then + break + fi + sleep 1 +done + +octez-client --base-dir "$CLIENT_DIR" --endpoint http://localhost:18731 \ + import secret key activator unencrypted:edsk31vznjHSSpGExDMHYASz45VZqXN4DPxvsa4hAyY8dHM28cZzp6 --force + +octez-client --base-dir "$CLIENT_DIR" --endpoint http://localhost:18731 \ + import secret key injector unencrypted:edsk3gUfUPyBSfrS9CCgmCiQsTCHGkviBDusMxDJstFtojtc1zcpsh --force + +octez-client --base-dir "$CLIENT_DIR" --endpoint http://localhost:18731 \ + import secret key rollup_operator unencrypted:edsk3D6aGWpSiMMiEfNZ7Jyi52S9AtjvLCutqnCi3qev65WShKLKW4 --force + +#cp /Users/alanmarko/projects/jstz_attempt2/jstz/crates/jstzd/tests/sandbox-params.json "$BASE_DIR/protocol_params.json" + +# Use the same parameter file that jstzd uses by default +cp crates/octez/resources/protocol_parameters/sandbox/ProtoALphaALphaALphaALphaALphaALphaALphaALphaDdp3zK "$BASE_DIR/protocol_params.json" + +# Add bootstrap accounts that jstzd adds (from crates/jstzd/resources/bootstrap_account/accounts.json) +jq '.bootstrap_accounts += [ + ["edpkuSLWfVU1Vq7Jg9FucPyKmma6otcMHac9zG4oU1KMHSTBpJuGQ2", "4000000000000"], + ["edpkuBknW28nW72KG6RoHtYW7p12T6GKc7nAbwYX5m8Wd9sDVC9yav", "4000000000000"], + ["edpktoeTraS2WW9iaceu8hvHJ1sUJFSKavtzrMcp4jwMoJWWBts8AK", "4000000000000"], + ["edpkuumXzkHj1AhFmjEVLRq4z54iU2atLPUKt4fcu7ihqsEBiUT4wK", "4000000000000"], + ["edpktzNbDAUjUk697W7gYg2CRuBQjyPxbEg8dLccYYwKSKvkPvjtV9", "4000000000000"], + ["edpkuTXkJDGcFd5nh6VvMz8phXxU3Bi7h6hqgywNFi1vZTfQNnS1RV", "4000000000000"], + ["edpkuFrRoDSEbJYgxRtLx2ps82UdaYc1WwfS9sE11yhauZt5DgCHbU", "4000000000000"], + ["edpkv8EUUH68jmo3f7Um5PezmfGrRF24gnfLpH3sVNwJnV5bVCxL2n", "4000000000000"] +]' "$BASE_DIR/protocol_params.json" >"$BASE_DIR/protocol_params_tmp.json" +mv "$BASE_DIR/protocol_params_tmp.json" "$BASE_DIR/protocol_params.json" + +octez-client --base-dir "$CLIENT_DIR" --endpoint http://localhost:18731 \ + -block genesis activate protocol ProtoALphaALphaALphaALphaALphaALphaALphaALphaDdp3zK \ + with fitness 1 and key activator and parameters "$BASE_DIR/protocol_params.json" + +octez-baker-alpha --base-dir "$CLIENT_DIR" --endpoint http://localhost:18731 \ + run with local node "$NODE_DIR" injector --liquidity-baking-toggle-vote pass --without-dal diff --git a/scripts/debug-simple/3-originate-and-run-rollup.sh b/scripts/debug-simple/3-originate-and-run-rollup.sh new file mode 100755 index 000000000..d8afe8794 --- /dev/null +++ b/scripts/debug-simple/3-originate-and-run-rollup.sh @@ -0,0 +1,47 @@ +#!/bin/bash +set -e + +source /tmp/jstz-debug-env.sh + +OPERATOR_ADDR=$(octez-client --base-dir "$CLIENT_DIR" --endpoint http://localhost:18731 \ + show address rollup_operator | grep Hash: | awk '{print $2}') + +octez-client --base-dir "$CLIENT_DIR" --endpoint http://localhost:18731 \ + transfer 1000000 from injector to rollup_operator --burn-cap 1 2>&1 | grep -v "Warning:" + +for i in {1..30}; do + LEVEL=$(octez-client --base-dir "$CLIENT_DIR" --endpoint http://localhost:18731 \ + rpc get /chains/main/blocks/head/header 2>/dev/null | grep -o '"level":[0-9]*' | cut -d':' -f2) + if [ -n "$LEVEL" ] && [ "$LEVEL" -ge 3 ]; then + break + fi + sleep 1 +done + +ORIGINATION_OUTPUT=$(octez-client --base-dir "$CLIENT_DIR" --endpoint http://localhost:18731 \ + originate smart rollup jstz_rollup from rollup_operator \ + of kind riscv \ + of type string \ + with kernel "kernel:crates/jstzd/resources/jstz_rollup/lightweight-kernel-executable.elf:d9c179173a5b0f014853cabad53f6a0eab92287f85f5c07e32ece8f40c36caff" \ + --burn-cap 999999 \ + --force \ + --whitelist "[\"$OPERATOR_ADDR\"]" 2>&1) + +ROLLUP_ADDR=$(echo "$ORIGINATION_OUTPUT" | grep -o 'sr1[a-zA-Z0-9]*' | head -1) + +echo "export ROLLUP_ADDR=$ROLLUP_ADDR" >>/tmp/jstz-debug-env.sh + +sleep 10 + +mkdir -p "$BASE_DIR/rollup" + +octez-smart-rollup-node \ + --endpoint http://localhost:18731 \ + --base-dir "$CLIENT_DIR" \ + run operator for "$ROLLUP_ADDR" \ + with operators rollup_operator \ + --data-dir "$BASE_DIR/rollup" \ + --rpc-addr 127.0.0.1 \ + --rpc-port 18745 \ + --acl-override allow-all \ + --history-mode full diff --git a/scripts/debug-working/1-start-node.sh b/scripts/debug-working/1-start-node.sh new file mode 100755 index 000000000..dc36a2848 --- /dev/null +++ b/scripts/debug-working/1-start-node.sh @@ -0,0 +1,59 @@ +#!/bin/bash +# Script 1: Start Octez Node +# Run this in Terminal 1 + +set -e + +# Colors for output +GREEN='\033[0;32m' +BLUE='\033[0;34m' +NC='\033[0m' # No Color + +echo -e "${BLUE}=== Starting Octez Node ===${NC}" + +# Setup directories +export BASE_DIR="/tmp/jstz-debug-$(date +%s)" +export NODE_DIR="$BASE_DIR/node" +export CLIENT_DIR="$BASE_DIR/client" + +mkdir -p "$NODE_DIR" +mkdir -p "$CLIENT_DIR" + +echo "Base directory: $BASE_DIR" +echo "Node directory: $NODE_DIR" +echo "Client directory: $CLIENT_DIR" + +# Save directories to file for other scripts +echo "export BASE_DIR=$BASE_DIR" >/tmp/jstz-debug-env.sh +echo "export NODE_DIR=$NODE_DIR" >>/tmp/jstz-debug-env.sh +echo "export CLIENT_DIR=$CLIENT_DIR" >>/tmp/jstz-debug-env.sh +echo "export NODE_RPC=http://localhost:18731" >>/tmp/jstz-debug-env.sh + +echo -e "${GREEN}āœ“ Directories created${NC}" + +# Generate identity +echo -e "\n${BLUE}Generating node identity...${NC}" +octez-node identity generate --data-dir "$NODE_DIR" +echo -e "${GREEN}āœ“ Identity generated${NC}" + +# Initialize config +echo -e "\n${BLUE}Initializing node config...${NC}" +octez-node config init \ + --data-dir "$NODE_DIR" \ + --network sandbox \ + --net-addr "127.0.0.1:19732" \ + --rpc-addr "127.0.0.1:18731" \ + --expected-pow 0 +echo -e "${GREEN}āœ“ Config initialized${NC}" + +# Start the node +echo -e "\n${BLUE}Starting octez node...${NC}" +echo "RPC endpoint: http://localhost:18731" +echo "Logs will appear below:" +echo "" + +octez-node run \ + --data-dir "$NODE_DIR" \ + --network sandbox \ + --synchronisation-threshold 0 \ + --connections 0 diff --git a/scripts/debug-working/2-setup-protocol.sh b/scripts/debug-working/2-setup-protocol.sh new file mode 100755 index 000000000..723082915 --- /dev/null +++ b/scripts/debug-working/2-setup-protocol.sh @@ -0,0 +1,150 @@ +#!/bin/bash +# Script 2: Setup Protocol, Accounts, and Baker +# Run this in Terminal 2 after the node is running + +set -e + +# Colors +GREEN='\033[0;32m' +BLUE='\033[0;34m' +YELLOW='\033[1;33m' +NC='\033[0m' + +echo -e "${BLUE}=== Setting up Protocol and Accounts ===${NC}" + +# Load environment +source /tmp/jstz-debug-env.sh + +# Wait for node to be ready +echo -e "\n${YELLOW}Waiting for node to be ready...${NC}" +for i in {1..30}; do + if curl -s http://localhost:18731/health/ready >/dev/null 2>&1; then + echo -e "${GREEN}āœ“ Node is ready!${NC}" + break + fi + echo -n "." + sleep 1 +done +echo "" + +# Import bootstrap accounts +echo -e "\n${BLUE}Importing bootstrap accounts...${NC}" + +# Activator +octez-client --base-dir "$CLIENT_DIR" --endpoint http://localhost:18731 \ + import secret key activator unencrypted:edsk31vznjHSSpGExDMHYASz45VZqXN4DPxvsa4hAyY8dHM28cZzp6 --force + +# Injector (bootstrap1) +octez-client --base-dir "$CLIENT_DIR" --endpoint http://localhost:18731 \ + import secret key injector unencrypted:edsk3gUfUPyBSfrS9CCgmCiQsTCHGkviBDusMxDJstFtojtc1zcpsh --force + +# Rollup operator +octez-client --base-dir "$CLIENT_DIR" --endpoint http://localhost:18731 \ + import secret key rollup_operator unencrypted:edsk3D6aGWpSiMMiEfNZ7Jyi52S9AtjvLCutqnCi3qev65WShKLKW4 --force + +echo -e "${GREEN}āœ“ Bootstrap accounts imported${NC}" + +# Show addresses +echo -e "\n${BLUE}Account addresses:${NC}" +octez-client --base-dir "$CLIENT_DIR" --endpoint http://localhost:18731 show address activator +octez-client --base-dir "$CLIENT_DIR" --endpoint http://localhost:18731 show address injector +octez-client --base-dir "$CLIENT_DIR" --endpoint http://localhost:18731 show address rollup_operator + +# Activate protocol +echo -e "\n${BLUE}Activating protocol...${NC}" + +# Get protocol parameters - copy from jstzd's sandbox params +PARAMS_FILE="$BASE_DIR/protocol_params.json" +JSTZD_PARAMS="/Users/alanmarko/projects/jstz_attempt2/jstz/crates/jstzd/tests/sandbox-params.json" + +if [ -f "$JSTZD_PARAMS" ]; then + echo "Using parameters from: $JSTZD_PARAMS" + cp "$JSTZD_PARAMS" "$PARAMS_FILE" +else + echo "Warning: Could not find jstzd params, using minimal params" + # Create minimal protocol parameters as fallback + cat >"$PARAMS_FILE" <<'EOF' +{ + "bootstrap_accounts": [ + ["edpkuBknW28nW72KG6RoHtYW7p12T6GKc7nAbwYX5m8Wd9sDVC9yav", "4000000000000"], + ["edpktzNbDAUjUk697W7gYg2CRuBQjyPxbEg8dLccYYwKSKvkPvjtV9", "4000000000000"], + ["edpkuTXkJDGcFd5nh6VvMz8phXxU3Bi7h6hqgywNFi1vZTfQNnS1RV", "4000000000000"], + ["edpktoeTraS2WW9iaceu8hvHJ1sUJFSKavtzrMcp4jwMoJWWBts8AK", "4000000000000"] + ], + "consensus_rights_delay": 2, + "blocks_per_cycle": 8, + "blocks_per_commitment": 4, + "nonce_revelation_threshold": 4, + "cycles_per_voting_period": 8, + "hard_gas_limit_per_operation": "1040000", + "hard_gas_limit_per_block": "5200000", + "proof_of_work_threshold": "-1", + "minimal_stake": "6000000000", + "vdf_difficulty": "50000", + "seed_nonce_revelation_tip": "125000", + "origination_size": 257, + "issuance_weights": { + "base_total_issued_per_minute": "85007812" + }, + "cost_per_byte": "250", + "hard_storage_limit_per_operation": "60000", + "quorum_min": 2000, + "quorum_max": 7000, + "min_proposal_quorum": 500, + "liquidity_baking_toggle_ew_period": 262144, + "max_operations_time_to_live": 120, + "minimal_block_delay": "1", + "delay_increment_per_round": "1", + "consensus_committee_size": 7000, + "consensus_threshold": 4667, + "minimal_participation_ratio": { + "numerator": 2, + "denominator": 3 + }, + "limit_of_delegation_over_baking": 9, + "percentage_of_frozen_deposits_slashed_per_double_baking": 700, + "percentage_of_frozen_deposits_slashed_per_double_attestation": 5000, + "cache_script_size": 100000000, + "cache_stake_distribution_cycles": 8, + "cache_sampler_state_cycles": 8, + "dal_parametric": { + "feature_enable": false, + "number_of_slots": 256, + "attestation_lag": 4, + "attestation_threshold": 50, + "blocks_per_epoch": 1 + }, + "smart_rollup_arith_pvm_enable": false, + "smart_rollup_origination_size": 6314, + "smart_rollup_challenge_window_in_blocks": 20, + "smart_rollup_stake_amount": "10000000000", + "smart_rollup_commitment_period_in_blocks": 10, + "smart_rollup_max_lookahead_in_blocks": 30000, + "smart_rollup_max_active_outbox_levels": 20, + "smart_rollup_max_outbox_messages_per_level": 100, + "smart_rollup_number_of_sections_in_dissection": 32, + "smart_rollup_timeout_period_in_blocks": 20, + "smart_rollup_max_number_of_cemented_commitments": 5, + "smart_rollup_max_number_of_parallel_games": 32, + "smart_rollup_reveal_activation_level": { + "raw_data": { + "Blake2B": 0 + }, + "metadata": 0, + "dal_page": 0, + "dal_parameters": 0, + "dal_attested_slots_validity_lag": 0 + }, + "smart_rollup_private_enable": true, + "smart_rollup_riscv_pvm_enable": true +} +EOF +fi + +octez-client --base-dir "$CLIENT_DIR" --endpoint http://localhost:18731 \ + -block genesis activate protocol ProtoALphaALphaALphaALphaALphaALphaALphaALphaDdp3zK \ + with fitness 1 and key activator and parameters "$PARAMS_FILE" + +echo -e "${GREEN}āœ“ Protocol activated${NC}" + +echo -e "\n${YELLOW}You can now proceed to script 3 to start the baker${NC}" diff --git a/scripts/debug-working/3-start-baker.sh b/scripts/debug-working/3-start-baker.sh new file mode 100755 index 000000000..65d7b0d10 --- /dev/null +++ b/scripts/debug-working/3-start-baker.sh @@ -0,0 +1,24 @@ +#!/bin/bash +# Script 3: Start Baker +# Run this in Terminal 3 after protocol activation + +set -e + +# Colors +GREEN='\033[0;32m' +BLUE='\033[0;34m' +NC='\033[0m' + +echo -e "${BLUE}=== Starting Baker ===${NC}" + +# Load environment +source /tmp/jstz-debug-env.sh + +echo -e "\n${BLUE}Starting baker for injector account...${NC}" +echo "Baker will produce blocks automatically" +echo "Logs will appear below:" +echo "" + +# Start baking (without DAL node) +octez-baker-alpha --base-dir "$CLIENT_DIR" --endpoint http://localhost:18731 \ + run with local node "$NODE_DIR" injector --liquidity-baking-toggle-vote pass --without-dal diff --git a/scripts/debug-working/4-originate-rollup.sh b/scripts/debug-working/4-originate-rollup.sh new file mode 100755 index 000000000..a7f3337f4 --- /dev/null +++ b/scripts/debug-working/4-originate-rollup.sh @@ -0,0 +1,113 @@ +#!/bin/bash +# Script 4: Originate RISC-V Rollup +# Run this in a new terminal after the baker has produced a few blocks + +set -e + +# Colors +GREEN='\033[0;32m' +BLUE='\033[0;34m' +YELLOW='\033[1;33m' +RED='\033[0;31m' +NC='\033[0m' + +echo -e "${BLUE}=== Originating RISC-V Rollup ===${NC}" + +# Load environment +source /tmp/jstz-debug-env.sh + +# Get the RISC-V kernel path and checksum +KERNEL_PATH="/Users/alanmarko/projects/jstz_attempt2/jstz/crates/jstzd/resources/jstz_rollup/lightweight-kernel-executable.elf" + +if [ ! -f "$KERNEL_PATH" ]; then + echo -e "${RED}Error: Kernel not found at $KERNEL_PATH${NC}" + exit 1 +fi + +echo -e "\n${BLUE}Computing kernel checksum...${NC}" +# macOS uses shasum, Linux uses sha256sum +if command -v sha256sum &>/dev/null; then + KERNEL_CHECKSUM=$(sha256sum "$KERNEL_PATH" | awk '{print $1}') +elif command -v shasum &>/dev/null; then + KERNEL_CHECKSUM=$(shasum -a 256 "$KERNEL_PATH" | awk '{print $1}') +else + echo -e "${RED}Error: Neither sha256sum nor shasum found${NC}" + exit 1 +fi +echo "Checksum: $KERNEL_CHECKSUM" + +# Format kernel parameter +KERNEL_PARAM="kernel:${KERNEL_PATH}:${KERNEL_CHECKSUM}" + +echo -e "\n${BLUE}Kernel parameter:${NC}" +echo "$KERNEL_PARAM" + +# Get rollup operator address for whitelist +echo -e "\n${BLUE}Getting rollup operator address...${NC}" +OPERATOR_ADDR=$(octez-client --base-dir "$CLIENT_DIR" --endpoint http://localhost:18731 \ + show address rollup_operator | grep Hash: | awk '{print $2}') +echo "Operator address: $OPERATOR_ADDR" + +# Transfer funds to rollup_operator (it's not a bootstrap account) +echo -e "\n${BLUE}Transferring funds to rollup_operator...${NC}" +octez-client --base-dir "$CLIENT_DIR" --endpoint http://localhost:18731 \ + transfer 1000000 from injector to rollup_operator --burn-cap 1 2>&1 | grep -v "Warning:" +echo -e "${GREEN}āœ“ Funds transferred${NC}" + +# Wait for a few blocks +echo -e "\n${YELLOW}Waiting for block level 3...${NC}" +for i in {1..30}; do + LEVEL=$(octez-client --base-dir "$CLIENT_DIR" --endpoint http://localhost:18731 \ + rpc get /chains/main/blocks/head/header 2>/dev/null | grep -o '"level":[0-9]*' | cut -d':' -f2) + if [ -n "$LEVEL" ] && [ "$LEVEL" -ge 3 ]; then + echo -e "${GREEN}āœ“ At block level $LEVEL${NC}" + break + fi + echo -n "." + sleep 1 +done +echo "" + +# Originate the rollup +echo -e "\n${BLUE}Originating RISC-V smart rollup...${NC}" +echo "This may take a moment..." + +set +e # Don't exit on error so we can see what happened +ORIGINATION_OUTPUT=$(octez-client --base-dir "$CLIENT_DIR" --endpoint http://localhost:18731 \ + originate smart rollup jstz_rollup from rollup_operator \ + of kind riscv \ + of type string \ + with kernel "$KERNEL_PARAM" \ + --burn-cap 999999 \ + --force \ + --whitelist "[\"$OPERATOR_ADDR\"]" 2>&1) +ORIGINATION_EXIT_CODE=$? +set -e + +echo "$ORIGINATION_OUTPUT" + +if [ $ORIGINATION_EXIT_CODE -ne 0 ]; then + echo -e "\n${RED}Error: Origination failed with exit code $ORIGINATION_EXIT_CODE${NC}" + exit 1 +fi + +# Extract rollup address +ROLLUP_ADDR=$(echo "$ORIGINATION_OUTPUT" | grep -o 'sr1[a-zA-Z0-9]*' | head -1) + +if [ -z "$ROLLUP_ADDR" ]; then + echo -e "${RED}Error: Could not extract rollup address${NC}" + echo "Output was:" + echo "$ORIGINATION_OUTPUT" + exit 1 +fi + +echo -e "\n${GREEN}āœ“ Rollup originated successfully!${NC}" +echo -e "${GREEN} Address: $ROLLUP_ADDR${NC}" + +# Save rollup address +echo "export ROLLUP_ADDR=$ROLLUP_ADDR" >>/tmp/jstz-debug-env.sh + +echo -e "\n${YELLOW}Waiting for origination to be included in a block...${NC}" +sleep 10 + +echo -e "\n${GREEN}Ready to start rollup node (script 5)${NC}" diff --git a/scripts/debug-working/5-start-rollup-node.sh b/scripts/debug-working/5-start-rollup-node.sh new file mode 100755 index 000000000..a07001130 --- /dev/null +++ b/scripts/debug-working/5-start-rollup-node.sh @@ -0,0 +1,48 @@ +#!/bin/bash +# Script 5: Start Rollup Node +# Run this in Terminal 4 after originating the rollup + +set -e + +# Colors +GREEN='\033[0;32m' +BLUE='\033[0;34m' +YELLOW='\033[1;33m' +RED='\033[0;31m' +NC='\033[0m' + +echo -e "${BLUE}=== Starting Rollup Node ===${NC}" + +# Load environment +source /tmp/jstz-debug-env.sh + +if [ -z "$ROLLUP_ADDR" ]; then + echo -e "${RED}Error: ROLLUP_ADDR not set. Did you run script 4?${NC}" + exit 1 +fi + +echo "Rollup address: $ROLLUP_ADDR" +echo "Connecting to node: http://localhost:18731" + +# Setup rollup data directory +ROLLUP_DIR="$BASE_DIR/rollup" +mkdir -p "$ROLLUP_DIR" + +echo -e "\n${BLUE}Starting octez-smart-rollup-node...${NC}" +echo "Data directory: $ROLLUP_DIR" +echo "RPC will be available at: http://localhost:18745" +echo "" +echo "Logs will appear below:" +echo "" + +# Start the rollup node +octez-smart-rollup-node \ + --endpoint http://localhost:18731 \ + --base-dir "$CLIENT_DIR" \ + run operator for "$ROLLUP_ADDR" \ + with operators rollup_operator \ + --data-dir "$ROLLUP_DIR" \ + --rpc-addr 127.0.0.1 \ + --rpc-port 18745 \ + --acl-override allow-all \ + --history-mode full diff --git a/scripts/debug-working/README.md b/scripts/debug-working/README.md new file mode 100644 index 000000000..7bc59a2d2 --- /dev/null +++ b/scripts/debug-working/README.md @@ -0,0 +1,198 @@ +# RISC-V Rollup Debug Scripts + +This directory contains shell scripts to manually reproduce what `cargo run --bin jstzd` does, but split into separate components for easier debugging. + +## Prerequisites + +- Octez binaries in PATH: + - `octez-node` + - `octez-client` + - `octez-baker-alpha` + - `octez-smart-rollup-node-alpha` +- The RISC-V kernel at: `crates/jstzd/resources/jstz_rollup/lightweight-kernel-executable` + +## Usage + +Run each script in a separate terminal window in order: + +### Terminal 1: Start Octez Node + +```bash +./scripts/debug/1-start-node.sh +``` + +This will: + +- Create temporary directories +- Generate node identity +- Initialize node config +- Start the octez node +- Keep running (showing node logs) + +**Wait for**: Node to start accepting connections + +### Terminal 2: Setup Protocol + +```bash +./scripts/debug/2-setup-protocol.sh +``` + +This will: + +- Wait for node to be ready +- Import bootstrap accounts (activator, injector, rollup_operator) +- Activate the protocol +- Exit when done + +**Wait for**: Script to complete successfully + +### Terminal 3: Start Baker + +```bash +./scripts/debug/3-start-baker.sh +``` + +This will: + +- Start the baker +- Begin producing blocks automatically +- Keep running (showing baker logs) + +**Wait for**: A few blocks to be produced (check Terminal 1 logs) + +### Terminal 4: Originate Rollup + +```bash +./scripts/debug/4-originate-rollup.sh +``` + +This will: + +- Compute the RISC-V kernel checksum +- Get the operator address for the whitelist +- Wait for block level 3 +- Originate the RISC-V smart rollup +- Save the rollup address +- Exit when done + +**Output**: You'll see the rollup address (sr1...) + +### Terminal 5: Start Rollup Node + +```bash +./scripts/debug/5-start-rollup-node.sh +``` + +This will: + +- Start the octez-smart-rollup-node +- Connect to the L1 node +- Begin syncing +- Keep running (showing rollup node logs) + +**Watch for**: + +- Connection messages +- Block processing +- Any timeout errors + +## Debugging Tips + +### Check Node Health + +```bash +curl http://localhost:18731/health/ready +``` + +### Check Current Block Level + +```bash +source /tmp/jstz-debug-env.sh +octez-client --base-dir "$CLIENT_DIR" --endpoint http://localhost:18731 \ + rpc get /chains/main/blocks/head/header | grep level +``` + +### List Rollups + +```bash +source /tmp/jstz-debug-env.sh +octez-client --base-dir "$CLIENT_DIR" --endpoint http://localhost:18731 \ + list known smart rollups +``` + +### Check Rollup Node Health + +```bash +curl http://localhost:18745/health/ready +``` + +### View Rollup Node Status + +```bash +curl http://localhost:18745/local/batcher/queue +``` + +## Environment Variables + +All scripts save and load environment variables from `/tmp/jstz-debug-env.sh`: + +- `BASE_DIR`: Temporary directory for all data +- `NODE_DIR`: Octez node data directory +- `CLIENT_DIR`: Octez client data directory +- `NODE_RPC`: Node RPC endpoint +- `ROLLUP_ADDR`: Originated rollup address (after script 4) + +## Cleanup + +To clean up after testing: + +```bash +source /tmp/jstz-debug-env.sh +rm -rf "$BASE_DIR" +rm /tmp/jstz-debug-env.sh +``` + +## Common Issues + +### "Kernel not found" error + +Make sure the kernel exists at: + +```bash +ls -lh crates/jstzd/resources/jstz_rollup/lightweight-kernel-executable +``` + +### "Connection timeout" in rollup node + +- Check that the node is still running (Terminal 1) +- Check the node RPC is accessible: `curl http://localhost:18731/health/ready` +- The rollup node may show some timeout warnings initially - this is often normal + +### "Whitelist" JSON error + +The operator address must be a valid tz1 address, not an alias. Script 4 handles this automatically. + +### Baker not producing blocks + +- Make sure the protocol was activated (script 2 completed successfully) +- Check node logs for any errors +- The baker needs the injector account which should have XTZ from the bootstrap + +## What This Replicates + +These scripts replicate the key steps that `jstzd` does: + +1. āœ… Start octez node +2. āœ… Import bootstrap accounts +3. āœ… Activate protocol +4. āœ… Start baker +5. āœ… Originate RISC-V rollup (with proper kernel format) +6. āœ… Start rollup node + +The main differences: + +- No jstz_node (JavaScript execution layer) +- No oracle node +- Simpler protocol parameters +- Manual control over timing +- Easier to see what's happening at each step diff --git a/scripts/debug/1-start-node.sh b/scripts/debug/1-start-node.sh new file mode 100755 index 000000000..9029cbc35 --- /dev/null +++ b/scripts/debug/1-start-node.sh @@ -0,0 +1,60 @@ +#!/bin/bash +# Script 1: Start Octez Node +# This replicates what jstzd does when starting the octez node +# Run this in Terminal 1 + +set -e + +# Colors for output +GREEN='\033[0;32m' +BLUE='\033[0;34m' +NC='\033[0m' # No Color + +echo -e "${BLUE}=== Starting Octez Node (jstzd equivalent) ===${NC}" + +# Setup directories (using temp dir like jstzd does) +export BASE_DIR="/tmp/jstz-debug-$(date +%s)" +export NODE_DIR="$BASE_DIR/octez-node" +export CLIENT_DIR="$BASE_DIR/octez-client" + +mkdir -p "$NODE_DIR" +mkdir -p "$CLIENT_DIR" + +echo "Base directory: $BASE_DIR" +echo "Node directory: $NODE_DIR" +echo "Client directory: $CLIENT_DIR" + +# Save directories to file for other scripts +echo "export BASE_DIR=$BASE_DIR" >/tmp/jstz-debug-env.sh +echo "export NODE_DIR=$NODE_DIR" >>/tmp/jstz-debug-env.sh +echo "export CLIENT_DIR=$CLIENT_DIR" >>/tmp/jstz-debug-env.sh +echo "export NODE_RPC=http://localhost:18731" >>/tmp/jstz-debug-env.sh + +echo -e "${GREEN}āœ“ Directories created${NC}" + +# Generate identity +echo -e "\n${BLUE}Generating node identity...${NC}" +octez-node identity generate --data-dir "$NODE_DIR" +echo -e "${GREEN}āœ“ Identity generated${NC}" + +# Initialize config +echo -e "\n${BLUE}Initializing node config...${NC}" +octez-node config init \ + --data-dir "$NODE_DIR" \ + --network sandbox \ + --net-addr "127.0.0.1:19732" \ + --rpc-addr "127.0.0.1:18731" \ + --expected-pow 0 +echo -e "${GREEN}āœ“ Config initialized${NC}" + +# Start the node +echo -e "\n${BLUE}Starting octez node...${NC}" +echo "RPC endpoint: http://localhost:18731" +echo "Logs will appear below:" +echo "" + +octez-node run \ + --data-dir "$NODE_DIR" \ + --network sandbox \ + --synchronisation-threshold 0 \ + --connections 0 diff --git a/scripts/debug/2-setup-protocol.sh b/scripts/debug/2-setup-protocol.sh new file mode 100755 index 000000000..107bcc518 --- /dev/null +++ b/scripts/debug/2-setup-protocol.sh @@ -0,0 +1,135 @@ +#!/bin/bash +# Script 2: Setup Protocol and Accounts +# This replicates what jstzd does for protocol setup +# Run this in Terminal 2 after the node is running + +set -e + +# Colors +GREEN='\033[0;32m' +BLUE='\033[0;34m' +YELLOW='\033[1;33m' +NC='\033[0m' + +echo -e "${BLUE}=== Setting up Protocol and Accounts (jstzd equivalent) ===${NC}" + +# Load environment +source /tmp/jstz-debug-env.sh + +# Wait for node to be ready (jstzd waits 30 retries Ɨ 1 second) +echo -e "\n${YELLOW}Waiting for node to be ready...${NC}" +for i in {1..30}; do + if curl -s http://localhost:18731/health/ready >/dev/null 2>&1; then + echo -e "${GREEN}āœ“ Node is ready!${NC}" + break + fi + echo -n "." + sleep 1 +done +echo "" + +# Import ALL 8 bootstrap accounts that jstzd uses +# These are from crates/jstzd/resources/bootstrap_account/accounts.json +echo -e "\n${BLUE}Importing 8 bootstrap accounts (jstzd uses all of these)...${NC}" + +# Activator (1 mutez) +octez-client --base-dir "$CLIENT_DIR" --endpoint http://localhost:18731 \ + import secret key activator unencrypted:edsk31vznjHSSpGExDMHYASz45VZqXN4DPxvsa4hAyY8dHM28cZzp6 --force + +# Injector (100,000,000,000 mutez) +octez-client --base-dir "$CLIENT_DIR" --endpoint http://localhost:18731 \ + import secret key injector unencrypted:edsk3gUfUPyBSfrS9CCgmCiQsTCHGkviBDusMxDJstFtojtc1zcpsh --force + +# Rollup operator (100,000,000,000 mutez) - THIS IS A BOOTSTRAP ACCOUNT IN JSTZD! +octez-client --base-dir "$CLIENT_DIR" --endpoint http://localhost:18731 \ + import secret key rollup_operator unencrypted:edsk3D6aGWpSiMMiEfNZ7Jyi52S9AtjvLCutqnCi3qev65WShKLKW4 --force + +# Bootstrap1 (100,000,000,000 mutez) +octez-client --base-dir "$CLIENT_DIR" --endpoint http://localhost:18731 \ + import secret key bootstrap1 unencrypted:edsk3Admhyr2GZe5bz7LAx5KEjz6U8U56ouvdsgCuFRf2m6Wakhebz --force + +# Bootstrap2 (100,000,000,000 mutez) +octez-client --base-dir "$CLIENT_DIR" --endpoint http://localhost:18731 \ + import secret key bootstrap2 unencrypted:edsk39qAm1fiMjgmPkw1EgQYkMzkJezLNewd7PLNHTkr6w9XA2zdfo --force + +# Bootstrap3 (100,000,000,000 mutez) +octez-client --base-dir "$CLIENT_DIR" --endpoint http://localhost:18731 \ + import secret key bootstrap3 unencrypted:edsk4ArLQgBTLWG5FJmnGnT689VKoqhXwmDPBuGx3z4cvwU9MmrPZZ --force + +# Bootstrap4 (100,000,000,000 mutez) +octez-client --base-dir "$CLIENT_DIR" --endpoint http://localhost:18731 \ + import secret key bootstrap4 unencrypted:edsk2uqQB9AY4FvioK2YMdfmyMrer5R8mGFyuaLLFfSRo8EoyNdht3 --force + +# Bootstrap5 (100,000,000,000 mutez) +octez-client --base-dir "$CLIENT_DIR" --endpoint http://localhost:18731 \ + import secret key bootstrap5 unencrypted:edsk4QLrcijEffxV31gGdN2HU7UpyJjA8drFoNcmnB28n89YjPNRFm --force + +echo -e "${GREEN}āœ“ All 8 bootstrap accounts imported${NC}" + +# Show addresses +echo -e "\n${BLUE}Account addresses:${NC}" +octez-client --base-dir "$CLIENT_DIR" --endpoint http://localhost:18731 show address activator +octez-client --base-dir "$CLIENT_DIR" --endpoint http://localhost:18731 show address injector +octez-client --base-dir "$CLIENT_DIR" --endpoint http://localhost:18731 show address rollup_operator + +# Activate protocol using octez protocol parameters (not jstzd/tests params!) +echo -e "\n${BLUE}Activating protocol...${NC}" + +# Use the octez sandbox protocol parameters that jstzd uses +PARAMS_FILE="$BASE_DIR/protocol_params.json" +OCTEZ_PARAMS="/Users/alanmarko/projects/jstz_attempt2/jstz/crates/octez/resources/protocol_parameters/sandbox/ProtoALphaALphaALphaALphaALphaALphaALphaALphaDdp3zK" + +if [ -f "$OCTEZ_PARAMS" ]; then + echo "Using octez parameters from: $OCTEZ_PARAMS" + cp "$OCTEZ_PARAMS" "$PARAMS_FILE" + + # Add the bootstrap accounts to the parameters + # jstzd adds these programmatically in config.rs:387-395 + echo -e "\n${BLUE}Adding bootstrap accounts to protocol parameters...${NC}" + + # Use jq to add bootstrap accounts if it's available, otherwise use python + if command -v jq &>/dev/null; then + jq '. + { + "bootstrap_accounts": [ + ["edpkuSLWfVU1Vq7Jg9FucPyKmma6otcMHac9zG4oU1KMHSTBpJuGQ2", "1"], + ["edpkuBknW28nW72KG6RoHtYW7p12T6GKc7nAbwYX5m8Wd9sDVC9yav", "100000000000"], + ["edpktoeTraS2WW9iaceu8hvHJ1sUJFSKavtzrMcp4jwMoJWWBts8AK", "100000000000"], + ["edpkuumXzkHj1AhFmjEVLRq4z54iU2atLPUKt4fcu7ihqsEBiUT4wK", "100000000000"], + ["edpktzNbDAUjUk697W7gYg2CRuBQjyPxbEg8dLccYYwKSKvkPvjtV9", "100000000000"], + ["edpkuTXkJDGcFd5nh6VvMz8phXxU3Bi7h6hqgywNFi1vZTfQNnS1RV", "100000000000"], + ["edpkuFrRoDSEbJYgxRtLx2ps82UdaYc1WwfS9sE11yhauZt5DgCHbU", "100000000000"], + ["edpkv8EUUH68jmo3f7Um5PezmfGrRF24gnfLpH3sVNwJnV5bVCxL2n", "100000000000"] + ] + }' "$PARAMS_FILE" >"$PARAMS_FILE.tmp" && mv "$PARAMS_FILE.tmp" "$PARAMS_FILE" + else + # Fallback to python if jq not available + python3 -c " +import json +with open('$PARAMS_FILE', 'r') as f: + params = json.load(f) +params['bootstrap_accounts'] = [ + ['edpkuSLWfVU1Vq7Jg9FucPyKmma6otcMHac9zG4oU1KMHSTBpJuGQ2', '1'], + ['edpkuBknW28nW72KG6RoHtYW7p12T6GKc7nAbwYX5m8Wd9sDVC9yav', '100000000000'], + ['edpktoeTraS2WW9iaceu8hvHJ1sUJFSKavtzrMcp4jwMoJWWBts8AK', '100000000000'], + ['edpkuumXzkHj1AhFmjEVLRq4z54iU2atLPUKt4fcu7ihqsEBiUT4wK', '100000000000'], + ['edpktzNbDAUjUk697W7gYg2CRuBQjyPxbEg8dLccYYwKSKvkPvjtV9', '100000000000'], + ['edpkuTXkJDGcFd5nh6VvMz8phXxU3Bi7h6hqgywNFi1vZTfQNnS1RV', '100000000000'], + ['edpkuFrRoDSEbJYgxRtLx2ps82UdaYc1WwfS9sE11yhauZt5DgCHbU', '100000000000'], + ['edpkv8EUUH68jmo3f7Um5PezmfGrRF24gnfLpH3sVNwJnV5bVCxL2n', '100000000000'] +] +with open('$PARAMS_FILE', 'w') as f: + json.dump(params, f, indent=2) +" + fi +else + echo "Error: Could not find octez params at $OCTEZ_PARAMS" + exit 1 +fi + +octez-client --base-dir "$CLIENT_DIR" --endpoint http://localhost:18731 \ + -block genesis activate protocol ProtoALphaALphaALphaALphaALphaALphaALphaALphaDdp3zK \ + with fitness 1 and key activator and parameters "$PARAMS_FILE" + +echo -e "${GREEN}āœ“ Protocol activated${NC}" + +echo -e "\n${YELLOW}You can now proceed to script 3 to start the baker${NC}" diff --git a/scripts/debug/3-start-baker.sh b/scripts/debug/3-start-baker.sh new file mode 100755 index 000000000..f639d727e --- /dev/null +++ b/scripts/debug/3-start-baker.sh @@ -0,0 +1,25 @@ +#!/bin/bash +# Script 3: Start Baker +# This replicates what jstzd does when starting the baker +# Run this in Terminal 3 after protocol activation + +set -e + +# Colors +GREEN='\033[0;32m' +BLUE='\033[0;34m' +NC='\033[0m' + +echo -e "${BLUE}=== Starting Baker (jstzd equivalent) ===${NC}" + +# Load environment +source /tmp/jstz-debug-env.sh + +echo -e "\n${BLUE}Starting baker for injector account...${NC}" +echo "Baker will produce blocks automatically" +echo "Logs will appear below:" +echo "" + +# Start baking (without DAL node, as jstzd does) +octez-baker-alpha --base-dir "$CLIENT_DIR" --endpoint http://localhost:18731 \ + run with local node "$NODE_DIR" injector --liquidity-baking-toggle-vote pass --without-dal diff --git a/scripts/debug/4-originate-rollup.sh b/scripts/debug/4-originate-rollup.sh new file mode 100755 index 000000000..64cb887d8 --- /dev/null +++ b/scripts/debug/4-originate-rollup.sh @@ -0,0 +1,122 @@ +#!/bin/bash +# Script 4: Originate RISC-V Rollup +# This replicates what jstzd does when originating the rollup +# Run this in a new terminal after the baker has produced a few blocks + +set -e + +# Colors +GREEN='\033[0;32m' +BLUE='\033[0;34m' +YELLOW='\033[1;33m' +RED='\033[0;31m' +NC='\033[0m' + +echo -e "${BLUE}=== Originating RISC-V Rollup (jstzd equivalent) ===${NC}" + +# Load environment +source /tmp/jstz-debug-env.sh + +# Wait for block level 3 (jstzd waits for level 3 before originating) +echo -e "\n${YELLOW}Waiting for block level 3...${NC}" +for i in {1..30}; do + LEVEL=$(octez-client --base-dir "$CLIENT_DIR" --endpoint http://localhost:18731 \ + rpc get /chains/main/blocks/head/header 2>/dev/null | grep -o '"level":[0-9]*' | cut -d':' -f2 || echo "0") + if [ -n "$LEVEL" ] && [ "$LEVEL" -ge 3 ]; then + echo -e "${GREEN}āœ“ At block level $LEVEL${NC}" + break + fi + echo -n "." + sleep 1 +done +echo "" + +# Get the RISC-V kernel path +# This should match what build.rs generates +KERNEL_PATH="/Users/alanmarko/projects/jstz_attempt2/jstz/crates/jstzd/resources/jstz_rollup/lightweight-kernel-executable" + +if [ ! -f "$KERNEL_PATH" ]; then + echo -e "${RED}Error: Kernel not found at $KERNEL_PATH${NC}" + echo "Note: jstzd uses the file WITHOUT the .elf extension" + exit 1 +fi + +echo -e "\n${BLUE}Computing kernel checksum...${NC}" +# macOS uses shasum, Linux uses sha256sum +if command -v sha256sum &>/dev/null; then + KERNEL_CHECKSUM=$(sha256sum "$KERNEL_PATH" | awk '{print $1}') +elif command -v shasum &>/dev/null; then + KERNEL_CHECKSUM=$(shasum -a 256 "$KERNEL_PATH" | awk '{print $1}') +else + echo -e "${RED}Error: Neither sha256sum nor shasum found${NC}" + exit 1 +fi +echo "Checksum: $KERNEL_CHECKSUM" + +# Format kernel parameter (jstzd uses: kernel::) +KERNEL_PARAM="kernel:${KERNEL_PATH}:${KERNEL_CHECKSUM}" + +echo -e "\n${BLUE}Kernel parameter:${NC}" +echo "$KERNEL_PARAM" + +# Get rollup operator address for whitelist +echo -e "\n${BLUE}Getting rollup operator address...${NC}" +OPERATOR_ADDR=$(octez-client --base-dir "$CLIENT_DIR" --endpoint http://localhost:18731 \ + show address rollup_operator | grep Hash: | awk '{print $2}') +echo "Operator address: $OPERATOR_ADDR" + +# NOTE: No need to transfer funds! rollup_operator is a bootstrap account with 100,000,000,000 mutez + +# Originate the rollup (jstzd does this at level 3) +echo -e "\n${BLUE}Originating RISC-V smart rollup...${NC}" +echo "This may take a moment..." + +set +e # Don't exit on error so we can see what happened +ORIGINATION_OUTPUT=$(octez-client --base-dir "$CLIENT_DIR" --endpoint http://localhost:18731 \ + originate smart rollup jstz_rollup from rollup_operator \ + of kind riscv \ + of type string \ + with kernel "$KERNEL_PARAM" \ + --burn-cap 999999 \ + --force 2>&1) +ORIGINATION_EXIT_CODE=$? +set -e + +echo "$ORIGINATION_OUTPUT" + +if [ $ORIGINATION_EXIT_CODE -ne 0 ]; then + echo -e "\n${RED}Error: Origination failed with exit code $ORIGINATION_EXIT_CODE${NC}" + exit 1 +fi + +# Extract rollup address +ROLLUP_ADDR=$(echo "$ORIGINATION_OUTPUT" | grep -o 'sr1[a-zA-Z0-9]*' | head -1) + +if [ -z "$ROLLUP_ADDR" ]; then + echo -e "${RED}Error: Could not extract rollup address${NC}" + echo "Output was:" + echo "$ORIGINATION_OUTPUT" + exit 1 +fi + +echo -e "\n${GREEN}āœ“ Rollup originated successfully!${NC}" +echo -e "${GREEN} Address: $ROLLUP_ADDR${NC}" + +# Save rollup address +echo "export ROLLUP_ADDR=$ROLLUP_ADDR" >>/tmp/jstz-debug-env.sh + +# Wait for block level 5 (jstzd waits for level 5 after origination) +echo -e "\n${YELLOW}Waiting for block level 5 (jstzd waits 2 more blocks)...${NC}" +for i in {1..30}; do + LEVEL=$(octez-client --base-dir "$CLIENT_DIR" --endpoint http://localhost:18731 \ + rpc get /chains/main/blocks/head/header 2>/dev/null | grep -o '"level":[0-9]*' | cut -d':' -f2 || echo "0") + if [ -n "$LEVEL" ] && [ "$LEVEL" -ge 5 ]; then + echo -e "${GREEN}āœ“ At block level $LEVEL${NC}" + break + fi + echo -n "." + sleep 1 +done +echo "" + +echo -e "\n${GREEN}Ready to start rollup node (script 5)${NC}" diff --git a/scripts/debug/5-start-rollup-node.sh b/scripts/debug/5-start-rollup-node.sh new file mode 100755 index 000000000..e5be73eb3 --- /dev/null +++ b/scripts/debug/5-start-rollup-node.sh @@ -0,0 +1,53 @@ +#!/bin/bash +# Script 5: Start Rollup Node +# This replicates what jstzd does when starting the rollup node +# Run this in Terminal 4 after originating the rollup + +set -e + +# Colors +GREEN='\033[0;32m' +BLUE='\033[0;34m' +YELLOW='\033[1;33m' +RED='\033[0;31m' +NC='\033[0m' + +echo -e "${BLUE}=== Starting Rollup Node (jstzd equivalent) ===${NC}" + +# Load environment +source /tmp/jstz-debug-env.sh + +if [ -z "$ROLLUP_ADDR" ]; then + echo -e "${RED}Error: ROLLUP_ADDR not set. Did you run script 4?${NC}" + exit 1 +fi + +echo "Rollup address: $ROLLUP_ADDR" +echo "Connecting to node: http://localhost:18731" + +# Setup rollup data directory +ROLLUP_DIR="$BASE_DIR/rollup" +mkdir -p "$ROLLUP_DIR" + +echo -e "\n${BLUE}Starting octez-smart-rollup-node...${NC}" +echo "Data directory: $ROLLUP_DIR" +echo "RPC will be available at: http://localhost:18745" +echo "" +echo -e "${YELLOW}IMPORTANT: NO boot sector file is used (RISC-V kernel comes from origination)${NC}" +echo "" +echo "Logs will appear below:" +echo "" + +# Start the rollup node +# CRITICAL: jstzd does NOT use --boot-sector-file for RISC-V rollups! +# The kernel comes from the origination (kernel::) +octez-smart-rollup-node \ + --endpoint http://localhost:18731 \ + --base-dir "$CLIENT_DIR" \ + run operator for "$ROLLUP_ADDR" \ + with operators rollup_operator \ + --data-dir "$ROLLUP_DIR" \ + --rpc-addr 127.0.0.1 \ + --rpc-port 18745 \ + --acl-override allow-all \ + --history-mode full diff --git a/scripts/debug/README.md b/scripts/debug/README.md new file mode 100644 index 000000000..81790d66a --- /dev/null +++ b/scripts/debug/README.md @@ -0,0 +1,161 @@ +# Debug Scripts - jstzd Equivalent + +These scripts replicate exactly what `cargo run --bin jstzd -- run` does. + +## Overview + +These scripts break down the jstzd startup process into individual steps for debugging. They use the **same configuration, accounts, and parameters** that jstzd uses. + +## Key Differences from Old Debug Scripts + +1. **8 Bootstrap Accounts**: Uses all 8 bootstrap accounts from `crates/jstzd/resources/bootstrap_account/accounts.json` + + - activator (1 mutez) + - injector (100,000,000,000 mutez) + - **rollup_operator (100,000,000,000 mutez)** ← Bootstrap account, doesn't need manual funding! + - bootstrap1-5 (each 100,000,000,000 mutez) + +2. **Protocol Parameters**: Uses octez sandbox parameters from `crates/octez/resources/protocol_parameters/sandbox/ProtoALphaALphaALphaALphaALphaALphaALphaALphaDdp3zK` + + - Not the jstzd/tests params! + +3. **NO Boot Sector File**: The rollup node does NOT use `--boot-sector-file` + + - RISC-V rollups get their kernel from origination: `kernel::` + - Boot sector files are only for legacy WASM rollups + +4. **Block Level Timing**: Waits for level 5 after origination (not just level 3 + 10 seconds) + +## Usage + +Open 4 terminals and run these scripts in order: + +### Terminal 1: Start Node + +```bash +./scripts/debug/1-start-node.sh +``` + +Wait for the node to start and show "Node is now running". + +### Terminal 2: Setup Protocol + +```bash +./scripts/debug/2-setup-protocol.sh +``` + +This imports all 8 bootstrap accounts and activates the protocol. + +### Terminal 3: Start Baker + +```bash +./scripts/debug/3-start-baker.sh +``` + +Wait for the baker to start producing blocks. + +### Terminal 4: Originate Rollup + +```bash +./scripts/debug/4-originate-rollup.sh +``` + +This originates the RISC-V rollup. No manual funding needed since rollup_operator is a bootstrap account. + +### Terminal 4 (same): Start Rollup Node + +```bash +./scripts/debug/5-start-rollup-node.sh +``` + +Starts the rollup node WITHOUT boot sector file. + +## What Each Script Does + +### 1-start-node.sh + +- Creates temp directories (like jstzd does) +- Generates node identity +- Initializes node config +- Starts octez-node in sandbox mode + +### 2-setup-protocol.sh + +- Waits for node readiness (30 retries Ɨ 1 second) +- Imports ALL 8 bootstrap accounts (matching jstzd) +- Uses octez sandbox protocol parameters +- Adds bootstrap accounts to parameters +- Activates protocol + +### 3-start-baker.sh + +- Starts baker for injector account +- Uses --without-dal flag (matching jstzd) + +### 4-originate-rollup.sh + +- Waits for block level 3 +- Computes RISC-V kernel checksum +- Originates rollup with `kernel::` format +- NO manual funding (rollup_operator has funds from genesis) +- Waits for block level 5 (2 more blocks) + +### 5-start-rollup-node.sh + +- Starts rollup node for the originated rollup +- **DOES NOT use --boot-sector-file** (critical!) +- Uses full history mode +- RPC on port 18745 + +## Debugging Tips + +1. **Check Node Health**: `curl http://localhost:18731/health/ready` +2. **Check Block Level**: `curl http://localhost:18731/chains/main/blocks/head/header | grep level` +3. **Check Rollup Status**: `curl http://localhost:18745/global/block/head/status` +4. **View Account Balance**: + ```bash + octez-client --base-dir /tmp/jstz-debug-*/octez-client --endpoint http://localhost:18731 \ + get balance for rollup_operator + ``` + +## Cleanup + +When done, press Ctrl+C in each terminal. The files are in `/tmp/jstz-debug-*` and will be cleaned up automatically. + +## Common Issues + +### Rollup Node Fails to Start + +- **Old Issue**: Used boot sector file for RISC-V rollup āŒ +- **Fixed**: No boot sector file for RISC-V rollups āœ… + +### Rollup Operator Has No Funds + +- **Old Issue**: rollup_operator wasn't a bootstrap account āŒ +- **Fixed**: rollup_operator is a bootstrap account with 100B mutez āœ… + +### Wrong Protocol Parameters + +- **Old Issue**: Used jstzd/tests params āŒ +- **Fixed**: Uses octez sandbox params āœ… + +## References + +- Bootstrap accounts: `crates/jstzd/resources/bootstrap_account/accounts.json` +- Protocol parameters: `crates/octez/resources/protocol_parameters/sandbox/ProtoALphaALphaALphaALphaALphaALphaALphaALphaDdp3zK` +- Kernel path: `crates/jstzd/resources/jstz_rollup/lightweight-kernel-executable` (no .elf extension!) +- Kernel checksum: Computed at build time by `crates/jstzd/build.rs` + +## Comparison with jstzd + +| Aspect | jstzd | These Scripts | +| ----------------------- | ------------- | ---------------- | +| Bootstrap Accounts | 8 accounts | 8 accounts āœ… | +| Protocol Params | octez sandbox | octez sandbox āœ… | +| Rollup Operator Funding | From genesis | From genesis āœ… | +| Boot Sector File | None | None āœ… | +| Wait for Level | 3, then 5 | 3, then 5 āœ… | +| Health Checks | Yes (60Ɨ2s) | Manual āš ļø | +| jstz_node | Optional | Not included āš ļø | + +These scripts are functionally equivalent to `cargo run --bin jstzd -- run` for the core Tezos infrastructure (node, baker, rollup). The jstz_node startup would need to be added separately if needed.