Improve capability information and disable old clients.

This commit is contained in:
Gav Wood
2016-12-11 16:52:41 +01:00
parent 74a6203f72
commit 22cb5753d0
6 changed files with 83 additions and 18 deletions

View File

@@ -282,7 +282,6 @@ impl Configuration {
no_periodic_snapshot: self.args.flag_no_periodic_snapshot,
check_seal: !self.args.flag_no_seal_check,
download_old_blocks: !self.args.flag_no_ancient_blocks,
require_consensus: !self.args.flag_no_consensus,
serve_light: self.args.flag_serve_light,
verifier_settings: verifier_settings,
};
@@ -628,6 +627,7 @@ impl Configuration {
fn update_policy(&self) -> Result<UpdatePolicy, String> {
Ok(UpdatePolicy {
enable_downloading: !self.args.flag_no_download,
require_consensus: !self.args.flag_no_consensus,
filter: match self.args.flag_auto_update.as_ref() {
"none" => UpdateFilter::None,
"critical" => UpdateFilter::Critical,
@@ -943,7 +943,7 @@ mod tests {
acc_conf: Default::default(),
gas_pricer: Default::default(),
miner_extras: Default::default(),
update_policy: UpdatePolicy { enable_downloading: true, filter: UpdateFilter::Critical },
update_policy: UpdatePolicy { enable_downloading: true, require_consensus: true, filter: UpdateFilter::Critical },
mode: Default::default(),
tracing: Default::default(),
compaction: Default::default(),
@@ -961,7 +961,6 @@ mod tests {
no_periodic_snapshot: false,
check_seal: true,
download_old_blocks: true,
require_consensus: true,
serve_light: false,
verifier_settings: Default::default(),
}));
@@ -992,14 +991,14 @@ mod tests {
fn should_parse_updater_options() {
// when
let conf0 = parse(&["parity"]);
let conf1 = parse(&["parity", "--auto-update", "all"]);
let conf1 = parse(&["parity", "--auto-update", "all", "--no-consensus"]);
let conf2 = parse(&["parity", "--no-download", "--auto-update=all"]);
let conf3 = parse(&["parity", "--auto-update=xxx"]);
// then
assert_eq!(conf0.update_policy().unwrap(), UpdatePolicy{enable_downloading: true, filter: UpdateFilter::Critical});
assert_eq!(conf1.update_policy().unwrap(), UpdatePolicy{enable_downloading: true, filter: UpdateFilter::All});
assert_eq!(conf2.update_policy().unwrap(), UpdatePolicy{enable_downloading: false, filter: UpdateFilter::All});
assert_eq!(conf0.update_policy().unwrap(), UpdatePolicy{enable_downloading: true, require_consensus: true, filter: UpdateFilter::Critical});
assert_eq!(conf1.update_policy().unwrap(), UpdatePolicy{enable_downloading: true, require_consensus: false, filter: UpdateFilter::All});
assert_eq!(conf2.update_policy().unwrap(), UpdatePolicy{enable_downloading: false, require_consensus: true, filter: UpdateFilter::All});
assert!(conf3.update_policy().is_err());
}

View File

@@ -94,7 +94,6 @@ pub struct RunCmd {
pub no_periodic_snapshot: bool,
pub check_seal: bool,
pub download_old_blocks: bool,
pub require_consensus: bool,
pub serve_light: bool,
pub verifier_settings: VerifierSettings,
}

View File

@@ -40,6 +40,8 @@ pub enum UpdateFilter {
pub struct UpdatePolicy {
/// Download potential updates.
pub enable_downloading: bool,
/// Disable client if we know we're incapable of syncing.
pub require_consensus: bool,
/// Which of those downloaded should be automatically installed.
pub filter: UpdateFilter,
}
@@ -48,6 +50,7 @@ impl Default for UpdatePolicy {
fn default() -> Self {
UpdatePolicy {
enable_downloading: false,
require_consensus: true,
filter: UpdateFilter::None,
}
}
@@ -81,6 +84,23 @@ pub struct OperationsInfo {
pub minor: Option<ReleaseInfo>,
}
/// 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<OperationsInfo>,
@@ -88,6 +108,8 @@ struct UpdaterState {
fetching: Option<ReleaseInfo>,
ready: Option<ReleaseInfo>,
installed: Option<ReleaseInfo>,
capability: CapState,
}
/// Service for checking for updates and determining whether we can achieve consensus.
@@ -135,18 +157,16 @@ 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?
/// `Some` answer or `None` if information on the running client is not available.
pub fn is_capable(&self) -> Option<bool> {
self.state.lock().latest.as_ref().and_then(|latest| {
latest.this_fork.map(|this_fork| {
let current_number = self.client.upgrade().map_or(0, |c| c.block_number(BlockId::Latest).unwrap_or(0));
this_fork >= latest.fork || current_number < latest.fork
})
})
/// 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
@@ -294,6 +314,7 @@ impl Updater {
let current_number = self.client.upgrade().map_or(0, |c| c.block_number(BlockId::Latest).unwrap_or(0));
let mut capability = CapState::Unknown;
let latest = self.collect_latest().ok();
if let Some(ref latest) = latest {
info!(target: "updater", "Latest release in our track is v{} it is {}critical ({} binary is {})",
@@ -321,8 +342,31 @@ impl Updater {
}
}
info!(target: "updater", "Fork: this/current/latest/latest-known: {}/#{}/#{}/#{}", match latest.this_fork { Some(f) => format!("#{}", f), None => "unknown".into(), }, current_number, latest.track.fork, latest.fork);
if let Some(this_fork) = latest.this_fork {
if this_fork < latest.fork {
// We're behind the latest fork. Now is the time to be upgrading; perhaps we're too late...
if let Some(c) = self.client.upgrade() {
let current_number = c.block_number(BlockId::Latest).unwrap_or(0);
if current_number >= latest.fork - 1 {
// We're at (or past) the last block we can import. Disable the client.
if self.update_policy.require_consensus {
c.disable();
}
capability = CapState::IncapableSince(latest.fork);
} else {
capability = CapState::CapableUntil(latest.fork);
}
}
} else {
capability = CapState::Capable;
}
}
}
(*self.state.lock()).latest = latest;
let mut s = self.state.lock();
s.latest = latest;
s.capability = capability;
}
}