From bc70f9010f79f8b10f4b890f7d9e2003fe1e3a33 Mon Sep 17 00:00:00 2001 From: Willem Wyndham Date: Wed, 19 Jun 2024 11:51:58 -0400 Subject: [PATCH] feat: separate out log events --- .../tests/it/integration/hello_world.rs | 23 ++++++++++++++ cmd/soroban-cli/src/log.rs | 31 ++++++++++++------- cmd/soroban-cli/src/log/log_event.rs | 19 ++++++++++++ 3 files changed, 62 insertions(+), 11 deletions(-) create mode 100644 cmd/soroban-cli/src/log/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 6eb3bfb0f7..2aa8ef68c1 100644 --- a/cmd/crates/soroban-test/tests/it/integration/hello_world.rs +++ b/cmd/crates/soroban-test/tests/it/integration/hello_world.rs @@ -136,6 +136,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).await; } fn invoke_hello_world(sandbox: &TestEnv, id: &str) { @@ -371,3 +372,25 @@ async fn invoke_prng_u64_in_range_test(sandbox: &TestEnv, id: &str) { .await .is_ok()); } +async 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 soroban_cli::log::contract_event: 0: DiagnosticEvent {", + )) + .stderr(predicates::str::contains("StringM(hello)")) + .stderr(predicates::str::contains( + "INFO soroban_cli::log::log_event: 0: DiagnosticEvent", + )) + .stderr(predicates::str::contains("StringM(hello {})")) + .stderr(predicates::str::contains("StringM(world)")) + ; +} diff --git a/cmd/soroban-cli/src/log.rs b/cmd/soroban-cli/src/log.rs index b3b454f185..ba13dd52ac 100644 --- a/cmd/soroban-cli/src/log.rs +++ b/cmd/soroban-cli/src/log.rs @@ -6,6 +6,7 @@ pub mod cost; pub mod diagnostic_event; pub mod footprint; pub mod host_event; +pub mod log_event; pub use auth::*; pub use budget::*; @@ -14,11 +15,15 @@ pub use cost::*; pub use diagnostic_event::*; pub use footprint::*; pub use host_event::*; +pub use log_event::*; pub fn events(events: &[xdr::DiagnosticEvent]) { let (contract_events, other_events): (Vec<_>, Vec<_>) = events.iter().partition(|e| is_contract_event(e)); contract_event::contract_events(&contract_events, tracing::Level::INFO); + let (log_events, other_events): (Vec<_>, Vec<_>) = + other_events.into_iter().partition(|e| is_log_event(e)); + log_event::log_events(&log_events, tracing::Level::INFO); diagnostic_event::diagnostic_events(&other_events, tracing::Level::DEBUG); } @@ -27,17 +32,7 @@ pub fn extract_events(tx_meta: &xdr::TransactionMeta) -> Vec { - let mut events = meta.diagnostic_events.to_vec(); - // NOTE: we assume there can only be one operation, since we only send one - if meta.events.len() >= 1 { - events.extend(meta.events.iter().map(|e| xdr::DiagnosticEvent { - in_successful_contract_call: true, - event: e.clone(), - })); - }; - events - } + }) => meta.diagnostic_events.to_vec(), _ => Vec::new(), } } @@ -45,3 +40,17 @@ pub fn extract_events(tx_meta: &xdr::TransactionMeta) -> Vec 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 => { + topics[0] == xdr::ScVal::Symbol(str_to_sc_string("log")) + } + _ => false, + } +} + +fn str_to_sc_string(s: &str) -> xdr::ScSymbol { + let inner: xdr::StringM<32> = s.try_into().unwrap(); + xdr::ScSymbol(inner) +} diff --git a/cmd/soroban-cli/src/log/log_event.rs b/cmd/soroban-cli/src/log/log_event.rs new file mode 100644 index 0000000000..76dfc54a53 --- /dev/null +++ b/cmd/soroban-cli/src/log/log_event.rs @@ -0,0 +1,19 @@ +pub fn log_events(events: &[impl std::fmt::Debug], level: tracing::Level) { + for (i, event) in events.iter().enumerate() { + match level { + tracing::Level::TRACE => { + tracing::trace!("{i}: {event:#?}"); + } + tracing::Level::INFO => { + tracing::info!("{i}: {event:#?}"); + } + tracing::Level::ERROR => { + tracing::error!("{i}: {event:#?}"); + } + tracing::Level::DEBUG => { + tracing::debug!("{i}: {event:#?}"); + } + _ => {} + } + } +}