diff --git a/Cargo.lock b/Cargo.lock
index f0f64af94..4a8e6002b 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -22,6 +22,7 @@ dependencies = [
"rpassword 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)",
"rustc-serialize 0.3.18 (registry+https://github.com/rust-lang/crates.io-index)",
"rustc_version 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)",
+ "semver 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)",
"time 0.1.34 (registry+https://github.com/rust-lang/crates.io-index)",
]
diff --git a/Cargo.toml b/Cargo.toml
index 3fe923db7..2f0d0789c 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -29,7 +29,7 @@ ethminer = { path = "miner" }
ethcore-devtools = { path = "devtools" }
ethcore-rpc = { path = "rpc", optional = true }
ethcore-webapp = { path = "webapp", optional = true }
-
+semver = "0.2"
[dependencies.hyper]
version = "0.8"
diff --git a/parity/main.rs b/parity/main.rs
index 8ee9c6f63..b605a9dd4 100644
--- a/parity/main.rs
+++ b/parity/main.rs
@@ -36,6 +36,7 @@ extern crate daemonize;
extern crate time;
extern crate number_prefix;
extern crate rpassword;
+extern crate semver;
// for price_info.rs
#[macro_use] extern crate hyper;
@@ -71,6 +72,7 @@ use rpc::Server as RpcServer;
use webapp::Listening as WebappServer;
mod price_info;
+mod upgrade;
fn die_with_message(msg: &str) -> ! {
println!("ERROR: {}", msg);
diff --git a/parity/upgrade.rs b/parity/upgrade.rs
new file mode 100644
index 000000000..22ef4a571
--- /dev/null
+++ b/parity/upgrade.rs
@@ -0,0 +1,84 @@
+// Copyright 2015, 2016 Ethcore (UK) Ltd.
+// This file is part of Parity.
+
+// Parity is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+
+// Parity is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License
+// along with Parity. If not, see .
+
+//! Parity upgrade logic
+
+use semver::Version;
+use std::collections::*;
+use std::path::*;
+
+struct Error;
+
+const CURRENT_VERSION: &'static str = env!("CARGO_PKG_VERSION");
+
+#[derive(Hash, PartialEq, Eq)]
+struct UpgradeKey {
+ pub old_version: Version,
+ pub new_version: Version,
+}
+
+type UpgradeList = HashMap Result<(), Error>>;
+
+impl UpgradeKey {
+ // given the following config exist
+ // ver.lock 1.1 (`previous_version`)
+ //
+ // current_version 1.4 (`current_version`)
+ //
+ //
+ //upgrades (set of `UpgradeKey`)
+ // 1.0 -> 1.1 (u1)
+ // 1.1 -> 1.2 (u2)
+ // 1.2 -> 1.3 (u3)
+ // 1.3 -> 1.4 (u4)
+ // 1.4 -> 1.5 (u5)
+ //
+ // then the following upgrades should be applied:
+ // u2, u3, u4
+ fn is_applicable(&self, previous_version: &Version, current_version: &Version) -> bool {
+ self.old_version >= *previous_version && self.new_version <= *current_version
+ }
+}
+
+// dummy upgrade (remove when the first one is in)
+fn dummy_upgrade() -> Result<(), Error> {
+ Ok(())
+}
+
+fn push_updrades(upgrades: &mut UpgradeList)
+{
+ // dummy upgrade (remove when the first one is in)
+ upgrades.insert(
+ UpgradeKey { old_version: Version::parse("1.0.0").unwrap(), new_version: Version::parse("99.99.0").unwrap() },
+ dummy_upgrade);
+}
+
+fn upgrade_from_version(previous_version: &Version) -> Result {
+ let mut upgrades = HashMap::new();
+ push_updrades(&mut upgrades);
+
+ let current_version = Version::parse(CURRENT_VERSION).unwrap();
+
+ let mut count = 0;
+ for upgrade_key in upgrades.keys() {
+ if upgrade_key.is_applicable(previous_version, ¤t_version) {
+ let upgrade_script = upgrades[upgrade_key];
+ try!(upgrade_script());
+ count = count + 1;
+ }
+ }
+ Ok(count)
+}