From 00826cf36f740ebc4664827942044cf57072db6c Mon Sep 17 00:00:00 2001 From: Willem Wyndham Date: Sun, 4 Aug 2024 20:48:29 -0400 Subject: [PATCH] feat: separate out different events to only log user defined ones by default (#1394) * feat: separate contract events from diagnostic * feat: separate out log events * fix: fmt * fix: clippy --- .../tests/it/integration/hello_world.rs | 22 ++++++++++ .../src/commands/contract/invoke.rs | 10 +++-- cmd/soroban-cli/src/log.rs | 15 ++++++- cmd/soroban-cli/src/log/diagnostic_event.rs | 11 ----- cmd/soroban-cli/src/log/event.rs | 44 +++++++++++++++++++ 5 files changed, 86 insertions(+), 16 deletions(-) delete mode 100644 cmd/soroban-cli/src/log/diagnostic_event.rs create mode 100644 cmd/soroban-cli/src/log/event.rs diff --git a/cmd/crates/soroban-test/tests/it/integration/hello_world.rs b/cmd/crates/soroban-test/tests/it/integration/hello_world.rs index 25e00f093..7cdc77b3e 100644 --- a/cmd/crates/soroban-test/tests/it/integration/hello_world.rs +++ b/cmd/crates/soroban-test/tests/it/integration/hello_world.rs @@ -134,6 +134,7 @@ async fn invoke() { handles_kebab_case(sandbox, id).await; fetch(sandbox, id).await; invoke_prng_u64_in_range_test(sandbox, id).await; + invoke_log(sandbox, id); } fn invoke_hello_world(sandbox: &TestEnv, id: &str) { @@ -381,3 +382,24 @@ async fn invoke_prng_u64_in_range_test(sandbox: &TestEnv, id: &str) { .await .is_ok()); } +fn invoke_log(sandbox: &TestEnv, id: &str) { + sandbox + .new_assert_cmd("contract") + .arg("invoke") + .arg("--id") + .arg(id) + .arg("--") + .arg("log") + .arg("--str=world") + .assert() + .success() + .stderr(predicates::str::contains( + "INFO contract_event: soroban_cli::log::event: 1: DiagnosticEvent {", + )) + .stderr(predicates::str::contains("StringM(hello)")) + .stderr(predicates::str::contains( + "INFO log_event: soroban_cli::log::event: 2: DiagnosticEvent", + )) + .stderr(predicates::str::contains("StringM(hello {})")) + .stderr(predicates::str::contains("StringM(world)")); +} diff --git a/cmd/soroban-cli/src/commands/contract/invoke.rs b/cmd/soroban-cli/src/commands/contract/invoke.rs index 041613ba2..6d0a0799b 100644 --- a/cmd/soroban-cli/src/commands/contract/invoke.rs +++ b/cmd/soroban-cli/src/commands/contract/invoke.rs @@ -386,10 +386,14 @@ impl NetworkRunnable for Cmd { if !no_cache { data::write(res.clone().try_into()?, &network.rpc_uri()?)?; } - (res.return_value()?, res.contract_events()?) + let events = res + .result_meta + .as_ref() + .map(crate::log::extract_events) + .unwrap_or_default(); + (res.return_value()?, events) }; - - crate::log::diagnostic_events(&events, tracing::Level::INFO); + crate::log::events(&events); output_to_string(&spec, &return_value, &function) } } diff --git a/cmd/soroban-cli/src/log.rs b/cmd/soroban-cli/src/log.rs index 16121982d..28ed4041b 100644 --- a/cmd/soroban-cli/src/log.rs +++ b/cmd/soroban-cli/src/log.rs @@ -1,13 +1,24 @@ +use crate::xdr; pub mod auth; pub mod budget; pub mod cost; -pub mod diagnostic_event; +pub mod event; pub mod footprint; pub mod host_event; pub use auth::*; pub use budget::*; pub use cost::*; -pub use diagnostic_event::*; +pub use event::*; pub use footprint::*; pub use host_event::*; + +pub fn extract_events(tx_meta: &xdr::TransactionMeta) -> Vec { + match tx_meta { + xdr::TransactionMeta::V3(xdr::TransactionMetaV3 { + soroban_meta: Some(meta), + .. + }) => meta.diagnostic_events.to_vec(), + _ => Vec::new(), + } +} diff --git a/cmd/soroban-cli/src/log/diagnostic_event.rs b/cmd/soroban-cli/src/log/diagnostic_event.rs deleted file mode 100644 index 68af67a4e..000000000 --- a/cmd/soroban-cli/src/log/diagnostic_event.rs +++ /dev/null @@ -1,11 +0,0 @@ -pub fn diagnostic_events(events: &[impl std::fmt::Debug], level: tracing::Level) { - for (i, event) in events.iter().enumerate() { - if level == tracing::Level::TRACE { - tracing::trace!("{i}: {event:#?}"); - } else if level == tracing::Level::INFO { - tracing::info!("{i}: {event:#?}"); - } else if level == tracing::Level::ERROR { - tracing::error!("{i}: {event:#?}"); - } - } -} diff --git a/cmd/soroban-cli/src/log/event.rs b/cmd/soroban-cli/src/log/event.rs new file mode 100644 index 000000000..8a4fedfbf --- /dev/null +++ b/cmd/soroban-cli/src/log/event.rs @@ -0,0 +1,44 @@ +use tracing::{debug, info, span, Level}; + +use crate::xdr; + +pub fn events(events: &[xdr::DiagnosticEvent]) { + for (i, event) in events.iter().enumerate() { + let span = if is_contract_event(event) { + span!(Level::INFO, "contract_event") + } else if is_log_event(event) { + span!(Level::INFO, "log_event") + } else { + span!(Level::DEBUG, "diagnostic_event") + }; + + let _enter = span.enter(); + + if span.metadata().unwrap().level() == &Level::INFO { + info!("{i}: {event:#?}"); + } else { + debug!("{i}: {event:#?}"); + } + } +} + +fn is_contract_event(event: &xdr::DiagnosticEvent) -> bool { + matches!(event.event.type_, xdr::ContractEventType::Contract) +} + +fn is_log_event(event: &xdr::DiagnosticEvent) -> bool { + match &event.event.body { + xdr::ContractEventBody::V0(xdr::ContractEventV0 { topics, .. }) + if topics.len() == 1 + && matches!(event.event.type_, xdr::ContractEventType::Diagnostic) => + { + topics[0] == xdr::ScVal::Symbol(str_to_sc_symbol("log")) + } + xdr::ContractEventBody::V0(_) => false, + } +} + +fn str_to_sc_symbol(s: &str) -> xdr::ScSymbol { + let inner: xdr::StringM<32> = s.try_into().unwrap(); + xdr::ScSymbol(inner) +}