Add LRU cache to database (#837)

* Add LRU caches to store

* Improvements to LRU caches

* Take state by value in `Store::put_state`

* Store blocks by value, configurable cache sizes

* Use a StateBatch to efficiently store skip states

* Fix store tests

* Add CloneConfig test, remove unused metrics

* Use Mutexes instead of RwLocks for LRU caches
This commit is contained in:
Michael Sproul
2020-02-10 11:30:21 +11:00
committed by GitHub
parent c3182e3c1c
commit e0b9fa599f
29 changed files with 514 additions and 385 deletions

View File

@@ -7,7 +7,7 @@ use beacon_chain::{
slot_clock::{SlotClock, SystemTimeSlotClock},
store::{
migrate::{BackgroundMigrator, Migrate, NullMigrator},
DiskStore, MemoryStore, SimpleDiskStore, Store,
DiskStore, MemoryStore, SimpleDiskStore, Store, StoreConfig,
},
BeaconChain, BeaconChainTypes, Eth1ChainBackend, EventHandler,
};
@@ -478,7 +478,7 @@ where
mut self,
hot_path: &Path,
cold_path: &Path,
slots_per_restore_point: u64,
config: StoreConfig,
) -> Result<Self, String> {
let context = self
.runtime_context
@@ -490,14 +490,8 @@ where
.clone()
.ok_or_else(|| "disk_store requires a chain spec".to_string())?;
let store = DiskStore::open(
hot_path,
cold_path,
slots_per_restore_point,
spec,
context.log,
)
.map_err(|e| format!("Unable to open database: {:?}", e))?;
let store = DiskStore::open(hot_path, cold_path, config, spec, context.log)
.map_err(|e| format!("Unable to open database: {:?}", e))?;
self.store = Some(Arc::new(store));
Ok(self)
}

View File

@@ -6,6 +6,9 @@ use std::path::PathBuf;
/// The number initial validators when starting the `Minimal`.
const TESTNET_SPEC_CONSTANTS: &str = "minimal";
/// Default directory name for the freezer database under the top-level data dir.
const DEFAULT_FREEZER_DB_DIR: &str = "freezer_db";
/// Defines how the client should initialize the `BeaconChain` and other components.
#[derive(Debug, Clone, Serialize, Deserialize)]
pub enum ClientGenesis {
@@ -41,6 +44,10 @@ impl Default for ClientGenesis {
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct Config {
pub data_dir: PathBuf,
/// Name of the directory inside the data directory where the main "hot" DB is located.
pub db_name: String,
/// Path where the freezer database will be located.
pub freezer_db_path: Option<PathBuf>,
pub testnet_dir: Option<PathBuf>,
pub log_file: PathBuf,
pub spec_constants: String,
@@ -64,6 +71,8 @@ impl Default for Config {
fn default() -> Self {
Self {
data_dir: PathBuf::from(".lighthouse"),
db_name: "chain_db".to_string(),
freezer_db_path: None,
testnet_dir: None,
log_file: PathBuf::from(""),
genesis: <_>::default(),
@@ -83,7 +92,7 @@ impl Config {
/// Get the database path without initialising it.
pub fn get_db_path(&self) -> Option<PathBuf> {
self.get_data_dir()
.map(|data_dir| data_dir.join(&self.store.db_name))
.map(|data_dir| data_dir.join(&self.db_name))
}
/// Get the database path, creating it if necessary.
@@ -97,7 +106,7 @@ impl Config {
/// Fetch default path to use for the freezer database.
fn default_freezer_db_path(&self) -> Option<PathBuf> {
self.get_data_dir()
.map(|data_dir| data_dir.join(self.store.default_freezer_db_dir()))
.map(|data_dir| data_dir.join(DEFAULT_FREEZER_DB_DIR))
}
/// Returns the path to which the client may initialize the on-disk freezer database.
@@ -105,8 +114,7 @@ impl Config {
/// Will attempt to use the user-supplied path from e.g. the CLI, or will default
/// to a directory in the data_dir if no path is provided.
pub fn get_freezer_db_path(&self) -> Option<PathBuf> {
self.store
.freezer_db_path
self.freezer_db_path
.clone()
.or_else(|| self.default_freezer_db_path())
}