@@ -104,48 +104,64 @@ impl CallInfo {
104104 )
105105 }
106106
107- /// Yields the contract calls in DFS (preorder).
107+ /// Returns the contract calls in DFS (preorder).
108108 pub fn gen_call_topology ( & self ) -> Vec < CallInfo > {
109109 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 ( ) ) ;
116117 }
117118 }
119+
118120 calls
119121 }
120122
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
122124 /// in which they were emitted.
123125 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)
124128 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 ) ;
137152 }
138153 }
139154
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)
146162 }
147163
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
149165 /// by the order in which they were sent.
150166 pub fn get_sorted_l2_to_l1_messages ( & self ) -> Result < Vec < L2toL1MessageInfo > , TransactionError > {
151167 let calls = self . gen_call_topology ( ) ;
@@ -586,6 +602,8 @@ impl TransactionExecutionInfo {
586602 } )
587603 }
588604
605+ /// Returns an ordered vector with all the event emitted during the transaction.
606+ /// Including the ones emitted by internal calls.
589607 pub fn get_sorted_events ( & self ) -> Result < Vec < Event > , TransactionError > {
590608 let calls = self . non_optional_calls ( ) ;
591609 let mut sorted_events: Vec < Event > = Vec :: new ( ) ;
@@ -838,7 +856,7 @@ mod tests {
838856
839857 call_root. internal_calls = [ child1, child2] . to_vec ( ) ;
840858
841- assert ! ( call_root. get_sorted_events( ) . is_err ( ) )
859+ assert ! ( call_root. get_sorted_events( ) . is_ok ( ) )
842860 }
843861
844862 #[ test]
0 commit comments