diff --git a/.gitignore b/.gitignore
index 47546d0ed..e3bb529c4 100644
--- a/.gitignore
+++ b/.gitignore
@@ -32,3 +32,5 @@
out/
.vscode
+
+parity.*
diff --git a/updater/src/lib.rs b/updater/src/lib.rs
index bc1d2d2c3..08ed57717 100644
--- a/updater/src/lib.rs
+++ b/updater/src/lib.rs
@@ -24,5 +24,7 @@ extern crate ethabi;
mod updater;
mod operations;
+mod service;
-pub use updater::{Updater, UpdateFilter, UpdatePolicy, ReleaseInfo, OperationsInfo, CapState};
\ No newline at end of file
+pub use service::{Service, ReleaseInfo, OperationsInfo, CapState};
+pub use updater::{Updater, UpdateFilter, UpdatePolicy};
\ No newline at end of file
diff --git a/updater/src/service.rs b/updater/src/service.rs
new file mode 100644
index 000000000..2343a95f7
--- /dev/null
+++ b/updater/src/service.rs
@@ -0,0 +1,84 @@
+// Copyright 2015, 2016 Parity Technologies (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 .
+
+use util::{H256};
+use util::misc::{VersionInfo};
+
+/// Information regarding a particular release of Parity
+#[derive(Debug, Clone, PartialEq)]
+pub struct ReleaseInfo {
+ /// Information on the version.
+ pub version: VersionInfo,
+ /// Does this release contain critical security updates?
+ pub is_critical: bool,
+ /// The latest fork that this release can handle.
+ pub fork: u64,
+ /// Our platform's binary, if known.
+ pub binary: Option,
+}
+
+/// Information on our operations environment.
+#[derive(Debug, Clone, PartialEq)]
+pub struct OperationsInfo {
+ /// Our blockchain's latest fork.
+ pub fork: u64,
+
+ /// Last fork our client supports, if known.
+ pub this_fork: Option,
+
+ /// Information on our track's latest release.
+ pub track: ReleaseInfo,
+ /// Information on our minor version's latest release.
+ pub minor: Option,
+}
+
+/// Information on the current version's consensus capabililty.
+#[derive(Debug, Clone, Copy, PartialEq)]
+pub enum CapState {
+ /// Unknown.
+ Unknown,
+ /// Capable of consensus indefinitely.
+ Capable,
+ /// Capable of consensus up until a definite block.
+ CapableUntil(u64),
+ /// Incapable of consensus since a particular block.
+ IncapableSince(u64),
+}
+
+impl Default for CapState {
+ fn default() -> Self { CapState::Unknown }
+}
+
+pub trait Service: Send + Sync {
+ /// Is the currently running client capable of supporting the current chain?
+ /// We default to true if there's no clear information.
+ fn capability(&self) -> CapState;
+
+ /// The release which is ready to be upgraded to, if any. If this returns `Some`, then
+ /// `execute_upgrade` may be called.
+ fn upgrade_ready(&self) -> Option;
+
+ /// Actually upgrades the client. Assumes that the binary has been downloaded.
+ /// @returns `true` on success.
+ fn execute_upgrade(&self) -> bool;
+
+ /// Our version info.
+ fn version_info(&self) -> VersionInfo;
+
+ /// Information gathered concerning the release.
+ fn info(&self) -> Option;
+}
+
diff --git a/updater/src/updater.rs b/updater/src/updater.rs
index b400d5fc8..f0226f9e0 100644
--- a/updater/src/updater.rs
+++ b/updater/src/updater.rs
@@ -23,6 +23,7 @@ use util::{Address, H160, H256, FixedHash, Mutex, Bytes};
use ethcore::client::{BlockId, BlockChainClient, ChainNotify};
use hash_fetch::{self as fetch, HashFetch};
use operations::Operations;
+use service::{Service, ReleaseInfo, OperationsInfo, CapState};
/// Filter for releases.
#[derive(Debug, Eq, PartialEq, Clone)]
@@ -56,51 +57,6 @@ impl Default for UpdatePolicy {
}
}
-/// Information regarding a particular release of Parity
-#[derive(Debug, Clone, PartialEq)]
-pub struct ReleaseInfo {
- /// Information on the version.
- pub version: VersionInfo,
- /// Does this release contain critical security updates?
- pub is_critical: bool,
- /// The latest fork that this release can handle.
- pub fork: u64,
- /// Our platform's binary, if known.
- pub binary: Option,
-}
-
-/// Information on our operations environment.
-#[derive(Debug, Clone, PartialEq)]
-pub struct OperationsInfo {
- /// Our blockchain's latest fork.
- pub fork: u64,
-
- /// Last fork our client supports, if known.
- pub this_fork: Option,
-
- /// Information on our track's latest release.
- pub track: ReleaseInfo,
- /// Information on our minor version's latest release.
- pub minor: Option,
-}
-
-/// Information on the current version's consensus capabililty.
-#[derive(Debug, Clone, Copy, PartialEq)]
-pub enum CapState {
- /// Unknown.
- Unknown,
- /// Capable of consensus indefinitely.
- Capable,
- /// Capable of consensus up until a definite block.
- CapableUntil(u64),
- /// Incapable of consensus since a particular block.
- IncapableSince(u64),
-}
-
-impl Default for CapState {
- fn default() -> Self { CapState::Unknown }
-}
-
#[derive(Debug, Default)]
struct UpdaterState {
latest: Option,
@@ -157,60 +113,10 @@ impl Updater {
let r = Arc::new(u);
*r.fetcher.lock() = Some(fetch::Client::new(r.clone()));
*r.weak_self.lock() = Arc::downgrade(&r);
-
r.poll();
-
r
}
- /// Is the currently running client capable of supporting the current chain?
- /// We default to true if there's no clear information.
- pub fn capability(&self) -> CapState {
- self.state.lock().capability
- }
-
- /// The release which is ready to be upgraded to, if any. If this returns `Some`, then
- /// `execute_upgrade` may be called.
- pub fn upgrade_ready(&self) -> Option {
- self.state.lock().ready.clone()
- }
-
- /// Actually upgrades the client. Assumes that the binary has been downloaded.
- /// @returns `true` on success.
- pub fn execute_upgrade(&self) -> bool {
- (|| -> Result {
- let mut s = self.state.lock();
- if let Some(r) = s.ready.take() {
- let p = Self::update_file_name(&r.version);
- let n = Self::updates_path("latest");
- // TODO: creating then writing is a bit fragile. would be nice to make it atomic.
- match fs::File::create(&n).and_then(|mut f| f.write_all(p.as_bytes())) {
- Ok(_) => {
- info!("Completed upgrade to {}", &r.version);
- s.installed = Some(r);
- if let Some(ref h) = *self.exit_handler.lock() {
- (*h)();
- }
- Ok(true)
- }
- Err(e) => {
- s.ready = Some(r);
- Err(format!("Unable to create soft-link for update {:?}", e))
- }
- }
- } else {
- warn!("Execute upgrade called when no upgrade ready.");
- Ok(false)
- }
- })().unwrap_or_else(|e| { warn!("{}", e); false })
- }
-
- /// Our version info.
- pub fn version_info(&self) -> &VersionInfo { &self.this }
-
- /// Information gathered concerning the release.
- pub fn info(&self) -> Option { self.state.lock().latest.clone() }
-
/// Set a closure to call when we want to restart the client
pub fn set_exit_handler(&self, f: F) where F: Fn() + 'static + Send {
*self.exit_handler.lock() = Some(Box::new(f));
@@ -391,3 +297,45 @@ impl fetch::urlhint::ContractClient for Updater {
.call_contract(address, data)
}
}
+
+impl Service for Updater {
+ fn capability(&self) -> CapState {
+ self.state.lock().capability
+ }
+
+ fn upgrade_ready(&self) -> Option {
+ self.state.lock().ready.clone()
+ }
+
+ fn execute_upgrade(&self) -> bool {
+ (|| -> Result {
+ let mut s = self.state.lock();
+ if let Some(r) = s.ready.take() {
+ let p = Self::update_file_name(&r.version);
+ let n = Self::updates_path("latest");
+ // TODO: creating then writing is a bit fragile. would be nice to make it atomic.
+ match fs::File::create(&n).and_then(|mut f| f.write_all(p.as_bytes())) {
+ Ok(_) => {
+ info!("Completed upgrade to {}", &r.version);
+ s.installed = Some(r);
+ if let Some(ref h) = *self.exit_handler.lock() {
+ (*h)();
+ }
+ Ok(true)
+ }
+ Err(e) => {
+ s.ready = Some(r);
+ Err(format!("Unable to create soft-link for update {:?}", e))
+ }
+ }
+ } else {
+ warn!("Execute upgrade called when no upgrade ready.");
+ Ok(false)
+ }
+ })().unwrap_or_else(|e| { warn!("{}", e); false })
+ }
+
+ fn version_info(&self) -> VersionInfo { self.this.clone() }
+
+ fn info(&self) -> Option { self.state.lock().latest.clone() }
+}
\ No newline at end of file