Skip to content

Commit

Permalink
feat(blockifier): add library_call 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 4c0a5bd
Show file tree
Hide file tree
Showing 2 changed files with 46 additions and 13 deletions.
43 changes: 34 additions & 9 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,12 +12,14 @@ use cairo_native::starknet::{
U256,
};
use cairo_vm::vm::runners::cairo_runner::ExecutionResources;
use starknet_api::core::{ContractAddress, EntryPointSelector};
use starknet_api::contract_class::EntryPointType;
use starknet_api::core::{ClassHash, 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::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::SyscallSelector;
Expand Down Expand Up @@ -69,13 +72,11 @@ impl<'state> NativeSyscallHandler<'state> {
}
}

#[allow(dead_code)]
fn increment_syscall_count_by(&mut self, selector: &SyscallSelector, n: usize) {
let syscall_count = self.syscall_counter.entry(*selector).or_default();
*syscall_count += n
}

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

fn library_call(
&mut self,
_class_hash: Felt,
_function_selector: Felt,
_calldata: &[Felt],
_remaining_gas: &mut u128,
class_hash: Felt,
function_selector: Felt,
calldata: &[Felt],
remaining_gas: &mut u128,
) -> SyscallResult<Vec<Felt>> {
todo!("Implement library_call syscall.");
self.substract_syscall_gas_cost(
remaining_gas,
SyscallSelector::LibraryCall,
self.context.gas_costs().library_call_gas_cost,
)?;

let class_hash = ClassHash(class_hash);

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

let entry_point = CallEntryPoint {
class_hash: Some(class_hash),
code_address: None,
entry_point_type: EntryPointType::External,
entry_point_selector: EntryPointSelector(function_selector),
calldata: wrapper_calldata,
// The call context remains the same in a library call.
storage_address: self.contract_address,
caller_address: self.caller_address,
call_type: CallType::Delegate,
initial_gas: u64::try_from(*remaining_gas)
.expect("Failed to convert gas (u128 -> u64)"),
};

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

fn call_contract(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ use crate::test_utils::{
};
use crate::versioned_constants::VersionedConstants;

#[test_case(FeatureContract::TestContract(CairoVersion::Native), 189470; "Native")]
#[test_case(FeatureContract::TestContract(CairoVersion::Cairo1), REQUIRED_GAS_LIBRARY_CALL_TEST; "VM")]
fn test_library_call(test_contract: FeatureContract, expected_gas: u64) {
let chain_info = &ChainInfo::create_for_testing();
Expand Down Expand Up @@ -60,6 +61,7 @@ fn test_library_call(test_contract: FeatureContract, expected_gas: u64) {
);
}

#[test_case(FeatureContract::TestContract(CairoVersion::Native); "Native")]
#[test_case(FeatureContract::TestContract(CairoVersion::Cairo1); "VM")]
fn test_library_call_assert_fails(test_contract: FeatureContract) {
let chain_info = &ChainInfo::create_for_testing();
Expand All @@ -81,12 +83,18 @@ fn test_library_call_assert_fails(test_contract: FeatureContract) {

let call_info = entry_point_call.execute_directly(&mut state).unwrap();
assert!(call_info.execution.failed);
assert_eq!(
format_panic_data(&call_info.execution.retdata.0),
"(0x7820213d2079 ('x != y'), 0x454e545259504f494e545f4641494c4544 ('ENTRYPOINT_FAILED'))"
);

let expected_err = match test_contract.cairo_version() {
CairoVersion::Cairo0 | CairoVersion::Cairo1 => {
"(0x7820213d2079 ('x != y'), 0x454e545259504f494e545f4641494c4544 \
('ENTRYPOINT_FAILED'))"
}
CairoVersion::Native => "0x7820213d2079 ('x != y')",
};
assert_eq!(format_panic_data(&call_info.execution.retdata.0), expected_err);
}

#[test_case(FeatureContract::TestContract(CairoVersion::Native), 518110; "Native")]
#[test_case(FeatureContract::TestContract(CairoVersion::Cairo1), 478110; "VM")]
fn test_nested_library_call(test_contract: FeatureContract, expected_gas: u64) {
let chain_info = &ChainInfo::create_for_testing();
Expand Down

0 comments on commit 4c0a5bd

Please sign in to comment.