Merge branch 'master' into jsonrpc_panic_handle

This commit is contained in:
debris 2016-03-09 13:46:08 +01:00
commit 3655354980
3 changed files with 106 additions and 48 deletions

View File

@ -87,6 +87,8 @@ pub struct ClientConfig {
pub blockchain: BlockChainConfig,
/// Prefer journal rather than archive.
pub prefer_journal: bool,
/// The name of the client instance.
pub name: String,
}
impl Default for ClientConfig {
@ -95,6 +97,7 @@ impl Default for ClientConfig {
queue: Default::default(),
blockchain: Default::default(),
prefer_journal: false,
name: Default::default(),
}
}
}

View File

@ -53,6 +53,16 @@ use docopt::Docopt;
use daemonize::Daemonize;
use number_prefix::{binary_prefix, Standalone, Prefixed};
fn die_with_message(msg: &str) -> ! {
println!("ERROR: {}", msg);
exit(1);
}
#[macro_export]
macro_rules! die {
($($arg:tt)*) => (die_with_message(&format!("{}", format_args!($($arg)*))));
}
const USAGE: &'static str = r#"
Parity. Ethereum Client.
By Wood/Paronyan/Kotewicz/Drwięga/Volf.
@ -62,13 +72,17 @@ Usage:
parity daemon <pid-file> [options] [ --no-bootstrap | <enode>... ]
parity [options] [ --no-bootstrap | <enode>... ]
Options:
Protocol Options:
--chain CHAIN Specify the blockchain type. CHAIN may be either a JSON chain specification file
or frontier, mainnet, morden, or testnet [default: frontier].
or olympic, frontier, homestead, mainnet, morden, or testnet [default: homestead].
--testnet Equivalent to --chain testnet (geth-compatible).
--networkid INDEX Override the network identifier from the chain we are on.
--archive Client should not prune the state/storage trie.
-d --db-path PATH Specify the database & configuration directory path [default: $HOME/.parity]
-d --datadir PATH Specify the database & configuration directory path [default: $HOME/.parity]
--keys-path PATH Specify the path for JSON key files to be found [default: $HOME/.web3/keys]
--identity NAME Specify your node's name.
Networking Options:
--no-bootstrap Don't bother trying to connect to any nodes initially.
--listen-address URL Specify the IP/port on which to listen for peers [default: 0.0.0.0:30304].
--public-address URL Specify the IP/port on which peers may connect.
@ -78,18 +92,32 @@ Options:
--no-upnp Disable trying to figure out the correct public adderss over UPnP.
--node-key KEY Specify node secret key, either as 64-character hex string or input to SHA3 operation.
API and Console Options:
-j --jsonrpc Enable the JSON-RPC API sever.
--jsonrpc-addr HOST Specify the hostname portion of the JSONRPC API server [default: 127.0.0.1].
--jsonrpc-port PORT Specify the port portion of the JSONRPC API server [default: 8545].
--jsonrpc-cors URL Specify CORS header for JSON-RPC API responses [default: null].
--jsonrpc-apis APIS Specify the APIs available through the JSONRPC interface. APIS is a comma-delimited
list of API name. Possible name are web3, eth and net. [default: web3,eth,net].
--rpc Equivalent to --jsonrpc (geth-compatible).
--rpcaddr HOST Equivalent to --jsonrpc-addr HOST (geth-compatible).
--rpcport PORT Equivalent to --jsonrpc-port PORT (geth-compatible).
--rpcapi APIS Equivalent to --jsonrpc-apis APIS (geth-compatible).
--rpccorsdomain URL Equivalent to --jsonrpc-cors URL (geth-compatible).
Sealing/Mining Options:
--author ADDRESS Specify the block author (aka "coinbase") address for sending block rewards
from sealed blocks [default: 0037a6b811ffeb6e072da21179d11b1406371c63].
--extradata STRING Specify a custom extra-data for authored blocks, no more than 32 characters.
Memory Footprint Options:
--cache-pref-size BYTES Specify the prefered size of the blockchain cache in bytes [default: 16384].
--cache-max-size BYTES Specify the maximum size of the blockchain cache in bytes [default: 262144].
--queue-max-size BYTES Specify the maximum size of memory to use for block queue [default: 52428800].
--cache MEGABYTES Set total amount of cache to use for the entire system, mutually exclusive with
other cache options (geth-compatible).
-j --jsonrpc Enable the JSON-RPC API sever.
--jsonrpc-url URL Specify URL for JSON-RPC API server [default: 127.0.0.1:8545].
--jsonrpc-cors URL Specify CORS header for JSON-RPC API responses [default: null].
--author ADDRESS Specify the block author (aka "coinbase") address for sending block rewards
from sealed blocks [default: 0037a6b811ffeb6e072da21179d11b1406371c63].
--extra-data STRING Specify a custom extra-data for authored blocks, no more than 32 characters.
Miscellaneous Options:
-l --logging LOGGING Specify the logging level.
-v --version Show information about version.
-h --help Show this screen.
@ -101,14 +129,18 @@ struct Args {
arg_pid_file: String,
arg_enode: Vec<String>,
flag_chain: String,
flag_db_path: String,
flag_testnet: bool,
flag_datadir: String,
flag_networkid: Option<String>,
flag_identity: String,
flag_cache: Option<usize>,
flag_keys_path: String,
flag_archive: bool,
flag_no_bootstrap: bool,
flag_listen_address: String,
flag_public_address: Option<String>,
flag_address: Option<String>,
flag_peers: u32,
flag_peers: usize,
flag_no_discovery: bool,
flag_no_upnp: bool,
flag_node_key: Option<String>,
@ -116,8 +148,15 @@ struct Args {
flag_cache_max_size: usize,
flag_queue_max_size: usize,
flag_jsonrpc: bool,
flag_jsonrpc_url: String,
flag_jsonrpc_addr: String,
flag_jsonrpc_port: u16,
flag_jsonrpc_cors: String,
flag_jsonrpc_apis: String,
flag_rpc: bool,
flag_rpcaddr: Option<String>,
flag_rpcport: Option<u16>,
flag_rpccorsdomain: Option<String>,
flag_rpcapi: Option<String>,
flag_logging: Option<String>,
flag_version: bool,
flag_author: String,
@ -151,14 +190,23 @@ fn setup_log(init: &Option<String>) {
}
#[cfg(feature = "rpc")]
fn setup_rpc_server(client: Arc<Client>, sync: Arc<EthSync>, url: &str, cors_domain: &str) -> Option<Arc<PanicHandler>> {
fn setup_rpc_server(client: Arc<Client>, sync: Arc<EthSync>, url: &str, cors_domain: &str, apis: Vec<&str>) -> Option<Arc<PanicHandler>> {
use rpc::v1::*;
let mut server = rpc::HttpServer::new(1);
server.add_delegate(Web3Client::new().to_delegate());
server.add_delegate(EthClient::new(&client, &sync).to_delegate());
server.add_delegate(EthFilterClient::new(&client).to_delegate());
server.add_delegate(NetClient::new(&sync).to_delegate());
for api in apis.into_iter() {
match api {
"web3" => server.add_delegate(Web3Client::new().to_delegate()),
"net" => server.add_delegate(NetClient::new(&sync).to_delegate()),
"eth" => {
server.add_delegate(EthClient::new(&client, &sync).to_delegate());
server.add_delegate(EthFilterClient::new(&client).to_delegate());
}
_ => {
die!("{}: Invalid API name to be enabled.", api);
}
}
}
Some(server.start_async(url, cors_domain))
}
@ -180,16 +228,6 @@ By Wood/Paronyan/Kotewicz/Drwięga/Volf.\
", version());
}
fn die_with_message(msg: &str) -> ! {
println!("ERROR: {}", msg);
exit(1);
}
#[macro_export]
macro_rules! die {
($($arg:tt)*) => (die_with_message(&format!("{}", format_args!($($arg)*))));
}
struct Configuration {
args: Args
}
@ -202,7 +240,7 @@ impl Configuration {
}
fn path(&self) -> String {
self.args.flag_db_path.replace("$HOME", env::home_dir().unwrap().to_str().unwrap())
self.args.flag_datadir.replace("$HOME", env::home_dir().unwrap().to_str().unwrap())
}
fn author(&self) -> Address {
@ -222,8 +260,11 @@ impl Configuration {
}
fn spec(&self) -> Spec {
if self.args.flag_testnet {
return ethereum::new_morden();
}
match self.args.flag_chain.as_ref() {
"frontier" | "mainnet" => ethereum::new_frontier(),
"frontier" | "homestead" | "mainnet" => ethereum::new_frontier(),
"morden" | "testnet" => ethereum::new_morden(),
"olympic" => ethereum::new_olympic(),
f => Spec::from_json_utf8(contents(f).unwrap_or_else(|_| die!("{}: Couldn't read chain specification file. Sure it exists?", f)).as_ref()),
@ -277,7 +318,7 @@ impl Configuration {
ret.public_address = public;
ret.use_secret = self.args.flag_node_key.as_ref().map(|s| Secret::from_str(&s).unwrap_or_else(|_| s.sha3()));
ret.discovery_enabled = !self.args.flag_no_discovery;
ret.ideal_peers = self.args.flag_peers;
ret.ideal_peers = self.args.flag_peers as u32;
let mut net_path = PathBuf::from(&self.path());
net_path.push("network");
ret.config_path = Some(net_path.to_str().unwrap().to_owned());
@ -308,13 +349,22 @@ impl Configuration {
let spec = self.spec();
let net_settings = self.net_settings(&spec);
let mut sync_config = SyncConfig::default();
sync_config.network_id = spec.network_id();
sync_config.network_id = self.args.flag_networkid.as_ref().map(|id| U256::from_str(id).unwrap_or_else(|_| die!("{}: Invalid index given with --networkid", id))).unwrap_or(spec.network_id());
// Build client
let mut client_config = ClientConfig::default();
client_config.blockchain.pref_cache_size = self.args.flag_cache_pref_size;
client_config.blockchain.max_cache_size = self.args.flag_cache_max_size;
match self.args.flag_cache {
Some(mb) => {
client_config.blockchain.max_cache_size = mb * 1024 * 1024;
client_config.blockchain.pref_cache_size = client_config.blockchain.max_cache_size / 2;
}
None => {
client_config.blockchain.pref_cache_size = self.args.flag_cache_pref_size;
client_config.blockchain.max_cache_size = self.args.flag_cache_max_size;
}
}
client_config.prefer_journal = !self.args.flag_archive;
client_config.name = self.args.flag_identity.clone();
client_config.queue.max_mem_use = self.args.flag_queue_max_size;
let mut service = ClientService::start(client_config, spec, net_settings, &Path::new(&self.path())).unwrap();
let client = service.client().clone();
@ -324,6 +374,21 @@ impl Configuration {
// Sync
let sync = EthSync::register(service.network(), sync_config, client);
// Setup rpc
let server_handler = if self.args.flag_jsonrpc || self.args.flag_rpc {
let url = format!("{}:{}",
self.args.flag_rpcaddr.as_ref().unwrap_or(&self.args.flag_jsonrpc_addr),
self.args.flag_rpcport.unwrap_or(self.args.flag_jsonrpc_port)
);
SocketAddr::from_str(&url).unwrap_or_else(|_|die!("{}: Invalid JSONRPC listen host/port given.", url));
let cors = self.args.flag_rpccorsdomain.as_ref().unwrap_or(&self.args.flag_jsonrpc_cors);
// TODO: use this as the API list.
let apis = self.args.flag_rpcapi.as_ref().unwrap_or(&self.args.flag_jsonrpc_apis);
setup_rpc_server(service.client(), sync.clone(), &url, cors, apis.split(",").collect())
} else {
None
};
// Register IO handler
let io_handler = Arc::new(ClientIoHandler {
client: service.client(),
@ -332,14 +397,6 @@ impl Configuration {
});
service.io().register_handler(io_handler).expect("Error registering IO handler");
// Setup rpc
let server_handler = if self.args.flag_jsonrpc {
SocketAddr::from_str(&self.args.flag_jsonrpc_url).unwrap_or_else(|_|die!("{}: Invalid JSONRPC listen address given with --jsonrpc-url. Should be of the form 'IP:port'.", self.args.flag_jsonrpc_url));
setup_rpc_server(service.client(), sync, &self.args.flag_jsonrpc_url, &self.args.flag_jsonrpc_cors)
} else {
None
};
// Handle exit
wait_for_exit(&service, server_handler);
}

View File

@ -575,7 +575,7 @@ impl ChainSync {
pub fn on_peer_connected(&mut self, io: &mut SyncIo, peer: PeerId) {
trace!(target: "sync", "== Connected {}", peer);
if let Err(e) = self.send_status(io) {
trace!(target:"sync", "Error sending status request: {:?}", e);
warn!(target:"sync", "Error sending status request: {:?}", e);
io.disable_peer(peer);
}
}
@ -900,9 +900,8 @@ impl ChainSync {
}
match sync.send(peer_id, packet_id, packet) {
Err(e) => {
warn!(target:"sync", "Error sending request: {:?}", e);
debug!(target:"sync", "Error sending request: {:?}", e);
sync.disable_peer(peer_id);
self.on_peer_aborting(sync, peer_id);
}
Ok(_) => {
let mut peer = self.peers.get_mut(&peer_id).unwrap();
@ -915,9 +914,8 @@ impl ChainSync {
/// Generic packet sender
fn send_packet(&mut self, sync: &mut SyncIo, peer_id: PeerId, packet_id: PacketId, packet: Bytes) {
if let Err(e) = sync.send(peer_id, packet_id, packet) {
warn!(target:"sync", "Error sending packet: {:?}", e);
debug!(target:"sync", "Error sending packet: {:?}", e);
sync.disable_peer(peer_id);
self.on_peer_aborting(sync, peer_id);
}
}
/// Called when peer sends us new transactions