Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(blockifier): don't count Sierra gas in CairoSteps mode #2440

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
25 changes: 13 additions & 12 deletions crates/blockifier/src/execution/contract_class.rs
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,6 @@ use starknet_api::deprecated_contract_class::{
EntryPointV0,
Program as DeprecatedProgram,
};
use starknet_api::transaction::fields::GasVectorComputationMode;
use starknet_types_core::felt::Felt;

use crate::abi::constants::{self};
Expand Down Expand Up @@ -133,18 +132,20 @@ impl RunnableCompiledClass {
pub fn tracked_resource(
&self,
min_sierra_version: &CompilerVersion,
gas_mode: GasVectorComputationMode,
last_tracked_resource: Option<&TrackedResource>,
) -> TrackedResource {
match gas_mode {
GasVectorComputationMode::All => match self {
Self::V0(_) => TrackedResource::CairoSteps,
Self::V1(contract_class) => contract_class.tracked_resource(min_sierra_version),
#[cfg(feature = "cairo_native")]
Self::V1Native(contract_class) => {
contract_class.casm().tracked_resource(min_sierra_version)
}
},
GasVectorComputationMode::NoL2Gas => TrackedResource::CairoSteps,
let contract_tracked_resource = match self {
Self::V0(_) => TrackedResource::CairoSteps,
Self::V1(contract_class) => contract_class.tracked_resource(min_sierra_version),
#[cfg(feature = "cairo_native")]
Self::V1Native(contract_class) => {
contract_class.casm().tracked_resource(min_sierra_version)
}
};
match last_tracked_resource {
// Once we ran with CairoSteps, we will continue to run using it for all nested calls.
Some(TrackedResource::CairoSteps) => TrackedResource::CairoSteps,
Some(TrackedResource::SierraGas) | None => contract_tracked_resource,
}
}
}
Expand Down
9 changes: 7 additions & 2 deletions crates/blockifier/src/execution/entry_point_execution.rs
Original file line number Diff line number Diff line change
Expand Up @@ -408,7 +408,7 @@ pub fn finalize_execution(
runner.vm.mark_address_range_as_accessed(args_ptr, n_total_args)?;
syscall_handler.read_only_segments.mark_as_accessed(&mut runner)?;

let call_result = get_call_result(&runner, &syscall_handler)?;
let call_result = get_call_result(&runner, &syscall_handler, &tracked_resource)?;

// Take into account the resources of the current call, without inner calls.
// Has to happen after marking holes in segments as accessed.
Expand Down Expand Up @@ -460,6 +460,7 @@ pub fn finalize_execution(
fn get_call_result(
runner: &CairoRunner,
syscall_handler: &SyscallHintProcessor<'_>,
tracked_resource: &TrackedResource,
) -> Result<CallResult, PostExecutionError> {
let return_result = runner.vm.get_return_values(5)?;
// Corresponds to the Cairo 1.0 enum:
Expand Down Expand Up @@ -496,7 +497,11 @@ fn get_call_result(
});
}

let gas_consumed = syscall_handler.base.call.initial_gas - gas;
let gas_consumed = match tracked_resource {
// Do not count Sierra gas in CairoSteps mode.
TrackedResource::CairoSteps => 0,
TrackedResource::SierraGas => syscall_handler.base.call.initial_gas - gas,
};
Ok(CallResult {
failed,
retdata: read_execution_retdata(runner, retdata_size, retdata_start)?,
Expand Down
32 changes: 10 additions & 22 deletions crates/blockifier/src/execution/execution_utils.rs
Original file line number Diff line number Diff line change
Expand Up @@ -57,33 +57,21 @@ pub fn execute_entry_point_call_wrapper(
context: &mut EntryPointExecutionContext,
remaining_gas: &mut u64,
) -> EntryPointExecutionResult<CallInfo> {
let contract_tracked_resource = compiled_class.tracked_resource(
let current_tracked_resource = compiled_class.tracked_resource(
&context.versioned_constants().min_compiler_version_for_sierra_gas,
context.tx_context.tx_info.gas_mode(),
context.tracked_resource_stack.last(),
);
if current_tracked_resource == TrackedResource::CairoSteps {
// Override the initial gas with a high value so it won't limit the run.
call.initial_gas = context.versioned_constants().default_initial_gas_cost();
}
let orig_call = call.clone();

// Note: no return statements (explicit or implicit) should be added between the push and the
// pop commands.

// Once we ran with CairoSteps, we will continue to run using it for all nested calls.
match context.tracked_resource_stack.last() {
Some(TrackedResource::CairoSteps) => {
context.tracked_resource_stack.push(TrackedResource::CairoSteps)
}
Some(TrackedResource::SierraGas) => {
if contract_tracked_resource == TrackedResource::CairoSteps {
// Switching from SierraGas to CairoSteps: override initial_gas with a high value so
// it won't limit the run.
call.initial_gas = context.versioned_constants().default_initial_gas_cost();
};
context.tracked_resource_stack.push(contract_tracked_resource)
}
None => context.tracked_resource_stack.push(contract_tracked_resource),
};

let orig_call = call.clone();
context.tracked_resource_stack.push(current_tracked_resource);
let res = execute_entry_point_call(call, compiled_class, state, context);
let current_tracked_resource =
context.tracked_resource_stack.pop().expect("Unexpected empty tracked resource.");
context.tracked_resource_stack.pop().expect("Unexpected empty tracked resource.");

match res {
Ok(call_info) => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -221,16 +221,19 @@ fn test_tracked_resources_nested(
calldata: concated_calldata,
..trivial_external_entry_point_new(sierra_gas_contract)
};
let execution = entry_point_call.execute_directly(&mut state).unwrap();
let main_call_info = entry_point_call.execute_directly(&mut state).unwrap();

assert_eq!(execution.tracked_resource, TrackedResource::SierraGas);
let first_call_info = execution.inner_calls.first().unwrap();
assert_eq!(first_call_info.tracked_resource, TrackedResource::CairoSteps);
assert_eq!(
first_call_info.inner_calls.first().unwrap().tracked_resource,
TrackedResource::CairoSteps
);
assert_eq!(main_call_info.tracked_resource, TrackedResource::SierraGas);
assert_ne!(main_call_info.execution.gas_consumed, 0);

let first_inner_call = main_call_info.inner_calls.first().unwrap();
assert_eq!(first_inner_call.tracked_resource, TrackedResource::CairoSteps);
assert_eq!(first_inner_call.execution.gas_consumed, 0);
let inner_inner_call = first_inner_call.inner_calls.first().unwrap();
assert_eq!(inner_inner_call.tracked_resource, TrackedResource::CairoSteps);
assert_eq!(inner_inner_call.execution.gas_consumed, 0);

let second_inner_call_info = execution.inner_calls.get(1).unwrap();
assert_eq!(second_inner_call_info.tracked_resource, TrackedResource::SierraGas);
let second_inner_call = main_call_info.inner_calls.get(1).unwrap();
assert_eq!(second_inner_call.tracked_resource, TrackedResource::SierraGas);
assert_ne!(second_inner_call.execution.gas_consumed, 0);
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@ use cairo_vm::vm::runners::cairo_runner::ExecutionResources;
use pretty_assertions::assert_eq;
use starknet_api::abi::abi_utils::selector_from_name;
use starknet_api::execution_resources::GasAmount;
use starknet_api::transaction::fields::GasVectorComputationMode;
use starknet_api::{calldata, felt, storage_key};
use test_case::test_case;

Expand Down Expand Up @@ -172,7 +171,7 @@ fn test_nested_library_call(cairo_version: CairoVersion) {
// The default VersionedConstants is used in the execute_directly call bellow.
let tracked_resource = test_contract.get_runnable_class().tracked_resource(
&VersionedConstants::create_for_testing().min_compiler_version_for_sierra_gas,
GasVectorComputationMode::All,
None,
);

let nested_storage_call_info = CallInfo {
Expand Down
35 changes: 18 additions & 17 deletions crates/blockifier/src/transaction/transactions_test.rs
Original file line number Diff line number Diff line change
Expand Up @@ -229,7 +229,12 @@ fn expected_validate_call_info(
builtin_instance_counter: HashMap::from([(BuiltinName::range_check, n_range_checks)]),
}
.filter_unused_builtins();
let initial_gas = user_initial_gas.unwrap_or(GasAmount(default_initial_gas_cost())).0;
let initial_gas = match tracked_resource {
TrackedResource::CairoSteps => default_initial_gas_cost(),
TrackedResource::SierraGas => {
user_initial_gas.unwrap_or(GasAmount(default_initial_gas_cost())).0
}
};

Some(CallInfo {
call: CallEntryPoint {
Expand Down Expand Up @@ -479,10 +484,9 @@ fn test_invoke_tx(

let actual_execution_info = invoke_tx.execute(state, block_context, true, true).unwrap();

let tracked_resource = account_contract.get_runnable_class().tracked_resource(
&versioned_constants.min_compiler_version_for_sierra_gas,
tx_context.tx_info.gas_mode(),
);
let tracked_resource = account_contract
.get_runnable_class()
.tracked_resource(&versioned_constants.min_compiler_version_for_sierra_gas, None);
if tracked_resource == TrackedResource::CairoSteps {
// In CairoSteps mode, the initial gas is set to the default once before the validate call.
expected_arguments.inner_call_initial_gas -=
Expand Down Expand Up @@ -1547,10 +1551,9 @@ fn test_declare_tx(
class_hash,
account.get_class_hash(),
sender_address,
account.get_runnable_class().tracked_resource(
&versioned_constants.min_compiler_version_for_sierra_gas,
tx_context.tx_info.gas_mode(),
),
account
.get_runnable_class()
.tracked_resource(&versioned_constants.min_compiler_version_for_sierra_gas, None),
if tx_version >= TransactionVersion::THREE {
user_initial_gas_from_bounds(default_all_resource_bounds)
} else {
Expand Down Expand Up @@ -1762,10 +1765,9 @@ fn test_deploy_account_tx(
validate_calldata,
deployed_account_address,
cairo_version,
account.get_runnable_class().tracked_resource(
&versioned_constants.min_compiler_version_for_sierra_gas,
tx_context.tx_info.gas_mode(),
),
account
.get_runnable_class()
.tracked_resource(&versioned_constants.min_compiler_version_for_sierra_gas, None),
user_initial_gas,
);

Expand Down Expand Up @@ -2299,10 +2301,9 @@ fn test_l1_handler(#[values(false, true)] use_kzg_da: bool) {
builtin_instance_counter: HashMap::from([(BuiltinName::range_check, 6)]),
}),
accessed_storage_keys: HashSet::from_iter(vec![accessed_storage_key]),
tracked_resource: test_contract.get_runnable_class().tracked_resource(
&versioned_constants.min_compiler_version_for_sierra_gas,
GasVectorComputationMode::NoL2Gas,
),
tracked_resource: test_contract
.get_runnable_class()
.tracked_resource(&versioned_constants.min_compiler_version_for_sierra_gas, None),
..Default::default()
};

Expand Down
Loading