Skip to content

Commit 308dc8e

Browse files
starknet_os_flow_tests: migrate test_meta_tx
1 parent e7bb1ee commit 308dc8e

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

0 commit comments

Comments
 (0)