Skip to content

Commit

Permalink
Merge pull request #61 from starkware-libs/arni/transaction_validator…
Browse files Browse the repository at this point in the history
…/stateless/tests/orgenize_tests

test: organize tests for maintainability
  • Loading branch information
ArniStarkware authored Apr 21, 2024
2 parents e7101f8 + e693fd7 commit d545119
Show file tree
Hide file tree
Showing 2 changed files with 160 additions and 142 deletions.
33 changes: 30 additions & 3 deletions crates/gateway/src/starknet_api_test_utils.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,34 @@ use starknet_api::transaction::{
};

// Utils.
pub fn external_declare_tx_for_testing(
pub enum TransactionType {
Declare,
DeployAccount,
Invoke,
}

pub fn external_tx_for_testing(
transaction_type: TransactionType,
resource_bounds: ResourceBoundsMapping,
calldata: Option<Calldata>,
signature: TransactionSignature,
) -> ExternalTransaction {
match transaction_type {
TransactionType::Declare => external_declare_tx_for_testing(resource_bounds, signature),
TransactionType::DeployAccount => external_deploy_account_tx_for_testing(
resource_bounds,
calldata.expect("Calldata is missing."),
signature,
),
TransactionType::Invoke => external_invoke_tx_for_testing(
resource_bounds,
calldata.expect("Calldata is missing."),
signature,
),
}
}

fn external_declare_tx_for_testing(
resource_bounds: ResourceBoundsMapping,
signature: TransactionSignature,
) -> ExternalTransaction {
Expand All @@ -30,7 +57,7 @@ pub fn external_declare_tx_for_testing(
))
}

pub fn external_deploy_account_tx_for_testing(
fn external_deploy_account_tx_for_testing(
resource_bounds: ResourceBoundsMapping,
constructor_calldata: Calldata,
signature: TransactionSignature,
Expand All @@ -51,7 +78,7 @@ pub fn external_deploy_account_tx_for_testing(
))
}

pub fn external_invoke_tx_for_testing(
fn external_invoke_tx_for_testing(
resource_bounds: ResourceBoundsMapping,
calldata: Calldata,
signature: TransactionSignature,
Expand Down
269 changes: 130 additions & 139 deletions crates/gateway/src/stateless_transaction_validator_test.rs
Original file line number Diff line number Diff line change
@@ -1,20 +1,18 @@
use rstest::rstest;

use starknet_api::calldata;
use starknet_api::external_transaction::ExternalTransaction;
use starknet_api::hash::StarkFelt;
use starknet_api::transaction::{
Calldata, Resource, ResourceBounds, ResourceBoundsMapping, TransactionSignature,
};

use crate::starknet_api_test_utils::{
create_resource_bounds_mapping, external_declare_tx_for_testing,
external_deploy_account_tx_for_testing, external_invoke_tx_for_testing,
non_zero_resource_bounds_mapping, zero_resource_bounds_mapping, NON_EMPTY_RESOURCE_BOUNDS,
create_resource_bounds_mapping, external_tx_for_testing, non_zero_resource_bounds_mapping,
zero_resource_bounds_mapping, TransactionType, NON_EMPTY_RESOURCE_BOUNDS,
};
use crate::stateless_transaction_validator::{
StatelessTransactionValidator, StatelessTransactionValidatorConfig,
StatelessTransactionValidatorError, StatelessTransactionValidatorResult,
StatelessTransactionValidatorError,
};

const DEFAULT_VALIDATOR_CONFIG_FOR_TESTING: StatelessTransactionValidatorConfig =
Expand All @@ -27,171 +25,164 @@ const DEFAULT_VALIDATOR_CONFIG_FOR_TESTING: StatelessTransactionValidatorConfig
};

#[rstest]
// Resource bounds validation tests.
#[case::ignore_resource_bounds(
StatelessTransactionValidatorConfig{
validate_non_zero_l1_gas_fee: false,
validate_non_zero_l2_gas_fee: false,
..DEFAULT_VALIDATOR_CONFIG_FOR_TESTING
},
external_invoke_tx_for_testing(
zero_resource_bounds_mapping(), calldata![], TransactionSignature::default()
),
Ok(())
zero_resource_bounds_mapping(),
calldata![],
TransactionSignature::default()
)]
#[case::valid_l2_gas_invoke_tx(
StatelessTransactionValidatorConfig{
validate_non_zero_l1_gas_fee: false,
validate_non_zero_l2_gas_fee: true,
..DEFAULT_VALIDATOR_CONFIG_FOR_TESTING
},
create_resource_bounds_mapping(ResourceBounds::default(), NON_EMPTY_RESOURCE_BOUNDS),
calldata![],
TransactionSignature::default()
)]
#[case::non_empty_valid_calldata(
DEFAULT_VALIDATOR_CONFIG_FOR_TESTING,
non_zero_resource_bounds_mapping(),
calldata![StarkFelt::from_u128(1)],
TransactionSignature::default()
)]
#[case::non_empty_valid_signature(
DEFAULT_VALIDATOR_CONFIG_FOR_TESTING,
non_zero_resource_bounds_mapping(),
calldata![],
TransactionSignature(vec![StarkFelt::from_u128(1)])
)]
#[case::valid_tx(
DEFAULT_VALIDATOR_CONFIG_FOR_TESTING,
non_zero_resource_bounds_mapping(),
calldata![],
TransactionSignature::default()
)]
fn test_positive_flow(
#[case] config: StatelessTransactionValidatorConfig,
#[case] resource_bounds: ResourceBoundsMapping,
#[case] tx_calldata: Calldata,
#[case] signature: TransactionSignature,
#[values(
TransactionType::Declare,
TransactionType::DeployAccount,
TransactionType::Invoke
)]
tx_type: TransactionType,
) {
let tx_validator = StatelessTransactionValidator { config };
let tx = external_tx_for_testing(tx_type, resource_bounds, Some(tx_calldata), signature);

assert!(tx_validator.validate(&tx).is_ok());
}

