diff --git a/.gitignore b/.gitignore index 44eb39b3..d11348c1 100644 --- a/.gitignore +++ b/.gitignore @@ -12,3 +12,5 @@ etc/**/*.zbin !.vscode/extensions.json !.vscode/launch.json !.vscode/tasks.json + +*.log \ No newline at end of file diff --git a/Cargo.lock b/Cargo.lock index f4bb180d..3201955d 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1779,11 +1779,13 @@ dependencies = [ "jsonrpc-derive", "jsonrpc-http-server", "lazy_static", + "log", "once_cell", "openssl-sys", "reqwest", "serde", "serde_json", + "simplelog", "tokio", "tracing", "tracing-subscriber", @@ -3932,6 +3934,15 @@ dependencies = [ "syn 2.0.29", ] +[[package]] +name = "num_threads" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2819ce041d2ee131036f4fc9d6ae7ae125a3a40e97ba64d04fe799ad9dabbb44" +dependencies = [ + "libc", +] + [[package]] name = "object" version = "0.31.1" @@ -5717,6 +5728,17 @@ dependencies = [ "time 0.3.25", ] +[[package]] +name = "simplelog" +version = "0.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "acee08041c5de3d5048c8b3f6f13fafb3026b24ba43c6a695a0c76179b844369" +dependencies = [ + "log", + "termcolor", + "time 0.3.25", +] + [[package]] name = "skeptic" version = "0.13.7" @@ -6101,9 +6123,9 @@ dependencies = [ [[package]] name = "termcolor" -version = "1.2.0" +version = "1.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "be55cf8942feac5c765c2c993422806843c9a9a45d4d5c407ad6dd2ea95eb9b6" +checksum = "bab24d30b911b2376f3a13cc2cd443142f0c81dda04c118693e35b3835757755" dependencies = [ "winapi-util", ] @@ -6196,6 +6218,8 @@ checksum = "b0fdd63d58b18d663fbdf70e049f00a22c8e42be082203be7f26589213cd75ea" dependencies = [ "deranged", "itoa", + "libc", + "num_threads", "serde", "time-core", "time-macros", diff --git a/Cargo.toml b/Cargo.toml index 4ea22c24..c7f3c1c7 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -44,4 +44,6 @@ serde_json = "1.0.67" bigdecimal = { version = "0.2.0" } hex = "0.4" ethabi = "16.0.0" -itertools = "0.10.5" \ No newline at end of file +itertools = "0.10.5" +log = "0.4.20" +simplelog = "0.12.1" diff --git a/README.md b/README.md index dd34878e..00ae513e 100644 --- a/README.md +++ b/README.md @@ -55,6 +55,17 @@ Please note that `era-test-node` is still in its **alpha** stage. Some features ```bash era_test_node run ``` +## šŸ“ƒ Logging + +The node may be started in either of `debug`, `info`, `warn` or `error` logging levels via the `--log` option: +```bash +era_test_node --log=error run +``` + +Additionally, the file path can be provided via the `--log-file-path` option (defaults to `./era_test_node.log`): +```bash +era_test_node --log=error --log-file-path=run.log run +``` ## šŸŒ Network Details diff --git a/src/console_log.rs b/src/console_log.rs index c56fc62c..d21c9e6d 100644 --- a/src/console_log.rs +++ b/src/console_log.rs @@ -68,6 +68,6 @@ impl ConsoleLogHandler { tokens.iter().map(|t| format!("{}", t)).join(" ") }) }); - println!("{}", message.cyan()); + log::info!("{}", message.cyan()); } } diff --git a/src/fork.rs b/src/fork.rs index dd6cfc16..6b81ad53 100644 --- a/src/fork.rs +++ b/src/fork.rs @@ -75,7 +75,7 @@ impl ForkStorage { .as_ref() .and_then(|d| d.overwrite_chain_id) .unwrap_or(L2ChainId(TEST_NODE_NETWORK_ID)); - println!("Starting network with chain id: {:?}", chain_id); + log::info!("Starting network with chain id: {:?}", chain_id); ForkStorage { inner: Arc::new(RwLock::new(ForkStorageInner { @@ -239,7 +239,7 @@ impl ForkDetails { let l1_batch_number = block_details.l1_batch_number; - println!( + log::info!( "Creating fork from {:?} L1 block: {:?} L2 block: {:?} with timestamp {:?} and L1 gas price {:?}", url, l1_batch_number, miniblock, block_details.base.timestamp, block_details.base.l1_gas_price, ); diff --git a/src/formatter.rs b/src/formatter.rs index d6beb68d..7060ab6e 100644 --- a/src/formatter.rs +++ b/src/formatter.rs @@ -72,7 +72,7 @@ pub fn print_event(event: &VmEvent, resolve_hashes: bool) { } } - println!( + log::info!( "{} {}", address_to_human_readable(event.address) .map(|x| format!("{:42}", x.blue())) @@ -150,9 +150,9 @@ pub fn print_call(call: &Call, padding: usize, show_calls: &ShowCalls, resolve_h ); if call.revert_reason.as_ref().is_some() || call.error.as_ref().is_some() { - println!("{}", pretty_print.on_red()); + log::info!("{}", pretty_print.on_red()); } else { - println!("{}", pretty_print); + log::info!("{}", pretty_print); } } for subcall in &call.calls { @@ -162,44 +162,48 @@ pub fn print_call(call: &Call, padding: usize, show_calls: &ShowCalls, resolve_h pub fn print_logs(log_query: &StorageLogQuery) { let separator = "ā”€".repeat(82); - println!("{:<15} {:?}", "Type:", log_query.log_type); - println!( + log::info!("{:<15} {:?}", "Type:", log_query.log_type); + log::info!( "{:<15} {}", "Address:", address_to_human_readable(log_query.log_query.address) .unwrap_or(format!("{}", log_query.log_query.address)) ); - println!("{:<15} {:#066x}", "Key:", log_query.log_query.key); + log::info!("{:<15} {:#066x}", "Key:", log_query.log_query.key); - println!( + log::info!( "{:<15} {:#066x}", - "Read Value:", log_query.log_query.read_value + "Read Value:", + log_query.log_query.read_value ); if log_query.log_type != StorageLogQueryType::Read { - println!( + log::info!( "{:<15} {:#066x}", - "Written Value:", log_query.log_query.written_value + "Written Value:", + log_query.log_query.written_value ); } - println!("{}", separator); + log::info!("{}", separator); } pub fn print_vm_details(result: &VmPartialExecutionResult) { - println!("\nā”Œā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”"); - println!("ā”‚ VM EXECUTION RESULTS ā”‚"); - println!("ā””ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”˜"); + log::info!(""); + log::info!("ā”Œā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”"); + log::info!("ā”‚ VM EXECUTION RESULTS ā”‚"); + log::info!("ā””ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”˜"); - println!("Cycles Used: {}", result.cycles_used); - println!("Computation Gas Used: {}", result.computational_gas_used); - println!("Contracts Used: {}", result.contracts_used); + log::info!("Cycles Used: {}", result.cycles_used); + log::info!("Computation Gas Used: {}", result.computational_gas_used); + log::info!("Contracts Used: {}", result.contracts_used); if let Some(revert_reason) = &result.revert_reason { - println!( + log::info!(""); + log::info!( "{}", - format!("\n[!] Revert Reason: {}", revert_reason).on_red() + format!("[!] Revert Reason: {}", revert_reason).on_red() ); } - println!("ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•"); + log::info!("ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•"); } diff --git a/src/main.rs b/src/main.rs index 5d8f6c2d..4ca2990d 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,10 +1,13 @@ use crate::hardhat::{HardhatNamespaceImpl, HardhatNamespaceT}; use crate::node::{ShowGasDetails, ShowStorageLogs, ShowVMDetails}; -use clap::{Parser, Subcommand}; +use clap::{Parser, Subcommand, ValueEnum}; use configuration_api::ConfigurationApiNamespaceT; use evm::{EvmNamespaceImpl, EvmNamespaceT}; use fork::{ForkDetails, ForkSource}; use node::ShowCalls; +use simplelog::{ + ColorChoice, CombinedLogger, ConfigBuilder, LevelFilter, TermLogger, TerminalMode, WriteLogger, +}; use zks::ZkMockNamespaceImpl; mod bootloader_debug; @@ -27,6 +30,7 @@ use zksync_core::api_server::web3::namespaces::NetNamespace; use std::{ env, + fs::File, net::{IpAddr, Ipv4Addr, SocketAddr}, str::FromStr, }; @@ -135,6 +139,26 @@ async fn build_json_http< tokio::spawn(recv.map(drop)) } +/// Log filter level for the node. +#[derive(Debug, Clone, ValueEnum)] +enum LogLevel { + Debug, + Info, + Warn, + Error, +} + +impl From for LevelFilter { + fn from(value: LogLevel) -> Self { + match value { + LogLevel::Debug => LevelFilter::Debug, + LogLevel::Info => LevelFilter::Info, + LogLevel::Warn => LevelFilter::Warn, + LogLevel::Error => LevelFilter::Error, + } + } +} + #[derive(Debug, Parser)] #[command(author = "Matter Labs", version, about = "Test Node", long_about = None)] struct Cli { @@ -165,6 +189,14 @@ struct Cli { #[arg(long)] /// If true, will load the locally compiled system contracts (useful when doing changes to system contracts or bootloader) dev_use_local_contracts: bool, + + /// Log filter level - default: info + #[arg(long, default_value = "info")] + log: LogLevel, + + /// Log file path - default: era_test_node.log + #[arg(long, default_value = "era_test_node.log")] + log_file_path: String, } #[derive(Debug, Subcommand)] @@ -210,14 +242,33 @@ struct ReplayArgs { #[tokio::main] async fn main() -> anyhow::Result<()> { let opt = Cli::parse(); - let filter = EnvFilter::from_default_env(); + + let log_level_filter = LevelFilter::from(opt.log); + let log_config = ConfigBuilder::new() + .add_filter_allow_str("era_test_node") + .build(); + CombinedLogger::init(vec![ + TermLogger::new( + log_level_filter, + log_config.clone(), + TerminalMode::Mixed, + ColorChoice::Auto, + ), + WriteLogger::new( + log_level_filter, + log_config, + File::create(opt.log_file_path).unwrap(), + ), + ]) + .expect("failed instantiating logger"); if opt.dev_use_local_contracts { if let Some(path) = env::var_os("ZKSYNC_HOME") { - println!("+++++ Reading local contracts from {:?} +++++", path); + log::info!("+++++ Reading local contracts from {:?} +++++", path); } } + let filter = EnvFilter::from_default_env(); let subscriber = FmtSubscriber::builder() .with_max_level(Level::TRACE) .with_env_filter(filter) @@ -265,14 +316,15 @@ async fn main() -> anyhow::Result<()> { let _ = node.apply_txs(transactions_to_replay); } - println!("\nRich Accounts"); - println!("============="); + log::info!("Rich Accounts"); + log::info!("============="); for (index, wallet) in RICH_WALLETS.iter().enumerate() { let address = wallet.0; let private_key = wallet.1; node.set_rich_account(H160::from_str(address).unwrap()); - println!("Account #{}: {} (1_000_000_000_000 ETH)", index, address); - println!("Private Key: {}\n", private_key); + log::info!("Account #{}: {} (1_000_000_000_000 ETH)", index, address); + log::info!("Private Key: {}", private_key); + log::info!(""); } let net = NetNamespace::new(L2ChainId(TEST_NODE_NETWORK_ID)); @@ -292,9 +344,9 @@ async fn main() -> anyhow::Result<()> { ) .await; - println!("========================================"); - println!(" Node is ready at 127.0.0.1:{}", opt.port); - println!("========================================"); + log::info!("========================================"); + log::info!(" Node is ready at 127.0.0.1:{}", opt.port); + log::info!("========================================"); future::select_all(vec![threads]).await.0.unwrap(); diff --git a/src/node.rs b/src/node.rs index c6352452..35924ac7 100644 --- a/src/node.rs +++ b/src/node.rs @@ -408,8 +408,8 @@ impl InMemoryNodeInner { match estimate_gas_result { Err(tx_revert_reason) => { - println!("{}", format!("Unable to estimate gas for the request with our suggested gas limit of {}. The transaction is most likely unexecutable. Breakdown of estimation:", suggested_gas_limit + overhead).red()); - println!( + log::info!("{}", format!("Unable to estimate gas for the request with our suggested gas limit of {}. The transaction is most likely unexecutable. Breakdown of estimation:", suggested_gas_limit + overhead).red()); + log::info!( "{}", format!( "\tEstimated transaction body gas cost: {}", @@ -417,11 +417,11 @@ impl InMemoryNodeInner { ) .red() ); - println!( + log::info!( "{}", format!("\tGas for pubdata: {}", gas_for_bytecodes_pubdata).red() ); - println!("{}", format!("\tOverhead: {}", overhead).red()); + log::info!("{}", format!("\tOverhead: {}", overhead).red()); let message = tx_revert_reason.to_string(); let pretty_message = format!( "execution reverted{}{}", @@ -433,7 +433,7 @@ impl InMemoryNodeInner { TxRevertReason::TxReverted(vm_revert_reason) => vm_revert_reason.encoded_data(), _ => vec![], }; - println!("{}", pretty_message.on_red()); + log::info!("{}", pretty_message.on_red()); Err(into_jsrpc_error(Web3Error::SubmitTransactionError( pretty_message, data, @@ -445,8 +445,8 @@ impl InMemoryNodeInner { { (value, false) => value, (_, true) => { - println!("{}", "Overflow when calculating gas estimation. We've exceeded the block gas limit by summing the following values:".red()); - println!( + log::info!("{}", "Overflow when calculating gas estimation. We've exceeded the block gas limit by summing the following values:".red()); + log::info!( "{}", format!( "\tEstimated transaction body gas cost: {}", @@ -454,11 +454,11 @@ impl InMemoryNodeInner { ) .red() ); - println!( + log::info!( "{}", format!("\tGas for pubdata: {}", gas_for_bytecodes_pubdata).red() ); - println!("{}", format!("\tOverhead: {}", overhead).red()); + log::info!("{}", format!("\tOverhead: {}", overhead).red()); return Err(into_jsrpc_error(Web3Error::SubmitTransactionError( "exceeds block gas limit".into(), Default::default(), @@ -560,7 +560,7 @@ impl InMemoryNodeInner { fn not_implemented( method_name: &str, ) -> jsonrpc_core::BoxFuture> { - println!("Method {} is not implemented", method_name); + log::info!("Method {} is not implemented", method_name); Err(jsonrpc_core::Error { data: None, code: jsonrpc_core::ErrorCode::MethodNotFound, @@ -643,7 +643,7 @@ impl InMemoryNode { /// Applies multiple transactions - but still one per L1 batch. pub fn apply_txs(&self, txs: Vec) -> Result<(), String> { - println!("Running {:?} transactions (one per batch)", txs.len()); + log::info!("Running {:?} transactions (one per batch)", txs.len()); for tx in txs { self.run_l2_tx(tx, TxExecutionMode::VerifyExecute)?; @@ -659,7 +659,7 @@ impl InMemoryNode { let mut inner = match self.inner.write() { Ok(guard) => guard, Err(e) => { - println!("Failed to acquire write lock: {}", e); + log::info!("Failed to acquire write lock: {}", e); return; } }; @@ -713,17 +713,17 @@ impl InMemoryNode { vm.execute_till_block_end_with_call_tracer(BootloaderJobType::TransactionExecution); if let Some(revert_reason) = &vm_block_result.full_result.revert_reason { - println!("Call {} {:?}", "FAILED".red(), revert_reason.revert_reason); + log::info!("Call {} {:?}", "FAILED".red(), revert_reason.revert_reason); } else { - println!("Call {}", "SUCCESS".green()); + log::info!("Call {}", "SUCCESS".green()); } if let VmTrace::CallTrace(call_trace) = &vm_block_result.full_result.trace { - println!("=== Console Logs: "); + log::info!("=== Console Logs: "); for call in call_trace { inner.console_log_handler.handle_call_recurive(call); } - println!("=== Call traces:"); + log::info!("=== Call traces:"); for call in call_trace { formatter::print_call(call, 0, &inner.show_calls, inner.resolve_hashes); } @@ -739,9 +739,9 @@ impl InMemoryNode { ) -> eyre::Result<()> { let debug = BootloaderDebug::load_from_memory(vm)?; - println!("ā”Œā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”"); - println!("ā”‚ GAS DETAILS ā”‚"); - println!("ā””ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”˜"); + log::info!("ā”Œā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”"); + log::info!("ā”‚ GAS DETAILS ā”‚"); + log::info!("ā””ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”˜"); // Total amount of gas (should match tx.gas_limit). let total_gas_limit = debug @@ -759,7 +759,7 @@ impl InMemoryNode { + debug.gas_spent_on_bytecode_preparation + gas_spent_on_compute; - println!( + log::info!( "Gas - Limit: {} | Used: {} | Refunded: {}", to_human_size(total_gas_limit), to_human_size(gas_used), @@ -767,7 +767,7 @@ impl InMemoryNode { ); if debug.total_gas_limit_from_user != total_gas_limit { - println!( + log::info!( "{}", format!( " WARNING: user actually provided more gas {}, but system had a lower max limit.", @@ -777,7 +777,7 @@ impl InMemoryNode { ); } if debug.refund_computed != debug.refund_by_operator { - println!( + log::info!( "{}", format!( " WARNING: Refund by VM: {}, but operator refunded more: {}", @@ -789,7 +789,7 @@ impl InMemoryNode { } if debug.refund_computed + gas_used != total_gas_limit { - println!( + log::info!( "{}", format!( " WARNING: Gas totals don't match. {} != {} , delta: {}", @@ -803,54 +803,57 @@ impl InMemoryNode { let bytes_published = spent_on_pubdata / debug.gas_per_pubdata.as_u32(); - println!( + log::info!( "During execution published {} bytes to L1, @{} each - in total {} gas", to_human_size(bytes_published.into()), to_human_size(debug.gas_per_pubdata), to_human_size(spent_on_pubdata.into()) ); - println!("Out of {} gas used, we spent:", to_human_size(gas_used)); - println!( + log::info!("Out of {} gas used, we spent:", to_human_size(gas_used)); + log::info!( " {:>15} gas ({:>2}%) for transaction setup", to_human_size(intrinsic_gas), to_human_size(intrinsic_gas * 100 / gas_used) ); - println!( + log::info!( " {:>15} gas ({:>2}%) for bytecode preparation (decompression etc)", to_human_size(debug.gas_spent_on_bytecode_preparation), to_human_size(debug.gas_spent_on_bytecode_preparation * 100 / gas_used) ); - println!( + log::info!( " {:>15} gas ({:>2}%) for account validation", to_human_size(gas_for_validation), to_human_size(gas_for_validation * 100 / gas_used) ); - println!( + log::info!( " {:>15} gas ({:>2}%) for computations (opcodes)", to_human_size(gas_spent_on_compute), to_human_size(gas_spent_on_compute * 100 / gas_used) ); - println!( - "\n\n {}", + log::info!(""); + log::info!(""); + log::info!( + "{}", "=== Transaction setup cost breakdown ===".to_owned().bold(), ); - println!("Total cost: {}", to_human_size(intrinsic_gas).bold()); - println!( + log::info!("Total cost: {}", to_human_size(intrinsic_gas).bold()); + log::info!( " {:>15} gas ({:>2}%) fixed cost", to_human_size(debug.intrinsic_overhead), to_human_size(debug.intrinsic_overhead * 100 / intrinsic_gas) ); - println!( + log::info!( " {:>15} gas ({:>2}%) operator cost", to_human_size(debug.operator_overhead), to_human_size(debug.operator_overhead * 100 / intrinsic_gas) ); - println!( - "\n FYI: operator could have charged up to: {}, so you got {}% discount", + log::info!(""); + log::info!( + " FYI: operator could have charged up to: {}, so you got {}% discount", to_human_size(debug.required_overhead), to_human_size( (debug.required_overhead - debug.operator_overhead) * 100 / debug.required_overhead @@ -858,24 +861,24 @@ impl InMemoryNode { ); let publish_block_l1_bytes = BLOCK_OVERHEAD_PUBDATA; - println!( + log::info!( "Publishing full block costs the operator up to: {}, where {} is due to {} bytes published to L1", to_human_size(debug.total_overhead_for_block), to_human_size(debug.gas_per_pubdata * publish_block_l1_bytes), to_human_size(publish_block_l1_bytes.into()) ); - println!("Your transaction has contributed to filling up the block in the following way (we take the max contribution as the cost):"); - println!( + log::info!("Your transaction has contributed to filling up the block in the following way (we take the max contribution as the cost):"); + log::info!( " Circuits overhead:{:>15} ({}% of the full block: {})", to_human_size(debug.overhead_for_circuits), to_human_size(debug.overhead_for_circuits * 100 / debug.total_overhead_for_block), to_human_size(debug.total_overhead_for_block) ); - println!( + log::info!( " Length overhead: {:>15}", to_human_size(debug.overhead_for_length) ); - println!( + log::info!( " Slot overhead: {:>15}", to_human_size(debug.overhead_for_slot) ); @@ -927,21 +930,18 @@ impl InMemoryNode { let spent_on_pubdata = vm.state.local_state.spent_pubdata_counter - spent_on_pubdata_before; - println!("ā”Œā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”"); - println!("ā”‚ TRANSACTION SUMMARY ā”‚"); - println!("ā””ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”˜"); + log::info!("ā”Œā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”"); + log::info!("ā”‚ TRANSACTION SUMMARY ā”‚"); + log::info!("ā””ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”˜"); match tx_result.status { - TxExecutionStatus::Success => println!("Transaction: {}", "SUCCESS".green()), - TxExecutionStatus::Failure => println!("Transaction: {}", "FAILED".red()), + TxExecutionStatus::Success => log::info!("Transaction: {}", "SUCCESS".green()), + TxExecutionStatus::Failure => log::info!("Transaction: {}", "FAILED".red()), } - println!( - "Initiator: {:?}\nPayer: {:?}", - tx.initiator_account(), - tx.payer() - ); - println!( + log::info!("Initiator: {:?}", tx.initiator_account()); + log::info!("Payer: {:?}", tx.payer()); + log::info!( "Gas - Limit: {} | Used: {} | Refunded: {}", to_human_size(tx.gas_limit()), to_human_size(tx.gas_limit() - tx_result.gas_refunded), @@ -949,7 +949,7 @@ impl InMemoryNode { ); match inner.show_gas_details { - ShowGasDetails::None => println!( + ShowGasDetails::None => log::info!( "Use --show-gas-details flag or call config_setShowGasDetails to display more info" ), ShowGasDetails::All => { @@ -957,7 +957,7 @@ impl InMemoryNode { .display_detailed_gas_info(&vm, spent_on_pubdata) .is_err() { - println!( + log::info!( "{}", "!!! FAILED TO GET DETAILED GAS INFO !!!".to_owned().red() ); @@ -966,9 +966,10 @@ impl InMemoryNode { } if inner.show_storage_logs != ShowStorageLogs::None { - println!("\nā”Œā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”"); - println!("ā”‚ STORAGE LOGS ā”‚"); - println!("ā””ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”˜"); + log::info!(""); + log::info!("ā”Œā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”"); + log::info!("ā”‚ STORAGE LOGS ā”‚"); + log::info!("ā””ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”˜"); } for log_query in &tx_result.result.logs.storage_logs { @@ -997,13 +998,15 @@ impl InMemoryNode { formatter::print_vm_details(&tx_result.result); } - println!("\n==== Console logs: "); + log::info!(""); + log::info!("==== Console logs: "); for call in &tx_result.call_traces { inner.console_log_handler.handle_call_recurive(call); } - println!( - "\n==== {} Use --show-calls flag or call config_setShowCalls to display more info.", + log::info!(""); + log::info!( + "==== {} Use --show-calls flag or call config_setShowCalls to display more info.", format!("{:?} call traces. ", tx_result.call_traces.len()).bold() ); @@ -1013,15 +1016,17 @@ impl InMemoryNode { } } - println!( - "\n==== {}", + log::info!(""); + log::info!( + "==== {}", format!("{} events", tx_result.result.logs.events.len()).bold() ); for event in &tx_result.result.logs.events { formatter::print_event(event, inner.resolve_hashes); } - println!("\n\n"); + log::info!(""); + log::info!(""); vm.execute_till_block_end(BootloaderJobType::BlockPostprocessing); @@ -1039,7 +1044,8 @@ impl InMemoryNode { /// Runs L2 transaction and commits it to a new block. fn run_l2_tx(&self, l2_tx: L2Tx, execution_mode: TxExecutionMode) -> Result<(), String> { let tx_hash = l2_tx.hash(); - println!("\nExecuting {}", format!("{:?}", tx_hash).bold()); + log::info!(""); + log::info!("Executing {}", format!("{:?}", tx_hash).bold()); let (keys, result, block, bytecodes) = self.run_l2_tx_inner(l2_tx.clone(), execution_mode)?; // Write all the mutated keys (storage slots). @@ -1132,7 +1138,7 @@ impl EthNamespaceT for } _ => vec![], }; - println!("{}", pretty_message.on_red()); + log::info!("{}", pretty_message.on_red()); Err(into_jsrpc_error(Web3Error::SubmitTransactionError( pretty_message, data, @@ -1231,13 +1237,13 @@ impl EthNamespaceT for match block_number { zksync_types::api::BlockNumber::Earliest => { - println!( + log::info!( "Method get_block_by_number with BlockNumber::Earliest is not implemented" ); return Err(into_jsrpc_error(Web3Error::NotImplemented)); } zksync_types::api::BlockNumber::Pending => { - println!( + log::info!( "Method get_block_by_number with BlockNumber::Pending is not implemented" ); return Err(into_jsrpc_error(Web3Error::NotImplemented)); @@ -1245,7 +1251,7 @@ impl EthNamespaceT for zksync_types::api::BlockNumber::Number(ask_number) if ask_number != U64::from(reader.current_miniblock) => { - println!("Method get_block_by_number with BlockNumber::Number({}) is not implemented", ask_number); + log::info!("Method get_block_by_number with BlockNumber::Number({}) is not implemented", ask_number); return Err(into_jsrpc_error(Web3Error::NotImplemented)); } _ => {} diff --git a/src/zks.rs b/src/zks.rs index b9a84ae7..91e0926e 100644 --- a/src/zks.rs +++ b/src/zks.rs @@ -134,7 +134,7 @@ impl ZksNamespaceT Ok(1.into()).into_boxed_future() } address => { - println!( + log::error!( "{}", format!("Token price requested for unknown address {:?}", address).red() );