Skip to content

Commit

Permalink
test: add deploy_account to integration test (#302)
Browse files Browse the repository at this point in the history
  • Loading branch information
Yael-Starkware authored Jul 1, 2024
1 parent e78af98 commit 9456a55
Show file tree
Hide file tree
Showing 8 changed files with 101 additions and 46 deletions.
1 change: 1 addition & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@ futures = "0.3.30"
hyper = { version = "0.14", features = ["client", "http1", "http2"] }
indexmap = "2.1.0"
itertools = "0.13.0"
lazy_static = "1.4.0"
num-bigint = { version = "0.4.5", default-features = false }
# TODO(YaelD, 28/5/2024): The special Papyrus version is needed in order to be aligned with the
# starknet-api version. This should be removed once we have a mono-repo.
Expand Down
2 changes: 1 addition & 1 deletion crates/gateway/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ testing = []

[dependencies]
axum.workspace = true
assert_matches.workspace = true
blockifier.workspace = true
cairo-lang-starknet-classes.workspace = true
cairo-vm.workspace = true
Expand All @@ -30,7 +31,6 @@ tokio.workspace = true
validator.workspace = true

[dev-dependencies]
assert_matches.workspace = true
pretty_assertions.workspace = true
rstest.workspace = true
starknet_mempool = { path = "../mempool", version = "0.0" }
19 changes: 18 additions & 1 deletion crates/gateway/src/starknet_api_test_utils.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,13 @@ use std::env;
use std::fs::File;
use std::path::Path;

use assert_matches::assert_matches;
use blockifier::test_utils::contracts::FeatureContract;
use blockifier::test_utils::{create_trivial_calldata, CairoVersion, NonceManager};
use serde_json::to_string_pretty;
use starknet_api::core::{ClassHash, CompiledClassHash, ContractAddress, Nonce};
use starknet_api::core::{
calculate_contract_address, ClassHash, CompiledClassHash, ContractAddress, Nonce,
};
use starknet_api::data_availability::DataAvailabilityMode;
use starknet_api::hash::StarkFelt;
use starknet_api::rpc_transaction::{
Expand Down Expand Up @@ -380,3 +383,17 @@ pub fn deploy_account_tx() -> RPCTransaction {
resource_bounds: executable_resource_bounds_mapping(),
))
}

