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

@ -18,6 +18,7 @@
use util::{U256, H256}; use util::{U256, H256};
use header::BlockNumber; use header::BlockNumber;
use types::security_level::SecurityLevel;
/// Information about the blockchain gathered together. /// Information about the blockchain gathered together.
#[derive(Clone, Debug, Binary)] #[derive(Clone, Debug, Binary)]
@ -41,3 +42,15 @@ pub struct BlockChainInfo {
/// Number of the first block on the best sequence. /// Number of the first block on the best sequence.
pub first_block_number: Option<BlockNumber>, 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. //! Indication of how secure the chain is.
use header::BlockNumber;
/// Indication of how secure the chain is. /// Indication of how secure the chain is.
#[derive(Debug, PartialEq, Copy, Clone, Hash, Eq, Binary)] #[derive(Debug, PartialEq, Copy, Clone, Hash, Eq, Binary)]
pub enum SecurityLevel { pub enum SecurityLevel {
/// Chain was synced through manually evaluating all transactions from genesis. /// All blocks from genesis to chain head are known to have valid state transitions and PoW.
Full, FullState,
/// All blocks are known to have a valid PoW from genesis. /// All blocks from genesis to chain head are known to have a valid PoW.
Continuous, FullProofOfWork,
/// Some headers (the argument) are known to have a valid PoW from genesis. /// Some recent headers (the argument) are known to have a valid PoW.
Light(u64), 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) { fn poll(&self) {
info!(target: "updater", "Current release is {} ({:?})", self.this, self.this.hash); 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 self.operations.lock().is_none() {
if let Some(ops_addr) = self.client.upgrade().and_then(|c| c.registry_address("operations".into())) { if let Some(ops_addr) = self.client.upgrade().and_then(|c| c.registry_address("operations".into())) {
trace!(target: "updater", "Found operations at {}", ops_addr); trace!(target: "updater", "Found operations at {}", ops_addr);