From 8410686d9558263adf7da336a209c4c14a34dc9d Mon Sep 17 00:00:00 2001 From: Thomas Coratger Date: Wed, 3 Jul 2024 10:41:36 +0200 Subject: [PATCH] test: add unit tests for save_receipts --- crates/revm/src/batch.rs | 186 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 186 insertions(+) diff --git a/crates/revm/src/batch.rs b/crates/revm/src/batch.rs index f2903a4f47cf..02ffba017bdf 100644 --- a/crates/revm/src/batch.rs +++ b/crates/revm/src/batch.rs @@ -210,3 +210,189 @@ impl BlockExecutorStats { ); } } + +#[cfg(test)] +mod tests { + use super::*; + use reth_primitives::{Address, Log, Receipt}; + use reth_prune_types::{PruneMode, ReceiptsLogPruneConfig}; + use std::collections::BTreeMap; + + #[test] + fn test_save_receipts_empty() { + let mut recorder = BlockBatchRecord::default(); + // Create an empty vector of receipts + let receipts = vec![]; + + // Verify that saving receipts completes without error + assert!(recorder.save_receipts(receipts).is_ok()); + // Verify that the saved receipts are equal to a nested empty vector + assert_eq!(*recorder.receipts(), vec![vec![]].into()); + } + + #[test] + fn test_save_receipts_non_empty_no_pruning() { + let mut recorder = BlockBatchRecord::default(); + let receipts = vec![Receipt::default()]; + + // Verify that saving receipts completes without error + assert!(recorder.save_receipts(receipts).is_ok()); + // Verify that there is one block of receipts + assert_eq!(recorder.receipts().len(), 1); + // Verify that the first block contains one receipt + assert_eq!(recorder.receipts()[0].len(), 1); + // Verify that the saved receipt is the default receipt + assert_eq!(recorder.receipts()[0][0], Some(Receipt::default())); + } + + #[test] + fn test_save_receipts_with_pruning_no_prunable_receipts() { + let mut recorder = BlockBatchRecord::default(); + + // Set the first block number + recorder.set_first_block(1); + // Set the tip (highest known block) + recorder.set_tip(130); + + // Create a vector of receipts with a default receipt + let receipts = vec![Receipt::default()]; + + // Verify that saving receipts completes without error + assert!(recorder.save_receipts(receipts).is_ok()); + // Verify that there is one block of receipts + assert_eq!(recorder.receipts().len(), 1); + // Verify that the first block contains one receipt + assert_eq!(recorder.receipts()[0].len(), 1); + // Verify that the saved receipt is the default receipt + assert_eq!(recorder.receipts()[0][0], Some(Receipt::default())); + } + + #[test] + fn test_save_receipts_with_pruning_no_tip() { + // Create a PruneModes with receipts set to PruneMode::Full + let prune_modes = PruneModes { receipts: Some(PruneMode::Full), ..Default::default() }; + + let mut recorder = BlockBatchRecord::new(prune_modes); + + // Set the first block number + recorder.set_first_block(1); + // Create a vector of receipts with a default receipt + let receipts = vec![Receipt::default()]; + + // Verify that saving receipts completes without error + assert!(recorder.save_receipts(receipts).is_ok()); + // Verify that there is one block of receipts + assert_eq!(recorder.receipts().len(), 1); + // Verify that the first block contains one receipt + assert_eq!(recorder.receipts()[0].len(), 1); + // Verify that the saved receipt is the default receipt + assert_eq!(recorder.receipts()[0][0], Some(Receipt::default())); + } + + #[test] + fn test_save_receipts_with_pruning_no_block_number() { + // Create a PruneModes with receipts set to PruneMode::Full + let prune_modes = PruneModes { receipts: Some(PruneMode::Full), ..Default::default() }; + + // Create a BlockBatchRecord with the prune_modes + let mut recorder = BlockBatchRecord::new(prune_modes); + + // Set the tip (highest known block) + recorder.set_tip(130); + + // Create a vector of receipts with a default receipt + let receipts = vec![Receipt::default()]; + + // Verify that saving receipts completes without error + assert!(recorder.save_receipts(receipts).is_ok()); + // Verify that there is one block of receipts + assert_eq!(recorder.receipts().len(), 1); + // Verify that the first block contains one receipt + assert_eq!(recorder.receipts()[0].len(), 1); + // Verify that the saved receipt is the default receipt + assert_eq!(recorder.receipts()[0][0], Some(Receipt::default())); + } + + // Test saving receipts with pruning configuration and receipts should be pruned + #[test] + fn test_save_receipts_with_pruning_should_prune() { + // Create a PruneModes with receipts set to PruneMode::Full + let prune_modes = PruneModes { receipts: Some(PruneMode::Full), ..Default::default() }; + + // Create a BlockBatchRecord with the prune_modes + let mut recorder = BlockBatchRecord::new(prune_modes); + + // Set the first block number + recorder.set_first_block(1); + // Set the tip (highest known block) + recorder.set_tip(130); + + // Create a vector of receipts with a default receipt + let receipts = vec![Receipt::default()]; + + // Verify that saving receipts completes without error + assert!(recorder.save_receipts(receipts).is_ok()); + // Verify that there is one block of receipts + assert_eq!(recorder.receipts().len(), 1); + // Verify that the receipts are pruned (empty) + assert!(recorder.receipts()[0].is_empty()); + } + + // Test saving receipts with address filter pruning + #[test] + fn test_save_receipts_with_address_filter_pruning() { + // Create a PruneModes with receipts_log_filter configuration + let prune_modes = PruneModes { + receipts_log_filter: ReceiptsLogPruneConfig(BTreeMap::from([ + (Address::with_last_byte(1), PruneMode::Before(1300001)), + (Address::with_last_byte(2), PruneMode::Before(1300002)), + (Address::with_last_byte(3), PruneMode::Distance(1300003)), + ])), + ..Default::default() + }; + + // Create a BlockBatchRecord with the prune_modes + let mut recorder = BlockBatchRecord::new(prune_modes); + + // Set the first block number + recorder.set_first_block(1); + // Set the tip (highest known block) + recorder.set_tip(1300000); + + // With a receipt that should be pruned (address 4 not in the log filter) + let mut receipt = Receipt::default(); + receipt.logs.push(Log { address: Address::with_last_byte(4), ..Default::default() }); + let receipts = vec![receipt.clone()]; + assert!(recorder.save_receipts(receipts).is_ok()); + // Verify that the receipts are pruned (empty) + assert_eq!(recorder.receipts().len(), 1); + assert_eq!(recorder.receipts()[0], vec![None]); + + // With a receipt that should not be pruned (address 1 in the log filter) + let mut receipt1 = Receipt::default(); + receipt1.logs.push(Log { address: Address::with_last_byte(1), ..Default::default() }); + let receipts = vec![receipt1.clone()]; + assert!(recorder.save_receipts(receipts).is_ok()); + // Verify that the second block of receipts contains the receipt + assert_eq!(recorder.receipts().len(), 2); + assert_eq!(recorder.receipts()[1][0], Some(receipt1)); + + // With a receipt that should not be pruned (address 2 in the log filter) + let mut receipt2 = Receipt::default(); + receipt2.logs.push(Log { address: Address::with_last_byte(2), ..Default::default() }); + let receipts = vec![receipt2.clone()]; + assert!(recorder.save_receipts(receipts).is_ok()); + // Verify that the third block of receipts contains the receipt + assert_eq!(recorder.receipts().len(), 3); + assert_eq!(recorder.receipts()[2][0], Some(receipt2)); + + // With a receipt that should not be pruned (address 3 in the log filter) + let mut receipt3 = Receipt::default(); + receipt3.logs.push(Log { address: Address::with_last_byte(3), ..Default::default() }); + let receipts = vec![receipt3.clone()]; + assert!(recorder.save_receipts(receipts).is_ok()); + // Verify that the fourth block of receipts contains the receipt + assert_eq!(recorder.receipts().len(), 4); + assert_eq!(recorder.receipts()[3][0], Some(receipt3)); + } +}