Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

test: add unit tests for save_receipts #9255

Merged
merged 1 commit into from
Jul 3, 2024
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
186 changes: 186 additions & 0 deletions crates/revm/src/batch.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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));
}
}
Loading