Remove the dapps system (#9017)

* Remove the dapps system from Parity

* Move node-health outside of dapps

* Fix set dapps list test

* Update Cargo.lock

* Deprecate options

* Add _legacy_ prefixes in Dapps

* Fix tests

* Fix deprecatedness of dapps-path
This commit is contained in:
Pierre Krieger
2018-07-11 12:19:54 +02:00
committed by Afri Schoedon
parent fe678dcd2f
commit 494eb4ab6b
79 changed files with 165 additions and 6105 deletions

View File

@@ -184,7 +184,7 @@ fn execute_import_light(cmd: ImportBlockchain) -> Result<(), String> {
execute_upgrades(&cmd.dirs.base, &db_dirs, algorithm, &cmd.compaction)?;
// create dirs used by parity
cmd.dirs.create_dirs(false, false, false)?;
cmd.dirs.create_dirs(false, false)?;
let cache = Arc::new(Mutex::new(
LightDataCache::new(Default::default(), Duration::new(0, 0))
@@ -337,7 +337,7 @@ fn execute_import(cmd: ImportBlockchain) -> Result<(), String> {
execute_upgrades(&cmd.dirs.base, &db_dirs, algorithm, &cmd.compaction)?;
// create dirs used by parity
cmd.dirs.create_dirs(false, false, false)?;
cmd.dirs.create_dirs(false, false)?;
// prepare client config
let mut client_config = to_client_config(
@@ -528,7 +528,7 @@ fn start_client(
execute_upgrades(&dirs.base, &db_dirs, algorithm, &compaction)?;
// create dirs used by parity
dirs.create_dirs(false, false, false)?;
dirs.create_dirs(false, false)?;
// prepare client config
let client_config = to_client_config(

View File

@@ -26,15 +26,6 @@ usage! {
// Arguments must start with arg_
// Flags must start with flag_
CMD cmd_dapp
{
"Manage dapps",
ARG arg_dapp_path: (Option<String>) = None,
"<PATH>",
"Path to the dapps",
}
CMD cmd_daemon
{
"Use Parity as a daemon",
@@ -232,6 +223,17 @@ usage! {
{
"Print the hashed light clients headers of the given --chain (default: mainnet) in a JSON format. To be used as hardcoded headers in a genesis file.",
}
// CMD removed in 2.0
CMD cmd_dapp
{
"Manage dapps",
ARG arg_dapp_path: (Option<String>) = None,
"<PATH>",
"Path to the dapps",
}
}
{
// Global flags and arguments
@@ -539,15 +541,6 @@ usage! {
"--ipc-apis=[APIS]",
"Specify custom API set available via JSON-RPC over IPC using a comma-delimited list of API names. Possible names are: all, safe, web3, net, eth, pubsub, personal, signer, parity, parity_pubsub, parity_accounts, parity_set, traces, rpc, secretstore, shh, shh_pubsub. You can also disable a specific API by putting '-' in the front, example: all,-personal. 'safe' enables the following APIs: web3, net, eth, pubsub, parity, parity_pubsub, traces, rpc, shh, shh_pubsub",
["API and Console Options Dapps"]
FLAG flag_no_dapps: (bool) = false, or |c: &Config| c.dapps.as_ref()?.disable.clone(),
"--no-dapps",
"Disable the Dapps server (e.g. status page).",
ARG arg_dapps_path: (String) = "$BASE/dapps", or |c: &Config| c.dapps.as_ref()?.path.clone(),
"--dapps-path=[PATH]",
"Specify directory where dapps should be installed.",
["API and Console Options IPFS"]
FLAG flag_ipfs_api: (bool) = false, or |c: &Config| c.ipfs.as_ref()?.enable.clone(),
"--ipfs-api",
@@ -969,6 +962,10 @@ usage! {
"--fast-and-loose",
"Does nothing; DB WAL is always activated.",
FLAG flag_no_dapps: (bool) = false, or |c: &Config| c.dapps.as_ref()?._legacy_disable.clone(),
"--no-dapps",
"Disable the Dapps server (e.g. status page).",
// ARG Removed in 1.6 or before.
ARG arg_etherbase: (Option<String>) = None, or |_| None,
@@ -1029,27 +1026,27 @@ usage! {
// ARG Removed in 1.7.
ARG arg_dapps_port: (Option<u16>) = None, or |c: &Config| c.dapps.as_ref()?.port.clone(),
ARG arg_dapps_port: (Option<u16>) = None, or |c: &Config| c.dapps.as_ref()?._legacy_port.clone(),
"--dapps-port=[PORT]",
"Does nothing; dapps server has been removed.",
ARG arg_dapps_interface: (Option<String>) = None, or |c: &Config| c.dapps.as_ref()?.interface.clone(),
ARG arg_dapps_interface: (Option<String>) = None, or |c: &Config| c.dapps.as_ref()?._legacy_interface.clone(),
"--dapps-interface=[IP]",
"Does nothing; dapps server has been removed.",
ARG arg_dapps_hosts: (Option<String>) = None, or |c: &Config| c.dapps.as_ref()?.hosts.as_ref().map(|vec| vec.join(",")),
ARG arg_dapps_hosts: (Option<String>) = None, or |c: &Config| c.dapps.as_ref()?._legacy_hosts.as_ref().map(|vec| vec.join(",")),
"--dapps-hosts=[HOSTS]",
"Does nothing; dapps server has been removed.",
ARG arg_dapps_cors: (Option<String>) = None, or |c: &Config| c.dapps.as_ref()?.cors.clone(),
ARG arg_dapps_cors: (Option<String>) = None, or |c: &Config| c.dapps.as_ref()?._legacy_cors.clone(),
"--dapps-cors=[URL]",
"Does nothing; dapps server has been removed.",
ARG arg_dapps_user: (Option<String>) = None, or |c: &Config| c.dapps.as_ref()?.user.clone(),
ARG arg_dapps_user: (Option<String>) = None, or |c: &Config| c.dapps.as_ref()?._legacy_user.clone(),
"--dapps-user=[USERNAME]",
"Dapps server authentication has been removed.",
ARG arg_dapps_pass: (Option<String>) = None, or |c: &Config| c.dapps.as_ref()?.pass.clone(),
ARG arg_dapps_pass: (Option<String>) = None, or |c: &Config| c.dapps.as_ref()?._legacy_pass.clone(),
"--dapps-pass=[PASSWORD]",
"Dapps server authentication has been removed.",
@@ -1074,6 +1071,12 @@ usage! {
ARG arg_tx_queue_ban_time: (Option<u16>) = None, or |c: &Config| c.mining.as_ref()?.tx_queue_ban_time.clone(),
"--tx-queue-ban-time=[SEC]",
"Not supported.",
// ARG removed in 2.0.
ARG arg_dapps_path: (Option<String>) = None, or |c: &Config| c.dapps.as_ref()?._legacy_path.clone(),
"--dapps-path=[PATH]",
"Specify directory where dapps should be installed.",
}
}
@@ -1223,14 +1226,22 @@ struct Ipc {
#[derive(Default, Debug, PartialEq, Deserialize)]
#[serde(deny_unknown_fields)]
struct Dapps {
disable: Option<bool>,
port: Option<u16>,
interface: Option<String>,
hosts: Option<Vec<String>>,
cors: Option<String>,
path: Option<String>,
user: Option<String>,
pass: Option<String>,
#[serde(rename="disable")]
_legacy_disable: Option<bool>,
#[serde(rename="port")]
_legacy_port: Option<u16>,
#[serde(rename="interface")]
_legacy_interface: Option<String>,
#[serde(rename="hosts")]
_legacy_hosts: Option<Vec<String>>,
#[serde(rename="cors")]
_legacy_cors: Option<String>,
#[serde(rename="path")]
_legacy_path: Option<String>,
#[serde(rename="user")]
_legacy_user: Option<String>,
#[serde(rename="pass")]
_legacy_pass: Option<String>,
}
#[derive(Default, Debug, PartialEq, Deserialize)]
@@ -1663,7 +1674,7 @@ mod tests {
arg_ipc_apis: "web3,eth,net,parity,parity_accounts,personal,traces,rpc,secretstore".into(),
// DAPPS
arg_dapps_path: "$HOME/.parity/dapps".into(),
arg_dapps_path: Some("$HOME/.parity/dapps".into()),
flag_no_dapps: false,
// SECRETSTORE
@@ -1922,14 +1933,14 @@ mod tests {
apis: Some(vec!["rpc".into(), "eth".into()]),
}),
dapps: Some(Dapps {
disable: None,
port: Some(8080),
path: None,
interface: None,
hosts: None,
cors: None,
user: Some("username".into()),
pass: Some("password".into())
_legacy_disable: None,
_legacy_port: Some(8080),
_legacy_path: None,
_legacy_interface: None,
_legacy_hosts: None,
_legacy_cors: None,
_legacy_user: Some("username".into()),
_legacy_pass: Some("password".into())
}),
secretstore: Some(SecretStore {
disable: None,

View File

@@ -17,7 +17,7 @@
use std::time::Duration;
use std::io::Read;
use std::net::SocketAddr;
use std::path::{Path, PathBuf};
use std::path::PathBuf;
use std::collections::BTreeMap;
use std::cmp;
use cli::{Args, ArgsError};
@@ -41,7 +41,6 @@ use dir::helpers::{replace_home, replace_home_and_local};
use params::{ResealPolicy, AccountsConfig, GasPricerConfig, MinerExtras, SpecType};
use ethcore_logger::Config as LogConfig;
use dir::{self, Directories, default_hypervisor_path, default_local_path, default_data_path};
use dapps::Configuration as DappsConfiguration;
use ipfs::Configuration as IpfsConfiguration;
use ethcore_private_tx::{ProviderConfig, EncryptorConfig};
use secretstore::{NodeSecretKey, Configuration as SecretStoreConfiguration, ContractAddress as SecretStoreContractAddress};
@@ -136,7 +135,6 @@ impl Configuration {
let compaction = self.args.arg_db_compaction.parse()?;
let warp_sync = !self.args.flag_no_warp;
let geth_compatibility = self.args.flag_geth;
let dapps_conf = self.dapps_config();
let ipfs_conf = self.ipfs_config();
let secretstore_conf = self.secretstore_config()?;
let format = self.format()?;
@@ -370,13 +368,11 @@ impl Configuration {
warp_barrier: self.args.arg_warp_barrier,
geth_compatibility: geth_compatibility,
net_settings: self.network_settings()?,
dapps_conf: dapps_conf,
ipfs_conf: ipfs_conf,
secretstore_conf: secretstore_conf,
private_provider_conf: private_provider_conf,
private_encryptor_conf: private_enc_conf,
private_tx_enabled,
dapp: self.dapp_to_open()?,
name: self.args.arg_identity,
custom_bootnodes: self.args.arg_bootnodes.is_some(),
no_periodic_snapshot: self.args.flag_no_periodic_snapshot,
@@ -582,18 +578,6 @@ impl Configuration {
self.args.arg_ntp_servers.split(",").map(str::to_owned).collect()
}
fn dapps_config(&self) -> DappsConfiguration {
DappsConfiguration {
enabled: self.dapps_enabled(),
dapps_path: PathBuf::from(self.directories().dapps),
extra_dapps: if self.args.cmd_dapp {
self.args.arg_dapp_path.iter().map(|path| PathBuf::from(path)).collect()
} else {
vec![]
},
}
}
fn secretstore_config(&self) -> Result<SecretStoreConfiguration, String> {
Ok(SecretStoreConfiguration {
enabled: self.secretstore_enabled(),
@@ -627,19 +611,6 @@ impl Configuration {
}
}
fn dapp_to_open(&self) -> Result<Option<String>, String> {
if !self.args.cmd_dapp {
return Ok(None);
}
let path = self.args.arg_dapp_path.as_ref().map(String::as_str).unwrap_or(".");
let path = Path::new(path).canonicalize()
.map_err(|e| format!("Invalid path: {}. Error: {:?}", path, e))?;
let name = path.file_name()
.and_then(|name| name.to_str())
.ok_or_else(|| "Root path is not supported.".to_owned())?;
Ok(Some(name.into()))
}
fn gas_pricer_config(&self) -> Result<GasPricerConfig, String> {
fn wei_per_gas(usd_per_tx: f32, usd_per_eth: f32) -> U256 {
let wei_per_usd: f32 = 1.0e18 / usd_per_eth;
@@ -881,8 +852,6 @@ impl Configuration {
}
fn ws_config(&self) -> Result<WsConfiguration, String> {
let http = self.http_config()?;
let support_token_api =
// enabled when not unlocking
self.args.arg_unlock.is_none();
@@ -896,7 +865,6 @@ impl Configuration {
origins: self.ws_origins(),
signer_path: self.directories().signer.into(),
support_token_api,
dapps_address: http.address(),
max_connections: self.args.arg_ws_max_connections,
};
@@ -980,7 +948,6 @@ impl Configuration {
let db_path = replace_home_and_local(&data_path, &local_path, &base_db_path);
let cache_path = replace_home_and_local(&data_path, &local_path, cache_path);
let keys_path = replace_home(&data_path, &self.args.arg_keys_path);
let dapps_path = replace_home(&data_path, &self.args.arg_dapps_path);
let secretstore_path = replace_home(&data_path, &self.args.arg_secretstore_path);
let ui_path = replace_home(&data_path, &self.args.arg_ui_path);
@@ -989,7 +956,6 @@ impl Configuration {
base: data_path,
cache: cache_path,
db: db_path,
dapps: dapps_path,
signer: ui_path,
secretstore: secretstore_path,
}
@@ -1094,10 +1060,6 @@ impl Configuration {
!self.args.flag_no_ws
}
fn dapps_enabled(&self) -> bool {
!self.args.flag_dapps_off && !self.args.flag_no_dapps && self.rpc_enabled() && cfg!(feature = "dapps")
}
fn secretstore_enabled(&self) -> bool {
!self.args.flag_no_secretstore && cfg!(feature = "secretstore")
}
@@ -1364,7 +1326,6 @@ mod tests {
origins: Some(vec!["parity://*".into(),"chrome-extension://*".into(), "moz-extension://*".into()]),
hosts: Some(vec![]),
signer_path: expected.into(),
dapps_address: Some("127.0.0.1:8545".into()),
support_token_api: true,
max_connections: 100,
}, LogConfig {
@@ -1433,13 +1394,11 @@ mod tests {
vm_type: Default::default(),
geth_compatibility: false,
net_settings: Default::default(),
dapps_conf: Default::default(),
ipfs_conf: Default::default(),
secretstore_conf: Default::default(),
private_provider_conf: Default::default(),
private_encryptor_conf: Default::default(),
private_tx_enabled: false,
dapp: None,
name: "".into(),
custom_bootnodes: false,
fat_db: Default::default(),
@@ -1649,20 +1608,6 @@ mod tests {
assert_eq!(conf4.directories().signer, "signer".to_owned());
}
#[test]
fn should_parse_dapp_opening() {
// given
let tempdir = TempDir::new("").unwrap();
// when
let conf0 = parse(&["parity", "dapp", tempdir.path().to_str().unwrap()]);
// then
assert_eq!(conf0.dapp_to_open(), Ok(Some(tempdir.path().file_name().unwrap().to_str().unwrap().into())));
let extra_dapps = conf0.dapps_config().extra_dapps;
assert_eq!(extra_dapps, vec![tempdir.path().to_owned()]);
}
#[test]
fn should_not_bail_on_empty_line_in_reserved_peers() {
let tempdir = TempDir::new("").unwrap();
@@ -1708,7 +1653,6 @@ mod tests {
assert_eq!(c.net_conf.min_peers, 50);
assert_eq!(c.net_conf.max_peers, 100);
assert_eq!(c.ipc_conf.enabled, false);
assert_eq!(c.dapps_conf.enabled, false);
assert_eq!(c.miner_options.force_sealing, true);
assert_eq!(c.miner_options.reseal_on_external_tx, true);
assert_eq!(c.miner_options.reseal_on_own_tx, true);

View File

@@ -1,272 +0,0 @@
// Copyright 2015-2018 Parity Technologies (UK) Ltd.
// This file is part of Parity.
// Parity 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 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. If not, see <http://www.gnu.org/licenses/>.
use std::path::PathBuf;
use std::sync::Arc;
use bytes::Bytes;
use dir::default_data_path;
use dir::helpers::replace_home;
use ethcore::client::{Client, BlockChainClient, BlockId, CallContract};
use sync::LightSync;
use futures::{Future, future, IntoFuture};
use futures_cpupool::CpuPool;
use hash_fetch::fetch::Client as FetchClient;
use registrar::{RegistrarClient, Asynchronous};
use light::client::LightChainClient;
use light::on_demand::{self, OnDemand};
use node_health::{SyncStatus, NodeHealth};
use rpc;
use rpc_apis::SignerService;
use transaction::{Transaction, Action};
use ethereum_types::Address;
#[derive(Debug, PartialEq, Clone)]
pub struct Configuration {
pub enabled: bool,
pub dapps_path: PathBuf,
pub extra_dapps: Vec<PathBuf>,
}
impl Default for Configuration {
fn default() -> Self {
let data_dir = default_data_path();
Configuration {
enabled: true,
dapps_path: replace_home(&data_dir, "$BASE/dapps").into(),
extra_dapps: vec![],
}
}
}
impl Configuration {
pub fn address(&self, address: Option<::parity_rpc::Host>) -> Option<::parity_rpc::Host> {
match self.enabled {
true => address,
false => None,
}
}
}
/// Registrar implementation of the full client.
pub struct FullRegistrar {
/// Handle to the full client.
pub client: Arc<Client>,
}
impl FullRegistrar {
pub fn new(client: Arc<Client>) -> Self {
FullRegistrar {
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())
}
}
/// Registrar implementation for the light client.
pub struct LightRegistrar<T> {
/// The light client.
pub client: Arc<T>,
/// Handle to the on-demand service.
pub on_demand: Arc<OnDemand>,
/// Handle to the light network service.
pub sync: Arc<LightSync>,
}
impl<T: LightChainClient + 'static> RegistrarClient for LightRegistrar<T> {
type Call = Box<Future<Item = Bytes, Error = String> + Send>;
fn registrar_address(&self) -> Result<Address, String> {
self.client.engine().additional_params().get("registrar")
.ok_or_else(|| "Registrar not defined.".into())
.and_then(|registrar| {
registrar.parse().map_err(|e| format!("Invalid registrar address: {:?}", e))
})
}
fn call_contract(&self, address: Address, data: Bytes) -> Self::Call {
let header = self.client.best_block_header();
let env_info = self.client.env_info(BlockId::Hash(header.hash()))
.ok_or_else(|| format!("Cannot fetch env info for header {}", header.hash()));
let env_info = match env_info {
Ok(e) => e,
Err(e) => return Box::new(future::err(e)),
};
let maybe_future = self.sync.with_context(move |ctx| {
self.on_demand
.request(ctx, on_demand::request::TransactionProof {
tx: Transaction {
nonce: self.client.engine().account_start_nonce(header.number()),
action: Action::Call(address),
gas: 50_000.into(), // should be enough for all registry lookups. TODO: exponential backoff
gas_price: 0.into(),
value: 0.into(),
data: data,
}.fake_sign(Address::default()),
header: header.into(),
env_info: env_info,
engine: self.client.engine().clone(),
})
.expect("No back-references; therefore all back-refs valid; qed")
.then(|res| match res {
Ok(Ok(executed)) => Ok(executed.output),
Ok(Err(e)) => Err(format!("Failed to execute transaction: {}", e)),
Err(_) => Err(format!("On-demand service dropped request unexpectedly.")),
})
});
match maybe_future {
Some(fut) => Box::new(fut),
None => Box::new(future::err("cannot query registry: network disabled".into())),
}
}
}
// TODO: light client implementation forwarding to OnDemand and waiting for future
// to resolve.
#[derive(Clone)]
pub struct Dependencies {
pub node_health: NodeHealth,
pub sync_status: Arc<SyncStatus>,
pub contract_client: Arc<RegistrarClient<Call=Asynchronous>>,
pub fetch: FetchClient,
pub pool: CpuPool,
pub signer: Arc<SignerService>,
}
pub fn new(configuration: Configuration, deps: Dependencies) -> Result<Option<Middleware>, String> {
if !configuration.enabled {
return Ok(None);
}
server::dapps_middleware(
deps,
configuration.dapps_path,
configuration.extra_dapps,
rpc::DAPPS_DOMAIN,
).map(Some)
}
pub use self::server::{Middleware, service};
#[cfg(not(feature = "dapps"))]
mod server {
use super::Dependencies;
use std::sync::Arc;
use std::path::PathBuf;
use parity_rpc::{hyper, RequestMiddleware, RequestMiddlewareAction};
use rpc_apis;
pub struct Middleware;
impl RequestMiddleware for Middleware {
fn on_request(&self, _req: hyper::Request) -> RequestMiddlewareAction {
unreachable!()
}
}
pub fn dapps_middleware(
_deps: Dependencies,
_dapps_path: PathBuf,
_extra_dapps: Vec<PathBuf>,
_dapps_domain: &str,
) -> Result<Middleware, String> {
Err("Your Parity version has been compiled without WebApps support.".into())
}
pub fn service(_: &Option<Middleware>) -> Option<Arc<rpc_apis::DappsService>> {
None
}
}
#[cfg(feature = "dapps")]
mod server {
use super::Dependencies;
use std::path::PathBuf;
use std::sync::Arc;
use rpc_apis;
use parity_dapps;
pub use parity_dapps::Middleware;
pub fn dapps_middleware(
deps: Dependencies,
dapps_path: PathBuf,
extra_dapps: Vec<PathBuf>,
dapps_domain: &str,
) -> Result<Middleware, String> {
let signer = deps.signer;
let web_proxy_tokens = Arc::new(move |token| signer.web_proxy_access_token_domain(&token));
Ok(parity_dapps::Middleware::dapps(
deps.pool,
deps.node_health,
dapps_path,
extra_dapps,
dapps_domain,
deps.contract_client,
deps.sync_status,
web_proxy_tokens,
deps.fetch,
))
}
pub fn service(middleware: &Option<Middleware>) -> Option<Arc<rpc_apis::DappsService>> {
middleware.as_ref().map(|m| Arc::new(DappsServiceWrapper {
endpoints: m.endpoints().clone(),
}) as Arc<rpc_apis::DappsService>)
}
pub struct DappsServiceWrapper {
endpoints: parity_dapps::Endpoints,
}
impl rpc_apis::DappsService for DappsServiceWrapper {
fn list_dapps(&self) -> Vec<rpc_apis::LocalDapp> {
self.endpoints.list()
.into_iter()
.map(|app| rpc_apis::LocalDapp {
id: app.id.unwrap_or_else(|| "unknown".into()),
name: app.name,
description: app.description,
version: app.version,
author: app.author,
icon_url: app.icon_url,
local_url: app.local_url,
})
.collect()
}
fn refresh_local_dapps(&self) -> bool {
self.endpoints.refresh_local_dapps();
true
}
}
}

View File

@@ -209,6 +209,22 @@ pub fn find_deprecated(args: &Args) -> Vec<Deprecated> {
result.push(Deprecated::Removed("--fast-and-loose"));
}
if args.cmd_dapp {
result.push(Deprecated::Removed("parity dapp"));
}
if args.arg_dapp_path.is_some() {
result.push(Deprecated::Removed("--dapp-path"));
}
if args.flag_no_dapps {
result.push(Deprecated::Removed("--no-dapps"));
}
if args.arg_dapps_path.is_some() {
result.push(Deprecated::Removed("--dapps-path"));
}
result
}

View File

@@ -68,7 +68,7 @@ pub fn execute(cmd: ExportHsyncCmd) -> Result<String, String> {
execute_upgrades(&cmd.dirs.base, &db_dirs, algorithm, &cmd.compaction)?;
// create dirs used by parity
cmd.dirs.create_dirs(false, false, false)?;
cmd.dirs.create_dirs(false, false)?;
// TODO: configurable cache size.
let cache = LightDataCache::new(Default::default(), Duration::from_secs(60 * GAS_CORPUS_EXPIRATION_MINUTES));

View File

@@ -87,8 +87,6 @@ extern crate parity_dapps;
#[macro_use]
extern crate pretty_assertions;
#[cfg(windows)] extern crate winapi;
#[cfg(test)]
extern crate tempdir;
@@ -97,7 +95,6 @@ mod blockchain;
mod cache;
mod cli;
mod configuration;
mod dapps;
mod export_hardcoded_sync;
mod ipfs;
mod deprecated;
@@ -114,7 +111,6 @@ mod secretstore;
mod signer;
mod snapshot;
mod upgrade;
mod url;
mod user_defaults;
mod whisper;
mod db;
@@ -201,10 +197,6 @@ fn execute<Cr, Rr>(command: Execute, on_client_rq: Cr, on_updater_rq: Rr) -> Res
match command.cmd {
Cmd::Run(run_cmd) => {
if let Some(ref dapp) = run_cmd.dapp {
open_dapp(&run_cmd.dapps_conf, &run_cmd.http_conf, dapp)?;
}
let outcome = run::execute(run_cmd, logger, on_client_rq, on_updater_rq)?;
Ok(ExecutionAction::Running(outcome))
},
@@ -244,13 +236,3 @@ pub fn start<Cr, Rr>(conf: Configuration, on_client_rq: Cr, on_updater_rq: Rr) -
execute(conf.into_command()?, on_client_rq, on_updater_rq)
}
fn open_dapp(dapps_conf: &dapps::Configuration, rpc_conf: &rpc::HttpConfiguration, dapp: &str) -> Result<(), String> {
if !dapps_conf.enabled {
return Err("Cannot use DAPP command with Dapps turned off.".into())
}
let url = format!("http://{}:{}/{}/", rpc_conf.interface, rpc_conf.port, dapp);
url::open(&url).map_err(|e| format!("{}", e))?;
Ok(())
}

View File

@@ -19,7 +19,6 @@ use std::sync::Arc;
use std::path::PathBuf;
use std::collections::HashSet;
use dapps;
use dir::default_data_path;
use dir::helpers::replace_home;
use helpers::parity_ipc_path;
@@ -48,12 +47,6 @@ pub struct HttpConfiguration {
pub max_payload: usize,
}
impl HttpConfiguration {
pub fn address(&self) -> Option<rpc::Host> {
address(self.enabled, &self.interface, self.port, &self.hosts)
}
}
impl Default for HttpConfiguration {
fn default() -> Self {
HttpConfiguration {
@@ -103,7 +96,6 @@ pub struct WsConfiguration {
pub hosts: Option<Vec<String>>,
pub signer_path: PathBuf,
pub support_token_api: bool,
pub dapps_address: Option<rpc::Host>,
}
impl Default for WsConfiguration {
@@ -119,7 +111,6 @@ impl Default for WsConfiguration {
hosts: Some(Vec::new()),
signer_path: replace_home(&data_dir, "$BASE/signer").into(),
support_token_api: true,
dapps_address: Some("127.0.0.1:8545".into()),
}
}
}
@@ -173,7 +164,7 @@ pub fn new_ws<D: rpc_apis::Dependencies>(
};
let remote = deps.remote.clone();
let allowed_origins = into_domains(with_domain(conf.origins, domain, &conf.dapps_address));
let allowed_origins = into_domains(with_domain(conf.origins, domain, &None));
let allowed_hosts = into_domains(with_domain(conf.hosts, domain, &Some(url.clone().into())));
let signer_path;
@@ -210,7 +201,6 @@ pub fn new_http<D: rpc_apis::Dependencies>(
options: &str,
conf: HttpConfiguration,
deps: &Dependencies<D>,
middleware: Option<dapps::Middleware>,
) -> Result<Option<HttpServer>, String> {
if !conf.enabled {
return Ok(None);
@@ -232,7 +222,6 @@ pub fn new_http<D: rpc_apis::Dependencies>(
handler,
remote,
rpc::RpcExtractor,
middleware,
conf.server_threads,
conf.max_payload,
);

View File

@@ -20,7 +20,7 @@ use std::str::FromStr;
use std::sync::{Arc, Weak};
pub use parity_rpc::signer::SignerService;
pub use parity_rpc::dapps::{DappsService, LocalDapp};
pub use parity_rpc::dapps::LocalDapp;
use ethcore_service::PrivateTxService;
use ethcore::account_provider::AccountProvider;
@@ -227,8 +227,6 @@ pub struct FullDependencies {
pub updater: Arc<Updater>,
pub health: NodeHealth,
pub geth_compatibility: bool,
pub dapps_service: Option<Arc<DappsService>>,
pub dapps_address: Option<Host>,
pub ws_address: Option<Host>,
pub fetch: FetchClient,
pub pool: CpuPool,
@@ -337,7 +335,6 @@ impl FullDependencies {
self.logger.clone(),
self.settings.clone(),
signer,
self.dapps_address.clone(),
self.ws_address.clone(),
).to_delegate());
@@ -362,7 +359,6 @@ impl FullDependencies {
&self.miner,
&self.updater,
&self.net_service,
self.dapps_service.clone(),
self.fetch.clone(),
self.pool.clone(),
).to_delegate())
@@ -439,8 +435,6 @@ pub struct LightDependencies<T> {
pub on_demand: Arc<::light::on_demand::OnDemand>,
pub cache: Arc<Mutex<LightDataCache>>,
pub transaction_queue: Arc<RwLock<LightTransactionQueue>>,
pub dapps_service: Option<Arc<DappsService>>,
pub dapps_address: Option<Host>,
pub ws_address: Option<Host>,
pub fetch: FetchClient,
pub pool: CpuPool,
@@ -553,7 +547,6 @@ impl<C: LightChainClient + 'static> LightDependencies<C> {
self.settings.clone(),
self.health.clone(),
signer,
self.dapps_address.clone(),
self.ws_address.clone(),
self.gas_price_percentile,
).to_delegate());
@@ -576,7 +569,6 @@ impl<C: LightChainClient + 'static> LightDependencies<C> {
Api::ParitySet => {
handler.extend_with(light::ParitySetClient::new(
self.sync.clone(),
self.dapps_service.clone(),
self.fetch.clone(),
self.pool.clone(),
).to_delegate())

View File

@@ -21,8 +21,9 @@ use std::time::{Duration, Instant};
use std::thread;
use ansi_term::Colour;
use bytes::Bytes;
use ethcore::account_provider::{AccountProvider, AccountProviderSettings};
use ethcore::client::{Client, Mode, DatabaseCompactionProfile, VMType, BlockChainClient, BlockInfo};
use ethcore::client::{BlockId, CallContract, Client, Mode, DatabaseCompactionProfile, VMType, BlockChainClient, BlockInfo};
use ethcore::ethstore::ethkey;
use ethcore::miner::{stratum, Miner, MinerService, MinerOptions};
use ethcore::snapshot;
@@ -30,9 +31,11 @@ use ethcore::spec::{SpecParams, OptimizeFor};
use ethcore::verification::queue::VerifierSettings;
use ethcore_logger::{Config as LogConfig, RotatingLogger};
use ethcore_service::ClientService;
use ethereum_types::Address;
use sync::{self, SyncConfig};
#[cfg(feature = "work-notify")]
use miner::work_notify::WorkPoster;
use futures::IntoFuture;
use futures_cpupool::CpuPool;
use hash_fetch::{self, fetch};
use informant::{Informant, LightNodeInformantData, FullNodeInformantData};
@@ -55,10 +58,10 @@ use upgrade::upgrade_key_location;
use dir::{Directories, DatabaseDirectories};
use cache::CacheConfig;
use user_defaults::UserDefaults;
use dapps;
use ipfs;
use jsonrpc_core;
use modules;
use registrar::{RegistrarClient, Asynchronous};
use rpc;
use rpc_apis;
use secretstore;
@@ -112,13 +115,11 @@ pub struct RunCmd {
pub vm_type: VMType,
pub geth_compatibility: bool,
pub net_settings: NetworkSettings,
pub dapps_conf: dapps::Configuration,
pub ipfs_conf: ipfs::Configuration,
pub secretstore_conf: secretstore::Configuration,
pub private_provider_conf: ProviderConfig,
pub private_encryptor_conf: EncryptorConfig,
pub private_tx_enabled: bool,
pub dapp: Option<String>,
pub name: String,
pub custom_bootnodes: bool,
pub stratum: Option<stratum::Options>,
@@ -185,10 +186,10 @@ fn execute_light_impl(cmd: RunCmd, logger: Arc<RotatingLogger>) -> Result<Runnin
execute_upgrades(&cmd.dirs.base, &db_dirs, algorithm, &cmd.compaction)?;
// create dirs used by parity
cmd.dirs.create_dirs(cmd.dapps_conf.enabled, cmd.acc_conf.unlocked_accounts.len() == 0, cmd.secretstore_conf.enabled)?;
cmd.dirs.create_dirs(cmd.acc_conf.unlocked_accounts.len() == 0, cmd.secretstore_conf.enabled)?;
//print out running parity environment
print_running_environment(&spec.name, &cmd.dirs, &db_dirs, &cmd.dapps_conf);
print_running_environment(&spec.name, &cmd.dirs, &db_dirs);
info!("Running in experimental {} mode.", Colour::Blue.bold().paint("Light Client"));
@@ -287,13 +288,7 @@ fn execute_light_impl(cmd: RunCmd, logger: Arc<RotatingLogger>) -> Result<Runnin
// the dapps server
let signer_service = Arc::new(signer::new_service(&cmd.ws_conf, &cmd.logger_config));
let (node_health, dapps_deps) = {
let contract_client = ::dapps::LightRegistrar {
client: client.clone(),
sync: light_sync.clone(),
on_demand: on_demand.clone(),
};
let node_health = {
struct LightSyncStatus(Arc<LightSync>);
impl fmt::Debug for LightSyncStatus {
fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
@@ -309,26 +304,14 @@ fn execute_light_impl(cmd: RunCmd, logger: Arc<RotatingLogger>) -> Result<Runnin
}
let sync_status = Arc::new(LightSyncStatus(light_sync.clone()));
let node_health = node_health::NodeHealth::new(
node_health::NodeHealth::new(
sync_status.clone(),
node_health::TimeChecker::new(&cmd.ntp_servers, cpu_pool.clone()),
event_loop.remote(),
);
(node_health.clone(), dapps::Dependencies {
sync_status,
node_health,
contract_client: Arc::new(contract_client),
fetch: fetch.clone(),
pool: cpu_pool.clone(),
signer: signer_service.clone(),
})
)
};
let dapps_middleware = dapps::new(cmd.dapps_conf.clone(), dapps_deps.clone())?;
// start RPCs
let dapps_service = dapps::service(&dapps_middleware);
let deps_for_rpc_apis = Arc::new(rpc_apis::LightDependencies {
signer_service: signer_service,
client: client.clone(),
@@ -341,8 +324,6 @@ fn execute_light_impl(cmd: RunCmd, logger: Arc<RotatingLogger>) -> Result<Runnin
on_demand: on_demand,
cache: cache.clone(),
transaction_queue: txq,
dapps_service: dapps_service,
dapps_address: cmd.dapps_conf.address(cmd.http_conf.address()),
ws_address: cmd.ws_conf.address(),
fetch: fetch,
pool: cpu_pool.clone(),
@@ -368,7 +349,7 @@ fn execute_light_impl(cmd: RunCmd, logger: Arc<RotatingLogger>) -> Result<Runnin
// start rpc servers
let rpc_direct = rpc::setup_apis(rpc_apis::ApiSet::All, &dependencies);
let ws_server = rpc::new_ws(cmd.ws_conf, &dependencies)?;
let http_server = rpc::new_http("HTTP JSON-RPC", "jsonrpc", cmd.http_conf.clone(), &dependencies, dapps_middleware)?;
let http_server = rpc::new_http("HTTP JSON-RPC", "jsonrpc", cmd.http_conf.clone(), &dependencies)?;
let ipc_server = rpc::new_ipc(cmd.ipc_conf, &dependencies)?;
// the informant
@@ -440,7 +421,7 @@ fn execute_impl<Cr, Rr>(cmd: RunCmd, logger: Arc<RotatingLogger>, on_client_rq:
execute_upgrades(&cmd.dirs.base, &db_dirs, algorithm, &cmd.compaction)?;
// create dirs used by parity
cmd.dirs.create_dirs(cmd.dapps_conf.enabled, cmd.acc_conf.unlocked_accounts.len() == 0, cmd.secretstore_conf.enabled)?;
cmd.dirs.create_dirs(cmd.acc_conf.unlocked_accounts.len() == 0, cmd.secretstore_conf.enabled)?;
// run in daemon mode
if let Some(pid_file) = cmd.daemon {
@@ -448,7 +429,7 @@ fn execute_impl<Cr, Rr>(cmd: RunCmd, logger: Arc<RotatingLogger>, on_client_rq:
}
//print out running parity environment
print_running_environment(&spec.name, &cmd.dirs, &db_dirs, &cmd.dapps_conf);
print_running_environment(&spec.name, &cmd.dirs, &db_dirs);
// display info about used pruning algorithm
info!("State DB configuration: {}{}{}",
@@ -709,7 +690,21 @@ fn execute_impl<Cr, Rr>(cmd: RunCmd, logger: Arc<RotatingLogger>, on_client_rq:
chain_notify.start();
}
let contract_client = Arc::new(::dapps::FullRegistrar::new(client.clone()));
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();
@@ -727,7 +722,7 @@ fn execute_impl<Cr, Rr>(cmd: RunCmd, logger: Arc<RotatingLogger>, on_client_rq:
let signer_service = Arc::new(signer::new_service(&cmd.ws_conf, &cmd.logger_config));
// the dapps server
let (node_health, dapps_deps) = {
let node_health = {
let (sync, client) = (sync_provider.clone(), client.clone());
struct SyncStatus(Arc<sync::SyncProvider>, Arc<Client>, sync::NetworkConfiguration);
@@ -747,23 +742,13 @@ fn execute_impl<Cr, Rr>(cmd: RunCmd, logger: Arc<RotatingLogger>, on_client_rq:
}
let sync_status = Arc::new(SyncStatus(sync, client, net_conf));
let node_health = node_health::NodeHealth::new(
node_health::NodeHealth::new(
sync_status.clone(),
node_health::TimeChecker::new(&cmd.ntp_servers, cpu_pool.clone()),
event_loop.remote(),
);
(node_health.clone(), dapps::Dependencies {
sync_status,
node_health,
contract_client,
fetch: fetch.clone(),
pool: cpu_pool.clone(),
signer: signer_service.clone(),
})
)
};
let dapps_middleware = dapps::new(cmd.dapps_conf.clone(), dapps_deps.clone())?;
let dapps_service = dapps::service(&dapps_middleware);
let deps_for_rpc_apis = Arc::new(rpc_apis::FullDependencies {
signer_service: signer_service,
snapshot: snapshot_service.clone(),
@@ -779,8 +764,6 @@ fn execute_impl<Cr, Rr>(cmd: RunCmd, logger: Arc<RotatingLogger>, on_client_rq:
net_service: manage_network.clone(),
updater: updater.clone(),
geth_compatibility: cmd.geth_compatibility,
dapps_service: dapps_service,
dapps_address: cmd.dapps_conf.address(cmd.http_conf.address()),
ws_address: cmd.ws_conf.address(),
fetch: fetch.clone(),
pool: cpu_pool.clone(),
@@ -807,7 +790,7 @@ fn execute_impl<Cr, Rr>(cmd: RunCmd, logger: Arc<RotatingLogger>, on_client_rq:
let rpc_direct = rpc::setup_apis(rpc_apis::ApiSet::All, &dependencies);
let ws_server = rpc::new_ws(cmd.ws_conf.clone(), &dependencies)?;
let ipc_server = rpc::new_ipc(cmd.ipc_conf, &dependencies)?;
let http_server = rpc::new_http("HTTP JSON-RPC", "jsonrpc", cmd.http_conf.clone(), &dependencies, dapps_middleware)?;
let http_server = rpc::new_http("HTTP JSON-RPC", "jsonrpc", cmd.http_conf.clone(), &dependencies)?;
// secret store key server
let secretstore_deps = secretstore::Dependencies {
@@ -1001,11 +984,10 @@ fn daemonize(_pid_file: String) -> Result<(), String> {
Err("daemon is no supported on windows".into())
}
fn print_running_environment(spec_name: &String, dirs: &Directories, db_dirs: &DatabaseDirectories, dapps_conf: &dapps::Configuration) {
fn print_running_environment(spec_name: &String, dirs: &Directories, db_dirs: &DatabaseDirectories) {
info!("Starting {}", Colour::White.bold().paint(version()));
info!("Keys path {}", Colour::White.bold().paint(dirs.keys_path(spec_name).to_string_lossy().into_owned()));
info!("DB path {}", Colour::White.bold().paint(db_dirs.db_root_path().to_string_lossy().into_owned()));
info!("Path to dapps {}", Colour::White.bold().paint(dapps_conf.dapps_path.to_string_lossy().into_owned()));
}
fn prepare_account_provider(spec: &SpecType, dirs: &Directories, data_dir: &str, cfg: AccountsConfig, passwords: &[Password]) -> Result<AccountProvider, String> {

View File

@@ -1,88 +0,0 @@
// Copyright 2015-2018 Parity Technologies (UK) Ltd.
// This file is part of Parity.
// Parity 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 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. If not, see <http://www.gnu.org/licenses/>.
//! Cross-platform open url in default browser
use std;
use std::os::raw::c_int;
#[allow(unused)]
pub enum Error {
ProcessError(std::io::Error),
WindowsShellExecute(c_int),
}
impl From<std::io::Error> for Error {
fn from(err: std::io::Error) -> Self {
Error::ProcessError(err)
}
}
impl std::fmt::Display for Error {
fn fmt(&self, f: &mut std::fmt::Formatter) -> Result<(), std::fmt::Error> {
match *self {
Error::ProcessError(ref e) => write!(f, "{}", e),
Error::WindowsShellExecute(e) => write!(f, "WindowsShellExecute error: {}", e),
}
}
}
#[cfg(windows)]
pub fn open(url: &str) -> Result<(), Error> {
use std::ffi::CString;
use std::ptr;
use winapi::um::shellapi::ShellExecuteA;
use winapi::um::winuser::SW_SHOWNORMAL as Normal;
const WINDOWS_SHELL_EXECUTE_SUCCESS: c_int = 32;
let h_instance = unsafe {
ShellExecuteA(ptr::null_mut(),
CString::new("open").unwrap().as_ptr(),
CString::new(url.to_owned().replace("\n", "%0A")).unwrap().as_ptr(),
ptr::null(),
ptr::null(),
Normal) as c_int
};
// https://msdn.microsoft.com/en-us/library/windows/desktop/bb762153(v=vs.85).aspx
// `ShellExecute` returns a value greater than 32 on success
if h_instance > WINDOWS_SHELL_EXECUTE_SUCCESS {
Ok(())
} else {
Err(Error::WindowsShellExecute(h_instance))
}
}
#[cfg(any(target_os="macos", target_os="freebsd"))]
pub fn open(url: &str) -> Result<(), Error> {
let _ = std::process::Command::new("open").arg(url).spawn()?;
Ok(())
}
#[cfg(target_os="linux")]
pub fn open(url: &str) -> Result<(), Error> {
let _ = std::process::Command::new("xdg-open").arg(url).spawn()?;
Ok(())
}
#[cfg(any(target_os="android", target_os="ios"))]
pub fn open(_url: &str) -> Result<(), Error> {
// TODO: While it is generally always bad to leave a function implemented, there is not much
// more we can do here. This function will eventually be removed when we compile Parity
// as a library and not as a full binary.
Ok(())
}