#![deny(warnings)]
use cairo_vm::felt::Felt252;
use starknet_in_rust::{
execution::{
execution_entry_point::ExecutionEntryPoint,
objects::{CallInfo, CallType, TransactionExecutionContext},
},
state::{
contract_state::ContractState, in_memory_state_reader::InMemoryStateReader,
structs::ExecutionResourcesManager,
},
state::cached_state::CachedState,
definitions::{
constants::TRANSACTION_VERSION,
block_context::BlockContext,
},
services::api::contract_class::{ContractClass, EntryPointType},
utils::{calculate_sn_keccak, Address},
};
use std::path::Path;
fn test_contract(
contract_path: impl AsRef<Path>,
entry_point: &str,
call_data: Vec<Felt252>,
return_data: impl Into<Vec<Felt252>>,
) {
let contract_class = ContractClass::try_from(contract_path.as_ref().to_path_buf())
.expect("Could not load contract from JSON");
let contract_address = Address(1111.into());
let class_hash = [1; 32];
let block_context = BlockContext::default();
let tx_execution_context =
TransactionExecutionContext::create_for_testing(
Address(0.into()),
10,
0.into(),
block_context.invoke_tx_max_n_steps(),
TRANSACTION_VERSION,
);
let contract_state = ContractState::new(
class_hash,
tx_execution_context.nonce(),
Default::default(),
);
let mut state_reader = InMemoryStateReader::new(HashMap::new(), HashMap::new());
state_reader
.contract_states_mut()
.insert(contract_address, contract_state);
let mut state = CachedState::new(
state_reader,
Some([(class_hash, contract_class)].iter().collect()),
);
let caller_address = Address(0.into());
let entry_point_selector = Felt252::from_bytes_be(&calculate_sn_keccak(entry_point.as_bytes()));
let entry_point = ExecutionEntryPoint::new(
contract_address,
call_data,
entry_point_selector,
caller_address,
EntryPointType::External,
CallType::Delegate.into(),
class_hash.into(),
);
let mut resources_manager = ExecutionResourcesManager::default();
assert_eq!(
entry_point
.execute(
&mut state,
&block_context,
&mut resources_manager,
&tx_execution_context,
)
.expect("Could not execute contract"),
CallInfo {
contract_address,
caller_address,
entry_point_type: EntryPointType::External.into(),
call_type: CallType::Delegate.into(),
class_hash: class_hash.into(),
entry_point_selector: Some(entry_point_selector),
calldata: call_data.into(),
retdata: return_data.into(),
..Default::default()
},
);
}
#[test]
fn test_fibonacci(){
test_contract(
"starknet_programs/fibonacci.json",
"fib",
[1.into(), 1.into(), 10.into()].to_vec(),
[144.into()].to_vec(),
);
}
#[test]
fn test_factorial(){
test_contract("starknet_programs/factorial.json",
"factorial",
[10.into()].to_vec(),
[3628800.into()].to_vec()
);
}