Skip to content

Commit 887b42e

Browse files
Address review
1 parent a63addc commit 887b42e

6 files changed

Lines changed: 76 additions & 13 deletions

File tree

CHANGELOG.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
2424
- `#[should_panic(expected: (...))]` now supports regular strings inside mixed tuples, alongside short strings and numbers.
2525
- `#[derive(Fuzzable)]` macro that automatically generates `Fuzzable` trait implementations for structs and enums
2626
- `SNFOUNDRY_CACHE` environment variable to allow to specify a custom cache directory
27-
- Contract debug traces now include emitted Starknet events via the `events` trace component and `detailed` trace verbosity. A dedicated reversed data transformer decodes raw keys and values of an event into a struct-like output.
27+
- Contract debug traces now include emitted Starknet events via the `events` trace component and `detailed` trace verbosity, rendering ABI-decodable events in a struct-like format.
2828

2929
#### Changed
3030

crates/debugging/src/trace/collect.rs

Lines changed: 67 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,8 @@ use blockifier::execution::call_info::OrderedEvent;
88
use cheatnet::runtime_extensions::outer_call_runtime_extension::rpc::{CallFailure, CallSuccess};
99
use cheatnet::trace_data::{CallTrace, CallTraceNode};
1010
use data_transformer::{
11-
ReverseTransformError, reverse_transform_event, reverse_transform_input,
12-
reverse_transform_output,
11+
ReverseTransformError, ReverseTransformEventError, reverse_transform_event,
12+
reverse_transform_input, reverse_transform_output,
1313
};
1414
use starknet_api::core::ClassHash;
1515
use starknet_api::execution_utils::format_panic_data;
@@ -198,7 +198,11 @@ fn collect_event(event: &OrderedEvent, abi: &[AbiEntry]) -> Event {
198198

199199
match reverse_transform_event(&keys, &data, abi) {
200200
Ok(decoded) => Event::Decoded(decoded),
201-
Err(_) => Event::Raw { keys, data },
201+
Err(
202+
ReverseTransformEventError::EventNotFound(_)
203+
| ReverseTransformEventError::UnsupportedUntypedEvent(_),
204+
) => Event::Raw { keys, data },
205+
Err(error) => panic!("Failed to decode event: {error}"),
202206
}
203207
}
204208

