Skip to content

Commit

Permalink
feat(blockifier): add call_contract cairo native syscall
Browse files Browse the repository at this point in the history
  • Loading branch information
PearsonWhite committed Oct 25, 2024
1 parent f9d4b21 commit 8e422b7
Show file tree
Hide file tree
Showing 2 changed files with 60 additions and 16 deletions.
55 changes: 47 additions & 8 deletions crates/blockifier/src/execution/native/syscall_handler.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
use std::collections::HashSet;
use std::hash::RandomState;
use std::sync::Arc;

use cairo_native::starknet::{
ExecutionInfo,
Expand All @@ -11,14 +12,21 @@ use cairo_native::starknet::{
U256,
};
use cairo_vm::vm::runners::cairo_runner::ExecutionResources;
use starknet_api::contract_class::EntryPointType;
use starknet_api::core::{ContractAddress, EntryPointSelector};
use starknet_api::state::StorageKey;
use starknet_api::transaction::Calldata;
use starknet_types_core::felt::Felt;

use crate::execution::call_info::{CallInfo, OrderedEvent, OrderedL2ToL1Message, Retdata};
use crate::execution::entry_point::{CallEntryPoint, EntryPointExecutionContext};
use crate::execution::common_hints::ExecutionMode;
use crate::execution::entry_point::{CallEntryPoint, CallType, EntryPointExecutionContext};
use crate::execution::native::utils::encode_str_as_felts;
use crate::execution::syscalls::hint_processor::{SyscallCounter, OUT_OF_GAS_ERROR};
use crate::execution::syscalls::hint_processor::{
SyscallCounter,
SyscallExecutionError,
OUT_OF_GAS_ERROR,
};
use crate::execution::syscalls::SyscallSelector;
use crate::state::state_api::State;

Expand Down Expand Up @@ -75,7 +83,6 @@ impl<'state> NativeSyscallHandler<'state> {
*syscall_count += n
}

#[allow(dead_code)]
fn execute_inner_call(
&mut self,
entry_point: CallEntryPoint,
Expand Down Expand Up @@ -181,12 +188,44 @@ impl<'state> StarknetSyscallHandler for &mut NativeSyscallHandler<'state> {

fn call_contract(
&mut self,
_address: Felt,
_entry_point_selector: Felt,
_calldata: &[Felt],
_remaining_gas: &mut u128,
address: Felt,
entry_point_selector: Felt,
calldata: &[Felt],
remaining_gas: &mut u128,
) -> SyscallResult<Vec<Felt>> {
todo!("Implement call_contract syscall.");
self.substract_syscall_gas_cost(
remaining_gas,
SyscallSelector::CallContract,
self.context.gas_costs().call_contract_gas_cost,
)?;

let contract_address = ContractAddress::try_from(address)
.expect("Failed to convert address argument to a ContractAddress");
if self.context.execution_mode == ExecutionMode::Validate
&& self.contract_address != contract_address
{
let err = SyscallExecutionError::InvalidSyscallInExecutionMode {
syscall_name: "call_contract".to_string(),
execution_mode: self.context.execution_mode,
};
return Err(encode_str_as_felts(&err.to_string()));
}

let wrapper_calldata = Calldata(Arc::new(calldata.to_vec()));

let entry_point = CallEntryPoint {
class_hash: None,
code_address: Some(contract_address),
entry_point_type: EntryPointType::External,
entry_point_selector: EntryPointSelector(entry_point_selector),
calldata: wrapper_calldata,
storage_address: contract_address,
caller_address: self.contract_address,
call_type: CallType::Call,
initial_gas: u64::try_from(*remaining_gas).unwrap(),
};

Ok(self.execute_inner_call(entry_point, remaining_gas)?.0)
}

fn storage_read(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,12 @@ fn test_call_contract_that_panics() {
);
}

#[test_case(
FeatureContract::TestContract(CairoVersion::Native),
FeatureContract::TestContract(CairoVersion::Native),
191870;
"Call Contract between two contracts using Native"
)]
#[test_case(
FeatureContract::TestContract(CairoVersion::Cairo1),
FeatureContract::TestContract(CairoVersion::Cairo1),
Expand Down Expand Up @@ -102,8 +108,10 @@ fn test_call_contract(
/// Cairo0 / Cairo1 calls to Cairo0 / Cairo1.
#[rstest]
fn test_track_resources(
#[values(CairoVersion::Cairo0, CairoVersion::Cairo1)] outer_version: CairoVersion,
#[values(CairoVersion::Cairo0, CairoVersion::Cairo1)] inner_version: CairoVersion,
#[values(CairoVersion::Cairo0, CairoVersion::Cairo1, CairoVersion::Native)]
outer_version: CairoVersion,
#[values(CairoVersion::Cairo0, CairoVersion::Cairo1, CairoVersion::Native)]
inner_version: CairoVersion,
) {
let outer_contract = FeatureContract::TestContract(outer_version);
let inner_contract = FeatureContract::TestContract(inner_version);
Expand Down Expand Up @@ -132,12 +140,9 @@ fn test_track_resources(
};
assert_eq!(execution.tracked_resource, expected_outer_resource);

let expected_inner_resource = match (outer_version, inner_version) {
(
CairoVersion::Cairo1 | CairoVersion::Native,
CairoVersion::Cairo1 | CairoVersion::Native,
) => TrackedResource::SierraGas,
_ => TrackedResource::CairoSteps,
let expected_inner_resource = match inner_version {
CairoVersion::Cairo0 => TrackedResource::CairoSteps,
CairoVersion::Cairo1 | CairoVersion::Native => TrackedResource::SierraGas,
};
assert_eq!(execution.inner_calls.first().unwrap().tracked_resource, expected_inner_resource);
}
Expand Down

0 comments on commit 8e422b7

Please sign in to comment.