@@ -104,48 +104,64 @@ impl CallInfo {
104
104
)
105
105
}
106
106
107
- /// Yields the contract calls in DFS (preorder).
107
+ /// Returns the contract calls in DFS (preorder).
108
108
pub fn gen_call_topology ( & self ) -> Vec < CallInfo > {
109
109
let mut calls = Vec :: new ( ) ;
110
- if self . internal_calls . is_empty ( ) {
111
- calls. push ( self . clone ( ) )
112
- } else {
113
- calls. push ( self . clone ( ) ) ;
114
- for call_info in self . internal_calls . clone ( ) {
115
- calls. extend ( call_info. gen_call_topology ( ) ) ;
110
+ // add the current call
111
+ calls. push ( self . clone ( ) ) ;
112
+
113
+ // if it has internal calls we need to add them too.
114
+ if !self . internal_calls . is_empty ( ) {
115
+ for inner_call in self . internal_calls . clone ( ) {
116
+ calls. extend ( inner_call. gen_call_topology ( ) ) ;
116
117
}
117
118
}
119
+
118
120
calls
119
121
}
120
122
121
- /// Returns a list of Starknet Event objects collected during the execution, sorted by the order
123
+ /// Returns a list of [` Event`] objects collected during the execution, sorted by the order
122
124
/// in which they were emitted.
123
125
pub fn get_sorted_events ( & self ) -> Result < Vec < Event > , TransactionError > {
126
+ // collect a vector of the full call topology (all the internal
127
+ // calls performed during the current call)
124
128
let calls = self . gen_call_topology ( ) ;
125
- let n_events = calls. iter ( ) . fold ( 0 , |acc, c| acc + c. events . len ( ) ) ;
126
-
127
- let mut starknet_events: Vec < Option < Event > > = ( 0 ..n_events) . map ( |_| None ) . collect ( ) ;
128
-
129
- for call in calls {
130
- for ordered_event in call. events {
131
- let event = Event :: new ( ordered_event. clone ( ) , call. contract_address . clone ( ) ) ;
132
- starknet_events. remove ( ( ordered_event. order as isize - 1 ) . max ( 0 ) as usize ) ;
133
- starknet_events. insert (
134
- ( ordered_event. order as isize - 1 ) . max ( 0 ) as usize ,
135
- Some ( event) ,
136
- ) ;
129
+ let mut collected_events = Vec :: new ( ) ;
130
+
131
+ // for each call, collect its ordered events
132
+ for c in calls {
133
+ collected_events. extend (
134
+ c. events
135
+ . iter ( )
136
+ . map ( |oe| ( oe. clone ( ) , c. contract_address . clone ( ) ) ) ,
137
+ ) ;
138
+ }
139
+ // sort the collected events using the ordering given by the order
140
+ collected_events. sort_by_key ( |( oe, _) | oe. order ) ;
141
+
142
+ // check that there is no holes.
143
+ // since it is already sorted, we only need to check for continuity
144
+ let mut i = 0 ;
145
+ for ( oe, _) in collected_events. iter ( ) {
146
+ if i == oe. order {
147
+ continue ;
148
+ }
149
+ i += 1 ;
150
+ if i != oe. order {
151
+ return Err ( TransactionError :: UnexpectedHolesInEventOrder ) ;
137
152
}
138
153
}
139
154
140
- let are_all_some = starknet_events. iter ( ) . all ( |e| e. is_some ( ) ) ;
141
-
142
- if !are_all_some {
143
- return Err ( TransactionError :: UnexpectedHolesInEventOrder ) ;
144
- }
145
- Ok ( starknet_events. into_iter ( ) . flatten ( ) . collect ( ) )
155
+ // now that it is ordered and without holes, we can discard the order and
156
+ // convert each [`OrderedEvent`] to the underlying [`Event`].
157
+ let collected_events = collected_events
158
+ . into_iter ( )
159
+ . map ( |( oe, ca) | Event :: new ( oe, ca) )
160
+ . collect ( ) ;
161
+ Ok ( collected_events)
146
162
}
147
163
148
- /// Returns a list of Starknet L2ToL1MessageInfo objects collected during the execution, sorted
164
+ /// Returns a list of L2ToL1MessageInfo objects collected during the execution, sorted
149
165
/// by the order in which they were sent.
150
166
pub fn get_sorted_l2_to_l1_messages ( & self ) -> Result < Vec < L2toL1MessageInfo > , TransactionError > {
151
167
let calls = self . gen_call_topology ( ) ;
@@ -586,6 +602,8 @@ impl TransactionExecutionInfo {
586
602
} )
587
603
}
588
604
605
+ /// Returns an ordered vector with all the event emitted during the transaction.
606
+ /// Including the ones emitted by internal calls.
589
607
pub fn get_sorted_events ( & self ) -> Result < Vec < Event > , TransactionError > {
590
608
let calls = self . non_optional_calls ( ) ;
591
609
let mut sorted_events: Vec < Event > = Vec :: new ( ) ;
@@ -838,7 +856,7 @@ mod tests {
838
856
839
857
call_root. internal_calls = [ child1, child2] . to_vec ( ) ;
840
858
841
- assert ! ( call_root. get_sorted_events( ) . is_err ( ) )
859
+ assert ! ( call_root. get_sorted_events( ) . is_ok ( ) )
842
860
}
843
861
844
862
#[ test]
0 commit comments