Skip to content

Commit d5495c5

Browse files
starknet_os_flow_tests: migrate test_meta_tx
1 parent 7ebfd03 commit d5495c5

File tree

1 file changed

+208
-1
lines changed
  • crates/starknet_os_flow_tests/src

1 file changed

+208
-1
lines changed

crates/starknet_os_flow_tests/src/tests.rs

Lines changed: 208 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,10 @@ use starknet_api::test_utils::{
4646
DEFAULT_STRK_L2_GAS_PRICE,
4747
TEST_SEQUENCER_ADDRESS,
4848
};
49-
use starknet_api::transaction::constants::DEPLOY_CONTRACT_FUNCTION_ENTRY_POINT_NAME;
49+
use starknet_api::transaction::constants::{
50+
DEPLOY_CONTRACT_FUNCTION_ENTRY_POINT_NAME,
51+
EXECUTE_ENTRY_POINT_NAME,
52+
};
5053
use starknet_api::transaction::fields::{
5154
AllResourceBounds,
5255
Calldata,
@@ -2432,3 +2435,207 @@ async fn test_direct_execute_call() {
24322435
test_output.assert_storage_diff_eq(test_contract_address, HashMap::default());
24332436
test_output.assert_storage_diff_eq(dummy_account_address, HashMap::default());
24342437
}
2438+
2439+
#[rstest]
2440+
#[tokio::test]
2441+
async fn test_meta_tx() {
2442+
let meta_tx_contract = FeatureContract::MetaTx(RunnableCairo1::Casm);
2443+
let tx_info_contract = FeatureContract::TxInfoWriter;
2444+
let (mut test_manager, [meta_tx_contract_address, tx_info_contract_address]) =
2445+
TestManager::<DictStateReader>::new_with_default_initial_state([
2446+
(meta_tx_contract, calldata![]),
2447+
(tx_info_contract, calldata![]),
2448+
])
2449+
.await;
2450+
2451+
let argument = Felt::from(1234);
2452+
let signature = vec![Felt::from(5432), Felt::from(100)];
2453+
2454+
// Create and run an invoke tx.
2455+
let invoke_args = invoke_tx_args! {
2456+
sender_address: *FUNDED_ACCOUNT_ADDRESS,
2457+
nonce: test_manager.next_nonce(*FUNDED_ACCOUNT_ADDRESS),
2458+
calldata: create_calldata(
2459+
meta_tx_contract_address,
2460+
"execute_meta_tx_v0",
2461+
&[
2462+
vec![
2463+
**meta_tx_contract_address,
2464+
selector_from_name(EXECUTE_ENTRY_POINT_NAME).0,
2465+
Felt::ONE, // Calldata length.
2466+
argument,
2467+
signature.len().into()
2468+
],
2469+
signature.clone(),
2470+
vec![false.into()], // Should revert.
2471+
].concat()
2472+
),
2473+
resource_bounds: *NON_TRIVIAL_RESOURCE_BOUNDS,
2474+
};
2475+
let tx0 = InvokeTransaction::create(invoke_tx(invoke_args), &CHAIN_ID_FOR_TESTS).unwrap();
2476+
let tx0_hash = tx0.tx_hash();
2477+
let tx0_nonce = tx0.nonce();
2478+
assert!(tx0.nonce() != Nonce(Felt::ZERO));
2479+
test_manager.add_invoke_tx(tx0, None);
2480+
2481+
// Compute the meta-tx hash.
2482+
let meta_tx_hash0 = InvokeTransaction::create(
2483+
invoke_tx(invoke_tx_args! {
2484+
version: TransactionVersion::ZERO,
2485+
sender_address: meta_tx_contract_address,
2486+
calldata: calldata![argument],
2487+
max_fee: Fee(0),
2488+
}),
2489+
&CHAIN_ID_FOR_TESTS,
2490+
)
2491+
.unwrap()
2492+
.tx_hash();
2493+
2494+
// Call `tx_info_writer` with a meta transaction.
2495+
let argument1 = Felt::ONE;
2496+
let invoke_args = invoke_tx_args! {
2497+
sender_address: *FUNDED_ACCOUNT_ADDRESS,
2498+
nonce: test_manager.next_nonce(*FUNDED_ACCOUNT_ADDRESS),
2499+
calldata: create_calldata(
2500+
meta_tx_contract_address,
2501+
"execute_meta_tx_v0",
2502+
&[
2503+
vec![
2504+
**tx_info_contract_address,
2505+
selector_from_name(EXECUTE_ENTRY_POINT_NAME).0,
2506+
Felt::ONE, // Calldata length.
2507+
argument1,
2508+
signature.len().into(),
2509+
],
2510+
signature.clone(),
2511+
vec![false.into()], // Should revert.
2512+
].concat()
2513+
),
2514+
resource_bounds: *NON_TRIVIAL_RESOURCE_BOUNDS,
2515+
};
2516+
let tx1 = InvokeTransaction::create(invoke_tx(invoke_args), &CHAIN_ID_FOR_TESTS).unwrap();
2517+
assert!(tx1.nonce() != Nonce(Felt::ZERO));
2518+
let tx1_hash = tx1.tx_hash();
2519+
let tx1_nonce = tx1.nonce();
2520+
test_manager.add_invoke_tx(tx1, None);
2521+
2522+
// Compute the meta-tx hash.
2523+
let meta_tx_hash1 = InvokeTransaction::create(
2524+
invoke_tx(invoke_tx_args! {
2525+
version: TransactionVersion::ZERO,
2526+
sender_address: tx_info_contract_address,
2527+
calldata: calldata![argument1],
2528+
max_fee: Fee(0),
2529+
}),
2530+
&CHAIN_ID_FOR_TESTS,
2531+
)
2532+
.unwrap()
2533+
.tx_hash();
2534+
2535+
// Check that calling an entry point other than '__execute__` fails.
2536+
let invoke_args = invoke_tx_args! {
2537+
sender_address: *FUNDED_ACCOUNT_ADDRESS,
2538+
nonce: test_manager.next_nonce(*FUNDED_ACCOUNT_ADDRESS),
2539+
calldata: create_calldata(
2540+
meta_tx_contract_address,
2541+
"execute_meta_tx_v0",
2542+
&[
2543+
vec![
2544+
**meta_tx_contract_address,
2545+
selector_from_name("foo").0,
2546+
Felt::ZERO,
2547+
signature.len().into()
2548+
],
2549+
signature.clone(),
2550+
vec![true.into()] // Should revert.
2551+
].concat()
2552+
),
2553+
resource_bounds: *NON_TRIVIAL_RESOURCE_BOUNDS,
2554+
};
2555+
let tx2 = InvokeTransaction::create(invoke_tx(invoke_args), &CHAIN_ID_FOR_TESTS).unwrap();
2556+
assert!(tx2.nonce() != Nonce(Felt::ZERO));
2557+
let tx2_hash = tx2.tx_hash();
2558+
let tx2_nonce = tx2.nonce();
2559+
test_manager.add_invoke_tx(tx2, None);
2560+
2561+
// Construct the expected storage diff for each of the two contracts.
2562+
// All zero-valued keys should be filtered out (as they don't appear in the state diff).
2563+
let calldata_key = selector_from_name("call_data").0;
2564+
let calldata_item_keys: Vec<Felt> =
2565+
(0..4u8).map(|i| Pedersen::hash(&calldata_key, &i.into())).collect();
2566+
let no_argument = Felt::from_bytes_be_slice(b"NO_ARGUMENT");
2567+
let no_signature = Felt::from_bytes_be_slice(b"NO_SIGNATURE");
2568+
let expected_meta_tx_contract_diffs: HashMap<Felt, Felt> = HashMap::from_iter([
2569+
(calldata_key, Felt::from(4)), // Size of `call_data` vector.
2570+
// Inside the meta-tx.
2571+
(calldata_item_keys[0], Felt::ZERO), // caller_address.
2572+
(calldata_item_keys[0] + Felt::ONE, **meta_tx_contract_address), /* account_contract_address. */
2573+
(calldata_item_keys[0] + Felt::TWO, Felt::ZERO), // tx_version.
2574+
(calldata_item_keys[0] + Felt::THREE, argument), // Argument.
2575+
(calldata_item_keys[0] + Felt::from(4u8), *meta_tx_hash0), // transaction_hash.
2576+
(calldata_item_keys[0] + Felt::from(5u8), signature[0]), // signature.
2577+
(calldata_item_keys[0] + Felt::from(6u8), Felt::ZERO), // max_fee.
2578+
(calldata_item_keys[0] + Felt::from(7u8), Felt::ZERO), // resource_bound_len.
2579+
(calldata_item_keys[0] + Felt::from(8u8), Felt::ZERO), // nonce.
2580+
// Outside the meta-tx.
2581+
(calldata_item_keys[1], ***FUNDED_ACCOUNT_ADDRESS), // caller_address.
2582+
(calldata_item_keys[1] + Felt::ONE, ***FUNDED_ACCOUNT_ADDRESS), // account_contract_address.
2583+
(calldata_item_keys[1] + Felt::TWO, Felt::THREE), // tx_version.
2584+
(calldata_item_keys[1] + Felt::THREE, no_argument), // Argument.
2585+
(calldata_item_keys[1] + Felt::from(4u8), *tx0_hash), // transaction_hash.
2586+
(calldata_item_keys[1] + Felt::from(5u8), no_signature), // signature.
2587+
(calldata_item_keys[1] + Felt::from(6u8), Felt::ZERO), // max_fee.
2588+
(calldata_item_keys[1] + Felt::from(7u8), Felt::THREE), // resource_bound_len.
2589+
(calldata_item_keys[1] + Felt::from(8u8), *tx0_nonce), // nonce.
2590+
// Outside the meta-tx (second tx).
2591+
(calldata_item_keys[2], ***FUNDED_ACCOUNT_ADDRESS), // caller_address.
2592+
(calldata_item_keys[2] + Felt::ONE, ***FUNDED_ACCOUNT_ADDRESS), // account_contract_address.
2593+
(calldata_item_keys[2] + Felt::TWO, Felt::THREE), // tx_version.
2594+
(calldata_item_keys[2] + Felt::THREE, no_argument), // Argument.
2595+
(calldata_item_keys[2] + Felt::from(4u8), *tx1_hash), // transaction_hash.
2596+
(calldata_item_keys[2] + Felt::from(5u8), no_signature), // signature.
2597+
(calldata_item_keys[2] + Felt::from(6u8), Felt::ZERO), // max_fee.
2598+
(calldata_item_keys[2] + Felt::from(7u8), Felt::THREE), // resource_bound_len.
2599+
(calldata_item_keys[2] + Felt::from(8u8), *tx1_nonce), // nonce.
2600+
// Outside the meta-tx (third tx).
2601+
(calldata_item_keys[3], ***FUNDED_ACCOUNT_ADDRESS), // caller_address.
2602+
(calldata_item_keys[3] + Felt::ONE, ***FUNDED_ACCOUNT_ADDRESS), // account_contract_address.
2603+
(calldata_item_keys[3] + Felt::TWO, Felt::THREE), // tx_version.
2604+
(calldata_item_keys[3] + Felt::THREE, no_argument), // Argument.
2605+
(calldata_item_keys[3] + Felt::from(4u8), *tx2_hash), // transaction_hash.
2606+
(calldata_item_keys[3] + Felt::from(5u8), no_signature), // signature.
2607+
(calldata_item_keys[3] + Felt::from(6u8), Felt::ZERO), // max_fee.
2608+
(calldata_item_keys[3] + Felt::from(7u8), Felt::THREE), // resource_bound_len.
2609+
(calldata_item_keys[3] + Felt::from(8u8), *tx2_nonce), // nonce.
2610+
].into_iter().filter(|(_, v)| *v != Felt::ZERO));
2611+
let expected_tx_info_writer_diffs: HashMap<Felt, Felt> = HashMap::from_iter(
2612+
[
2613+
(**get_storage_var_address("version", &[Felt::ZERO]), Felt::ZERO),
2614+
(
2615+
**get_storage_var_address("account_contract_address", &[Felt::ZERO]),
2616+
**tx_info_contract_address,
2617+
),
2618+
(**get_storage_var_address("max_fee", &[Felt::ZERO]), Felt::ZERO),
2619+
(**get_storage_var_address("signature_len", &[Felt::ZERO]), Felt::TWO),
2620+
(**get_storage_var_address("transaction_hash", &[Felt::ZERO]), *meta_tx_hash1),
2621+
(
2622+
**get_storage_var_address("chain_id", &[Felt::ZERO]),
2623+
Felt::try_from(&*CHAIN_ID_FOR_TESTS).unwrap(),
2624+
),
2625+
(**get_storage_var_address("nonce", &[Felt::ZERO]), Felt::ZERO),
2626+
]
2627+
.into_iter()
2628+
.filter(|(_, v)| *v != Felt::ZERO),
2629+
);
2630+
2631+
// Run the test and verify the storage changes.
2632+
let test_output = test_manager
2633+
.execute_test_with_default_block_contexts(&TestParameters {
2634+
use_kzg_da: true,
2635+
..Default::default()
2636+
})
2637+
.await;
2638+
test_output.perform_default_validations();
2639+
test_output.assert_storage_diff_eq(meta_tx_contract_address, expected_meta_tx_contract_diffs);
2640+
test_output.assert_storage_diff_eq(tx_info_contract_address, expected_tx_info_writer_diffs);
2641+
}

0 commit comments

Comments
 (0)