Skip to content

Commit bddee0e

Browse files
authored
Fix gas calculation (#1623)
## Introduced changes - now gas used for constructor execution and l1 handler execution is included in total gas cost - `DeployPayload` and `CallOutput` struct were removed (no longer necessary) ## Checklist - [x] Linked relevant issue - [x] Updated relevant documentation - [x] Added relevant tests - [x] Performed self-review of the code - [x] Added changes to `CHANGELOG.md`
1 parent bf143ab commit bddee0e

File tree

32 files changed

+410
-728
lines changed

32 files changed

+410
-728
lines changed

CHANGELOG.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
1313

1414
- Gas estimation is now aligned with the Starknet v0.13
1515

16+
### Fixed
17+
18+
- Gas used in constructors and handling of L1 messages is now properly included in total gas cost
19+
1620
## [0.16.0] - 2024-01-26
1721

1822
### Forge

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

Lines changed: 7 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ use crate::runtime_extensions::call_to_blockifier_runtime_extension::rpc::{
3030
};
3131
use crate::runtime_extensions::call_to_blockifier_runtime_extension::{
3232
execution::cheated_syscalls::SingleSegmentResponse,
33-
rpc::{CallFailure, CallOutput, CallResult},
33+
rpc::{CallFailure, CallResult},
3434
};
3535

3636
use super::io_runtime_extension::IORuntime;
@@ -81,15 +81,15 @@ where
8181
self,
8282
blockifier_state: &mut BlockifierState,
8383
cheatnet_state: &mut CheatnetState,
84-
) -> CallOutput;
84+
) -> CallResult;
8585
}
8686

