Merge branch 'master' into on-demand-priority
This commit is contained in:
@@ -461,7 +461,7 @@ fn execute_export_state(cmd: ExportState) -> Result<(), String> {
|
||||
let at = cmd.at;
|
||||
let mut i = 0usize;
|
||||
|
||||
out.write_fmt(format_args!("{{ \"state\": [", )).expect("Couldn't write to stream.");
|
||||
out.write_fmt(format_args!("{{ \"state\": {{", )).expect("Couldn't write to stream.");
|
||||
loop {
|
||||
let accounts = client.list_accounts(at, last.as_ref(), 1000).ok_or("Specified block not found")?;
|
||||
if accounts.is_empty() {
|
||||
@@ -498,13 +498,11 @@ fn execute_export_state(cmd: ExportState) -> Result<(), String> {
|
||||
break;
|
||||
}
|
||||
|
||||
let mut si = 0;
|
||||
for key in keys.into_iter() {
|
||||
if si != 0 {
|
||||
if last_storage.is_some() {
|
||||
out.write(b",").expect("Write error");
|
||||
}
|
||||
out.write_fmt(format_args!("\n\t\"0x{}\": \"0x{}\"", key.hex(), client.storage_at(&account, &key, at).unwrap_or_else(Default::default).hex())).expect("Write error");
|
||||
si += 1;
|
||||
last_storage = Some(key);
|
||||
}
|
||||
}
|
||||
@@ -519,7 +517,7 @@ fn execute_export_state(cmd: ExportState) -> Result<(), String> {
|
||||
last = Some(account);
|
||||
}
|
||||
}
|
||||
out.write_fmt(format_args!("\n]}}")).expect("Write error");
|
||||
out.write_fmt(format_args!("\n}}}}")).expect("Write error");
|
||||
info!("Export completed.");
|
||||
Ok(())
|
||||
}
|
||||
|
||||
@@ -19,7 +19,7 @@ use std::cmp::max;
|
||||
const MIN_BC_CACHE_MB: u32 = 4;
|
||||
const MIN_DB_CACHE_MB: u32 = 2;
|
||||
const MIN_BLOCK_QUEUE_SIZE_LIMIT_MB: u32 = 16;
|
||||
const DEFAULT_BLOCK_QUEUE_SIZE_LIMIT_MB: u32 = 50;
|
||||
const DEFAULT_BLOCK_QUEUE_SIZE_LIMIT_MB: u32 = 40;
|
||||
const DEFAULT_TRACE_CACHE_SIZE: u32 = 20;
|
||||
const DEFAULT_STATE_CACHE_SIZE: u32 = 25;
|
||||
|
||||
@@ -41,7 +41,7 @@ pub struct CacheConfig {
|
||||
|
||||
impl Default for CacheConfig {
|
||||
fn default() -> Self {
|
||||
CacheConfig::new(64, 8, DEFAULT_BLOCK_QUEUE_SIZE_LIMIT_MB, DEFAULT_STATE_CACHE_SIZE)
|
||||
CacheConfig::new(32, 8, DEFAULT_BLOCK_QUEUE_SIZE_LIMIT_MB, DEFAULT_STATE_CACHE_SIZE)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -113,7 +113,7 @@ mod tests {
|
||||
let config = CacheConfig::new_with_total_cache_size(200);
|
||||
assert_eq!(config.db, 140);
|
||||
assert_eq!(config.blockchain(), 20);
|
||||
assert_eq!(config.queue(), 50);
|
||||
assert_eq!(config.queue(), 40);
|
||||
assert_eq!(config.state(), 30);
|
||||
assert_eq!(config.jump_tables(), 10);
|
||||
}
|
||||
@@ -129,6 +129,6 @@ mod tests {
|
||||
#[test]
|
||||
fn test_cache_config_default() {
|
||||
assert_eq!(CacheConfig::default(),
|
||||
CacheConfig::new(64, 8, super::DEFAULT_BLOCK_QUEUE_SIZE_LIMIT_MB, super::DEFAULT_STATE_CACHE_SIZE));
|
||||
CacheConfig::new(32, 8, super::DEFAULT_BLOCK_QUEUE_SIZE_LIMIT_MB, super::DEFAULT_STATE_CACHE_SIZE));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -7,6 +7,7 @@ release_track = "current"
|
||||
public_node = false
|
||||
no_download = false
|
||||
no_consensus = false
|
||||
no_persistent_txqueue = false
|
||||
|
||||
chain = "homestead"
|
||||
base_path = "$HOME/.parity"
|
||||
@@ -49,13 +50,21 @@ disable = false
|
||||
port = 8545
|
||||
interface = "local"
|
||||
cors = "null"
|
||||
apis = ["web3", "eth", "net", "parity", "traces", "rpc"]
|
||||
apis = ["web3", "eth", "net", "parity", "traces", "rpc", "secretstore"]
|
||||
hosts = ["none"]
|
||||
|
||||
[websockets]
|
||||
disable = false
|
||||
port = 8546
|
||||
interface = "local"
|
||||
origins = ["none"]
|
||||
apis = ["web3", "eth", "net", "parity", "traces", "rpc", "secretstore"]
|
||||
hosts = ["none"]
|
||||
|
||||
[ipc]
|
||||
disable = false
|
||||
path = "$HOME/.parity/jsonrpc.ipc"
|
||||
apis = ["web3", "eth", "net", "parity", "parity_accounts", "personal", "traces", "rpc"]
|
||||
apis = ["web3", "eth", "net", "parity", "parity_accounts", "personal", "traces", "rpc", "secretstore"]
|
||||
|
||||
[dapps]
|
||||
disable = false
|
||||
|
||||
@@ -24,6 +24,9 @@ allow_ips = "public"
|
||||
reserved_only = true
|
||||
reserved_peers = "./path/to/reserved_peers"
|
||||
|
||||
[websockets]
|
||||
disable = true
|
||||
origins = ["none"]
|
||||
|
||||
[rpc]
|
||||
disable = true
|
||||
|
||||
@@ -95,6 +95,8 @@ usage! {
|
||||
flag_keys_path: String = "$BASE/keys", or |c: &Config| otry!(c.parity).keys_path.clone(),
|
||||
flag_identity: String = "", or |c: &Config| otry!(c.parity).identity.clone(),
|
||||
flag_light: bool = false, or |c: &Config| otry!(c.parity).light,
|
||||
flag_no_persistent_txqueue: bool = false,
|
||||
or |c: &Config| otry!(c.parity).no_persistent_txqueue,
|
||||
|
||||
// -- Account Options
|
||||
flag_unlock: Option<String> = None,
|
||||
@@ -163,19 +165,33 @@ usage! {
|
||||
or |c: &Config| otry!(c.rpc).interface.clone(),
|
||||
flag_jsonrpc_cors: Option<String> = None,
|
||||
or |c: &Config| otry!(c.rpc).cors.clone().map(Some),
|
||||
flag_jsonrpc_apis: String = "web3,eth,net,parity,traces,rpc",
|
||||
flag_jsonrpc_apis: String = "web3,eth,net,parity,traces,rpc,secretstore",
|
||||
or |c: &Config| otry!(c.rpc).apis.as_ref().map(|vec| vec.join(",")),
|
||||
flag_jsonrpc_hosts: String = "none",
|
||||
or |c: &Config| otry!(c.rpc).hosts.as_ref().map(|vec| vec.join(",")),
|
||||
flag_jsonrpc_threads: Option<usize> = None,
|
||||
or |c: &Config| otry!(c.rpc).threads.map(Some),
|
||||
|
||||
// WS
|
||||
flag_no_ws: bool = false,
|
||||
or |c: &Config| otry!(c.websockets).disable.clone(),
|
||||
flag_ws_port: u16 = 8546u16,
|
||||
or |c: &Config| otry!(c.websockets).port.clone(),
|
||||
flag_ws_interface: String = "local",
|
||||
or |c: &Config| otry!(c.websockets).interface.clone(),
|
||||
flag_ws_apis: String = "web3,eth,net,parity,traces,rpc,secretstore",
|
||||
or |c: &Config| otry!(c.websockets).apis.as_ref().map(|vec| vec.join(",")),
|
||||
flag_ws_origins: String = "none",
|
||||
or |c: &Config| otry!(c.websockets).origins.as_ref().map(|vec| vec.join(",")),
|
||||
flag_ws_hosts: String = "none",
|
||||
or |c: &Config| otry!(c.websockets).hosts.as_ref().map(|vec| vec.join(",")),
|
||||
|
||||
// IPC
|
||||
flag_no_ipc: bool = false,
|
||||
or |c: &Config| otry!(c.ipc).disable.clone(),
|
||||
flag_ipc_path: String = "$BASE/jsonrpc.ipc",
|
||||
or |c: &Config| otry!(c.ipc).path.clone(),
|
||||
flag_ipc_apis: String = "web3,eth,net,parity,parity_accounts,traces,rpc",
|
||||
flag_ipc_apis: String = "web3,eth,net,parity,parity_accounts,traces,rpc,secretstore",
|
||||
or |c: &Config| otry!(c.ipc).apis.as_ref().map(|vec| vec.join(",")),
|
||||
|
||||
// DAPPS
|
||||
@@ -280,13 +296,13 @@ usage! {
|
||||
or |c: &Config| otry!(c.footprint).pruning.clone(),
|
||||
flag_pruning_history: u64 = 64u64,
|
||||
or |c: &Config| otry!(c.footprint).pruning_history.clone(),
|
||||
flag_pruning_memory: usize = 75usize,
|
||||
flag_pruning_memory: usize = 32usize,
|
||||
or |c: &Config| otry!(c.footprint).pruning_memory.clone(),
|
||||
flag_cache_size_db: u32 = 64u32,
|
||||
flag_cache_size_db: u32 = 32u32,
|
||||
or |c: &Config| otry!(c.footprint).cache_size_db.clone(),
|
||||
flag_cache_size_blocks: u32 = 8u32,
|
||||
or |c: &Config| otry!(c.footprint).cache_size_blocks.clone(),
|
||||
flag_cache_size_queue: u32 = 50u32,
|
||||
flag_cache_size_queue: u32 = 40u32,
|
||||
or |c: &Config| otry!(c.footprint).cache_size_queue.clone(),
|
||||
flag_cache_size_state: u32 = 25u32,
|
||||
or |c: &Config| otry!(c.footprint).cache_size_state.clone(),
|
||||
@@ -331,7 +347,6 @@ usage! {
|
||||
flag_no_color: bool = false,
|
||||
or |c: &Config| otry!(c.misc).color.map(|c| !c).clone(),
|
||||
|
||||
|
||||
// -- Legacy Options supported in configs
|
||||
flag_dapps_port: Option<u16> = None,
|
||||
or |c: &Config| otry!(c.dapps).port.clone().map(Some),
|
||||
@@ -363,6 +378,7 @@ struct Config {
|
||||
ui: Option<Ui>,
|
||||
network: Option<Network>,
|
||||
rpc: Option<Rpc>,
|
||||
websockets: Option<Ws>,
|
||||
ipc: Option<Ipc>,
|
||||
dapps: Option<Dapps>,
|
||||
secretstore: Option<SecretStore>,
|
||||
@@ -391,6 +407,7 @@ struct Operating {
|
||||
keys_path: Option<String>,
|
||||
identity: Option<String>,
|
||||
light: Option<bool>,
|
||||
no_persistent_txqueue: Option<bool>,
|
||||
}
|
||||
|
||||
#[derive(Default, Debug, PartialEq, RustcDecodable)]
|
||||
@@ -440,6 +457,16 @@ struct Rpc {
|
||||
threads: Option<usize>,
|
||||
}
|
||||
|
||||
#[derive(Default, Debug, PartialEq, RustcDecodable)]
|
||||
struct Ws {
|
||||
disable: Option<bool>,
|
||||
port: Option<u16>,
|
||||
interface: Option<String>,
|
||||
apis: Option<Vec<String>>,
|
||||
origins: Option<Vec<String>>,
|
||||
hosts: Option<Vec<String>>,
|
||||
}
|
||||
|
||||
#[derive(Default, Debug, PartialEq, RustcDecodable)]
|
||||
struct Ipc {
|
||||
disable: Option<bool>,
|
||||
@@ -554,7 +581,7 @@ struct Misc {
|
||||
mod tests {
|
||||
use super::{
|
||||
Args, ArgsError,
|
||||
Config, Operating, Account, Ui, Network, Rpc, Ipc, Dapps, Ipfs, Mining, Footprint,
|
||||
Config, Operating, Account, Ui, Network, Ws, Rpc, Ipc, Dapps, Ipfs, Mining, Footprint,
|
||||
Snapshots, VM, Misc, SecretStore,
|
||||
};
|
||||
use toml;
|
||||
@@ -657,6 +684,7 @@ mod tests {
|
||||
flag_keys_path: "$HOME/.parity/keys".into(),
|
||||
flag_identity: "".into(),
|
||||
flag_light: false,
|
||||
flag_no_persistent_txqueue: false,
|
||||
|
||||
// -- Account Options
|
||||
flag_unlock: Some("0xdeadbeefcafe0000000000000000000000000000".into()),
|
||||
@@ -695,14 +723,22 @@ mod tests {
|
||||
flag_jsonrpc_port: 8545u16,
|
||||
flag_jsonrpc_interface: "local".into(),
|
||||
flag_jsonrpc_cors: Some("null".into()),
|
||||
flag_jsonrpc_apis: "web3,eth,net,parity,traces,rpc".into(),
|
||||
flag_jsonrpc_apis: "web3,eth,net,parity,traces,rpc,secretstore".into(),
|
||||
flag_jsonrpc_hosts: "none".into(),
|
||||
flag_jsonrpc_threads: None,
|
||||
|
||||
// WS
|
||||
flag_no_ws: false,
|
||||
flag_ws_port: 8546u16,
|
||||
flag_ws_interface: "local".into(),
|
||||
flag_ws_apis: "web3,eth,net,parity,traces,rpc,secretstore".into(),
|
||||
flag_ws_origins: "none".into(),
|
||||
flag_ws_hosts: "none".into(),
|
||||
|
||||
// IPC
|
||||
flag_no_ipc: false,
|
||||
flag_ipc_path: "$HOME/.parity/jsonrpc.ipc".into(),
|
||||
flag_ipc_apis: "web3,eth,net,parity,parity_accounts,personal,traces,rpc".into(),
|
||||
flag_ipc_apis: "web3,eth,net,parity,parity_accounts,personal,traces,rpc,secretstore".into(),
|
||||
|
||||
// DAPPS
|
||||
flag_dapps_path: "$HOME/.parity/dapps".into(),
|
||||
@@ -868,6 +904,7 @@ mod tests {
|
||||
keys_path: None,
|
||||
identity: None,
|
||||
light: None,
|
||||
no_persistent_txqueue: None,
|
||||
}),
|
||||
account: Some(Account {
|
||||
unlock: Some(vec!["0x1".into(), "0x2".into(), "0x3".into()]),
|
||||
@@ -899,6 +936,14 @@ mod tests {
|
||||
reserved_only: Some(true),
|
||||
no_serve_light: None,
|
||||
}),
|
||||
websockets: Some(Ws {
|
||||
disable: Some(true),
|
||||
port: None,
|
||||
interface: None,
|
||||
apis: None,
|
||||
origins: Some(vec!["none".into()]),
|
||||
hosts: None,
|
||||
}),
|
||||
rpc: Some(Rpc {
|
||||
disable: Some(true),
|
||||
port: Some(8180),
|
||||
|
||||
@@ -157,7 +157,28 @@ API and Console Options:
|
||||
vectors. Special options: "all", "none",
|
||||
(default: {flag_jsonrpc_hosts}).
|
||||
--jsonrpc-threads THREADS Enables experimental faster implementation of JSON-RPC server.
|
||||
Requires Dapps server to be disabled using --no-dapps. (default: {flag_jsonrpc_threads:?})
|
||||
Requires Dapps server to be disabled
|
||||
using --no-dapps. (default: {flag_jsonrpc_threads:?})
|
||||
|
||||
--no-ws Disable the WebSockets server. (default: {flag_no_ws})
|
||||
--ws-port PORT Specify the port portion of the WebSockets server
|
||||
(default: {flag_ws_port}).
|
||||
--ws-interface IP Specify the hostname portion of the WebSockets
|
||||
server, IP should be an interface's IP address, or
|
||||
all (all interfaces) or local (default: {flag_ws_interface}).
|
||||
--ws-apis APIS Specify the APIs available through the WebSockets
|
||||
interface. APIS is a comma-delimited list of API
|
||||
name. Possible name are web3, eth, net, personal,
|
||||
parity, parity_set, traces, rpc, parity_accounts.
|
||||
(default: {flag_ws_apis}).
|
||||
--ws-origins URL Specify Origin header values allowed to connect.
|
||||
Special options: "all", "none".
|
||||
(default: {flag_ws_origins})
|
||||
--ws-hosts HOSTS List of allowed Host header values. This option will
|
||||
validate the Host header sent by the browser, it
|
||||
is additional security against some attack
|
||||
vectors. Special options: "all", "none",
|
||||
(default: {flag_ws_hosts}).
|
||||
|
||||
--no-ipc Disable JSON-RPC over IPC service. (default: {flag_no_ipc})
|
||||
--ipc-path PATH Specify custom path for JSON-RPC over IPC service
|
||||
@@ -283,6 +304,9 @@ Sealing/Mining Options:
|
||||
execution time limit. Also number of offending actions
|
||||
have to reach the threshold within that time.
|
||||
(default: {flag_tx_queue_ban_time} seconds)
|
||||
--no-persistent-txqueue Don't save pending local transactions to disk to be
|
||||
restored whenever the node restarts.
|
||||
(default: {flag_no_persistent_txqueue}).
|
||||
--remove-solved Move solved blocks from the work package queue
|
||||
instead of cloning them. This gives a slightly
|
||||
faster import speed, but means that extra solutions
|
||||
|
||||
@@ -30,9 +30,9 @@ use ethcore::client::{VMType};
|
||||
use ethcore::miner::{MinerOptions, Banning, StratumOptions};
|
||||
use ethcore::verification::queue::VerifierSettings;
|
||||
|
||||
use rpc::{IpcConfiguration, HttpConfiguration};
|
||||
use rpc::{IpcConfiguration, HttpConfiguration, WsConfiguration};
|
||||
use rpc_apis::ApiSet;
|
||||
use ethcore_rpc::NetworkSettings;
|
||||
use parity_rpc::NetworkSettings;
|
||||
use cache::CacheConfig;
|
||||
use helpers::{to_duration, to_mode, to_block_id, to_u256, to_pending_set, to_price, replace_home, replace_home_for_db,
|
||||
geth_ipc_path, parity_ipc_path, to_bootnodes, to_addresses, to_address, to_gas_limit, to_queue_strategy};
|
||||
@@ -114,6 +114,7 @@ impl Configuration {
|
||||
};
|
||||
let update_policy = self.update_policy()?;
|
||||
let logger_config = self.logger_config();
|
||||
let ws_conf = self.ws_config()?;
|
||||
let http_conf = self.http_config()?;
|
||||
let ipc_conf = self.ipc_config()?;
|
||||
let net_conf = self.net_config()?;
|
||||
@@ -352,6 +353,7 @@ impl Configuration {
|
||||
daemon: daemon,
|
||||
logger_config: logger_config.clone(),
|
||||
miner_options: miner_options,
|
||||
ws_conf: ws_conf,
|
||||
http_conf: http_conf,
|
||||
ipc_conf: ipc_conf,
|
||||
net_conf: net_conf,
|
||||
@@ -386,6 +388,7 @@ impl Configuration {
|
||||
verifier_settings: verifier_settings,
|
||||
serve_light: !self.args.flag_no_serve_light,
|
||||
light: self.args.flag_light,
|
||||
no_persistent_txqueue: self.args.flag_no_persistent_txqueue,
|
||||
};
|
||||
Cmd::Run(run_cmd)
|
||||
};
|
||||
@@ -638,7 +641,7 @@ impl Configuration {
|
||||
|
||||
info!(
|
||||
"Using a fixed conversion rate of Ξ1 = {} ({} wei/gas)",
|
||||
Colour::White.bold().paint(format!("US${}", usd_per_eth)),
|
||||
Colour::White.bold().paint(format!("US${:.2}", usd_per_eth)),
|
||||
Colour::Yellow.bold().paint(format!("{}", wei_per_gas))
|
||||
);
|
||||
|
||||
@@ -757,6 +760,14 @@ impl Configuration {
|
||||
Self::hosts(&self.args.flag_jsonrpc_hosts)
|
||||
}
|
||||
|
||||
fn ws_hosts(&self) -> Option<Vec<String>> {
|
||||
Self::hosts(&self.args.flag_ws_hosts)
|
||||
}
|
||||
|
||||
fn ws_origins(&self) -> Option<Vec<String>> {
|
||||
Self::hosts(&self.args.flag_ws_origins)
|
||||
}
|
||||
|
||||
fn ipfs_hosts(&self) -> Option<Vec<String>> {
|
||||
Self::hosts(&self.args.flag_ipfs_api_hosts)
|
||||
}
|
||||
@@ -801,6 +812,19 @@ impl Configuration {
|
||||
Ok(conf)
|
||||
}
|
||||
|
||||
fn ws_config(&self) -> Result<WsConfiguration, String> {
|
||||
let conf = WsConfiguration {
|
||||
enabled: self.ws_enabled(),
|
||||
interface: self.ws_interface(),
|
||||
port: self.args.flag_ws_port,
|
||||
apis: self.args.flag_ws_apis.parse()?,
|
||||
hosts: self.ws_hosts(),
|
||||
origins: self.ws_origins()
|
||||
};
|
||||
|
||||
Ok(conf)
|
||||
}
|
||||
|
||||
fn network_settings(&self) -> NetworkSettings {
|
||||
NetworkSettings {
|
||||
name: self.args.flag_identity.clone(),
|
||||
@@ -913,6 +937,10 @@ impl Configuration {
|
||||
Self::interface(&self.network_settings().rpc_interface)
|
||||
}
|
||||
|
||||
fn ws_interface(&self) -> String {
|
||||
Self::interface(&self.args.flag_ws_interface)
|
||||
}
|
||||
|
||||
fn ipfs_interface(&self) -> String {
|
||||
Self::interface(&self.args.flag_ipfs_api_interface)
|
||||
}
|
||||
@@ -965,6 +993,10 @@ impl Configuration {
|
||||
!self.args.flag_jsonrpc_off && !self.args.flag_no_jsonrpc
|
||||
}
|
||||
|
||||
fn ws_enabled(&self) -> bool {
|
||||
!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")
|
||||
}
|
||||
@@ -1000,7 +1032,7 @@ impl Configuration {
|
||||
mod tests {
|
||||
use super::*;
|
||||
use cli::Args;
|
||||
use ethcore_rpc::NetworkSettings;
|
||||
use parity_rpc::NetworkSettings;
|
||||
use ethcore::client::{VMType, BlockId};
|
||||
use ethcore::miner::{MinerOptions, PrioritizationStrategy};
|
||||
use helpers::{default_network_config};
|
||||
@@ -1093,7 +1125,7 @@ mod tests {
|
||||
format: Default::default(),
|
||||
pruning: Default::default(),
|
||||
pruning_history: 64,
|
||||
pruning_memory: 75,
|
||||
pruning_memory: 32,
|
||||
compaction: Default::default(),
|
||||
wal: true,
|
||||
tracing: Default::default(),
|
||||
@@ -1116,7 +1148,7 @@ mod tests {
|
||||
file_path: Some("blockchain.json".into()),
|
||||
pruning: Default::default(),
|
||||
pruning_history: 64,
|
||||
pruning_memory: 75,
|
||||
pruning_memory: 32,
|
||||
format: Default::default(),
|
||||
compaction: Default::default(),
|
||||
wal: true,
|
||||
@@ -1139,7 +1171,7 @@ mod tests {
|
||||
file_path: Some("state.json".into()),
|
||||
pruning: Default::default(),
|
||||
pruning_history: 64,
|
||||
pruning_memory: 75,
|
||||
pruning_memory: 32,
|
||||
format: Default::default(),
|
||||
compaction: Default::default(),
|
||||
wal: true,
|
||||
@@ -1164,7 +1196,7 @@ mod tests {
|
||||
file_path: Some("blockchain.json".into()),
|
||||
pruning: Default::default(),
|
||||
pruning_history: 64,
|
||||
pruning_memory: 75,
|
||||
pruning_memory: 32,
|
||||
format: Some(DataFormat::Hex),
|
||||
compaction: Default::default(),
|
||||
wal: true,
|
||||
@@ -1200,10 +1232,11 @@ mod tests {
|
||||
spec: Default::default(),
|
||||
pruning: Default::default(),
|
||||
pruning_history: 64,
|
||||
pruning_memory: 75,
|
||||
pruning_memory: 32,
|
||||
daemon: None,
|
||||
logger_config: Default::default(),
|
||||
miner_options: Default::default(),
|
||||
ws_conf: Default::default(),
|
||||
http_conf: Default::default(),
|
||||
ipc_conf: Default::default(),
|
||||
net_conf: default_network_config(),
|
||||
@@ -1238,6 +1271,7 @@ mod tests {
|
||||
verifier_settings: Default::default(),
|
||||
serve_light: true,
|
||||
light: false,
|
||||
no_persistent_txqueue: false,
|
||||
};
|
||||
expected.secretstore_conf.enabled = cfg!(feature = "secretstore");
|
||||
assert_eq!(conf.into_command().unwrap().cmd, Cmd::Run(expected));
|
||||
@@ -1337,13 +1371,13 @@ mod tests {
|
||||
let conf0 = parse(&["parity"]);
|
||||
let conf1 = parse(&["parity", "--jsonrpc-hosts", "none"]);
|
||||
let conf2 = parse(&["parity", "--jsonrpc-hosts", "all"]);
|
||||
let conf3 = parse(&["parity", "--jsonrpc-hosts", "ethcore.io,something.io"]);
|
||||
let conf3 = parse(&["parity", "--jsonrpc-hosts", "parity.io,something.io"]);
|
||||
|
||||
// then
|
||||
assert_eq!(conf0.rpc_hosts(), Some(Vec::new()));
|
||||
assert_eq!(conf1.rpc_hosts(), Some(Vec::new()));
|
||||
assert_eq!(conf2.rpc_hosts(), None);
|
||||
assert_eq!(conf3.rpc_hosts(), Some(vec!["ethcore.io".into(), "something.io".into()]));
|
||||
assert_eq!(conf3.rpc_hosts(), Some(vec!["parity.io".into(), "something.io".into()]));
|
||||
}
|
||||
|
||||
#[test]
|
||||
@@ -1354,13 +1388,13 @@ mod tests {
|
||||
let conf0 = parse(&["parity"]);
|
||||
let conf1 = parse(&["parity", "--ipfs-api-hosts", "none"]);
|
||||
let conf2 = parse(&["parity", "--ipfs-api-hosts", "all"]);
|
||||
let conf3 = parse(&["parity", "--ipfs-api-hosts", "ethcore.io,something.io"]);
|
||||
let conf3 = parse(&["parity", "--ipfs-api-hosts", "parity.io,something.io"]);
|
||||
|
||||
// then
|
||||
assert_eq!(conf0.ipfs_hosts(), Some(Vec::new()));
|
||||
assert_eq!(conf1.ipfs_hosts(), Some(Vec::new()));
|
||||
assert_eq!(conf2.ipfs_hosts(), None);
|
||||
assert_eq!(conf3.ipfs_hosts(), Some(vec!["ethcore.io".into(), "something.io".into()]));
|
||||
assert_eq!(conf3.ipfs_hosts(), Some(vec!["parity.io".into(), "something.io".into()]));
|
||||
}
|
||||
|
||||
#[test]
|
||||
@@ -1370,12 +1404,12 @@ mod tests {
|
||||
// when
|
||||
let conf0 = parse(&["parity"]);
|
||||
let conf1 = parse(&["parity", "--ipfs-api-cors", "*"]);
|
||||
let conf2 = parse(&["parity", "--ipfs-api-cors", "http://ethcore.io,http://something.io"]);
|
||||
let conf2 = parse(&["parity", "--ipfs-api-cors", "http://parity.io,http://something.io"]);
|
||||
|
||||
// then
|
||||
assert_eq!(conf0.ipfs_cors(), None);
|
||||
assert_eq!(conf1.ipfs_cors(), Some(vec!["*".into()]));
|
||||
assert_eq!(conf2.ipfs_cors(), Some(vec!["http://ethcore.io".into(),"http://something.io".into()]));
|
||||
assert_eq!(conf2.ipfs_cors(), Some(vec!["http://parity.io".into(),"http://something.io".into()]));
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
||||
@@ -109,7 +109,7 @@ pub use self::server::{SyncStatus, Middleware, dapps_middleware};
|
||||
mod server {
|
||||
use super::Dependencies;
|
||||
use std::path::PathBuf;
|
||||
use ethcore_rpc::{hyper, RequestMiddleware, RequestMiddlewareAction};
|
||||
use parity_rpc::{hyper, RequestMiddleware, RequestMiddlewareAction};
|
||||
|
||||
pub type SyncStatus = Fn() -> bool;
|
||||
|
||||
|
||||
@@ -30,8 +30,8 @@ use ethcore::service::ClientIoMessage;
|
||||
use ethcore::snapshot::service::Service as SnapshotService;
|
||||
use ethcore::snapshot::{RestorationStatus, SnapshotService as SS};
|
||||
use number_prefix::{binary_prefix, Standalone, Prefixed};
|
||||
use ethcore_rpc::{is_major_importing};
|
||||
use ethcore_rpc::informant::RpcStats;
|
||||
use parity_rpc::{is_major_importing};
|
||||
use parity_rpc::informant::RpcStats;
|
||||
|
||||
pub struct Informant {
|
||||
report: RwLock<Option<ClientReport>>,
|
||||
|
||||
@@ -51,18 +51,18 @@ extern crate ethcore_ipc_hypervisor as hypervisor;
|
||||
extern crate ethcore_ipc_nano as nanoipc;
|
||||
extern crate ethcore_light as light;
|
||||
extern crate ethcore_logger;
|
||||
extern crate ethcore_rpc;
|
||||
extern crate ethcore_signer;
|
||||
extern crate ethcore_util as util;
|
||||
extern crate ethkey;
|
||||
extern crate ethsync;
|
||||
extern crate parity_hash_fetch as hash_fetch;
|
||||
extern crate parity_ipfs_api;
|
||||
extern crate parity_reactor;
|
||||
extern crate parity_updater as updater;
|
||||
extern crate parity_local_store as local_store;
|
||||
extern crate rpc_cli;
|
||||
extern crate parity_reactor;
|
||||
extern crate parity_rpc;
|
||||
extern crate parity_updater as updater;
|
||||
extern crate path;
|
||||
extern crate rpc_cli;
|
||||
|
||||
#[macro_use]
|
||||
extern crate log as rlog;
|
||||
|
||||
178
parity/rpc.rs
178
parity/rpc.rs
@@ -14,19 +14,20 @@
|
||||
// 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::{io, fmt};
|
||||
use std::io;
|
||||
use std::sync::Arc;
|
||||
|
||||
use dapps;
|
||||
use dir::default_data_path;
|
||||
use ethcore_rpc::informant::{RpcStats, Middleware};
|
||||
use ethcore_rpc::{self as rpc, HttpServerError, Metadata, Origin, AccessControlAllowOrigin, Host};
|
||||
use parity_rpc::informant::{RpcStats, Middleware};
|
||||
use parity_rpc::{self as rpc, HttpServerError, Metadata, Origin, DomainsValidation};
|
||||
use helpers::parity_ipc_path;
|
||||
use jsonrpc_core::MetaIoHandler;
|
||||
use jsonrpc_core::{futures, MetaIoHandler};
|
||||
use parity_reactor::TokioRemote;
|
||||
use rpc_apis::{self, ApiSet};
|
||||
|
||||
pub use ethcore_rpc::{IpcServer, HttpServer, RequestMiddleware};
|
||||
pub use parity_rpc::{IpcServer, HttpServer, RequestMiddleware};
|
||||
pub use parity_rpc::ws::Server as WsServer;
|
||||
|
||||
#[derive(Debug, Clone, PartialEq)]
|
||||
pub struct HttpConfiguration {
|
||||
@@ -71,12 +72,25 @@ impl Default for IpcConfiguration {
|
||||
}
|
||||
}
|
||||
|
||||
impl fmt::Display for IpcConfiguration {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
if self.enabled {
|
||||
write!(f, "endpoint address [{}], api list [{:?}]", self.socket_addr, self.apis)
|
||||
} else {
|
||||
write!(f, "disabled")
|
||||
#[derive(Debug, PartialEq)]
|
||||
pub struct WsConfiguration {
|
||||
pub enabled: bool,
|
||||
pub interface: String,
|
||||
pub port: u16,
|
||||
pub apis: ApiSet,
|
||||
pub origins: Option<Vec<String>>,
|
||||
pub hosts: Option<Vec<String>>,
|
||||
}
|
||||
|
||||
impl Default for WsConfiguration {
|
||||
fn default() -> Self {
|
||||
WsConfiguration {
|
||||
enabled: true,
|
||||
interface: "127.0.0.1".into(),
|
||||
port: 8546,
|
||||
apis: ApiSet::UnsafeContext,
|
||||
origins: Some(Vec::new()),
|
||||
hosts: Some(Vec::new()),
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -112,12 +126,115 @@ impl rpc::IpcMetaExtractor<Metadata> for RpcExtractor {
|
||||
}
|
||||
}
|
||||
|
||||
struct Sender(rpc::ws::ws::Sender, futures::sync::mpsc::Receiver<String>);
|
||||
|
||||
impl futures::Future for Sender {
|
||||
type Item = ();
|
||||
type Error = ();
|
||||
|
||||
fn poll(&mut self) -> futures::Poll<Self::Item, Self::Error> {
|
||||
use self::futures::Stream;
|
||||
|
||||
let item = self.1.poll()?;
|
||||
match item {
|
||||
futures::Async::NotReady => {
|
||||
Ok(futures::Async::NotReady)
|
||||
},
|
||||
futures::Async::Ready(None) => {
|
||||
Ok(futures::Async::Ready(()))
|
||||
},
|
||||
futures::Async::Ready(Some(val)) => {
|
||||
if let Err(e) = self.0.send(val) {
|
||||
warn!("Error sending a subscription update: {:?}", e);
|
||||
}
|
||||
self.poll()
|
||||
},
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
struct WsRpcExtractor {
|
||||
remote: TokioRemote,
|
||||
}
|
||||
|
||||
impl WsRpcExtractor {
|
||||
fn wrap_out(&self, out: rpc::ws::ws::Sender) -> futures::sync::mpsc::Sender<String> {
|
||||
let (sender, receiver) = futures::sync::mpsc::channel(8);
|
||||
self.remote.spawn(move |_| Sender(out, receiver));
|
||||
sender
|
||||
}
|
||||
}
|
||||
|
||||
impl rpc::ws::MetaExtractor<Metadata> for WsRpcExtractor {
|
||||
fn extract(&self, req: &rpc::ws::RequestContext) -> Metadata {
|
||||
let mut metadata = Metadata::default();
|
||||
let id = req.session_id as u64;
|
||||
metadata.origin = Origin::Ws(id.into());
|
||||
metadata.session = Some(Arc::new(rpc::PubSubSession::new(
|
||||
self.wrap_out(req.out.clone())
|
||||
)));
|
||||
metadata
|
||||
}
|
||||
}
|
||||
|
||||
struct WsStats {
|
||||
stats: Arc<RpcStats>,
|
||||
}
|
||||
|
||||
impl rpc::ws::SessionStats for WsStats {
|
||||
fn open_session(&self, _id: rpc::ws::SessionId) {
|
||||
self.stats.open_session()
|
||||
}
|
||||
|
||||
fn close_session(&self, _id: rpc::ws::SessionId) {
|
||||
self.stats.close_session()
|
||||
}
|
||||
}
|
||||
|
||||
fn setup_apis<D>(apis: ApiSet, deps: &Dependencies<D>) -> MetaIoHandler<Metadata, Middleware<D::Notifier>>
|
||||
where D: rpc_apis::Dependencies
|
||||
{
|
||||
rpc_apis::setup_rpc(deps.stats.clone(), &*deps.apis, apis)
|
||||
}
|
||||
|
||||
pub fn new_ws<D: rpc_apis::Dependencies>(
|
||||
conf: WsConfiguration,
|
||||
deps: &Dependencies<D>,
|
||||
) -> Result<Option<WsServer>, String> {
|
||||
if !conf.enabled {
|
||||
return Ok(None);
|
||||
}
|
||||
|
||||
let url = format!("{}:{}", conf.interface, conf.port);
|
||||
let addr = url.parse().map_err(|_| format!("Invalid WebSockets listen host/port given: {}", url))?;
|
||||
let handler = setup_apis(conf.apis, deps);
|
||||
let remote = deps.remote.clone();
|
||||
let allowed_origins = into_domains(conf.origins);
|
||||
let allowed_hosts = into_domains(conf.hosts);
|
||||
|
||||
let start_result = rpc::start_ws(
|
||||
&addr,
|
||||
handler,
|
||||
remote.clone(),
|
||||
allowed_origins,
|
||||
allowed_hosts,
|
||||
WsRpcExtractor {
|
||||
remote: remote,
|
||||
},
|
||||
WsStats {
|
||||
stats: deps.stats.clone(),
|
||||
},
|
||||
);
|
||||
|
||||
match start_result {
|
||||
Ok(server) => Ok(Some(server)),
|
||||
Err(rpc::ws::Error::Io(ref err)) if err.kind() == io::ErrorKind::AddrInUse => Err(
|
||||
format!("WebSockets address {} is already in use, make sure that another instance of an Ethereum client is not running or change the address using the --ws-port and --ws-interface options.", url)
|
||||
),
|
||||
Err(e) => Err(format!("WebSockets error: {:?}", e)),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn new_http<D: rpc_apis::Dependencies>(
|
||||
conf: HttpConfiguration,
|
||||
deps: &Dependencies<D>,
|
||||
@@ -128,17 +245,17 @@ pub fn new_http<D: rpc_apis::Dependencies>(
|
||||
}
|
||||
|
||||
let url = format!("{}:{}", conf.interface, conf.port);
|
||||
let addr = url.parse().map_err(|_| format!("Invalid JSONRPC listen host/port given: {}", url))?;
|
||||
let addr = url.parse().map_err(|_| format!("Invalid HTTP JSON-RPC listen host/port given: {}", url))?;
|
||||
let handler = setup_apis(conf.apis, deps);
|
||||
let remote = deps.remote.clone();
|
||||
|
||||
let cors_domains: Option<Vec<_>> = conf.cors.map(|domains| domains.into_iter().map(AccessControlAllowOrigin::from).collect());
|
||||
let allowed_hosts: Option<Vec<_>> = conf.hosts.map(|hosts| hosts.into_iter().map(Host::from).collect());
|
||||
let cors_domains = into_domains(conf.cors);
|
||||
let allowed_hosts = into_domains(conf.hosts);
|
||||
|
||||
let start_result = rpc::start_http(
|
||||
&addr,
|
||||
cors_domains.into(),
|
||||
allowed_hosts.into(),
|
||||
cors_domains,
|
||||
allowed_hosts,
|
||||
handler,
|
||||
remote,
|
||||
RpcExtractor,
|
||||
@@ -153,16 +270,17 @@ pub fn new_http<D: rpc_apis::Dependencies>(
|
||||
|
||||
match start_result {
|
||||
Ok(server) => Ok(Some(server)),
|
||||
Err(HttpServerError::Io(err)) => match err.kind() {
|
||||
io::ErrorKind::AddrInUse => Err(
|
||||
format!("RPC address {} is already in use, make sure that another instance of an Ethereum client is not running or change the address using the --jsonrpc-port and --jsonrpc-interface options.", url)
|
||||
),
|
||||
_ => Err(format!("RPC io error: {}", err)),
|
||||
},
|
||||
Err(e) => Err(format!("RPC error: {:?}", e)),
|
||||
Err(HttpServerError::Io(ref err)) if err.kind() == io::ErrorKind::AddrInUse => Err(
|
||||
format!("HTTP address {} is already in use, make sure that another instance of an Ethereum client is not running or change the address using the --jsonrpc-port and --jsonrpc-interface options.", url)
|
||||
),
|
||||
Err(e) => Err(format!("HTTP error: {:?}", e)),
|
||||
}
|
||||
}
|
||||
|
||||
fn into_domains<T: From<String>>(items: Option<Vec<String>>) -> DomainsValidation<T> {
|
||||
items.map(|vals| vals.into_iter().map(T::from).collect()).into()
|
||||
}
|
||||
|
||||
pub fn new_ipc<D: rpc_apis::Dependencies>(
|
||||
conf: IpcConfiguration,
|
||||
dependencies: &Dependencies<D>
|
||||
@@ -170,18 +288,26 @@ pub fn new_ipc<D: rpc_apis::Dependencies>(
|
||||
if !conf.enabled {
|
||||
return Ok(None);
|
||||
}
|
||||
|
||||
let handler = setup_apis(conf.apis, dependencies);
|
||||
let remote = dependencies.remote.clone();
|
||||
match rpc::start_ipc(&conf.socket_addr, handler, remote, RpcExtractor) {
|
||||
let ipc = rpc::start_ipc(
|
||||
&conf.socket_addr,
|
||||
handler,
|
||||
remote,
|
||||
RpcExtractor,
|
||||
);
|
||||
|
||||
match ipc {
|
||||
Ok(server) => Ok(Some(server)),
|
||||
Err(io_error) => Err(format!("RPC io error: {}", io_error)),
|
||||
Err(io_error) => Err(format!("IPC error: {}", io_error)),
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::RpcExtractor;
|
||||
use ethcore_rpc::{HttpMetaExtractor, Origin};
|
||||
use parity_rpc::{HttpMetaExtractor, Origin};
|
||||
|
||||
#[test]
|
||||
fn should_extract_rpc_origin() {
|
||||
|
||||
@@ -20,22 +20,23 @@ use std::collections::HashSet;
|
||||
use std::str::FromStr;
|
||||
use std::sync::Arc;
|
||||
|
||||
pub use ethcore_rpc::SignerService;
|
||||
pub use parity_rpc::SignerService;
|
||||
|
||||
use ethcore::account_provider::AccountProvider;
|
||||
use ethcore::client::Client;
|
||||
use ethcore::miner::{Miner, ExternalMiner};
|
||||
use ethcore::snapshot::SnapshotService;
|
||||
use ethcore_rpc::{Metadata, NetworkSettings};
|
||||
use ethcore_rpc::informant::{ActivityNotifier, Middleware, RpcStats, ClientNotifier};
|
||||
use ethcore_rpc::dispatch::{FullDispatcher, LightDispatcher};
|
||||
use parity_rpc::{Metadata, NetworkSettings};
|
||||
use parity_rpc::informant::{ActivityNotifier, Middleware, RpcStats, ClientNotifier};
|
||||
use parity_rpc::dispatch::{FullDispatcher, LightDispatcher};
|
||||
use ethsync::{ManageNetwork, SyncProvider, LightSync};
|
||||
use hash_fetch::fetch::Client as FetchClient;
|
||||
use jsonrpc_core::{MetaIoHandler};
|
||||
use jsonrpc_core::{self as core, MetaIoHandler};
|
||||
use light::{TransactionQueue as LightTransactionQueue, Cache as LightDataCache};
|
||||
use updater::Updater;
|
||||
use util::{Mutex, RwLock};
|
||||
use ethcore_logger::RotatingLogger;
|
||||
use parity_reactor;
|
||||
|
||||
#[derive(Debug, PartialEq, Clone, Eq, Hash)]
|
||||
pub enum Api {
|
||||
@@ -59,6 +60,8 @@ pub enum Api {
|
||||
Traces,
|
||||
/// Rpc (Safe)
|
||||
Rpc,
|
||||
/// SecretStore (Safe)
|
||||
SecretStore,
|
||||
}
|
||||
|
||||
impl FromStr for Api {
|
||||
@@ -78,6 +81,7 @@ impl FromStr for Api {
|
||||
"parity_set" => Ok(ParitySet),
|
||||
"traces" => Ok(Traces),
|
||||
"rpc" => Ok(Rpc),
|
||||
"secretstore" => Ok(SecretStore),
|
||||
api => Err(format!("Unknown api: {}", api))
|
||||
}
|
||||
}
|
||||
@@ -156,6 +160,7 @@ fn to_modules(apis: &[Api]) -> BTreeMap<String, String> {
|
||||
Api::ParitySet => ("parity_set", "1.0"),
|
||||
Api::Traces => ("traces", "1.0"),
|
||||
Api::Rpc => ("rpc", "1.0"),
|
||||
Api::SecretStore => ("secretstore", "1.0"),
|
||||
};
|
||||
modules.insert(name.into(), version.into());
|
||||
}
|
||||
@@ -191,19 +196,17 @@ pub struct FullDependencies {
|
||||
pub dapps_interface: Option<String>,
|
||||
pub dapps_port: Option<u16>,
|
||||
pub fetch: FetchClient,
|
||||
pub remote: parity_reactor::Remote,
|
||||
}
|
||||
|
||||
impl Dependencies for FullDependencies {
|
||||
type Notifier = ClientNotifier;
|
||||
|
||||
fn activity_notifier(&self) -> ClientNotifier {
|
||||
ClientNotifier {
|
||||
client: self.client.clone(),
|
||||
}
|
||||
}
|
||||
|
||||
fn extend_with_set(&self, handler: &mut MetaIoHandler<Metadata, Middleware>, apis: &[Api]) {
|
||||
use ethcore_rpc::v1::*;
|
||||
impl FullDependencies {
|
||||
fn extend_api<T: core::Middleware<Metadata>>(
|
||||
&self,
|
||||
handler: &mut MetaIoHandler<Metadata, T>,
|
||||
apis: &[Api],
|
||||
for_generic_pubsub: bool,
|
||||
) {
|
||||
use parity_rpc::v1::*;
|
||||
|
||||
macro_rules! add_signing_methods {
|
||||
($namespace:ident, $handler:expr, $deps:expr) => {
|
||||
@@ -244,10 +247,12 @@ impl Dependencies for FullDependencies {
|
||||
);
|
||||
handler.extend_with(client.to_delegate());
|
||||
|
||||
let filter_client = EthFilterClient::new(self.client.clone(), self.miner.clone());
|
||||
handler.extend_with(filter_client.to_delegate());
|
||||
if !for_generic_pubsub {
|
||||
let filter_client = EthFilterClient::new(self.client.clone(), self.miner.clone());
|
||||
handler.extend_with(filter_client.to_delegate());
|
||||
|
||||
add_signing_methods!(EthSigning, handler, self);
|
||||
add_signing_methods!(EthSigning, handler, self);
|
||||
}
|
||||
},
|
||||
Api::Personal => {
|
||||
handler.extend_with(PersonalClient::new(&self.secret_store, dispatcher.clone(), self.geth_compatibility).to_delegate());
|
||||
@@ -274,8 +279,14 @@ impl Dependencies for FullDependencies {
|
||||
self.dapps_port,
|
||||
).to_delegate());
|
||||
|
||||
add_signing_methods!(EthSigning, handler, self);
|
||||
add_signing_methods!(ParitySigning, handler, self);
|
||||
if !for_generic_pubsub {
|
||||
let mut rpc = MetaIoHandler::default();
|
||||
self.extend_api(&mut rpc, apis, true);
|
||||
handler.extend_with(PubSubClient::new(rpc, self.remote.clone()).to_delegate());
|
||||
|
||||
add_signing_methods!(EthSigning, handler, self);
|
||||
add_signing_methods!(ParitySigning, handler, self);
|
||||
}
|
||||
},
|
||||
Api::ParityAccounts => {
|
||||
handler.extend_with(ParityAccountsClient::new(&self.secret_store).to_delegate());
|
||||
@@ -295,12 +306,29 @@ impl Dependencies for FullDependencies {
|
||||
Api::Rpc => {
|
||||
let modules = to_modules(&apis);
|
||||
handler.extend_with(RpcClient::new(modules).to_delegate());
|
||||
}
|
||||
},
|
||||
Api::SecretStore => {
|
||||
handler.extend_with(SecretStoreClient::new(&self.secret_store).to_delegate());
|
||||
},
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Dependencies for FullDependencies {
|
||||
type Notifier = ClientNotifier;
|
||||
|
||||
fn activity_notifier(&self) -> ClientNotifier {
|
||||
ClientNotifier {
|
||||
client: self.client.clone(),
|
||||
}
|
||||
}
|
||||
|
||||
fn extend_with_set(&self, handler: &mut MetaIoHandler<Metadata, Middleware<Self::Notifier>>, apis: &[Api]) {
|
||||
self.extend_api(handler, apis, false)
|
||||
}
|
||||
}
|
||||
|
||||
/// Light client notifier. Doesn't do anything yet, but might in the future.
|
||||
pub struct LightClientNotifier;
|
||||
|
||||
@@ -331,7 +359,7 @@ impl Dependencies for LightDependencies {
|
||||
|
||||
fn activity_notifier(&self) -> Self::Notifier { LightClientNotifier }
|
||||
fn extend_with_set(&self, handler: &mut MetaIoHandler<Metadata, Middleware<Self::Notifier>>, apis: &[Api]) {
|
||||
use ethcore_rpc::v1::*;
|
||||
use parity_rpc::v1::*;
|
||||
|
||||
let dispatcher = LightDispatcher::new(
|
||||
self.sync.clone(),
|
||||
@@ -395,6 +423,7 @@ impl Dependencies for LightDependencies {
|
||||
false => None,
|
||||
};
|
||||
handler.extend_with(light::ParityClient::new(
|
||||
self.client.clone(),
|
||||
Arc::new(dispatcher.clone()),
|
||||
self.secret_store.clone(),
|
||||
self.logger.clone(),
|
||||
@@ -423,7 +452,11 @@ impl Dependencies for LightDependencies {
|
||||
Api::Rpc => {
|
||||
let modules = to_modules(&apis);
|
||||
handler.extend_with(RpcClient::new(modules).to_delegate());
|
||||
}
|
||||
},
|
||||
Api::SecretStore => {
|
||||
let secret_store = Some(self.secret_store.clone());
|
||||
handler.extend_with(SecretStoreClient::new(&secret_store).to_delegate());
|
||||
},
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -437,7 +470,7 @@ impl ApiSet {
|
||||
|
||||
pub fn list_apis(&self) -> HashSet<Api> {
|
||||
let mut public_list = vec![
|
||||
Api::Web3, Api::Net, Api::Eth, Api::Parity, Api::Rpc,
|
||||
Api::Web3, Api::Net, Api::Eth, Api::Parity, Api::Rpc, Api::SecretStore,
|
||||
].into_iter().collect();
|
||||
match *self {
|
||||
ApiSet::List(ref apis) => apis.clone(),
|
||||
@@ -495,6 +528,7 @@ mod test {
|
||||
assert_eq!(Api::ParitySet, "parity_set".parse().unwrap());
|
||||
assert_eq!(Api::Traces, "traces".parse().unwrap());
|
||||
assert_eq!(Api::Rpc, "rpc".parse().unwrap());
|
||||
assert_eq!(Api::SecretStore, "secretstore".parse().unwrap());
|
||||
assert!("rp".parse::<Api>().is_err());
|
||||
}
|
||||
|
||||
@@ -512,7 +546,7 @@ mod test {
|
||||
fn test_api_set_unsafe_context() {
|
||||
let expected = vec![
|
||||
// make sure this list contains only SAFE methods
|
||||
Api::Web3, Api::Net, Api::Eth, Api::Parity, Api::Traces, Api::Rpc
|
||||
Api::Web3, Api::Net, Api::Eth, Api::Parity, Api::Traces, Api::Rpc, Api::SecretStore
|
||||
].into_iter().collect();
|
||||
assert_eq!(ApiSet::UnsafeContext.list_apis(), expected);
|
||||
}
|
||||
@@ -521,7 +555,7 @@ mod test {
|
||||
fn test_api_set_ipc_context() {
|
||||
let expected = vec![
|
||||
// safe
|
||||
Api::Web3, Api::Net, Api::Eth, Api::Parity, Api::Traces, Api::Rpc,
|
||||
Api::Web3, Api::Net, Api::Eth, Api::Parity, Api::Traces, Api::Rpc, Api::SecretStore,
|
||||
// semi-safe
|
||||
Api::ParityAccounts
|
||||
].into_iter().collect();
|
||||
@@ -532,7 +566,7 @@ mod test {
|
||||
fn test_api_set_safe_context() {
|
||||
let expected = vec![
|
||||
// safe
|
||||
Api::Web3, Api::Net, Api::Eth, Api::Parity, Api::Traces, Api::Rpc,
|
||||
Api::Web3, Api::Net, Api::Eth, Api::Parity, Api::Traces, Api::Rpc, Api::SecretStore,
|
||||
// semi-safe
|
||||
Api::ParityAccounts,
|
||||
// Unsafe
|
||||
@@ -544,7 +578,7 @@ mod test {
|
||||
#[test]
|
||||
fn test_all_apis() {
|
||||
assert_eq!("all".parse::<ApiSet>().unwrap(), ApiSet::List(vec![
|
||||
Api::Web3, Api::Net, Api::Eth, Api::Parity, Api::Traces, Api::Rpc,
|
||||
Api::Web3, Api::Net, Api::Eth, Api::Parity, Api::Traces, Api::Rpc, Api::SecretStore,
|
||||
Api::ParityAccounts,
|
||||
Api::ParitySet, Api::Signer,
|
||||
Api::Personal
|
||||
@@ -554,7 +588,7 @@ mod test {
|
||||
#[test]
|
||||
fn test_all_without_personal_apis() {
|
||||
assert_eq!("personal,all,-personal".parse::<ApiSet>().unwrap(), ApiSet::List(vec![
|
||||
Api::Web3, Api::Net, Api::Eth, Api::Parity, Api::Traces, Api::Rpc,
|
||||
Api::Web3, Api::Net, Api::Eth, Api::Parity, Api::Traces, Api::Rpc, Api::SecretStore,
|
||||
Api::ParityAccounts,
|
||||
Api::ParitySet, Api::Signer,
|
||||
].into_iter().collect()));
|
||||
@@ -563,7 +597,7 @@ mod test {
|
||||
#[test]
|
||||
fn test_safe_parsing() {
|
||||
assert_eq!("safe".parse::<ApiSet>().unwrap(), ApiSet::List(vec![
|
||||
Api::Web3, Api::Net, Api::Eth, Api::Parity, Api::Traces, Api::Rpc,
|
||||
Api::Web3, Api::Net, Api::Eth, Api::Parity, Api::Traces, Api::Rpc, Api::SecretStore,
|
||||
].into_iter().collect()));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -18,7 +18,7 @@ use std::sync::Arc;
|
||||
use std::net::{TcpListener};
|
||||
use ctrlc::CtrlC;
|
||||
use fdlimit::raise_fd_limit;
|
||||
use ethcore_rpc::{NetworkSettings, informant, is_major_importing};
|
||||
use parity_rpc::{NetworkSettings, informant, is_major_importing};
|
||||
use ethsync::NetworkConfiguration;
|
||||
use util::{Colour, version, Mutex, Condvar};
|
||||
use io::{MayPanic, ForwardPanic, PanicHandler};
|
||||
@@ -80,6 +80,7 @@ pub struct RunCmd {
|
||||
pub daemon: Option<String>,
|
||||
pub logger_config: LogConfig,
|
||||
pub miner_options: MinerOptions,
|
||||
pub ws_conf: rpc::WsConfiguration,
|
||||
pub http_conf: rpc::HttpConfiguration,
|
||||
pub ipc_conf: rpc::IpcConfiguration,
|
||||
pub net_conf: NetworkConfiguration,
|
||||
@@ -114,6 +115,7 @@ pub struct RunCmd {
|
||||
pub verifier_settings: VerifierSettings,
|
||||
pub serve_light: bool,
|
||||
pub light: bool,
|
||||
pub no_persistent_txqueue: bool,
|
||||
}
|
||||
|
||||
pub fn open_ui(signer_conf: &signer::Configuration) -> Result<(), String> {
|
||||
@@ -141,15 +143,20 @@ pub fn open_dapp(dapps_conf: &dapps::Configuration, rpc_conf: &rpc::HttpConfigur
|
||||
|
||||
// node info fetcher for the local store.
|
||||
struct FullNodeInfo {
|
||||
miner: Arc<Miner>, // TODO: only TXQ needed, just use that after decoupling.
|
||||
miner: Option<Arc<Miner>>, // TODO: only TXQ needed, just use that after decoupling.
|
||||
}
|
||||
|
||||
impl ::local_store::NodeInfo for FullNodeInfo {
|
||||
fn pending_transactions(&self) -> Vec<::ethcore::transaction::PendingTransaction> {
|
||||
let local_txs = self.miner.local_transactions();
|
||||
self.miner.pending_transactions()
|
||||
let miner = match self.miner.as_ref() {
|
||||
Some(m) => m,
|
||||
None => return Vec::new(),
|
||||
};
|
||||
|
||||
let local_txs = miner.local_transactions();
|
||||
miner.pending_transactions()
|
||||
.into_iter()
|
||||
.chain(self.miner.future_transactions())
|
||||
.chain(miner.future_transactions())
|
||||
.filter(|tx| local_txs.contains_key(&tx.hash()))
|
||||
.collect()
|
||||
}
|
||||
@@ -294,7 +301,8 @@ fn execute_light(cmd: RunCmd, can_restart: bool, logger: Arc<RotatingLogger>) ->
|
||||
};
|
||||
|
||||
// start rpc servers
|
||||
let _http_server = rpc::new_http(cmd.http_conf, &dependencies, None)?;
|
||||
let _ws_server = rpc::new_ws(cmd.ws_conf, &dependencies)?;
|
||||
let _http_server = rpc::new_http(cmd.http_conf.clone(), &dependencies, None)?;
|
||||
let _ipc_server = rpc::new_ipc(cmd.ipc_conf, &dependencies)?;
|
||||
|
||||
// the signer server
|
||||
@@ -512,11 +520,22 @@ pub fn execute(cmd: RunCmd, can_restart: bool, logger: Arc<RotatingLogger>) -> R
|
||||
let store = {
|
||||
let db = service.db();
|
||||
let node_info = FullNodeInfo {
|
||||
miner: miner.clone(),
|
||||
miner: match cmd.no_persistent_txqueue {
|
||||
true => None,
|
||||
false => Some(miner.clone()),
|
||||
}
|
||||
};
|
||||
|
||||
let store = ::local_store::create(db, ::ethcore::db::COL_NODE_INFO, node_info);
|
||||
|
||||
if cmd.no_persistent_txqueue {
|
||||
info!("Running without a persistent transaction queue.");
|
||||
|
||||
if let Err(e) = store.clear() {
|
||||
warn!("Error clearing persistent transaction queue: {}", e);
|
||||
}
|
||||
}
|
||||
|
||||
// re-queue pending transactions.
|
||||
match store.pending_transactions() {
|
||||
Ok(pending) => {
|
||||
@@ -611,6 +630,7 @@ pub fn execute(cmd: RunCmd, can_restart: bool, logger: Arc<RotatingLogger>) -> R
|
||||
false => None,
|
||||
},
|
||||
fetch: fetch.clone(),
|
||||
remote: event_loop.remote(),
|
||||
});
|
||||
|
||||
let dependencies = rpc::Dependencies {
|
||||
@@ -635,6 +655,7 @@ pub fn execute(cmd: RunCmd, can_restart: bool, logger: Arc<RotatingLogger>) -> R
|
||||
let dapps_middleware = dapps::new(cmd.dapps_conf.clone(), dapps_deps)?;
|
||||
|
||||
// start rpc servers
|
||||
let ws_server = rpc::new_ws(cmd.ws_conf, &dependencies)?;
|
||||
let http_server = rpc::new_http(cmd.http_conf.clone(), &dependencies, dapps_middleware)?;
|
||||
let ipc_server = rpc::new_ipc(cmd.ipc_conf, &dependencies)?;
|
||||
|
||||
@@ -715,7 +736,7 @@ pub fn execute(cmd: RunCmd, can_restart: bool, logger: Arc<RotatingLogger>) -> R
|
||||
let restart = wait_for_exit(panic_handler, Some(updater), Some(client), can_restart);
|
||||
|
||||
// drop this stuff as soon as exit detected.
|
||||
drop((http_server, ipc_server, signer_server, secretstore_key_server, ipfs_server, event_loop));
|
||||
drop((ws_server, http_server, ipc_server, signer_server, secretstore_key_server, ipfs_server, event_loop));
|
||||
|
||||
info!("Finishing work, please wait...");
|
||||
|
||||
|
||||
@@ -96,9 +96,6 @@ mod server {
|
||||
port: port,
|
||||
})).collect(),
|
||||
allow_connecting_to_higher_nodes: true,
|
||||
encryption_config: ethcore_secretstore::EncryptionConfiguration {
|
||||
key_check_timeout_ms: 1000,
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
|
||||
@@ -22,8 +22,8 @@ pub use ethcore_signer::Server as SignerServer;
|
||||
|
||||
use ansi_term::Colour;
|
||||
use dir::default_data_path;
|
||||
use ethcore_rpc::informant::RpcStats;
|
||||
use ethcore_rpc::{self, ConfirmationsQueue};
|
||||
use parity_rpc::informant::RpcStats;
|
||||
use parity_rpc::{self, ConfirmationsQueue};
|
||||
use ethcore_signer as signer;
|
||||
use helpers::replace_home;
|
||||
use parity_reactor::TokioRemote;
|
||||
@@ -69,10 +69,10 @@ pub struct NewToken {
|
||||
|
||||
#[derive(Debug, Default, Clone)]
|
||||
pub struct StandardExtractor;
|
||||
impl signer::MetaExtractor<ethcore_rpc::Metadata> for StandardExtractor {
|
||||
fn extract_metadata(&self, session: &H256) -> ethcore_rpc::Metadata {
|
||||
let mut metadata = ethcore_rpc::Metadata::default();
|
||||
metadata.origin = ethcore_rpc::Origin::Signer((*session).into());
|
||||
impl signer::MetaExtractor<parity_rpc::Metadata> for StandardExtractor {
|
||||
fn extract_metadata(&self, session: &H256) -> parity_rpc::Metadata {
|
||||
let mut metadata = parity_rpc::Metadata::default();
|
||||
metadata.origin = parity_rpc::Origin::Signer((*session).into());
|
||||
metadata
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user