Add methods to delete blocks and states from disk (#843)

Closes #833
This commit is contained in:
Michael Sproul
2020-03-04 16:48:35 +11:00
committed by GitHub
parent 12d9b42188
commit 1f16d8fe4d
3 changed files with 142 additions and 9 deletions

View File

@@ -138,6 +138,12 @@ impl<E: EthSpec> Store<E> for HotColdDB<E> {
}
}
/// Delete a block from the store and the block cache.
fn delete_block(&self, block_root: &Hash256) -> Result<(), Error> {
self.block_cache.lock().pop(block_root);
self.delete::<SignedBeaconBlock<E>>(block_root)
}
/// Store a state in the store.
fn put_state(&self, state_root: &Hash256, state: BeaconState<E>) -> Result<(), Error> {
if state.slot < self.get_split_slot() {
@@ -181,6 +187,29 @@ impl<E: EthSpec> Store<E> for HotColdDB<E> {
}
}
/// Delete a state, ensuring it is removed from the LRU cache, as well as from on-disk.
///
/// It is assumed that all states being deleted reside in the hot DB, even if their slot is less
/// than the split point. You shouldn't delete states from the finalized portion of the chain
/// (which are frozen, and won't be deleted), or valid descendents of the finalized checkpoint
/// (which will be deleted by this function but shouldn't be).
fn delete_state(&self, state_root: &Hash256, slot: Slot) -> Result<(), Error> {
// Delete the state summary.
self.hot_db
.key_delete(DBColumn::BeaconStateSummary.into(), state_root.as_bytes())?;
// Delete the full state if it lies on an epoch boundary.
if slot % E::slots_per_epoch() == 0 {
self.hot_db
.key_delete(DBColumn::BeaconState.into(), state_root.as_bytes())?;
}
// Delete from the cache.
self.state_cache.lock().pop(state_root);
Ok(())
}
/// Advance the split point of the store, moving new finalized states to the freezer.
fn freeze_to_state(
store: Arc<Self>,
@@ -232,10 +261,7 @@ impl<E: EthSpec> Store<E> for HotColdDB<E> {
store.store_cold_state_slot(&state_root, slot)?;
// Delete the old summary, and the full state if we lie on an epoch boundary.
to_delete.push((DBColumn::BeaconStateSummary, state_root));
if slot % E::slots_per_epoch() == 0 {
to_delete.push((DBColumn::BeaconState, state_root));
}
to_delete.push((state_root, slot));
}
// 2. Update the split slot
@@ -246,10 +272,8 @@ impl<E: EthSpec> Store<E> for HotColdDB<E> {
store.store_split()?;
// 3. Delete from the hot DB
for (column, state_root) in to_delete {
store
.hot_db
.key_delete(column.into(), state_root.as_bytes())?;
for (state_root, slot) in to_delete {
store.delete_state(&state_root, slot)?;
}
debug!(

View File

@@ -91,6 +91,11 @@ pub trait Store<E: EthSpec>: Sync + Send + Sized + 'static {
self.get(block_root)
}
/// Delete a block from the store.
fn delete_block(&self, block_root: &Hash256) -> Result<(), Error> {
self.delete::<SignedBeaconBlock<E>>(block_root)
}
/// Store a state in the store.
fn put_state(&self, state_root: &Hash256, state: BeaconState<E>) -> Result<(), Error>;
@@ -123,6 +128,11 @@ pub trait Store<E: EthSpec>: Sync + Send + Sized + 'static {
self.get_state(state_root, slot)
}
/// Delete a state from the store.
fn delete_state(&self, state_root: &Hash256, _slot: Slot) -> Result<(), Error> {
self.key_delete(DBColumn::BeaconState.into(), state_root.as_bytes())
}
/// (Optionally) Move all data before the frozen slot to the freezer database.
fn freeze_to_state(
_store: Arc<Self>,