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 23, 2024
1 parent 17de6e7 commit 2229bee
Show file tree
Hide file tree
Showing 2 changed files with 45 additions and 12 deletions.
41 changes: 33 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,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::OUT_OF_GAS_ERROR;
use crate::state::state_api::State;
Expand Down Expand Up @@ -66,7 +69,6 @@ impl<'state> NativeSyscallHandler<'state> {
}
}

#[allow(dead_code)]
fn execute_inner_call(
&mut self,
entry_point: CallEntryPoint,
Expand Down Expand Up @@ -156,12 +158,35 @@ 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,
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), REQUIRED_GAS_LIBRARY_CALL_TEST; "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), REQUIRED_GAS_LIBRARY_CALL_TEST; "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 2229bee

Please sign in to comment.