diff --git a/cli/src/cmd/testnet/add_node.rs b/cli/src/cmd/testnet/add_node.rs index 34ea367..9793e48 100644 --- a/cli/src/cmd/testnet/add_node.rs +++ b/cli/src/cmd/testnet/add_node.rs @@ -12,7 +12,7 @@ use clap::Parser; use color_eyre::eyre::{eyre, Context as _}; use color_eyre::Result; use malachitebft_eth_types::Address; -use tracing::info; +use tracing::{debug, info, warn}; use super::reth::{self, RethProcess}; use super::types::RethNode; @@ -46,16 +46,18 @@ pub struct TestnetAddNodeCmd { impl TestnetAddNodeCmd { /// Execute the add-node command pub fn run(&self, home_dir: &Path) -> Result<()> { - println!("šŸ“ Adding non-validator node to testnet...\n"); + info!("Adding non-validator node to testnet"); // 1. Check if custom-reth is available - print!("Checking custom-reth installation... "); + debug!("Checking custom-reth installation"); match reth::check_installation(&self.custom_reth_bin) { Ok(version) => { - println!("āœ“ {}", version.lines().next().unwrap_or(&version)); + info!( + "Custom-reth installation verified: {}", + version.lines().next().unwrap_or(&version) + ); } Err(e) => { - println!("āœ—"); return Err(e.wrap_err( "Custom reth is not available. Make sure custom-reth/ directory exists and contains a valid reth binary." )); @@ -64,26 +66,26 @@ impl TestnetAddNodeCmd { // 2. Determine the next node ID let node_id = self.find_next_node_id(home_dir)?; - println!("\nšŸ“‹ Next available node ID: {node_id}"); + info!("Next available node ID: {node_id}"); // 3. Create node directories - println!("\nšŸ“ Creating node directories..."); + info!("Creating node directories"); let node_home = home_dir.join(node_id.to_string()); let config_dir = node_home.join("config"); let log_dir = node_home.join("logs"); fs::create_dir_all(&config_dir)?; fs::create_dir_all(&log_dir)?; - println!("āœ“ Node directories created"); + info!("Node directories created"); // 4. Copy genesis file from existing testnet - println!("\nšŸ“‹ Copying genesis file..."); + info!("Copying genesis file"); self.copy_genesis(home_dir, node_id)?; - println!("āœ“ Genesis file copied"); + info!("Genesis file copied"); // 5. Generate Malachite config - println!("\nāš™ļø Generating Malachite config..."); + info!("Generating Malachite config"); self.generate_malachite_config(home_dir, node_id)?; - println!("āœ“ Malachite config generated"); + info!("Malachite config generated"); let fee_receiver = if let Some(fee_receiver_str) = &self.fee_receiver { Address::from(AlloyAddress::from_str(fee_receiver_str)?) @@ -92,23 +94,23 @@ impl TestnetAddNodeCmd { }; // 6. Generate Emerald config - println!("\nāš™ļø Generating Emerald config..."); + info!("Generating Emerald config"); info!("Will use address `{fee_receiver}` as Fee Receiver address"); self.generate_emerald_config(home_dir, node_id, fee_receiver)?; - println!("āœ“ Emerald config generated"); + info!("Emerald config generated"); // 7. Generate private validator key - println!("\nšŸ”‘ Generating private validator key..."); + info!("Generating private validator key"); self.generate_private_key(home_dir, node_id)?; - println!("āœ“ Private validator key generated"); + info!("Private validator key generated"); // 8. Spawn Reth process - println!("\nšŸ”— Starting Reth execution client..."); + info!("Starting Reth execution client"); let reth_process = self.spawn_reth_node(home_dir, node_id)?; - println!("āœ“ Reth node started (PID: {})", reth_process.pid); + info!("Reth node started (PID: {})", reth_process.pid); // 9. Wait for Reth node to be ready - println!("\nā³ Waiting for Reth node to initialize..."); + info!("Waiting for Reth node to initialize"); let assets_dir = home_dir.join("assets"); let reth_node = RethNode::new( node_id, @@ -126,25 +128,22 @@ impl TestnetAddNodeCmd { rpc.get_block_number() }, )?; - println!("āœ“ Reth node ready"); + info!("Reth node ready"); // 10. Connect to existing peers - println!("\nšŸ”— Connecting to existing peers..."); + info!("Connecting to existing peers"); self.connect_to_peers(home_dir, node_id)?; - println!("āœ“ Connected to peers"); + info!("Connected to peers"); // 11. Spawn Emerald process - println!("\nšŸ’Ž Starting Emerald consensus node..."); + info!("Starting Emerald consensus node"); let emerald_process = self.spawn_emerald_node(home_dir, node_id)?; - println!("āœ“ Emerald node started (PID: {})", emerald_process.pid); - - println!("\nāœ… Non-validator node {node_id} added successfully!"); - println!("\nšŸ“ Logs:"); - println!(" Reth: {}/{}/logs/reth.log", home_dir.display(), node_id); - println!( - " Emerald: {}/{}/logs/emerald.log", - home_dir.display(), - node_id + info!("Emerald node started (PID: {})", emerald_process.pid); + + info!( + reth_log=%format!("{}/{}/logs/reth.log", home_dir.display(), node_id), + emerald_log=%format!("{}/{}/logs/emerald.log", home_dir.display(), node_id), + "Non-validator node {node_id} added successfully!" ); Ok(()) @@ -414,18 +413,18 @@ fee_recipient = "{}" ); // Try to get enode and connect if let Ok(enode) = existing_node.get_enode() { - print!(" Connecting to node {id}... "); + debug!("Connecting to node {id}"); if new_node.add_peer(&enode).is_ok() { - println!("āœ“"); + debug!("Connected to node {id}"); connected += 1; } else { - println!("āœ— (skipped)"); + warn!("Failed to connect to node {id} (skipped)"); } } } if connected == 0 { - println!(" āš ļø No existing peers found to connect to"); + warn!("No existing peers found to connect to"); } Ok(()) diff --git a/cli/src/cmd/testnet/destroy.rs b/cli/src/cmd/testnet/destroy.rs index 7520816..a16d5fd 100644 --- a/cli/src/cmd/testnet/destroy.rs +++ b/cli/src/cmd/testnet/destroy.rs @@ -7,6 +7,7 @@ use std::process::Command; use clap::Parser; use color_eyre::eyre::eyre; use color_eyre::Result; +use tracing::{debug, info, warn}; #[derive(Parser, Debug, Clone, PartialEq)] pub struct TestnetDestroyCmd { @@ -19,19 +20,15 @@ impl TestnetDestroyCmd { /// Execute the destroy command pub fn run(&self, home_dir: &Path) -> Result<()> { if !home_dir.exists() { - println!( - "āš ļø Testnet directory does not exist at {}", - home_dir.display() - ); + warn!("Testnet directory does not exist at {}", home_dir.display()); return Ok(()); } // Confirm with user unless --force is specified if !self.force { - println!("āš ļø This will stop all nodes and permanently delete all testnet data at:"); + println!("This will stop all nodes and permanently delete all testnet data at:"); println!(" {}", home_dir.display()); - println!(); - print!(" Are you sure? (y/N): "); + println!("Are you sure? (y/N): "); use std::io::{self, Write}; io::stdout().flush()?; @@ -41,21 +38,21 @@ impl TestnetDestroyCmd { let input = input.trim().to_lowercase(); if input != "y" && input != "yes" { - println!("Cancelled."); + info!("Cancelled."); return Ok(()); } } // First, stop all running processes - println!("šŸ›‘ Stopping all running nodes..."); + info!("Stopping all running nodes"); self.stop_all_nodes(home_dir)?; - println!("\nšŸ—‘ļø Removing testnet data..."); + info!("Removing testnet data"); // Remove the entire directory fs::remove_dir_all(home_dir).map_err(|e| eyre!("Failed to remove directory: {}", e))?; - println!("āœ… Testnet data removed successfully"); + info!("Testnet data removed successfully"); Ok(()) } @@ -105,7 +102,7 @@ impl TestnetDestroyCmd { } if stopped_count > 0 { - println!(" Stopped {stopped_count} process(es)"); + debug!("Stopped {stopped_count} process(es)"); } Ok(()) diff --git a/cli/src/cmd/testnet/reth.rs b/cli/src/cmd/testnet/reth.rs index da351a1..2c0885e 100644 --- a/cli/src/cmd/testnet/reth.rs +++ b/cli/src/cmd/testnet/reth.rs @@ -6,6 +6,7 @@ use std::process::Command; use color_eyre::eyre::{eyre, Context as _}; use color_eyre::Result; +use tracing::info; use super::rpc::RpcClient; use super::types::{ProcessHandle, RethNode}; @@ -109,12 +110,15 @@ impl RethNode { let args = self.build_args(); - println!("Starting Reth node {} on ports:", self.node_id); - println!(" HTTP: {}", self.ports.http); - println!(" AuthRPC: {}", self.ports.authrpc); - println!(" Metrics: {}", self.ports.metrics); - println!(" P2P: {}", self.ports.p2p); - println!(" Logs: {}", log_file_path.display()); + info!( + node_id = %self.node_id, + http_port = %self.ports.http, + authrpc_port = %self.ports.authrpc, + metrics_port = %self.ports.metrics, + p2p_port = %self.ports.p2p, + log_file = %log_file_path.display(), + "Starting Reth node" + ); let pid_file = self .home_dir diff --git a/cli/src/cmd/testnet/start.rs b/cli/src/cmd/testnet/start.rs index d7e74a1..d08653a 100644 --- a/cli/src/cmd/testnet/start.rs +++ b/cli/src/cmd/testnet/start.rs @@ -15,7 +15,7 @@ use malachitebft_config::LoggingConfig; use malachitebft_core_types::{Context, SigningScheme}; use malachitebft_eth_types::Address; use serde_json::{json, Value}; -use tracing::info; +use tracing::{debug, info, warn}; use super::reth::{self, RethProcess}; use super::types::RethNode; @@ -77,16 +77,19 @@ impl TestnetStartCmd { )); } - println!("šŸš€ Initializing testnet with {} nodes...\n", self.nodes); + info!("Initializing testnet with {} nodes", self.nodes); // 1. Check if custom-reth is available - print!("Checking custom-reth installation... "); + debug!("Checking custom-reth installation"); match reth::check_installation(&self.custom_reth_bin) { Ok(version) => { - println!("āœ“ {}", version.lines().next().unwrap_or(&version)); + info!( + "Custom-reth installation verified: {}", + version.lines().next().unwrap_or(&version) + ); } Err(e) => { - println!("āœ—"); + warn!("Custom-reth installation check failed"); return Err(e.wrap_err( "Custom reth is not available. Make sure custom-reth/ directory exists and contains a valid reth binary." )); @@ -94,14 +97,14 @@ impl TestnetStartCmd { } // 2. Generate testnet configuration - println!("\nšŸ“ Generating testnet configuration..."); + info!("Generating testnet configuration"); self.generate_testnet_config(node, home_dir, logging)?; - println!("āœ“ Configuration generated"); + info!("Configuration generated"); // 2b. Set up assets directory - println!("\nšŸ“¦ Setting up assets directory..."); + info!("Setting up assets directory"); self.setup_assets_directory(home_dir)?; - println!("āœ“ Assets directory set up"); + info!("Assets directory set up"); let fee_receiver = if let Some(fee_receiver_str) = &self.fee_receiver { Address::from(AlloyAddress::from_str(fee_receiver_str)?) @@ -110,63 +113,62 @@ impl TestnetStartCmd { }; // 2c. Generate Emerald configs - println!("\nāš™ļø Generating Emerald configs..."); + info!("Generating Emerald configs"); info!("Will use address `{fee_receiver}` as Fee Receiver address"); self.generate_emerald_configs(home_dir, fee_receiver)?; - println!("āœ“ Emerald configs generated"); + info!("Emerald configs generated"); // 3. Extract validator public keys - println!("\nšŸ”‘ Extracting validator public keys..."); + info!("Extracting validator public keys"); self.extract_public_keys(home_dir)?; - println!("āœ“ Public keys extracted"); + info!("Public keys extracted"); // 4. Generate genesis file - println!("\nāš™ļø Generating genesis file..."); + info!("Generating genesis file"); self.generate_genesis(home_dir)?; - println!("āœ“ Genesis file created"); + info!("Genesis file created"); // 5. Spawn Reth processes - println!("\nšŸ”— Starting Reth execution clients..."); + info!("Starting Reth execution clients"); let reth_processes = self.spawn_reth_nodes(home_dir)?; - println!("āœ“ All Reth nodes started"); + info!("All Reth nodes started"); // 6. Wait for Reth nodes to be ready - println!("\nā³ Waiting for Reth nodes to initialize..."); + info!("Waiting for Reth nodes to initialize"); self.wait_for_reth_nodes(home_dir)?; - println!("āœ“ All Reth nodes ready"); + info!("All Reth nodes ready"); // 7. Connect Reth peers - println!("\nšŸ”— Connecting Reth peers..."); + info!("Connecting Reth peers"); self.connect_reth_peers(home_dir)?; - println!("āœ“ Reth peers connected"); + info!("Reth peers connected"); // 8. Spawn Emerald processes - println!("\nšŸ’Ž Starting Emerald consensus nodes..."); + info!("Starting Emerald consensus nodes"); let emerald_processes = self.spawn_emerald_nodes(home_dir)?; - println!("āœ“ All Emerald nodes started"); - - println!("\nāœ… Testnet started successfully!"); - println!("\nšŸ“Š Status:"); - println!(" Reth processes: {} running", reth_processes.len()); - println!(" Emerald processes: {} running", emerald_processes.len()); - println!("\nšŸ“ Logs:"); - println!( - " Reth: {}/{{0..{}}}/logs/reth.log", + info!("All Emerald nodes started"); + + info!( + "Testnet started successfully!\n\ + Status:\n\ + \tReth processes: {} running\n\ + \tEmerald processes: {} running\n\ + Logs:\n\ + \tReth: {}/{{0..{}}}/logs/reth.log\n\ + \tEmerald: {}/{{0..{}}}/logs/emerald.log\n\ + Commands:\n\ + \temerald testnet status - Check status of all nodes\n\ + \temerald testnet stop-node - Stop a specific node\n\ + \temerald testnet stop - Stop all nodes\n\ + \temerald testnet destroy - Remove all testnet data", + reth_processes.len(), + emerald_processes.len(), home_dir.display(), - self.nodes - 1 - ); - println!( - " Emerald: {}/{{0..{}}}/logs/emerald.log", + self.nodes - 1, home_dir.display(), self.nodes - 1 ); - println!("\nšŸ’” Commands:"); - println!(" emerald testnet status - Check status of all nodes"); - println!(" emerald testnet stop-node - Stop a specific node"); - println!(" emerald testnet stop - Stop all nodes"); - println!(" emerald testnet destroy - Remove all testnet data"); - Ok(()) } @@ -354,7 +356,7 @@ fee_recipient = "{}" PathBuf::from("emerald-utils") } }; - println!( + info!( " Using emerald-utils from: {}", emerald_utils_bin.display() ); @@ -436,9 +438,9 @@ fee_recipient = "{}" assets_dir.clone(), &self.reth_config_path, ); - print!(" Starting Reth node {i}... "); + debug!("Starting Reth node {i}"); let process = reth_node.spawn(&self.custom_reth_bin)?; - println!("āœ“ (PID: {})", process.pid); + info!("Started Reth node {i} (PID: {})", process.pid); processes.push(process); // Small delay between spawns @@ -458,7 +460,7 @@ fee_recipient = "{}" assets_dir.clone(), &self.reth_config_path, ); - print!(" Waiting for Reth node {i} to be ready... "); + debug!("Waiting for Reth node {i} to be ready"); let rpc = RpcClient::new(reth_node.ports.http); retry_with_timeout( "reth node ready", @@ -469,7 +471,7 @@ fee_recipient = "{}" rpc.get_block_number() }, )?; - println!("āœ“"); + info!("Reth node {i} is ready"); } Ok(()) @@ -487,9 +489,9 @@ fee_recipient = "{}" assets_dir.clone(), &self.reth_config_path, ); - print!(" Getting enode for Reth node {i}... "); + debug!("Getting enode for Reth node {i}"); let enode = reth_node.get_enode()?; - println!("āœ“"); + debug!("Got enode for Reth node {i}"); enodes.push(enode); } @@ -503,9 +505,9 @@ fee_recipient = "{}" ); for (j, enode) in enodes.iter().enumerate() { if i != j { - print!(" Connecting node {i} -> {j}... "); + debug!("Connecting node {i} -> {j}"); reth_node.add_peer(enode)?; - println!("āœ“"); + debug!("Connected node {i} -> {j}"); } } } @@ -517,9 +519,9 @@ fee_recipient = "{}" let mut processes = Vec::new(); for i in 0..self.nodes { - print!(" Starting Emerald node {i}... "); + debug!("Starting Emerald node {i}"); let process = self.spawn_emerald_node(i, home_dir)?; - println!("āœ“ (PID: {})", process.pid); + info!("Started Emerald node {i} (PID: {})", process.pid); processes.push(process); // Small delay between spawns diff --git a/cli/src/cmd/testnet/start_node.rs b/cli/src/cmd/testnet/start_node.rs index a77cae1..fe2b08c 100644 --- a/cli/src/cmd/testnet/start_node.rs +++ b/cli/src/cmd/testnet/start_node.rs @@ -8,7 +8,7 @@ use std::process::Command; use clap::Parser; use color_eyre::eyre::{eyre, Context as _}; use color_eyre::Result; -use tracing::info; +use tracing::{debug, info, warn}; use super::reth; use super::types::RethNode; @@ -91,16 +91,19 @@ impl TestnetStartNodeCmd { return Ok(()); } - println!("šŸš€ Starting node {}...", self.node_id); + info!("Starting node {}", self.node_id); // Check if custom-reth is available - print!("Checking custom-reth installation... "); + debug!("Checking custom-reth installation"); match reth::check_installation(&self.custom_reth_bin) { Ok(version) => { - println!("āœ“ {}", version.lines().next().unwrap_or(&version)); + info!( + "Custom-reth installation verified: {}", + version.lines().next().unwrap_or(&version) + ); } Err(e) => { - println!("āœ—"); + warn!("Custom-reth installation check failed"); return Err(e.wrap_err( "Custom reth is not available. Make sure custom-reth/ directory exists and contains a valid reth binary or custom-reth binary is in your $PATH." )); @@ -109,7 +112,7 @@ impl TestnetStartNodeCmd { // Start Reth process if reth_status != NodeStatus::Running { - println!("\nšŸ”— Starting Reth execution client..."); + info!("Starting Reth execution client"); let assets_dir = home_dir.join("assets"); let reth_node = RethNode::new( self.node_id, @@ -118,10 +121,10 @@ impl TestnetStartNodeCmd { &self.reth_config_path, ); let reth_process = reth_node.spawn(&self.custom_reth_bin)?; - println!("āœ“ Reth node started (PID: {})", reth_process.pid); + info!("Reth node started (PID: {})", reth_process.pid); // Wait for Reth to be ready - println!("\nā³ Waiting for Reth node to initialize..."); + info!("Waiting for Reth node to initialize"); let rpc = RpcClient::new(reth_node.ports.http); retry_with_timeout( "reth node ready", @@ -132,31 +135,24 @@ impl TestnetStartNodeCmd { rpc.get_block_number() }, )?; - println!("āœ“ Reth node ready"); + info!("Reth node ready"); // Connect to existing peers - println!("\nšŸ”— Connecting to existing peers..."); + info!("Connecting to existing peers"); self.connect_to_peers(home_dir, self.node_id)?; - println!("āœ“ Connected to peers"); + info!("Connected to peers"); } // Start Emerald process if emerald_status != NodeStatus::Running { - println!("\nšŸ’Ž Starting Emerald consensus node..."); + info!("Starting Emerald consensus node"); let emerald_process = self.spawn_emerald_node(home_dir, self.node_id)?; - println!("āœ“ Emerald node started (PID: {})", emerald_process.pid); - - println!("\nāœ… Node {} started successfully!", self.node_id); - println!("\nšŸ“ Logs:"); - println!( - " Reth: {}/{}/logs/reth.log", - home_dir.display(), - self.node_id - ); - println!( - " Emerald: {}/{}/logs/emerald.log", - home_dir.display(), - self.node_id + info!("Emerald node started (PID: {})", emerald_process.pid); + + info!( + reth_log=%format!("{}/{}/logs/reth.log", home_dir.display(), self.node_id), + emerald_log=%format!("{}/{}/logs/emerald.log", home_dir.display(), self.node_id), + "Node {} started successfully!", self.node_id ); } @@ -195,18 +191,18 @@ impl TestnetStartNodeCmd { ); // Try to get enode and connect if let Ok(enode) = peer_node.get_enode() { - print!(" Connecting to node {id}... "); + debug!("Connecting to node {id}"); if node.add_peer(&enode).is_ok() { - println!("āœ“"); + debug!("Connected to node {id}"); connected += 1; } else { - println!("āœ— (skipped)"); + debug!("Failed to connect to node {id} (skipped)"); } } } if connected == 0 { - println!(" āš ļø No existing peers found to connect to"); + warn!("No existing peers found to connect to"); } Ok(()) diff --git a/cli/src/cmd/testnet/status.rs b/cli/src/cmd/testnet/status.rs index 21bd938..3d6ca94 100644 --- a/cli/src/cmd/testnet/status.rs +++ b/cli/src/cmd/testnet/status.rs @@ -4,6 +4,7 @@ use std::path::Path; use clap::Parser; use color_eyre::Result; +use tracing::info; use super::rpc::RpcClient; use super::types::{ProcessHandle, RethPorts}; @@ -16,8 +17,8 @@ pub struct TestnetStatusCmd { impl TestnetStatusCmd { /// Execute the testnet status command pub fn run(&self, home_dir: &Path) -> Result<()> { - println!("šŸ“Š Testnet Status"); - println!("Looking for nodes in: {}\n", home_dir.display()); + info!("Testnet Status"); + info!("Looking for nodes in: {}", home_dir.display()); // Find all node directories let mut node_count = 0; @@ -29,14 +30,14 @@ impl TestnetStatusCmd { let node_dir = home_dir.join(i.to_string()); if !node_dir.exists() { if i == 0 { - println!("No testnet found. Run 'emerald testnet start' first."); + info!("No testnet found. Run 'emerald testnet start' first."); return Ok(()); } break; } node_count += 1; - println!("Node {i}:"); + info!("Node {i}:"); // Check Emerald status let emerald_pid_file = node_dir.join("emerald.pid"); @@ -51,7 +52,7 @@ impl TestnetStatusCmd { } else { "Not started".to_string() }; - println!(" Emerald: {emerald_status}"); + info!(" Emerald: {emerald_status}"); // Check Reth status let reth_pid_file = node_dir.join("reth.pid"); @@ -66,28 +67,28 @@ impl TestnetStatusCmd { } else { "Not started".to_string() }; - println!(" Reth: {reth_status}"); + info!(" Reth: {reth_status}"); // Get block height if Reth is running let ports = RethPorts::for_node(i); let rpc = RpcClient::new(ports.http); if let Ok(height) = rpc.get_block_number() { - println!(" Height: {height}"); + info!(" Height: {height}"); } // Get peer count if Reth is running if let Ok(peers) = rpc.get_peer_count() { - println!(" Peers: {peers}"); + info!(" Peers: {peers}"); } - - println!(); } - println!("Summary:"); - println!(" Total nodes: {node_count}"); - println!(" Emerald running: {running_emerald}/{node_count}"); - println!(" Reth running: {running_reth}/{node_count}"); + info!( + total_nodes=?node_count, + emerald_running=?running_emerald, + reth_running=?running_reth, + "Status" + ); Ok(()) } diff --git a/cli/src/cmd/testnet/stop.rs b/cli/src/cmd/testnet/stop.rs index f669626..de5b6f2 100644 --- a/cli/src/cmd/testnet/stop.rs +++ b/cli/src/cmd/testnet/stop.rs @@ -6,6 +6,7 @@ use std::process::Command; use clap::Parser; use color_eyre::Result; +use tracing::{debug, info, warn}; #[derive(Parser, Debug, Clone, PartialEq)] pub struct TestnetStopCmd {} @@ -13,13 +14,10 @@ pub struct TestnetStopCmd {} impl TestnetStopCmd { /// Execute the stop command pub fn run(&self, home_dir: &Path) -> Result<()> { - println!("šŸ›‘ Stopping all testnet nodes...\n"); + info!("Stopping all testnet nodes"); if !home_dir.exists() { - println!( - "āš ļø Testnet directory does not exist at {}", - home_dir.display() - ); + warn!("Testnet directory does not exist at {}", home_dir.display()); return Ok(()); } @@ -41,7 +39,7 @@ impl TestnetStopCmd { // Iterate through all node directories for (node_id, path) in node_infos { - println!("Stopping node {node_id}..."); + info!("Stopping node {node_id}"); // Stop Reth process let reth_pid_file = path.join("reth.pid"); @@ -49,14 +47,14 @@ impl TestnetStopCmd { if let Ok(pid_str) = fs::read_to_string(&reth_pid_file) { if let Ok(pid) = pid_str.trim().parse::() { total_processes += 1; - print!(" Stopping Reth (PID: {pid})... "); + debug!("Stopping Reth (PID: {pid})"); match Command::new("kill").args(["-9", &pid.to_string()]).output() { Ok(output) if output.status.success() => { - println!("āœ“"); + info!("Stopped Reth (PID: {pid})"); stopped_count += 1; } _ => { - println!("āœ— (process may already be stopped)"); + debug!("Process may already be stopped (PID: {pid})"); } } let _ = fs::remove_file(&reth_pid_file); @@ -70,14 +68,14 @@ impl TestnetStopCmd { if let Ok(pid_str) = fs::read_to_string(&emerald_pid_file) { if let Ok(pid) = pid_str.trim().parse::() { total_processes += 1; - print!(" Stopping Emerald (PID: {pid})... "); + debug!("Stopping Emerald (PID: {pid})"); match Command::new("kill").args(["-9", &pid.to_string()]).output() { Ok(output) if output.status.success() => { - println!("āœ“"); + info!("Stopped Emerald (PID: {pid})"); stopped_count += 1; } _ => { - println!("āœ— (process may already be stopped)"); + debug!("Process may already be stopped (PID: {pid})"); } } let _ = fs::remove_file(&emerald_pid_file); @@ -86,11 +84,10 @@ impl TestnetStopCmd { } } - println!(); if total_processes == 0 { - println!("āš ļø No running processes found"); + warn!("No running processes found"); } else { - println!("āœ… Stopped {stopped_count}/{total_processes} processes"); + info!("Stopped {stopped_count}/{total_processes} processes"); } Ok(()) diff --git a/cli/src/cmd/testnet/stop_node.rs b/cli/src/cmd/testnet/stop_node.rs index efaaf7b..a8b8056 100644 --- a/cli/src/cmd/testnet/stop_node.rs +++ b/cli/src/cmd/testnet/stop_node.rs @@ -7,6 +7,7 @@ use std::process::Command; use clap::Parser; use color_eyre::eyre::eyre; use color_eyre::Result; +use tracing::{debug, info, warn}; #[derive(Parser, Debug, Clone, PartialEq)] pub struct TestnetStopNodeCmd { @@ -27,7 +28,7 @@ impl TestnetStopNodeCmd { )); } - println!("šŸ›‘ Stopping node {}...", self.node_id); + info!("Stopping node {}", self.node_id); let mut stopped_count = 0; @@ -37,24 +38,24 @@ impl TestnetStopNodeCmd { match fs::read_to_string(&reth_pid_file) { Ok(pid_str) => { if let Ok(pid) = pid_str.trim().parse::() { - print!(" Stopping Reth process (PID: {pid})... "); + debug!("Stopping Reth process (PID: {pid})"); match Command::new("kill").args(["-9", &pid.to_string()]).output() { Ok(output) if output.status.success() => { - println!("āœ“"); + info!("Stopped Reth process (PID: {pid})"); stopped_count += 1; } _ => { - println!("āœ— (failed to stop)"); + warn!("Failed to stop Reth process (PID: {pid})"); } } // Always remove PID file regardless let _ = fs::remove_file(&reth_pid_file); } } - Err(_) => println!(" No Reth PID file found"), + Err(_) => debug!("No Reth PID file found"), } } else { - println!(" No Reth PID file found"); + debug!("No Reth PID file found"); } // Stop Emerald process @@ -63,31 +64,31 @@ impl TestnetStopNodeCmd { match fs::read_to_string(&emerald_pid_file) { Ok(pid_str) => { if let Ok(pid) = pid_str.trim().parse::() { - print!(" Stopping Emerald process (PID: {pid})... "); + debug!("Stopping Emerald process (PID: {pid})"); match Command::new("kill").args(["-9", &pid.to_string()]).output() { Ok(output) if output.status.success() => { - println!("āœ“"); + info!("Stopped Emerald process (PID: {pid})"); stopped_count += 1; } _ => { - println!("āœ— (failed to stop)"); + warn!("Failed to stop Emerald process (PID: {pid})"); } } // Always remove PID file regardless let _ = fs::remove_file(&emerald_pid_file); } } - Err(_) => println!(" No Emerald PID file found"), + Err(_) => debug!("No Emerald PID file found"), } } else { - println!(" No Emerald PID file found"); + debug!("No Emerald PID file found"); } if stopped_count == 0 { - println!("\nāš ļø No running processes found for node {}", self.node_id); + warn!("No running processes found for node {}", self.node_id); } else { - println!( - "\nāœ… Stopped {} process(es) for node {}", + info!( + "Stopped {} process(es) for node {}", stopped_count, self.node_id ); } diff --git a/utils/src/poa.rs b/utils/src/poa.rs index 7b75c28..ee11d0d 100644 --- a/utils/src/poa.rs +++ b/utils/src/poa.rs @@ -8,6 +8,7 @@ use color_eyre::eyre::{Context, Result}; use k256::elliptic_curve::sec1::ToEncodedPoint; use k256::PublicKey; use reqwest::Url; +use tracing::info; // Define the Solidity contract ABI alloy_sol_types::sol!( @@ -107,33 +108,37 @@ pub async fn list_validators(rpc_url: &Url, contract_address: &Address) -> Resul let contract = ValidatorManager::new(*contract_address, &provider); let poa_owner_address = contract.owner().call().await?.0; - println!("POA Owner Address: 0x{poa_owner_address:x}"); - println!(); + info!("POA Owner Address: 0x{poa_owner_address:x}"); let validators = contract.getValidators().call().await?; - println!("Total validators: {}", validators.len()); - println!(); - // sort validators by power descending let mut validators = validators; validators.sort_by(|a, b| b.power.cmp(&a.power)); + info!( + poa_owner=%format!("0x{poa_owner_address:x}"), + total_validators=validators.len(), + "POA Validator Status" + ); + for (i, validator) in validators.iter().enumerate() { - println!("Validator #{}:", i + 1); - println!(" Power: {}", validator.power); // validator pubkey in hex let mut pubkey_bytes = Vec::with_capacity(65); pubkey_bytes.push(0x04); // uncompressed prefix pubkey_bytes.extend_from_slice(&validator.validatorKey.x.to_be_bytes::<32>()); pubkey_bytes.extend_from_slice(&validator.validatorKey.y.to_be_bytes::<32>()); - println!(" Pubkey: {}", hex::encode(&pubkey_bytes)); + // print validator address 0x let pubkey = PublicKey::from_sec1_bytes(&pubkey_bytes) .map_err(|e| color_eyre::eyre::eyre!("Invalid public key bytes: {}", e))?; let address = raw_public_key_to_address(&pubkey.to_encoded_point(false).as_bytes()[1..]); - println!("Validator address: 0x{address:x}"); - println!(); + + info!( + power=validator.power, + pubkey=%hex::encode(&pubkey_bytes), + address=%format!("0x{address:x}"), + "Validator {} Info", i+1); } Ok(()) @@ -185,8 +190,11 @@ pub async fn add_validator( let contract = ValidatorManager::new(*contract_address, &provider); // Call the register function - println!("Adding validator with pubkey: {validator_identifier}"); - println!(" Power: {power}"); + info!( + pubkey=%validator_identifier, + power=power, + "Adding validator" + ); let tx = contract .register(validator_public_key_bytes.into(), power) @@ -194,15 +202,19 @@ pub async fn add_validator( .await .context("Failed to send register transaction")?; - println!("Transaction sent: {:?}", tx.tx_hash()); + let tx_hash = tx.tx_hash(); + info!(tx_hash=?tx_hash, "Transaction sent"); let receipt = tx .get_receipt() .await .context("Failed to get transaction receipt")?; - println!("Transaction confirmed in block: {:?}", receipt.block_number); - println!("Gas used: {}", receipt.gas_used); + info!( + block_number=?receipt.block_number, + gas_used=receipt.gas_used, + "Transaction confirmed" + ); Ok(()) } @@ -232,8 +244,11 @@ pub async fn remove_validator( let addr = parse_validator_identifier(validator_identifier)?; // Call the unregister function - println!("Removing validator: {validator_identifier}"); - println!(" Validator address: {addr:?}"); + info!( + validator=%validator_identifier, + address=%format!("{addr:?}"), + "Removing validator" + ); let tx = contract .unregister(addr) @@ -241,16 +256,17 @@ pub async fn remove_validator( .await .context("Failed to send unregister transaction")?; - println!("Transaction sent: {:?}", tx.tx_hash()); + let tx_hash = tx.tx_hash(); + info!(tx_hash=?tx_hash, "Transaction sent"); let receipt = tx .get_receipt() .await .context("Failed to get transaction receipt")?; - println!( - "Transaction confirmed in block: {:?}", - receipt.block_number.unwrap() + info!( + block_number=?receipt.block_number, + "Transaction confirmed" ); Ok(()) @@ -282,9 +298,12 @@ pub async fn update_validator_power( let validator_address = parse_validator_identifier(validator_identifier)?; // Call the updatePower function - println!("Updating validator power: {validator_identifier}"); - println!(" Validator address: {validator_address:?}"); - println!(" New power: {new_power}"); + info!( + validator=%validator_identifier, + address=%validator_address, + new_power=new_power, + "Updating validator power" + ); let tx = contract .updatePower(validator_address, new_power) @@ -292,15 +311,19 @@ pub async fn update_validator_power( .await .context("Failed to send updatePower transaction")?; - println!("Transaction sent: {:?}", tx.tx_hash()); + let tx_hash = tx.tx_hash(); + info!(tx_hash=?tx_hash, "Transaction sent"); let receipt = tx .get_receipt() .await .context("Failed to get transaction receipt")?; - println!("Transaction confirmed in block: {receipt:?}"); - println!("Gas used: {}", receipt.gas_used); + info!( + block_number=?receipt.block_number, + gas_used=receipt.gas_used, + "Transaction confirmed" + ); Ok(()) }