8787
impl ExecuteCall for CallContractRequest {
8888
fn execute_call(
8989
self: CallContractRequest,
9090
blockifier_state: &mut BlockifierState,
9191
cheatnet_state: &mut CheatnetState,
92-
) -> CallOutput {
92+
) -> CallResult {
9393
let contract_address = self.contract_address;
9494

9595
let entry_point = CallEntryPoint {
@@ -110,7 +110,6 @@ impl ExecuteCall for CallContractRequest {
110110
entry_point,
111111
&AddressOrClassHash::ContractAddress(contract_address),
112112
)
113-
.unwrap_or_else(|err| panic!("Transaction execution error: {err}"))
114113
}
115114
}
116115

@@ -119,7 +118,7 @@ impl ExecuteCall for LibraryCallRequest {
119118
self: LibraryCallRequest,
120119
blockifier_state: &mut BlockifierState,
121120
cheatnet_state: &mut CheatnetState,
122-
) -> CallOutput {
121+
) -> CallResult {
123122
let class_hash = self.class_hash;
124123

125124
let entry_point = CallEntryPoint {
@@ -140,7 +139,6 @@ impl ExecuteCall for LibraryCallRequest {
140139
entry_point,
141140
&AddressOrClassHash::ClassHash(class_hash),
142141
)
143-
.unwrap_or_else(|err| panic!("Transaction execution error: {err}"))
144142
}
145143
}
146144

@@ -161,34 +159,22 @@ fn execute_syscall<Request: ExecuteCall + SyscallRequest>(
161159
let mut blockifier_state = BlockifierState::from(syscall_handler.state);
162160

163161
let call_result = request.execute_call(&mut blockifier_state, cheatnet_state);
164-
write_call_response(
165-
syscall_handler,
166-
cheatnet_state,
167-
vm,
168-
gas_counter,
169-
call_result,
170-
)?;
162+
write_call_response(syscall_handler, vm, gas_counter, call_result)?;
171163
Ok(())
172164
}
173165

174166
fn write_call_response(
175167
syscall_handler: &mut SyscallHintProcessor<'_>,
176-
cheatnet_state: &mut CheatnetState,
177168
vm: &mut VirtualMachine,
178169
gas_counter: u64,
179-
call_output: CallOutput,
170+
call_result: CallResult,
180171
) -> Result<(), HintError> {
181-
let response_wrapper: SyscallResponseWrapper<SingleSegmentResponse> = match call_output.result {
172+
let response_wrapper: SyscallResponseWrapper<SingleSegmentResponse> = match call_result {
182173
CallResult::Success { ret_data, .. } => {
183174
let memory_segment_start_ptr = syscall_handler
184175
.read_only_segments
185176
.allocate(vm, &ret_data.iter().map(Into::into).collect())?;
186177

187-
// add execution resources used by call to all used resources
188-
cheatnet_state
189-
.used_resources
190-
.extend(&call_output.used_resources);
191-
192178
SyscallResponseWrapper::Success {
193179
gas_counter,
194180
response: SingleSegmentResponse {

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

Lines changed: 14 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
1-
use anyhow::Result;
21
use blockifier::execution::execution_utils::stark_felt_to_felt;
32
use cairo_lang_runner::casm_run::format_next_item;
43

@@ -39,13 +38,6 @@ impl UsedResources {
3938
}
4039
}
4140

42-
/// Represents call output, along with the data and the resources consumed during execution
43-
#[derive(Debug)]
44-
pub struct CallOutput {
45-
pub result: CallResult,
46-
pub used_resources: UsedResources,
47-
}
48-
4941
/// Enum representing possible call execution result, along with the data
5042
#[derive(Debug)]
5143
pub enum CallResult {
@@ -178,7 +170,7 @@ pub fn call_l1_handler(
178170
contract_address: &ContractAddress,
179171
entry_point_selector: &Felt252,
180172
calldata: &[Felt252],
181-
) -> Result<CallOutput> {
173+
) -> CallResult {
182174
let entry_point_selector = create_entry_point_selector(entry_point_selector);
183175
let calldata = create_execute_calldata(calldata);
184176

@@ -207,7 +199,7 @@ pub fn call_entry_point(
207199
cheatnet_state: &mut CheatnetState,
208200
mut entry_point: CallEntryPoint,
209201
starknet_identifier: &AddressOrClassHash,
210-
) -> Result<CallOutput> {
202+
) -> CallResult {
211203
let mut resources = ExecutionResources::default();
212204
let account_context = build_transaction_context();
213205
let block_context = build_block_context(cheatnet_state.block_info);
@@ -228,15 +220,16 @@ pub fn call_entry_point(
228220
&mut context,
229221
);
230222

231-
let result = CallResult::from_execution_result(&exec_result, starknet_identifier);
232-
233-
Ok(CallOutput {
234-
result,
235-
used_resources: UsedResources {
236-
execution_resources: resources,
237-
l2_to_l1_payloads_length: exec_result.map_or(vec![], |call_info| {
238-
call_info.get_sorted_l2_to_l1_payloads_length().unwrap()
239-
}),
240-
},
241-
})
223+
let call_result = CallResult::from_execution_result(&exec_result, starknet_identifier);
224+
225+
let used_resources = UsedResources {
226+
execution_resources: resources,
227+
l2_to_l1_payloads_length: exec_result.map_or(vec![], |call_info| {
228+
call_info.get_sorted_l2_to_l1_payloads_length().unwrap()
229+
}),
230+
};
231+
// add execution resources used by call contract, library call or l1 handler execution to all used resources
232+
cheatnet_state.used_resources.extend(&used_resources);
233+
234+
call_result
242235
}

crates/cheatnet/src/runtime_extensions/forge_runtime_extension/cheatcodes/deploy.rs

Lines changed: 13 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
use crate::constants::TEST_ADDRESS;
22
use crate::runtime_extensions::call_to_blockifier_runtime_extension::rpc::{
3-
AddressOrClassHash, CallFailure,
3+
AddressOrClassHash, CallFailure, UsedResources,
44
};
55
use crate::state::BlockifierState;
66
use crate::CheatnetState;
@@ -27,19 +27,13 @@ use starknet_api::transaction::Calldata;
2727

2828
use super::CheatcodeError;
2929

30-
#[derive(Debug)]
31-
pub struct DeployCallPayload {
32-
pub used_resources: ExecutionResources,
33-
pub contract_address: ContractAddress,
34-
}
35-
3630
pub fn deploy_at(
3731
blockifier_state: &mut BlockifierState,
3832
cheatnet_state: &mut CheatnetState,
3933
class_hash: &ClassHash,
4034
calldata: &[Felt252],
4135
contract_address: ContractAddress,
42-
) -> Result<DeployCallPayload, CheatcodeError> {
36+
) -> Result<ContractAddress, CheatcodeError> {
4337
let blockifier_state_raw: &mut dyn State = blockifier_state.blockifier_state;
4438

4539
if let Ok(class_hash) = blockifier_state_raw.get_class_hash_at(contract_address) {
@@ -69,20 +63,17 @@ pub fn deploy_at(
6963
calldata.to_vec().iter().map(felt_to_stark_felt).collect(),
7064
));
7165

72-
let resources = &mut ExecutionResources::default();
66+
let mut resources = ExecutionResources::default();
7367
let result = cheated_syscalls::execute_deployment(
7468
blockifier_state_raw,
75-
resources,
69+
&mut resources,
7670
entry_point_execution_ctx,
7771
ctor_context,
7872
calldata,
7973
u64::MAX,
8074
cheatnet_state,
8175
)
82-
.map(|_call_info| DeployCallPayload {
83-
used_resources: resources.clone(),
84-
contract_address,
85-
})
76+
.map(|_call_info| contract_address)
8677
.map_err(|err| {
8778
let call_contract_failure = CallFailure::from_execution_error(
8879
&err,
@@ -91,6 +82,13 @@ pub fn deploy_at(
9182
CheatcodeError::from(call_contract_failure)
9283
});
9384
cheatnet_state.increment_deploy_salt_base();
85+
86+
// add execution resources used by deploy to all used resources
87+
cheatnet_state.used_resources.extend(&UsedResources {
88+
execution_resources: resources,
89+
l2_to_l1_payloads_length: vec![],
90+
});
91+
9492
result
9593
}
9694

@@ -99,7 +97,7 @@ pub fn deploy(
9997
cheatnet_state: &mut CheatnetState,
10098
class_hash: &ClassHash,
10199
calldata: &[Felt252],
102-
) -> Result<DeployCallPayload, CheatcodeError> {
100+
) -> Result<ContractAddress, CheatcodeError> {
103101
let contract_address = cheatnet_state.precalculate_address(class_hash, calldata);
104102

105103
deploy_at(

crates/cheatnet/src/runtime_extensions/forge_runtime_extension/cheatcodes/l1_handler_execute.rs

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
use crate::runtime_extensions::call_to_blockifier_runtime_extension::rpc::{
2-
call_l1_handler, CallOutput,
2+
call_l1_handler, CallResult,
33
};
44
use crate::state::{BlockifierState, CheatnetState};
55
use blockifier::abi::abi_utils::starknet_keccak;
@@ -14,7 +14,7 @@ impl BlockifierState<'_> {
1414
function_name: &Felt252,
1515
from_address: &Felt252,
1616
payload: &[Felt252],
17-
) -> CallOutput {
17+
) -> CallResult {
1818
let selector = starknet_keccak(&function_name.to_bytes_be());
1919

2020
let mut calldata = vec![from_address.clone()];
@@ -27,6 +27,5 @@ impl BlockifierState<'_> {
2727
&selector,
2828
calldata.as_slice(),
2929
)
30-
.expect("Calling l1 handler failed")
3130
}
3231
}

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

Lines changed: 14 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,7 @@ use std::collections::HashMap;
33
use crate::runtime_extensions::call_to_blockifier_runtime_extension::rpc::{
44
CallFailure, CallResult, UsedResources,
55
};
6-
use crate::runtime_extensions::forge_runtime_extension::cheatcodes::deploy::{
7-
deploy, deploy_at, DeployCallPayload,
8-
};
6+
use crate::runtime_extensions::forge_runtime_extension::cheatcodes::deploy::{deploy, deploy_at};
97
use crate::runtime_extensions::forge_runtime_extension::cheatcodes::CheatcodeError;
108
use crate::state::{BlockifierState, CallTrace, CheatTarget};
119
use anyhow::{Context, Result};
@@ -288,9 +286,9 @@ impl<'a> ExtensionLogic for ForgeExtension<'a> {
288286
"deploy" => {
289287
let class_hash = reader.read_felt().into_();
290288
let calldata = reader.read_vec();
291-
let cheatable_starknet_runtime = &mut extended_runtime.extended_runtime;
289+
let cheatnet_runtime = &mut extended_runtime.extended_runtime;
292290
let mut blockifier_state = BlockifierState::from(
293-
cheatable_starknet_runtime
291+
cheatnet_runtime
294292
.extended_runtime
295293
.extended_runtime
296294
.hint_handler
@@ -299,10 +297,7 @@ impl<'a> ExtensionLogic for ForgeExtension<'a> {
299297

300298
handle_deploy_result(deploy(
301299
&mut blockifier_state,
302-
cheatable_starknet_runtime
303-
.extended_runtime
304-
.extension
305-
.cheatnet_state,
300+
cheatnet_runtime.extended_runtime.extension.cheatnet_state,
306301
&class_hash,
307302
&calldata,
308303
))
@@ -393,16 +388,13 @@ impl<'a> ExtensionLogic for ForgeExtension<'a> {
393388
let mut blockifier_state =
394389
BlockifierState::from(cheatnet_runtime.extended_runtime.hint_handler.state);
395390

396-
match blockifier_state
397-
.l1_handler_execute(
398-
cheatnet_runtime.extension.cheatnet_state,
399-
contract_address,
400-
&function_name,
401-
&from_address,
402-
&payload,
403-
)
404-
.result
405-
{
391+
match blockifier_state.l1_handler_execute(
392+
cheatnet_runtime.extension.cheatnet_state,
393+
contract_address,
394+
&function_name,
395+
&from_address,
396+
&payload,
397+
) {
406398
CallResult::Success { .. } => {
407399
Ok(CheatcodeHandlingResult::Handled(vec![Felt252::from(0)]))
408400
}
@@ -667,11 +659,11 @@ impl<'a> ExtensionLogic for ForgeExtension<'a> {
667659
}
668660

669661
fn handle_deploy_result(
670-
deploy_result: Result<DeployCallPayload, CheatcodeError>,
662+
deploy_result: Result<ContractAddress, CheatcodeError>,
671663
) -> Result<CheatcodeHandlingResult, EnhancedHintError> {
672664
match deploy_result {
673-
Ok(deploy_payload) => {
674-
let felt_contract_address: Felt252 = deploy_payload.contract_address.into_();
665+
Ok(contract_address) => {
666+
let felt_contract_address = contract_address.into_();
675667
let result = vec![Felt252::from(0), felt_contract_address];
676668
Ok(CheatcodeHandlingResult::Handled(result))
677669
}

crates/cheatnet/tests/builtins/panic_call.rs

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -22,8 +22,7 @@ fn call_contract_error() {
2222
&contract_address,
2323
&selector,
2424
&[Felt252::from(420)],
25-
)
26-
.unwrap();
25+
);
2726

2827
assert_error!(output, "0x496e70757420746f6f206c6f6e6720666f7220617267756d656e7473 ('Input too long for arguments')");
2928
}
@@ -44,8 +43,7 @@ fn call_contract_panic() {
4443
&contract_address,
4544
&selector,
4645
&[],
47-
)
48-
.unwrap();
46+
);
4947

5048
assert_panic!(
5149
output,

crates/cheatnet/tests/builtins/segment_arena.rs

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,8 +20,7 @@ fn segment_arena_simple() {
2020
&contract_address,
2121
&selector,
2222
&[],
23-
)
24-
.unwrap();
23+
);
2524

2625
assert_success!(output, &[]);
2726
}

0 commit comments

Comments
 (0)