Remove updater

This commit is contained in:
Artem Vorotnikov 2020-08-14 13:24:16 +03:00
parent 194101ed00
commit defd24c40e
No known key found for this signature in database
GPG Key ID: E0148C3F2FBB7A20
43 changed files with 60 additions and 4502 deletions

64
Cargo.lock generated
View File

@ -2279,15 +2279,6 @@ name = "mime"
version = "0.3.14" version = "0.3.14"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "mime_guess"
version = "2.0.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"mime 0.3.14 (registry+https://github.com/rust-lang/crates.io-index)",
"unicase 2.5.1 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]] [[package]]
name = "mio" name = "mio"
version = "0.6.19" version = "0.6.19"
@ -2623,6 +2614,7 @@ dependencies = [
"ethstore 0.2.1", "ethstore 0.2.1",
"fake-fetch 0.0.1", "fake-fetch 0.0.1",
"fdlimit 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", "fdlimit 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
"fetch 0.1.0",
"futures 0.1.29 (registry+https://github.com/rust-lang/crates.io-index)", "futures 0.1.29 (registry+https://github.com/rust-lang/crates.io-index)",
"ipnetwork 0.12.8 (registry+https://github.com/rust-lang/crates.io-index)", "ipnetwork 0.12.8 (registry+https://github.com/rust-lang/crates.io-index)",
"journaldb 0.2.0", "journaldb 0.2.0",
@ -2639,13 +2631,11 @@ dependencies = [
"panic_hook 0.1.0", "panic_hook 0.1.0",
"parity-bytes 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", "parity-bytes 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
"parity-daemonize 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", "parity-daemonize 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
"parity-hash-fetch 1.12.0",
"parity-ipfs-api 1.12.0", "parity-ipfs-api 1.12.0",
"parity-local-store 0.1.0", "parity-local-store 0.1.0",
"parity-path 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", "parity-path 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
"parity-rpc 1.12.0", "parity-rpc 1.12.0",
"parity-runtime 0.1.0", "parity-runtime 0.1.0",
"parity-updater 1.12.0",
"parity-version 2.5.13", "parity-version 2.5.13",
"parking_lot 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)", "parking_lot 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)",
"pretty_assertions 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", "pretty_assertions 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
@ -2666,29 +2656,6 @@ dependencies = [
"winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", "winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)",
] ]
[[package]]
name = "parity-hash-fetch"
version = "1.12.0"
dependencies = [
"ethabi 6.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
"ethabi-contract 6.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
"ethabi-derive 6.0.2 (registry+https://github.com/rust-lang/crates.io-index)",
"ethereum-types 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)",
"fake-fetch 0.0.1",
"fetch 0.1.0",
"futures 0.1.29 (registry+https://github.com/rust-lang/crates.io-index)",
"keccak-hash 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
"log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)",
"mime 0.3.14 (registry+https://github.com/rust-lang/crates.io-index)",
"mime_guess 2.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
"parity-bytes 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
"parity-runtime 0.1.0",
"parking_lot 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)",
"rand 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)",
"registrar 0.0.1",
"rustc-hex 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]] [[package]]
name = "parity-ipfs-api" name = "parity-ipfs-api"
version = "1.12.0" version = "1.12.0"
@ -2788,14 +2755,12 @@ dependencies = [
"parity-bytes 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", "parity-bytes 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
"parity-crypto 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", "parity-crypto 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)",
"parity-runtime 0.1.0", "parity-runtime 0.1.0",
"parity-updater 1.12.0",
"parity-version 2.5.13", "parity-version 2.5.13",
"parking_lot 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)", "parking_lot 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)",
"pretty_assertions 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", "pretty_assertions 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
"rand 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", "rand 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)",
"rlp 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", "rlp 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
"rustc-hex 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", "rustc-hex 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
"semver 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)",
"serde 1.0.102 (registry+https://github.com/rust-lang/crates.io-index)", "serde 1.0.102 (registry+https://github.com/rust-lang/crates.io-index)",
"serde_derive 1.0.102 (registry+https://github.com/rust-lang/crates.io-index)", "serde_derive 1.0.102 (registry+https://github.com/rust-lang/crates.io-index)",
"serde_json 1.0.41 (registry+https://github.com/rust-lang/crates.io-index)", "serde_json 1.0.41 (registry+https://github.com/rust-lang/crates.io-index)",
@ -2869,32 +2834,6 @@ dependencies = [
"winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", "winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)",
] ]
[[package]]
name = "parity-updater"
version = "1.12.0"
dependencies = [
"common-types 0.1.0",
"ethabi 6.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
"ethabi-contract 6.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
"ethabi-derive 6.0.2 (registry+https://github.com/rust-lang/crates.io-index)",
"ethcore 1.12.0",
"ethcore-sync 1.12.0",
"ethereum-types 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)",
"keccak-hash 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
"lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
"log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)",
"matches 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)",
"parity-bytes 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
"parity-hash-fetch 1.12.0",
"parity-path 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
"parity-version 2.5.13",
"parking_lot 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)",
"rand 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)",
"semver 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)",
"target_info 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
"tempdir 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]] [[package]]
name = "parity-version" name = "parity-version"
version = "2.5.13" version = "2.5.13"
@ -4927,7 +4866,6 @@ dependencies = [
"checksum memory-db 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)" = "94da53143d45f6bad3753f532e56ad57a6a26c0ca6881794583310c7cb4c885f" "checksum memory-db 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)" = "94da53143d45f6bad3753f532e56ad57a6a26c0ca6881794583310c7cb4c885f"
"checksum memory_units 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "71d96e3f3c0b6325d8ccd83c33b28acb183edcb6c67938ba104ec546854b0882" "checksum memory_units 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "71d96e3f3c0b6325d8ccd83c33b28acb183edcb6c67938ba104ec546854b0882"
"checksum mime 0.3.14 (registry+https://github.com/rust-lang/crates.io-index)" = "dd1d63acd1b78403cc0c325605908475dd9b9a3acbf65ed8bcab97e27014afcf" "checksum mime 0.3.14 (registry+https://github.com/rust-lang/crates.io-index)" = "dd1d63acd1b78403cc0c325605908475dd9b9a3acbf65ed8bcab97e27014afcf"
"checksum mime_guess 2.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "1a0ed03949aef72dbdf3116a383d7b38b4768e6f960528cd6a6044aa9ed68599"
"checksum mio 0.6.19 (registry+https://github.com/rust-lang/crates.io-index)" = "83f51996a3ed004ef184e16818edc51fadffe8e7ca68be67f9dee67d84d0ff23" "checksum mio 0.6.19 (registry+https://github.com/rust-lang/crates.io-index)" = "83f51996a3ed004ef184e16818edc51fadffe8e7ca68be67f9dee67d84d0ff23"
"checksum mio-extras 2.0.5 (registry+https://github.com/rust-lang/crates.io-index)" = "46e73a04c2fa6250b8d802134d56d554a9ec2922bf977777c805ea5def61ce40" "checksum mio-extras 2.0.5 (registry+https://github.com/rust-lang/crates.io-index)" = "46e73a04c2fa6250b8d802134d56d554a9ec2922bf977777c805ea5def61ce40"
"checksum mio-named-pipes 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)" = "f5e374eff525ce1c5b7687c4cef63943e7686524a387933ad27ca7ec43779cb3" "checksum mio-named-pipes 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)" = "f5e374eff525ce1c5b7687c4cef63943e7686524a387933ad27ca7ec43779cb3"

View File

@ -47,16 +47,15 @@ ethcore-sync = { path = "ethcore/sync" }
ethereum-types = "0.4" ethereum-types = "0.4"
ethkey = { path = "accounts/ethkey" } ethkey = { path = "accounts/ethkey" }
ethstore = { path = "accounts/ethstore" } ethstore = { path = "accounts/ethstore" }
fetch = { path = "util/fetch" }
node-filter = { path = "ethcore/node-filter" } node-filter = { path = "ethcore/node-filter" }
rlp = { version = "0.3.0", features = ["ethereum"] } rlp = { version = "0.3.0", features = ["ethereum"] }
cli-signer= { path = "cli-signer" } cli-signer= { path = "cli-signer" }
parity-daemonize = "0.3" parity-daemonize = "0.3"
parity-hash-fetch = { path = "updater/hash-fetch" }
parity-ipfs-api = { path = "ipfs" } parity-ipfs-api = { path = "ipfs" }
parity-local-store = { path = "miner/local-store" } parity-local-store = { path = "miner/local-store" }
parity-runtime = { path = "util/runtime" } parity-runtime = { path = "util/runtime" }
parity-rpc = { path = "rpc" } parity-rpc = { path = "rpc" }
parity-updater = { path = "updater" }
parity-version = { path = "util/version" } parity-version = { path = "util/version" }
parity-path = "0.1" parity-path = "0.1"
dir = { path = "util/dir" } dir = { path = "util/dir" }
@ -104,10 +103,6 @@ deadlock_detection = ["parking_lot/deadlock_detection"]
# `valgrind --tool=massif /path/to/parity <parity params>` # `valgrind --tool=massif /path/to/parity <parity params>`
# and `massif-visualizer` for visualization # and `massif-visualizer` for visualization
memory_profiling = [] memory_profiling = []
# hardcode version number 1.3.7 of parity to force an update
# in order to manually test that parity fall-over to the local version
# in case of invalid or deprecated command line arguments are entered
test-updater = ["parity-updater/test-updater"]
[lib] [lib]
path = "parity/lib.rs" path = "parity/lib.rs"

View File

@ -194,11 +194,6 @@ struct Importer {
/// Call `import_block()` to import a block asynchronously; `flush_queue()` flushes the queue. /// Call `import_block()` to import a block asynchronously; `flush_queue()` flushes the queue.
pub struct Client { pub struct Client {
/// Flag used to disable the client forever. Not to be confused with `liveness`. /// Flag used to disable the client forever. Not to be confused with `liveness`.
///
/// For example, auto-updater will disable client forever if there is a
/// hard fork registered on-chain that we don't have capability for.
/// When hard fork block rolls around, the client (if `update` is false)
/// knows it can't proceed further.
enabled: AtomicBool, enabled: AtomicBool,
/// Operating mode for the client /// Operating mode for the client
@ -1003,17 +998,6 @@ impl Client {
self.notify.write().push(Arc::downgrade(&target)); self.notify.write().push(Arc::downgrade(&target));
} }
/// Set a closure to call when the client wants to be restarted.
///
/// The parameter passed to the callback is the name of the new chain spec to use after
/// the restart.
pub fn set_exit_handler<F>(&self, f: F)
where
F: Fn(String) + 'static + Send,
{
*self.exit_handler.lock() = Some(Box::new(f));
}
/// Returns engine reference. /// Returns engine reference.
pub fn engine(&self) -> &dyn EthEngine { pub fn engine(&self) -> &dyn EthEngine {
&*self.engine &*self.engine

View File

@ -234,18 +234,6 @@ usage! {
{ {
// Global flags and arguments // Global flags and arguments
["Operating Options"] ["Operating Options"]
FLAG flag_no_download: (bool) = false, or |c: &Config| c.parity.as_ref()?.no_download.clone(),
"--no-download",
"Normally new releases will be downloaded ready for updating. This disables it. Not recommended.",
FLAG flag_no_consensus: (bool) = false, or |c: &Config| c.parity.as_ref()?.no_consensus.clone(),
"--no-consensus",
"Force the binary to run even if there are known issues regarding consensus. Not recommended.",
FLAG flag_force_direct: (bool) = false, or |_| None,
"--force-direct",
"Run the originally installed version of Parity, ignoring any updates that have since been installed.",
ARG arg_mode: (String) = "last", or |c: &Config| c.parity.as_ref()?.mode.clone(), ARG arg_mode: (String) = "last", or |c: &Config| c.parity.as_ref()?.mode.clone(),
"--mode=[MODE]", "--mode=[MODE]",
"Set the operating mode. MODE can be one of: last - Uses the last-used mode, active if none; active - Parity continuously syncs the chain; passive - Parity syncs initially, then sleeps and wakes regularly to resync; dark - Parity syncs only when the JSON-RPC is active; offline - Parity doesn't sync.", "Set the operating mode. MODE can be one of: last - Uses the last-used mode, active if none; active - Parity continuously syncs the chain; passive - Parity syncs initially, then sleeps and wakes regularly to resync; dark - Parity syncs only when the JSON-RPC is active; offline - Parity doesn't sync.",
@ -258,22 +246,6 @@ usage! {
"--mode-alarm=[SECS]", "--mode-alarm=[SECS]",
"Specify the number of seconds before auto sleep reawake timeout occurs when mode is passive", "Specify the number of seconds before auto sleep reawake timeout occurs when mode is passive",
ARG arg_auto_update: (String) = "critical", or |c: &Config| c.parity.as_ref()?.auto_update.clone(),
"--auto-update=[SET]",
"Set a releases set to automatically update and install. SET can be one of: all - All updates in the our release track; critical - Only consensus/security updates; none - No updates will be auto-installed.",
ARG arg_auto_update_delay: (u16) = 100u16, or |c: &Config| c.parity.as_ref()?.auto_update_delay.clone(),
"--auto-update-delay=[NUM]",
"Specify the maximum number of blocks used for randomly delaying updates.",
ARG arg_auto_update_check_frequency: (u16) = 20u16, or |c: &Config| c.parity.as_ref()?.auto_update_check_frequency.clone(),
"--auto-update-check-frequency=[NUM]",
"Specify the number of blocks between each auto-update check.",
ARG arg_release_track: (String) = "current", or |c: &Config| c.parity.as_ref()?.release_track.clone(),
"--release-track=[TRACK]",
"Set which release track we should use for updates. TRACK can be one of: stable - Stable releases; beta - Beta releases; nightly - Nightly releases (unstable); testing - Testing releases (do not use); current - Whatever track this executable was released on.",
ARG arg_chain: (String) = "foundation", or |c: &Config| c.parity.as_ref()?.chain.clone(), ARG arg_chain: (String) = "foundation", or |c: &Config| c.parity.as_ref()?.chain.clone(),
"--chain=[CHAIN]", "--chain=[CHAIN]",
"Specify the blockchain type. CHAIN may be either a JSON chain specification file or ethereum, classic, poacore, xdai, volta, ewc, musicoin, ellaism, mix, callisto, morden, mordor, ropsten, kovan, rinkeby, goerli, kotti, poasokol, testnet, or dev.", "Specify the blockchain type. CHAIN may be either a JSON chain specification file or ethereum, classic, poacore, xdai, volta, ewc, musicoin, ellaism, mix, callisto, morden, mordor, ropsten, kovan, rinkeby, goerli, kotti, poasokol, testnet, or dev.",
@ -896,12 +868,6 @@ struct Operating {
mode: Option<String>, mode: Option<String>,
mode_timeout: Option<u64>, mode_timeout: Option<u64>,
mode_alarm: Option<u64>, mode_alarm: Option<u64>,
auto_update: Option<String>,
auto_update_delay: Option<u16>,
auto_update_check_frequency: Option<u16>,
release_track: Option<String>,
no_download: Option<bool>,
no_consensus: Option<bool>,
chain: Option<String>, chain: Option<String>,
base_path: Option<String>, base_path: Option<String>,
db_path: Option<String>, db_path: Option<String>,
@ -1344,19 +1310,12 @@ mod tests {
arg_mode: "last".into(), arg_mode: "last".into(),
arg_mode_timeout: 300u64, arg_mode_timeout: 300u64,
arg_mode_alarm: 3600u64, arg_mode_alarm: 3600u64,
arg_auto_update: "none".into(),
arg_auto_update_delay: 200u16,
arg_auto_update_check_frequency: 50u16,
arg_release_track: "current".into(),
flag_no_download: false,
flag_no_consensus: false,
arg_chain: "xyz".into(), arg_chain: "xyz".into(),
arg_base_path: Some("$HOME/.parity".into()), arg_base_path: Some("$HOME/.parity".into()),
arg_db_path: Some("$HOME/.parity/chains".into()), arg_db_path: Some("$HOME/.parity/chains".into()),
arg_keys_path: "$HOME/.parity/keys".into(), arg_keys_path: "$HOME/.parity/keys".into(),
arg_identity: "".into(), arg_identity: "".into(),
flag_no_persistent_txqueue: false, flag_no_persistent_txqueue: false,
flag_force_direct: false,
// -- Convenience Options // -- Convenience Options
arg_config: "$BASE/config.toml".into(), arg_config: "$BASE/config.toml".into(),
@ -1574,12 +1533,6 @@ mod tests {
mode: Some("dark".into()), mode: Some("dark".into()),
mode_timeout: Some(15u64), mode_timeout: Some(15u64),
mode_alarm: Some(10u64), mode_alarm: Some(10u64),
auto_update: None,
auto_update_delay: None,
auto_update_check_frequency: None,
release_track: None,
no_download: None,
no_consensus: None,
chain: Some("./chain.json".into()), chain: Some("./chain.json".into()),
base_path: None, base_path: None,
db_path: None, db_path: None,

View File

@ -1,5 +1,4 @@
[parity] [parity]
no_consensus = true
chain = "dev" chain = "dev"
[mining] [mining]

View File

@ -1,6 +1,3 @@
[parity]
no_consensus = true
[rpc] [rpc]
interface = "all" interface = "all"
apis = ["all"] apis = ["all"]

View File

@ -2,12 +2,6 @@
mode = "last" mode = "last"
mode_timeout = 300 mode_timeout = 300
mode_alarm = 3600 mode_alarm = 3600
auto_update = "none"
auto_update_delay = 200
auto_update_check_frequency = 50
release_track = "current"
no_download = false
no_consensus = false
no_persistent_txqueue = false no_persistent_txqueue = false
chain = "homestead" chain = "homestead"

View File

@ -47,7 +47,7 @@ use blockchain::{
}; };
use cache::CacheConfig; use cache::CacheConfig;
use dir::{ use dir::{
self, default_data_path, default_hypervisor_path, default_local_path, self, default_data_path, default_local_path,
helpers::{replace_home, replace_home_and_local}, helpers::{replace_home, replace_home_and_local},
Directories, Directories,
}; };
@ -70,7 +70,6 @@ use secretstore::{
}; };
use snapshot::{self, SnapshotCommand}; use snapshot::{self, SnapshotCommand};
use types::data_format::DataFormat; use types::data_format::DataFormat;
use updater::{ReleaseTrack, UpdateFilter, UpdatePolicy};
const DEFAULT_MAX_PEERS: u16 = 50; const DEFAULT_MAX_PEERS: u16 = 50;
const DEFAULT_MIN_PEERS: u16 = 25; const DEFAULT_MIN_PEERS: u16 = 25;
@ -146,7 +145,6 @@ impl Configuration {
self.args.arg_mode_alarm, self.args.arg_mode_alarm,
)?), )?),
}; };
let update_policy = self.update_policy()?;
let logger_config = self.logger_config(); let logger_config = self.logger_config();
let ws_conf = self.ws_config()?; let ws_conf = self.ws_config()?;
let snapshot_conf = self.snapshot_config()?; let snapshot_conf = self.snapshot_config()?;
@ -411,7 +409,6 @@ impl Configuration {
gas_pricer_conf: self.gas_pricer_config()?, gas_pricer_conf: self.gas_pricer_config()?,
miner_extras: self.miner_extras()?, miner_extras: self.miner_extras()?,
stratum: self.stratum_options()?, stratum: self.stratum_options()?,
update_policy: update_policy,
allow_missing_blocks: self.args.flag_jsonrpc_allow_missing_blocks, allow_missing_blocks: self.args.flag_jsonrpc_allow_missing_blocks,
mode: mode, mode: mode,
tracing: tracing, tracing: tracing,
@ -1036,41 +1033,6 @@ 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.arg_auto_update.as_ref() {
"none" => UpdateFilter::None,
"critical" => UpdateFilter::Critical,
"all" => UpdateFilter::All,
_ => {
return Err(
"Invalid value for `--auto-update`. See `--help` for more information."
.into(),
)
}
},
track: match self.args.arg_release_track.as_ref() {
"stable" => ReleaseTrack::Stable,
"beta" => ReleaseTrack::Beta,
"nightly" => ReleaseTrack::Nightly,
"testing" => ReleaseTrack::Testing,
"current" => ReleaseTrack::Unknown,
_ => {
return Err(
"Invalid value for `--releases-track`. See `--help` for more information."
.into(),
)
}
},
path: default_hypervisor_path(),
max_size: 128 * 1024 * 1024,
max_delay: self.args.arg_auto_update_delay as u64,
frequency: self.args.arg_auto_update_check_frequency as u64,
})
}
fn directories(&self) -> Directories { fn directories(&self) -> Directories {
let local_path = default_local_path(); let local_path = default_local_path();
let base_path = self let base_path = self
@ -1318,7 +1280,7 @@ mod tests {
use account::{AccountCmd, ImportAccounts, ListAccounts, NewAccount}; use account::{AccountCmd, ImportAccounts, ListAccounts, NewAccount};
use blockchain::{BlockchainCmd, ExportBlockchain, ExportState, ImportBlockchain}; use blockchain::{BlockchainCmd, ExportBlockchain, ExportState, ImportBlockchain};
use cli::Args; use cli::Args;
use dir::{default_hypervisor_path, Directories}; use dir::Directories;
use ethcore::{client::VMType, miner::MinerOptions}; use ethcore::{client::VMType, miner::MinerOptions};
use helpers::default_network_config; use helpers::default_network_config;
use miner::pool::PrioritizationStrategy; use miner::pool::PrioritizationStrategy;
@ -1330,7 +1292,6 @@ mod tests {
use run::RunCmd; use run::RunCmd;
use tempdir::TempDir; use tempdir::TempDir;
use types::{data_format::DataFormat, ids::BlockId}; use types::{data_format::DataFormat, ids::BlockId};
use updater::{ReleaseTrack, UpdateFilter, UpdatePolicy};
use network::{AllowIP, IpFilter}; use network::{AllowIP, IpFilter};
@ -1611,16 +1572,6 @@ mod tests {
acc_conf: Default::default(), acc_conf: Default::default(),
gas_pricer_conf: Default::default(), gas_pricer_conf: Default::default(),
miner_extras: Default::default(), miner_extras: Default::default(),
update_policy: UpdatePolicy {
enable_downloading: true,
require_consensus: true,
filter: UpdateFilter::Critical,
track: ReleaseTrack::Unknown,
path: default_hypervisor_path(),
max_size: 128 * 1024 * 1024,
max_delay: 100,
frequency: 20,
},
mode: Default::default(), mode: Default::default(),
tracing: Default::default(), tracing: Default::default(),
compaction: Default::default(), compaction: Default::default(),
@ -1677,71 +1628,6 @@ mod tests {
assert!(conf.miner_options().is_err()); assert!(conf.miner_options().is_err());
} }
#[test]
fn should_parse_updater_options() {
// when
let conf0 = parse(&["parity", "--release-track=testing"]);
let conf1 = parse(&[
"parity",
"--auto-update",
"all",
"--no-consensus",
"--auto-update-delay",
"300",
]);
let conf2 = parse(&[
"parity",
"--no-download",
"--auto-update=all",
"--release-track=beta",
"--auto-update-delay=300",
"--auto-update-check-frequency=100",
]);
let conf3 = parse(&["parity", "--auto-update=xxx"]);
// then
assert_eq!(
conf0.update_policy().unwrap(),
UpdatePolicy {
enable_downloading: true,
require_consensus: true,
filter: UpdateFilter::Critical,
track: ReleaseTrack::Testing,
path: default_hypervisor_path(),
max_size: 128 * 1024 * 1024,
max_delay: 100,
frequency: 20,
}
);
assert_eq!(
conf1.update_policy().unwrap(),
UpdatePolicy {
enable_downloading: true,
require_consensus: false,
filter: UpdateFilter::All,
track: ReleaseTrack::Unknown,
path: default_hypervisor_path(),
max_size: 128 * 1024 * 1024,
max_delay: 300,
frequency: 20,
}
);
assert_eq!(
conf2.update_policy().unwrap(),
UpdatePolicy {
enable_downloading: false,
require_consensus: true,
filter: UpdateFilter::All,
track: ReleaseTrack::Beta,
path: default_hypervisor_path(),
max_size: 128 * 1024 * 1024,
max_delay: 300,
frequency: 100,
}
);
assert!(conf3.update_policy().is_err());
}
#[test] #[test]
fn should_parse_network_settings() { fn should_parse_network_settings() {
// given // given
@ -1922,7 +1808,6 @@ mod tests {
let conf = Configuration::parse_cli(&args).unwrap(); let conf = Configuration::parse_cli(&args).unwrap();
match conf.into_command().unwrap().cmd { match conf.into_command().unwrap().cmd {
Cmd::Run(c) => { Cmd::Run(c) => {
assert_eq!(c.update_policy.require_consensus, false);
assert_eq!(c.net_settings.rpc_interface, "0.0.0.0"); assert_eq!(c.net_settings.rpc_interface, "0.0.0.0");
match c.http_conf.apis { match c.http_conf.apis {
ApiSet::List(set) => assert_eq!(set, ApiSet::All.list_apis()), ApiSet::List(set) => assert_eq!(set, ApiSet::All.list_apis()),
@ -1945,7 +1830,6 @@ mod tests {
assert_eq!(c.net_settings.chain, "dev"); assert_eq!(c.net_settings.chain, "dev");
assert_eq!(c.gas_pricer_conf, GasPricerConfig::Fixed(0.into())); assert_eq!(c.gas_pricer_conf, GasPricerConfig::Fixed(0.into()));
assert_eq!(c.miner_options.reseal_min_period, Duration::from_millis(0)); assert_eq!(c.miner_options.reseal_min_period, Duration::from_millis(0));
assert_eq!(c.update_policy.require_consensus, false);
assert_eq!(c.net_settings.rpc_interface, "0.0.0.0"); assert_eq!(c.net_settings.rpc_interface, "0.0.0.0");
match c.http_conf.apis { match c.http_conf.apis {
ApiSet::List(set) => assert_eq!(set, ApiSet::All.list_apis()), ApiSet::List(set) => assert_eq!(set, ApiSet::All.list_apis()),

View File

@ -55,18 +55,17 @@ extern crate ethcore_sync as sync;
extern crate ethereum_types; extern crate ethereum_types;
extern crate ethkey; extern crate ethkey;
extern crate ethstore; extern crate ethstore;
extern crate fetch;
extern crate journaldb; extern crate journaldb;
extern crate keccak_hash as hash; extern crate keccak_hash as hash;
extern crate kvdb; extern crate kvdb;
extern crate node_filter; extern crate node_filter;
extern crate parity_bytes as bytes; extern crate parity_bytes as bytes;
extern crate parity_hash_fetch as hash_fetch;
extern crate parity_ipfs_api; extern crate parity_ipfs_api;
extern crate parity_local_store as local_store; extern crate parity_local_store as local_store;
extern crate parity_path as path; extern crate parity_path as path;
extern crate parity_rpc; extern crate parity_rpc;
extern crate parity_runtime; extern crate parity_runtime;
extern crate parity_updater as updater;
extern crate parity_version; extern crate parity_version;
extern crate registrar; extern crate registrar;
@ -182,22 +181,13 @@ pub enum ExecutionAction {
Running(RunningClient), Running(RunningClient),
} }
fn execute<Cr, Rr>( fn execute(command: Execute, logger: Arc<RotatingLogger>) -> Result<ExecutionAction, String> {
command: Execute,
logger: Arc<RotatingLogger>,
on_client_rq: Cr,
on_updater_rq: Rr,
) -> Result<ExecutionAction, String>
where
Cr: Fn(String) + 'static + Send,
Rr: Fn() + 'static + Send,
{
#[cfg(feature = "deadlock_detection")] #[cfg(feature = "deadlock_detection")]
run_deadlock_detection_thread(); run_deadlock_detection_thread();
match command.cmd { match command.cmd {
Cmd::Run(run_cmd) => { Cmd::Run(run_cmd) => {
let outcome = run::execute(run_cmd, logger, on_client_rq, on_updater_rq)?; let outcome = run::execute(run_cmd, logger)?;
Ok(ExecutionAction::Running(outcome)) Ok(ExecutionAction::Running(outcome))
} }
Cmd::Version => Ok(ExecutionAction::Instant(Some(Args::print_version()))), Cmd::Version => Ok(ExecutionAction::Instant(Some(Args::print_version()))),
@ -237,25 +227,11 @@ where
/// Starts the parity client. /// Starts the parity client.
/// ///
/// `on_client_rq` is the action to perform when the client receives an RPC request to be restarted
/// with a different chain.
///
/// `on_updater_rq` is the action to perform when the updater has a new binary to execute.
///
/// The first parameter is the command line arguments that you would pass when running the parity /// The first parameter is the command line arguments that you would pass when running the parity
/// binary. /// binary.
/// ///
/// On error, returns what to print on stderr. /// On error, returns what to print on stderr.
// FIXME: totally independent logging capability, see https://github.com/paritytech/parity-ethereum/issues/10252 // FIXME: totally independent logging capability, see https://github.com/paritytech/parity-ethereum/issues/10252
pub fn start<Cr, Rr>( pub fn start(conf: Configuration, logger: Arc<RotatingLogger>) -> Result<ExecutionAction, String> {
conf: Configuration, execute(conf.into_command()?, logger)
logger: Arc<RotatingLogger>,
on_client_rq: Cr,
on_updater_rq: Rr,
) -> Result<ExecutionAction, String>
where
Cr: Fn(String) + 'static + Send,
Rr: Fn() + 'static + Send,
{
execute(conf.into_command()?, logger, on_client_rq, on_updater_rq)
} }

View File

@ -34,11 +34,7 @@ extern crate ethcore_logger;
extern crate winapi; extern crate winapi;
use std::{ use std::{
env, io::Write,
ffi::OsString,
fs::{create_dir_all, metadata, remove_file, File},
io::{Read, Write},
path::PathBuf,
process, process,
sync::{ sync::{
atomic::{AtomicBool, Ordering}, atomic::{AtomicBool, Ordering},
@ -48,148 +44,12 @@ use std::{
use ansi_term::Colour; use ansi_term::Colour;
use ctrlc::CtrlC; use ctrlc::CtrlC;
use dir::default_hypervisor_path;
use ethcore_logger::setup_log; use ethcore_logger::setup_log;
use fdlimit::raise_fd_limit; use fdlimit::raise_fd_limit;
use parity_daemonize::AsHandle; use parity_daemonize::AsHandle;
use parity_ethereum::{start, ExecutionAction}; use parity_ethereum::{start, ExecutionAction};
use parking_lot::{Condvar, Mutex}; use parking_lot::{Condvar, Mutex};
const PLEASE_RESTART_EXIT_CODE: i32 = 69;
const PARITY_EXECUTABLE_NAME: &str = "parity";
#[derive(Debug)]
enum Error {
BinaryNotFound,
ExitCode(i32),
Restart,
Unknown,
}
fn update_path(name: &str) -> PathBuf {
let mut dest = default_hypervisor_path();
dest.push(name);
dest
}
fn latest_exe_path() -> Result<PathBuf, Error> {
File::open(update_path("latest"))
.and_then(|mut f| {
let mut exe_path = String::new();
trace!(target: "updater", "latest binary path: {:?}", f);
f.read_to_string(&mut exe_path)
.map(|_| update_path(&exe_path))
})
.or(Err(Error::BinaryNotFound))
}
fn latest_binary_is_newer(
current_binary: &Option<PathBuf>,
latest_binary: &Option<PathBuf>,
) -> bool {
match (
current_binary
.as_ref()
.and_then(|p| metadata(p.as_path()).ok())
.and_then(|m| m.modified().ok()),
latest_binary
.as_ref()
.and_then(|p| metadata(p.as_path()).ok())
.and_then(|m| m.modified().ok()),
) {
(Some(latest_exe_time), Some(this_exe_time)) if latest_exe_time > this_exe_time => true,
_ => false,
}
}
fn set_spec_name_override(spec_name: &str) {
if let Err(e) = create_dir_all(default_hypervisor_path()).and_then(|_| {
File::create(update_path("spec_name_override"))
.and_then(|mut f| f.write_all(spec_name.as_bytes()))
}) {
warn!(
"Couldn't override chain spec: {} at {:?}",
e,
update_path("spec_name_override")
);
}
}
fn take_spec_name_override() -> Option<String> {
let p = update_path("spec_name_override");
let r = File::open(p.clone()).ok().and_then(|mut f| {
let mut spec_name = String::new();
f.read_to_string(&mut spec_name).ok().map(|_| spec_name)
});
let _ = remove_file(p);
r
}
#[cfg(windows)]
fn global_cleanup() {
// We need to cleanup all sockets before spawning another Parity process. This makes sure everything is cleaned up.
// The loop is required because of internal reference counter for winsock dll. We don't know how many crates we use do
// initialize it. There's at least 2 now.
for _ in 0..10 {
unsafe {
::winapi::um::winsock2::WSACleanup();
}
}
}
#[cfg(not(windows))]
fn global_init() {}
#[cfg(windows)]
fn global_init() {
// When restarting in the same process this reinits windows sockets.
unsafe {
const WS_VERSION: u16 = 0x202;
let mut wsdata: ::winapi::um::winsock2::WSADATA = ::std::mem::zeroed();
::winapi::um::winsock2::WSAStartup(WS_VERSION, &mut wsdata);
}
}
#[cfg(not(windows))]
fn global_cleanup() {}
// Starts parity binary installed via `parity-updater` and returns the code it exits with.
fn run_parity() -> Result<(), Error> {
global_init();
let prefix = vec![
OsString::from("--can-restart"),
OsString::from("--force-direct"),
];
let res: Result<(), Error> = latest_exe_path().and_then(|exe| {
process::Command::new(exe)
.args(
&(env::args_os()
.skip(1)
.chain(prefix.into_iter())
.collect::<Vec<_>>()),
)
.status()
.ok()
.map_or(Err(Error::Unknown), |es| {
match es.code() {
// Process success
Some(0) => Ok(()),
// Please restart
Some(PLEASE_RESTART_EXIT_CODE) => Err(Error::Restart),
// Process error code `c`
Some(c) => Err(Error::ExitCode(c)),
// Unknown error, couldn't determine error code
_ => Err(Error::Unknown),
}
})
});
global_cleanup();
res
}
#[derive(Debug)] #[derive(Debug)]
/// Status used to exit or restart the program. /// Status used to exit or restart the program.
struct ExitStatus { struct ExitStatus {
@ -197,18 +57,10 @@ struct ExitStatus {
panicking: bool, panicking: bool,
/// Whether the program should exit. /// Whether the program should exit.
should_exit: bool, should_exit: bool,
/// Whether the program should restart.
should_restart: bool,
/// If a restart happens, whether a new chain spec should be used.
spec_name_override: Option<String>,
} }
// Run `locally installed version` of parity (i.e, not installed via `parity-updater`) fn main() -> Result<(), i32> {
// Returns the exit error code. let conf = {
fn main_direct(force_can_restart: bool) -> i32 {
global_init();
let mut conf = {
let args = std::env::args().collect::<Vec<_>>(); let args = std::env::args().collect::<Vec<_>>();
parity_ethereum::Configuration::parse_cli(&args).unwrap_or_else(|e| e.exit()) parity_ethereum::Configuration::parse_cli(&args).unwrap_or_else(|e| e.exit())
}; };
@ -218,10 +70,6 @@ fn main_direct(force_can_restart: bool) -> i32 {
process::exit(2) process::exit(2)
}); });
if let Some(spec_override) = take_spec_name_override() {
conf.args.arg_chain = spec_override;
}
// FIXME: `pid_file` shouldn't need to cloned here // FIXME: `pid_file` shouldn't need to cloned here
// see: `https://github.com/paritytech/parity-daemonize/pull/13` for more info // see: `https://github.com/paritytech/parity-daemonize/pull/13` for more info
let handle = if let Some(pid) = conf.args.arg_daemon_pid_file.clone() { let handle = if let Some(pid) = conf.args.arg_daemon_pid_file.clone() {
@ -235,15 +83,13 @@ fn main_direct(force_can_restart: bool) -> i32 {
Ok(h) => Some(h), Ok(h) => Some(h),
Err(e) => { Err(e) => {
error!("{}", Colour::Red.paint(format!("{}", e))); error!("{}", Colour::Red.paint(format!("{}", e)));
return 1; return Err(1);
} }
} }
} else { } else {
None None
}; };
let can_restart = force_can_restart || conf.args.flag_can_restart;
// increase max number of open files // increase max number of open files
raise_fd_limit(); raise_fd_limit();
@ -251,8 +97,6 @@ fn main_direct(force_can_restart: bool) -> i32 {
Mutex::new(ExitStatus { Mutex::new(ExitStatus {
panicking: false, panicking: false,
should_exit: false, should_exit: false,
should_restart: false,
spec_name_override: None,
}), }),
Condvar::new(), Condvar::new(),
)); ));
@ -261,53 +105,16 @@ fn main_direct(force_can_restart: bool) -> i32 {
// again. // again.
let exiting = Arc::new(AtomicBool::new(false)); let exiting = Arc::new(AtomicBool::new(false));
let exec = if can_restart {
start(
conf,
logger,
{
let e = exit.clone();
let exiting = exiting.clone();
move |new_chain: String| {
if !exiting.swap(true, Ordering::SeqCst) {
*e.0.lock() = ExitStatus {
panicking: false,
should_exit: true,
should_restart: true,
spec_name_override: Some(new_chain),
};
e.1.notify_all();
}
}
},
{
let e = exit.clone();
let exiting = exiting.clone();
move || {
if !exiting.swap(true, Ordering::SeqCst) {
*e.0.lock() = ExitStatus {
panicking: false,
should_exit: true,
should_restart: true,
spec_name_override: None,
};
e.1.notify_all();
}
}
},
)
} else {
trace!(target: "mode", "Not hypervised: not setting exit handlers."); trace!(target: "mode", "Not hypervised: not setting exit handlers.");
start(conf, logger, move |_| {}, move || {}) let exec = start(conf, logger);
};
let res = match exec { match exec {
Ok(result) => match result { Ok(result) => match result {
ExecutionAction::Instant(Some(s)) => { ExecutionAction::Instant(output) => {
if let Some(s) = output {
println!("{}", s); println!("{}", s);
0
} }
ExecutionAction::Instant(None) => 0, }
ExecutionAction::Running(client) => { ExecutionAction::Running(client) => {
panic_hook::set_with({ panic_hook::set_with({
let e = exit.clone(); let e = exit.clone();
@ -319,8 +126,6 @@ fn main_direct(force_can_restart: bool) -> i32 {
*e.0.lock() = ExitStatus { *e.0.lock() = ExitStatus {
panicking: true, panicking: true,
should_exit: true, should_exit: true,
should_restart: false,
spec_name_override: None,
}; };
e.1.notify_all(); e.1.notify_all();
} }
@ -335,8 +140,6 @@ fn main_direct(force_can_restart: bool) -> i32 {
*e.0.lock() = ExitStatus { *e.0.lock() = ExitStatus {
panicking: false, panicking: false,
should_exit: true, should_exit: true,
should_restart: false,
spec_name_override: None,
}; };
e.1.notify_all(); e.1.notify_all();
} }
@ -357,17 +160,8 @@ fn main_direct(force_can_restart: bool) -> i32 {
client.shutdown(); client.shutdown();
if lock.should_restart {
if let Some(ref spec_name) = lock.spec_name_override {
set_spec_name_override(&spec_name.clone());
}
PLEASE_RESTART_EXIT_CODE
} else {
if lock.panicking { if lock.panicking {
1 return Err(1);
} else {
0
}
} }
} }
}, },
@ -378,125 +172,9 @@ fn main_direct(force_can_restart: bool) -> i32 {
handle.detach_with_msg(format!("{}", Colour::Red.paint(&err))) handle.detach_with_msg(format!("{}", Colour::Red.paint(&err)))
} }
eprintln!("{}", err); eprintln!("{}", err);
1 return Err(1);
} }
}; };
global_cleanup(); Ok(())
res
}
fn println_trace_main(s: String) {
if env::var("RUST_LOG")
.ok()
.and_then(|s| s.find("main=trace"))
.is_some()
{
println!("{}", s);
}
}
macro_rules! trace_main {
($arg:expr) => (println_trace_main($arg.into()));
($($arg:tt)*) => (println_trace_main(format!("{}", format_args!($($arg)*))));
}
fn main() {
panic_hook::set_abort();
// the user has specified to run its originally installed binary (not via `parity-updater`)
let force_direct = std::env::args().any(|arg| arg == "--force-direct");
// absolute path to the current `binary`
let exe_path = std::env::current_exe().ok();
// the binary is named `target/xx/yy`
let development = exe_path
.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);
// the binary is named `parity`
let same_name = exe_path.as_ref().map_or(false, |p| {
p.file_stem().map_or(false, |n| n == PARITY_EXECUTABLE_NAME)
});
trace_main!(
"Starting up {} (force-direct: {}, development: {}, same-name: {})",
std::env::current_exe()
.ok()
.map_or_else(|| "<unknown>".into(), |x| format!("{}", x.display())),
force_direct,
development,
same_name
);
if !force_direct && !development && same_name {
// Try to run the latest installed version of `parity`,
// Upon failure it falls back to the locally installed version of `parity`
// Everything run inside a loop, so we'll be able to restart from the child into a new version seamlessly.
loop {
// `Path` to the latest downloaded binary
let latest_exe = latest_exe_path().ok();
// `Latest´ binary exist
let have_update = latest_exe.as_ref().map_or(false, |p| p.exists());
// Canonicalized path to the current binary is not the same as to latest binary
let canonicalized_path_not_same = exe_path.as_ref().map_or(false, |exe| {
latest_exe.as_ref().map_or(false, |lexe| {
exe.canonicalize().ok() != lexe.canonicalize().ok()
})
});
// Downloaded `binary` is newer
let update_is_newer = latest_binary_is_newer(&latest_exe, &exe_path);
trace_main!(
"Starting... (have-update: {}, non-updated-current: {}, update-is-newer: {})",
have_update,
canonicalized_path_not_same,
update_is_newer
);
let exit_code = if have_update && canonicalized_path_not_same && update_is_newer {
trace_main!(
"Attempting to run latest update ({})...",
latest_exe
.as_ref()
.expect(
"guarded by have_update; latest_exe must exist for have_update; qed"
)
.display()
);
match run_parity() {
Ok(_) => 0,
// Restart parity
Err(Error::Restart) => PLEASE_RESTART_EXIT_CODE,
// Fall back to local version
Err(e) => {
error!(target: "updater", "Updated binary could not be executed error: {:?}. Falling back to local version", e);
main_direct(true)
}
}
} else {
trace_main!("No latest update. Attempting to direct...");
main_direct(true)
};
trace_main!("Latest binary exited with exit code: {}", exit_code);
if exit_code != PLEASE_RESTART_EXIT_CODE {
trace_main!("Quitting...");
process::exit(exit_code);
}
trace!(target: "updater", "Re-running updater loop");
}
} else {
trace_main!("Running direct");
// Otherwise, we're presumably running the version we want. Just run and fall-through.
process::exit(main_direct(false));
}
} }

View File

@ -22,7 +22,7 @@ use ethcore::{
spec::{Spec, SpecParams}, spec::{Spec, SpecParams},
}; };
use ethereum_types::{Address, U256}; use ethereum_types::{Address, U256};
use hash_fetch::fetch::Client as FetchClient; use fetch::Client as FetchClient;
use journaldb::Algorithm; use journaldb::Algorithm;
use miner::{ use miner::{
gas_price_calibrator::{GasPriceCalibrator, GasPriceCalibratorOptions}, gas_price_calibrator::{GasPriceCalibrator, GasPriceCalibratorOptions},

View File

@ -22,7 +22,7 @@ use account_utils::{self, AccountProvider};
use ethcore::{client::Client, miner::Miner, snapshot::SnapshotService}; use ethcore::{client::Client, miner::Miner, snapshot::SnapshotService};
use ethcore_logger::RotatingLogger; use ethcore_logger::RotatingLogger;
use ethcore_service::PrivateTxService; use ethcore_service::PrivateTxService;
use hash_fetch::fetch::Client as FetchClient; use fetch::Client as FetchClient;
use jsonrpc_core::{self as core, MetaIoHandler}; use jsonrpc_core::{self as core, MetaIoHandler};
use miner::external::ExternalMiner; use miner::external::ExternalMiner;
use parity_rpc::{ use parity_rpc::{
@ -33,7 +33,6 @@ use parity_rpc::{
use parity_runtime::Executor; use parity_runtime::Executor;
use parking_lot::Mutex; use parking_lot::Mutex;
use sync::{ManageNetwork, SyncProvider}; use sync::{ManageNetwork, SyncProvider};
use updater::Updater;
#[derive(Debug, PartialEq, Clone, Eq, Hash)] #[derive(Debug, PartialEq, Clone, Eq, Hash)]
pub enum Api { pub enum Api {
@ -198,7 +197,6 @@ pub struct FullDependencies {
pub logger: Arc<RotatingLogger>, pub logger: Arc<RotatingLogger>,
pub settings: Arc<NetworkSettings>, pub settings: Arc<NetworkSettings>,
pub net_service: Arc<dyn ManageNetwork>, pub net_service: Arc<dyn ManageNetwork>,
pub updater: Arc<Updater>,
pub experimental_rpcs: bool, pub experimental_rpcs: bool,
pub ws_address: Option<Host>, pub ws_address: Option<Host>,
pub fetch: FetchClient, pub fetch: FetchClient,
@ -326,7 +324,6 @@ impl FullDependencies {
self.client.clone(), self.client.clone(),
self.miner.clone(), self.miner.clone(),
self.sync.clone(), self.sync.clone(),
self.updater.clone(),
self.net_service.clone(), self.net_service.clone(),
self.logger.clone(), self.logger.clone(),
self.settings.clone(), self.settings.clone(),
@ -373,7 +370,6 @@ impl FullDependencies {
ParitySetClient::new( ParitySetClient::new(
&self.client, &self.client,
&self.miner, &self.miner,
&self.updater,
&self.net_service, &self.net_service,
self.fetch.clone(), self.fetch.clone(),
) )

View File

@ -23,15 +23,11 @@ use std::{
use account_utils; use account_utils;
use ansi_term::Colour; use ansi_term::Colour;
use bytes::Bytes;
use cache::CacheConfig; use cache::CacheConfig;
use call_contract::CallContract;
use db; use db;
use dir::{DatabaseDirectories, Directories}; use dir::{DatabaseDirectories, Directories};
use ethcore::{ use ethcore::{
client::{ client::{BlockChainClient, BlockInfo, Client, DatabaseCompactionProfile, Mode, VMType},
BlockChainClient, BlockId, BlockInfo, Client, DatabaseCompactionProfile, Mode, VMType,
},
miner::{self, stratum, Miner, MinerOptions, MinerService}, miner::{self, stratum, Miner, MinerOptions, MinerService},
snapshot::{self, SnapshotConfiguration}, snapshot::{self, SnapshotConfiguration},
verification::queue::VerifierSettings, verification::queue::VerifierSettings,
@ -39,9 +35,6 @@ use ethcore::{
use ethcore_logger::{Config as LogConfig, RotatingLogger}; use ethcore_logger::{Config as LogConfig, RotatingLogger};
use ethcore_private_tx::{EncryptorConfig, ProviderConfig, SecretStoreEncryptor}; use ethcore_private_tx::{EncryptorConfig, ProviderConfig, SecretStoreEncryptor};
use ethcore_service::ClientService; use ethcore_service::ClientService;
use ethereum_types::Address;
use futures::IntoFuture;
use hash_fetch::{self, fetch};
use helpers::{execute_upgrades, passwords_from_files, to_client_config}; use helpers::{execute_upgrades, passwords_from_files, to_client_config};
use informant::{FullNodeInformantData, Informant}; use informant::{FullNodeInformantData, Informant};
use ipfs; use ipfs;
@ -60,13 +53,11 @@ use parity_rpc::{
}; };
use parity_runtime::Runtime; use parity_runtime::Runtime;
use parity_version::version; use parity_version::version;
use registrar::{Asynchronous, RegistrarClient};
use rpc; use rpc;
use rpc_apis; use rpc_apis;
use secretstore; use secretstore;
use signer; use signer;
use sync::{self, PrivateTxHandler, SyncConfig}; use sync::{self, PrivateTxHandler, SyncConfig};
use updater::{UpdatePolicy, Updater};
use user_defaults::UserDefaults; use user_defaults::UserDefaults;
// how often to take periodic snapshots. // how often to take periodic snapshots.
@ -102,7 +93,6 @@ pub struct RunCmd {
pub acc_conf: AccountsConfig, pub acc_conf: AccountsConfig,
pub gas_pricer_conf: GasPricerConfig, pub gas_pricer_conf: GasPricerConfig,
pub miner_extras: MinerExtras, pub miner_extras: MinerExtras,
pub update_policy: UpdatePolicy,
pub mode: Option<Mode>, pub mode: Option<Mode>,
pub tracing: Switch, pub tracing: Switch,
pub fat_db: Switch, pub fat_db: Switch,
@ -154,22 +144,8 @@ impl ::local_store::NodeInfo for FullNodeInfo {
/// Executes the given run command. /// Executes the given run command.
/// ///
/// `on_client_rq` is the action to perform when the client receives an RPC request to be restarted
/// with a different chain.
///
/// `on_updater_rq` is the action to perform when the updater has a new binary to execute.
///
/// On error, returns what to print on stderr. /// On error, returns what to print on stderr.
pub fn execute<Cr, Rr>( pub fn execute(cmd: RunCmd, logger: Arc<RotatingLogger>) -> Result<RunningClient, String> {
cmd: RunCmd,
logger: Arc<RotatingLogger>,
on_client_rq: Cr,
on_updater_rq: Rr,
) -> Result<RunningClient, String>
where
Cr: Fn(String) + 'static + Send,
Rr: Fn() + 'static + Send,
{
// load spec // load spec
let spec = cmd.spec.spec(&cmd.dirs.cache)?; let spec = cmd.spec.spec(&cmd.dirs.cache)?;
@ -206,9 +182,6 @@ where
_ => true, _ => true,
}; };
// get the update policy
let update_policy = cmd.update_policy;
// prepare client and snapshot paths. // prepare client and snapshot paths.
let client_path = db_dirs.client_path(algorithm); let client_path = db_dirs.client_path(algorithm);
let snapshot_path = db_dirs.snapshot_path(); let snapshot_path = db_dirs.snapshot_path();
@ -523,41 +496,6 @@ where
chain_notify.start(); chain_notify.start();
} }
let contract_client = {
struct FullRegistrar {
client: Arc<Client>,
}
impl RegistrarClient for FullRegistrar {
type Call = Asynchronous;
fn registrar_address(&self) -> Result<Address, String> {
self.client
.registrar_address()
.ok_or_else(|| "Registrar not defined.".into())
}
fn call_contract(&self, address: Address, data: Bytes) -> Self::Call {
Box::new(
self.client
.call_contract(BlockId::Latest, address, data)
.into_future(),
)
}
}
Arc::new(FullRegistrar {
client: client.clone(),
})
};
// the updater service
let updater_fetch = fetch.clone();
let updater = Updater::new(
&Arc::downgrade(&(service.client() as Arc<dyn BlockChainClient>)),
&Arc::downgrade(&sync_provider),
update_policy,
hash_fetch::Client::with_fetch(contract_client.clone(), updater_fetch, runtime.executor()),
);
service.add_notify(updater.clone());
// set up dependencies for rpc servers // set up dependencies for rpc servers
let rpc_stats = Arc::new(informant::RpcStats::default()); let rpc_stats = Arc::new(informant::RpcStats::default());
let secret_store = account_provider.clone(); let secret_store = account_provider.clone();
@ -575,7 +513,6 @@ where
logger: logger.clone(), logger: logger.clone(),
settings: Arc::new(cmd.net_settings.clone()), settings: Arc::new(cmd.net_settings.clone()),
net_service: manage_network.clone(), net_service: manage_network.clone(),
updater: updater.clone(),
experimental_rpcs: cmd.experimental_rpcs, experimental_rpcs: cmd.experimental_rpcs,
ws_address: cmd.ws_conf.address(), ws_address: cmd.ws_conf.address(),
fetch: fetch.clone(), fetch: fetch.clone(),
@ -672,9 +609,6 @@ where
} }
}; };
client.set_exit_handler(on_client_rq);
updater.set_exit_handler(on_updater_rq);
Ok(RunningClient { Ok(RunningClient {
inner: RunningClientInner::Full { inner: RunningClientInner::Full {
rpc: rpc_direct, rpc: rpc_direct,
@ -683,7 +617,6 @@ where
client_service: Arc::new(service), client_service: Arc::new(service),
keep_alive: Box::new(( keep_alive: Box::new((
watcher, watcher,
updater,
ws_server, ws_server,
http_server, http_server,
ipc_server, ipc_server,

View File

@ -17,7 +17,6 @@ order-stat = "0.1"
parking_lot = "0.7" parking_lot = "0.7"
rand = "0.4" rand = "0.4"
rustc-hex = "1.0" rustc-hex = "1.0"
semver = "0.9"
serde = "1.0" serde = "1.0"
serde_derive = "1.0" serde_derive = "1.0"
serde_json = "1.0" serde_json = "1.0"
@ -54,7 +53,6 @@ ethstore = { path = "../accounts/ethstore" }
fetch = { path = "../util/fetch" } fetch = { path = "../util/fetch" }
keccak-hash = "0.1.2" keccak-hash = "0.1.2"
parity-runtime = { path = "../util/runtime" } parity-runtime = { path = "../util/runtime" }
parity-updater = { path = "../updater" }
parity-version = { path = "../util/version" } parity-version = { path = "../util/version" }
rlp = { version = "0.3.0", features = ["ethereum"] } rlp = { version = "0.3.0", features = ["ethereum"] }
stats = { path = "../util/stats" } stats = { path = "../util/stats" }

View File

@ -48,7 +48,6 @@ extern crate order_stat;
extern crate parking_lot; extern crate parking_lot;
extern crate rand; extern crate rand;
extern crate rustc_hex; extern crate rustc_hex;
extern crate semver;
extern crate serde; extern crate serde;
extern crate serde_json; extern crate serde_json;
extern crate tokio_timer; extern crate tokio_timer;
@ -77,7 +76,6 @@ extern crate keccak_hash as hash;
extern crate parity_bytes as bytes; extern crate parity_bytes as bytes;
extern crate parity_crypto as crypto; extern crate parity_crypto as crypto;
extern crate parity_runtime; extern crate parity_runtime;
extern crate parity_updater as updater;
extern crate parity_version as version; extern crate parity_version as version;
extern crate rlp; extern crate rlp;
extern crate stats; extern crate stats;

View File

@ -31,7 +31,6 @@ use ethstore::random_phrase;
use jsonrpc_core::{futures::future, BoxFuture, Result}; use jsonrpc_core::{futures::future, BoxFuture, Result};
use sync::{ManageNetwork, SyncProvider}; use sync::{ManageNetwork, SyncProvider};
use types::ids::BlockId; use types::ids::BlockId;
use updater::Service as UpdateService;
use version::version_data; use version::version_data;
use v1::{ use v1::{
@ -45,18 +44,17 @@ use v1::{
metadata::Metadata, metadata::Metadata,
traits::Parity, traits::Parity,
types::{ types::{
block_number_to_id, BlockNumber, Bytes, CallRequest, ChainStatus, ConsensusCapability, block_number_to_id, BlockNumber, Bytes, CallRequest, ChainStatus, Histogram,
Histogram, LocalTransactionStatus, OperationsInfo, Peers, Receipt, RecoveredAccount, LocalTransactionStatus, Peers, Receipt, RecoveredAccount, RichHeader, RpcSettings,
RichHeader, RpcSettings, Transaction, TransactionStats, VersionInfo, Transaction, TransactionStats,
}, },
}; };
use Host; use Host;
/// Parity implementation. /// Parity implementation.
pub struct ParityClient<C, M, U> { pub struct ParityClient<C, M> {
client: Arc<C>, client: Arc<C>,
miner: Arc<M>, miner: Arc<M>,
updater: Arc<U>,
sync: Arc<dyn SyncProvider>, sync: Arc<dyn SyncProvider>,
net: Arc<dyn ManageNetwork>, net: Arc<dyn ManageNetwork>,
logger: Arc<RotatingLogger>, logger: Arc<RotatingLogger>,
@ -66,7 +64,7 @@ pub struct ParityClient<C, M, U> {
snapshot: Option<Arc<dyn SnapshotService>>, snapshot: Option<Arc<dyn SnapshotService>>,
} }
impl<C, M, U> ParityClient<C, M, U> impl<C, M> ParityClient<C, M>
where where
C: BlockChainClient, C: BlockChainClient,
{ {
@ -75,7 +73,6 @@ where
client: Arc<C>, client: Arc<C>,
miner: Arc<M>, miner: Arc<M>,
sync: Arc<dyn SyncProvider>, sync: Arc<dyn SyncProvider>,
updater: Arc<U>,
net: Arc<dyn ManageNetwork>, net: Arc<dyn ManageNetwork>,
logger: Arc<RotatingLogger>, logger: Arc<RotatingLogger>,
settings: Arc<NetworkSettings>, settings: Arc<NetworkSettings>,
@ -87,7 +84,6 @@ where
client, client,
miner, miner,
sync, sync,
updater,
net, net,
logger, logger,
settings, settings,
@ -98,7 +94,7 @@ where
} }
} }
impl<C, M, U, S> Parity for ParityClient<C, M, U> impl<C, M, S> Parity for ParityClient<C, M>
where where
S: StateInfo + 'static, S: StateInfo + 'static,
C: miner::BlockChainClient C: miner::BlockChainClient
@ -107,7 +103,6 @@ where
+ Call<State = S> + Call<State = S>
+ 'static, + 'static,
M: MinerService<State = S> + 'static, M: MinerService<State = S> + 'static,
U: UpdateService + 'static,
{ {
type Metadata = Metadata; type Metadata = Metadata;
@ -330,18 +325,6 @@ where
self.sync.enode().ok_or_else(errors::network_disabled) self.sync.enode().ok_or_else(errors::network_disabled)
} }
fn consensus_capability(&self) -> Result<ConsensusCapability> {
Ok(self.updater.capability().into())
}
fn version_info(&self) -> Result<VersionInfo> {
Ok(self.updater.version_info().into())
}
fn releases_info(&self) -> Result<Option<OperationsInfo>> {
Ok(self.updater.info().map(Into::into))
}
fn chain_status(&self) -> Result<ChainStatus> { fn chain_status(&self) -> Result<ChainStatus> {
let chain_info = self.client.chain_info(); let chain_info = self.client.chain_info();

View File

@ -27,13 +27,12 @@ use ethkey;
use fetch::{self, Fetch}; use fetch::{self, Fetch};
use hash::keccak_buffer; use hash::keccak_buffer;
use sync::ManageNetwork; use sync::ManageNetwork;
use updater::Service as UpdateService;
use jsonrpc_core::{futures::Future, BoxFuture, Result}; use jsonrpc_core::{futures::Future, BoxFuture, Result};
use v1::{ use v1::{
helpers::errors, helpers::errors,
traits::ParitySet, traits::ParitySet,
types::{Bytes, ReleaseInfo, Transaction}, types::{Bytes, Transaction},
}; };
#[cfg(any(test, feature = "accounts"))] #[cfg(any(test, feature = "accounts"))]
@ -82,41 +81,32 @@ pub mod accounts {
} }
/// Parity-specific rpc interface for operations altering the settings. /// Parity-specific rpc interface for operations altering the settings.
pub struct ParitySetClient<C, M, U, F = fetch::Client> { pub struct ParitySetClient<C, M, F = fetch::Client> {
client: Arc<C>, client: Arc<C>,
miner: Arc<M>, miner: Arc<M>,
updater: Arc<U>,
net: Arc<dyn ManageNetwork>, net: Arc<dyn ManageNetwork>,
fetch: F, fetch: F,
} }
impl<C, M, U, F> ParitySetClient<C, M, U, F> impl<C, M, F> ParitySetClient<C, M, F>
where where
C: BlockChainClient + 'static, C: BlockChainClient + 'static,
{ {
/// Creates new `ParitySetClient` with given `Fetch`. /// Creates new `ParitySetClient` with given `Fetch`.
pub fn new( pub fn new(client: &Arc<C>, miner: &Arc<M>, net: &Arc<dyn ManageNetwork>, fetch: F) -> Self {
client: &Arc<C>,
miner: &Arc<M>,
updater: &Arc<U>,
net: &Arc<dyn ManageNetwork>,
fetch: F,
) -> Self {
ParitySetClient { ParitySetClient {
client: client.clone(), client: client.clone(),
miner: miner.clone(), miner: miner.clone(),
updater: updater.clone(),
net: net.clone(), net: net.clone(),
fetch, fetch,
} }
} }
} }
impl<C, M, U, F> ParitySet for ParitySetClient<C, M, U, F> impl<C, M, F> ParitySet for ParitySetClient<C, M, F>
where where
C: BlockChainClient + 'static, C: BlockChainClient + 'static,
M: MinerService + 'static, M: MinerService + 'static,
U: UpdateService + 'static,
F: Fetch + 'static, F: Fetch + 'static,
{ {
fn set_min_gas_price(&self, gas_price: U256) -> Result<bool> { fn set_min_gas_price(&self, gas_price: U256) -> Result<bool> {
@ -239,14 +229,6 @@ where
Box::new(future) Box::new(future)
} }
fn upgrade_ready(&self) -> Result<Option<ReleaseInfo>> {
Ok(self.updater.upgrade_ready().map(Into::into))
}
fn execute_upgrade(&self) -> Result<bool> {
Ok(self.updater.execute_upgrade())
}
fn remove_transaction(&self, hash: H256) -> Result<Option<Transaction>> { fn remove_transaction(&self, hash: H256) -> Result<Option<Transaction>> {
Ok(self Ok(self
.miner .miner

View File

@ -19,11 +19,9 @@
mod miner_service; mod miner_service;
mod snapshot_service; mod snapshot_service;
mod sync_provider; mod sync_provider;
mod update_service;
pub use self::{ pub use self::{
miner_service::TestMinerService, miner_service::TestMinerService,
snapshot_service::TestSnapshotService, snapshot_service::TestSnapshotService,
sync_provider::{Config, TestSyncProvider}, sync_provider::{Config, TestSyncProvider},
update_service::TestUpdater,
}; };

View File

@ -1,111 +0,0 @@
// Copyright 2015-2019 Parity Technologies (UK) Ltd.
// This file is part of Parity Ethereum.
// Parity Ethereum 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 Ethereum 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 Ethereum. If not, see <http://www.gnu.org/licenses/>.
//! Test implementation of fetch client.
use semver::Version;
use std::sync::atomic::{AtomicBool, AtomicUsize, Ordering};
use updater::{
CapState, OperationsInfo, ReleaseInfo, ReleaseTrack, Service as UpdateService, VersionInfo,
};
/// Test implementation of fetcher. Will always return the same file.
#[derive(Default)]
pub struct TestUpdater {
updated: AtomicBool,
current_block: AtomicUsize,
}
impl TestUpdater {
/// Update the (faked) current block.
pub fn set_current_block(&self, n: usize) {
self.current_block.store(n, Ordering::Relaxed);
}
/// Update the (faked) current block.
pub fn set_updated(&self, v: bool) {
self.updated.store(v, Ordering::Relaxed);
}
}
impl UpdateService for TestUpdater {
fn capability(&self) -> CapState {
if self.updated.load(Ordering::Relaxed) {
CapState::Capable
} else {
if self.current_block.load(Ordering::Relaxed) < 15100 {
CapState::CapableUntil(15100)
} else {
CapState::IncapableSince(15100)
}
}
}
fn upgrade_ready(&self) -> Option<ReleaseInfo> {
if self.updated.load(Ordering::Relaxed) {
None
} else {
self.info().map(|i| i.track)
}
}
fn execute_upgrade(&self) -> bool {
if self.updated.load(Ordering::Relaxed) {
false
} else {
self.updated.store(true, Ordering::Relaxed);
true
}
}
fn version_info(&self) -> VersionInfo {
VersionInfo {
track: ReleaseTrack::Beta,
version: Version {
major: 1,
minor: 5,
patch: 0,
build: vec![],
pre: vec![],
},
hash: 150.into(),
}
}
fn info(&self) -> Option<OperationsInfo> {
Some(OperationsInfo {
fork: 15100,
this_fork: Some(15000),
track: ReleaseInfo {
version: VersionInfo {
track: ReleaseTrack::Beta,
version: Version {
major: 1,
minor: 5,
patch: 1,
build: vec![],
pre: vec![],
},
hash: 151.into(),
},
is_critical: true,
fork: 15100,
binary: Some(1510.into()),
},
minor: None,
})
}
}

View File

@ -28,18 +28,17 @@ use jsonrpc_core::IoHandler;
use v1::{ use v1::{
helpers::{external_signer::SignerService, NetworkSettings}, helpers::{external_signer::SignerService, NetworkSettings},
metadata::Metadata, metadata::Metadata,
tests::helpers::{Config, TestMinerService, TestSyncProvider, TestUpdater}, tests::helpers::{Config, TestMinerService, TestSyncProvider},
Parity, ParityClient, Parity, ParityClient,
}; };
use Host; use Host;
pub type TestParityClient = ParityClient<TestBlockChainClient, TestMinerService, TestUpdater>; pub type TestParityClient = ParityClient<TestBlockChainClient, TestMinerService>;
pub struct Dependencies { pub struct Dependencies {
pub miner: Arc<TestMinerService>, pub miner: Arc<TestMinerService>,
pub client: Arc<TestBlockChainClient>, pub client: Arc<TestBlockChainClient>,
pub sync: Arc<TestSyncProvider>, pub sync: Arc<TestSyncProvider>,
pub updater: Arc<TestUpdater>,
pub logger: Arc<RotatingLogger>, pub logger: Arc<RotatingLogger>,
pub settings: Arc<NetworkSettings>, pub settings: Arc<NetworkSettings>,
pub network: Arc<dyn ManageNetwork>, pub network: Arc<dyn ManageNetwork>,
@ -55,7 +54,6 @@ impl Dependencies {
network_id: 3, network_id: 3,
num_peers: 120, num_peers: 120,
})), })),
updater: Arc::new(TestUpdater::default()),
logger: Arc::new(RotatingLogger::new("rpc=trace".to_owned())), logger: Arc::new(RotatingLogger::new("rpc=trace".to_owned())),
settings: Arc::new(NetworkSettings { settings: Arc::new(NetworkSettings {
name: "mynode".to_owned(), name: "mynode".to_owned(),
@ -76,7 +74,6 @@ impl Dependencies {
self.client.clone(), self.client.clone(),
self.miner.clone(), self.miner.clone(),
self.sync.clone(), self.sync.clone(),
self.updater.clone(),
self.network.clone(), self.network.clone(),
self.logger.clone(), self.logger.clone(),
self.settings.clone(), self.settings.clone(),
@ -99,51 +96,6 @@ impl Dependencies {
} }
} }
#[test]
fn rpc_parity_consensus_capability() {
let deps = Dependencies::new();
let io = deps.default_client();
let request =
r#"{"jsonrpc": "2.0", "method": "parity_consensusCapability", "params": [], "id": 1}"#;
let response = r#"{"jsonrpc":"2.0","result":{"capableUntil":15100},"id":1}"#;
assert_eq!(io.handle_request_sync(request), Some(response.to_owned()));
deps.updater.set_current_block(15101);
let request =
r#"{"jsonrpc": "2.0", "method": "parity_consensusCapability", "params": [], "id": 1}"#;
let response = r#"{"jsonrpc":"2.0","result":{"incapableSince":15100},"id":1}"#;
assert_eq!(io.handle_request_sync(request), Some(response.to_owned()));
deps.updater.set_updated(true);
let request =
r#"{"jsonrpc": "2.0", "method": "parity_consensusCapability", "params": [], "id": 1}"#;
let response = r#"{"jsonrpc":"2.0","result":"capable","id":1}"#;
assert_eq!(io.handle_request_sync(request), Some(response.to_owned()));
}
#[test]
fn rpc_parity_version_info() {
let deps = Dependencies::new();
let io = deps.default_client();
let request = r#"{"jsonrpc": "2.0", "method": "parity_versionInfo", "params": [], "id": 1}"#;
let response = r#"{"jsonrpc":"2.0","result":{"hash":"0x0000000000000000000000000000000000000096","track":"beta","version":{"major":1,"minor":5,"patch":0}},"id":1}"#;
assert_eq!(io.handle_request_sync(request), Some(response.to_owned()));
}
#[test]
fn rpc_parity_releases_info() {
let deps = Dependencies::new();
let io = deps.default_client();
let request = r#"{"jsonrpc": "2.0", "method": "parity_releasesInfo", "params": [], "id": 1}"#;
let response = r#"{"jsonrpc":"2.0","result":{"fork":15100,"minor":null,"this_fork":15000,"track":{"binary":"0x00000000000000000000000000000000000000000000000000000000000005e6","fork":15100,"is_critical":true,"version":{"hash":"0x0000000000000000000000000000000000000097","track":"beta","version":{"major":1,"minor":5,"patch":1}}}},"id":1}"#;
assert_eq!(io.handle_request_sync(request), Some(response.to_owned()));
}
#[test] #[test]
fn rpc_parity_extra_data() { fn rpc_parity_extra_data() {
let deps = Dependencies::new(); let deps = Dependencies::new();

View File

@ -23,10 +23,7 @@ use sync::ManageNetwork;
use super::manage_network::TestManageNetwork; use super::manage_network::TestManageNetwork;
use jsonrpc_core::IoHandler; use jsonrpc_core::IoHandler;
use v1::{ use v1::{tests::helpers::TestMinerService, ParitySet, ParitySetClient};
tests::helpers::{TestMinerService, TestUpdater},
ParitySet, ParitySetClient,
};
use fake_fetch::FakeFetch; use fake_fetch::FakeFetch;
@ -42,75 +39,30 @@ fn network_service() -> Arc<TestManageNetwork> {
Arc::new(TestManageNetwork) Arc::new(TestManageNetwork)
} }
fn updater_service() -> Arc<TestUpdater> {
Arc::new(TestUpdater::default())
}
pub type TestParitySetClient = pub type TestParitySetClient =
ParitySetClient<TestBlockChainClient, TestMinerService, TestUpdater, FakeFetch<usize>>; ParitySetClient<TestBlockChainClient, TestMinerService, FakeFetch<usize>>;
fn parity_set_client( fn parity_set_client(
client: &Arc<TestBlockChainClient>, client: &Arc<TestBlockChainClient>,
miner: &Arc<TestMinerService>, miner: &Arc<TestMinerService>,
updater: &Arc<TestUpdater>,
net: &Arc<TestManageNetwork>, net: &Arc<TestManageNetwork>,
) -> TestParitySetClient { ) -> TestParitySetClient {
ParitySetClient::new( ParitySetClient::new(
client, client,
miner, miner,
updater,
&(net.clone() as Arc<dyn ManageNetwork>), &(net.clone() as Arc<dyn ManageNetwork>),
FakeFetch::new(Some(1)), FakeFetch::new(Some(1)),
) )
} }
#[test]
fn rpc_parity_execute_upgrade() {
let miner = miner_service();
let client = client_service();
let network = network_service();
let updater = updater_service();
let mut io = IoHandler::new();
io.extend_with(parity_set_client(&client, &miner, &updater, &network).to_delegate());
let request = r#"{"jsonrpc": "2.0", "method": "parity_executeUpgrade", "params": [], "id": 1}"#;
let response = r#"{"jsonrpc":"2.0","result":true,"id":1}"#;
assert_eq!(io.handle_request_sync(request), Some(response.to_owned()));
let request = r#"{"jsonrpc": "2.0", "method": "parity_executeUpgrade", "params": [], "id": 1}"#;
let response = r#"{"jsonrpc":"2.0","result":false,"id":1}"#;
assert_eq!(io.handle_request_sync(request), Some(response.to_owned()));
}
#[test]
fn rpc_parity_upgrade_ready() {
let miner = miner_service();
let client = client_service();
let network = network_service();
let updater = updater_service();
let mut io = IoHandler::new();
io.extend_with(parity_set_client(&client, &miner, &updater, &network).to_delegate());
let request = r#"{"jsonrpc": "2.0", "method": "parity_upgradeReady", "params": [], "id": 1}"#;
let response = r#"{"jsonrpc":"2.0","result":{"binary":"0x00000000000000000000000000000000000000000000000000000000000005e6","fork":15100,"is_critical":true,"version":{"hash":"0x0000000000000000000000000000000000000097","track":"beta","version":{"major":1,"minor":5,"patch":1}}},"id":1}"#;
assert_eq!(io.handle_request_sync(request), Some(response.to_owned()));
updater.set_updated(true);
let request = r#"{"jsonrpc": "2.0", "method": "parity_upgradeReady", "params": [], "id": 1}"#;
let response = r#"{"jsonrpc":"2.0","result":null,"id":1}"#;
assert_eq!(io.handle_request_sync(request), Some(response.to_owned()));
}
#[test] #[test]
fn rpc_parity_set_min_gas_price() { fn rpc_parity_set_min_gas_price() {
let miner = miner_service(); let miner = miner_service();
let client = client_service(); let client = client_service();
let network = network_service(); let network = network_service();
let updater = updater_service();
let mut io = IoHandler::new(); let mut io = IoHandler::new();
io.extend_with(parity_set_client(&client, &miner, &updater, &network).to_delegate()); io.extend_with(parity_set_client(&client, &miner, &network).to_delegate());
let request = r#"{"jsonrpc": "2.0", "method": "parity_setMinGasPrice", "params":["0xcd1722f3947def4cf144679da39c4c32bdc35681"], "id": 1}"#; let request = r#"{"jsonrpc": "2.0", "method": "parity_setMinGasPrice", "params":["0xcd1722f3947def4cf144679da39c4c32bdc35681"], "id": 1}"#;
let response = r#"{"jsonrpc":"2.0","result":true,"id":1}"#; let response = r#"{"jsonrpc":"2.0","result":true,"id":1}"#;
@ -125,10 +77,9 @@ fn rpc_parity_set_min_gas_price_with_automated_calibration_enabled() {
let client = client_service(); let client = client_service();
let network = network_service(); let network = network_service();
let updater = updater_service();
let mut io = IoHandler::new(); let mut io = IoHandler::new();
io.extend_with(parity_set_client(&client, &miner, &updater, &network).to_delegate()); io.extend_with(parity_set_client(&client, &miner, &network).to_delegate());
let request = r#"{"jsonrpc": "2.0", "method": "parity_setMinGasPrice", "params":["0xdeadbeef"], "id": 1}"#; let request = r#"{"jsonrpc": "2.0", "method": "parity_setMinGasPrice", "params":["0xdeadbeef"], "id": 1}"#;
let response = r#"{"jsonrpc":"2.0","error":{"code":-32000,"message":"Can't update fixed gas price while automatic gas calibration is enabled."},"id":1}"#; let response = r#"{"jsonrpc":"2.0","error":{"code":-32000,"message":"Can't update fixed gas price while automatic gas calibration is enabled."},"id":1}"#;
@ -141,10 +92,9 @@ fn rpc_parity_set_gas_floor_target() {
let miner = miner_service(); let miner = miner_service();
let client = client_service(); let client = client_service();
let network = network_service(); let network = network_service();
let updater = updater_service();
let mut io = IoHandler::new(); let mut io = IoHandler::new();
io.extend_with(parity_set_client(&client, &miner, &updater, &network).to_delegate()); io.extend_with(parity_set_client(&client, &miner, &network).to_delegate());
let request = r#"{"jsonrpc": "2.0", "method": "parity_setGasFloorTarget", "params":["0xcd1722f3947def4cf144679da39c4c32bdc35681"], "id": 1}"#; let request = r#"{"jsonrpc": "2.0", "method": "parity_setGasFloorTarget", "params":["0xcd1722f3947def4cf144679da39c4c32bdc35681"], "id": 1}"#;
let response = r#"{"jsonrpc":"2.0","result":true,"id":1}"#; let response = r#"{"jsonrpc":"2.0","result":true,"id":1}"#;
@ -161,10 +111,9 @@ fn rpc_parity_set_extra_data() {
let miner = miner_service(); let miner = miner_service();
let client = client_service(); let client = client_service();
let network = network_service(); let network = network_service();
let updater = updater_service();
let mut io = IoHandler::new(); let mut io = IoHandler::new();
io.extend_with(parity_set_client(&client, &miner, &updater, &network).to_delegate()); io.extend_with(parity_set_client(&client, &miner, &network).to_delegate());
let request = r#"{"jsonrpc": "2.0", "method": "parity_setExtraData", "params":["0xcd1722f3947def4cf144679da39c4c32bdc35681"], "id": 1}"#; let request = r#"{"jsonrpc": "2.0", "method": "parity_setExtraData", "params":["0xcd1722f3947def4cf144679da39c4c32bdc35681"], "id": 1}"#;
let response = r#"{"jsonrpc":"2.0","result":true,"id":1}"#; let response = r#"{"jsonrpc":"2.0","result":true,"id":1}"#;
@ -183,9 +132,9 @@ fn rpc_parity_set_author() {
let miner = miner_service(); let miner = miner_service();
let client = client_service(); let client = client_service();
let network = network_service(); let network = network_service();
let updater = updater_service();
let mut io = IoHandler::new(); let mut io = IoHandler::new();
io.extend_with(parity_set_client(&client, &miner, &updater, &network).to_delegate()); io.extend_with(parity_set_client(&client, &miner, &network).to_delegate());
let request = r#"{"jsonrpc": "2.0", "method": "parity_setAuthor", "params":["0xcd1722f3947def4cf144679da39c4c32bdc35681"], "id": 1}"#; let request = r#"{"jsonrpc": "2.0", "method": "parity_setAuthor", "params":["0xcd1722f3947def4cf144679da39c4c32bdc35681"], "id": 1}"#;
let response = r#"{"jsonrpc":"2.0","result":true,"id":1}"#; let response = r#"{"jsonrpc":"2.0","result":true,"id":1}"#;
@ -202,9 +151,9 @@ fn rpc_parity_set_transactions_limit() {
let miner = miner_service(); let miner = miner_service();
let client = client_service(); let client = client_service();
let network = network_service(); let network = network_service();
let updater = updater_service();
let mut io = IoHandler::new(); let mut io = IoHandler::new();
io.extend_with(parity_set_client(&client, &miner, &updater, &network).to_delegate()); io.extend_with(parity_set_client(&client, &miner, &network).to_delegate());
let request = r#"{"jsonrpc": "2.0", "method": "parity_setTransactionsLimit", "params":[10240240], "id": 1}"#; let request = r#"{"jsonrpc": "2.0", "method": "parity_setTransactionsLimit", "params":[10240240], "id": 1}"#;
let response = r#"{"jsonrpc":"2.0","result":false,"id":1}"#; let response = r#"{"jsonrpc":"2.0","result":false,"id":1}"#;
@ -217,9 +166,9 @@ fn rpc_parity_set_hash_content() {
let miner = miner_service(); let miner = miner_service();
let client = client_service(); let client = client_service();
let network = network_service(); let network = network_service();
let updater = updater_service();
let mut io = IoHandler::new(); let mut io = IoHandler::new();
io.extend_with(parity_set_client(&client, &miner, &updater, &network).to_delegate()); io.extend_with(parity_set_client(&client, &miner, &network).to_delegate());
let request = r#"{"jsonrpc": "2.0", "method": "parity_hashContent", "params":["https://parity.io/assets/images/ethcore-black-horizontal.png"], "id": 1}"#; let request = r#"{"jsonrpc": "2.0", "method": "parity_hashContent", "params":["https://parity.io/assets/images/ethcore-black-horizontal.png"], "id": 1}"#;
let response = r#"{"jsonrpc":"2.0","result":"0x2be00befcf008bc0e7d9cdefc194db9c75352e8632f48498b5a6bfce9f02c88e","id":1}"#; let response = r#"{"jsonrpc":"2.0","result":"0x2be00befcf008bc0e7d9cdefc194db9c75352e8632f48498b5a6bfce9f02c88e","id":1}"#;
@ -234,9 +183,9 @@ fn rpc_parity_remove_transaction() {
let miner = miner_service(); let miner = miner_service();
let client = client_service(); let client = client_service();
let network = network_service(); let network = network_service();
let updater = updater_service();
let mut io = IoHandler::new(); let mut io = IoHandler::new();
io.extend_with(parity_set_client(&client, &miner, &updater, &network).to_delegate()); io.extend_with(parity_set_client(&client, &miner, &network).to_delegate());
let tx = Transaction { let tx = Transaction {
nonce: 1.into(), nonce: 1.into(),

View File

@ -22,9 +22,8 @@ use ethereum_types::{H160, H256, H512, H64, U256, U64};
use jsonrpc_core::{BoxFuture, Result}; use jsonrpc_core::{BoxFuture, Result};
use jsonrpc_derive::rpc; use jsonrpc_derive::rpc;
use v1::types::{ use v1::types::{
BlockNumber, Bytes, CallRequest, ChainStatus, ConsensusCapability, Histogram, BlockNumber, Bytes, CallRequest, ChainStatus, Histogram, LocalTransactionStatus, Peers,
LocalTransactionStatus, OperationsInfo, Peers, Receipt, RecoveredAccount, RichHeader, Receipt, RecoveredAccount, RichHeader, RpcSettings, Transaction, TransactionStats,
RpcSettings, Transaction, TransactionStats, VersionInfo,
}; };
/// Parity-specific rpc interface. /// Parity-specific rpc interface.
@ -177,18 +176,6 @@ pub trait Parity {
#[rpc(name = "parity_enode")] #[rpc(name = "parity_enode")]
fn enode(&self) -> Result<String>; fn enode(&self) -> Result<String>;
/// Returns information on current consensus capability.
#[rpc(name = "parity_consensusCapability")]
fn consensus_capability(&self) -> Result<ConsensusCapability>;
/// Get our version information in a nice object.
#[rpc(name = "parity_versionInfo")]
fn version_info(&self) -> Result<VersionInfo>;
/// Get information concerning the latest releases if available.
#[rpc(name = "parity_releasesInfo")]
fn releases_info(&self) -> Result<Option<OperationsInfo>>;
/// Get the current chain status. /// Get the current chain status.
#[rpc(name = "parity_chainStatus")] #[rpc(name = "parity_chainStatus")]
fn chain_status(&self) -> Result<ChainStatus>; fn chain_status(&self) -> Result<ChainStatus>;

View File

@ -20,7 +20,7 @@ use ethereum_types::{H160, H256, U256};
use jsonrpc_core::{BoxFuture, Result}; use jsonrpc_core::{BoxFuture, Result};
use jsonrpc_derive::rpc; use jsonrpc_derive::rpc;
use v1::types::{Bytes, ReleaseInfo, Transaction}; use v1::types::{Bytes, Transaction};
/// Parity-specific rpc interface for operations altering the account-related settings. /// Parity-specific rpc interface for operations altering the account-related settings.
#[rpc(server)] #[rpc(server)]
@ -105,14 +105,6 @@ pub trait ParitySet {
#[rpc(name = "parity_hashContent")] #[rpc(name = "parity_hashContent")]
fn hash_content(&self, _: String) -> BoxFuture<H256>; fn hash_content(&self, _: String) -> BoxFuture<H256>;
/// Is there a release ready for install?
#[rpc(name = "parity_upgradeReady")]
fn upgrade_ready(&self) -> Result<Option<ReleaseInfo>>;
/// Execute a release which is ready according to upgrade_ready().
#[rpc(name = "parity_executeUpgrade")]
fn execute_upgrade(&self) -> Result<bool>;
/// Removes transaction from transaction queue. /// Removes transaction from transaction queue.
/// Makes sense only for transactions that were not propagated to other peers yet /// Makes sense only for transactions that were not propagated to other peers yet
/// like scheduled transactions or transactions in future. /// like scheduled transactions or transactions in future.

View File

@ -1,163 +0,0 @@
// Copyright 2015-2019 Parity Technologies (UK) Ltd.
// This file is part of Parity Ethereum.
// Parity Ethereum 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 Ethereum 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 Ethereum. If not, see <http://www.gnu.org/licenses/>.
use ethereum_types::{H160, H256};
use semver;
use updater::{self, CapState};
/// Capability info
#[derive(Debug, PartialEq, Serialize)]
#[serde(rename_all = "camelCase")]
pub enum ConsensusCapability {
/// 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 Into<ConsensusCapability> for CapState {
fn into(self) -> ConsensusCapability {
match self {
CapState::Unknown => ConsensusCapability::Unknown,
CapState::Capable => ConsensusCapability::Capable,
CapState::CapableUntil(n) => ConsensusCapability::CapableUntil(n),
CapState::IncapableSince(n) => ConsensusCapability::IncapableSince(n),
}
}
}
/// A release's track.
#[derive(Debug, PartialEq, Serialize)]
#[serde(rename_all = "camelCase")]
pub enum ReleaseTrack {
/// Stable track.
Stable,
/// Beta track.
Beta,
/// Nightly track.
Nightly,
/// Testing track.
Testing,
/// No known track.
#[serde(rename = "null")]
Unknown,
}
impl Into<ReleaseTrack> for updater::ReleaseTrack {
fn into(self) -> ReleaseTrack {
match self {
updater::ReleaseTrack::Stable => ReleaseTrack::Stable,
updater::ReleaseTrack::Beta => ReleaseTrack::Beta,
updater::ReleaseTrack::Nightly => ReleaseTrack::Nightly,
updater::ReleaseTrack::Testing => ReleaseTrack::Testing,
updater::ReleaseTrack::Unknown => ReleaseTrack::Unknown,
}
}
}
/// Semantic version.
#[derive(Debug, PartialEq, Serialize)]
pub struct Version {
/// Major part.
major: u64,
/// Minor part.
minor: u64,
/// Patch part.
patch: u64,
}
impl Into<Version> for semver::Version {
fn into(self) -> Version {
Version {
major: self.major,
minor: self.minor,
patch: self.patch,
}
}
}
/// Version information of a particular release.
#[derive(Debug, PartialEq, Serialize)]
pub struct VersionInfo {
/// The track on which it was released.
pub track: ReleaseTrack,
/// The version.
pub version: Version,
/// The (SHA1?) 160-bit hash of this build's code base.
pub hash: H160,
}
impl Into<VersionInfo> for updater::VersionInfo {
fn into(self) -> VersionInfo {
VersionInfo {
track: self.track.into(),
version: self.version.into(),
hash: self.hash,
}
}
}
/// Information regarding a particular release of Parity
#[derive(Debug, PartialEq, Serialize)]
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<H256>,
}
impl Into<ReleaseInfo> for updater::ReleaseInfo {
fn into(self) -> ReleaseInfo {
ReleaseInfo {
version: self.version.into(),
is_critical: self.is_critical,
fork: self.fork,
binary: self.binary.map(Into::into),
}
}
}
/// Information on our operations environment.
#[derive(Debug, PartialEq, Serialize)]
pub struct OperationsInfo {
/// Our blockchain's latest fork.
pub fork: u64,
/// Last fork our client supports, if known.
pub this_fork: Option<u64>,
/// Information on our track's latest release.
pub track: ReleaseInfo,
/// Information on our minor version's latest release.
pub minor: Option<ReleaseInfo>,
}
impl Into<OperationsInfo> for updater::OperationsInfo {
fn into(self) -> OperationsInfo {
OperationsInfo {
fork: self.fork,
this_fork: self.this_fork,
track: self.track.into(),
minor: self.minor.map(Into::into),
}
}
}

View File

@ -25,7 +25,6 @@ mod block_number;
mod bytes; mod bytes;
mod call_request; mod call_request;
mod confirmations; mod confirmations;
mod consensus_status;
mod derivation; mod derivation;
mod eip191; mod eip191;
mod filter; mod filter;
@ -59,7 +58,6 @@ pub use self::{
ConfirmationResponseWithToken, DecryptRequest, EIP191SignRequest, Either, EthSignRequest, ConfirmationResponseWithToken, DecryptRequest, EIP191SignRequest, Either, EthSignRequest,
TransactionModification, TransactionModification,
}, },
consensus_status::*,
derivation::{Derive, DeriveHash, DeriveHierarchical}, derivation::{Derive, DeriveHash, DeriveHierarchical},
eip191::{EIP191Version, PresignedTransaction}, eip191::{EIP191Version, PresignedTransaction},
filter::{Filter, FilterChanges}, filter::{Filter, FilterChanges},

View File

@ -1,37 +0,0 @@
[package]
description = "Parity Updater Service."
name = "parity-updater"
version = "1.12.0"
license = "GPL-3.0"
authors = ["Parity Technologies <admin@parity.io>"]
[dependencies]
common-types = { path = "../ethcore/types" }
ethabi = "6.0"
ethabi-contract = "6.0"
ethabi-derive = "6.0"
ethcore = { path = "../ethcore" }
ethcore-sync = { path = "../ethcore/sync" }
ethereum-types = "0.4"
keccak-hash = "0.1"
lazy_static = "1.0"
log = "0.4"
parity-bytes = "0.1"
parity-hash-fetch = { path = "hash-fetch" }
parity-path = "0.1"
parity-version = { path = "../util/version" }
parking_lot = "0.7"
rand = "0.4"
semver = "0.9"
target_info = "0.1"
[dev-dependencies]
ethcore = { path = "../ethcore", features = ["test-helpers"] }
tempdir = "0.3"
matches = "0.1"
[features]
# hardcode version number 1.3.7 of parity to force an update
# in order to manually test that parity fall-over to the local version
# in case of invalid or deprecated command line arguments are entered
test-updater = []

View File

@ -1,29 +0,0 @@
[package]
description = "Fetching hash-addressed content."
homepage = "http://parity.io"
license = "GPL-3.0"
name = "parity-hash-fetch"
version = "1.12.0"
authors = ["Parity Technologies <admin@parity.io>"]
[dependencies]
futures = "0.1"
log = "0.4"
mime = "0.3"
mime_guess = "2.0.0-alpha.2"
rand = "0.4"
rustc-hex = "1.0"
fetch = { path = "../../util/fetch" }
parity-bytes = "0.1"
ethereum-types = "0.4"
parity-runtime = { path = "../../util/runtime" }
keccak-hash = "0.1"
registrar = { path = "../../util/registrar" }
ethabi = "6.0"
ethabi-derive = "6.0"
ethabi-contract = "6.0"
[dev-dependencies]
parking_lot = "0.7"
fake-fetch = { path = "../../util/fake-fetch" }

View File

@ -1,6 +0,0 @@
[
{"constant":false,"inputs":[{"name":"_content","type":"bytes32"},{"name":"_url","type":"string"}],"name":"hintURL","outputs":[],"type":"function"},
{"constant":false,"inputs":[{"name":"_content","type":"bytes32"},{"name":"_accountSlashRepo","type":"string"},{"name":"_commit","type":"bytes20"}],"name":"hint","outputs":[],"type":"function"},
{"constant":true,"inputs":[{"name":"","type":"bytes32"}],"name":"entries","outputs":[{"name":"accountSlashRepo","type":"string"},{"name":"commit","type":"bytes20"},{"name":"owner","type":"address"}],"type":"function"},
{"constant":false,"inputs":[{"name":"_content","type":"bytes32"}],"name":"unhint","outputs":[],"type":"function"}
]

View File

@ -1,327 +0,0 @@
// Copyright 2015-2019 Parity Technologies (UK) Ltd.
// This file is part of Parity Ethereum.
// Parity Ethereum 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 Ethereum 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 Ethereum. If not, see <http://www.gnu.org/licenses/>.
//! Hash-addressed content resolver & fetcher.
use std::{fs, io, io::Write, path::PathBuf, sync::Arc};
use ethereum_types::H256;
use fetch::{self, Fetch};
use futures::{Future, IntoFuture};
use hash::keccak_buffer;
use parity_runtime::Executor;
use registrar::{Asynchronous, RegistrarClient};
use urlhint::{URLHint, URLHintContract, URLHintResult};
/// API for fetching by hash.
pub trait HashFetch: Send + Sync + 'static {
/// Fetch hash-addressed content.
/// Parameters:
/// 1. `hash` - content hash
/// 2. `on_done` - callback function invoked when the content is ready (or there was error during fetch)
///
/// This function may fail immediately when fetch cannot be initialized or content cannot be resolved.
fn fetch(
&self,
hash: H256,
abort: fetch::Abort,
on_done: Box<dyn Fn(Result<PathBuf, Error>) + Send>,
);
}
/// Hash-fetching error.
#[derive(Debug)]
pub enum Error {
/// Hash could not be resolved to a valid content address.
NoResolution,
/// Downloaded content hash does not match.
HashMismatch {
/// Expected hash
expected: H256,
/// Computed hash
got: H256,
},
/// Server didn't respond with OK status.
InvalidStatus,
/// IO Error while validating hash.
IO(io::Error),
/// Error during fetch.
Fetch(fetch::Error),
}
#[cfg(test)]
impl PartialEq for Error {
fn eq(&self, other: &Self) -> bool {
use Error::*;
match (self, other) {
(
&HashMismatch { expected, got },
&HashMismatch {
expected: e,
got: g,
},
) => expected == e && got == g,
(&NoResolution, &NoResolution) => true,
(&InvalidStatus, &InvalidStatus) => true,
(&IO(_), &IO(_)) => true,
(&Fetch(_), &Fetch(_)) => true,
_ => false,
}
}
}
impl From<fetch::Error> for Error {
fn from(error: fetch::Error) -> Self {
Error::Fetch(error)
}
}
impl From<io::Error> for Error {
fn from(error: io::Error) -> Self {
Error::IO(error)
}
}
fn validate_hash(path: PathBuf, hash: H256, body: fetch::BodyReader) -> Result<PathBuf, Error> {
// Read the response
let mut reader = io::BufReader::new(body);
let mut writer = io::BufWriter::new(fs::File::create(&path)?);
io::copy(&mut reader, &mut writer)?;
writer.flush()?;
// And validate the hash
let mut file_reader = io::BufReader::new(fs::File::open(&path)?);
let content_hash = keccak_buffer(&mut file_reader)?;
if content_hash != hash {
Err(Error::HashMismatch {
got: content_hash,
expected: hash,
})
} else {
Ok(path)
}
}
/// Default Hash-fetching client using on-chain contract to resolve hashes to URLs.
pub struct Client<F: Fetch + 'static = fetch::Client> {
contract: URLHintContract,
fetch: F,
executor: Executor,
random_path: Arc<dyn Fn() -> PathBuf + Sync + Send>,
}
impl<F: Fetch + 'static> Client<F> {
/// Creates new instance of the `Client` given on-chain contract client, fetch service and task runner.
pub fn with_fetch(
contract: Arc<dyn RegistrarClient<Call = Asynchronous>>,
fetch: F,
executor: Executor,
) -> Self {
Client {
contract: URLHintContract::new(contract),
fetch: fetch,
executor: executor,
random_path: Arc::new(random_temp_path),
}
}
}
impl<F: Fetch + 'static> HashFetch for Client<F> {
fn fetch(
&self,
hash: H256,
abort: fetch::Abort,
on_done: Box<dyn Fn(Result<PathBuf, Error>) + Send>,
) {
debug!(target: "fetch", "Fetching: {:?}", hash);
let random_path = self.random_path.clone();
let remote_fetch = self.fetch.clone();
let future = self
.contract
.resolve(hash)
.map_err(|e| {
warn!("Error resolving URL: {}", e);
Error::NoResolution
})
.and_then(|maybe_url| maybe_url.ok_or(Error::NoResolution))
.map(|content| match content {
URLHintResult::Dapp(dapp) => dapp.url(),
URLHintResult::GithubDapp(content) => content.url,
URLHintResult::Content(content) => content.url,
})
.into_future()
.and_then(move |url| {
debug!(target: "fetch", "Resolved {:?} to {:?}. Fetching...", hash, url);
remote_fetch.get(&url, abort).from_err()
})
.and_then(move |response| {
if !response.is_success() {
Err(Error::InvalidStatus)
} else {
Ok(response)
}
})
.and_then(move |response| {
debug!(target: "fetch", "Content fetched, validating hash ({:?})", hash);
let path = random_path();
let res = validate_hash(path.clone(), hash, fetch::BodyReader::new(response));
if let Err(ref err) = res {
trace!(target: "fetch", "Error: {:?}", err);
// Remove temporary file in case of error
let _ = fs::remove_file(&path);
}
res
})
.then(move |res| {
on_done(res);
Ok(()) as Result<(), ()>
});
self.executor.spawn(future);
}
}
fn random_temp_path() -> PathBuf {
use rand::Rng;
use std::env;
let mut rng = ::rand::OsRng::new().expect("Reliable random source is required to work.");
let file: String = rng.gen_ascii_chars().take(12).collect();
let mut path = env::temp_dir();
path.push(file);
path
}
#[cfg(test)]
mod tests {
use super::{random_temp_path, Client, Error, HashFetch};
use fake_fetch::FakeFetch;
use parity_runtime::Executor;
use parking_lot::Mutex;
use rustc_hex::FromHex;
use std::sync::{mpsc, Arc};
use urlhint::tests::{FakeRegistrar, URLHINT};
fn registrar() -> FakeRegistrar {
let mut registrar = FakeRegistrar::new();
registrar.responses = Mutex::new(vec![
Ok(format!("000000000000000000000000{}", URLHINT).from_hex().unwrap()),
Ok("00000000000000000000000000000000000000000000000000000000000000600000000000000000000000000000000000000000000000000000000000000000000000000000000000000000deadcafebeefbeefcafedeaddeedfeedffffffff000000000000000000000000000000000000000000000000000000000000003c68747470733a2f2f7061726974792e696f2f6173736574732f696d616765732f657468636f72652d626c61636b2d686f72697a6f6e74616c2e706e6700000000".from_hex().unwrap()),
]);
registrar
}
#[test]
fn should_return_error_if_hash_not_found() {
// given
let contract = Arc::new(FakeRegistrar::new());
let fetch = FakeFetch::new(None::<usize>);
let client = Client::with_fetch(contract.clone(), fetch, Executor::new_sync());
// when
let (tx, rx) = mpsc::channel();
client.fetch(
2.into(),
Default::default(),
Box::new(move |result| {
tx.send(result).unwrap();
}),
);
// then
let result = rx.recv().unwrap();
assert_eq!(result.unwrap_err(), Error::NoResolution);
}
#[test]
fn should_return_error_if_response_is_not_successful() {
// given
let registrar = Arc::new(registrar());
let fetch = FakeFetch::new(None::<usize>);
let client = Client::with_fetch(registrar.clone(), fetch, Executor::new_sync());
// when
let (tx, rx) = mpsc::channel();
client.fetch(
2.into(),
Default::default(),
Box::new(move |result| {
tx.send(result).unwrap();
}),
);
// then
let result = rx.recv().unwrap();
assert_eq!(result.unwrap_err(), Error::InvalidStatus);
}
#[test]
fn should_return_hash_mismatch() {
// given
let registrar = Arc::new(registrar());
let fetch = FakeFetch::new(Some(1));
let mut client = Client::with_fetch(registrar.clone(), fetch, Executor::new_sync());
let path = random_temp_path();
let path2 = path.clone();
client.random_path = Arc::new(move || path2.clone());
// when
let (tx, rx) = mpsc::channel();
client.fetch(
2.into(),
Default::default(),
Box::new(move |result| {
tx.send(result).unwrap();
}),
);
// then
let result = rx.recv().unwrap();
let hash = "0x2be00befcf008bc0e7d9cdefc194db9c75352e8632f48498b5a6bfce9f02c88e".into();
assert_eq!(
result.unwrap_err(),
Error::HashMismatch {
expected: 2.into(),
got: hash
}
);
assert!(!path.exists(), "Temporary file should be removed.");
}
#[test]
fn should_return_path_if_hash_matches() {
// given
let registrar = Arc::new(registrar());
let fetch = FakeFetch::new(Some(1));
let client = Client::with_fetch(registrar.clone(), fetch, Executor::new_sync());
// when
let (tx, rx) = mpsc::channel();
client.fetch(
"0x2be00befcf008bc0e7d9cdefc194db9c75352e8632f48498b5a6bfce9f02c88e".into(),
Default::default(),
Box::new(move |result| {
tx.send(result).unwrap();
}),
);
// then
let result = rx.recv().unwrap();
assert!(result.is_ok(), "Should return path, got: {:?}", result);
}
}

View File

@ -1,52 +0,0 @@
// Copyright 2015-2019 Parity Technologies (UK) Ltd.
// This file is part of Parity Ethereum.
// Parity Ethereum 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 Ethereum 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 Ethereum. If not, see <http://www.gnu.org/licenses/>.
//! Hash-addressed content resolver & fetcher.
#![warn(missing_docs)]
#[macro_use]
extern crate log;
extern crate ethabi;
extern crate ethereum_types;
extern crate futures;
extern crate keccak_hash as hash;
extern crate mime;
extern crate mime_guess;
extern crate parity_bytes as bytes;
extern crate parity_runtime;
extern crate rand;
extern crate registrar;
extern crate rustc_hex;
pub extern crate fetch;
#[macro_use]
extern crate ethabi_derive;
#[macro_use]
extern crate ethabi_contract;
#[cfg(test)]
extern crate fake_fetch;
#[cfg(test)]
extern crate parking_lot;
mod client;
pub mod urlhint;
pub use client::{Client, Error, HashFetch};
pub use fetch::Abort;

View File

@ -1,395 +0,0 @@
// Copyright 2015-2019 Parity Technologies (UK) Ltd.
// This file is part of Parity Ethereum.
// Parity Ethereum 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 Ethereum 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 Ethereum. If not, see <http://www.gnu.org/licenses/>.
//! URLHint Contract
use mime::{self, Mime};
use mime_guess;
use rustc_hex::ToHex;
use std::sync::Arc;
use ethereum_types::{Address, H256};
use futures::{future, future::Either, Future};
use registrar::{Asynchronous, Registrar, RegistrarClient};
use_contract!(urlhint, "res/urlhint.json");
const COMMIT_LEN: usize = 20;
const GITHUB_HINT: &'static str = "githubhint";
/// GithubHint entries with commit set as `0x0..01` should be treated
/// as Github Dapp, downloadable zip files, than can be extracted, containing
/// the manifest.json file along with the dapp
static GITHUB_DAPP_COMMIT: &[u8; COMMIT_LEN] =
&[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1];
/// Github-hosted dapp.
#[derive(Debug, PartialEq)]
pub struct GithubApp {
/// Github Account
pub account: String,
/// Github Repository
pub repo: String,
/// Commit on Github
pub commit: [u8; COMMIT_LEN],
/// Dapp owner address
pub owner: Address,
}
impl GithubApp {
/// Returns URL of this Github-hosted dapp package.
pub fn url(&self) -> String {
// Since https fetcher doesn't support redirections we use direct link
// format!("https://github.com/{}/{}/archive/{}.zip", self.account, self.repo, self.commit.to_hex())
format!(
"https://codeload.github.com/{}/{}/zip/{}",
self.account,
self.repo,
self.commit.to_hex()
)
}
fn commit(bytes: &[u8]) -> Option<[u8; COMMIT_LEN]> {
if bytes.len() < COMMIT_LEN {
return None;
}
let mut commit = [0; COMMIT_LEN];
for i in 0..COMMIT_LEN {
commit[i] = bytes[i];
}
Some(commit)
}
}
/// Hash-Addressed Content
#[derive(Debug, PartialEq)]
pub struct Content {
/// URL of the content
pub url: String,
/// MIME type of the content
pub mime: Mime,
/// Content owner address
pub owner: Address,
}
/// Result of resolving id to URL
#[derive(Debug, PartialEq)]
pub enum URLHintResult {
/// Dapp
Dapp(GithubApp),
/// GithubDapp
GithubDapp(Content),
/// Content
Content(Content),
}
/// URLHint Contract interface
pub trait URLHint: Send + Sync {
/// Resolves given id to registrar entry.
fn resolve(
&self,
id: H256,
) -> Box<dyn Future<Item = Option<URLHintResult>, Error = String> + Send>;
}
/// `URLHintContract` API
pub struct URLHintContract {
registrar: Registrar,
client: Arc<dyn RegistrarClient<Call = Asynchronous>>,
}
impl URLHintContract {
/// Creates new `URLHintContract`
pub fn new(client: Arc<dyn RegistrarClient<Call = Asynchronous>>) -> Self {
URLHintContract {
registrar: Registrar::new(client.clone()),
client: client,
}
}
}
fn get_urlhint_content(account_slash_repo: String, owner: Address) -> Content {
let mime = guess_mime_type(&account_slash_repo).unwrap_or(mime::APPLICATION_JSON);
Content {
url: account_slash_repo,
mime,
owner,
}
}
fn decode_urlhint_output(output: (String, [u8; 20], Address)) -> Option<URLHintResult> {
let (account_slash_repo, commit, owner) = output;
if owner == Address::default() {
return None;
}
let commit = GithubApp::commit(&commit);
if commit == Some(Default::default()) {
let content = get_urlhint_content(account_slash_repo, owner);
return Some(URLHintResult::Content(content));
}
if commit == Some(*GITHUB_DAPP_COMMIT) {
let content = get_urlhint_content(account_slash_repo, owner);
return Some(URLHintResult::GithubDapp(content));
}
let (account, repo) = {
let mut it = account_slash_repo.split('/');
match (it.next(), it.next()) {
(Some(account), Some(repo)) => (account.into(), repo.into()),
_ => return None,
}
};
commit.map(|commit| {
URLHintResult::Dapp(GithubApp {
account: account,
repo: repo,
commit: commit,
owner: owner,
})
})
}
impl URLHint for URLHintContract {
fn resolve(
&self,
id: H256,
) -> Box<dyn Future<Item = Option<URLHintResult>, Error = String> + Send> {
let client = self.client.clone();
let future = self
.registrar
.get_address(GITHUB_HINT)
.and_then(move |addr| {
if !addr.is_zero() {
let data = urlhint::functions::entries::encode_input(id);
let result = client
.call_contract(addr, data)
.and_then(move |output| {
urlhint::functions::entries::decode_output(&output)
.map_err(|e| e.to_string())
})
.map(decode_urlhint_output);
Either::B(result)
} else {
Either::A(future::ok(None))
}
});
Box::new(future)
}
}
fn guess_mime_type(url: &str) -> Option<Mime> {
const CONTENT_TYPE: &'static str = "content-type=";
let mut it = url.split('#');
// skip url
let url = it.next();
// get meta headers
let metas = it.next();
if let Some(metas) = metas {
for meta in metas.split('&') {
let meta = meta.to_lowercase();
if meta.starts_with(CONTENT_TYPE) {
return meta[CONTENT_TYPE.len()..].parse().ok();
}
}
}
url.and_then(|url| url.split('.').last())
.and_then(|extension| mime_guess::from_ext(extension).first())
}
#[cfg(test)]
pub mod tests {
use rustc_hex::FromHex;
use std::{str::FromStr, sync::Arc};
use futures::{Future, IntoFuture};
use super::{guess_mime_type, *};
use bytes::{Bytes, ToPretty};
use ethereum_types::Address;
use parking_lot::Mutex;
pub struct FakeRegistrar {
pub calls: Arc<Mutex<Vec<(String, String)>>>,
pub responses: Mutex<Vec<Result<Bytes, String>>>,
}
pub const REGISTRAR: &'static str = "8e4e9b13d4b45cb0befc93c3061b1408f67316b2";
pub const URLHINT: &'static str = "deadbeefcafe0000000000000000000000000000";
impl FakeRegistrar {
pub fn new() -> Self {
FakeRegistrar {
calls: Arc::new(Mutex::new(Vec::new())),
responses: Mutex::new(vec![
Ok(format!("000000000000000000000000{}", URLHINT)
.from_hex()
.unwrap()),
Ok(Vec::new()),
]),
}
}
}
impl RegistrarClient for FakeRegistrar {
type Call = Asynchronous;
fn registrar_address(&self) -> Result<Address, String> {
Ok(REGISTRAR.parse().unwrap())
}
fn call_contract(&self, address: Address, data: Bytes) -> Self::Call {
self.calls.lock().push((address.to_hex(), data.to_hex()));
let res = self.responses.lock().remove(0);
Box::new(res.into_future())
}
}
#[test]
fn should_call_registrar_and_urlhint_contracts() {
// given
let registrar = FakeRegistrar::new();
let resolve_result = {
use ethabi::{encode, Token};
encode(&[
Token::String(String::new()),
Token::FixedBytes(vec![0; 20]),
Token::Address([0; 20].into()),
])
};
registrar.responses.lock()[1] = Ok(resolve_result);
let calls = registrar.calls.clone();
let urlhint = URLHintContract::new(Arc::new(registrar));
// when
let res = urlhint.resolve("test".as_bytes().into()).wait().unwrap();
let calls = calls.lock();
let call0 = calls.get(0).expect("Registrar resolve called");
let call1 = calls.get(1).expect("URLHint Resolve called");
// then
assert!(res.is_none());
assert_eq!(call0.0, REGISTRAR);
assert_eq!(call0.1,
"6795dbcd058740ee9a5a3fb9f1cfa10752baec87e09cc45cd7027fd54708271aca300c75000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000014100000000000000000000000000000000000000000000000000000000000000".to_owned()
);
assert_eq!(call1.0, URLHINT);
assert_eq!(
call1.1,
"267b69227465737400000000000000000000000000000000000000000000000000000000".to_owned()
);
}
#[test]
fn should_decode_urlhint_output() {
// given
let mut registrar = FakeRegistrar::new();
registrar.responses = Mutex::new(vec![
Ok(format!("000000000000000000000000{}", URLHINT).from_hex().unwrap()),
Ok("0000000000000000000000000000000000000000000000000000000000000060ec4c1fe06c808fe3739858c347109b1f5f1ed4b5000000000000000000000000000000000000000000000000deadcafebeefbeefcafedeaddeedfeedffffffff0000000000000000000000000000000000000000000000000000000000000011657468636f72652f64616f2e636c61696d000000000000000000000000000000".from_hex().unwrap()),
]);
let urlhint = URLHintContract::new(Arc::new(registrar));
// when
let res = urlhint.resolve("test".as_bytes().into()).wait().unwrap();
// then
assert_eq!(
res,
Some(URLHintResult::Dapp(GithubApp {
account: "ethcore".into(),
repo: "dao.claim".into(),
commit: GithubApp::commit(
&"ec4c1fe06c808fe3739858c347109b1f5f1ed4b5"
.from_hex()
.unwrap()
)
.unwrap(),
owner: Address::from_str("deadcafebeefbeefcafedeaddeedfeedffffffff").unwrap(),
}))
)
}
#[test]
fn should_decode_urlhint_content_output() {
// given
let mut registrar = FakeRegistrar::new();
registrar.responses = Mutex::new(vec![
Ok(format!("000000000000000000000000{}", URLHINT).from_hex().unwrap()),
Ok("00000000000000000000000000000000000000000000000000000000000000600000000000000000000000000000000000000000000000000000000000000000000000000000000000000000deadcafebeefbeefcafedeaddeedfeedffffffff000000000000000000000000000000000000000000000000000000000000003c68747470733a2f2f7061726974792e696f2f6173736574732f696d616765732f657468636f72652d626c61636b2d686f72697a6f6e74616c2e706e6700000000".from_hex().unwrap()),
]);
let urlhint = URLHintContract::new(Arc::new(registrar));
// when
let res = urlhint.resolve("test".as_bytes().into()).wait().unwrap();
// then
assert_eq!(
res,
Some(URLHintResult::Content(Content {
url: "https://parity.io/assets/images/ethcore-black-horizontal.png".into(),
mime: mime::IMAGE_PNG,
owner: Address::from_str("deadcafebeefbeefcafedeaddeedfeedffffffff").unwrap(),
}))
)
}
#[test]
fn should_return_valid_url() {
// given
let app = GithubApp {
account: "test".into(),
repo: "xyz".into(),
commit: [
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19,
],
owner: Address::default(),
};
// when
let url = app.url();
// then
assert_eq!(
url,
"https://codeload.github.com/test/xyz/zip/000102030405060708090a0b0c0d0e0f10111213"
.to_owned()
);
}
#[test]
fn should_guess_mime_type_from_url() {
let url1 = "https://parity.io/parity";
let url2 = "https://parity.io/parity#content-type=image/png";
let url3 = "https://parity.io/parity#something&content-type=image/png";
let url4 = "https://parity.io/parity.png#content-type=image/jpeg";
let url5 = "https://parity.io/parity.png";
assert_eq!(guess_mime_type(url1), None);
assert_eq!(guess_mime_type(url2), Some(mime::IMAGE_PNG));
assert_eq!(guess_mime_type(url3), Some(mime::IMAGE_PNG));
assert_eq!(guess_mime_type(url4), Some(mime::IMAGE_JPEG));
assert_eq!(guess_mime_type(url5), Some(mime::IMAGE_PNG));
}
}

View File

@ -1,597 +0,0 @@
[
{
"constant": false,
"inputs": [
{
"name": "_client",
"type": "bytes32"
},
{
"name": "_newOwner",
"type": "address"
}
],
"name": "resetClientOwner",
"outputs": [],
"payable": false,
"type": "function"
},
{
"constant": true,
"inputs": [
{
"name": "_client",
"type": "bytes32"
},
{
"name": "_release",
"type": "bytes32"
}
],
"name": "isLatest",
"outputs": [
{
"name": "",
"type": "bool"
}
],
"payable": false,
"type": "function"
},
{
"constant": false,
"inputs": [
{
"name": "_txid",
"type": "bytes32"
}
],
"name": "rejectTransaction",
"outputs": [],
"payable": false,
"type": "function"
},
{
"constant": false,
"inputs": [
{
"name": "_newOwner",
"type": "address"
}
],
"name": "setOwner",
"outputs": [],
"payable": false,
"type": "function"
},
{
"constant": false,
"inputs": [
{
"name": "_number",
"type": "uint32"
},
{
"name": "_name",
"type": "bytes32"
},
{
"name": "_hard",
"type": "bool"
},
{
"name": "_spec",
"type": "bytes32"
}
],
"name": "proposeFork",
"outputs": [],
"payable": false,
"type": "function"
},
{
"constant": false,
"inputs": [
{
"name": "_client",
"type": "bytes32"
}
],
"name": "removeClient",
"outputs": [],
"payable": false,
"type": "function"
},
{
"constant": true,
"inputs": [
{
"name": "_client",
"type": "bytes32"
},
{
"name": "_release",
"type": "bytes32"
}
],
"name": "release",
"outputs": [
{
"name": "o_forkBlock",
"type": "uint32"
},
{
"name": "o_track",
"type": "uint8"
},
{
"name": "o_semver",
"type": "uint24"
},
{
"name": "o_critical",
"type": "bool"
}
],
"payable": false,
"type": "function"
},
{
"constant": true,
"inputs": [
{
"name": "_client",
"type": "bytes32"
},
{
"name": "_checksum",
"type": "bytes32"
}
],
"name": "build",
"outputs": [
{
"name": "o_release",
"type": "bytes32"
},
{
"name": "o_platform",
"type": "bytes32"
}
],
"payable": false,
"type": "function"
},
{
"constant": false,
"inputs": [],
"name": "rejectFork",
"outputs": [],
"payable": false,
"type": "function"
},
{
"constant": true,
"inputs": [
{
"name": "",
"type": "bytes32"
}
],
"name": "client",
"outputs": [
{
"name": "owner",
"type": "address"
},
{
"name": "required",
"type": "bool"
}
],
"payable": false,
"type": "function"
},
{
"constant": false,
"inputs": [
{
"name": "_newOwner",
"type": "address"
}
],
"name": "setClientOwner",
"outputs": [],
"payable": false,
"type": "function"
},
{
"constant": true,
"inputs": [
{
"name": "",
"type": "uint32"
}
],
"name": "fork",
"outputs": [
{
"name": "name",
"type": "bytes32"
},
{
"name": "spec",
"type": "bytes32"
},
{
"name": "hard",
"type": "bool"
},
{
"name": "ratified",
"type": "bool"
},
{
"name": "requiredCount",
"type": "uint256"
}
],
"payable": false,
"type": "function"
},
{
"constant": false,
"inputs": [
{
"name": "_release",
"type": "bytes32"
},
{
"name": "_platform",
"type": "bytes32"
},
{
"name": "_checksum",
"type": "bytes32"
}
],
"name": "addChecksum",
"outputs": [],
"payable": false,
"type": "function"
},
{
"constant": false,
"inputs": [
{
"name": "_txid",
"type": "bytes32"
}
],
"name": "confirmTransaction",
"outputs": [
{
"name": "txSuccess",
"type": "uint256"
}
],
"payable": false,
"type": "function"
},
{
"constant": true,
"inputs": [
{
"name": "",
"type": "bytes32"
}
],
"name": "proxy",
"outputs": [
{
"name": "requiredCount",
"type": "uint256"
},
{
"name": "to",
"type": "address"
},
{
"name": "data",
"type": "bytes"
},
{
"name": "value",
"type": "uint256"
},
{
"name": "gas",
"type": "uint256"
}
],
"payable": false,
"type": "function"
},
{
"constant": false,
"inputs": [
{
"name": "_client",
"type": "bytes32"
},
{
"name": "_owner",
"type": "address"
}
],
"name": "addClient",
"outputs": [],
"payable": false,
"type": "function"
},
{
"constant": true,
"inputs": [
{
"name": "",
"type": "address"
}
],
"name": "clientOwner",
"outputs": [
{
"name": "",
"type": "bytes32"
}
],
"payable": false,
"type": "function"
},
{
"constant": false,
"inputs": [
{
"name": "_txid",
"type": "bytes32"
},
{
"name": "_to",
"type": "address"
},
{
"name": "_data",
"type": "bytes"
},
{
"name": "_value",
"type": "uint256"
},
{
"name": "_gas",
"type": "uint256"
}
],
"name": "proposeTransaction",
"outputs": [
{
"name": "txSuccess",
"type": "uint256"
}
],
"payable": false,
"type": "function"
},
{
"constant": true,
"inputs": [],
"name": "grandOwner",
"outputs": [
{
"name": "",
"type": "address"
}
],
"payable": false,
"type": "function"
},
{
"constant": false,
"inputs": [
{
"name": "_release",
"type": "bytes32"
},
{
"name": "_forkBlock",
"type": "uint32"
},
{
"name": "_track",
"type": "uint8"
},
{
"name": "_semver",
"type": "uint24"
},
{
"name": "_critical",
"type": "bool"
}
],
"name": "addRelease",
"outputs": [],
"payable": false,
"type": "function"
},
{
"constant": false,
"inputs": [],
"name": "acceptFork",
"outputs": [],
"payable": false,
"type": "function"
},
{
"constant": true,
"inputs": [],
"name": "clientsRequired",
"outputs": [
{
"name": "",
"type": "uint32"
}
],
"payable": false,
"type": "function"
},
{
"constant": true,
"inputs": [
{
"name": "_client",
"type": "bytes32"
},
{
"name": "_release",
"type": "bytes32"
}
],
"name": "track",
"outputs": [
{
"name": "",
"type": "uint8"
}
],
"payable": false,
"type": "function"
},
{
"constant": false,
"inputs": [
{
"name": "_client",
"type": "bytes32"
},
{
"name": "_r",
"type": "bool"
}
],
"name": "setClientRequired",
"outputs": [],
"payable": false,
"type": "function"
},
{
"constant": true,
"inputs": [],
"name": "latestFork",
"outputs": [
{
"name": "",
"type": "uint32"
}
],
"payable": false,
"type": "function"
},
{
"constant": true,
"inputs": [
{
"name": "_client",
"type": "bytes32"
},
{
"name": "_track",
"type": "uint8"
}
],
"name": "latestInTrack",
"outputs": [
{
"name": "",
"type": "bytes32"
}
],
"payable": false,
"type": "function"
},
{
"constant": true,
"inputs": [
{
"name": "_client",
"type": "bytes32"
},
{
"name": "_release",
"type": "bytes32"
},
{
"name": "_platform",
"type": "bytes32"
}
],
"name": "checksum",
"outputs": [
{
"name": "",
"type": "bytes32"
}
],
"payable": false,
"type": "function"
},
{
"constant": true,
"inputs": [],
"name": "proposedFork",
"outputs": [
{
"name": "",
"type": "uint32"
}
],
"payable": false,
"type": "function"
},
{
"name": "ReleaseAdded",
"type": "event",
"anonymous": false,
"inputs": [
{
"indexed": true,
"name": "client",
"type": "bytes32"
},
{
"indexed": true,
"name": "forkBlock",
"type": "uint32"
},
{
"indexed": false,
"name": "release",
"type": "bytes32"
},
{
"indexed": false,
"name": "track",
"type": "uint8"
},
{
"indexed": false,
"name": "semver",
"type": "uint24"
},
{
"indexed": true,
"name": "critical",
"type": "bool"
}
]
}
]

View File

@ -1,58 +0,0 @@
// Copyright 2015-2019 Parity Technologies (UK) Ltd.
// This file is part of Parity Ethereum.
// Parity Ethereum 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 Ethereum 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 Ethereum. If not, see <http://www.gnu.org/licenses/>.
//! Updater for Parity executables
#![warn(missing_docs)]
extern crate common_types;
extern crate ethabi;
extern crate ethcore;
extern crate ethcore_sync as sync;
extern crate ethereum_types;
extern crate keccak_hash as hash;
extern crate parity_bytes as bytes;
extern crate parity_hash_fetch as hash_fetch;
extern crate parity_path;
extern crate parity_version as version;
extern crate parking_lot;
extern crate rand;
extern crate semver;
extern crate target_info;
#[macro_use]
extern crate ethabi_contract;
#[macro_use]
extern crate ethabi_derive;
#[macro_use]
extern crate lazy_static;
#[macro_use]
extern crate log;
#[cfg(test)]
extern crate tempdir;
#[cfg(test)]
#[macro_use]
extern crate matches;
mod service;
mod types;
mod updater;
pub use service::Service;
pub use types::{CapState, OperationsInfo, ReleaseInfo, ReleaseTrack, VersionInfo};
pub use updater::{UpdateFilter, UpdatePolicy, Updater};

View File

@ -1,38 +0,0 @@
// Copyright 2015-2019 Parity Technologies (UK) Ltd.
// This file is part of Parity Ethereum.
// Parity Ethereum 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 Ethereum 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 Ethereum. If not, see <http://www.gnu.org/licenses/>.
use types::{CapState, OperationsInfo, ReleaseInfo, VersionInfo};
/// Parity updater service trait
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<ReleaseInfo>;
/// 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<OperationsInfo>;
}

View File

@ -1,67 +0,0 @@
// Copyright 2015-2019 Parity Technologies (UK) Ltd.
// This file is part of Parity Ethereum.
// Parity Ethereum 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 Ethereum 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 Ethereum. If not, see <http://www.gnu.org/licenses/>.
//! Types used in the public API
use ethereum_types::H256;
use types::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<H256>,
}
/// 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<u64>,
/// Information on our track's latest release.
pub track: ReleaseInfo,
/// Information on our minor version's latest release.
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
}
}

View File

@ -1,27 +0,0 @@
// Copyright 2015-2019 Parity Technologies (UK) Ltd.
// This file is part of Parity Ethereum.
// Parity Ethereum 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 Ethereum 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 Ethereum. If not, see <http://www.gnu.org/licenses/>.
//! Types used in the public api
mod all;
mod release_track;
mod version_info;
pub use self::{
all::{CapState, OperationsInfo, ReleaseInfo},
release_track::ReleaseTrack,
version_info::VersionInfo,
};

View File

@ -1,122 +0,0 @@
// Copyright 2015-2019 Parity Technologies (UK) Ltd.
// This file is part of Parity Ethereum.
// Parity Ethereum 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 Ethereum 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 Ethereum. If not, see <http://www.gnu.org/licenses/>.
//! Types used in the public API
use std::fmt;
/// A release's track.
#[repr(u8)]
#[derive(PartialEq, Eq, Clone, Copy, Debug)]
pub enum ReleaseTrack {
/// Stable track.
Stable = 1,
/// Beta track.
Beta = 2,
/// Nightly track.
Nightly = 3,
/// Testing track.
Testing = 4,
/// No known track, also "current executable's track" when it's not yet known.
Unknown = 0,
}
impl fmt::Display for ReleaseTrack {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(
f,
"{}",
match *self {
ReleaseTrack::Stable => "stable",
ReleaseTrack::Beta => "beta",
ReleaseTrack::Nightly => "nightly",
ReleaseTrack::Testing => "testing",
ReleaseTrack::Unknown => "unknown",
}
)
}
}
impl<'a> From<&'a str> for ReleaseTrack {
fn from(s: &'a str) -> Self {
match s {
"stable" => ReleaseTrack::Stable,
"beta" => ReleaseTrack::Beta,
"nightly" => ReleaseTrack::Nightly,
"testing" => ReleaseTrack::Testing,
_ => ReleaseTrack::Unknown,
}
}
}
impl From<u8> for ReleaseTrack {
fn from(i: u8) -> Self {
match i {
1 => ReleaseTrack::Stable,
2 => ReleaseTrack::Beta,
3 => ReleaseTrack::Nightly,
4 => ReleaseTrack::Testing,
_ => ReleaseTrack::Unknown,
}
}
}
impl From<ReleaseTrack> for u8 {
fn from(rt: ReleaseTrack) -> Self {
rt as u8
}
}
#[cfg(test)]
mod tests {
use super::ReleaseTrack;
#[test]
fn test_release_track_from() {
assert_eq!(ReleaseTrack::Stable, 1u8.into());
assert_eq!(ReleaseTrack::Beta, 2u8.into());
assert_eq!(ReleaseTrack::Nightly, 3u8.into());
assert_eq!(ReleaseTrack::Testing, 4u8.into());
assert_eq!(ReleaseTrack::Unknown, 0u8.into());
}
#[test]
fn test_release_track_into() {
assert_eq!(1u8, u8::from(ReleaseTrack::Stable));
assert_eq!(2u8, u8::from(ReleaseTrack::Beta));
assert_eq!(3u8, u8::from(ReleaseTrack::Nightly));
assert_eq!(4u8, u8::from(ReleaseTrack::Testing));
assert_eq!(0u8, u8::from(ReleaseTrack::Unknown));
}
#[test]
fn test_release_track_from_str() {
assert_eq!(ReleaseTrack::Stable, "stable".into());
assert_eq!(ReleaseTrack::Beta, "beta".into());
assert_eq!(ReleaseTrack::Nightly, "nightly".into());
assert_eq!(ReleaseTrack::Testing, "testing".into());
assert_eq!(ReleaseTrack::Unknown, "unknown".into());
}
#[test]
fn test_release_track_into_str() {
assert_eq!("stable", ReleaseTrack::Stable.to_string());
assert_eq!("beta", ReleaseTrack::Beta.to_string());
assert_eq!("nightly", ReleaseTrack::Nightly.to_string());
assert_eq!("testing", ReleaseTrack::Testing.to_string());
assert_eq!("unknown", ReleaseTrack::Unknown.to_string());
}
}

View File

@ -1,78 +0,0 @@
// Copyright 2015-2019 Parity Technologies (UK) Ltd.
// This file is part of Parity Ethereum.
// Parity Ethereum 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 Ethereum 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 Ethereum. If not, see <http://www.gnu.org/licenses/>.
//! Types used in the public API
use ethereum_types::H160;
use semver::Version;
use std::fmt;
use types::ReleaseTrack;
use version::raw_package_info;
/// Version information of a particular release.
#[derive(Debug, Clone, PartialEq)]
pub struct VersionInfo {
/// The track on which it was released.
pub track: ReleaseTrack,
/// The version.
pub version: Version,
/// The (SHA1?) 160-bit hash of this build's code base.
pub hash: H160,
}
impl fmt::Display for VersionInfo {
fn fmt(&self, f: &mut fmt::Formatter) -> Result<(), fmt::Error> {
write!(
f,
"{}.{}.{}-{}-{}",
self.version.major, self.version.minor, self.version.patch, self.track, self.hash
)
}
}
impl VersionInfo {
/// Get information for this (currently running) binary.
pub fn this() -> Self {
let raw = raw_package_info();
VersionInfo {
track: raw.0.into(),
version: {
let mut v = Version::parse(raw.1)
.expect("Environment variables are known to be valid; qed");
v.build = vec![];
v.pre = vec![];
v
},
hash: raw.2.parse::<H160>().unwrap_or_else(|_| H160::zero()),
}
}
/// Compose the information from the provided raw fields.
pub fn from_raw(semver: u32, track: u8, hash: H160) -> Self {
let t = track.into();
VersionInfo {
version: Version {
major: u64::from(semver >> 16),
minor: u64::from((semver >> 8) & 0xff),
patch: u64::from(semver & 0xff),
build: vec![],
pre: vec![],
},
track: t,
hash,
}
}
}

File diff suppressed because it is too large Load Diff

View File

@ -268,16 +268,6 @@ pub fn default_local_path() -> String {
.unwrap_or_else(|_| "$HOME/.parity".to_owned()) .unwrap_or_else(|_| "$HOME/.parity".to_owned())
} }
/// Default hypervisor path
pub fn default_hypervisor_path() -> PathBuf {
let app_info = AppInfo {
name: PRODUCT_HYPERVISOR,
author: AUTHOR,
};
get_app_root(AppDataType::UserData, &app_info)
.unwrap_or_else(|_| "$HOME/.parity-hypervisor".into())
}
/// Get home directory. /// Get home directory.
fn home() -> PathBuf { fn home() -> PathBuf {
home_dir().expect("Failed to get home dir") home_dir().expect("Failed to get home dir")
@ -295,7 +285,6 @@ mod platform {
use std::path::PathBuf; use std::path::PathBuf;
pub const AUTHOR: &str = "Parity"; pub const AUTHOR: &str = "Parity";
pub const PRODUCT: &str = "io.parity.ethereum"; pub const PRODUCT: &str = "io.parity.ethereum";
pub const PRODUCT_HYPERVISOR: &str = "io.parity.ethereum-updates";
pub fn parity_base() -> PathBuf { pub fn parity_base() -> PathBuf {
let mut home = super::home(); let mut home = super::home();
@ -312,7 +301,6 @@ mod platform {
use std::path::PathBuf; use std::path::PathBuf;
pub const AUTHOR: &str = "Parity"; pub const AUTHOR: &str = "Parity";
pub const PRODUCT: &str = "Ethereum"; pub const PRODUCT: &str = "Ethereum";
pub const PRODUCT_HYPERVISOR: &str = "EthereumUpdates";
pub fn parity_base() -> PathBuf { pub fn parity_base() -> PathBuf {
let mut home = super::home(); let mut home = super::home();
@ -330,7 +318,6 @@ mod platform {
use std::path::PathBuf; use std::path::PathBuf;
pub const AUTHOR: &str = "parity"; pub const AUTHOR: &str = "parity";
pub const PRODUCT: &str = "io.parity.ethereum"; pub const PRODUCT: &str = "io.parity.ethereum";
pub const PRODUCT_HYPERVISOR: &str = "io.parity.ethereum-updates";
pub fn parity_base() -> PathBuf { pub fn parity_base() -> PathBuf {
let mut home = super::home(); let mut home = super::home();

View File

@ -1,5 +1,3 @@
# NOTE This file is used by the auto-updater service.
# Make sure to update the service if it's moved or the structure is changed.
[package] [package]
name = "parity-version" name = "parity-version"
# NOTE: this value is used for Parity Ethereum version string (via env CARGO_PKG_VERSION) # NOTE: this value is used for Parity Ethereum version string (via env CARGO_PKG_VERSION)
@ -8,18 +6,6 @@ authors = ["Parity Technologies <admin@parity.io>"]
build = "build.rs" build = "build.rs"
[package.metadata] [package.metadata]
# This versions track. Should be changed to `stable` or `beta` when on respective branches.
# Used by auto-updater and for Parity version string.
track = "stable"
# Network specific settings, used ONLY by auto-updater.
# Latest supported fork blocks.
# Indicates a critical release in this track (i.e. consensus issue).
[package.metadata.networks]
foundation = { forkBlock = 7280000, critical = false }
ropsten = { forkBlock = 4939394, critical = false }
kovan = { forkBlock = 10255201, critical = false }
goerli = { forkBlock = 0, critical = false }
[dependencies] [dependencies]
parity-bytes = "0.1" parity-bytes = "0.1"

View File

@ -28,25 +28,15 @@ fn main() {
let version = rustc_version::version().expect(ERROR_MSG); let version = rustc_version::version().expect(ERROR_MSG);
let cargo: toml::Value = toml::from_str(include_str!("./Cargo.toml")).expect(ERROR_MSG);
let track = cargo["package"]["metadata"]["track"]
.as_str()
.expect("'track' has to be a string!");
create_file( create_file(
"meta.rs", "meta.rs",
format!( format!(
" "
/// This versions track.
#[allow(unused)]
pub const TRACK: &str = {track:?};
/// Returns compiler version. /// Returns compiler version.
pub fn rustc_version() -> &'static str {{ pub fn rustc_version() -> &'static str {{
\"{version}\" \"{version}\"
}} }}
", ",
track = track,
version = version, version = version,
), ),
); );

View File

@ -34,8 +34,8 @@ mod generated {
} }
#[cfg(feature = "final")] #[cfg(feature = "final")]
const THIS_TRACK: &'static str = generated::TRACK; const THIS_TRACK: &'static str = "stable";
// ^^^ should be reset in Cargo.toml to "stable" or "beta" according to the release branch. // ^^^ should be reset in Cargo.toml to "stable"
#[cfg(not(feature = "final"))] #[cfg(not(feature = "final"))]
const THIS_TRACK: &'static str = "unstable"; const THIS_TRACK: &'static str = "unstable";