Improve freezer DB efficiency with periodic restore points (#649)

* Draft of checkpoint freezer DB

* Fix bugs

* Adjust root iterators for checkpoint database

* Fix freezer state lookups with no slot hint

* Fix split comment

* Use "restore point" to refer to frozen states

* Resolve some FIXMEs

* Configurable slots per restore point

* Document new freezer DB functions

* Fix up StoreConfig

* Fix new test for merge

* Document SPRP default CLI flag, clarify tests
This commit is contained in:
Michael Sproul
2019-12-06 14:29:06 +11:00
committed by Paul Hauner
parent 5a765396b7
commit d0319320ce
13 changed files with 587 additions and 91 deletions

View File

@@ -577,7 +577,12 @@ where
TEventHandler: EventHandler<TEthSpec> + 'static,
{
/// Specifies that the `Client` should use a `DiskStore` database.
pub fn disk_store(mut self, hot_path: &Path, cold_path: &Path) -> Result<Self, String> {
pub fn disk_store(
mut self,
hot_path: &Path,
cold_path: &Path,
slots_per_restore_point: u64,
) -> Result<Self, String> {
let context = self
.runtime_context
.as_ref()
@@ -588,8 +593,14 @@ where
.clone()
.ok_or_else(|| "disk_store requires a chain spec".to_string())?;
let store = DiskStore::open(hot_path, cold_path, spec, context.log)
.map_err(|e| format!("Unable to open database: {:?}", e).to_string())?;
let store = DiskStore::open::<TEthSpec>(
hot_path,
cold_path,
slots_per_restore_point,
spec,
context.log,
)
.map_err(|e| format!("Unable to open database: {:?}", e).to_string())?;
self.store = Some(Arc::new(store));
Ok(self)
}

View File

@@ -6,9 +6,6 @@ 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 {
@@ -45,9 +42,6 @@ impl Default for ClientGenesis {
pub struct Config {
pub data_dir: PathBuf,
pub testnet_dir: Option<PathBuf>,
pub db_type: String,
pub db_name: String,
pub freezer_db_path: Option<PathBuf>,
pub log_file: PathBuf,
pub spec_constants: String,
/// If true, the node will use co-ordinated junk for eth1 values.
@@ -59,6 +53,7 @@ pub struct Config {
/// The `genesis` field is not serialized or deserialized by `serde` to ensure it is defined
/// via the CLI at runtime, instead of from a configuration file saved to disk.
pub genesis: ClientGenesis,
pub store: store::StoreConfig,
pub network: network::NetworkConfig,
pub rest_api: rest_api::Config,
pub websocket_server: websocket_server::Config,
@@ -71,10 +66,8 @@ impl Default for Config {
data_dir: PathBuf::from(".lighthouse"),
testnet_dir: None,
log_file: PathBuf::from(""),
db_type: "disk".to_string(),
db_name: "chain_db".to_string(),
freezer_db_path: None,
genesis: <_>::default(),
store: <_>::default(),
network: NetworkConfig::default(),
rest_api: <_>::default(),
websocket_server: <_>::default(),
@@ -90,7 +83,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.db_name))
.map(|data_dir| data_dir.join(&self.store.db_name))
}
/// Get the database path, creating it if necessary.
@@ -104,7 +97,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(DEFAULT_FREEZER_DB_DIR))
.map(|data_dir| data_dir.join(self.store.default_freezer_db_dir()))
}
/// Returns the path to which the client may initialize the on-disk freezer database.
@@ -112,7 +105,8 @@ 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.freezer_db_path
self.store
.freezer_db_path
.clone()
.or_else(|| self.default_freezer_db_path())
}