@@ -17,14 +17,17 @@ use crate::runtime_extensions::{
1717        storage:: { calculate_variable_address,  load,  store} , 
1818    } , 
1919} ; 
20- use  crate :: state:: { CallTrace ,  CallTraceNode } ; 
20+ use  crate :: state:: { CallTrace ,  CallTraceNode ,   GasReportData } ; 
2121use  anyhow:: { Context ,  Result ,  anyhow} ; 
2222use  blockifier:: bouncer:: vm_resources_to_sierra_gas; 
2323use  blockifier:: context:: TransactionContext ; 
24- use  blockifier:: execution:: call_info:: CallInfo ; 
24+ use  blockifier:: execution:: call_info:: { 
25+     CallInfo ,  CallSummary ,  ChargedResources ,  EventSummary ,  ExecutionSummary ,  OrderedEvent , 
26+ } ; 
2527use  blockifier:: execution:: contract_class:: TrackedResource ; 
2628use  blockifier:: execution:: syscalls:: vm_syscall_utils:: { SyscallSelector ,  SyscallUsageMap } ; 
2729use  blockifier:: state:: errors:: StateError ; 
30+ use  blockifier:: utils:: u64_from_usize; 
2831use  cairo_vm:: vm:: runners:: cairo_runner:: CairoRunner ; 
2932use  cairo_vm:: vm:: { 
3033    errors:: hint_errors:: HintError ,  runners:: cairo_runner:: ExecutionResources , 
@@ -42,10 +45,11 @@ use runtime::{
4245} ; 
4346use  scarb_oracle_hint_service:: OracleHintService ; 
4447use  starknet:: signers:: SigningKey ; 
48+ use  starknet_api:: execution_resources:: GasAmount ; 
4549use  starknet_api:: { contract_class:: EntryPointType :: L1Handler ,  core:: ClassHash } ; 
4650use  starknet_types_core:: felt:: Felt ; 
4751use  std:: cell:: RefCell ; 
48- use  std:: collections:: HashMap ; 
52+ use  std:: collections:: { HashMap ,   HashSet } ; 
4953use  std:: rc:: Rc ; 
5054use  std:: sync:: { Arc ,  Mutex } ; 
5155
@@ -738,6 +742,65 @@ pub fn update_top_call_vm_trace(runtime: &mut ForgeRuntime, cairo_runner: &mut C
738742    } 
739743} 
740744
745+ pub  fn  compute_and_store_execution_summary ( trace :  & Rc < RefCell < CallTrace > > )  { 
746+     let  execution_summary = if  trace. borrow ( ) . nested_calls . is_empty ( )  { 
747+         get_execution_summary_without_nested_calls ( trace) 
748+     }  else  { 
749+         let  mut  nested_calls_summaries = vec ! [ ] ; 
750+         for  nested_call in  & trace. borrow ( ) . nested_calls  { 
751+             if  let  CallTraceNode :: EntryPointCall ( nested_call)  = nested_call { 
752+                 compute_and_store_execution_summary ( nested_call) ; 
753+                 nested_calls_summaries. push ( 
754+                     nested_call
755+                         . borrow ( ) 
756+                         . gas_report_data 
757+                         . as_ref ( ) 
758+                         . expect ( "Gas report data must be set after calling `compute_and_store_execution_summary`" ) 
759+                         . execution_summary 
760+                         . clone ( ) ) ; 
761+             } 
762+         } 
763+         let  mut  current_call_summary = get_execution_summary_without_nested_calls ( trace) 
764+             + nested_calls_summaries. into_iter ( ) . sum ( ) ; 
765+ 
766+         // vm_resources and gas_consumed of a call already contain the resources of its inner calls. 
767+         current_call_summary. charged_resources . vm_resources  =
768+             trace. borrow ( ) . used_execution_resources . clone ( ) ; 
769+         current_call_summary. charged_resources . gas_consumed  =
770+             GasAmount ( trace. borrow ( ) . gas_consumed ) ; 
771+         current_call_summary
772+     } ; 
773+ 
774+     trace. borrow_mut ( ) . gas_report_data  = Some ( GasReportData :: new ( execution_summary. clone ( ) ) ) ; 
775+ } 
776+ 
777+ // Based on blockifier/src/execution/call_info.rs (summarize) 
778+ fn  get_execution_summary_without_nested_calls ( trace :  & Rc < RefCell < CallTrace > > )  -> ExecutionSummary  { 
779+     let  current_call = trace. borrow ( ) ; 
780+     ExecutionSummary  { 
781+         charged_resources :  ChargedResources  { 
782+             vm_resources :  current_call. used_execution_resources . clone ( ) , 
783+             gas_consumed :  GasAmount ( current_call. gas_consumed ) , 
784+         } , 
785+         l2_to_l1_payload_lengths :  current_call. used_l1_resources . l2_l1_message_sizes . clone ( ) , 
786+         event_summary :  { 
787+             let  mut  event_summary = EventSummary  { 
788+                 n_events :  current_call. events . len ( ) , 
789+                 ..Default :: default ( ) 
790+             } ; 
791+             for  OrderedEvent  {  event,  .. }  in  & current_call. events  { 
792+                 event_summary. total_event_data_size  += u64_from_usize ( event. data . 0 . len ( ) ) ; 
793+                 event_summary. total_event_keys  += u64_from_usize ( event. keys . len ( ) ) ; 
794+             } 
795+             event_summary
796+         } , 
797+         // Fields below are not relevant for partial gas calculation. 
798+         call_summary :  CallSummary :: default ( ) , 
799+         executed_class_hashes :  HashSet :: default ( ) , 
800+         visited_storage_entries :  HashSet :: default ( ) , 
801+     } 
802+ } 
803+ 
741804fn  add_sierra_gas_resources ( top_call :  & Rc < RefCell < CallTrace > > )  -> u64  { 
742805    let  mut  gas_consumed = top_call. borrow ( ) . gas_consumed ; 
743806    for  nested_call in  & top_call. borrow ( ) . nested_calls  { 
0 commit comments