Fix build.

This commit is contained in:
Gav Wood 2016-12-11 02:02:40 +01:00
parent fa30dfd4b9
commit 0302d582d2
No known key found for this signature in database
GPG Key ID: C49C1ACA1CC9B252
13 changed files with 115 additions and 107 deletions

1
Cargo.lock generated
View File

@ -8,6 +8,7 @@ dependencies = [
"daemonize 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", "daemonize 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
"docopt 0.6.80 (registry+https://github.com/rust-lang/crates.io-index)", "docopt 0.6.80 (registry+https://github.com/rust-lang/crates.io-index)",
"env_logger 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)", "env_logger 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)",
"ethabi 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
"ethcore 1.5.0", "ethcore 1.5.0",
"ethcore-dapps 1.5.0", "ethcore-dapps 1.5.0",
"ethcore-devtools 1.5.0", "ethcore-devtools 1.5.0",

View File

@ -48,6 +48,7 @@ ethcore-stratum = { path = "stratum" }
ethcore-dapps = { path = "dapps", optional = true } ethcore-dapps = { path = "dapps", optional = true }
clippy = { version = "0.0.103", optional = true} clippy = { version = "0.0.103", optional = true}
ethcore-light = { path = "ethcore/light" } ethcore-light = { path = "ethcore/light" }
ethabi = "0.2.2"
[target.'cfg(windows)'.dependencies] [target.'cfg(windows)'.dependencies]
winapi = "0.2" winapi = "0.2"

View File

@ -711,16 +711,6 @@ impl Client {
} }
} }
/// Look up the block number for the given block ID.
pub fn block_number(&self, id: BlockId) -> Option<BlockNumber> {
match id {
BlockId::Number(number) => Some(number),
BlockId::Hash(ref hash) => self.chain.read().block_number(hash),
BlockId::Earliest => Some(0),
BlockId::Latest | BlockId::Pending => Some(self.chain.read().best_block_number()),
}
}
/// Take a snapshot at the given block. /// Take a snapshot at the given block.
/// If the ID given is "latest", this will default to 1000 blocks behind. /// If the ID given is "latest", this will default to 1000 blocks behind.
pub fn take_snapshot<W: snapshot_io::SnapshotWriter + Send>(&self, writer: W, at: BlockId, p: &snapshot::Progress) -> Result<(), EthcoreError> { pub fn take_snapshot<W: snapshot_io::SnapshotWriter + Send>(&self, writer: W, at: BlockId, p: &snapshot::Progress) -> Result<(), EthcoreError> {
@ -946,6 +936,15 @@ impl BlockChainClient for Client {
Self::block_hash(&chain, id).and_then(|hash| chain.block_header_data(&hash)) Self::block_hash(&chain, id).and_then(|hash| chain.block_header_data(&hash))
} }
fn block_number(&self, id: BlockId) -> Option<BlockNumber> {
match id {
BlockId::Number(number) => Some(number),
BlockId::Hash(ref hash) => self.chain.read().block_number(hash),
BlockId::Earliest => Some(0),
BlockId::Latest | BlockId::Pending => Some(self.chain.read().best_block_number()),
}
}
fn block_body(&self, id: BlockId) -> Option<Bytes> { fn block_body(&self, id: BlockId) -> Option<Bytes> {
let chain = self.chain.read(); let chain = self.chain.read();
Self::block_hash(&chain, id).and_then(|hash| chain.block_body(&hash)) Self::block_hash(&chain, id).and_then(|hash| chain.block_body(&hash))

View File

@ -473,6 +473,10 @@ impl BlockChainClient for TestBlockChainClient {
self.block_hash(id).and_then(|hash| self.blocks.read().get(&hash).map(|r| Rlp::new(r).at(0).as_raw().to_vec())) self.block_hash(id).and_then(|hash| self.blocks.read().get(&hash).map(|r| Rlp::new(r).at(0).as_raw().to_vec()))
} }
fn block_number(&self, _id: BlockId) -> Option<BlockNumber> {
unimplemented!()
}
fn block_body(&self, id: BlockId) -> Option<Bytes> { fn block_body(&self, id: BlockId) -> Option<Bytes> {
self.block_hash(id).and_then(|hash| self.blocks.read().get(&hash).map(|r| { self.block_hash(id).and_then(|hash| self.blocks.read().get(&hash).map(|r| {
let mut stream = RlpStream::new_list(2); let mut stream = RlpStream::new_list(2);

View File

@ -52,6 +52,9 @@ pub trait BlockChainClient : Sync + Send {
/// Get raw block header data by block id. /// Get raw block header data by block id.
fn block_header(&self, id: BlockId) -> Option<Bytes>; fn block_header(&self, id: BlockId) -> Option<Bytes>;
/// Look up the block number for the given block ID.
fn block_number(&self, id: BlockId) -> Option<BlockNumber>;
/// Get raw block body data by block id. /// Get raw block body data by block id.
/// Block body is an RLP list of two items: uncles and transactions. /// Block body is an RLP list of two items: uncles and transactions.
fn block_body(&self, id: BlockId) -> Option<Bytes>; fn block_body(&self, id: BlockId) -> Option<Bytes>;

View File

@ -178,7 +178,6 @@ fn execute_import(cmd: ImportBlockchain) -> Result<String, String> {
// prepare client config // prepare client config
let mut client_config = to_client_config( let mut client_config = to_client_config(
&cmd.cache_config, &cmd.cache_config,
Default::default(),
Mode::Active, Mode::Active,
tracing, tracing,
fat_db, fat_db,
@ -345,7 +344,7 @@ fn start_client(
try!(execute_upgrades(&db_dirs, algorithm, compaction.compaction_profile(db_dirs.fork_path().as_path()))); try!(execute_upgrades(&db_dirs, algorithm, compaction.compaction_profile(db_dirs.fork_path().as_path())));
// prepare client config // prepare client config
let client_config = to_client_config(&cache_config, Default::default(), Mode::Active, tracing, fat_db, compaction, wal, VMType::default(), "".into(), algorithm, pruning_history, true); let client_config = to_client_config(&cache_config, Mode::Active, tracing, fat_db, compaction, wal, VMType::default(), "".into(), algorithm, pruning_history, true);
let service = try!(ClientService::start( let service = try!(ClientService::start(
client_config, client_config,

View File

@ -23,7 +23,7 @@ use cli::{Args, ArgsError};
use util::{Hashable, U256, Uint, Bytes, version_data, Secret, Address}; use util::{Hashable, U256, Uint, Bytes, version_data, Secret, Address};
use util::log::Colour; use util::log::Colour;
use ethsync::{NetworkConfiguration, is_valid_node_url, AllowIP}; use ethsync::{NetworkConfiguration, is_valid_node_url, AllowIP};
use ethcore::client::{VMType, UpdatePolicy, UpdateFilter}; use ethcore::client::{VMType};
use ethcore::miner::{MinerOptions, Banning}; use ethcore::miner::{MinerOptions, Banning};
use ethcore::verification::queue::VerifierSettings; use ethcore::verification::queue::VerifierSettings;
@ -37,6 +37,7 @@ use ethcore_logger::Config as LogConfig;
use dir::Directories; use dir::Directories;
use dapps::Configuration as DappsConfiguration; use dapps::Configuration as DappsConfiguration;
use signer::{Configuration as SignerConfiguration}; use signer::{Configuration as SignerConfiguration};
use updater::{UpdatePolicy, UpdateFilter};
use run::RunCmd; use run::RunCmd;
use blockchain::{BlockchainCmd, ImportBlockchain, ExportBlockchain, ExportState, DataFormat}; use blockchain::{BlockchainCmd, ImportBlockchain, ExportBlockchain, ExportState, DataFormat};
use presale::ImportWallet; use presale::ImportWallet;

View File

@ -20,7 +20,7 @@ use std::time::Duration;
use std::fs::File; use std::fs::File;
use util::{clean_0x, U256, Uint, Address, path, CompactionProfile}; use util::{clean_0x, U256, Uint, Address, path, CompactionProfile};
use util::journaldb::Algorithm; use util::journaldb::Algorithm;
use ethcore::client::{UpdatePolicy, Mode, BlockId, VMType, DatabaseCompactionProfile, ClientConfig, VerifierType}; use ethcore::client::{Mode, BlockId, VMType, DatabaseCompactionProfile, ClientConfig, VerifierType};
use ethcore::miner::{PendingSet, GasLimit, PrioritizationStrategy}; use ethcore::miner::{PendingSet, GasLimit, PrioritizationStrategy};
use cache::CacheConfig; use cache::CacheConfig;
use dir::DatabaseDirectories; use dir::DatabaseDirectories;

View File

@ -19,12 +19,14 @@ use self::ansi_term::Colour::{White, Yellow, Green, Cyan, Blue};
use self::ansi_term::Style; use self::ansi_term::Style;
use std::sync::{Arc}; use std::sync::{Arc};
use std::sync::atomic::{AtomicUsize, Ordering as AtomicOrdering}; use std::sync::atomic::{AtomicUsize, AtomicBool, Ordering as AtomicOrdering};
use std::time::{Instant, Duration}; use std::time::{Instant, Duration};
use io::{TimerToken, IoContext, IoHandler};
use isatty::{stdout_isatty}; use isatty::{stdout_isatty};
use ethsync::{SyncProvider, ManageNetwork}; use ethsync::{SyncProvider, ManageNetwork};
use util::{Uint, RwLock, Mutex, H256, Colour}; use util::{Uint, RwLock, Mutex, H256, Colour};
use ethcore::client::*; use ethcore::client::*;
use ethcore::service::ClientIoMessage;
use ethcore::views::BlockView; use ethcore::views::BlockView;
use ethcore::snapshot::service::Service as SnapshotService; use ethcore::snapshot::service::Service as SnapshotService;
use ethcore::snapshot::{RestorationStatus, SnapshotService as SS}; use ethcore::snapshot::{RestorationStatus, SnapshotService as SS};
@ -44,6 +46,7 @@ pub struct Informant {
last_import: Mutex<Instant>, last_import: Mutex<Instant>,
skipped: AtomicUsize, skipped: AtomicUsize,
skipped_txs: AtomicUsize, skipped_txs: AtomicUsize,
in_shutdown: AtomicBool,
} }
/// Format byte counts to standard denominations. /// Format byte counts to standard denominations.
@ -82,9 +85,14 @@ impl Informant {
last_import: Mutex::new(Instant::now()), last_import: Mutex::new(Instant::now()),
skipped: AtomicUsize::new(0), skipped: AtomicUsize::new(0),
skipped_txs: AtomicUsize::new(0), skipped_txs: AtomicUsize::new(0),
in_shutdown: AtomicBool::new(false),
} }
} }
/// Signal that we're shutting down; no more output necessary.
pub fn shutdown(&self) {
self.in_shutdown.store(true, ::std::sync::atomic::Ordering::SeqCst);
}
#[cfg_attr(feature="dev", allow(match_bool))] #[cfg_attr(feature="dev", allow(match_bool))]
pub fn tick(&self) { pub fn tick(&self) {
@ -222,14 +230,16 @@ impl ChainNotify for Informant {
} }
} }
const INFO_TIMER: TimerToken = 0;
impl IoHandler<ClientIoMessage> for Informant { impl IoHandler<ClientIoMessage> for Informant {
fn initialize(&self, io: &IoContext<ClientIoMessage>) { fn initialize(&self, io: &IoContext<ClientIoMessage>) {
io.register_timer(INFO_TIMER, 5000).expect("Error registering timer"); io.register_timer(INFO_TIMER, 5000).expect("Error registering timer");
} }
fn timeout(&self, _io: &IoContext<ClientIoMessage>, timer: TimerToken) { fn timeout(&self, _io: &IoContext<ClientIoMessage>, timer: TimerToken) {
if timer == INFO_TIMER && !self.shutdown.load(Ordering::SeqCst) { if timer == INFO_TIMER && !self.in_shutdown.load(AtomicOrdering::SeqCst) {
self.info.tick(); self.tick();
} }
} }
} }

View File

@ -25,6 +25,7 @@
extern crate docopt; extern crate docopt;
extern crate num_cpus; extern crate num_cpus;
extern crate rustc_serialize; extern crate rustc_serialize;
extern crate ethabi;
extern crate ethcore_devtools as devtools; extern crate ethcore_devtools as devtools;
extern crate ethcore; extern crate ethcore;
extern crate ethsync; extern crate ethsync;
@ -87,7 +88,6 @@ mod upgrade;
mod rpc; mod rpc;
mod dapps; mod dapps;
mod informant; mod informant;
mod io_handler;
mod cli; mod cli;
mod configuration; mod configuration;
mod migration; mod migration;
@ -111,7 +111,6 @@ mod boot;
mod user_defaults; mod user_defaults;
mod updater; mod updater;
mod operations; mod operations;
mod fetch;
#[cfg(feature="stratum")] #[cfg(feature="stratum")]
mod stratum; mod stratum;
@ -254,12 +253,12 @@ fn main() {
// if argv[0] == "parity" and this executable != ~/.parity-updates/parity, run that instead. // if argv[0] == "parity" and this executable != ~/.parity-updates/parity, run that instead.
let force_direct = std::env::args().any(|arg| arg == "--force-direct"); let force_direct = std::env::args().any(|arg| arg == "--force-direct");
let exe = std::env::current_exe().ok(); let exe = std::env::current_exe().ok();
let development = exe.and_then(|p| p.parent().and_then(|p| p.parent()).and_then(|p| p.file_name()).map(|n| n == "target")).unwrap_or(false); let development = exe.as_ref().and_then(|p| p.parent().and_then(|p| p.parent()).and_then(|p| p.file_name()).map(|n| n == "target")).unwrap_or(false);
let same_name = exe.and_then(|p| p.file_stem().map_or(false, |s| s == "parity")); let same_name = exe.as_ref().and_then(|p| p.file_stem().map(|s| s == "parity")).unwrap_or(false);
let have_update = updates_latest().exists(); let have_update = updates_latest().exists();
let is_non_updated_current = exe.map_or(false, p.canonicalize() != updates_latest().canonicalize()); let is_non_updated_current = exe.map_or(false, |p| p.canonicalize().ok() != updates_latest().canonicalize().ok());
trace_main!("Starting up {} (force-direct: {}, development: {}, have-update: {}, non-updated-current: {})", std::env::current_exe().map(|x| format!("{}", x.display())).unwrap_or("<unknown>".to_owned()), force_direct, development, have_update, is_non_updated_current); trace_main!("Starting up {} (force-direct: {}, development: {}, same-name: {}, have-update: {}, non-updated-current: {})", std::env::current_exe().map(|x| format!("{}", x.display())).unwrap_or("<unknown>".to_owned()), force_direct, development, same_name, have_update, is_non_updated_current);
if !force_direct && ! development && have_update && is_non_updated_current { if !force_direct && !development && same_name && have_update && is_non_updated_current {
// looks like we're not running ~/.parity-updates/parity when the user is expecting otherwise. // looks like we're not running ~/.parity-updates/parity when the user is expecting otherwise.
// Everything run inside a loop, so we'll be able to restart from the child into a new version seamlessly. // Everything run inside a loop, so we'll be able to restart from the child into a new version seamlessly.
loop { loop {

View File

@ -14,16 +14,16 @@
// You should have received a copy of the GNU General Public License // You should have received a copy of the GNU General Public License
// along with Parity. If not, see <http://www.gnu.org/licenses/>. // along with Parity. If not, see <http://www.gnu.org/licenses/>.
use std::sync::{Arc, Mutex, Condvar}; use std::sync::Arc;
use std::net::{TcpListener}; use std::net::{TcpListener};
use ctrlc::CtrlC; use ctrlc::CtrlC;
use fdlimit::raise_fd_limit; use fdlimit::raise_fd_limit;
use ethcore_rpc::{NetworkSettings, is_major_importing}; use ethcore_rpc::{NetworkSettings, is_major_importing};
use ethsync::NetworkConfiguration; use ethsync::NetworkConfiguration;
use util::{Colour, version, RotatingLogger}; use util::{Colour, version, RotatingLogger, Mutex, Condvar};
use io::{MayPanic, ForwardPanic, PanicHandler}; use io::{MayPanic, ForwardPanic, PanicHandler};
use ethcore_logger::{Config as LogConfig}; use ethcore_logger::{Config as LogConfig};
use ethcore::client::{Mode, UpdatePolicy, Updater, DatabaseCompactionProfile, VMType, ChainNotify, BlockChainClient}; use ethcore::client::{Mode, DatabaseCompactionProfile, VMType, BlockChainClient};
use ethcore::service::ClientService; use ethcore::service::ClientService;
use ethcore::account_provider::AccountProvider; use ethcore::account_provider::AccountProvider;
use ethcore::miner::{Miner, MinerService, ExternalMiner, MinerOptions}; use ethcore::miner::{Miner, MinerService, ExternalMiner, MinerOptions};
@ -31,7 +31,7 @@ use ethcore::snapshot;
use ethcore::verification::queue::VerifierSettings; use ethcore::verification::queue::VerifierSettings;
use ethsync::SyncConfig; use ethsync::SyncConfig;
use informant::Informant; use informant::Informant;
use updater::Updater; use updater::{UpdatePolicy, Updater};
use rpc::{HttpServer, IpcServer, HttpConfiguration, IpcConfiguration}; use rpc::{HttpServer, IpcServer, HttpConfiguration, IpcConfiguration};
use signer::SignerServer; use signer::SignerServer;
@ -312,10 +312,8 @@ pub fn execute(cmd: RunCmd, logger: Arc<RotatingLogger>) -> Result<bool, String>
} }
// the updater service // the updater service
let updater = Updater::new(service.client(), update_policy); let updater = Updater::new(Arc::downgrade(&(service.client() as Arc<BlockChainClient>)), update_policy);
if let Some(ref u) = updater { service.add_notify(updater.clone());
service.add_notify(u.clone());
}
// set up dependencies for rpc servers // set up dependencies for rpc servers
let signer_path = cmd.signer_conf.signer_path.clone(); let signer_path = cmd.signer_conf.signer_path.clone();
@ -422,9 +420,9 @@ pub fn execute(cmd: RunCmd, logger: Arc<RotatingLogger>) -> Result<bool, String>
info!("Finishing work, please wait..."); info!("Finishing work, please wait...");
// to make sure timer does not spawn requests while shutdown is in progress // to make sure timer does not spawn requests while shutdown is in progress
io_handler.shutdown.store(true, ::std::sync::atomic::Ordering::SeqCst); informant.shutdown();
// just Arc is dropping here, to allow other reference release in its default time // just Arc is dropping here, to allow other reference release in its default time
drop(io_handler); drop(informant);
// hypervisor should be shutdown first while everything still works and can be // hypervisor should be shutdown first while everything still works and can be
// terminated gracefully // terminated gracefully
@ -474,7 +472,7 @@ fn wait_for_exit(
_ipc_server: Option<IpcServer>, _ipc_server: Option<IpcServer>,
_dapps_server: Option<WebappServer>, _dapps_server: Option<WebappServer>,
_signer_server: Option<SignerServer>, _signer_server: Option<SignerServer>,
updater: Option<Arc<Updater>> updater: Arc<Updater>
) -> bool { ) -> bool {
let exit = Arc::new((Mutex::new(false), Condvar::new())); let exit = Arc::new((Mutex::new(false), Condvar::new()));
@ -487,12 +485,11 @@ fn wait_for_exit(
panic_handler.on_panic(move |_reason| { e.1.notify_all(); }); panic_handler.on_panic(move |_reason| { e.1.notify_all(); });
// Handle updater wanting to restart us // Handle updater wanting to restart us
if let Some(ref u) = updater {
let e = exit.clone(); let e = exit.clone();
u.set_exit_handler(move || { e.0.lock() = true; e.1.notify_all(); }); updater.set_exit_handler(move || { *e.0.lock() = true; e.1.notify_all(); });
}
// Wait for signal // Wait for signal
let _ = exit.1.wait(exit.0.lock().unwrap()); let mut l = exit.0.lock();
*exit.0.lock() let _ = exit.1.wait(&mut l);
*l
} }

View File

@ -170,7 +170,7 @@ impl SnapshotCommand {
try!(execute_upgrades(&db_dirs, algorithm, self.compaction.compaction_profile(db_dirs.fork_path().as_path()))); try!(execute_upgrades(&db_dirs, algorithm, self.compaction.compaction_profile(db_dirs.fork_path().as_path())));
// prepare client config // prepare client config
let client_config = to_client_config(&self.cache_config, Default::default(), Mode::Active, tracing, fat_db, self.compaction, self.wal, VMType::default(), "".into(), algorithm, self.pruning_history, true); let client_config = to_client_config(&self.cache_config, Mode::Active, tracing, fat_db, self.compaction, self.wal, VMType::default(), "".into(), algorithm, self.pruning_history, true);
let service = try!(ClientService::start( let service = try!(ClientService::start(
client_config, client_config,

View File

@ -14,15 +14,14 @@
// You should have received a copy of the GNU General Public License // You should have received a copy of the GNU General Public License
// along with Parity. If not, see <http://www.gnu.org/licenses/>. // along with Parity. If not, see <http://www.gnu.org/licenses/>.
use std::sync::{Weak}; use std::sync::{Arc, Weak};
use std::{io, os, fs, env}; use std::{io, os, fs, env};
use std::path::{Path, PathBuf}; use std::path::{Path, PathBuf};
use util::misc::{VersionInfo, ReleaseTrack/*, platform*/}; use util::misc::{VersionInfo, ReleaseTrack/*, platform*/};
use util::{Address, H160, H256, FixedHash, Mutex}; use util::{Address, H160, H256, FixedHash, Mutex, Bytes};
use super::operations::Operations; use super::operations::Operations;
use ethcore::client::{Client, BlockId}; use ethcore::client::{BlockId, BlockChainClient, ChainNotify};
use fetch::HashFetch; use hash_fetch::{self as fetch, HashFetch};
use fetch;
/// Filter for releases. /// Filter for releases.
#[derive(Debug, Eq, PartialEq, Clone)] #[derive(Debug, Eq, PartialEq, Clone)]
@ -94,11 +93,11 @@ struct UpdaterState {
pub struct Updater { pub struct Updater {
// Useful environmental stuff. // Useful environmental stuff.
update_policy: UpdatePolicy, update_policy: UpdatePolicy,
weak_self: Weak<Updater>, weak_self: Mutex<Weak<Updater>>,
client: Weak<Client>, client: Weak<BlockChainClient>,
fetcher: Option<fetch::Client>, fetcher: Option<fetch::Client>,
operations: Mutex<Option<Operations>>, operations: Mutex<Option<Operations>>,
exit_handler: Mutex<Option<Fn()>>, exit_handler: Mutex<Option<Box<Fn() + 'static + Send>>>,
// Our version info (static) // Our version info (static)
this: VersionInfo, this: VersionInfo,
@ -128,7 +127,7 @@ impl Updater {
pub fn new(client: Weak<BlockChainClient>, update_policy: UpdatePolicy) -> Arc<Self> { pub fn new(client: Weak<BlockChainClient>, update_policy: UpdatePolicy) -> Arc<Self> {
let mut u = Updater { let mut u = Updater {
update_policy: update_policy, update_policy: update_policy,
weak_self: Default::default(), weak_self: Mutex::new(Default::default()),
client: client.clone(), client: client.clone(),
fetcher: None, fetcher: None,
operations: Mutex::new(None), operations: Mutex::new(None),
@ -142,9 +141,9 @@ impl Updater {
u.this.track = ReleaseTrack::Nightly; u.this.track = ReleaseTrack::Nightly;
} }
let r = Arc::new(u); let mut r = Arc::new(u);
r.as_mut().weak_self = Arc::downgrade(&r); Arc::get_mut(&mut r).expect("arc created on previous line; qed").fetcher = Some(fetch::Client::new(r.clone()));
r.as_mut().fetcher = Some(fetch::Client::new(r)); *r.weak_self.lock() = Arc::downgrade(&r);
r r
} }
@ -167,9 +166,9 @@ impl Updater {
/// Actually upgrades the client. Assumes that the binary has been downloaded. /// Actually upgrades the client. Assumes that the binary has been downloaded.
/// @returns `true` on success. /// @returns `true` on success.
pub fn execute_upgrade(&mut self) -> bool { pub fn execute_upgrade(&self) -> bool {
(|| -> Result<bool, String> { (|| -> Result<bool, String> {
let s = state.lock(); let mut s = self.state.lock();
if let Some(r) = s.ready.take() { if let Some(r) = s.ready.take() {
let p = Self::update_file_path(&r.version); let p = Self::update_file_path(&r.version);
let n = Self::updates_latest(); let n = Self::updates_latest();
@ -178,7 +177,7 @@ impl Updater {
Ok(_) => { Ok(_) => {
info!("Completed upgrade to {}", &r.version); info!("Completed upgrade to {}", &r.version);
s.installed = Some(r); s.installed = Some(r);
if let Some(ref h) = self.exit_handler().lock() { if let Some(ref h) = *self.exit_handler.lock() {
(*h)(); (*h)();
} }
Ok(true) Ok(true)
@ -195,14 +194,6 @@ impl Updater {
})().unwrap_or_else(|e| { warn!("{}", e); false }) })().unwrap_or_else(|e| { warn!("{}", e); false })
} }
/// Returns true iff the current version is capable of forming consensus.
pub fn is_consensus_capable(&self) -> bool {
/* if let Some(ref latest) = self.latest {
*/ unimplemented!()
}
/// Our version info. /// Our version info.
pub fn version_info(&self) -> &VersionInfo { &self.this } pub fn version_info(&self) -> &VersionInfo { &self.this }
@ -210,13 +201,13 @@ impl Updater {
pub fn info(&self) -> Option<OperationsInfo> { self.state.lock().latest.clone() } pub fn info(&self) -> Option<OperationsInfo> { self.state.lock().latest.clone() }
/// Set a closure to call when we want to restart the client /// Set a closure to call when we want to restart the client
pub fn set_exit_handler(&self, f: Fn()) { pub fn set_exit_handler<F>(&self, f: F) where F: Fn() + 'static + Send {
*self.exit_handler.lock() = f; *self.exit_handler.lock() = Some(Box::new(f));
} }
fn collect_release_info(&self, release_id: &H256) -> Result<ReleaseInfo, String> { fn collect_release_info(operations: &Operations, release_id: &H256) -> Result<ReleaseInfo, String> {
let (fork, track, semver, is_critical) = self.operations.release(CLIENT_ID, release_id)?; let (fork, track, semver, is_critical) = operations.release(CLIENT_ID, release_id)?;
let latest_binary = self.operations.checksum(CLIENT_ID, release_id, &platform())?; let latest_binary = operations.checksum(CLIENT_ID, release_id, &platform())?;
Ok(ReleaseInfo { Ok(ReleaseInfo {
version: VersionInfo::from_raw(semver, track, release_id.clone().into()), version: VersionInfo::from_raw(semver, track, release_id.clone().into()),
is_critical: is_critical, is_critical: is_critical,
@ -226,15 +217,16 @@ impl Updater {
} }
fn collect_latest(&self) -> Result<OperationsInfo, String> { fn collect_latest(&self) -> Result<OperationsInfo, String> {
let this_fork = u.operations.release(CLIENT_ID, &u.this.hash.into()).ok() if let Some(ref operations) = *self.operations.lock() {
let this_fork = operations.release(CLIENT_ID, &self.this.hash.into()).ok()
.and_then(|(fork, track, _, _)| if track > 0 {Some(fork as u64)} else {None}); .and_then(|(fork, track, _, _)| if track > 0 {Some(fork as u64)} else {None});
if self.this.track == ReleaseTrack::Unknown { if self.this.track == ReleaseTrack::Unknown {
return Err(format!("Current executable ({}) is unreleased.", H160::from(self.this.hash))); return Err(format!("Current executable ({}) is unreleased.", H160::from(self.this.hash)));
} }
let latest_in_track = self.operations.latest_in_track(CLIENT_ID, self.this.track.into())?; let latest_in_track = operations.latest_in_track(CLIENT_ID, self.this.track.into())?;
let in_track = self.collect_release_info(&latest_in_track)?; let in_track = Self::collect_release_info(operations, &latest_in_track)?;
let mut in_minor = Some(in_track.clone()); let mut in_minor = Some(in_track.clone());
const PROOF: &'static str = "in_minor initialised and assigned with Some; loop breaks if None assigned; qed"; const PROOF: &'static str = "in_minor initialised and assigned with Some; loop breaks if None assigned; qed";
while in_minor.as_ref().expect(PROOF).version.track != self.this.track { while in_minor.as_ref().expect(PROOF).version.track != self.this.track {
@ -243,15 +235,18 @@ impl Updater {
ReleaseTrack::Nightly => ReleaseTrack::Beta, ReleaseTrack::Nightly => ReleaseTrack::Beta,
_ => { in_minor = None; break; } _ => { in_minor = None; break; }
}; };
in_minor = Some(self.collect_release_info(&self.operations.latest_in_track(CLIENT_ID, track.into())?)?); in_minor = Some(Self::collect_release_info(operations, &operations.latest_in_track(CLIENT_ID, track.into())?)?);
} }
Ok(OperationsInfo { Ok(OperationsInfo {
fork: self.operations.latest_fork()? as u64, fork: operations.latest_fork()? as u64,
this_fork: this_fork, this_fork: this_fork,
track: in_track, track: in_track,
minor: in_minor, minor: in_minor,
}) })
} else {
Err("Operations not available".into())
}
} }
fn update_file_path(v: &VersionInfo) -> PathBuf { fn update_file_path(v: &VersionInfo) -> PathBuf {
@ -268,10 +263,10 @@ impl Updater {
dest dest
} }
fn fetch_done(&mut self, result: Result<PathBuf, fetch::Error>) { fn fetch_done(&self, result: Result<PathBuf, fetch::Error>) {
(|| -> Result<(), String> { (|| -> Result<(), String> {
let auto = { let auto = {
let mut s = state.lock(); let mut s = self.state.lock();
let fetched = s.fetching.take().unwrap(); let fetched = s.fetching.take().unwrap();
let b = result.map_err(|e| format!("Unable to fetch update ({}): {:?}", fetched.version, e))?; let b = result.map_err(|e| format!("Unable to fetch update ({}): {:?}", fetched.version, e))?;
info!("Fetched latest version ({}) OK to {}", fetched.version, b.display()); info!("Fetched latest version ({}) OK to {}", fetched.version, b.display());
@ -288,17 +283,18 @@ impl Updater {
auto auto
}; };
if auto { if auto {
// will lock self.state, so ensure it's outside of previous block.
self.execute_upgrade(); self.execute_upgrade();
} }
Ok(()) Ok(())
})().unwrap_or_else(|e| warn!("{}", e)); })().unwrap_or_else(|e| warn!("{}", e));
} }
fn poll(&mut self) { fn poll(&self) {
info!(target: "updater", "Current release is {}", self.this); info!(target: "updater", "Current release is {}", self.this);
if *self.operations.lock().is_none() { if self.operations.lock().is_none() {
if let Some(ops_addr) = client.upgrade().registry_address("operations") { if let Some(ops_addr) = self.client.upgrade().and_then(|c| c.registry_address("operations".into())) {
trace!(target: "client", "Found operations at {}", ops_addr); trace!(target: "client", "Found operations at {}", ops_addr);
let client = self.client.clone(); let client = self.client.clone();
*self.operations.lock() = Some(Operations::new(ops_addr, move |a, d| client.upgrade().ok_or("No client!".into()).and_then(|c| c.call_contract(a, d)))); *self.operations.lock() = Some(Operations::new(ops_addr, move |a, d| client.upgrade().ok_or("No client!".into()).and_then(|c| c.call_contract(a, d))));
@ -308,8 +304,6 @@ impl Updater {
} }
} }
u.latest = u.collect_latest().ok();
let current_number = self.client.upgrade().map_or(0, |c| c.block_number(BlockId::Latest).unwrap_or(0)); let current_number = self.client.upgrade().map_or(0, |c| c.block_number(BlockId::Latest).unwrap_or(0));
let latest = self.collect_latest().ok(); let latest = self.collect_latest().ok();
@ -329,23 +323,23 @@ impl Updater {
let already_have_latest = s.installed.as_ref().or(s.ready.as_ref()).map_or(false, |t| *t == latest.track); let already_have_latest = s.installed.as_ref().or(s.ready.as_ref()).map_or(false, |t| *t == latest.track);
if self.update_policy.enable_downloading && !running_latest && !already_have_latest { if self.update_policy.enable_downloading && !running_latest && !already_have_latest {
if let Some(b) = latest.track.binary { if let Some(b) = latest.track.binary {
if fetching.is_none() { if s.fetching.is_none() {
info!("Attempting to get parity binary {}", b); info!("Attempting to get parity binary {}", b);
s.fetching = Some(latest.track.clone()); s.fetching = Some(latest.track.clone());
let weak_self = self.weak_self.clone(); let weak_self = self.weak_self.lock().clone();
let f = move |r: Result<PathBuf, fetch::Error>| if let Some(this) = weak_self.upgrade().as_mut() { this.fetch_done(r) }}; let f = move |r: Result<PathBuf, fetch::Error>| if let Some(this) = weak_self.upgrade() { this.fetch_done(r) };
fetcher.fetch(b, Box::new(f)).ok(); self.fetcher.as_ref().expect("Created on `new`; qed").fetch(b, Box::new(f)).ok();
} }
} }
} }
info!(target: "updater", "Fork: this/current/latest/latest-known: {}/#{}/#{}/#{}", match s.latest.this_fork { Some(f) => format!("#{}", f), None => "unknown".into(), }, current_number, s.latest.track.fork, s.latest.fork); 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);
} }
(*self.state.lock()).latest = latest; (*self.state.lock()).latest = latest;
} }
} }
impl ChainNotify for Updater { impl ChainNotify for Updater {
fn new_blocks(&self, _imported: Vec<H256>, _invalid: Vec<H256>, _enacted: Vec<H256>, _retracted: Vec<H256>, _sealed: Vec<H256>, duration: u64) { fn new_blocks(&self, _imported: Vec<H256>, _invalid: Vec<H256>, _enacted: Vec<H256>, _retracted: Vec<H256>, _sealed: Vec<H256>, _duration: u64) {
// TODO: something like this // TODO: something like this
// if !self.client.upgrade().map_or(true, |c| c.is_major_syncing()) { // if !self.client.upgrade().map_or(true, |c| c.is_major_syncing()) {
self.poll(); self.poll();