Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
31 changes: 31 additions & 0 deletions slasher/src/database/interface.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
#[cfg(feature = "redb")]
use crate::database::CURRENT_SCHEMA_VERSION;
use crate::{Config, DatabaseBackend, Error};
use std::borrow::Cow;
use std::marker::PhantomData;
Expand Down Expand Up @@ -119,6 +121,35 @@ impl Environment {
_ => vec![],
}
}

/// Upgrade the database if necessary (only meaningful for Redb).
pub fn upgrade(&self) -> Result<(), Error> {
match self {
#[cfg(feature = "redb")]
Self::Redb(env) => {
tracing::info!(
"Starting SlasherDB Redb schema to version {}",
CURRENT_SCHEMA_VERSION
);
env.upgrade()?;
tracing::info!(
"Finished SlasherDB Redb schema upgrade to version {}",
CURRENT_SCHEMA_VERSION
);
Ok(())
}
_ => Ok(()),
}
}

/// Returns true if this database is using Redb as the backend
pub fn is_redb(&self) -> bool {
#[cfg(feature = "redb")]
{
matches!(self, Self::Redb(_))
}
false
}
}

impl<'env> RwTransaction<'env> {
Expand Down
6 changes: 6 additions & 0 deletions slasher/src/database/redb_impl.rs
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,12 @@ impl Environment {
_phantom: PhantomData,
})
}

/// Upgrade the underlying Redb environment if necessary
/// Currently a no-op because schema versioning is handled in `SlasherDB::migrate`
pub fn upgrade(&self) -> Result<(), Error> {
Ok(())
}
}

impl<'env> RwTransaction<'env> {
Expand Down
33 changes: 26 additions & 7 deletions slasher/src/migrate.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,21 +9,40 @@ impl<E: EthSpec> SlasherDB<E> {
drop(txn);

if let Some(schema_version) = schema_version {
match (schema_version, CURRENT_SCHEMA_VERSION) {
tracing::info!(
"Found SlasherDB on-disk schema version v{} (software target v{})",
schema_version,
CURRENT_SCHEMA_VERSION
);
return match (schema_version, CURRENT_SCHEMA_VERSION) {
// Schema v3 changed the underlying database from LMDB to MDBX. Unless the user did
// some manual hacking it should be impossible to read an MDBX schema version < 3.
(from, _) if from < 3 => Err(Error::IncompatibleSchemaVersion {
database_schema_version: schema_version,
software_schema_version: CURRENT_SCHEMA_VERSION,
}),
(x, y) if x == y => Ok(self),
(_, _) => Err(Error::IncompatibleSchemaVersion {
database_schema_version: schema_version,
software_schema_version: CURRENT_SCHEMA_VERSION,

(from, to) if from + 1 == to && self.env.is_redb() => {
self.env.upgrade()?;
let mut txn = self.begin_rw_txn()?;
self.store_schema_version(&mut txn)?;
txn.commit()?;
Ok(self)
}

(from, to) => Err(Error::IncompatibleSchemaVersion {
database_schema_version: from,
software_schema_version: to,
}),
}
} else {
Ok(self)
};
}

// Store the schema version for future runs
let mut txn = self.begin_rw_txn()?;
self.store_schema_version(&mut txn)?;
txn.commit()?;

Ok(self)
}
}