Die if the DB is newer than the one supported. (#1630)

* die on DB from the future

* use error type to print messages, print db path
This commit is contained in:
keorn 2016-07-16 10:41:09 +02:00 committed by Gav Wood
parent d14b6871a5
commit 78007cf80b
2 changed files with 17 additions and 9 deletions

View File

@ -180,7 +180,7 @@ fn execute_upgrades(conf: &Configuration, spec: &Spec, client_config: &ClientCon
let db_path = get_db_path(Path::new(&conf.path()), client_config.pruning, spec.genesis_header().hash()); let db_path = get_db_path(Path::new(&conf.path()), client_config.pruning, spec.genesis_header().hash());
let result = migrate(&db_path, client_config.pruning); let result = migrate(&db_path, client_config.pruning);
if let Err(err) = result { if let Err(err) = result {
die_with_message(&format!("{}", err)); die_with_message(&format!("{} DB path: {}", err, db_path.to_string_lossy()));
} }
} }

View File

@ -37,11 +37,15 @@ const VERSION_FILE_NAME: &'static str = "db_version";
pub enum Error { pub enum Error {
/// Returned when current version cannot be read or guessed. /// Returned when current version cannot be read or guessed.
UnknownDatabaseVersion, UnknownDatabaseVersion,
/// Returned when migration is not possible. /// Migration does not support existing pruning algorithm.
UnsuportedPruningMethod,
/// Existing DB is newer than the known one.
FutureDBVersion,
/// Migration is not possible.
MigrationImpossible, MigrationImpossible,
/// Returned when migration unexpectadly failed. /// Migration unexpectadly failed.
MigrationFailed, MigrationFailed,
/// Returned when migration was completed succesfully, /// Migration was completed succesfully,
/// but there was a problem with io. /// but there was a problem with io.
Io(IoError), Io(IoError),
} }
@ -50,9 +54,11 @@ impl Display for Error {
fn fmt(&self, f: &mut Formatter) -> Result<(), FmtError> { fn fmt(&self, f: &mut Formatter) -> Result<(), FmtError> {
let out = match *self { let out = match *self {
Error::UnknownDatabaseVersion => "Current database version cannot be read".into(), Error::UnknownDatabaseVersion => "Current database version cannot be read".into(),
Error::MigrationImpossible => format!("Migration to version {} is not possible", CURRENT_VERSION), Error::UnsuportedPruningMethod => "Unsupported pruning method for database migration. Delete DB and resync.".into(),
Error::MigrationFailed => "Migration unexpectedly failed".into(), Error::FutureDBVersion => "Database was created with newer client version. Upgrade your client or delete DB and resync.".into(),
Error::Io(ref err) => format!("Unexpected io error: {}", err), Error::MigrationImpossible => format!("Database migration to version {} is not possible.", CURRENT_VERSION),
Error::MigrationFailed => "Database migration unexpectedly failed".into(),
Error::Io(ref err) => format!("Unexpected io error on DB migration: {}.", err),
}; };
write!(f, "{}", out) write!(f, "{}", out)
@ -159,7 +165,7 @@ fn state_database_migrations(pruning: Algorithm) -> Result<MigrationManager, Err
let res = match pruning { let res = match pruning {
Algorithm::Archive => manager.add_migration(migrations::state::ArchiveV7::default()), Algorithm::Archive => manager.add_migration(migrations::state::ArchiveV7::default()),
Algorithm::OverlayRecent => manager.add_migration(migrations::state::OverlayRecentV7::default()), Algorithm::OverlayRecent => manager.add_migration(migrations::state::OverlayRecentV7::default()),
_ => die!("Unsupported pruning method for migration. Delete DB and resync"), _ => return Err(Error::UnsuportedPruningMethod),
}; };
try!(res.map_err(|_| Error::MigrationImpossible)); try!(res.map_err(|_| Error::MigrationImpossible));
@ -207,12 +213,14 @@ pub fn migrate(path: &Path, pruning: Algorithm) -> Result<(), Error> {
// migrate the databases. // migrate the databases.
// main db directory may already exists, so let's check if we have blocks dir // main db directory may already exists, so let's check if we have blocks dir
if version != CURRENT_VERSION && exists(&blocks_database_path(path)) { if version < CURRENT_VERSION && exists(&blocks_database_path(path)) {
println!("Migrating database from version {} to {}", version, CURRENT_VERSION); println!("Migrating database from version {} to {}", version, CURRENT_VERSION);
try!(migrate_database(version, blocks_database_path(path), try!(blocks_database_migrations()))); try!(migrate_database(version, blocks_database_path(path), try!(blocks_database_migrations())));
try!(migrate_database(version, extras_database_path(path), try!(extras_database_migrations()))); try!(migrate_database(version, extras_database_path(path), try!(extras_database_migrations())));
try!(migrate_database(version, state_database_path(path), try!(state_database_migrations(pruning)))); try!(migrate_database(version, state_database_path(path), try!(state_database_migrations(pruning))));
println!("Migration finished"); println!("Migration finished");
} else if version > CURRENT_VERSION {
return Err(Error::FutureDBVersion);
} }
// update version file. // update version file.