Skip to content

Commit d146920

Browse files
authored
Update gas pointer in CallToBlockifierRuntime (#3664)
Closes #3658 commit-id:5ba0cf9f --- **Stack**: - #3672 - #3664⚠️ *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 8bd4b64 commit d146920

File tree

2 files changed

+62
-33
lines changed

2 files changed

+62
-33
lines changed

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

Lines changed: 61 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -1,24 +1,24 @@
11
use std::marker::PhantomData;
22

3+
use crate::state::CheatnetState;
34
use blockifier::execution::entry_point::{CallEntryPoint, CallType};
4-
use blockifier::execution::execution_utils::felt_from_ptr;
5-
use blockifier::execution::syscalls::hint_processor::SyscallHintProcessor;
5+
use blockifier::execution::syscalls::hint_processor::{OUT_OF_GAS_ERROR, SyscallHintProcessor};
66
use blockifier::execution::syscalls::syscall_executor::SyscallExecutor;
77
use blockifier::execution::syscalls::vm_syscall_utils::{
88
CallContractRequest, LibraryCallRequest, RevertData, SingleSegmentResponse,
9-
SyscallRequestWrapper, SyscallSelector,
9+
SyscallExecutorBaseError, SyscallRequestWrapper, SyscallSelector,
1010
};
1111
use blockifier::execution::{
1212
execution_utils::ReadOnlySegment,
1313
syscalls::vm_syscall_utils::{SyscallRequest, SyscallResponse, SyscallResponseWrapper},
1414
};
15+
use blockifier::utils::u64_from_usize;
1516
use cairo_vm::types::relocatable::MaybeRelocatable;
1617
use cairo_vm::vm::{errors::hint_errors::HintError, vm_core::VirtualMachine};
17-
use runtime::{ExtendedRuntime, ExtensionLogic, SyscallHandlingResult, SyscallPtrAccess};
18+
use runtime::{ExtendedRuntime, ExtensionLogic, SyscallHandlingResult};
1819
use starknet_api::contract_class::EntryPointType;
1920
use starknet_api::core::ContractAddress;
20-
21-
use crate::state::CheatnetState;
21+
use starknet_types_core::felt::Felt;
2222

2323
use crate::runtime_extensions::call_to_blockifier_runtime_extension::rpc::{
2424
AddressOrClassHash, call_entry_point,
@@ -53,26 +53,14 @@ impl<'a> ExtensionLogic for CallToBlockifierExtension<'a> {
5353
match selector {
5454
// We execute contract calls and library calls with modified blockifier
5555
// This is redirected to drop ForgeRuntimeExtension
56-
// and to enable handling call errors with safe dispatchers in the test code
57-
// since call errors cannot be handled on real starknet
58-
// https://docs.starknet.io/architecture-and-concepts/smart-contracts/system-calls-cairo1/#call_contract
56+
// and to enable executing outer calls in tests as non-revertible.
5957
SyscallSelector::CallContract => {
60-
execute_syscall::<CallContractRequest>(vm, extended_runtime)?;
61-
62-
extended_runtime
63-
.extended_runtime
64-
.hint_handler
65-
.increment_syscall_count_by(&selector, 1);
58+
execute_syscall::<CallContractRequest>(selector, vm, extended_runtime)?;
6659

6760
Ok(SyscallHandlingResult::Handled)
6861
}
6962
SyscallSelector::LibraryCall => {
70-
execute_syscall::<LibraryCallRequest>(vm, extended_runtime)?;
71-
72-
extended_runtime
73-
.extended_runtime
74-
.hint_handler
75-
.increment_syscall_count_by(&selector, 1);
63+
execute_syscall::<LibraryCallRequest>(selector, vm, extended_runtime)?;
7664

7765
Ok(SyscallHandlingResult::Handled)
7866
}
@@ -89,6 +77,7 @@ where
8977
self,
9078
syscall_handler: &mut SyscallHintProcessor,
9179
cheatnet_state: &mut CheatnetState,
80+
remaining_gas: &mut u64,
9281
) -> CallResult;
9382
}
9483

@@ -97,6 +86,7 @@ impl ExecuteCall for CallContractRequest {
9786
self: CallContractRequest,
9887
syscall_handler: &mut SyscallHintProcessor,
9988
cheatnet_state: &mut CheatnetState,
89+
remaining_gas: &mut u64,
10090
) -> CallResult {
10191
let contract_address = self.contract_address;
10292

@@ -109,7 +99,7 @@ impl ExecuteCall for CallContractRequest {
10999
storage_address: contract_address,
110100
caller_address: TryFromHexStr::try_from_hex_str(TEST_ADDRESS).unwrap(),
111101
call_type: CallType::Call,
112-
initial_gas: i64::MAX as u64,
102+
initial_gas: *remaining_gas,
113103
};
114104

115105
call_entry_point(
@@ -126,6 +116,7 @@ impl ExecuteCall for LibraryCallRequest {
126116
self: LibraryCallRequest,
127117
syscall_handler: &mut SyscallHintProcessor,
128118
cheatnet_state: &mut CheatnetState,
119+
remaining_gas: &mut u64,
129120
) -> CallResult {
130121
let class_hash = self.class_hash;
131122

@@ -138,7 +129,7 @@ impl ExecuteCall for LibraryCallRequest {
138129
storage_address: TryFromHexStr::try_from_hex_str(TEST_ADDRESS).unwrap(),
139130
caller_address: ContractAddress::default(),
140131
call_type: CallType::Delegate,
141-
initial_gas: u64::MAX,
132+
initial_gas: *remaining_gas,
142133
};
143134

144135
call_entry_point(
@@ -150,25 +141,63 @@ impl ExecuteCall for LibraryCallRequest {
150141
}
151142
}
152143

144+
// crates/blockifier/src/execution/syscalls/vm_syscall_utils.rs:677 (execute_syscall)
153145
fn execute_syscall<Request: ExecuteCall + SyscallRequest>(
146+
selector: SyscallSelector,
154147
vm: &mut VirtualMachine,
155148
cheatable_starknet_runtime: &mut CheatableStarknetRuntime,
156149
) -> Result<(), HintError> {
157-
let _selector = felt_from_ptr(vm, cheatable_starknet_runtime.get_mut_syscall_ptr())?;
150+
// region: Modified blockifier code
151+
let syscall_handler = &mut cheatable_starknet_runtime.extended_runtime.hint_handler;
152+
let cheatnet_state = &mut *cheatable_starknet_runtime.extension.cheatnet_state;
153+
154+
// Increment, since the selector was peeked into before
155+
syscall_handler.syscall_ptr += 1;
156+
syscall_handler.increment_syscall_count_by(&selector, 1);
157+
// endregion
158+
159+
let syscall_gas_cost = syscall_handler
160+
.get_gas_cost_from_selector(&selector)
161+
.map_err(|error| SyscallExecutorBaseError::GasCost { error, selector })?;
158162

159163
let SyscallRequestWrapper {
160164
gas_counter,
161165
request,
162-
} = SyscallRequestWrapper::<Request>::read(
163-
vm,
164-
cheatable_starknet_runtime.get_mut_syscall_ptr(),
165-
)?;
166+
} = SyscallRequestWrapper::<Request>::read(vm, syscall_handler.get_mut_syscall_ptr())?;
167+
168+
let syscall_gas_cost =
169+
syscall_gas_cost.get_syscall_cost(u64_from_usize(request.get_linear_factor_length()));
170+
let syscall_base_cost = syscall_handler.get_syscall_base_gas_cost();
171+
172+
// Sanity check for preventing underflow.
173+
assert!(
174+
syscall_gas_cost >= syscall_base_cost,
175+
"Syscall gas cost must be greater than base syscall gas cost"
176+
);
177+
178+
// Refund `SYSCALL_BASE_GAS_COST` as it was pre-charged.
179+
let required_gas = syscall_gas_cost - syscall_base_cost;
180+
181+
if gas_counter < required_gas {
182+
let out_of_gas_error =
183+
Felt::from_hex(OUT_OF_GAS_ERROR).map_err(SyscallExecutorBaseError::from)?;
184+
let response: SyscallResponseWrapper<SingleSegmentResponse> =
185+
SyscallResponseWrapper::Failure {
186+
gas_counter,
187+
revert_data: RevertData::new_normal(vec![out_of_gas_error]),
188+
};
189+
response.write(vm, syscall_handler.get_mut_syscall_ptr())?;
166190

167-
let cheatnet_state = &mut *cheatable_starknet_runtime.extension.cheatnet_state;
168-
let syscall_handler = &mut cheatable_starknet_runtime.extended_runtime.hint_handler;
191+
return Ok(());
192+
}
193+
194+
let mut remaining_gas = gas_counter - required_gas;
195+
196+
// region: Modified blockifier code
197+
let call_result = request.execute_call(syscall_handler, cheatnet_state, &mut remaining_gas);
198+
write_call_response(syscall_handler, vm, remaining_gas, call_result)?;
199+
// endregion
169200

170-
let call_result = request.execute_call(syscall_handler, cheatnet_state);
171-
write_call_response(syscall_handler, vm, gas_counter, call_result)?;
172201
Ok(())
173202
}
174203

crates/cheatnet/src/runtime_extensions/cheatable_starknet_runtime_extension.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -154,7 +154,7 @@ fn get_syscall_cost(
154154
}
155155

156156
impl CheatableStarknetRuntimeExtension<'_> {
157-
// crates/blockifier/src/execution/syscalls/hint_processor.rs:280 (SyscallHintProcessor::execute_syscall)
157+
// crates/blockifier/src/execution/syscalls/vm_syscall_utils.rs:677 (execute_syscall)
158158
fn execute_syscall<Request, Response, ExecuteCallback>(
159159
&mut self,
160160
syscall_handler: &mut SyscallHintProcessor,

0 commit comments

Comments
 (0)