diff --git a/beacon_node/beacon_chain/src/data_availability_checker/overflow_lru_cache.rs b/beacon_node/beacon_chain/src/data_availability_checker/overflow_lru_cache.rs index 3c05eba5eae..6f8c97046e6 100644 --- a/beacon_node/beacon_chain/src/data_availability_checker/overflow_lru_cache.rs +++ b/beacon_node/beacon_chain/src/data_availability_checker/overflow_lru_cache.rs @@ -212,6 +212,26 @@ impl PendingComponents { AvailableExecutedBlock::new(available_block, import_data, payload_verification_outcome), ))) } + + /// Returns the epoch of the block if it is cached, otherwise returns the epoch of the first blob. + pub fn epoch(&self) -> Option { + self.executed_block + .as_ref() + .map(|pending_block| pending_block.as_block().epoch()) + .or_else(|| { + for maybe_blob in self.verified_blobs.iter() { + if maybe_blob.is_some() { + return maybe_blob.as_ref().map(|kzg_verified_blob| { + kzg_verified_blob + .as_blob() + .slot() + .epoch(E::slots_per_epoch()) + }); + } + } + None + }) + } } /// This is the main struct for this module. Outside methods should @@ -359,6 +379,22 @@ impl DataAvailabilityCheckerInner { pub fn do_maintenance(&self, cutoff_epoch: Epoch) -> Result<(), AvailabilityCheckError> { // clean up any lingering states in the state cache self.state_cache.do_maintenance(cutoff_epoch); + + // Collect keys of pending blocks from a previous epoch to cutoff + let mut write_lock = self.critical.write(); + let mut keys_to_remove = vec![]; + for (key, value) in write_lock.iter() { + if let Some(epoch) = value.epoch() { + if epoch < cutoff_epoch { + keys_to_remove.push(*key); + } + } + } + // Now remove keys + for key in keys_to_remove { + write_lock.pop(&key); + } + Ok(()) }