Skip to content

Commit a729bf6

Browse files
committed
Update gas pointer in CallToBlockifierRuntime
Closes #3658 commit-id:5ba0cf9f
1 parent ed24639 commit a729bf6

File tree

1 file changed

+54
-32
lines changed
  • crates/cheatnet/src/runtime_extensions/call_to_blockifier_runtime_extension

1 file changed

+54
-32
lines changed

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

Lines changed: 54 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(
@@ -151,24 +142,55 @@ impl ExecuteCall for LibraryCallRequest {
151142
}
152143

153144
fn execute_syscall<Request: ExecuteCall + SyscallRequest>(
145+
selector: SyscallSelector,
154146
vm: &mut VirtualMachine,
155147
cheatable_starknet_runtime: &mut CheatableStarknetRuntime,
156148
) -> Result<(), HintError> {
157-
let _selector = felt_from_ptr(vm, cheatable_starknet_runtime.get_mut_syscall_ptr())?;
149+
let syscall_handler = &mut cheatable_starknet_runtime.extended_runtime.hint_handler;
150+
let cheatnet_state = &mut *cheatable_starknet_runtime.extension.cheatnet_state;
151+
152+
// Increment, since the selector was peeked into before
153+
syscall_handler.syscall_ptr += 1;
154+
syscall_handler.increment_syscall_count_by(&selector, 1);
158155

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

167-
let cheatnet_state = &mut *cheatable_starknet_runtime.extension.cheatnet_state;
168-
let syscall_handler = &mut cheatable_starknet_runtime.extended_runtime.hint_handler;
187+
return Ok(());
188+
}
189+
190+
let mut remaining_gas = gas_counter - required_gas;
169191

170-
let call_result = request.execute_call(syscall_handler, cheatnet_state);
171-
write_call_response(syscall_handler, vm, gas_counter, call_result)?;
192+
let call_result = request.execute_call(syscall_handler, cheatnet_state, &mut remaining_gas);
193+
write_call_response(syscall_handler, vm, remaining_gas, call_result)?;
172194
Ok(())
173195
}
174196

0 commit comments

Comments
 (0)