Skip to content

Commit 033d444

Browse files
starknet_os_flow_tests: migrate test_reverted_call
1 parent 200080b commit 033d444

File tree

1 file changed

+138
-0
lines changed
  • crates/starknet_os_flow_tests/src

1 file changed

+138
-0
lines changed

crates/starknet_os_flow_tests/src/tests.rs

Lines changed: 138 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2083,3 +2083,141 @@ async fn test_initial_sierra_gas() {
20832083

20842084
test_output.perform_default_validations();
20852085
}
2086+
2087+
#[rstest]
2088+
#[tokio::test]
2089+
async fn test_reverted_call() {
2090+
let test_contract = FeatureContract::TestContract(CairoVersion::Cairo1(RunnableCairo1::Casm));
2091+
let test_class_hash = get_class_hash_of_feature_contract(test_contract);
2092+
let test_contract2 = FeatureContract::TestContract2;
2093+
let empty_contract = FeatureContract::Empty(CairoVersion::Cairo0);
2094+
let (mut test_manager, [main_contract_address, test_contract2_address, empty_contract_address]) =
2095+
TestManager::<DictStateReader>::new_with_default_initial_state([
2096+
// The `my_storage_var` cell is initialized as the sum of the ctor args in the
2097+
// constructor. This cell is also used in revert tests, so it must be
2098+
// initialized to zero.
2099+
(test_contract, calldata![Felt::ZERO, Felt::ZERO]),
2100+
(test_contract2, calldata![]),
2101+
(empty_contract, calldata![]),
2102+
])
2103+
.await;
2104+
2105+
// Tests 1+2.
2106+
2107+
// Tell inner contract to panic.
2108+
let to_panic = true;
2109+
for (inner_selector, is_meta_tx) in
2110+
[("test_revert_helper", false), ("bad_selector", false), ("__execute__", true)]
2111+
{
2112+
// Test contract call to test_revert_helper.
2113+
let calldata = create_calldata(
2114+
main_contract_address,
2115+
"test_call_contract_revert",
2116+
&[
2117+
**main_contract_address,
2118+
selector_from_name(inner_selector).0,
2119+
Felt::TWO,
2120+
test_class_hash.0,
2121+
to_panic.into(),
2122+
is_meta_tx.into(),
2123+
],
2124+
);
2125+
test_manager.add_funded_account_invoke(invoke_tx_args! { calldata });
2126+
}
2127+
2128+
// Test call to cairo0 contracts with 0 and more then 0 entry points.
2129+
for (contract, address) in
2130+
[(empty_contract, empty_contract_address), (test_contract2, test_contract2_address)]
2131+
{
2132+
let class_hash = get_class_hash_of_feature_contract(contract);
2133+
let calldata = create_calldata(
2134+
main_contract_address,
2135+
"test_call_contract_revert",
2136+
&[
2137+
**address,
2138+
selector_from_name("bad_selector").0,
2139+
Felt::TWO,
2140+
class_hash.0,
2141+
to_panic.into(),
2142+
false.into(),
2143+
],
2144+
);
2145+
test_manager.add_funded_account_invoke(invoke_tx_args! { calldata });
2146+
2147+
// Test 3:
2148+
// - Contract A calls Contract B.
2149+
// - Contract B changes the storage value from 0 to 10.
2150+
// - Contract A calls Contract C.
2151+
// - Contract C changes the storage value from 10 to 17 and raises an exception.
2152+
// - Contract A checks that the storage value == 10.
2153+
let calldata = create_calldata(
2154+
main_contract_address,
2155+
"test_revert_with_inner_call_and_reverted_storage",
2156+
&[**main_contract_address, test_class_hash.0],
2157+
);
2158+
test_manager.add_funded_account_invoke(invoke_tx_args! { calldata });
2159+
}
2160+
2161+
// Test 4:
2162+
// - Contract A calls Contract B and asserts that the state remains unchanged.
2163+
// - Contract B calls Contract C and panics.
2164+
// - Contract C modifies the state but does not panic.
2165+
2166+
// Tell contract C not to panic:
2167+
let to_panic = false;
2168+
let contract_c_calldata = [test_class_hash.0, to_panic.into()];
2169+
2170+
// Create calldata recursively.
2171+
let contract_b_calldata = [
2172+
vec![
2173+
**main_contract_address,
2174+
selector_from_name("test_revert_helper").0,
2175+
contract_c_calldata.len().into(),
2176+
],
2177+
contract_c_calldata.to_vec(),
2178+
]
2179+
.concat();
2180+
let contract_a_calldata = [
2181+
vec![
2182+
**main_contract_address,
2183+
selector_from_name("middle_revert_contract").0,
2184+
contract_b_calldata.len().into(),
2185+
],
2186+
contract_b_calldata,
2187+
vec![false.into()], // is_meta_tx.
2188+
]
2189+
.concat();
2190+
2191+
// Call contract A.
2192+
let calldata =
2193+
create_calldata(main_contract_address, "test_call_contract_revert", &contract_a_calldata);
2194+
test_manager.add_funded_account_invoke(invoke_tx_args! { calldata });
2195+
2196+
// Run the test and assert only the fee token contract and the OS contracts have storage
2197+
// updates.
2198+
let test_output = test_manager
2199+
.execute_test_with_default_block_contexts(&TestParameters {
2200+
use_kzg_da: true,
2201+
..Default::default()
2202+
})
2203+
.await;
2204+
2205+
test_output.perform_default_validations();
2206+
2207+
let block_hash_contract_address = ContractAddress(
2208+
Const::BlockHashContractAddress.fetch_from_os_program().unwrap().try_into().unwrap(),
2209+
);
2210+
let expected_changed_addresses: HashSet<&ContractAddress> = HashSet::from_iter([
2211+
&*STRK_FEE_TOKEN_ADDRESS,
2212+
&*ALIAS_CONTRACT_ADDRESS,
2213+
&block_hash_contract_address,
2214+
]);
2215+
let actual_changed_addresses =
2216+
test_output.decompressed_state_diff.storage_updates.keys().collect::<HashSet<_>>();
2217+
assert!(
2218+
actual_changed_addresses.is_subset(&expected_changed_addresses),
2219+
"Expected changed addresses are not subset of actual changed addresses: actual changed \
2220+
addresses are {actual_changed_addresses:#?}, expected changed addresses are \
2221+
{expected_changed_addresses:#?}"
2222+
);
2223+
}

0 commit comments

Comments
 (0)