From 7813a1decdf5d2f95631df52ac0ef2a990afb854 Mon Sep 17 00:00:00 2001 From: "mergify[bot]" <37929162+mergify[bot]@users.noreply.github.com> Date: Thu, 28 May 2020 08:40:41 -0700 Subject: [PATCH] Purge next slots to avoid a blockstore_processor panic on restart (#10281) (#10285) (cherry picked from commit 5ac2ae1178561e19bfbcd2aade8de90b84df07aa) Co-authored-by: Michael Vines --- ledger-tool/src/main.rs | 1 + ledger/src/blockstore.rs | 27 +++++++++++++++++++++++++++ 2 files changed, 28 insertions(+) diff --git a/ledger-tool/src/main.rs b/ledger-tool/src/main.rs index d866a8da3d..123029f4fb 100644 --- a/ledger-tool/src/main.rs +++ b/ledger-tool/src/main.rs @@ -1187,6 +1187,7 @@ fn main() { let end_slot = value_t_or_exit!(arg_matches, "end_slot", Slot); let blockstore = open_blockstore(&ledger_path); blockstore.purge_slots(start_slot, end_slot); + blockstore.purge_from_next_slots(start_slot, end_slot); } ("list-roots", Some(arg_matches)) => { let blockstore = open_blockstore(&ledger_path); diff --git a/ledger/src/blockstore.rs b/ledger/src/blockstore.rs index eb615c2bc9..24eb427a86 100644 --- a/ledger/src/blockstore.rs +++ b/ledger/src/blockstore.rs @@ -350,6 +350,33 @@ impl Blockstore { self.purge_slots_with_delay(from_slot, to_slot, None) } + /// Ensures that the SlotMeta::next_slots vector for all slots contain no references in the + /// [from_slot,to_slot] range + /// + /// Dangerous; Use with care + pub fn purge_from_next_slots(&self, from_slot: Slot, to_slot: Slot) { + for (slot, mut meta) in self + .slot_meta_iterator(0) + .expect("unable to iterate over meta") + { + if slot > to_slot { + break; + } + + let original_len = meta.next_slots.len(); + meta.next_slots + .retain(|slot| *slot < from_slot || *slot > to_slot); + if meta.next_slots.len() != original_len { + info!("purge_from_next_slots: adjusted meta for slot {}", slot); + self.put_meta_bytes( + slot, + &bincode::serialize(&meta).expect("couldn't update meta"), + ) + .expect("couldn't update meta"); + } + } + } + // Returns whether or not all columns successfully purged the slot range fn run_purge(&self, from_slot: Slot, to_slot: Slot) -> Result { let mut write_batch = self