Ensure chain state is at threshold security level before looking for updates.

This commit is contained in:
Gav Wood 2016-12-13 21:21:07 +01:00
parent 805b8cab2c
commit 597c3a4770
No known key found for this signature in database
GPG Key ID: C49C1ACA1CC9B252
4 changed files with 37 additions and 7 deletions

View File

@ -1377,7 +1377,7 @@ impl BlockChainClient for Client {
self.registrar.lock().as_ref()
.and_then(|r| r.get_address(&(name.as_bytes().sha3()), "A").ok())
.and_then(|a| if a.is_zero() { None } else { Some(a) })
}
}
}
impl MiningBlockChainClient for Client {

View File

@ -18,6 +18,7 @@
use util::{U256, H256};
use header::BlockNumber;
use types::security_level::SecurityLevel;
/// Information about the blockchain gathered together.
#[derive(Clone, Debug, Binary)]
@ -41,3 +42,15 @@ pub struct BlockChainInfo {
/// Number of the first block on the best sequence.
pub first_block_number: Option<BlockNumber>,
}
impl BlockChainInfo {
/// Determine the security model for the current state.
pub fn security_level(&self) -> SecurityLevel {
// TODO: Detect SecurityLevel::FullState : https://github.com/ethcore/parity/issues/3834
if self.ancient_block_number.is_none() || self.first_block_number.is_none() {
SecurityLevel::FullProofOfWork
} else {
SecurityLevel::PartialProofOfWork(self.best_block_number - self.first_block_number.expect("Guard condition means this is not none"))
}
}
}

View File

@ -16,13 +16,25 @@
//! Indication of how secure the chain is.
use header::BlockNumber;
/// Indication of how secure the chain is.
#[derive(Debug, PartialEq, Copy, Clone, Hash, Eq, Binary)]
pub enum SecurityLevel {
/// Chain was synced through manually evaluating all transactions from genesis.
Full,
/// All blocks are known to have a valid PoW from genesis.
Continuous,
/// Some headers (the argument) are known to have a valid PoW from genesis.
Light(u64),
/// All blocks from genesis to chain head are known to have valid state transitions and PoW.
FullState,
/// All blocks from genesis to chain head are known to have a valid PoW.
FullProofOfWork,
/// Some recent headers (the argument) are known to have a valid PoW.
PartialProofOfWork(BlockNumber),
}
impl SecurityLevel {
/// `true` for `FullPoW`/`FullState`.
pub fn is_full(&self) -> bool {
match *self {
SecurityLevel::FullState | SecurityLevel::FullProofOfWork => true,
_ => false,
}
}
}

View File

@ -214,6 +214,11 @@ impl Updater {
fn poll(&self) {
info!(target: "updater", "Current release is {} ({:?})", self.this, self.this.hash);
// We rely on a secure state. Bail if we're unsure about it.
if self.client.upgrade().map_or(true, |s| !s.chain_info().security_level().is_full()) {
return;
}
if self.operations.lock().is_none() {
if let Some(ops_addr) = self.client.upgrade().and_then(|c| c.registry_address("operations".into())) {
trace!(target: "updater", "Found operations at {}", ops_addr);