@@ -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