pub fn deployed_account_contract_address(deploy_tx: &RPCTransaction) -> ContractAddress {
let tx = assert_matches!(
deploy_tx,
RPCTransaction::DeployAccount(RPCDeployAccountTransaction::V3(tx)) => tx
);
calculate_contract_address(
tx.contract_address_salt,
tx.class_hash,
&tx.constructor_calldata,
ContractAddress::default(),
)
.unwrap()
}
21 changes: 4 additions & 17 deletions crates/gateway/src/state_reader_test_utils.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
use assert_matches::assert_matches;
use blockifier::blockifier::block::BlockInfo;
use blockifier::context::{BlockContext, ChainInfo};
use blockifier::execution::contract_class::ContractClass;
Expand All @@ -10,13 +9,12 @@ use blockifier::test_utils::initial_test_state::{fund_account, test_state_reader
use blockifier::test_utils::{CairoVersion, BALANCE};
use blockifier::versioned_constants::VersionedConstants;
use starknet_api::block::BlockNumber;
use starknet_api::core::{
calculate_contract_address, ClassHash, CompiledClassHash, ContractAddress, Nonce,
};
use starknet_api::core::{ClassHash, CompiledClassHash, ContractAddress, Nonce};
use starknet_api::hash::StarkFelt;
use starknet_api::rpc_transaction::{RPCDeployAccountTransaction, RPCTransaction};
use starknet_api::rpc_transaction::RPCTransaction;
use starknet_api::state::StorageKey;

use crate::starknet_api_test_utils::deployed_account_contract_address;
use crate::state_reader::{MempoolStateReader, StateReaderFactory};

#[derive(Clone)]
Expand Down Expand Up @@ -104,18 +102,7 @@ pub fn local_test_state_reader_factory_for_deploy_account(
let mut state_reader_factory = local_test_state_reader_factory(CairoVersion::Cairo1, false);

// Fund the deployed_account_address.
let tx = assert_matches!(
deploy_tx,
RPCTransaction::DeployAccount(RPCDeployAccountTransaction::V3(tx)) => tx
);

let deployed_account_address = calculate_contract_address(
tx.contract_address_salt,
tx.class_hash,
&tx.constructor_calldata,
ContractAddress::default(),
)
.unwrap();
let deployed_account_address = deployed_account_contract_address(deploy_tx);
fund_account(
BlockContext::create_for_testing().chain_info(),
deployed_account_address,
Expand Down
1 change: 1 addition & 0 deletions crates/tests-integration/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ axum.workspace = true
blockifier.workspace = true
cairo-lang-starknet-classes.workspace = true
indexmap.workspace = true
lazy_static.workspace = true
papyrus_common.workspace = true
papyrus_rpc.workspace = true
papyrus_storage.workspace = true
Expand Down
84 changes: 66 additions & 18 deletions crates/tests-integration/src/state_reader.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,12 @@ use blockifier::context::{BlockContext, ChainInfo};
use blockifier::test_utils::contracts::FeatureContract;
use blockifier::test_utils::{
CairoVersion, BALANCE, CURRENT_BLOCK_TIMESTAMP, DEFAULT_ETH_L1_GAS_PRICE,
DEFAULT_STRK_L1_GAS_PRICE,
DEFAULT_STRK_L1_GAS_PRICE, TEST_SEQUENCER_ADDRESS,
};
use blockifier::transaction::objects::FeeType;
use cairo_lang_starknet_classes::casm_contract_class::CasmContractClass;
use indexmap::{indexmap, IndexMap};
use lazy_static::lazy_static;
use papyrus_common::pending_classes::PendingClasses;
use papyrus_common::BlockHashAndNumber;
use papyrus_rpc::{run_server, RpcConfig};
Expand All @@ -23,21 +24,31 @@ use papyrus_storage::{open_storage, StorageConfig, StorageReader};
use starknet_api::block::{
BlockBody, BlockHeader, BlockNumber, BlockTimestamp, GasPrice, GasPricePerToken,
};
use starknet_api::core::{ClassHash, ContractAddress};
use starknet_api::core::{ClassHash, ContractAddress, PatriciaKey, SequencerContractAddress};
use starknet_api::deprecated_contract_class::ContractClass as DeprecatedContractClass;
use starknet_api::hash::StarkFelt;
use starknet_api::stark_felt;
use starknet_api::hash::{StarkFelt, StarkHash};
use starknet_api::state::{StorageKey, ThinStateDiff};
use starknet_api::{contract_address, patricia_key, stark_felt};
use starknet_client::reader::PendingData;
use starknet_gateway::config::RpcStateReaderConfig;
use starknet_gateway::rpc_state_reader::RpcStateReaderFactory;
use starknet_gateway::starknet_api_test_utils::{
deploy_account_tx, deployed_account_contract_address,
};
use strum::IntoEnumIterator;
use tempfile::tempdir;
use tokio::sync::RwLock;

type ContractClassesMap =
(Vec<(ClassHash, DeprecatedContractClass)>, Vec<(ClassHash, CasmContractClass)>);

lazy_static! {
static ref DEPLOY_ACCCOUNT_TX_CONTRACT_ADDRESS: ContractAddress = {
let deploy_tx = deploy_account_tx();
deployed_account_contract_address(&deploy_tx)
};
}

/// StateReader for integration tests.
///
/// Creates a papyrus storage reader and Spawns a papyrus rpc server for it.
Expand All @@ -52,16 +63,20 @@ pub async fn rpc_test_state_reader_factory(
let test_contract_cairo0 = FeatureContract::TestContract(CairoVersion::Cairo0);
let account_contract_cairo1 = FeatureContract::AccountWithoutValidations(CairoVersion::Cairo1);
let test_contract_cairo1 = FeatureContract::TestContract(CairoVersion::Cairo1);
let erc20 = FeatureContract::ERC20;
let fund_accounts = vec![*DEPLOY_ACCCOUNT_TX_CONTRACT_ADDRESS];

let storage_reader = initialize_papyrus_test_state(
block_context.chain_info(),
BALANCE,
&[
(erc20, 1),
(account_contract_cairo0, 1),
(test_contract_cairo0, 1),
(account_contract_cairo1, n_initialized_account_contracts),
(test_contract_cairo1, 1),
],
fund_accounts,
);
let addr = run_papyrus_rpc_server(storage_reader).await;

Expand All @@ -77,8 +92,14 @@ fn initialize_papyrus_test_state(
chain_info: &ChainInfo,
initial_balances: u128,
contract_instances: &[(FeatureContract, u16)],
fund_additional_accounts: Vec<ContractAddress>,
) -> StorageReader {
let state_diff = prepare_state_diff(chain_info, contract_instances, initial_balances);
let state_diff = prepare_state_diff(
chain_info,
contract_instances,
initial_balances,
fund_additional_accounts,
);

let (cairo0_contract_classes, cairo1_contract_classes) =
prepare_compiled_contract_classes(contract_instances);
Expand All @@ -90,6 +111,7 @@ fn prepare_state_diff(
chain_info: &ChainInfo,
contract_instances: &[(FeatureContract, u16)],
initial_balances: u128,
fund_accounts: Vec<ContractAddress>,
) -> ThinStateDiff {
let erc20 = FeatureContract::ERC20;
let erc20_class_hash = erc20.get_class_hash();
Expand All @@ -116,10 +138,20 @@ fn prepare_state_diff(
}
deployed_contracts
.insert(contract.get_instance_address(instance), contract.get_class_hash());
fund_account(&mut storage_diffs, contract, instance, initial_balances, chain_info);
fund_feature_account_contract(
&mut storage_diffs,
contract,
instance,
initial_balances,
chain_info,
);
}
}

fund_accounts.iter().for_each(|address| {
fund_account(&mut storage_diffs, address, initial_balances, chain_info)
});

ThinStateDiff {
storage_diffs,
deployed_contracts,
Expand All @@ -132,8 +164,8 @@ fn prepare_state_diff(
fn prepare_compiled_contract_classes(
contract_instances: &[(FeatureContract, u16)],
) -> ContractClassesMap {
let mut cairo0_contract_classes: Vec<(ClassHash, DeprecatedContractClass)> = Vec::new();
let mut cairo1_contract_classes: Vec<(ClassHash, CasmContractClass)> = Vec::new();
let mut cairo0_contract_classes = Vec::new();
let mut cairo1_contract_classes = Vec::new();
for (contract, _) in contract_instances.iter() {
match cairo_version(contract) {
CairoVersion::Cairo0 => {
Expand Down Expand Up @@ -196,13 +228,15 @@ fn cairo_version(contract: &FeatureContract) -> CairoVersion {
| FeatureContract::Empty(version)
| FeatureContract::FaultyAccount(version)
| FeatureContract::TestContract(version) => *version,
FeatureContract::ERC20 => CairoVersion::Cairo0,
_ => panic!("{contract:?} contract has no configurable version."),
}
}

fn test_block_header(block_number: BlockNumber) -> BlockHeader {
BlockHeader {
block_number,
sequencer: SequencerContractAddress(contract_address!(TEST_SEQUENCER_ADDRESS)),
l1_gas_price: GasPricePerToken {
price_in_wei: GasPrice(DEFAULT_ETH_L1_GAS_PRICE),
price_in_fri: GasPrice(DEFAULT_STRK_L1_GAS_PRICE),
Expand All @@ -216,7 +250,7 @@ fn test_block_header(block_number: BlockNumber) -> BlockHeader {
}
}

fn fund_account(
fn fund_feature_account_contract(
storage_diffs: &mut IndexMap<ContractAddress, IndexMap<StorageKey, StarkFelt>>,
contract: &FeatureContract,
instance: u16,
Expand All @@ -227,20 +261,34 @@ fn fund_account(
FeatureContract::AccountWithLongValidate(_)
| FeatureContract::AccountWithoutValidations(_)
| FeatureContract::FaultyAccount(_) => {
let key_value = indexmap! {
get_fee_token_var_address(contract.get_instance_address(instance)) => stark_felt!(initial_balances),
};
for fee_type in FeeType::iter() {
storage_diffs
.entry(chain_info.fee_token_address(&fee_type))
.or_default()
.extend(key_value.clone());
}
fund_account(
storage_diffs,
&contract.get_instance_address(instance),
initial_balances,
chain_info,
);
}
_ => (),
}
}

fn fund_account(
storage_diffs: &mut IndexMap<ContractAddress, IndexMap<StorageKey, StarkFelt>>,
account_address: &ContractAddress,
initial_balances: u128,
chain_info: &ChainInfo,
) {
let key_value = indexmap! {
get_fee_token_var_address(*account_address) => stark_felt!(initial_balances),
};
for fee_type in FeeType::iter() {
storage_diffs
.entry(chain_info.fee_token_address(&fee_type))
.or_default()
.extend(key_value.clone());
}
}

// TODO(Yael 5/6/2024): remove this function and use the one from papyrus test utils once we have
// mono-repo.
fn get_test_highest_block() -> Arc<RwLock<Option<BlockHashAndNumber>>> {
Expand Down
18 changes: 9 additions & 9 deletions crates/tests-integration/tests/end_to_end_test.rs
Original file line number Diff line number Diff line change
@@ -1,24 +1,24 @@
use blockifier::test_utils::CairoVersion;
use starknet_api::transaction::TransactionHash;
use starknet_gateway::starknet_api_test_utils::invoke_tx;
use starknet_gateway::starknet_api_test_utils::{deploy_account_tx, invoke_tx};
use starknet_mempool_integration_tests::integration_test_setup::IntegrationTestSetup;

#[tokio::test]
async fn test_end_to_end() {
let mut mock_running_system = IntegrationTestSetup::new(1).await;

let mut expected_tx_hashs = Vec::new();
expected_tx_hashs
let mut expected_tx_hashes = Vec::new();
expected_tx_hashes
.push(mock_running_system.assert_add_tx_success(&invoke_tx(CairoVersion::Cairo0)).await);
expected_tx_hashs
expected_tx_hashes
.push(mock_running_system.assert_add_tx_success(&invoke_tx(CairoVersion::Cairo1)).await);
expected_tx_hashes.push(mock_running_system.assert_add_tx_success(&deploy_account_tx()).await);

let mempool_txs = mock_running_system.get_txs(3).await;

assert_eq!(mempool_txs.len(), 2);
let mempool_txs = mock_running_system.get_txs(4).await;
assert_eq!(mempool_txs.len(), 3);
let mut actual_tx_hashes: Vec<TransactionHash> =
mempool_txs.iter().map(|tx| tx.tx_hash).collect();
actual_tx_hashes.sort();
expected_tx_hashs.sort();
assert_eq!(expected_tx_hashs, actual_tx_hashes);
expected_tx_hashes.sort();
assert_eq!(expected_tx_hashes, actual_tx_hashes);
}

0 comments on commit 9456a55

Please sign in to comment.