Skip to content

Commit 90a9881

Browse files
starknet_os_flow_tests: migrate test_meta_tx
1 parent c910561 commit 90a9881

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
@@ -49,7 +49,10 @@ use starknet_api::test_utils::{
4949
DEFAULT_STRK_L2_GAS_PRICE,
5050
TEST_SEQUENCER_ADDRESS,
5151
};
52-
use starknet_api::transaction::constants::DEPLOY_CONTRACT_FUNCTION_ENTRY_POINT_NAME;
52+
use starknet_api::transaction::constants::{
53+
DEPLOY_CONTRACT_FUNCTION_ENTRY_POINT_NAME,
54+
EXECUTE_ENTRY_POINT_NAME,
55+
};
5356
use starknet_api::transaction::fields::{
5457
AllResourceBounds,
5558
Calldata,
@@ -2598,3 +2601,207 @@ async fn test_direct_execute_call() {
25982601
test_output.assert_storage_diff_eq(test_contract_address, HashMap::default());
25992602
test_output.assert_storage_diff_eq(dummy_account_address, HashMap::default());
26002603
}
2604+
2605+
#[rstest]
2606+
#[tokio::test]
2607+
async fn test_meta_tx() {
2608+
let meta_tx_contract = FeatureContract::MetaTx(RunnableCairo1::Casm);
2609+
let tx_info_contract = FeatureContract::TxInfoWriter;
2610+
let (mut test_manager, mut nonce_manager, [meta_tx_contract_address, tx_info_contract_address]) =
2611+
TestManager::<DictStateReader>::new_with_default_initial_state([
2612+
(meta_tx_contract, calldata![]),
2613+
(tx_info_contract, calldata![]),
2614+
])
2615+
.await;
2616+
2617+
let argument = Felt::from(1234);
2618+
let signature = vec![Felt::from(5432), Felt::from(100)];
2619+
2620+
// Create and run an invoke tx.
2621+
let invoke_args = invoke_tx_args! {
2622+
sender_address: *FUNDED_ACCOUNT_ADDRESS,
2623+
nonce: nonce_manager.next(*FUNDED_ACCOUNT_ADDRESS),
2624+
calldata: create_calldata(
2625+
meta_tx_contract_address,
2626+
"execute_meta_tx_v0",
2627+
&[
2628+
vec![
2629+
**meta_tx_contract_address,
2630+
selector_from_name(EXECUTE_ENTRY_POINT_NAME).0,
2631+
Felt::ONE, // Calldata length.
2632+
argument,
2633+
signature.len().into()
2634+
],
2635+
signature.clone(),
2636+
vec![false.into()], // Should revert.
2637+
].concat()
2638+
),
2639+
resource_bounds: *NON_TRIVIAL_RESOURCE_BOUNDS,
2640+
};
2641+
let tx0 = InvokeTransaction::create(invoke_tx(invoke_args), &CHAIN_ID_FOR_TESTS).unwrap();
2642+
let tx0_hash = tx0.tx_hash();
2643+
let tx0_nonce = tx0.nonce();
2644+
assert!(tx0.nonce() != Nonce(Felt::ZERO));
2645+
test_manager.add_invoke_tx(tx0, None);
2646+
2647+
// Compute the meta-tx hash.
2648+
let meta_tx_hash0 = InvokeTransaction::create(
2649+
invoke_tx(invoke_tx_args! {
2650+
version: TransactionVersion::ZERO,
2651+
sender_address: meta_tx_contract_address,
2652+
calldata: calldata![argument],
2653+
max_fee: Fee(0),
2654+
}),
2655+
&CHAIN_ID_FOR_TESTS,
2656+
)
2657+
.unwrap()
2658+
.tx_hash();
2659+
2660+
// Call `tx_info_writer` with a meta transaction.
2661+
let argument1 = Felt::ONE;
2662+
let invoke_args = invoke_tx_args! {
2663+
sender_address: *FUNDED_ACCOUNT_ADDRESS,
2664+
nonce: nonce_manager.next(*FUNDED_ACCOUNT_ADDRESS),
2665+
calldata: create_calldata(
2666+
meta_tx_contract_address,
2667+
"execute_meta_tx_v0",
2668+
&[
2669+
vec![
2670+
**tx_info_contract_address,
2671+
selector_from_name(EXECUTE_ENTRY_POINT_NAME).0,
2672+
Felt::ONE, // Calldata length.
2673+
argument1,
2674+
signature.len().into(),
2675+
],
2676+
signature.clone(),
2677+
vec![false.into()], // Should revert.
2678+
].concat()
2679+
),
2680+
resource_bounds: *NON_TRIVIAL_RESOURCE_BOUNDS,
2681+
};
2682+
let tx1 = InvokeTransaction::create(invoke_tx(invoke_args), &CHAIN_ID_FOR_TESTS).unwrap();
2683+
assert!(tx1.nonce() != Nonce(Felt::ZERO));
2684+
let tx1_hash = tx1.tx_hash();
2685+
let tx1_nonce = tx1.nonce();
2686+
test_manager.add_invoke_tx(tx1, None);
2687+
2688+
// Compute the meta-tx hash.
2689+
let meta_tx_hash1 = InvokeTransaction::create(
2690+
invoke_tx(invoke_tx_args! {
2691+
version: TransactionVersion::ZERO,
2692+
sender_address: tx_info_contract_address,
2693+
calldata: calldata![argument1],
2694+
max_fee: Fee(0),
2695+
}),
2696+
&CHAIN_ID_FOR_TESTS,
2697+
)
2698+
.unwrap()
2699+
.tx_hash();
2700+
2701+
// Check that calling an entry point other than '__execute__` fails.
2702+
let invoke_args = invoke_tx_args! {
2703+
sender_address: *FUNDED_ACCOUNT_ADDRESS,
2704+
nonce: nonce_manager.next(*FUNDED_ACCOUNT_ADDRESS),
2705+
calldata: create_calldata(
2706+
meta_tx_contract_address,
2707+
"execute_meta_tx_v0",
2708+
&[
2709+
vec![
2710+
**meta_tx_contract_address,
2711+
selector_from_name("foo").0,
2712+
Felt::ZERO,
2713+
signature.len().into()
2714+
],
2715+
signature.clone(),
2716+
vec![true.into()] // Should revert.
2717+
].concat()
2718+
),
2719+
resource_bounds: *NON_TRIVIAL_RESOURCE_BOUNDS,
2720+
};
2721+
let tx2 = InvokeTransaction::create(invoke_tx(invoke_args), &CHAIN_ID_FOR_TESTS).unwrap();
2722+
assert!(tx2.nonce() != Nonce(Felt::ZERO));
2723+
let tx2_hash = tx2.tx_hash();
2724+
let tx2_nonce = tx2.nonce();
2725+
test_manager.add_invoke_tx(tx2, None);
2726+
2727+
// Construct the expected storage diff for each of the two contracts.
2728+
// All zero-valued keys should be filtered out (as they don't appear in the state diff).
2729+
let calldata_key = selector_from_name("call_data").0;
2730+
let calldata_item_keys: Vec<Felt> =
2731+
(0..4u8).map(|i| Pedersen::hash(&calldata_key, &i.into())).collect();
2732+
let no_argument = Felt::from_bytes_be_slice(b"NO_ARGUMENT");
2733+
let no_signature = Felt::from_bytes_be_slice(b"NO_SIGNATURE");
2734+
let expected_meta_tx_contract_diffs: HashMap<Felt, Felt> = HashMap::from_iter([
2735+
(calldata_key, Felt::from(4)), // Size of `call_data` vector.
2736+
// Inside the meta-tx.
2737+
(calldata_item_keys[0], Felt::ZERO), // caller_address.
2738+
(calldata_item_keys[0] + Felt::ONE, **meta_tx_contract_address), /* account_contract_address. */
2739+
(calldata_item_keys[0] + Felt::TWO, Felt::ZERO), // tx_version.
2740+
(calldata_item_keys[0] + Felt::THREE, argument), // Argument.
2741+
(calldata_item_keys[0] + Felt::from(4u8), *meta_tx_hash0), // transaction_hash.
2742+
(calldata_item_keys[0] + Felt::from(5u8), signature[0]), // signature.
2743+
(calldata_item_keys[0] + Felt::from(6u8), Felt::ZERO), // max_fee.
2744+
(calldata_item_keys[0] + Felt::from(7u8), Felt::ZERO), // resource_bound_len.
2745+
(calldata_item_keys[0] + Felt::from(8u8), Felt::ZERO), // nonce.
2746+
// Outside the meta-tx.
2747+
(calldata_item_keys[1], ***FUNDED_ACCOUNT_ADDRESS), // caller_address.
2748+
(calldata_item_keys[1] + Felt::ONE, ***FUNDED_ACCOUNT_ADDRESS), // account_contract_address.
2749+
(calldata_item_keys[1] + Felt::TWO, Felt::THREE), // tx_version.
2750+
(calldata_item_keys[1] + Felt::THREE, no_argument), // Argument.
2751+
(calldata_item_keys[1] + Felt::from(4u8), *tx0_hash), // transaction_hash.
2752+
(calldata_item_keys[1] + Felt::from(5u8), no_signature), // signature.
2753+
(calldata_item_keys[1] + Felt::from(6u8), Felt::ZERO), // max_fee.
2754+
(calldata_item_keys[1] + Felt::from(7u8), Felt::THREE), // resource_bound_len.
2755+
(calldata_item_keys[1] + Felt::from(8u8), *tx0_nonce), // nonce.
2756+
// Outside the meta-tx (second tx).
2757+
(calldata_item_keys[2], ***FUNDED_ACCOUNT_ADDRESS), // caller_address.
2758+
(calldata_item_keys[2] + Felt::ONE, ***FUNDED_ACCOUNT_ADDRESS), // account_contract_address.
2759+
(calldata_item_keys[2] + Felt::TWO, Felt::THREE), // tx_version.
2760+
(calldata_item_keys[2] + Felt::THREE, no_argument), // Argument.
2761+
(calldata_item_keys[2] + Felt::from(4u8), *tx1_hash), // transaction_hash.
2762+
(calldata_item_keys[2] + Felt::from(5u8), no_signature), // signature.
2763+
(calldata_item_keys[2] + Felt::from(6u8), Felt::ZERO), // max_fee.
2764+
(calldata_item_keys[2] + Felt::from(7u8), Felt::THREE), // resource_bound_len.
2765+
(calldata_item_keys[2] + Felt::from(8u8), *tx1_nonce), // nonce.
2766+
// Outside the meta-tx (third tx).
2767+
(calldata_item_keys[3], ***FUNDED_ACCOUNT_ADDRESS), // caller_address.
2768+
(calldata_item_keys[3] + Felt::ONE, ***FUNDED_ACCOUNT_ADDRESS), // account_contract_address.
2769+
(calldata_item_keys[3] + Felt::TWO, Felt::THREE), // tx_version.
2770+
(calldata_item_keys[3] + Felt::THREE, no_argument), // Argument.
2771+
(calldata_item_keys[3] + Felt::from(4u8), *tx2_hash), // transaction_hash.
2772+
(calldata_item_keys[3] + Felt::from(5u8), no_signature), // signature.
2773+
(calldata_item_keys[3] + Felt::from(6u8), Felt::ZERO), // max_fee.
2774+
(calldata_item_keys[3] + Felt::from(7u8), Felt::THREE), // resource_bound_len.
2775+
(calldata_item_keys[3] + Felt::from(8u8), *tx2_nonce), // nonce.
2776+
].into_iter().filter(|(_, v)| *v != Felt::ZERO));
2777+
let expected_tx_info_writer_diffs: HashMap<Felt, Felt> = HashMap::from_iter(
2778+
[
2779+
(**get_storage_var_address("version", &[Felt::ZERO]), Felt::ZERO),
2780+
(
2781+
**get_storage_var_address("account_contract_address", &[Felt::ZERO]),
2782+
**tx_info_contract_address,
2783+
),
2784+
(**get_storage_var_address("max_fee", &[Felt::ZERO]), Felt::ZERO),
2785+
(**get_storage_var_address("signature_len", &[Felt::ZERO]), Felt::TWO),
2786+
(**get_storage_var_address("transaction_hash", &[Felt::ZERO]), *meta_tx_hash1),
2787+
(
2788+
**get_storage_var_address("chain_id", &[Felt::ZERO]),
2789+
Felt::try_from(&*CHAIN_ID_FOR_TESTS).unwrap(),
2790+
),
2791+
(**get_storage_var_address("nonce", &[Felt::ZERO]), Felt::ZERO),
2792+
]
2793+
.into_iter()
2794+
.filter(|(_, v)| *v != Felt::ZERO),
2795+
);
2796+
2797+
// Run the test and verify the storage changes.
2798+
let test_output = test_manager
2799+
.execute_test_with_default_block_contexts(&TestParameters {
2800+
use_kzg_da: true,
2801+
..Default::default()
2802+
})
2803+
.await;
2804+
test_output.perform_default_validations();
2805+
test_output.assert_storage_diff_eq(meta_tx_contract_address, expected_meta_tx_contract_diffs);
2806+
test_output.assert_storage_diff_eq(tx_info_contract_address, expected_tx_info_writer_diffs);
2807+
}

0 commit comments

Comments
 (0)