@@ -59,6 +59,12 @@ fn get_l1_handler_message_hash(tx: &L1HandlerTransaction) -> Result<Felt, L1Hand
5959 Ok ( Felt :: from_bytes_le ( message. hash ( ) . as_bytes ( ) ) )
6060}
6161
62+ fn recursive_call_info_iter ( res : & TransactionExecutionInfo ) -> impl Iterator < Item = & CallInfo > {
63+ res
64+ . non_optional_call_infos ( ) // all root callinfos
65+ . flat_map ( |call_info| call_info. iter ( ) ) // flatmap over the roots' recursive inner call infos
66+ }
67+
6268pub fn from_blockifier_execution_info ( res : & TransactionExecutionInfo , tx : & Transaction ) -> TransactionReceipt {
6369 let price_unit = match blockifier_tx_fee_type ( tx) {
6470 FeeType :: Eth => PriceUnit :: Wei ,
@@ -68,9 +74,6 @@ pub fn from_blockifier_execution_info(res: &TransactionExecutionInfo, tx: &Trans
6874 let actual_fee = FeePayment { amount : res. transaction_receipt . fee . into ( ) , unit : price_unit } ;
6975 let transaction_hash = blockifier_tx_hash ( tx) ;
7076
71- let mut events: Vec < Event > = Vec :: new ( ) ;
72- get_events_from_call_info ( res. execute_call_info . as_ref ( ) , 0 , & mut events) ;
73-
7477 let message_hash = match tx {
7578 Transaction :: L1HandlerTransaction ( tx) => match get_l1_handler_message_hash ( tx) {
7679 Ok ( hash) => Some ( hash) ,
@@ -82,16 +85,29 @@ pub fn from_blockifier_execution_info(res: &TransactionExecutionInfo, tx: &Trans
8285 _ => None ,
8386 } ;
8487
85- let messages_sent = res
86- . non_optional_call_infos ( )
88+ let messages_sent = recursive_call_info_iter ( res)
8789 . flat_map ( |call| {
8890 call. execution . l2_to_l1_messages . iter ( ) . map ( |message| MsgToL1 {
91+ // Note: storage address here to identify the contract. Not caller address nor code address, because of delegate (library) calls.
8992 from_address : call. call . storage_address . into ( ) ,
9093 to_address : message. message . to_address . into ( ) ,
9194 payload : message. message . payload . 0 . clone ( ) ,
9295 } )
9396 } )
9497 . collect ( ) ;
98+ let events = recursive_call_info_iter ( res)
99+ . flat_map ( |call| {
100+ call. execution . events . iter ( ) . map ( |event| Event {
101+ // See above for why we use storage address.
102+ from_address : call. call . storage_address . into ( ) ,
103+ keys : event. event . keys . iter ( ) . map ( |k| k. 0 ) . collect ( ) ,
104+ data : event. event . data . 0 . clone ( ) ,
105+ } )
106+ } )
107+ . collect ( ) ;
108+
109+ // Note: these should not be iterated over recursively because they include the inner calls
110+ // We only add up the root calls here without recursing into the inner calls.
95111
96112 let get_applications = |resource| {
97113 res. non_optional_call_infos ( )
@@ -172,49 +188,9 @@ impl From<GasVector> for L1Gas {
172188 }
173189}
174190
175- /// To get all the events from the CallInfo including the inner call events.
176- fn get_events_from_call_info ( call_info : Option < & CallInfo > , next_order : usize , events_vec : & mut Vec < Event > ) -> usize {
177- let mut event_idx = 0 ;
178- let mut inner_call_idx = 0 ;
179- let mut next_order = next_order;
180-
181- let call_info = match call_info {
182- Some ( call) => call,
183- None => return 0 ,
184- } ;
185-
186- loop {
187- if event_idx < call_info. execution . events . len ( ) {
188- let ordered_event = & call_info. execution . events [ event_idx] ;
189- if ordered_event. order == next_order {
190- let event = Event {
191- from_address : call_info. call . storage_address . into ( ) ,
192- keys : ordered_event. event . keys . iter ( ) . map ( |k| k. 0 ) . collect ( ) ,
193- data : ordered_event. event . data . 0 . clone ( ) ,
194- } ;
195- events_vec. push ( event) ;
196- next_order += 1 ;
197- event_idx += 1 ;
198- continue ;
199- }
200- }
201-
202- if inner_call_idx < call_info. inner_calls . len ( ) {
203- next_order =
204- get_events_from_call_info ( Some ( & call_info. inner_calls [ inner_call_idx] ) , next_order, events_vec) ;
205- inner_call_idx += 1 ;
206- continue ;
207- }
208-
209- break ;
210- }
211-
212- next_order
213- }
214-
215191#[ cfg( test) ]
216192mod events_logic_tests {
217- use crate :: from_blockifier :: get_events_from_call_info ;
193+ use super :: * ;
218194 use crate :: Event ;
219195 use blockifier:: execution:: call_info:: { CallExecution , CallInfo , OrderedEvent } ;
220196 use rstest:: rstest;
@@ -223,17 +199,31 @@ mod events_logic_tests {
223199
224200 #[ rstest]
225201 fn test_event_ordering ( ) {
226- let mut events = Vec :: new ( ) ;
227202 let nested_calls = create_call_info (
228203 0 ,
229204 vec ! [ create_call_info(
230205 1 ,
231206 vec![ create_call_info( 2 , vec![ create_call_info( 3 , vec![ create_call_info( 4 , vec![ ] ) ] ) ] ) ] ,
232207 ) ] ,
233208 ) ;
234- get_events_from_call_info ( Some ( & nested_calls) , 0 , & mut events) ;
235-
236- let expected_events_ordering = vec ! [ event( 0 ) , event( 1 ) , event( 2 ) , event( 3 ) , event( 4 ) ] ;
209+ let call_2 = create_call_info ( 5 , vec ! [ ] ) ;
210+ let events: Vec < _ > = recursive_call_info_iter ( & TransactionExecutionInfo {
211+ validate_call_info : Some ( nested_calls) ,
212+ execute_call_info : None ,
213+ fee_transfer_call_info : Some ( call_2) ,
214+ revert_error : None ,
215+ transaction_receipt : Default :: default ( ) ,
216+ } )
217+ . flat_map ( |call| {
218+ call. execution . events . iter ( ) . map ( |event| Event {
219+ // See above for why we use storage address.
220+ from_address : call. call . storage_address . into ( ) ,
221+ keys : event. event . keys . iter ( ) . map ( |k| k. 0 ) . collect ( ) ,
222+ data : event. event . data . 0 . clone ( ) ,
223+ } )
224+ } )
225+ . collect ( ) ;
226+ let expected_events_ordering = vec ! [ event( 0 ) , event( 1 ) , event( 2 ) , event( 3 ) , event( 4 ) , event( 5 ) ] ;
237227
238228 assert_eq ! ( expected_events_ordering, events) ;
239229 }
0 commit comments