Skip to content

Commit

Permalink
feat: add and fix deploy test
Browse files Browse the repository at this point in the history
  • Loading branch information
varex83 committed Oct 29, 2024
1 parent dfdae34 commit d455814
Show file tree
Hide file tree
Showing 8 changed files with 7,456 additions and 6,998 deletions.
14,322 changes: 7,355 additions & 6,967 deletions crates/blockifier/feature_contracts/cairo_native/compiled/test_contract.sierra.json

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
Expand Up @@ -71,39 +71,42 @@ mod TestContract {
.span()
}


#[external(v0)]
fn test_call_contract_revert(
ref self: ContractState,
contract_address: ContractAddress,
entry_point_selector: felt252,
calldata: Array::<felt252>
) {
match syscalls::call_contract_syscall(
contract_address, entry_point_selector, calldata.span())
{
Result::Ok(_) => panic!("Expected revert"),
Result::Err(errors) => {
let mut error_span = errors.span();
assert(
*error_span.pop_back().unwrap() == 'ENTRYPOINT_FAILED',
'Unexpected error',
);
},
};
// TODO(Yoni, 1/12/2024): test replace class once get_class_hash_at syscall is supported.
assert(self.my_storage_var.read() == 0, 'values should not change.');
fn test_call_two_contracts(
self: @ContractState,
contract_address_0: ContractAddress,
entry_point_selector_0: felt252,
calldata_0: Array::<felt252>,
contract_address_1: ContractAddress,
entry_point_selector_1: felt252,
calldata_1: Array::<felt252>,
) -> Span::<felt252> {
let res_0 = syscalls::call_contract_syscall(
contract_address_0,
entry_point_selector_0,
calldata_0.span(),
)
.unwrap_syscall();
let res_1 = syscalls::call_contract_syscall(
contract_address_1,
entry_point_selector_1,
calldata_1.span(),
)
.unwrap_syscall();
let mut res: Array::<felt252> = Default::default();
res.append_span(res_0.snapshot.span());
res.append_span(res_1.snapshot.span());
res.span()
}


#[external(v0)]
fn test_revert_helper(ref self: ContractState, class_hash: ClassHash) {
let dummy_span = array![0].span();
syscalls::emit_event_syscall(dummy_span, dummy_span).unwrap_syscall();
syscalls::replace_class_syscall(class_hash).unwrap_syscall();
syscalls::send_message_to_l1_syscall(17.try_into().unwrap(), dummy_span).unwrap_syscall();
self.my_storage_var.write(17);
panic!("test_revert_helper");
panic(array!['test_revert_helper']);
}

#[external(v0)]
Expand Down Expand Up @@ -605,4 +608,33 @@ mod TestContract {
let in1 = CircuitElement::<CircuitInput<0>> {};
(in1,).new_inputs().next([3, 0, 0, 0]);
}

#[external(v0)]
fn test_call_contract_revert(
ref self: ContractState,
contract_address: ContractAddress,
entry_point_selector: felt252,
calldata: Array::<felt252>
) {
match syscalls::call_contract_syscall(
contract_address, entry_point_selector, calldata.span())
{
Result::Ok(_) => panic!("Expected revert"),
Result::Err(errors) => {
let mut error_span = errors.span();
assert(
*error_span.pop_back().unwrap() == 'ENTRYPOINT_FAILED',
'Unexpected error',
);
let inner_error = *error_span.pop_back().unwrap();
if entry_point_selector == selector!("bad_selector") {
assert(inner_error == 'ENTRYPOINT_NOT_FOUND', 'Unexpected error');
} else {
assert(inner_error == 'test_revert_helper', 'Unexpected error');
}
},
};
// TODO(Yoni, 1/12/2024): test replace class once get_class_hash_at syscall is supported.
assert(self.my_storage_var.read() == 0, 'values should not change.');
}
}
2 changes: 2 additions & 0 deletions crates/blockifier/src/execution/errors.rs
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,8 @@ pub enum EntryPointExecutionError {
#[cfg(feature = "cairo_native")]
#[error(transparent)]
NativeUnexpectedError(#[from] NativeError),
#[error("Native execution error: {info}")]
NativeExecutionError { info: String },
#[error(transparent)]
PostExecutionError(#[from] PostExecutionError),
#[error(transparent)]
Expand Down
3 changes: 3 additions & 0 deletions crates/blockifier/src/execution/execution_utils.rs
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,9 @@ pub fn execute_entry_point_call_wrapper(
let current_tracked_resource =
context.tracked_resource_stack.pop().expect("Unexpected empty tracked resource.");

println!("enable_reverts: {:?}", context.versioned_constants().enable_reverts);
println!("res: {:?}", res);

match res {
Ok(call_info) => {
if call_info.execution.failed && !context.versioned_constants().enable_reverts {
Expand Down
18 changes: 14 additions & 4 deletions crates/blockifier/src/execution/native/entry_point_execution.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ use crate::execution::entry_point::{
use crate::execution::errors::{EntryPointExecutionError, PostExecutionError};
use crate::execution::native::contract_class::NativeContractClassV1;
use crate::execution::native::syscall_handler::NativeSyscallHandler;
use crate::execution::native::utils::decode_felts_as_str;
use crate::state::state_api::State;

pub fn execute_entry_point_call(
Expand All @@ -26,15 +27,24 @@ pub fn execute_entry_point_call(
let mut syscall_handler: NativeSyscallHandler<'_> =
NativeSyscallHandler::new(call, state, resources, context);

let execution_result = contract_class.executor.invoke_contract_dynamic(
let call_result = match contract_class.executor.invoke_contract_dynamic(
&function_id,
&syscall_handler.call.calldata.0.clone(),
Some(syscall_handler.call.initial_gas.into()),
&mut syscall_handler,
);
) {
Ok(res) if res.failure_flag => Err(EntryPointExecutionError::NativeExecutionError {
info: if !res.return_values.is_empty() {
decode_felts_as_str(&res.return_values)
} else {
String::from("Unknown error")
},
}),
Err(runner_err) => Err(EntryPointExecutionError::NativeUnexpectedError(runner_err)),
Ok(res) => Ok(res),
}?;

let call_result = execution_result.map_err(EntryPointExecutionError::NativeUnexpectedError)?;
create_callinfo(call_result, syscall_handler)
create_call_info(call, call_result, syscall_handler)
}

fn create_callinfo(
Expand Down
7 changes: 4 additions & 3 deletions crates/blockifier/src/execution/native/syscall_handler.rs
Original file line number Diff line number Diff line change
Expand Up @@ -170,8 +170,9 @@ impl<'state> StarknetSyscallHandler for &mut NativeSyscallHandler<'state> {
) -> SyscallResult<(Felt, Vec<Felt>)> {
self.substract_syscall_gas_cost(remaining_gas, self.context.gas_costs().deploy_gas_cost)?;

let deployer_address =
if deploy_from_zero { ContractAddress::default() } else { self.contract_address };
let deployer_address = self.contract_address;
let deployer_address_for_calculation =
if deploy_from_zero { ContractAddress::default() } else { deployer_address };

let class_hash = ClassHash(class_hash);
let wrapper_calldata = Calldata(Arc::new(calldata.to_vec()));
Expand All @@ -180,7 +181,7 @@ impl<'state> StarknetSyscallHandler for &mut NativeSyscallHandler<'state> {
ContractAddressSalt(contract_address_salt),
class_hash,
&wrapper_calldata,
deployer_address,
deployer_address_for_calculation,
)
.map_err(|err| encode_str_as_felts(&err.to_string()))?;

Expand Down
20 changes: 20 additions & 0 deletions crates/blockifier/src/execution/native/utils.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
use cairo_lang_starknet_classes::contract_class::ContractEntryPoint;
use itertools::Itertools;
use starknet_api::core::EntryPointSelector;
use starknet_types_core::felt::Felt;

Expand All @@ -20,3 +21,22 @@ pub fn encode_str_as_felts(msg: &str) -> Vec<Felt> {
}
encoding
}

pub fn decode_felts_as_str(encoding: &[Felt]) -> String {
let bytes_err: Vec<_> =
encoding.iter().flat_map(|felt| felt.to_bytes_be()[1..32].to_vec()).collect();

match String::from_utf8(bytes_err) {
Ok(s) => s.trim_matches('\0').to_owned(),
Err(_) => {
let err_msgs = encoding
.iter()
.map(|felt| match String::from_utf8(felt.to_bytes_be()[1..32].to_vec()) {
Ok(s) => format!("{} ({})", s.trim_matches('\0'), felt),
Err(_) => felt.to_string(),
})
.join(", ");
format!("[{}]", err_msgs)
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,7 @@ fn no_constructor(deployer_contract: FeatureContract, expected_gas: u64) {
}

#[test_case(FeatureContract::TestContract(CairoVersion::Cairo1);"VM")]
#[test_case(FeatureContract::TestContract(CairoVersion::Native);"Native")]
fn no_constructor_nonempty_calldata(deployer_contract: FeatureContract) {
let empty_contract = FeatureContract::Empty(CairoVersion::Cairo1);
let class_hash = empty_contract.get_class_hash();
Expand All @@ -87,7 +88,7 @@ fn no_constructor_nonempty_calldata(deployer_contract: FeatureContract) {
constructor."
));
}

#[test_case(FeatureContract::TestContract(CairoVersion::Native),226750, 5210;"Native")]
#[test_case(FeatureContract::TestContract(CairoVersion::Cairo1),216750, 5210;"VM")]
fn with_constructor(
deployer_contract: FeatureContract,
Expand Down Expand Up @@ -151,6 +152,7 @@ fn with_constructor(
}

#[test_case(FeatureContract::TestContract(CairoVersion::Cairo1);"VM")]
#[test_case(FeatureContract::TestContract(CairoVersion::Native);"Native")]
fn to_unavailable_address(deployer_contract: FeatureContract) {
let empty_contract = FeatureContract::Empty(CairoVersion::Cairo1);
let mut state = test_state(
Expand Down

0 comments on commit d455814

Please sign in to comment.