@@ -216,7 +220,11 @@ mod tests {
216220
use cheatnet::trace_data::CallTrace;
217221
use starknet_api::core::{ClassHash, EntryPointSelector};
218222
use starknet_api::transaction::fields::Calldata;
219-
use starknet_rust::core::types::contract::AbiEntry;
223+
use starknet_api::transaction::{EventContent, EventData, EventKey};
224+
use starknet_rust::core::types::contract::{
225+
AbiEntry, AbiEvent, AbiEventEnum, EventField, EventFieldKind, TypedAbiEvent,
226+
};
227+
use starknet_rust::core::utils::get_selector_from_name;
220228
use starknet_types_core::felt::Felt;
221229
use std::collections::{HashMap, HashSet};
222230
use std::sync::Arc;
@@ -248,6 +256,34 @@ mod tests {
248256
Context::for_testing(store, Components::new(HashSet::new()))
249257
}
250258

259+
fn make_ordered_event(keys: Vec<Felt>, data: Vec<Felt>) -> OrderedEvent {
260+
OrderedEvent {
261+
order: 0,
262+
event: EventContent {
263+
keys: keys.into_iter().map(EventKey).collect(),
264+
data: EventData(data),
265+
},
266+
}
267+
}
268+
269+
fn typed_enum_event(name: &str, variants: &[(&str, &str, EventFieldKind)]) -> AbiEntry {
270+
AbiEntry::Event(AbiEvent::Typed(TypedAbiEvent::Enum(AbiEventEnum {
271+
name: name.to_string(),
272+
variants: variants
273+
.iter()
274+
.map(|(name, ty, kind)| EventField {
275+
name: (*name).to_string(),
276+
r#type: (*ty).to_string(),
277+
kind: kind.clone(),
278+
})
279+
.collect(),
280+
})))
281+
}
282+
283+
fn selector(name: &str) -> Felt {
284+
get_selector_from_name(name).unwrap()
285+
}
286+
251287
#[test]
252288
fn collect_selector_falls_back_to_hex_when_not_in_map() {
253289
let class_hash = ClassHash::default();
@@ -331,4 +367,31 @@ mod tests {
331367
let result = collector.collect_transformed_call_result(&[]);
332368
assert_eq!(result.0, "success: 0x1, 0x2a, 0xff");
333369
}
370+
371+
#[test]
372+
fn collect_event_falls_back_to_raw_when_event_not_in_abi() {
373+
let event = make_ordered_event(vec![Felt::from(0x123)], vec![Felt::from(0x456)]);
374+
375+
let result = collect_event(&event, &[]);
376+
377+
match result {
378+
Event::Raw { keys, data } => {
379+
assert_eq!(keys, vec![Felt::from(0x123)]);
380+
assert_eq!(data, vec![Felt::from(0x456)]);
381+
}
382+
Event::Decoded(decoded) => panic!("expected raw event fallback, got {decoded}"),
383+
}
384+
}
385+
386+
#[test]
387+
#[should_panic(expected = "Failed to decode event: abi is invalid")]
388+
fn collect_event_panics_on_invalid_event_abi() {
389+
let abi = vec![typed_enum_event(
390+
"test::Event",
391+
&[("Missing", "test::MissingEvent", EventFieldKind::Nested)],
392+
)];
393+
let event = make_ordered_event(vec![selector("Missing")], vec![]);
394+
395+
collect_event(&event, &abi);
396+
}
334397
}

crates/debugging/src/trace/types.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -70,7 +70,7 @@ pub struct Events(pub Vec<Event>);
7070
pub enum Event {
7171
/// A successfully reverse-transformed event, pretty-formatted as a human-readable struct.
7272
Decoded(String),
73-
/// A fallback for legacy Cairo1 events, events from contract which is missing an ABI, etc.
73+
/// A fallback for legacy Cairo1 events, events without matching ABI entries, or non-standard raw events.
7474
Raw { keys: Vec<Felt>, data: Vec<Felt> },
7575
}
7676

crates/forge/tests/e2e/debugging.rs

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -256,7 +256,7 @@ fn detailed_debugging_trace_message(test_name: &str, package_name: &str) -> Stri
256256
│ ├─ [caller address] [..]
257257
│ ├─ [call type] Call
258258
│ ├─ [call result] success: array![RecursiveCall {{ contract_address: ContractAddress([..]), payload: array![RecursiveCall {{ contract_address: ContractAddress([..]), payload: array![] }}, RecursiveCall {{ contract_address: ContractAddress([..]), payload: array![] }}] }}, RecursiveCall {{ contract_address: ContractAddress([..]), payload: array![] }}]
259-
│ ├─ [events] [Event::CallsExecuted(CallsExecuted {{ calls_len: 0x2 }})]
259+
│ ├─ [events] [CallsExecuted {{ calls_len: 0x2 }}]
260260
│ ├─ [L2 gas] [..]
261261
│ ├─ [selector] execute_calls
262262
│ │ ├─ [contract name] SimpleContract
@@ -266,7 +266,7 @@ fn detailed_debugging_trace_message(test_name: &str, package_name: &str) -> Stri
266266
│ │ ├─ [caller address] [..]
267267
│ │ ├─ [call type] Call
268268
│ │ ├─ [call result] success: array![RecursiveCall {{ contract_address: ContractAddress([..]), payload: array![] }}, RecursiveCall {{ contract_address: ContractAddress([..]), payload: array![] }}]
269-
│ │ ├─ [events] [Event::CallsExecuted(CallsExecuted {{ calls_len: 0x2 }})]
269+
│ │ ├─ [events] [CallsExecuted {{ calls_len: 0x2 }}]
270270
│ │ ├─ [L2 gas] [..]
271271
│ │ ├─ [selector] execute_calls
272272
│ │ │ ├─ [contract name] SimpleContract
@@ -276,7 +276,7 @@ fn detailed_debugging_trace_message(test_name: &str, package_name: &str) -> Stri
276276
│ │ │ ├─ [caller address] [..]
277277
│ │ │ ├─ [call type] Call
278278
│ │ │ ├─ [call result] success: array![]
279-
│ │ │ ├─ [events] [Event::CallsExecuted(CallsExecuted {{ calls_len: 0x0 }})]
279+
│ │ │ ├─ [events] [CallsExecuted {{ calls_len: 0x0 }}]
280280
│ │ │ └─ [L2 gas] [..]
281281
│ │ └─ [selector] execute_calls
282282
│ │ ├─ [contract name] SimpleContract
@@ -286,7 +286,7 @@ fn detailed_debugging_trace_message(test_name: &str, package_name: &str) -> Stri
286286
│ │ ├─ [caller address] [..]
287287
│ │ ├─ [call type] Call
288288
│ │ ├─ [call result] success: array![]
289-
│ │ ├─ [events] [Event::CallsExecuted(CallsExecuted {{ calls_len: 0x0 }})]
289+
│ │ ├─ [events] [CallsExecuted {{ calls_len: 0x0 }}]
290290
│ │ └─ [L2 gas] [..]
291291
│ └─ [selector] execute_calls
292292
│ ├─ [contract name] SimpleContract
@@ -296,7 +296,7 @@ fn detailed_debugging_trace_message(test_name: &str, package_name: &str) -> Stri
296296
│ ├─ [caller address] [..]
297297
│ ├─ [call type] Call
298298
│ ├─ [call result] success: array![]
299-
│ ├─ [events] [Event::CallsExecuted(CallsExecuted {{ calls_len: 0x0 }})]
299+
│ ├─ [events] [CallsExecuted {{ calls_len: 0x0 }}]
300300
│ └─ [L2 gas] [..]
301301
└─ [selector] fail
302302
├─ [contract name] SimpleContract

crates/forge/tests/e2e/snapshots/debugging/main__e2e__debugging__debugging_trace_events_component_only@2.18.0.snap

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,4 +8,4 @@ expression: stdout
88
[PASS] debugging_events_integrationtest::test_trace::test_debugging_trace_events_component (l1_gas: ~0, l1_data_gas: ~96, l2_gas: ~304300)
99
[test name] debugging_events_integrationtest::test_trace::test_debugging_trace_events_component
1010
└─ [selector] emit_event
11-
└─ [events] [Event::ValueEmitted(ValueEmitted { value: 0x2a })]
11+
└─ [events] [ValueEmitted { value: 0x2a }]

crates/forge/tests/e2e/snapshots/debugging/main__e2e__debugging__debugging_trace_multiple_events_component@2.18.0.snap

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,4 +8,4 @@ expression: stdout
88
[PASS] debugging_events_integrationtest::test_trace::test_debugging_trace_multiple_events (l1_gas: ~0, l1_data_gas: ~96, l2_gas: ~332360)
99
[test name] debugging_events_integrationtest::test_trace::test_debugging_trace_multiple_events
1010
└─ [selector] emit_two_events
11-
└─ [events] [Event::ValueEmitted(ValueEmitted { value: 0x2a }), Event::ValueEmitted(ValueEmitted { value: 0x2b })]
11+
└─ [events] [ValueEmitted { value: 0x2a }, ValueEmitted { value: 0x2b }]

0 commit comments

Comments
 (0)