Prevent fd leak in random slasher tests (#6254)

* Prevent fd leak in random slasher tests

* Clippy
This commit is contained in:
Michael Sproul
2024-08-19 19:21:07 +10:00
committed by GitHub
parent 042915859d
commit 6faa9c678e
3 changed files with 121 additions and 18 deletions

View File

@@ -4,8 +4,8 @@ mod mdbx_impl;
mod redb_impl;
use crate::{
metrics, AttesterRecord, AttesterSlashingStatus, CompactAttesterRecord, Config, Error,
ProposerSlashingStatus,
metrics, AttesterRecord, AttesterSlashingStatus, CompactAttesterRecord, Config, Database,
Error, ProposerSlashingStatus,
};
use byteorder::{BigEndian, ByteOrder};
use interface::{Environment, OpenDatabases, RwTransaction};
@@ -350,6 +350,18 @@ impl<E: EthSpec> SlasherDB<E> {
Ok(())
}
pub fn get_config(&self) -> &Config {
&self.config
}
/// TESTING ONLY.
///
/// Replace the config for this database. This is only a sane thing to do if the database
/// is empty (has been `reset`).
pub fn update_config(&mut self, config: Arc<Config>) {
self.config = config;
}
/// Load a config from disk.
///
/// This is generic in order to allow loading of configs for different schema versions.
@@ -799,6 +811,50 @@ impl<E: EthSpec> SlasherDB<E> {
Ok(())
}
/// Delete all data from the database, essentially re-initialising it.
///
/// We use this reset pattern in tests instead of leaking tonnes of file descriptors and
/// exhausting our allocation by creating (and leaking) databases.
///
/// THIS FUNCTION SHOULD ONLY BE USED IN TESTS.
pub fn reset(&self) -> Result<(), Error> {
// Clear the cache(s) first.
self.attestation_root_cache.lock().clear();
// Pattern match to avoid missing any database.
let OpenDatabases {
indexed_attestation_db,
indexed_attestation_id_db,
attesters_db,
attesters_max_targets_db,
min_targets_db,
max_targets_db,
current_epochs_db,
proposers_db,
metadata_db,
} = &self.databases;
let mut txn = self.begin_rw_txn()?;
self.reset_db(&mut txn, indexed_attestation_db)?;
self.reset_db(&mut txn, indexed_attestation_id_db)?;
self.reset_db(&mut txn, attesters_db)?;
self.reset_db(&mut txn, attesters_max_targets_db)?;
self.reset_db(&mut txn, min_targets_db)?;
self.reset_db(&mut txn, max_targets_db)?;
self.reset_db(&mut txn, current_epochs_db)?;
self.reset_db(&mut txn, proposers_db)?;
self.reset_db(&mut txn, metadata_db)?;
txn.commit()
}
fn reset_db(&self, txn: &mut RwTransaction<'_>, db: &Database<'static>) -> Result<(), Error> {
let mut cursor = txn.cursor(db)?;
if cursor.first_key()?.is_none() {
return Ok(());
}
cursor.delete_while(|_| Ok(true))?;
Ok(())
}
}
#[cfg(test)]