diff --git a/sz-poc-offsite-2025/evm/processor/src/lib.rs b/sz-poc-offsite-2025/evm/processor/src/lib.rs index c14e7da..3cba4b5 100644 --- a/sz-poc-offsite-2025/evm/processor/src/lib.rs +++ b/sz-poc-offsite-2025/evm/processor/src/lib.rs @@ -20,10 +20,10 @@ impl Processor { let metadata = Metadata::new([0; 32], block.number.into()); // the node expects blobs to be padded to the next chunk size let remainder = blob.len() % DaEncoderParams::MAX_BLS12_381_ENCODING_CHUNK_SIZE; - blob.extend( - std::iter::repeat(0) - .take(DaEncoderParams::MAX_BLS12_381_ENCODING_CHUNK_SIZE - remainder), - ); + blob.extend(std::iter::repeat_n( + 0, + DaEncoderParams::MAX_BLS12_381_ENCODING_CHUNK_SIZE - remainder, + )); if let Err(e) = self.da.disperse(blob, metadata).await { error!("Failed to disperse block: {e}"); } else { diff --git a/sz-poc-offsite-2025/evm/prover/Cargo.toml b/sz-poc-offsite-2025/evm/prover/Cargo.toml index 0a1ab45..b27505a 100644 --- a/sz-poc-offsite-2025/evm/prover/Cargo.toml +++ b/sz-poc-offsite-2025/evm/prover/Cargo.toml @@ -4,3 +4,8 @@ edition = { workspace = true } [dependencies] clap = { version = "4.5", features = ["derive"] } +reqwest = { version = "0.11", features = ["blocking", "json"] } +serde = { version = "1.0", features = ["derive"] } +serde_json = "1.0" +tracing = "0.1" +tracing-subscriber = { version = "0.3", features = ["env-filter"] } diff --git a/sz-poc-offsite-2025/evm/prover/src/main.rs b/sz-poc-offsite-2025/evm/prover/src/main.rs index 197581e..8694f4e 100644 --- a/sz-poc-offsite-2025/evm/prover/src/main.rs +++ b/sz-poc-offsite-2025/evm/prover/src/main.rs @@ -1,5 +1,9 @@ use clap::Parser; +use reqwest::blocking::Client; +use serde_json::{Value, json}; use std::{path::PathBuf, process::Command, thread, time::Duration}; +use tracing::{debug, error, info}; +use tracing_subscriber::{EnvFilter, fmt}; #[derive(Parser, Debug)] #[clap(author, version, about = "Ethereum Proof Generation Tool")] @@ -18,6 +22,9 @@ struct Args { #[clap(long)] zeth_binary_dir: Option, + + #[clap(long, default_value = "info")] + log_level: String, } fn run_ethereum_prove( @@ -25,27 +32,29 @@ fn run_ethereum_prove( block_number: u64, batch_size: u64, zeth_binary_dir: Option, + log_level: &str, ) -> Result<(), String> { - println!( + info!( "Running Ethereum prove for blocks {}-{}", block_number, block_number + batch_size - 1 ); - let binary_path = if let Some(dir) = &zeth_binary_dir { - let mut path = PathBuf::from(dir); - path.push("zeth-ethereum"); - path + let mut binary_path = if let Some(dir) = &zeth_binary_dir { + PathBuf::from(dir) } else { - return Err("No binary directory provided".to_string()); + debug!("No binary directory provided, trying current directory"); + std::env::current_dir().map_err(|e| format!("Failed to get current directory: {}", e))? }; + binary_path.push("zeth-ethereum"); + if !binary_path.exists() { return Err(format!("Binary not found at: {}", binary_path.display())); } let output = Command::new(&binary_path) - .env("RUST_LOG", "info") + .env("RUST_LOG", log_level) .args([ "prove", &format!("--rpc={}", rpc), @@ -56,70 +65,73 @@ fn run_ethereum_prove( .map_err(|e| format!("Failed to execute zeth-ethereum prove: {}", e))?; if !output.status.success() { + let stderr = String::from_utf8_lossy(&output.stderr); + error!("ethereum prove command failed: {}", stderr); return Err(format!( "ethereum prove command failed with status: {}\nStderr: {}", - output.status, - String::from_utf8_lossy(&output.stderr) + output.status, stderr )); } - println!("Successfully processed batch"); + info!("Successfully processed batch"); Ok(()) } -fn get_latest_block(rpc: &str) -> Result { - println!("Checking latest block height..."); +fn get_latest_block(client: &Client, rpc: &str) -> Result { + debug!("Checking latest block height..."); - let output = Command::new("curl") - .args([ - "-s", - "-X", - "POST", - "-H", - "Content-Type: application/json", - rpc, - "-d", - r#"{"jsonrpc":"2.0","method":"eth_blockNumber","params":[],"id":1}"#, - ]) - .output() - .map_err(|e| format!("Failed to execute curl: {}", e))?; + let request_body = json!({ + "jsonrpc": "2.0", + "method": "eth_blockNumber", + "params": [], + "id": 1 + }); - if !output.status.success() { - return Err(format!( - "curl command failed with status: {}", - output.status - )); + let response = client + .post(rpc) + .json(&request_body) + .send() + .map_err(|e| format!("Failed to send request: {}", e))?; + + if !response.status().is_success() { + return Err(format!("Request failed with status: {}", response.status())); } - let response = String::from_utf8_lossy(&output.stdout); + let response_json: Value = response + .json() + .map_err(|e| format!("Failed to parse response JSON: {}", e))?; - let block_hex = response - .split("\"result\":\"") - .nth(1) + let block_hex = response_json + .get("result") + .and_then(Value::as_str) .ok_or("Failed to parse response")? - .split("\"") - .next() - .ok_or("Failed to parse block number")? .trim_start_matches("0x"); let block_number = u64::from_str_radix(block_hex, 16) .map_err(|e| format!("Failed to parse hex block number: {}", e))?; - println!("Latest block: {}", block_number); + debug!("Latest block: {}", block_number); Ok(block_number) } fn main() -> Result<(), Box> { let args = Args::parse(); - println!("Starting Ethereum prover..."); - // todo: implement state if needed + let filter = + EnvFilter::try_from_default_env().unwrap_or_else(|_| EnvFilter::new(&args.log_level)); + + fmt::fmt().with_env_filter(filter).with_target(false).init(); + + info!("Starting Ethereum prover..."); + + let client = Client::new(); let mut current_block = args.start_block; + loop { - match get_latest_block(&args.rpc) { + match get_latest_block(&client, &args.rpc) { Ok(latest_block) => { if latest_block >= current_block + args.batch_size { - println!( + info!( "New blocks available. Current: {}, Latest: {}", current_block, latest_block ); @@ -129,25 +141,27 @@ fn main() -> Result<(), Box> { current_block, args.batch_size, args.zeth_binary_dir.clone(), + &args.log_level, ) { Ok(_) => { current_block += args.batch_size; - println!("Updated current block to {}", current_block); + info!("Updated current block to {}", current_block); } Err(e) => { - eprintln!("Error running prover: {}", e); + error!("Error running prover: {}", e); } } } else { - println!( - "No new blocks to process. Current: {}, Latest: {}, sleeeping...", + info!( + "No new blocks to process. Current: {}, Latest: {}, sleeping...", current_block, latest_block ); thread::sleep(Duration::from_secs(args.interval)); } } Err(e) => { - eprintln!("Error getting latest block: {}", e); + error!("Error getting latest block: {}", e); + thread::sleep(Duration::from_secs(args.interval)); } } }