diff --git a/src/test_utils/katana/mod.rs b/src/test_utils/katana/mod.rs index b64add557..1d15f06c7 100644 --- a/src/test_utils/katana/mod.rs +++ b/src/test_utils/katana/mod.rs @@ -37,7 +37,7 @@ use { super::mongo::MongoFuzzer, alloy_primitives::B256, alloy_rpc_types::Header, - alloy_rpc_types::Transaction, + alloy_rpc_types::{Transaction, TransactionReceipt}, alloy_serde::WithOtherFields, katana_node::config::{ rpc::{ApiKind, RpcConfig}, @@ -346,6 +346,20 @@ impl<'a> Katana { .map(Into::into) } + pub fn most_recent_run_out_of_resources_receipt(&self) -> Option> { + self.receipts + .iter() + .filter_map(|stored_receipt| { + let receipt = WithOtherFields::from(stored_receipt.clone()); + if receipt.other.contains_key("isRunOutOfRessources") { + Some(receipt) + } else { + None + } + }) + .max_by_key(|receipt| receipt.block_number.unwrap_or_default()) + } + /// Retrieves the stored header by hash pub fn header_by_hash(&self, hash: B256) -> Option
{ self.headers.iter().find_map( diff --git a/src/test_utils/mongo/mod.rs b/src/test_utils/mongo/mod.rs index 531becfe8..6e0a98780 100644 --- a/src/test_utils/mongo/mod.rs +++ b/src/test_utils/mongo/mod.rs @@ -8,7 +8,8 @@ use crate::providers::eth_provider::{ }, }; use alloy_primitives::{B256, U256}; -use alloy_rpc_types::Transaction; +use alloy_rpc_types::{Transaction, TransactionReceipt}; +use alloy_serde::WithOtherFields; use arbitrary::Arbitrary; use mongodb::{ bson::{self, doc, Document}, @@ -187,6 +188,8 @@ impl MongoFuzzer { self.receipts.push(receipt); } + self.add_random_transaction_with_other_field()?; + // At the end of our transaction list, for our tests, we need to add a block header with a base fee. let mut header_with_base_fee = StoredHeader::arbitrary(&mut arbitrary::Unstructured::new( &(0..self.rnd_bytes_size).map(|_| rand::random::()).collect::>(), @@ -201,6 +204,35 @@ impl MongoFuzzer { Ok(()) } + pub fn add_random_transaction_with_other_field(&mut self) -> Result<(), Box> { + // Build a transaction using the random byte size. + let transaction = StoredTransaction::arbitrary(&mut arbitrary::Unstructured::new( + &(0..self.rnd_bytes_size).map(|_| rand::random::()).collect::>(), + ))?; + + // Generate a receipt for the transaction. + let receipt = self.generate_transaction_receipt(&transaction.tx); + // add an isRunOutOfRessources field to the receipt + let mut receipt_with_other_fields: WithOtherFields = receipt.into(); + receipt_with_other_fields.other.insert("isRunOutOfRessources".to_string(), serde_json::Value::Bool(true)); + + let stored_receipt = StoredTransactionReceipt { receipt: receipt_with_other_fields }; + + // Convert the receipt into a vector of logs and append them to the existing logs collection. + self.logs.append(&mut Vec::from(stored_receipt.clone())); + + // Generate a header for the transaction and add it to the headers collection. + self.headers.push(self.generate_transaction_header(&transaction.tx)); + + // Add the transaction to the transactions collection. + self.transactions.push(transaction); + + // Add the receipt to the receipts collection. + self.receipts.push(stored_receipt); + + Ok(()) + } + /// Generates a transaction receipt based on the given transaction. fn generate_transaction_receipt(&self, transaction: &Transaction) -> StoredTransactionReceipt { let bytes: Vec = (0..self.rnd_bytes_size).map(|_| rand::random()).collect(); diff --git a/tests/tests/eth_provider.rs b/tests/tests/eth_provider.rs index 435e812cc..516ea82b3 100644 --- a/tests/tests/eth_provider.rs +++ b/tests/tests/eth_provider.rs @@ -1420,3 +1420,17 @@ async fn test_transaction_by_hash(#[future] katana_empty: Katana, _setup: ()) { transaction.tx ); } + +#[rstest] +#[awt] +#[tokio::test(flavor = "multi_thread")] +async fn test_with_other_fields(#[future] katana: Katana, _setup: ()) { + let eth_provider = katana.eth_provider(); + let run_out_of_resources_receipt = katana.most_recent_run_out_of_resources_receipt().unwrap(); + + let receipt_from_db = + eth_provider.transaction_receipt(run_out_of_resources_receipt.transaction_hash).await.unwrap(); + // Verify the receipt + assert_eq!(run_out_of_resources_receipt.other.get("isRunOutOfRessources"), Some(&serde_json::Value::Bool(true))); + assert_eq!(receipt_from_db.unwrap(), run_out_of_resources_receipt); +}