#[rstest]
#[case::missing_l1_gas_resource_bounds(
StatelessTransactionValidatorConfig {
validate_non_zero_l1_gas_fee: true,
validate_non_zero_l2_gas_fee: false,
..DEFAULT_VALIDATOR_CONFIG_FOR_TESTING
},
external_invoke_tx_for_testing(
ResourceBoundsMapping::default(), calldata![], TransactionSignature::default()
),
Err(StatelessTransactionValidatorError::MissingResource { resource: Resource::L1Gas })
ResourceBoundsMapping::default(),
StatelessTransactionValidatorError::MissingResource { resource: Resource::L1Gas }
)]
#[case::missing_l2_gas_resource_bounds(
StatelessTransactionValidatorConfig {
validate_non_zero_l1_gas_fee: false,
validate_non_zero_l2_gas_fee: true,
..DEFAULT_VALIDATOR_CONFIG_FOR_TESTING
},
external_invoke_tx_for_testing(
ResourceBoundsMapping::default(), calldata![], TransactionSignature::default()
),
Err(StatelessTransactionValidatorError::MissingResource { resource: Resource::L2Gas })
ResourceBoundsMapping::default(),
StatelessTransactionValidatorError::MissingResource { resource: Resource::L2Gas }
)]
#[case::zero_l1_gas_resource_bounds(
DEFAULT_VALIDATOR_CONFIG_FOR_TESTING,
external_invoke_tx_for_testing(
zero_resource_bounds_mapping(), calldata![], TransactionSignature::default()
),
Err(StatelessTransactionValidatorError::ZeroResourceBounds{
zero_resource_bounds_mapping(),
StatelessTransactionValidatorError::ZeroResourceBounds{
resource: Resource::L1Gas, resource_bounds: ResourceBounds::default()
})
}
)]
#[case::zero_l2_gas_resource_bounds(
DEFAULT_VALIDATOR_CONFIG_FOR_TESTING,
external_invoke_tx_for_testing(
create_resource_bounds_mapping(NON_EMPTY_RESOURCE_BOUNDS, ResourceBounds::default()),
calldata![],
TransactionSignature::default()
),
Err(StatelessTransactionValidatorError::ZeroResourceBounds{
create_resource_bounds_mapping(NON_EMPTY_RESOURCE_BOUNDS, ResourceBounds::default()),
StatelessTransactionValidatorError::ZeroResourceBounds{
resource: Resource::L2Gas, resource_bounds: ResourceBounds::default()
})
)]
#[case::valid_l2_gas_invoke_tx(
StatelessTransactionValidatorConfig{
validate_non_zero_l1_gas_fee: false,
validate_non_zero_l2_gas_fee: true,
..DEFAULT_VALIDATOR_CONFIG_FOR_TESTING
},
external_invoke_tx_for_testing(
create_resource_bounds_mapping(ResourceBounds::default(), NON_EMPTY_RESOURCE_BOUNDS),
calldata![],
TransactionSignature::default()
),
Ok(())
)]
// Transaction size validation tests.
#[case::deploy_account_calldata_too_long(
DEFAULT_VALIDATOR_CONFIG_FOR_TESTING,
external_deploy_account_tx_for_testing(
non_zero_resource_bounds_mapping(),
calldata![StarkFelt::from_u128(1), StarkFelt::from_u128(2)],
TransactionSignature::default()
),
Err(StatelessTransactionValidatorError::CalldataTooLong { calldata_length: 2, max_calldata_length: 1 })
)]
#[case::invoke_calldata_too_long(
DEFAULT_VALIDATOR_CONFIG_FOR_TESTING,
external_invoke_tx_for_testing(
non_zero_resource_bounds_mapping(),
calldata![StarkFelt::from_u128(1), StarkFelt::from_u128(2)],
TransactionSignature::default()
),
Err(StatelessTransactionValidatorError::CalldataTooLong { calldata_length: 2, max_calldata_length: 1 })
)]
#[case::non_empty_valid_calldata(
DEFAULT_VALIDATOR_CONFIG_FOR_TESTING,
external_invoke_tx_for_testing(
non_zero_resource_bounds_mapping(),
calldata![StarkFelt::from_u128(1)],
TransactionSignature::default()
),
Ok(())
}
)]
#[case::declare_signature_too_long(
DEFAULT_VALIDATOR_CONFIG_FOR_TESTING,
external_declare_tx_for_testing(
non_zero_resource_bounds_mapping(),
TransactionSignature(vec![StarkFelt::from_u128(1), StarkFelt::from_u128(2)]),
),
Err(StatelessTransactionValidatorError::SignatureTooLong { signature_length: 2, max_signature_length: 1 })
)]
#[case::deploy_account_signature_too_long(
DEFAULT_VALIDATOR_CONFIG_FOR_TESTING,
external_deploy_account_tx_for_testing(
non_zero_resource_bounds_mapping(),
calldata![],
TransactionSignature(vec![StarkFelt::from_u128(1), StarkFelt::from_u128(2)])
),
Err(StatelessTransactionValidatorError::SignatureTooLong { signature_length: 2, max_signature_length: 1 })
)]
#[case::invoke_signature_too_long(
DEFAULT_VALIDATOR_CONFIG_FOR_TESTING,
external_invoke_tx_for_testing(
non_zero_resource_bounds_mapping(),
calldata![],
TransactionSignature(vec![StarkFelt::from_u128(1), StarkFelt::from_u128(2)])
),
Err(StatelessTransactionValidatorError::SignatureTooLong { signature_length: 2, max_signature_length: 1 })
)]
#[case::non_empty_valid_signature(
DEFAULT_VALIDATOR_CONFIG_FOR_TESTING,
external_invoke_tx_for_testing(
non_zero_resource_bounds_mapping(),
calldata![],
TransactionSignature(vec![StarkFelt::from_u128(1)])
),
Ok(())
)]
// General cases.
#[case::valid_declare_tx(
DEFAULT_VALIDATOR_CONFIG_FOR_TESTING,
external_declare_tx_for_testing(
non_zero_resource_bounds_mapping(),
TransactionSignature::default()
),
Ok(())
)]
#[case::valid_deploy_account_tx(
DEFAULT_VALIDATOR_CONFIG_FOR_TESTING,
external_deploy_account_tx_for_testing(
non_zero_resource_bounds_mapping(),
calldata![],
TransactionSignature::default()
),
Ok(())
)]
#[case::valid_invoke_tx(
DEFAULT_VALIDATOR_CONFIG_FOR_TESTING,
external_invoke_tx_for_testing(
non_zero_resource_bounds_mapping(),
calldata![],
TransactionSignature::default()
),
Ok(())
)]
fn test_transaction_validator(
fn test_invalid_resource_bounds(
#[case] config: StatelessTransactionValidatorConfig,
#[case] tx: ExternalTransaction,
#[case] expected_result: StatelessTransactionValidatorResult<()>,
#[case] resource_bounds: ResourceBoundsMapping,
#[case] expected_error: StatelessTransactionValidatorError,
#[values(
TransactionType::Declare,
TransactionType::DeployAccount,
TransactionType::Invoke
)]
tx_type: TransactionType,
) {
let tx_validator = StatelessTransactionValidator { config };
let result = tx_validator.validate(&tx);
let tx = external_tx_for_testing(
tx_type,
resource_bounds,
Some(calldata![]),
TransactionSignature::default(),
);

assert_eq!(tx_validator.validate(&tx).unwrap_err(), expected_error);
}

