From 84b07c81fdd6a575e843a0d42115f6114f638669 Mon Sep 17 00:00:00 2001 From: Sunny Gleason Date: Tue, 17 Dec 2019 15:08:40 -0500 Subject: [PATCH] Fix/remove short circuit logic in ledger_purge_batch (&& -> &), found/fixed by @sdhawan (#7526) --- ledger/src/blocktree.rs | 102 ++++++++++++++++++++++++++++++++-------- 1 file changed, 82 insertions(+), 20 deletions(-) diff --git a/ledger/src/blocktree.rs b/ledger/src/blocktree.rs index 338ece757..b29c2d17b 100644 --- a/ledger/src/blocktree.rs +++ b/ledger/src/blocktree.rs @@ -286,35 +286,35 @@ impl Blocktree { .meta_cf .delete_slot(&mut write_batch, from_slot, batch_end) .unwrap_or(false) - && self + & self .erasure_meta_cf .delete_slot(&mut write_batch, from_slot, batch_end) .unwrap_or(false) - && self + & self .data_shred_cf .delete_slot(&mut write_batch, from_slot, batch_end) .unwrap_or(false) - && self + & self .code_shred_cf .delete_slot(&mut write_batch, from_slot, batch_end) .unwrap_or(false) - && self + & self .transaction_status_cf .delete_slot(&mut write_batch, from_slot, batch_end) .unwrap_or(false) - && self + & self .orphans_cf .delete_slot(&mut write_batch, from_slot, batch_end) .unwrap_or(false) - && self + & self .index_cf .delete_slot(&mut write_batch, from_slot, batch_end) .unwrap_or(false) - && self + & self .dead_slots_cf .delete_slot(&mut write_batch, from_slot, batch_end) .unwrap_or(false) - && self + & self .db .column::() .delete_slot(&mut write_batch, from_slot, batch_end) @@ -2283,6 +2283,74 @@ pub mod tests { entries } + // check that all columns are either empty or start at `min_slot` + fn test_all_empty_or_min(blocktree: &Blocktree, min_slot: Slot) { + let condition_met = blocktree + .db + .iter::(IteratorMode::Start) + .unwrap() + .next() + .map(|(slot, _)| slot >= min_slot) + .unwrap_or(true) + & blocktree + .db + .iter::(IteratorMode::Start) + .unwrap() + .next() + .map(|(slot, _)| slot >= min_slot) + .unwrap_or(true) + & blocktree + .db + .iter::(IteratorMode::Start) + .unwrap() + .next() + .map(|((slot, _), _)| slot >= min_slot) + .unwrap_or(true) + & blocktree + .db + .iter::(IteratorMode::Start) + .unwrap() + .next() + .map(|((slot, _), _)| slot >= min_slot) + .unwrap_or(true) + & blocktree + .db + .iter::(IteratorMode::Start) + .unwrap() + .next() + .map(|(slot, _)| slot >= min_slot) + .unwrap_or(true) + & blocktree + .db + .iter::(IteratorMode::Start) + .unwrap() + .next() + .map(|((slot, _), _)| slot >= min_slot) + .unwrap_or(true) + & blocktree + .db + .iter::(IteratorMode::Start) + .unwrap() + .next() + .map(|(slot, _)| slot >= min_slot) + .unwrap_or(true) + & blocktree + .db + .iter::(IteratorMode::Start) + .unwrap() + .next() + .map(|(slot, _)| slot >= min_slot) + .unwrap_or(true) + & blocktree + .db + .iter::(IteratorMode::Start) + .unwrap() + .next() + .map(|((slot, _), _)| slot >= min_slot) + .unwrap_or(true); + assert!(condition_met); + } + #[test] fn test_create_new_ledger() { let mint_total = 1_000_000_000_000; @@ -4113,15 +4181,14 @@ pub mod tests { blocktree.purge_slots(0, Some(5)); - blocktree - .slot_meta_iterator(0) - .unwrap() - .for_each(|(slot, _)| { - assert!(slot > 5); - }); + test_all_empty_or_min(&blocktree, 6); blocktree.purge_slots(0, None); + // min slot shouldn't matter, blocktree should be empty + test_all_empty_or_min(&blocktree, 100); + test_all_empty_or_min(&blocktree, 0); + blocktree.slot_meta_iterator(0).unwrap().for_each(|(_, _)| { assert!(false); }); @@ -4139,12 +4206,7 @@ pub mod tests { blocktree.purge_slots(0, Some(4999)); - blocktree - .slot_meta_iterator(0) - .unwrap() - .for_each(|(slot, _)| { - assert_eq!(slot, 5000); - }); + test_all_empty_or_min(&blocktree, 5000); drop(blocktree); Blocktree::destroy(&blocktree_path).expect("Expected successful database destruction");