Skip to content

Commit 8774130

Browse files
authored
Get gas resources from CallInfo (#3736)
Closes #3292 Closes #2960 commit-id:7967ca03 --- **Stack**: - #3756 - #3755 - #3752 - #3751 - #3736⚠️ *Part of a stack created by [spr](https://github.com/ejoffe/spr). Do not merge manually using the UI - doing so may have unexpected results.*
1 parent 3992282 commit 8774130

File tree

9 files changed

+169
-250
lines changed

9 files changed

+169
-250
lines changed

crates/cheatnet/src/runtime_extensions/call_to_blockifier_runtime_extension/rpc.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ use crate::runtime_extensions::{
55
},
66
common::create_execute_calldata,
77
};
8+
use blockifier::execution::call_info::ExecutionSummary;
89
use blockifier::execution::{
910
call_info::CallInfo,
1011
entry_point::{CallType, EntryPointExecutionResult},
@@ -18,22 +19,21 @@ use blockifier::state::errors::StateError;
1819
use cairo_vm::vm::runners::cairo_runner::ExecutionResources;
1920
use conversions::{byte_array::ByteArray, serde::serialize::CairoSerialize, string::IntoHexStr};
2021
use shared::utils::build_readable_text;
22+
use starknet_api::core::EntryPointSelector;
2123
use starknet_api::execution_resources::GasAmount;
2224
use starknet_api::{
2325
contract_class::EntryPointType,
2426
core::{ClassHash, ContractAddress},
2527
};
26-
use starknet_api::{core::EntryPointSelector, transaction::EventContent};
2728
use starknet_types_core::felt::Felt;
2829

2930
#[derive(Clone, Debug, Default)]
3031
pub struct UsedResources {
3132
pub syscall_usage: SyscallUsageMap,
3233
pub execution_resources: ExecutionResources,
3334
pub gas_consumed: GasAmount,
34-
pub l2_to_l1_payload_lengths: Vec<usize>,
35+
pub execution_summary: ExecutionSummary,
3536
pub l1_handler_payload_lengths: Vec<usize>,
36-
pub events: Vec<EventContent>,
3737
}
3838

3939
/// Enum representing possible call execution result, along with the data

crates/cheatnet/src/runtime_extensions/forge_runtime_extension/mod.rs

Lines changed: 10 additions & 78 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
use self::contracts_data::ContractsData;
22
use crate::runtime_extensions::call_to_blockifier_runtime_extension::rpc::UsedResources;
3-
use crate::runtime_extensions::common::{get_syscalls_gas_consumed, sum_syscall_usage};
3+
use crate::runtime_extensions::common::sum_syscall_usage;
44
use crate::runtime_extensions::forge_runtime_extension::cheatcodes::replace_bytecode::ReplaceBytecodeError;
55
use crate::runtime_extensions::{
66
call_to_blockifier_runtime_extension::{
@@ -19,27 +19,23 @@ use crate::runtime_extensions::{
1919
};
2020
use crate::state::{CallTrace, CallTraceNode};
2121
use anyhow::{Context, Result, anyhow};
22-
use blockifier::blockifier_versioned_constants::VersionedConstants;
2322
use blockifier::bouncer::vm_resources_to_sierra_gas;
2423
use blockifier::context::TransactionContext;
25-
use blockifier::execution::call_info::{CallExecution, CallInfo};
24+
use blockifier::execution::call_info::CallInfo;
2625
use blockifier::execution::contract_class::TrackedResource;
27-
use blockifier::execution::entry_point::CallEntryPoint;
2826
use blockifier::execution::syscalls::vm_syscall_utils::{SyscallSelector, SyscallUsageMap};
2927
use blockifier::state::errors::StateError;
3028
use cairo_vm::vm::runners::cairo_runner::CairoRunner;
3129
use cairo_vm::vm::{
3230
errors::hint_errors::HintError, runners::cairo_runner::ExecutionResources,
3331
vm_core::VirtualMachine,
3432
};
35-
use conversions::IntoConv;
3633
use conversions::byte_array::ByteArray;
3734
use conversions::felt::{ToShortString, TryInferFormat};
3835
use conversions::serde::deserialize::BufferReader;
3936
use conversions::serde::serialize::CairoSerialize;
4037
use data_transformer::cairo_types::CairoU256;
4138
use rand::prelude::StdRng;
42-
use runtime::starknet::constants::TEST_CONTRACT_CLASS_HASH;
4339
use runtime::{
4440
CheatcodeHandlingResult, EnhancedHintError, ExtendedRuntime, ExtensionLogic,
4541
SyscallHandlingResult,
@@ -752,15 +748,6 @@ pub fn update_top_call_vm_trace(runtime: &mut ForgeRuntime, cairo_runner: &mut C
752748
Some(get_relocated_vm_trace(cairo_runner));
753749
}
754750
}
755-
fn add_syscall_execution_resources(
756-
versioned_constants: &VersionedConstants,
757-
execution_resources: &ExecutionResources,
758-
syscall_usage: &SyscallUsageMap,
759-
) -> ExecutionResources {
760-
let mut total_vm_usage = execution_resources.filter_unused_builtins();
761-
total_vm_usage += &versioned_constants.get_additional_os_syscall_resources(syscall_usage);
762-
total_vm_usage
763-
}
764751

765752
fn add_sierra_gas_resources(top_call: &Rc<RefCell<CallTrace>>) -> u64 {
766753
let mut gas_consumed = top_call.borrow().gas_consumed;
@@ -788,78 +775,23 @@ fn add_execution_resources(top_call: Rc<RefCell<CallTrace>>) -> ExecutionResourc
788775

789776
#[must_use]
790777
pub fn get_all_used_resources(
791-
runtime: ForgeRuntime,
778+
call_info: &CallInfo,
779+
trace: &Rc<RefCell<CallTrace>>,
792780
transaction_context: &TransactionContext,
793-
tracked_resource: TrackedResource,
794781
) -> UsedResources {
795-
let starknet_runtime = runtime.extended_runtime.extended_runtime.extended_runtime;
796-
let top_call_l2_to_l1_messages = starknet_runtime.hint_handler.base.l2_to_l1_messages;
797-
let top_call_events = starknet_runtime.hint_handler.base.events;
798-
799782
let versioned_constants = transaction_context.block_context.versioned_constants();
800783

801-
// used just to obtain payloads of L2 -> L1 messages
802-
let runtime_call_info = CallInfo {
803-
execution: CallExecution {
804-
l2_to_l1_messages: top_call_l2_to_l1_messages,
805-
events: top_call_events,
806-
..Default::default()
807-
},
808-
call: CallEntryPoint {
809-
class_hash: Some(Felt::from_hex(TEST_CONTRACT_CLASS_HASH).unwrap().into_()),
810-
..Default::default()
811-
},
812-
inner_calls: starknet_runtime.hint_handler.base.inner_calls,
813-
tracked_resource,
814-
..Default::default()
815-
};
816-
let summary = runtime_call_info.summarize(versioned_constants);
817-
let l2_to_l1_payload_lengths = summary.l2_to_l1_payload_lengths;
818-
819-
let l1_handler_payload_lengths =
820-
get_l1_handlers_payloads_lengths(&runtime_call_info.inner_calls);
784+
let summary = call_info.summarize(versioned_constants);
821785

822-
// call representing the test code
823-
let top_call = runtime
824-
.extended_runtime
825-
.extended_runtime
826-
.extension
827-
.cheatnet_state
828-
.trace_data
829-
.current_call_stack
830-
.top();
786+
let l1_handler_payload_lengths = get_l1_handlers_payloads_lengths(&call_info.inner_calls);
831787

832-
let mut execution_resources = top_call.borrow().used_execution_resources.clone();
833-
let mut sierra_gas_consumed = top_call.borrow().gas_consumed;
834-
let top_call_syscalls = top_call.borrow().get_total_used_syscalls();
835-
836-
execution_resources = add_syscall_execution_resources(
837-
versioned_constants,
838-
&execution_resources,
839-
&top_call.borrow().used_syscalls_vm_resources,
840-
);
841-
sierra_gas_consumed += get_syscalls_gas_consumed(
842-
&top_call.borrow().used_syscalls_sierra_gas,
843-
versioned_constants,
844-
);
845-
846-
let events = runtime_call_info
847-
.iter() // This method iterates over inner calls as well
848-
.flat_map(|call_info| {
849-
call_info
850-
.execution
851-
.events
852-
.iter()
853-
.map(|evt| evt.event.clone())
854-
})
855-
.collect();
788+
let top_call_syscalls = trace.borrow().get_total_used_syscalls();
856789

857790
UsedResources {
858-
events,
859791
syscall_usage: top_call_syscalls,
860-
execution_resources,
861-
gas_consumed: GasAmount::from(sierra_gas_consumed),
792+
execution_resources: call_info.resources.clone(),
793+
gas_consumed: GasAmount::from(call_info.execution.gas_consumed),
794+
execution_summary: summary,
862795
l1_handler_payload_lengths,
863-
l2_to_l1_payload_lengths,
864796
}
865797
}

crates/forge-runner/src/gas.rs

Lines changed: 4 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -9,13 +9,11 @@ use blockifier::fee::resources::{
99
use blockifier::state::cached_state::CachedState;
1010
use blockifier::state::errors::StateError;
1111
use blockifier::transaction::objects::HasRelatedFeeType;
12-
use blockifier::utils::u64_from_usize;
1312
use cairo_vm::vm::runners::cairo_runner::ExecutionResources;
1413
use cheatnet::runtime_extensions::call_to_blockifier_runtime_extension::rpc::UsedResources;
1514
use cheatnet::runtime_extensions::forge_config_extension::config::RawAvailableResourceBoundsConfig;
1615
use cheatnet::state::ExtendedStateReader;
1716
use starknet_api::execution_resources::{GasAmount, GasVector};
18-
use starknet_api::transaction::EventContent;
1917
use starknet_api::transaction::fields::GasVectorComputationMode;
2018

2119
#[tracing::instrument(skip_all, level = "debug")]
@@ -27,13 +25,14 @@ pub fn calculate_used_gas(
2725
let versioned_constants = transaction_context.block_context.versioned_constants();
2826

2927
let message_resources = get_messages_resources(
30-
&resources.l2_to_l1_payload_lengths,
28+
&resources.execution_summary.l2_to_l1_payload_lengths,
3129
&resources.l1_handler_payload_lengths,
3230
);
3331

3432
let state_resources = get_state_resources(transaction_context, state)?;
3533

36-
let archival_data_resources = get_archival_data_resources(resources.events);
34+
let archival_data_resources =
35+
get_archival_data_resources(resources.execution_summary.event_summary);
3736

3837
let starknet_resources = StarknetResources {
3938
archival_data: archival_data_resources,
@@ -64,17 +63,7 @@ pub fn calculate_used_gas(
6463
))
6564
}
6665

67-
fn get_archival_data_resources(events: Vec<EventContent>) -> ArchivalDataResources {
68-
// Based on from https://github.com/starkware-libs/sequencer/blob/fc0f06a07f3338ae1e11612dcaed9c59373bca37/crates/blockifier/src/execution/call_info.rs#L222
69-
let mut event_summary = EventSummary {
70-
n_events: events.len(),
71-
..Default::default()
72-
};
73-
for event in events {
74-
event_summary.total_event_data_size += u64_from_usize(event.data.0.len());
75-
event_summary.total_event_keys += u64_from_usize(event.keys.len());
76-
}
77-
66+
fn get_archival_data_resources(event_summary: EventSummary) -> ArchivalDataResources {
7867
// calldata length, signature length and code size are set to 0, because
7968
// we don't include them in estimations
8069
// ref: https://github.com/foundry-rs/starknet-foundry/blob/5ce15b029135545452588c00aae580c05eb11ca8/docs/src/testing/gas-and-resource-estimation.md?plain=1#L73

crates/forge-runner/src/running.rs

Lines changed: 25 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -288,7 +288,7 @@ pub fn run_test_case(
288288
tracked_resource,
289289
)?;
290290

291-
// TODO(#3292) this can be done better, we can take gas directly from call info
291+
// TODO(#3744): Confirm if this is needed for the profiler
292292
let vm_resources_without_inner_calls = runner
293293
.get_execution_resources()
294294
.expect("Execution resources missing")
@@ -335,34 +335,38 @@ pub fn run_test_case(
335335
.clone();
336336

337337
let transaction_context = get_context(&forge_runtime).tx_context.clone();
338-
let used_resources =
339-
get_all_used_resources(forge_runtime, &transaction_context, tracked_resource);
340-
let gas_used = calculate_used_gas(
341-
&transaction_context,
342-
&mut cached_state,
343-
used_resources.clone(),
344-
)?;
345338

346339
let fork_data = cached_state
347340
.state
348341
.fork_state_reader
342+
.as_ref()
349343
.map(|fork_state_reader| ForkData::new(&fork_state_reader.compiled_contract_class_map()))
350344
.unwrap_or_default();
351345

352346
Ok(match result {
353-
Ok(result) => RunResult::Completed(Box::new(RunCompleted {
354-
status: if result.execution.failed {
355-
RunStatus::Panic(result.execution.retdata.0)
356-
} else {
357-
RunStatus::Success(result.execution.retdata.0)
358-
},
359-
call_trace: call_trace_ref,
360-
gas_used,
361-
used_resources,
362-
encountered_errors,
363-
fuzzer_args,
364-
fork_data,
365-
})),
347+
Ok(result) => {
348+
let used_resources =
349+
get_all_used_resources(&result, &call_trace_ref, &transaction_context);
350+
let gas_used = calculate_used_gas(
351+
&transaction_context,
352+
&mut cached_state,
353+
used_resources.clone(),
354+
)?;
355+
356+
RunResult::Completed(Box::new(RunCompleted {
357+
status: if result.execution.failed {
358+
RunStatus::Panic(result.execution.retdata.0)
359+
} else {
360+
RunStatus::Success(result.execution.retdata.0)
361+
},
362+
call_trace: call_trace_ref,
363+
gas_used,
364+
used_resources,
365+
encountered_errors,
366+
fuzzer_args,
367+
fork_data,
368+
}))
369+
}
366370
Err(error) => RunResult::Error(RunError {
367371
error: Box::new(error),
368372
call_trace: call_trace_ref,

crates/forge-runner/src/running/copied_code.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,7 @@ pub fn get_call_result(
6060
TrackedResource::CairoSteps => 0,
6161
TrackedResource::SierraGas => syscall_handler.base.call.initial_gas - gas,
6262
};
63+
6364
Ok(CallResult {
6465
failed,
6566
retdata: read_execution_retdata(runner, retdata_size, retdata_start)?,

crates/forge-runner/src/test_case_summary.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -125,6 +125,7 @@ impl TestType for Single {
125125
}
126126

127127
/// Summary of running a single test case
128+
#[expect(clippy::large_enum_variant)]
128129
#[derive(Debug, Clone)]
129130
pub enum TestCaseSummary<T: TestType> {
130131
/// Test case passed

crates/forge/tests/data/contracts/gas_constructor_checker.cairo

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,10 @@ mod GasConstructorChecker {
44
struct Storage {}
55

66
#[constructor]
7-
fn constructor(ref self: ContractState, _dummy_calldata: felt252) {
8-
keccak::keccak_u256s_le_inputs(array![1].span());
9-
keccak::keccak_u256s_le_inputs(array![1].span());
7+
fn constructor(ref self: ContractState, compute_keccak: bool) {
8+
if compute_keccak {
9+
keccak::keccak_u256s_le_inputs(array![1].span());
10+
keccak::keccak_u256s_le_inputs(array![1].span());
11+
}
1012
}
1113
}

crates/forge/tests/data/contracts/hello_starknet_for_nested_calls.cairo

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,6 @@ pub mod HelloStarknet {
1313
#[abi(embed_v0)]
1414
impl HelloStarknetImpl of super::IHelloStarknet<ContractState> {
1515
fn example_function(ref self: ContractState) {
16-
core::pedersen::pedersen(1, 2);
1716
core::keccak::keccak_u256s_le_inputs(array![1].span());
1817
let _hash = compute_sha256_u32_array(array![0x68656c6c], 0x6f, 1);
1918
starknet::syscalls::get_block_hash_syscall(1).unwrap_syscall();

0 commit comments

Comments
 (0)