Skip to content

Commit

Permalink
test(katana-provider): more elaborate tests (#1317)
Browse files Browse the repository at this point in the history
* test(katana-provider): more elaborate tests

* ignore log files from runner
  • Loading branch information
kariy authored Dec 19, 2023
1 parent 3af74d5 commit 1840d72
Show file tree
Hide file tree
Showing 10 changed files with 654 additions and 57 deletions.
2 changes: 2 additions & 0 deletions Cargo.lock

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

16 changes: 8 additions & 8 deletions crates/katana/primitives/src/receipt.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ use ethers::types::H256;
use crate::contract::ContractAddress;
use crate::FieldElement;

#[derive(Debug, Clone)]
#[derive(Debug, Clone, PartialEq, Eq)]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
pub struct Event {
/// The contract address that emitted the event.
Expand All @@ -15,7 +15,7 @@ pub struct Event {
}

/// Represents a message sent to L1.
#[derive(Debug, Clone)]
#[derive(Debug, Clone, PartialEq, Eq)]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
pub struct MessageToL1 {
/// The L2 contract address that sent the message.
Expand All @@ -27,7 +27,7 @@ pub struct MessageToL1 {
}

/// Receipt for a `Invoke` transaction.
#[derive(Debug, Clone, Default)]
#[derive(Debug, Clone, Default, PartialEq, Eq)]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
pub struct InvokeTxReceipt {
/// Actual fee paid for the transaction.
Expand All @@ -43,7 +43,7 @@ pub struct InvokeTxReceipt {
}

/// Receipt for a `Declare` transaction.
#[derive(Debug, Clone)]
#[derive(Debug, Clone, PartialEq, Eq)]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
pub struct DeclareTxReceipt {
/// Actual fee paid for the transaction.
Expand All @@ -59,7 +59,7 @@ pub struct DeclareTxReceipt {
}

/// Receipt for a `L1Handler` transaction.
#[derive(Debug, Clone)]
#[derive(Debug, Clone, PartialEq, Eq)]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
pub struct L1HandlerTxReceipt {
/// Actual fee paid for the transaction.
Expand All @@ -77,7 +77,7 @@ pub struct L1HandlerTxReceipt {
}

/// Receipt for a `DeployAccount` transaction.
#[derive(Debug, Clone)]
#[derive(Debug, Clone, PartialEq, Eq)]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
pub struct DeployAccountTxReceipt {
/// Actual fee paid for the transaction.
Expand All @@ -95,7 +95,7 @@ pub struct DeployAccountTxReceipt {
}

/// The receipt of a transaction containing the outputs of its execution.
#[derive(Debug, Clone)]
#[derive(Debug, Clone, PartialEq, Eq)]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
pub enum Receipt {
Invoke(InvokeTxReceipt),
Expand Down Expand Up @@ -139,7 +139,7 @@ impl Receipt {
/// Transaction execution resources.
///
/// The resources consumed by a transaction during its execution.
#[derive(Debug, Default, Clone)]
#[derive(Debug, Default, Clone, PartialEq, Eq)]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
pub struct TxExecutionResources {
/// The number of cairo steps used
Expand Down
1 change: 1 addition & 0 deletions crates/katana/storage/provider/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
/logs
8 changes: 5 additions & 3 deletions crates/katana/storage/provider/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -22,11 +22,13 @@ starknet.workspace = true
tokio.workspace = true

[features]
default = ["fork", "in-memory"]
fork = ["in-memory"]
in-memory = []
default = [ "fork", "in-memory" ]
fork = [ "in-memory" ]
in-memory = [ ]

[dev-dependencies]
katana-runner = { path = "../../runner" }
lazy_static.workspace = true
rand = "0.8.5"
rstest = "0.18.2"
rstest_reuse = "0.6.0"
Expand Down
Original file line number Diff line number Diff line change
@@ -1,46 +1,16 @@
use katana_primitives::block::{
Block, BlockHash, BlockHashOrNumber, FinalityStatus, Header, SealedBlockWithStatus,
};
use katana_primitives::transaction::{Tx, TxHash, TxWithHash};
use katana_primitives::FieldElement;
use katana_primitives::block::BlockHashOrNumber;
use katana_provider::providers::fork::ForkedProvider;
use katana_provider::providers::in_memory::InMemoryProvider;
use katana_provider::traits::block::{BlockProvider, BlockWriter};
use katana_provider::traits::transaction::TransactionProvider;
use katana_provider::traits::transaction::{ReceiptProvider, TransactionProvider};
use katana_provider::BlockchainProvider;
use rstest_reuse::{self, *};

mod fixtures;
mod utils;

use fixtures::{fork_provider, in_memory_provider};

fn generate_dummy_txs(count: u64) -> Vec<TxWithHash> {
let mut txs = Vec::with_capacity(count as usize);
for _ in 0..count {
txs.push(TxWithHash {
hash: TxHash::from(rand::random::<u128>()),
transaction: Tx::Invoke(Default::default()),
});
}
txs
}

fn generate_dummy_blocks(count: u64) -> Vec<SealedBlockWithStatus> {
let mut blocks = Vec::with_capacity(count as usize);
let mut parent_hash: BlockHash = 0u8.into();

for i in 0..count {
let body = generate_dummy_txs(rand::random::<u64>() % 10);
let header = Header { parent_hash, number: i, ..Default::default() };
let block =
Block { header, body }.seal_with_hash(FieldElement::from(rand::random::<u128>()));
parent_hash = block.header.hash;

blocks.push(SealedBlockWithStatus { block, status: FinalityStatus::AcceptedOnL2 });
}

blocks
}
use utils::generate_dummy_blocks_and_receipts;

#[template]
#[rstest::rstest]
Expand All @@ -55,39 +25,44 @@ fn insert_block_with_in_memory_provider(
#[from(in_memory_provider)] provider: BlockchainProvider<InMemoryProvider>,
#[case] block_count: u64,
) -> anyhow::Result<()> {
insert_block_impl(provider, block_count)
insert_block_test_impl(provider, block_count)
}

#[apply(insert_block_cases)]
fn insert_block_with_fork_provider(
#[from(fork_provider)] provider: BlockchainProvider<ForkedProvider>,
#[case] block_count: u64,
) -> anyhow::Result<()> {
insert_block_impl(provider, block_count)
insert_block_test_impl(provider, block_count)
}

fn insert_block_impl<Db>(provider: BlockchainProvider<Db>, count: u64) -> anyhow::Result<()>
fn insert_block_test_impl<Db>(provider: BlockchainProvider<Db>, count: u64) -> anyhow::Result<()>
where
Db: BlockProvider + BlockWriter,
Db: BlockProvider + BlockWriter + ReceiptProvider,
{
let blocks = generate_dummy_blocks(count);
let blocks = generate_dummy_blocks_and_receipts(count);

for block in &blocks {
for (block, receipts) in &blocks {
provider.insert_block_with_states_and_receipts(
block.clone(),
Default::default(),
Default::default(),
receipts.clone(),
)?;
}

for block in blocks {
for (block, receipts) in blocks {
let block_id = BlockHashOrNumber::Hash(block.block.header.hash);
let expected_block = block.block.unseal();

let actual_block = provider.block(block_id)?;
let actual_block_txs = provider.transactions_by_block(block_id)?;
let actual_block_tx_count = provider.transaction_count_by_block(block_id)?;

let actual_receipts = provider.receipts_by_block(block_id)?;

assert_eq!(actual_receipts.as_ref().map(|r| r.len()), Some(expected_block.body.len()));
assert_eq!(actual_receipts, Some(receipts));

assert_eq!(actual_block_tx_count, Some(expected_block.body.len() as u64));
assert_eq!(actual_block_txs, Some(expected_block.body.clone()));
assert_eq!(actual_block, Some(expected_block));
Expand Down
146 changes: 146 additions & 0 deletions crates/katana/storage/provider/tests/class.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,146 @@
mod fixtures;

use anyhow::Result;
use fixtures::{fork_provider_with_spawned_fork_network, in_memory_provider, provider_with_states};
use katana_primitives::block::{BlockHashOrNumber, BlockNumber};
use katana_primitives::contract::{ClassHash, CompiledClassHash};
use katana_provider::providers::fork::ForkedProvider;
use katana_provider::providers::in_memory::InMemoryProvider;
use katana_provider::traits::state::{StateFactoryProvider, StateProvider};
use katana_provider::BlockchainProvider;
use rstest_reuse::{self, *};
use starknet::macros::felt;

fn assert_state_provider_class(
state_provider: Box<dyn StateProvider>,
expected_class: Vec<(ClassHash, Option<CompiledClassHash>)>,
) -> Result<()> {
for (class_hash, expected_compiled_hash) in expected_class {
let actual_compiled_hash = state_provider.compiled_class_hash_of_class_hash(class_hash)?;
assert_eq!(actual_compiled_hash, expected_compiled_hash);
}
Ok(())
}

mod latest {
use super::*;

fn assert_latest_class<Db: StateFactoryProvider>(
provider: BlockchainProvider<Db>,
expected_class: Vec<(ClassHash, Option<CompiledClassHash>)>,
) -> Result<()> {
let state_provider = provider.latest()?;
assert_state_provider_class(state_provider, expected_class)
}

#[template]
#[rstest::rstest]
#[case(
vec![
(felt!("11"), Some(felt!("1000"))),
(felt!("22"), Some(felt!("2000"))),
(felt!("33"), Some(felt!("3000"))),
]
)]
fn test_latest_class_read<Db>(
#[from(provider_with_states)] provider: BlockchainProvider<Db>,
#[case] expected_class: Vec<(ClassHash, Option<CompiledClassHash>)>,
) {
}

#[apply(test_latest_class_read)]
fn read_class_from_in_memory_provider(
#[with(in_memory_provider())] provider: BlockchainProvider<InMemoryProvider>,
#[case] expected_class: Vec<(ClassHash, Option<CompiledClassHash>)>,
) -> Result<()> {
assert_latest_class(provider, expected_class)
}

#[apply(test_latest_class_read)]
fn read_class_from_fork_provider(
#[with(fork_provider_with_spawned_fork_network::default())] provider: BlockchainProvider<
ForkedProvider,
>,
#[case] expected_class: Vec<(ClassHash, Option<CompiledClassHash>)>,
) -> Result<()> {
assert_latest_class(provider, expected_class)
}
}

mod historical {
use super::*;

fn assert_historical_class<Db: StateFactoryProvider>(
provider: BlockchainProvider<Db>,
block_num: BlockNumber,
expected_class: Vec<(ClassHash, Option<CompiledClassHash>)>,
) -> Result<()> {
let state_provider = provider
.historical(BlockHashOrNumber::Num(block_num))?
.expect(ERROR_CREATE_HISTORICAL_PROVIDER);
assert_state_provider_class(state_provider, expected_class)
}

const ERROR_CREATE_HISTORICAL_PROVIDER: &str = "Failed to create historical state provider.";

#[template]
#[rstest::rstest]
#[case::class_hash_at_block_0(
0,
vec![
(felt!("11"), None),
(felt!("22"), None),
(felt!("33"), None)
])
]
#[case::class_hash_at_block_1(
1,
vec![
(felt!("11"), Some(felt!("1000"))),
(felt!("22"), None),
(felt!("33"), None),
])
]
#[case::class_hash_at_block_4(
4,
vec![
(felt!("11"), Some(felt!("1000"))),
(felt!("22"), Some(felt!("2000"))),
(felt!("33"), None),
])
]
#[case::class_hash_at_block_5(
5,
vec![
(felt!("11"), Some(felt!("1000"))),
(felt!("22"), Some(felt!("2000"))),
(felt!("33"), Some(felt!("3000"))),
])
]
fn test_historical_class_read(
#[from(provider_with_states)] provider: BlockchainProvider<InMemoryProvider>,
#[case] block_num: BlockNumber,
#[case] expected_class: Vec<(ClassHash, Option<CompiledClassHash>)>,
) {
}

#[apply(test_historical_class_read)]
fn read_class_from_in_memory_provider(
#[with(in_memory_provider())] provider: BlockchainProvider<InMemoryProvider>,
#[case] block_num: BlockNumber,
#[case] expected_class: Vec<(ClassHash, Option<CompiledClassHash>)>,
) -> Result<()> {
assert_historical_class(provider, block_num, expected_class)
}

#[apply(test_historical_class_read)]
fn read_class_from_fork_provider(
#[with(fork_provider_with_spawned_fork_network::default())] provider: BlockchainProvider<
ForkedProvider,
>,
#[case] block_num: BlockNumber,
#[case] expected_class: Vec<(ClassHash, Option<CompiledClassHash>)>,
) -> Result<()> {
assert_historical_class(provider, block_num, expected_class)
}
}
Loading

0 comments on commit 1840d72

Please sign in to comment.