From 47a7ee2afd5b42ccbc011eb67472dc8493d02713 Mon Sep 17 00:00:00 2001 From: Owanikin Date: Thu, 21 Aug 2025 17:46:34 +0100 Subject: [PATCH 01/20] upgrade redb file format to v3 --- Cargo.lock | 6 +-- beacon_node/beacon_chain/src/schema_change.rs | 9 +++++ .../src/schema_change/migration_schema_v29.rs | 38 +++++++++++++++++++ beacon_node/store/Cargo.toml | 2 +- beacon_node/store/src/metadata.rs | 2 +- 5 files changed, 52 insertions(+), 5 deletions(-) create mode 100644 beacon_node/beacon_chain/src/schema_change/migration_schema_v29.rs diff --git a/Cargo.lock b/Cargo.lock index 7c637a18471..c2837521a79 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -7353,7 +7353,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8a56d757972c98b346a9b766e3f02746cde6dd1cd1d1d563472929fdd74bec4d" dependencies = [ "anyhow", - "itertools 0.13.0", + "itertools 0.14.0", "proc-macro2", "quote", "syn 2.0.100", @@ -7665,9 +7665,9 @@ dependencies = [ [[package]] name = "redb" -version = "2.4.0" +version = "2.6.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ea0a72cd7140de9fc3e318823b883abf819c20d478ec89ce880466dc2ef263c6" +checksum = "59b38b05028f398f08bea4691640503ec25fcb60b82fb61ce1f8fd1f4fccd3f7" dependencies = [ "libc", ] diff --git a/beacon_node/beacon_chain/src/schema_change.rs b/beacon_node/beacon_chain/src/schema_change.rs index ddc59783394..aa4925deb30 100644 --- a/beacon_node/beacon_chain/src/schema_change.rs +++ b/beacon_node/beacon_chain/src/schema_change.rs @@ -5,6 +5,7 @@ mod migration_schema_v25; mod migration_schema_v26; mod migration_schema_v27; mod migration_schema_v28; +mod migration_schema_v29; use crate::beacon_chain::BeaconChainTypes; use std::sync::Arc; @@ -88,6 +89,14 @@ pub fn migrate_schema( let ops = migration_schema_v28::downgrade_from_v28::(db.clone())?; db.store_schema_version_atomically(to, ops) } + (SchemaVersion(28), SchemaVersion(29)) => { + let ops = migration_schema_v29::upgrade_to_v29::(db.clone())?; + db.store_schema_version_atomically(to, ops) + } + (SchemaVersion(29), SchemaVersion(28)) => { + let ops = migration_schema_v29::downgrade_from_v29::(db.clone())?; + db.store_schema_version_atomically(to, ops) + } // Anything else is an error. (_, _) => Err(HotColdDBError::UnsupportedSchemaVersion { target_version: to, diff --git a/beacon_node/beacon_chain/src/schema_change/migration_schema_v29.rs b/beacon_node/beacon_chain/src/schema_change/migration_schema_v29.rs new file mode 100644 index 00000000000..68001cda38c --- /dev/null +++ b/beacon_node/beacon_chain/src/schema_change/migration_schema_v29.rs @@ -0,0 +1,38 @@ +use crate::BeaconChainTypes; +use std::sync::Arc; +use store::{metadata::SchemaVersion, Error, HotColdDB, KeyValueStoreOp}; + +#[cfg(feature = "redb")] +use store::config::BeaconNodeBackend; +// Result, Error> +pub fn upgrade_to_v29( + db: Arc> +) -> Result, Error> { + #[cfg(feature = "redb")] + { + if let Some(backend) = db.backend() { + use store::database::interface::BeaconNodeBackend; + + if let BeaconNodeBackend::Redb(redb) = backend { + match redb.upgrade() { + Ok(did_upgrade) => {} + Err(e) => { + return Err(Error::MigrationError(format!{ + "Redb file-format upgrade failed: {e}" + })); + } + } + } + } + } + + Ok(vec![]) +} + +pub fn downgrade_from_v29( + _d: Arc>, +) -> Result, Error> { + Err(Error::MigrationError("Cannot downgrade from v29: Redb file format upgrade is irreversible".to_string())) +} + + diff --git a/beacon_node/store/Cargo.toml b/beacon_node/store/Cargo.toml index 13df83efabb..63d92bd44b4 100644 --- a/beacon_node/store/Cargo.toml +++ b/beacon_node/store/Cargo.toml @@ -21,7 +21,7 @@ logging = { workspace = true } lru = { workspace = true } metrics = { workspace = true } parking_lot = { workspace = true } -redb = { version = "2.1.3", optional = true } +redb = { version = "2.6.2", optional = true } safe_arith = { workspace = true } serde = { workspace = true } smallvec = { workspace = true } diff --git a/beacon_node/store/src/metadata.rs b/beacon_node/store/src/metadata.rs index cf494684515..215cdb2b64d 100644 --- a/beacon_node/store/src/metadata.rs +++ b/beacon_node/store/src/metadata.rs @@ -4,7 +4,7 @@ use ssz::{Decode, Encode}; use ssz_derive::{Decode, Encode}; use types::{Hash256, Slot}; -pub const CURRENT_SCHEMA_VERSION: SchemaVersion = SchemaVersion(28); +pub const CURRENT_SCHEMA_VERSION: SchemaVersion = SchemaVersion(29); // All the keys that get stored under the `BeaconMeta` column. // From 9f8a43f7abc0782fe58c749a3e3ea69dd5ef2fdd Mon Sep 17 00:00:00 2001 From: Owanikin Date: Thu, 28 Aug 2025 12:23:43 +0100 Subject: [PATCH 02/20] WIP: migration_schema_v29 changes --- .../src/schema_change/migration_schema_v29.rs | 18 ++++++++++++++++-- 1 file changed, 16 insertions(+), 2 deletions(-) diff --git a/beacon_node/beacon_chain/src/schema_change/migration_schema_v29.rs b/beacon_node/beacon_chain/src/schema_change/migration_schema_v29.rs index 68001cda38c..559b9e5f5f4 100644 --- a/beacon_node/beacon_chain/src/schema_change/migration_schema_v29.rs +++ b/beacon_node/beacon_chain/src/schema_change/migration_schema_v29.rs @@ -30,9 +30,23 @@ pub fn upgrade_to_v29( } pub fn downgrade_from_v29( - _d: Arc>, + db: Arc>, ) -> Result, Error> { - Err(Error::MigrationError("Cannot downgrade from v29: Redb file format upgrade is irreversible".to_string())) + #[cfg(feature = "redb")] + { + if let Some(backend) = db.backend() { + use store::database::interface::BeaconNodeBackend; + + if let BeaconNodeBackend::Redb(_) = backend { + return Err(Error::MigrationError( + "Cannot downgrade from v29: Redb file format upgrade is irreversible".to_string() + )); + } + } + } + + // For all other backends, just no-op + Ok(vec![]) } From 04728b5b0a53a57842ec275d4b590e61ace5fcfa Mon Sep 17 00:00:00 2001 From: Owanikin Date: Thu, 28 Aug 2025 15:54:51 +0100 Subject: [PATCH 03/20] WIP: logging if migration happened successfully or not --- .../src/schema_change/migration_schema_v29.rs | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/beacon_node/beacon_chain/src/schema_change/migration_schema_v29.rs b/beacon_node/beacon_chain/src/schema_change/migration_schema_v29.rs index 559b9e5f5f4..a529c0f5808 100644 --- a/beacon_node/beacon_chain/src/schema_change/migration_schema_v29.rs +++ b/beacon_node/beacon_chain/src/schema_change/migration_schema_v29.rs @@ -15,7 +15,15 @@ pub fn upgrade_to_v29( if let BeaconNodeBackend::Redb(redb) = backend { match redb.upgrade() { - Ok(did_upgrade) => {} + Ok(did_upgrade) => { + if did_upgrade { + info!("Redb file format successfully upgraded to v29"); + } else { + use tracing::info; + + info!("Redb file-format already at v29, no upgrade needed"); + } + } Err(e) => { return Err(Error::MigrationError(format!{ "Redb file-format upgrade failed: {e}" From e6806cd16aef76913b0fdb34d1bd86b2e90bfd03 Mon Sep 17 00:00:00 2001 From: Owanikin Date: Fri, 29 Aug 2025 14:12:11 +0100 Subject: [PATCH 04/20] WIP: migration_schema_v29 changes --- .../src/schema_change/migration_schema_v29.rs | 12 +++--------- 1 file changed, 3 insertions(+), 9 deletions(-) diff --git a/beacon_node/beacon_chain/src/schema_change/migration_schema_v29.rs b/beacon_node/beacon_chain/src/schema_change/migration_schema_v29.rs index a529c0f5808..855c0ea1b10 100644 --- a/beacon_node/beacon_chain/src/schema_change/migration_schema_v29.rs +++ b/beacon_node/beacon_chain/src/schema_change/migration_schema_v29.rs @@ -4,24 +4,20 @@ use store::{metadata::SchemaVersion, Error, HotColdDB, KeyValueStoreOp}; #[cfg(feature = "redb")] use store::config::BeaconNodeBackend; -// Result, Error> + pub fn upgrade_to_v29( db: Arc> ) -> Result, Error> { #[cfg(feature = "redb")] { if let Some(backend) = db.backend() { - use store::database::interface::BeaconNodeBackend; - if let BeaconNodeBackend::Redb(redb) = backend { match redb.upgrade() { Ok(did_upgrade) => { if did_upgrade { - info!("Redb file format successfully upgraded to v29"); + tracing::info!("Redb file format successfully upgraded to v29"); } else { - use tracing::info; - - info!("Redb file-format already at v29, no upgrade needed"); + tracing::info!("Redb file-format already at v29, no upgrade needed"); } } Err(e) => { @@ -43,8 +39,6 @@ pub fn downgrade_from_v29( #[cfg(feature = "redb")] { if let Some(backend) = db.backend() { - use store::database::interface::BeaconNodeBackend; - if let BeaconNodeBackend::Redb(_) = backend { return Err(Error::MigrationError( "Cannot downgrade from v29: Redb file format upgrade is irreversible".to_string() From 4fe948dd8126af3c253d6040c4ef1ec00b2a36cb Mon Sep 17 00:00:00 2001 From: Owanikin Date: Fri, 29 Aug 2025 14:45:41 +0100 Subject: [PATCH 05/20] fix formatting and linting issues --- beacon_node/beacon_chain/Cargo.toml | 1 + .../src/beacon_fork_choice_store.rs | 2 +- .../src/schema_change/migration_schema_v29.rs | 17 ++++++++--------- 3 files changed, 10 insertions(+), 10 deletions(-) diff --git a/beacon_node/beacon_chain/Cargo.toml b/beacon_node/beacon_chain/Cargo.toml index dca351cbac6..0e46238a3fc 100644 --- a/beacon_node/beacon_chain/Cargo.toml +++ b/beacon_node/beacon_chain/Cargo.toml @@ -13,6 +13,7 @@ participation_metrics = [] # Exposes validator participation metrics to Prometh fork_from_env = [] # Initialise the harness chain spec from the FORK_NAME env variable portable = ["bls/supranational-portable"] test_backfill = [] +redb = ["store/redb"] [dependencies] alloy-primitives = { workspace = true } diff --git a/beacon_node/beacon_chain/src/beacon_fork_choice_store.rs b/beacon_node/beacon_chain/src/beacon_fork_choice_store.rs index 2c05df3c7fe..440388661c2 100644 --- a/beacon_node/beacon_chain/src/beacon_fork_choice_store.rs +++ b/beacon_node/beacon_chain/src/beacon_fork_choice_store.rs @@ -377,7 +377,7 @@ where .store .get_hot_state(&self.justified_state_root, update_cache) .map_err(Error::FailedToReadState)? - .ok_or_else(|| Error::MissingState(self.justified_state_root))?; + .ok_or(Error::MissingState(self.justified_state_root))?; self.justified_balances = JustifiedBalances::from_justified_state(&state)?; } diff --git a/beacon_node/beacon_chain/src/schema_change/migration_schema_v29.rs b/beacon_node/beacon_chain/src/schema_change/migration_schema_v29.rs index 855c0ea1b10..87b2cbdb9fe 100644 --- a/beacon_node/beacon_chain/src/schema_change/migration_schema_v29.rs +++ b/beacon_node/beacon_chain/src/schema_change/migration_schema_v29.rs @@ -1,12 +1,12 @@ use crate::BeaconChainTypes; use std::sync::Arc; -use store::{metadata::SchemaVersion, Error, HotColdDB, KeyValueStoreOp}; +use store::{Error, HotColdDB, KeyValueStoreOp}; #[cfg(feature = "redb")] use store::config::BeaconNodeBackend; pub fn upgrade_to_v29( - db: Arc> + _db: Arc>, ) -> Result, Error> { #[cfg(feature = "redb")] { @@ -21,7 +21,7 @@ pub fn upgrade_to_v29( } } Err(e) => { - return Err(Error::MigrationError(format!{ + return Err(Error::MigrationError(format! { "Redb file-format upgrade failed: {e}" })); } @@ -29,26 +29,25 @@ pub fn upgrade_to_v29( } } } - + Ok(vec![]) } pub fn downgrade_from_v29( - db: Arc>, + _db: Arc>, ) -> Result, Error> { #[cfg(feature = "redb")] { if let Some(backend) = db.backend() { if let BeaconNodeBackend::Redb(_) = backend { return Err(Error::MigrationError( - "Cannot downgrade from v29: Redb file format upgrade is irreversible".to_string() + "Cannot downgrade from v29: Redb file format upgrade is irreversible" + .to_string(), )); } } } - + // For all other backends, just no-op Ok(vec![]) } - - From 0a94f45794422b1882192d144263d68a43eeba78 Mon Sep 17 00:00:00 2001 From: Eitan Seri-Levi Date: Wed, 3 Sep 2025 10:29:37 -0700 Subject: [PATCH 06/20] some hacking --- Cargo.lock | 1 + beacon_node/beacon_chain/Cargo.toml | 3 +- .../src/schema_change/migration_schema_v29.rs | 28 +++---------------- beacon_node/store/src/database/interface.rs | 8 ++++++ beacon_node/store/src/database/redb_impl.rs | 6 +++- beacon_node/store/src/hot_cold_store.rs | 11 ++++++++ beacon_node/store/src/lib.rs | 2 ++ lighthouse/Cargo.toml | 2 +- 8 files changed, 34 insertions(+), 27 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index c2837521a79..5cf01801c7b 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -893,6 +893,7 @@ dependencies = [ "proto_array", "rand 0.9.0", "rayon", + "redb", "safe_arith", "sensitive_url", "serde", diff --git a/beacon_node/beacon_chain/Cargo.toml b/beacon_node/beacon_chain/Cargo.toml index 0e46238a3fc..1d9e9d52469 100644 --- a/beacon_node/beacon_chain/Cargo.toml +++ b/beacon_node/beacon_chain/Cargo.toml @@ -13,7 +13,7 @@ participation_metrics = [] # Exposes validator participation metrics to Prometh fork_from_env = [] # Initialise the harness chain spec from the FORK_NAME env variable portable = ["bls/supranational-portable"] test_backfill = [] -redb = ["store/redb"] +redb = ["dep:redb"] [dependencies] alloy-primitives = { workspace = true } @@ -47,6 +47,7 @@ parking_lot = { workspace = true } proto_array = { workspace = true } rand = { workspace = true } rayon = { workspace = true } +redb = { version = "2.6.2", optional = true } safe_arith = { workspace = true } sensitive_url = { workspace = true } serde = { workspace = true } diff --git a/beacon_node/beacon_chain/src/schema_change/migration_schema_v29.rs b/beacon_node/beacon_chain/src/schema_change/migration_schema_v29.rs index 87b2cbdb9fe..750cbb3fb23 100644 --- a/beacon_node/beacon_chain/src/schema_change/migration_schema_v29.rs +++ b/beacon_node/beacon_chain/src/schema_change/migration_schema_v29.rs @@ -2,34 +2,13 @@ use crate::BeaconChainTypes; use std::sync::Arc; use store::{Error, HotColdDB, KeyValueStoreOp}; -#[cfg(feature = "redb")] -use store::config::BeaconNodeBackend; +use store::database::interface::BeaconNodeBackend; pub fn upgrade_to_v29( - _db: Arc>, + db: Arc>, ) -> Result, Error> { - #[cfg(feature = "redb")] - { - if let Some(backend) = db.backend() { - if let BeaconNodeBackend::Redb(redb) = backend { - match redb.upgrade() { - Ok(did_upgrade) => { - if did_upgrade { - tracing::info!("Redb file format successfully upgraded to v29"); - } else { - tracing::info!("Redb file-format already at v29, no upgrade needed"); - } - } - Err(e) => { - return Err(Error::MigrationError(format! { - "Redb file-format upgrade failed: {e}" - })); - } - } - } - } - } + db.upgrade(); Ok(vec![]) } @@ -47,6 +26,7 @@ pub fn downgrade_from_v29( } } } + // Downgrade would probably be a no-op in all cases, and we just wont allow it (so maybe return an error always) // For all other backends, just no-op Ok(vec![]) diff --git a/beacon_node/store/src/database/interface.rs b/beacon_node/store/src/database/interface.rs index 5646f1179c8..f8071d5ae72 100644 --- a/beacon_node/store/src/database/interface.rs +++ b/beacon_node/store/src/database/interface.rs @@ -5,6 +5,7 @@ use crate::database::redb_impl; use crate::{ColumnIter, ColumnKeyIter, DBColumn, Error, ItemStore, Key, KeyValueStore, metrics}; use crate::{KeyValueStoreOp, StoreConfig, config::DatabaseBackend}; use std::collections::HashSet; +use std::fmt::Debug; use std::path::Path; use types::EthSpec; @@ -168,6 +169,13 @@ impl KeyValueStore for BeaconNodeBackend { BeaconNodeBackend::Redb(txn) => redb_impl::Redb::delete_batch(txn, col, ops), } } + + fn upgrade(&self) { + match self { + BeaconNodeBackend::LevelDb(level_db) => todo!(), + BeaconNodeBackend::Redb(redb) => redb.upgrade(), + } + } fn delete_if( &self, diff --git a/beacon_node/store/src/database/redb_impl.rs b/beacon_node/store/src/database/redb_impl.rs index 4077326ecaf..cbb3f343185 100644 --- a/beacon_node/store/src/database/redb_impl.rs +++ b/beacon_node/store/src/database/redb_impl.rs @@ -29,7 +29,7 @@ impl From for redb::Durability { impl Redb { pub fn open(path: &Path) -> Result { let db_file = path.join(DB_FILE_NAME); - let db = redb::Database::create(db_file)?; + let mut db = redb::Database::create(db_file)?; for column in DBColumn::iter() { Redb::::create_table(&db, column.into())?; @@ -41,6 +41,10 @@ impl Redb { }) } + pub fn upgrade(&self) { + self.db.write().upgrade(); + } + fn create_table(db: &redb::Database, table_name: &str) -> Result<(), Error> { let table_definition: TableDefinition<'_, &[u8], &[u8]> = TableDefinition::new(table_name); let tx = db.begin_write()?; diff --git a/beacon_node/store/src/hot_cold_store.rs b/beacon_node/store/src/hot_cold_store.rs index 8116596aa09..11b8cdd5cda 100644 --- a/beacon_node/store/src/hot_cold_store.rs +++ b/beacon_node/store/src/hot_cold_store.rs @@ -1,3 +1,5 @@ +#[cfg(feature = "redb")] +use crate::config::DatabaseBackend; use crate::config::{OnDiskStoreConfig, StoreConfig}; use crate::database::interface::BeaconNodeBackend; use crate::forwards_iter::{HybridForwardsBlockRootsIterator, HybridForwardsStateRootsIterator}; @@ -82,6 +84,8 @@ pub struct HotColdDB, Cold: ItemStore> { historic_state_cache: Mutex>, /// Chain spec. pub spec: Arc, + /// Database backend type + pub database_backend: Option, /// Mere vessel for E. _phantom: PhantomData, } @@ -242,6 +246,7 @@ impl HotColdDB, MemoryStore> { config, hierarchy, spec, + database_backend: None, _phantom: PhantomData, }; @@ -265,6 +270,11 @@ impl HotColdDB, BeaconNodeBackend> { debug!("Opening HotColdDB"); config.verify::()?; + #[cfg(feature = "redb")] + let database_backend = DatabaseBackend::Redb; + #[cfg(feature = "leveldb")] + let database_backend = DatabaseBackend::LevelDb; + let hierarchy = config.hierarchy_config.to_moduli()?; debug!(?hot_path, "Opening LevelDB"); @@ -294,6 +304,7 @@ impl HotColdDB, BeaconNodeBackend> { config, hierarchy, spec, + database_backend: Some(database_backend), _phantom: PhantomData, }; // Load the config from disk but don't error on a failed read because the config itself may diff --git a/beacon_node/store/src/lib.rs b/beacon_node/store/src/lib.rs index a3d4e4a8cea..4c5ccda516c 100644 --- a/beacon_node/store/src/lib.rs +++ b/beacon_node/store/src/lib.rs @@ -106,6 +106,8 @@ pub trait KeyValueStore: Sync + Send + Sized + 'static { fn delete_batch(&self, column: DBColumn, ops: HashSet<&[u8]>) -> Result<(), Error>; + fn upgrade(&self); + fn delete_if( &self, column: DBColumn, diff --git a/lighthouse/Cargo.toml b/lighthouse/Cargo.toml index 849d30bcf2d..6d1f5d833fd 100644 --- a/lighthouse/Cargo.toml +++ b/lighthouse/Cargo.toml @@ -12,7 +12,7 @@ rust-version = "1.88.0" normal = ["target_check"] [features] -default = ["slasher-lmdb", "beacon-node-leveldb"] +default = ["slasher-lmdb", "beacon-node-redb"] # Writes debugging .ssz files to /tmp during block processing. write_ssz_files = ["beacon_node/write_ssz_files"] # Compiles the BLS crypto code so that the binary is portable across machines. From 86fa5bfb71cf2a1f0930e229c07753687044e135 Mon Sep 17 00:00:00 2001 From: Owanikin Date: Thu, 4 Sep 2025 14:23:00 +0100 Subject: [PATCH 07/20] WIP: some hacking upgrade-reddb-v3 --- Cargo.lock | 1 + beacon_node/beacon_chain/Cargo.toml | 3 +- .../src/schema_change/migration_schema_v29.rs | 31 +++---------------- beacon_node/store/src/database/interface.rs | 8 +++++ beacon_node/store/src/database/redb_impl.rs | 6 +++- beacon_node/store/src/hot_cold_store.rs | 12 ++++++- beacon_node/store/src/lib.rs | 2 ++ lighthouse/Cargo.toml | 2 +- 8 files changed, 35 insertions(+), 30 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index c2837521a79..5cf01801c7b 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -893,6 +893,7 @@ dependencies = [ "proto_array", "rand 0.9.0", "rayon", + "redb", "safe_arith", "sensitive_url", "serde", diff --git a/beacon_node/beacon_chain/Cargo.toml b/beacon_node/beacon_chain/Cargo.toml index 0e46238a3fc..ad3adff8504 100644 --- a/beacon_node/beacon_chain/Cargo.toml +++ b/beacon_node/beacon_chain/Cargo.toml @@ -13,7 +13,7 @@ participation_metrics = [] # Exposes validator participation metrics to Prometh fork_from_env = [] # Initialise the harness chain spec from the FORK_NAME env variable portable = ["bls/supranational-portable"] test_backfill = [] -redb = ["store/redb"] +redb = ["dep:redb"] [dependencies] alloy-primitives = { workspace = true } @@ -47,6 +47,7 @@ parking_lot = { workspace = true } proto_array = { workspace = true } rand = { workspace = true } rayon = { workspace = true } +redb ={ version = "2.6.2", optional = true } safe_arith = { workspace = true } sensitive_url = { workspace = true } serde = { workspace = true } diff --git a/beacon_node/beacon_chain/src/schema_change/migration_schema_v29.rs b/beacon_node/beacon_chain/src/schema_change/migration_schema_v29.rs index 87b2cbdb9fe..39b7e052b14 100644 --- a/beacon_node/beacon_chain/src/schema_change/migration_schema_v29.rs +++ b/beacon_node/beacon_chain/src/schema_change/migration_schema_v29.rs @@ -1,35 +1,12 @@ use crate::BeaconChainTypes; use std::sync::Arc; +use store::database::interface::BeaconNodeBackend; use store::{Error, HotColdDB, KeyValueStoreOp}; -#[cfg(feature = "redb")] -use store::config::BeaconNodeBackend; - pub fn upgrade_to_v29( - _db: Arc>, + db: Arc>, ) -> Result, Error> { - #[cfg(feature = "redb")] - { - if let Some(backend) = db.backend() { - if let BeaconNodeBackend::Redb(redb) = backend { - match redb.upgrade() { - Ok(did_upgrade) => { - if did_upgrade { - tracing::info!("Redb file format successfully upgraded to v29"); - } else { - tracing::info!("Redb file-format already at v29, no upgrade needed"); - } - } - Err(e) => { - return Err(Error::MigrationError(format! { - "Redb file-format upgrade failed: {e}" - })); - } - } - } - } - } - + db.upgrade(); Ok(vec![]) } @@ -48,6 +25,8 @@ pub fn downgrade_from_v29( } } + // Downgrade would probably be a no-op in all cases, and we just won't allow it (so we should maybe return an error always) + // For all other backends, just no-op Ok(vec![]) } diff --git a/beacon_node/store/src/database/interface.rs b/beacon_node/store/src/database/interface.rs index 5646f1179c8..e02d57216b8 100644 --- a/beacon_node/store/src/database/interface.rs +++ b/beacon_node/store/src/database/interface.rs @@ -5,6 +5,7 @@ use crate::database::redb_impl; use crate::{ColumnIter, ColumnKeyIter, DBColumn, Error, ItemStore, Key, KeyValueStore, metrics}; use crate::{KeyValueStoreOp, StoreConfig, config::DatabaseBackend}; use std::collections::HashSet; +use std::fmt::Debug; use std::path::Path; use types::EthSpec; @@ -169,6 +170,13 @@ impl KeyValueStore for BeaconNodeBackend { } } + fn upgrade(&self) { + match self { + BeaconNodeBackend::LevelDb(leveldb) => todo!(), + BeaconNodeBackend::Redb(redb) => redb.upgrade(), + } + } + fn delete_if( &self, column: DBColumn, diff --git a/beacon_node/store/src/database/redb_impl.rs b/beacon_node/store/src/database/redb_impl.rs index 4077326ecaf..cbb3f343185 100644 --- a/beacon_node/store/src/database/redb_impl.rs +++ b/beacon_node/store/src/database/redb_impl.rs @@ -29,7 +29,7 @@ impl From for redb::Durability { impl Redb { pub fn open(path: &Path) -> Result { let db_file = path.join(DB_FILE_NAME); - let db = redb::Database::create(db_file)?; + let mut db = redb::Database::create(db_file)?; for column in DBColumn::iter() { Redb::::create_table(&db, column.into())?; @@ -41,6 +41,10 @@ impl Redb { }) } + pub fn upgrade(&self) { + self.db.write().upgrade(); + } + fn create_table(db: &redb::Database, table_name: &str) -> Result<(), Error> { let table_definition: TableDefinition<'_, &[u8], &[u8]> = TableDefinition::new(table_name); let tx = db.begin_write()?; diff --git a/beacon_node/store/src/hot_cold_store.rs b/beacon_node/store/src/hot_cold_store.rs index 8116596aa09..aac8dc71332 100644 --- a/beacon_node/store/src/hot_cold_store.rs +++ b/beacon_node/store/src/hot_cold_store.rs @@ -1,4 +1,5 @@ -use crate::config::{OnDiskStoreConfig, StoreConfig}; +#[cfg(feature = "redb")] +use crate::config::DatabaseBackend; use crate::database::interface::BeaconNodeBackend; use crate::forwards_iter::{HybridForwardsBlockRootsIterator, HybridForwardsStateRootsIterator}; use crate::hdiff::{HDiff, HDiffBuffer, HierarchyConfig, HierarchyModuli, StorageStrategy}; @@ -82,6 +83,8 @@ pub struct HotColdDB, Cold: ItemStore> { historic_state_cache: Mutex>, /// Chain spec. pub spec: Arc, + /// Database backend type + pub database_backend: Option, /// Mere vessel for E. _phantom: PhantomData, } @@ -242,6 +245,7 @@ impl HotColdDB, MemoryStore> { config, hierarchy, spec, + database_backend: None, _phantom: PhantomData, }; @@ -265,6 +269,11 @@ impl HotColdDB, BeaconNodeBackend> { debug!("Opening HotColdDB"); config.verify::()?; + #[cfg(feature = "redb")] + let database_backend = DatabaseBackend::Redb; + #[cfg(feature = "leveldb")] + let database_backend = DatabaseBackend::LevelDb; + let hierarchy = config.hierarchy_config.to_moduli()?; debug!(?hot_path, "Opening LevelDB"); @@ -294,6 +303,7 @@ impl HotColdDB, BeaconNodeBackend> { config, hierarchy, spec, + database_backend: Some(database_backend), _phantom: PhantomData, }; // Load the config from disk but don't error on a failed read because the config itself may diff --git a/beacon_node/store/src/lib.rs b/beacon_node/store/src/lib.rs index a3d4e4a8cea..4c5ccda516c 100644 --- a/beacon_node/store/src/lib.rs +++ b/beacon_node/store/src/lib.rs @@ -106,6 +106,8 @@ pub trait KeyValueStore: Sync + Send + Sized + 'static { fn delete_batch(&self, column: DBColumn, ops: HashSet<&[u8]>) -> Result<(), Error>; + fn upgrade(&self); + fn delete_if( &self, column: DBColumn, diff --git a/lighthouse/Cargo.toml b/lighthouse/Cargo.toml index 849d30bcf2d..6d1f5d833fd 100644 --- a/lighthouse/Cargo.toml +++ b/lighthouse/Cargo.toml @@ -12,7 +12,7 @@ rust-version = "1.88.0" normal = ["target_check"] [features] -default = ["slasher-lmdb", "beacon-node-leveldb"] +default = ["slasher-lmdb", "beacon-node-redb"] # Writes debugging .ssz files to /tmp during block processing. write_ssz_files = ["beacon_node/write_ssz_files"] # Compiles the BLS crypto code so that the binary is portable across machines. From 2c82eb39d6b1ac400b1456383d03253f676b7661 Mon Sep 17 00:00:00 2001 From: Eitan Seri-Levi Date: Thu, 4 Sep 2025 11:26:20 -0700 Subject: [PATCH 08/20] Add ability to upgrade and check if redb --- .../src/schema_change/migration_schema_v29.rs | 16 +++------------- beacon_node/store/src/database/interface.rs | 15 ++++++++++++++- beacon_node/store/src/hot_cold_store.rs | 18 +++++++++--------- beacon_node/store/src/lib.rs | 4 ++++ beacon_node/store/src/memory_store.rs | 6 ++++++ 5 files changed, 36 insertions(+), 23 deletions(-) diff --git a/beacon_node/beacon_chain/src/schema_change/migration_schema_v29.rs b/beacon_node/beacon_chain/src/schema_change/migration_schema_v29.rs index 750cbb3fb23..08ab5e34e17 100644 --- a/beacon_node/beacon_chain/src/schema_change/migration_schema_v29.rs +++ b/beacon_node/beacon_chain/src/schema_change/migration_schema_v29.rs @@ -7,7 +7,7 @@ use store::database::interface::BeaconNodeBackend; pub fn upgrade_to_v29( db: Arc>, ) -> Result, Error> { - + // TODO(migration-v29) use db.is_redb() to check if its redb and then handle accordingly db.upgrade(); Ok(vec![]) } @@ -15,18 +15,8 @@ pub fn upgrade_to_v29( pub fn downgrade_from_v29( _db: Arc>, ) -> Result, Error> { - #[cfg(feature = "redb")] - { - if let Some(backend) = db.backend() { - if let BeaconNodeBackend::Redb(_) = backend { - return Err(Error::MigrationError( - "Cannot downgrade from v29: Redb file format upgrade is irreversible" - .to_string(), - )); - } - } - } - // Downgrade would probably be a no-op in all cases, and we just wont allow it (so maybe return an error always) + // TODO(migration-v29) use db.is_redb() to check if its redb and then handle accordingly + // i.e. raise an error message in the redb case and dont allow a downgrade // For all other backends, just no-op Ok(vec![]) diff --git a/beacon_node/store/src/database/interface.rs b/beacon_node/store/src/database/interface.rs index f8071d5ae72..787d91cc0e9 100644 --- a/beacon_node/store/src/database/interface.rs +++ b/beacon_node/store/src/database/interface.rs @@ -169,14 +169,27 @@ impl KeyValueStore for BeaconNodeBackend { BeaconNodeBackend::Redb(txn) => redb_impl::Redb::delete_batch(txn, col, ops), } } - + + // TODO(migration-v29) in the redb case, lets raise an info log + // TODO(migration-v29) the level_db case should be a no-op fn upgrade(&self) { match self { + #[cfg(feature = "leveldb")] BeaconNodeBackend::LevelDb(level_db) => todo!(), + #[cfg(feature = "redb")] BeaconNodeBackend::Redb(redb) => redb.upgrade(), } } + fn is_redb(&self) -> bool { + match self { + #[cfg(feature = "leveldb")] + BeaconNodeBackend::LevelDb(level_db) => false, + #[cfg(feature = "redb")] + BeaconNodeBackend::Redb(redb) => true, + } + } + fn delete_if( &self, column: DBColumn, diff --git a/beacon_node/store/src/hot_cold_store.rs b/beacon_node/store/src/hot_cold_store.rs index 11b8cdd5cda..d5b11b81bd6 100644 --- a/beacon_node/store/src/hot_cold_store.rs +++ b/beacon_node/store/src/hot_cold_store.rs @@ -84,8 +84,6 @@ pub struct HotColdDB, Cold: ItemStore> { historic_state_cache: Mutex>, /// Chain spec. pub spec: Arc, - /// Database backend type - pub database_backend: Option, /// Mere vessel for E. _phantom: PhantomData, } @@ -246,7 +244,6 @@ impl HotColdDB, MemoryStore> { config, hierarchy, spec, - database_backend: None, _phantom: PhantomData, }; @@ -270,11 +267,6 @@ impl HotColdDB, BeaconNodeBackend> { debug!("Opening HotColdDB"); config.verify::()?; - #[cfg(feature = "redb")] - let database_backend = DatabaseBackend::Redb; - #[cfg(feature = "leveldb")] - let database_backend = DatabaseBackend::LevelDb; - let hierarchy = config.hierarchy_config.to_moduli()?; debug!(?hot_path, "Opening LevelDB"); @@ -304,7 +296,6 @@ impl HotColdDB, BeaconNodeBackend> { config, hierarchy, spec, - database_backend: Some(database_backend), _phantom: PhantomData, }; // Load the config from disk but don't error on a failed read because the config itself may @@ -474,6 +465,15 @@ impl, Cold: ItemStore> HotColdDB } } + pub fn upgrade(&self) { + self.hot_db.upgrade(); + self.cold_db.upgrade(); + } + + pub fn is_redb(&self) -> bool { + self.hot_db.is_redb() + } + pub fn update_finalized_state( &self, state_root: Hash256, diff --git a/beacon_node/store/src/lib.rs b/beacon_node/store/src/lib.rs index 4c5ccda516c..6817a7b7cc0 100644 --- a/beacon_node/store/src/lib.rs +++ b/beacon_node/store/src/lib.rs @@ -106,7 +106,11 @@ pub trait KeyValueStore: Sync + Send + Sized + 'static { fn delete_batch(&self, column: DBColumn, ops: HashSet<&[u8]>) -> Result<(), Error>; + // TODO(migration-v29) can delete these functions once db migration v29 is deprecated + // TODO(migration-v29) make sure upgrade returns a Result<(), Error> and propogate the error up to + // the migration script accordingly. fn upgrade(&self); + fn is_redb(&self) -> bool; fn delete_if( &self, diff --git a/beacon_node/store/src/memory_store.rs b/beacon_node/store/src/memory_store.rs index 6baef61c9d8..b71dd6ea325 100644 --- a/beacon_node/store/src/memory_store.rs +++ b/beacon_node/store/src/memory_store.rs @@ -146,6 +146,12 @@ impl KeyValueStore for MemoryStore { }); Ok(()) } + + fn upgrade(&self) {} + + fn is_redb(&self) -> bool { + false + } } impl ItemStore for MemoryStore {} From 30c46668fee0b435c81963c1495d0712c62dd135 Mon Sep 17 00:00:00 2001 From: Eitan Seri-Levi Date: Thu, 4 Sep 2025 11:26:55 -0700 Subject: [PATCH 09/20] cargo --- Cargo.lock | 1 - beacon_node/beacon_chain/Cargo.toml | 2 -- 2 files changed, 3 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 5cf01801c7b..c2837521a79 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -893,7 +893,6 @@ dependencies = [ "proto_array", "rand 0.9.0", "rayon", - "redb", "safe_arith", "sensitive_url", "serde", diff --git a/beacon_node/beacon_chain/Cargo.toml b/beacon_node/beacon_chain/Cargo.toml index 1d9e9d52469..dca351cbac6 100644 --- a/beacon_node/beacon_chain/Cargo.toml +++ b/beacon_node/beacon_chain/Cargo.toml @@ -13,7 +13,6 @@ participation_metrics = [] # Exposes validator participation metrics to Prometh fork_from_env = [] # Initialise the harness chain spec from the FORK_NAME env variable portable = ["bls/supranational-portable"] test_backfill = [] -redb = ["dep:redb"] [dependencies] alloy-primitives = { workspace = true } @@ -47,7 +46,6 @@ parking_lot = { workspace = true } proto_array = { workspace = true } rand = { workspace = true } rayon = { workspace = true } -redb = { version = "2.6.2", optional = true } safe_arith = { workspace = true } sensitive_url = { workspace = true } serde = { workspace = true } From 798b6bf3c28b62cc9f6c42fd1b161c5a2de4b41b Mon Sep 17 00:00:00 2001 From: Owanikin Date: Mon, 8 Sep 2025 01:43:45 +0100 Subject: [PATCH 10/20] upgradedredb v3 --- .../src/schema_change/migration_schema_v29.rs | 25 ++++++++++--------- beacon_node/store/src/database/interface.rs | 19 +++++++++----- beacon_node/store/src/database/redb_impl.rs | 7 +++--- beacon_node/store/src/errors.rs | 8 ++++++ beacon_node/store/src/hot_cold_store.rs | 9 ++++--- beacon_node/store/src/lib.rs | 4 +-- beacon_node/store/src/memory_store.rs | 4 ++- 7 files changed, 47 insertions(+), 29 deletions(-) diff --git a/beacon_node/beacon_chain/src/schema_change/migration_schema_v29.rs b/beacon_node/beacon_chain/src/schema_change/migration_schema_v29.rs index 8c804de3955..0148e862c2d 100644 --- a/beacon_node/beacon_chain/src/schema_change/migration_schema_v29.rs +++ b/beacon_node/beacon_chain/src/schema_change/migration_schema_v29.rs @@ -1,26 +1,27 @@ use crate::BeaconChainTypes; use std::sync::Arc; -use store::database::interface::BeaconNodeBackend; use store::{Error, HotColdDB, KeyValueStoreOp}; - -use store::database::interface::BeaconNodeBackend; +use tracing::info; pub fn upgrade_to_v29( db: Arc>, ) -> Result, Error> { - // TODO(migration-v29) use db.is_redb() to check if its redb and then handle accordingly - db.upgrade(); + if db.is_redb() { + info!("Running Redb v29 migration"); + } else { + info!("Running non-Redb v29 migration"); + } + db.upgrade()?; Ok(vec![]) } pub fn downgrade_from_v29( - _db: Arc>, + db: Arc>, ) -> Result, Error> { - // TODO(migration-v29) use db.is_redb() to check if its redb and then handle accordingly - // i.e. raise an error message in the redb case and dont allow a downgrade - - // Downgrade would probably be a no-op in all cases, and we just won't allow it (so we should maybe return an error always) - - // For all other backends, just no-op + if db.is_redb() { + return Err(Error::MigrationError( + "Downgrade from v29 not supported for Redb".into(), + )); + } Ok(vec![]) } diff --git a/beacon_node/store/src/database/interface.rs b/beacon_node/store/src/database/interface.rs index 787d91cc0e9..b92a411af3e 100644 --- a/beacon_node/store/src/database/interface.rs +++ b/beacon_node/store/src/database/interface.rs @@ -5,8 +5,8 @@ use crate::database::redb_impl; use crate::{ColumnIter, ColumnKeyIter, DBColumn, Error, ItemStore, Key, KeyValueStore, metrics}; use crate::{KeyValueStoreOp, StoreConfig, config::DatabaseBackend}; use std::collections::HashSet; -use std::fmt::Debug; use std::path::Path; +use tracing::info; use types::EthSpec; pub enum BeaconNodeBackend { @@ -172,21 +172,28 @@ impl KeyValueStore for BeaconNodeBackend { // TODO(migration-v29) in the redb case, lets raise an info log // TODO(migration-v29) the level_db case should be a no-op - fn upgrade(&self) { + fn upgrade(&self) -> Result<(), Error> { match self { #[cfg(feature = "leveldb")] - BeaconNodeBackend::LevelDb(level_db) => todo!(), + BeaconNodeBackend::LevelDb(_) => { + info!("LevelDB upgrade: no migration needed"); + Ok(()) + } #[cfg(feature = "redb")] - BeaconNodeBackend::Redb(redb) => redb.upgrade(), + BeaconNodeBackend::Redb(redb) => { + info!("Running Redb v29 migration"); + redb.upgrade()?; + Ok(()) + } } } fn is_redb(&self) -> bool { match self { #[cfg(feature = "leveldb")] - BeaconNodeBackend::LevelDb(level_db) => false, + BeaconNodeBackend::LevelDb(_level_db) => false, #[cfg(feature = "redb")] - BeaconNodeBackend::Redb(redb) => true, + BeaconNodeBackend::Redb(_redb) => true, } } diff --git a/beacon_node/store/src/database/redb_impl.rs b/beacon_node/store/src/database/redb_impl.rs index cbb3f343185..4403c54d8f9 100644 --- a/beacon_node/store/src/database/redb_impl.rs +++ b/beacon_node/store/src/database/redb_impl.rs @@ -29,7 +29,7 @@ impl From for redb::Durability { impl Redb { pub fn open(path: &Path) -> Result { let db_file = path.join(DB_FILE_NAME); - let mut db = redb::Database::create(db_file)?; + let db = redb::Database::create(db_file)?; for column in DBColumn::iter() { Redb::::create_table(&db, column.into())?; @@ -41,8 +41,9 @@ impl Redb { }) } - pub fn upgrade(&self) { - self.db.write().upgrade(); + pub fn upgrade(&self) -> Result<(), Error> { + self.db.write().upgrade()?; + Ok(()) } fn create_table(db: &redb::Database, table_name: &str) -> Result<(), Error> { diff --git a/beacon_node/store/src/errors.rs b/beacon_node/store/src/errors.rs index 51b4bfef830..c1d230edcc4 100644 --- a/beacon_node/store/src/errors.rs +++ b/beacon_node/store/src/errors.rs @@ -66,6 +66,7 @@ pub enum Error { LevelDbError(LevelDBError), #[cfg(feature = "redb")] RedbError(Box), + RedbUpgrade(redb::UpgradeError), CacheBuildError(EpochCacheError), RandaoMixOutOfBounds, MilhouseError(milhouse::Error), @@ -235,6 +236,13 @@ impl From for Error { } } +#[cfg(feature = "redb")] +impl From for Error { + fn from(e: redb::UpgradeError) -> Self { + Error::RedbUpgrade(e) + } +} + impl From for Error { fn from(e: EpochCacheError) -> Error { Error::CacheBuildError(e) diff --git a/beacon_node/store/src/hot_cold_store.rs b/beacon_node/store/src/hot_cold_store.rs index b7169cf640a..f69f555c910 100644 --- a/beacon_node/store/src/hot_cold_store.rs +++ b/beacon_node/store/src/hot_cold_store.rs @@ -271,7 +271,7 @@ impl HotColdDB, BeaconNodeBackend> { config.verify::()?; #[cfg(feature = "redb")] - let database_backend = DatabaseBackend::Redb; + let _database_backend = DatabaseBackend::Redb; #[cfg(feature = "leveldb")] let database_backend = DatabaseBackend::LevelDb; @@ -474,9 +474,10 @@ impl, Cold: ItemStore> HotColdDB } } - pub fn upgrade(&self) { - self.hot_db.upgrade(); - self.cold_db.upgrade(); + pub fn upgrade(&self) -> Result<(), Error> { + self.hot_db.upgrade()?; + self.cold_db.upgrade()?; + Ok(()) } pub fn is_redb(&self) -> bool { diff --git a/beacon_node/store/src/lib.rs b/beacon_node/store/src/lib.rs index 6817a7b7cc0..3c5783b1d16 100644 --- a/beacon_node/store/src/lib.rs +++ b/beacon_node/store/src/lib.rs @@ -107,9 +107,7 @@ pub trait KeyValueStore: Sync + Send + Sized + 'static { fn delete_batch(&self, column: DBColumn, ops: HashSet<&[u8]>) -> Result<(), Error>; // TODO(migration-v29) can delete these functions once db migration v29 is deprecated - // TODO(migration-v29) make sure upgrade returns a Result<(), Error> and propogate the error up to - // the migration script accordingly. - fn upgrade(&self); + fn upgrade(&self) -> Result<(), Error>; fn is_redb(&self) -> bool; fn delete_if( diff --git a/beacon_node/store/src/memory_store.rs b/beacon_node/store/src/memory_store.rs index b71dd6ea325..98ce2892a1f 100644 --- a/beacon_node/store/src/memory_store.rs +++ b/beacon_node/store/src/memory_store.rs @@ -147,7 +147,9 @@ impl KeyValueStore for MemoryStore { Ok(()) } - fn upgrade(&self) {} + fn upgrade(&self) -> Result<(), Error> { + Ok(()) + } fn is_redb(&self) -> bool { false From 8beedc3501f74e06d1ef2f7bcfe8f87d4dd6404c Mon Sep 17 00:00:00 2001 From: Owanikin Date: Tue, 9 Sep 2025 14:48:38 +0100 Subject: [PATCH 11/20] upgrade-redb-v3 cleanup --- .../src/schema_change/migration_schema_v29.rs | 6 ------ beacon_node/store/src/database/interface.rs | 6 ++---- beacon_node/store/src/errors.rs | 1 + beacon_node/store/src/hot_cold_store.rs | 11 ----------- lighthouse/Cargo.toml | 2 +- 5 files changed, 4 insertions(+), 22 deletions(-) diff --git a/beacon_node/beacon_chain/src/schema_change/migration_schema_v29.rs b/beacon_node/beacon_chain/src/schema_change/migration_schema_v29.rs index 0148e862c2d..6a8c6d78b53 100644 --- a/beacon_node/beacon_chain/src/schema_change/migration_schema_v29.rs +++ b/beacon_node/beacon_chain/src/schema_change/migration_schema_v29.rs @@ -1,16 +1,10 @@ use crate::BeaconChainTypes; use std::sync::Arc; use store::{Error, HotColdDB, KeyValueStoreOp}; -use tracing::info; pub fn upgrade_to_v29( db: Arc>, ) -> Result, Error> { - if db.is_redb() { - info!("Running Redb v29 migration"); - } else { - info!("Running non-Redb v29 migration"); - } db.upgrade()?; Ok(vec![]) } diff --git a/beacon_node/store/src/database/interface.rs b/beacon_node/store/src/database/interface.rs index b92a411af3e..1cc940b4076 100644 --- a/beacon_node/store/src/database/interface.rs +++ b/beacon_node/store/src/database/interface.rs @@ -170,18 +170,16 @@ impl KeyValueStore for BeaconNodeBackend { } } - // TODO(migration-v29) in the redb case, lets raise an info log - // TODO(migration-v29) the level_db case should be a no-op fn upgrade(&self) -> Result<(), Error> { match self { #[cfg(feature = "leveldb")] BeaconNodeBackend::LevelDb(_) => { - info!("LevelDB upgrade: no migration needed"); + info!("LevelDB, no upgrade required"); Ok(()) } #[cfg(feature = "redb")] BeaconNodeBackend::Redb(redb) => { - info!("Running Redb v29 migration"); + info!("Updating Redb file format to v3"); redb.upgrade()?; Ok(()) } diff --git a/beacon_node/store/src/errors.rs b/beacon_node/store/src/errors.rs index c1d230edcc4..ed768f72b65 100644 --- a/beacon_node/store/src/errors.rs +++ b/beacon_node/store/src/errors.rs @@ -66,6 +66,7 @@ pub enum Error { LevelDbError(LevelDBError), #[cfg(feature = "redb")] RedbError(Box), + #[cfg(feature = "redb")] RedbUpgrade(redb::UpgradeError), CacheBuildError(EpochCacheError), RandaoMixOutOfBounds, diff --git a/beacon_node/store/src/hot_cold_store.rs b/beacon_node/store/src/hot_cold_store.rs index f69f555c910..c1ee9a7c588 100644 --- a/beacon_node/store/src/hot_cold_store.rs +++ b/beacon_node/store/src/hot_cold_store.rs @@ -1,5 +1,3 @@ -#[cfg(feature = "redb")] -use crate::config::DatabaseBackend; use crate::config::{OnDiskStoreConfig, StoreConfig}; use crate::database::interface::BeaconNodeBackend; use crate::forwards_iter::{HybridForwardsBlockRootsIterator, HybridForwardsStateRootsIterator}; @@ -84,8 +82,6 @@ pub struct HotColdDB, Cold: ItemStore> { historic_state_cache: Mutex>, /// Chain spec. pub spec: Arc, - /// Database backend type - pub database_backend: Option, /// Mere vessel for E. _phantom: PhantomData, } @@ -246,7 +242,6 @@ impl HotColdDB, MemoryStore> { config, hierarchy, spec, - database_backend: None, _phantom: PhantomData, }; @@ -270,11 +265,6 @@ impl HotColdDB, BeaconNodeBackend> { debug!("Opening HotColdDB"); config.verify::()?; - #[cfg(feature = "redb")] - let _database_backend = DatabaseBackend::Redb; - #[cfg(feature = "leveldb")] - let database_backend = DatabaseBackend::LevelDb; - let hierarchy = config.hierarchy_config.to_moduli()?; debug!(?hot_path, "Opening LevelDB"); @@ -304,7 +294,6 @@ impl HotColdDB, BeaconNodeBackend> { config, hierarchy, spec, - database_backend: Some(database_backend), _phantom: PhantomData, }; // Load the config from disk but don't error on a failed read because the config itself may diff --git a/lighthouse/Cargo.toml b/lighthouse/Cargo.toml index 6d1f5d833fd..849d30bcf2d 100644 --- a/lighthouse/Cargo.toml +++ b/lighthouse/Cargo.toml @@ -12,7 +12,7 @@ rust-version = "1.88.0" normal = ["target_check"] [features] -default = ["slasher-lmdb", "beacon-node-redb"] +default = ["slasher-lmdb", "beacon-node-leveldb"] # Writes debugging .ssz files to /tmp during block processing. write_ssz_files = ["beacon_node/write_ssz_files"] # Compiles the BLS crypto code so that the binary is portable across machines. From 04c4641e4b78793b73a8d6132fcccaea534187aa Mon Sep 17 00:00:00 2001 From: Owanikin Date: Tue, 9 Sep 2025 22:51:00 +0100 Subject: [PATCH 12/20] fix ci issues --- beacon_node/beacon_chain/Cargo.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/beacon_node/beacon_chain/Cargo.toml b/beacon_node/beacon_chain/Cargo.toml index 6c907e4cff6..e772470de1d 100644 --- a/beacon_node/beacon_chain/Cargo.toml +++ b/beacon_node/beacon_chain/Cargo.toml @@ -46,7 +46,7 @@ parking_lot = { workspace = true } proto_array = { workspace = true } rand = { workspace = true } rayon = { workspace = true } -redb ={ version = "2.6.2", optional = true } +redb = { version = "2.6.2", optional = true } safe_arith = { workspace = true } sensitive_url = { workspace = true } serde = { workspace = true } From f268bace1c42e24fb0c7b06168f1c2b96c82324f Mon Sep 17 00:00:00 2001 From: Owanikin Date: Wed, 19 Nov 2025 13:24:19 +0100 Subject: [PATCH 13/20] fix: markdown lint table format (advanced_database) --- book/src/advanced_database.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/book/src/advanced_database.md b/book/src/advanced_database.md index 4e77046c2dd..aeb90d09f49 100644 --- a/book/src/advanced_database.md +++ b/book/src/advanced_database.md @@ -64,7 +64,7 @@ that we have observed are: The following table lists the data for different configurations. Note that the disk space requirement is for the `chain_db` and `freezer_db`, excluding the `blobs_db`. | Hierarchy Exponents | Storage Requirement | Sequential Slot Query | Uncached Query | Time to Sync | -|---|---|---|---|---| +| --- | --- | --- | --- | --- | | 5,9,11,13,16,18,21 (default) | 418 GiB | 250-700 ms | up to 10 s | 1 week | | 5,7,11 (frequent snapshots) | 589 GiB | 250-700 ms | up to 6 s | 1 week | | 0,5,7,11 (per-slot diffs) | 2500 GiB | 250-700 ms | up to 4 s | 7 weeks | From 63b75151a34dfdeec352ddd278141e6c1c2deab5 Mon Sep 17 00:00:00 2001 From: Owanikin Date: Wed, 19 Nov 2025 13:32:56 +0100 Subject: [PATCH 14/20] fix: markdown lint table format (api_vc_endpoints) --- book/src/api_vc_endpoints.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/book/src/api_vc_endpoints.md b/book/src/api_vc_endpoints.md index 14f4933e171..d128b13b2f8 100644 --- a/book/src/api_vc_endpoints.md +++ b/book/src/api_vc_endpoints.md @@ -132,7 +132,7 @@ Returns information regarding the health of the host machine. | Property | Specification | |-------------------|--------------------------------------------| -| Path | `/lighthouse/ui/health` | +| Path | `/lighthouse/ui/health` | | Method | GET | | Required Headers | [`Authorization`](./api_vc_auth_header.md) | | Typical Responses | 200 | @@ -178,7 +178,7 @@ Returns the graffiti that will be used for the next block proposal of each valid | Property | Specification | |-------------------|--------------------------------------------| -| Path | `/lighthouse/ui/graffiti` | +| Path | `/lighthouse/ui/graffiti` | | Method | GET | | Required Headers | [`Authorization`](./api_vc_auth_header.md) | | Typical Responses | 200 | From 20622433d533029a65b53cbaed68cf0110410df7 Mon Sep 17 00:00:00 2001 From: Owanikin Date: Wed, 19 Nov 2025 13:39:18 +0100 Subject: [PATCH 15/20] fix: markdown lint table format (archived_merge_migration) --- book/src/archived_merge_migration.md | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/book/src/archived_merge_migration.md b/book/src/archived_merge_migration.md index ac9c78c5e3b..42526a8c0d9 100644 --- a/book/src/archived_merge_migration.md +++ b/book/src/archived_merge_migration.md @@ -25,14 +25,14 @@ All networks (**Mainnet**, **Goerli (Prater)**, **Ropsten**, **Sepolia**, **Kiln
-| Network | Bellatrix | The Merge | Remark | -|---------|-------------------------------|-------------------------------| -----------| -| Ropsten | 2nd June 2022 | 8th June 2022 | Deprecated | -| Sepolia | 20th June 2022 | 6th July 2022 | | -| Goerli | 4th August 2022 | 10th August 2022 | Previously named `Prater`| -| Mainnet | 6th September 2022| 15th September 2022| | -| Chiado | 10th October 2022 | 4th November 2022 | | -| Gnosis | 30th November 2022| 8th December 2022 | | +| Network | Bellatrix | The Merge | Remark | +| ------- | ----------------------------- | ----------------------------- | --------------------------- | +| Ropsten | 2nd June 2022 | 8th June 2022 | Deprecated | +| Sepolia | 20th June 2022 | 6th July 2022 | | +| Goerli | 4th August 2022 | 10th August 2022 | Previously named `Prater` | +| Mainnet | 6th September 2022 | 15th September 2022 | | +| Chiado | 10th October 2022 | 4th November 2022 | | +| Gnosis | 30th November 2022 | 8th December 2022 | |
From 86a76187d19b4adc7dabe1aa96818d77ff3b899f Mon Sep 17 00:00:00 2001 From: Owanikin Date: Wed, 19 Nov 2025 13:47:30 +0100 Subject: [PATCH 16/20] fix: markdownlint table formatting --- book/src/validator_voluntary_exit.md | 19 ++++++++++++++++++- 1 file changed, 18 insertions(+), 1 deletion(-) diff --git a/book/src/validator_voluntary_exit.md b/book/src/validator_voluntary_exit.md index 3b660efe702..5b8afeb99b7 100644 --- a/book/src/validator_voluntary_exit.md +++ b/book/src/validator_voluntary_exit.md @@ -120,7 +120,24 @@ There are two types of withdrawal credentials, `0x00` and `0x01`. To check which - A fixed waiting period of 256 epochs (27.3 hours) for the validator's status to become withdrawable. -- A varying time of "validator sweep" that take a few days. The "validator sweep" is the process of skimming through all eligible validators by index number for withdrawals (those with type `0x01` and balance above 32ETH). Once the "validator sweep" reaches your validator's index, your staked fund will be fully withdrawn to the withdrawal address set. +- A varying time of "validator sweep" that can take up to _n_ days with _n_ listed in the table below. The "validator sweep" is the process of skimming through all eligible validators by index number for withdrawals (those with type `0x01` and balance above 32ETH). Once the "validator sweep" reaches your validator's index, your staked fund will be fully withdrawn to the withdrawal address set. + +
+ +| Number of eligible validators | Ideal scenario _n_ | Practical scenario _n_ | +| :---------------------------: | :-----------------: | :---------------------: | +| 300000 | 2.60 | 2.63 | +| 400000 | 3.47 | 3.51 | +| 500000 | 4.34 | 4.38 | +| 600000 | 5.21 | 5.26 | +| 700000 | 6.08 | 6.14 | +| 800000 | 6.94 | 7.01 | +| 900000 | 7.81 | 7.89 | +| 1000000 | 8.68 | 8.77 | + +
+ +> Note: Ideal scenario assumes no block proposals are missed. This means a total of withdrawals of 7200 blocks/day × 16 withdrawals/block = 115200 withdrawals/day. Practical scenario assumes 1% of blocks are missed per day. As an example, if there are 700000 eligible validators, one would expect a waiting time of slightly more than 6 days. The total time taken is the summation of the above 3 waiting periods. After these waiting periods, you will receive the staked funds in your withdrawal address. From 8a3eab90c20bdfab9933ae46910c680f645ded81 Mon Sep 17 00:00:00 2001 From: Eitan Seri-Levi Date: Wed, 3 Dec 2025 11:47:56 -0300 Subject: [PATCH 17/20] Revert --- book/src/validator_voluntary_exit.md | 17 +---------------- 1 file changed, 1 insertion(+), 16 deletions(-) diff --git a/book/src/validator_voluntary_exit.md b/book/src/validator_voluntary_exit.md index 5b8afeb99b7..66a1dc4cca8 100644 --- a/book/src/validator_voluntary_exit.md +++ b/book/src/validator_voluntary_exit.md @@ -120,22 +120,7 @@ There are two types of withdrawal credentials, `0x00` and `0x01`. To check which - A fixed waiting period of 256 epochs (27.3 hours) for the validator's status to become withdrawable. -- A varying time of "validator sweep" that can take up to _n_ days with _n_ listed in the table below. The "validator sweep" is the process of skimming through all eligible validators by index number for withdrawals (those with type `0x01` and balance above 32ETH). Once the "validator sweep" reaches your validator's index, your staked fund will be fully withdrawn to the withdrawal address set. - -
- -| Number of eligible validators | Ideal scenario _n_ | Practical scenario _n_ | -| :---------------------------: | :-----------------: | :---------------------: | -| 300000 | 2.60 | 2.63 | -| 400000 | 3.47 | 3.51 | -| 500000 | 4.34 | 4.38 | -| 600000 | 5.21 | 5.26 | -| 700000 | 6.08 | 6.14 | -| 800000 | 6.94 | 7.01 | -| 900000 | 7.81 | 7.89 | -| 1000000 | 8.68 | 8.77 | - -
+- A varying time of "validator sweep" that take a few days. The "validator sweep" is the process of skimming through all eligible validators by index number for withdrawals (those with type `0x01` and balance above 32ETH). Once the "validator sweep" reaches your validator's index, your staked fund will be fully withdrawn to the withdrawal address set. > Note: Ideal scenario assumes no block proposals are missed. This means a total of withdrawals of 7200 blocks/day × 16 withdrawals/block = 115200 withdrawals/day. Practical scenario assumes 1% of blocks are missed per day. As an example, if there are 700000 eligible validators, one would expect a waiting time of slightly more than 6 days. From fa2cbe434615643e3fc7843fd63a2a397340b750 Mon Sep 17 00:00:00 2001 From: Eitan Seri-Levi Date: Wed, 3 Dec 2025 11:48:41 -0300 Subject: [PATCH 18/20] Revert --- book/src/validator_voluntary_exit.md | 2 -- 1 file changed, 2 deletions(-) diff --git a/book/src/validator_voluntary_exit.md b/book/src/validator_voluntary_exit.md index 66a1dc4cca8..3b660efe702 100644 --- a/book/src/validator_voluntary_exit.md +++ b/book/src/validator_voluntary_exit.md @@ -122,8 +122,6 @@ There are two types of withdrawal credentials, `0x00` and `0x01`. To check which - A varying time of "validator sweep" that take a few days. The "validator sweep" is the process of skimming through all eligible validators by index number for withdrawals (those with type `0x01` and balance above 32ETH). Once the "validator sweep" reaches your validator's index, your staked fund will be fully withdrawn to the withdrawal address set. -> Note: Ideal scenario assumes no block proposals are missed. This means a total of withdrawals of 7200 blocks/day × 16 withdrawals/block = 115200 withdrawals/day. Practical scenario assumes 1% of blocks are missed per day. As an example, if there are 700000 eligible validators, one would expect a waiting time of slightly more than 6 days. - The total time taken is the summation of the above 3 waiting periods. After these waiting periods, you will receive the staked funds in your withdrawal address. The voluntary exit and full withdrawal process is summarized in the Figure below. From 5dab08169193a011dbd6ba95e10aa4325131d389 Mon Sep 17 00:00:00 2001 From: Eitan Seri-Levi Date: Wed, 3 Dec 2025 12:15:02 -0300 Subject: [PATCH 19/20] 2.6.3 --- beacon_node/store/Cargo.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/beacon_node/store/Cargo.toml b/beacon_node/store/Cargo.toml index 7136768aa8c..821534b9986 100644 --- a/beacon_node/store/Cargo.toml +++ b/beacon_node/store/Cargo.toml @@ -21,7 +21,7 @@ logging = { workspace = true } lru = { workspace = true } metrics = { workspace = true } parking_lot = { workspace = true } -redb = { version = "2.6.2", optional = true } +redb = { version = "2.6.3", optional = true } safe_arith = { workspace = true } serde = { workspace = true } smallvec = { workspace = true } From f3dee1b11236592e6ce5e1bfdd64343af09d32b2 Mon Sep 17 00:00:00 2001 From: Eitan Seri-Levi Date: Wed, 3 Dec 2025 12:15:17 -0300 Subject: [PATCH 20/20] 2.6.3 --- Cargo.lock | 1 - beacon_node/beacon_chain/Cargo.toml | 1 - 2 files changed, 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 6244ed4f617..7ddcad7239a 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1261,7 +1261,6 @@ dependencies = [ "proto_array", "rand 0.9.2", "rayon", - "redb", "safe_arith", "sensitive_url", "serde", diff --git a/beacon_node/beacon_chain/Cargo.toml b/beacon_node/beacon_chain/Cargo.toml index 3cfe038985a..e889f53bb01 100644 --- a/beacon_node/beacon_chain/Cargo.toml +++ b/beacon_node/beacon_chain/Cargo.toml @@ -46,7 +46,6 @@ parking_lot = { workspace = true } proto_array = { workspace = true } rand = { workspace = true } rayon = { workspace = true } -redb = { version = "2.6.2", optional = true } safe_arith = { workspace = true } sensitive_url = { workspace = true } serde = { workspace = true }