Skip to content

Commit

Permalink
test(starknet_gateway): add sync state reader unit tests (#2903)
Browse files Browse the repository at this point in the history
  • Loading branch information
noamsp-starkware authored Dec 30, 2024
1 parent 70ed8c2 commit d2b0d17
Show file tree
Hide file tree
Showing 4 changed files with 192 additions and 1 deletion.
1 change: 1 addition & 0 deletions crates/starknet_gateway/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@ pretty_assertions.workspace = true
rstest.workspace = true
starknet_mempool.workspace = true
starknet_mempool_types = { workspace = true, features = ["testing"] }
starknet_state_sync_types = { workspace = true, features = ["testing"] }
tracing-test.workspace = true

[[bench]]
Expand Down
2 changes: 2 additions & 0 deletions crates/starknet_gateway/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,5 +15,7 @@ mod stateful_transaction_validator;
mod stateless_transaction_validator;
mod sync_state_reader;
#[cfg(test)]
mod sync_state_reader_test;
#[cfg(test)]
mod test_utils;
mod utils;
2 changes: 1 addition & 1 deletion crates/starknet_gateway/src/sync_state_reader.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ use starknet_types_core::felt::Felt;
use crate::state_reader::{MempoolStateReader, StateReaderFactory};

#[allow(dead_code)]
struct SyncStateReader {
pub(crate) struct SyncStateReader {
block_number: BlockNumber,
state_sync_client: SharedStateSyncClient,
}
Expand Down
188 changes: 188 additions & 0 deletions crates/starknet_gateway/src/sync_state_reader_test.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,188 @@
use std::sync::Arc;

use blockifier::execution::contract_class::RunnableCompiledClass;
use blockifier::state::state_api::StateReader;
use cairo_lang_starknet_classes::casm_contract_class::CasmContractClass;
use mockall::predicate;
use papyrus_test_utils::{get_rng, GetTestInstance};
use starknet_api::block::{
BlockHeaderWithoutHash,
BlockInfo,
BlockNumber,
BlockTimestamp,
GasPricePerToken,
GasPriceVector,
GasPrices,
NonzeroGasPrice,
};
use starknet_api::contract_class::{ContractClass, SierraVersion};
use starknet_api::core::SequencerContractAddress;
use starknet_api::data_availability::L1DataAvailabilityMode;
use starknet_api::{class_hash, contract_address, felt, nonce, storage_key};
use starknet_state_sync_types::communication::MockStateSyncClient;
use starknet_state_sync_types::state_sync_types::SyncBlock;

use crate::state_reader::MempoolStateReader;
use crate::sync_state_reader::SyncStateReader;
#[tokio::test]
async fn test_get_block_info() {
let mut mock_state_sync_client = MockStateSyncClient::new();
let block_number = BlockNumber(1);
let block_timestamp = BlockTimestamp(2);
let sequencer_address = contract_address!("0x3");
let l1_gas_price = GasPricePerToken { price_in_wei: 4_u8.into(), price_in_fri: 5_u8.into() };
let l1_data_gas_price =
GasPricePerToken { price_in_wei: 6_u8.into(), price_in_fri: 7_u8.into() };
let l2_gas_price = GasPricePerToken { price_in_wei: 8_u8.into(), price_in_fri: 9_u8.into() };
let l1_da_mode = L1DataAvailabilityMode::get_test_instance(&mut get_rng());

mock_state_sync_client.expect_get_block().times(1).with(predicate::eq(block_number)).returning(
move |_| {
Ok(Some(SyncBlock {
state_diff: Default::default(),
transaction_hashes: Default::default(),
block_header_without_hash: BlockHeaderWithoutHash {
block_number,
l1_gas_price,
l1_data_gas_price,
l2_gas_price,
sequencer: SequencerContractAddress(sequencer_address),
timestamp: block_timestamp,
l1_da_mode,
..Default::default()
},
}))
},
);

let state_sync_reader =
SyncStateReader::from_number(Arc::new(mock_state_sync_client), block_number);
let result = state_sync_reader.get_block_info().unwrap();

assert_eq!(
result,
BlockInfo {
block_number,
block_timestamp,
sequencer_address,
gas_prices: GasPrices {
eth_gas_prices: GasPriceVector {
l1_gas_price: NonzeroGasPrice::new_unchecked(l1_gas_price.price_in_wei),
l1_data_gas_price: NonzeroGasPrice::new_unchecked(
l1_data_gas_price.price_in_wei
),
l2_gas_price: NonzeroGasPrice::new_unchecked(l2_gas_price.price_in_wei),
},
strk_gas_prices: GasPriceVector {
l1_gas_price: NonzeroGasPrice::new_unchecked(l1_gas_price.price_in_fri),
l1_data_gas_price: NonzeroGasPrice::new_unchecked(
l1_data_gas_price.price_in_fri
),
l2_gas_price: NonzeroGasPrice::new_unchecked(l2_gas_price.price_in_fri),
},
},
use_kzg_da: match l1_da_mode {
L1DataAvailabilityMode::Blob => true,
L1DataAvailabilityMode::Calldata => false,
},
}
);
}

#[tokio::test]
async fn test_get_storage_at() {
let mut mock_state_sync_client = MockStateSyncClient::new();
let block_number = BlockNumber(1);
let contract_address = contract_address!("0x2");
let storage_key = storage_key!("0x3");
let value = felt!("0x4");
mock_state_sync_client
.expect_get_storage_at()
.times(1)
.with(
predicate::eq(block_number),
predicate::eq(contract_address),
predicate::eq(storage_key),
)
.returning(move |_, _, _| Ok(value));

let state_sync_reader =
SyncStateReader::from_number(Arc::new(mock_state_sync_client), block_number);

let result = state_sync_reader.get_storage_at(contract_address, storage_key).unwrap();
assert_eq!(result, value);
}

#[tokio::test]
async fn test_get_nonce_at() {
let mut mock_state_sync_client = MockStateSyncClient::new();
let block_number = BlockNumber(1);
let contract_address = contract_address!("0x2");
let expected_result = nonce!(0x3);

mock_state_sync_client
.expect_get_nonce_at()
.times(1)
.with(predicate::eq(block_number), predicate::eq(contract_address))
.returning(move |_, _| Ok(expected_result));

let state_sync_reader =
SyncStateReader::from_number(Arc::new(mock_state_sync_client), block_number);

let result = state_sync_reader.get_nonce_at(contract_address).unwrap();
assert_eq!(result, expected_result);
}

#[tokio::test]
async fn test_get_class_hash_at() {
let mut mock_state_sync_client = MockStateSyncClient::new();
let block_number = BlockNumber(1);
let contract_address = contract_address!("0x2");
let expected_result = class_hash!("0x3");

mock_state_sync_client
.expect_get_class_hash_at()
.times(1)
.with(predicate::eq(block_number), predicate::eq(contract_address))
.returning(move |_, _| Ok(expected_result));

let state_sync_reader =
SyncStateReader::from_number(Arc::new(mock_state_sync_client), block_number);

let result = state_sync_reader.get_class_hash_at(contract_address).unwrap();
assert_eq!(result, expected_result);
}

#[tokio::test]
async fn test_get_compiled_class() {
let mut mock_state_sync_client = MockStateSyncClient::new();
let block_number = BlockNumber(1);
let class_hash = class_hash!("0x2");
let casm_contract_class = CasmContractClass {
compiler_version: "0.0.0".to_string(),
prime: Default::default(),
bytecode: Default::default(),
bytecode_segment_lengths: Default::default(),
hints: Default::default(),
pythonic_hints: Default::default(),
entry_points_by_type: Default::default(),
};
let expected_result = casm_contract_class.clone();

mock_state_sync_client
.expect_get_compiled_class_deprecated()
.times(1)
.with(predicate::eq(block_number), predicate::eq(class_hash))
.returning(move |_, _| {
Ok(ContractClass::V1((casm_contract_class.clone(), SierraVersion::default())))
});

let state_sync_reader =
SyncStateReader::from_number(Arc::new(mock_state_sync_client), block_number);

let result = state_sync_reader.get_compiled_class(class_hash).unwrap();
assert_eq!(
result,
RunnableCompiledClass::V1((expected_result, SierraVersion::default()).try_into().unwrap())
);
}

0 comments on commit d2b0d17

Please sign in to comment.