#[rstest]
fn test_calldata_too_long(
#[values(TransactionType::DeployAccount, TransactionType::Invoke)] tx_type: TransactionType,
) {
let tx_validator = StatelessTransactionValidator {
config: DEFAULT_VALIDATOR_CONFIG_FOR_TESTING,
};
let tx = external_tx_for_testing(
tx_type,
non_zero_resource_bounds_mapping(),
Some(calldata![StarkFelt::from_u128(1), StarkFelt::from_u128(2)]),
TransactionSignature::default(),
);

assert_eq!(
tx_validator.validate(&tx).unwrap_err(),
StatelessTransactionValidatorError::CalldataTooLong {
calldata_length: 2,
max_calldata_length: 1
}
);
}

#[rstest]
fn test_signature_too_long(
#[values(
TransactionType::Declare,
TransactionType::DeployAccount,
TransactionType::Invoke
)]
tx_type: TransactionType,
) {
let tx_validator = StatelessTransactionValidator {
config: DEFAULT_VALIDATOR_CONFIG_FOR_TESTING,
};
let tx = external_tx_for_testing(
tx_type,
non_zero_resource_bounds_mapping(),
Some(calldata![]),
TransactionSignature(vec![StarkFelt::from_u128(1), StarkFelt::from_u128(2)]),
);

assert_eq!(result, expected_result);
assert_eq!(
tx_validator.validate(&tx).unwrap_err(),
StatelessTransactionValidatorError::SignatureTooLong {
signature_length: 2,
max_signature_length: 1
}
);
}

0 comments on commit d545119

Please sign in to comment.