Separating RPC
This commit is contained in:
parent
3c665f7640
commit
09b2d7b3a6
54
parity/die.rs
Normal file
54
parity/die.rs
Normal file
@ -0,0 +1,54 @@
|
|||||||
|
// Copyright 2015, 2016 Ethcore (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;
|
||||||
|
use ethcore;
|
||||||
|
use util::UtilError;
|
||||||
|
use std::process::exit;
|
||||||
|
|
||||||
|
#[macro_export]
|
||||||
|
macro_rules! die {
|
||||||
|
($($arg:tt)*) => (die_with_message(&format!("{}", format_args!($($arg)*))));
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn die_with_error(e: ethcore::error::Error) -> ! {
|
||||||
|
use ethcore::error::Error;
|
||||||
|
|
||||||
|
match e {
|
||||||
|
Error::Util(UtilError::StdIo(e)) => die_with_io_error(e),
|
||||||
|
_ => die!("{:?}", e),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn die_with_io_error(e: std::io::Error) -> ! {
|
||||||
|
match e.kind() {
|
||||||
|
std::io::ErrorKind::PermissionDenied => {
|
||||||
|
die!("No permissions to bind to specified port.")
|
||||||
|
},
|
||||||
|
std::io::ErrorKind::AddrInUse => {
|
||||||
|
die!("Specified address is already in use. Please make sure that nothing is listening on the same port or try using a different one.")
|
||||||
|
},
|
||||||
|
std::io::ErrorKind::AddrNotAvailable => {
|
||||||
|
die!("Could not use specified interface or given address is invalid.")
|
||||||
|
},
|
||||||
|
_ => die!("{:?}", e),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn die_with_message(msg: &str) -> ! {
|
||||||
|
println!("ERROR: {}", msg);
|
||||||
|
exit(1);
|
||||||
|
}
|
@ -116,6 +116,7 @@ impl Hypervisor {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
use super::*;
|
use super::*;
|
||||||
use std::sync::atomic::{AtomicBool,Ordering};
|
use std::sync::atomic::{AtomicBool,Ordering};
|
||||||
|
142
parity/main.rs
142
parity/main.rs
@ -20,6 +20,7 @@
|
|||||||
#![cfg_attr(feature="dev", feature(plugin))]
|
#![cfg_attr(feature="dev", feature(plugin))]
|
||||||
#![cfg_attr(feature="dev", plugin(clippy))]
|
#![cfg_attr(feature="dev", plugin(clippy))]
|
||||||
#![cfg_attr(feature="dev", allow(useless_format))]
|
#![cfg_attr(feature="dev", allow(useless_format))]
|
||||||
|
|
||||||
extern crate docopt;
|
extern crate docopt;
|
||||||
extern crate num_cpus;
|
extern crate num_cpus;
|
||||||
extern crate rustc_serialize;
|
extern crate rustc_serialize;
|
||||||
@ -46,7 +47,8 @@ extern crate bincode;
|
|||||||
#[macro_use] extern crate hyper;
|
#[macro_use] extern crate hyper;
|
||||||
|
|
||||||
#[cfg(feature = "rpc")]
|
#[cfg(feature = "rpc")]
|
||||||
extern crate ethcore_rpc as rpc;
|
extern crate ethcore_rpc;
|
||||||
|
|
||||||
#[cfg(feature = "webapp")]
|
#[cfg(feature = "webapp")]
|
||||||
extern crate ethcore_webapp as webapp;
|
extern crate ethcore_webapp as webapp;
|
||||||
|
|
||||||
@ -54,9 +56,7 @@ use std::io::{BufRead, BufReader};
|
|||||||
use std::fs::File;
|
use std::fs::File;
|
||||||
use std::net::{SocketAddr, IpAddr};
|
use std::net::{SocketAddr, IpAddr};
|
||||||
use std::env;
|
use std::env;
|
||||||
use std::process::exit;
|
|
||||||
use std::path::PathBuf;
|
use std::path::PathBuf;
|
||||||
use env_logger::LogBuilder;
|
|
||||||
use ctrlc::CtrlC;
|
use ctrlc::CtrlC;
|
||||||
use util::*;
|
use util::*;
|
||||||
use util::panics::{MayPanic, ForwardPanic, PanicHandler};
|
use util::panics::{MayPanic, ForwardPanic, PanicHandler};
|
||||||
@ -70,24 +70,20 @@ use ethminer::{Miner, MinerService};
|
|||||||
use docopt::Docopt;
|
use docopt::Docopt;
|
||||||
use daemonize::Daemonize;
|
use daemonize::Daemonize;
|
||||||
use number_prefix::{binary_prefix, Standalone, Prefixed};
|
use number_prefix::{binary_prefix, Standalone, Prefixed};
|
||||||
#[cfg(feature = "rpc")]
|
|
||||||
use rpc::Server as RpcServer;
|
|
||||||
#[cfg(feature = "webapp")]
|
#[cfg(feature = "webapp")]
|
||||||
use webapp::Server as WebappServer;
|
use webapp::Server as WebappServer;
|
||||||
|
|
||||||
|
#[macro_use]
|
||||||
|
mod die;
|
||||||
mod price_info;
|
mod price_info;
|
||||||
mod upgrade;
|
mod upgrade;
|
||||||
mod hypervisor;
|
mod hypervisor;
|
||||||
|
mod setup_log;
|
||||||
|
mod rpc;
|
||||||
|
|
||||||
fn die_with_message(msg: &str) -> ! {
|
use die::*;
|
||||||
println!("ERROR: {}", msg);
|
use rpc::RpcServer;
|
||||||
exit(1);
|
|
||||||
}
|
|
||||||
|
|
||||||
#[macro_export]
|
|
||||||
macro_rules! die {
|
|
||||||
($($arg:tt)*) => (die_with_message(&format!("{}", format_args!($($arg)*))));
|
|
||||||
}
|
|
||||||
|
|
||||||
const USAGE: &'static str = r#"
|
const USAGE: &'static str = r#"
|
||||||
Parity. Ethereum Client.
|
Parity. Ethereum Client.
|
||||||
@ -281,78 +277,6 @@ struct Args {
|
|||||||
flag_networkid: Option<String>,
|
flag_networkid: Option<String>,
|
||||||
}
|
}
|
||||||
|
|
||||||
fn setup_log(init: &Option<String>) -> Arc<RotatingLogger> {
|
|
||||||
use rlog::*;
|
|
||||||
|
|
||||||
let mut levels = String::new();
|
|
||||||
let mut builder = LogBuilder::new();
|
|
||||||
builder.filter(None, LogLevelFilter::Info);
|
|
||||||
|
|
||||||
if env::var("RUST_LOG").is_ok() {
|
|
||||||
let lvl = &env::var("RUST_LOG").unwrap();
|
|
||||||
levels.push_str(&lvl);
|
|
||||||
levels.push_str(",");
|
|
||||||
builder.parse(lvl);
|
|
||||||
}
|
|
||||||
|
|
||||||
if let Some(ref s) = *init {
|
|
||||||
levels.push_str(s);
|
|
||||||
builder.parse(s);
|
|
||||||
}
|
|
||||||
|
|
||||||
let logs = Arc::new(RotatingLogger::new(levels));
|
|
||||||
let log2 = logs.clone();
|
|
||||||
let format = move |record: &LogRecord| {
|
|
||||||
let timestamp = time::strftime("%Y-%m-%d %H:%M:%S %Z", &time::now()).unwrap();
|
|
||||||
let format = if max_log_level() <= LogLevelFilter::Info {
|
|
||||||
format!("{}{}", timestamp, record.args())
|
|
||||||
} else {
|
|
||||||
format!("{}{}:{}: {}", timestamp, record.level(), record.target(), record.args())
|
|
||||||
};
|
|
||||||
log2.append(format.clone());
|
|
||||||
format
|
|
||||||
};
|
|
||||||
builder.format(format);
|
|
||||||
builder.init().unwrap();
|
|
||||||
logs
|
|
||||||
}
|
|
||||||
|
|
||||||
#[cfg(feature = "rpc")]
|
|
||||||
fn setup_rpc_server(
|
|
||||||
client: Arc<Client>,
|
|
||||||
sync: Arc<EthSync>,
|
|
||||||
secret_store: Arc<AccountService>,
|
|
||||||
miner: Arc<Miner>,
|
|
||||||
url: &SocketAddr,
|
|
||||||
cors_domain: Option<String>,
|
|
||||||
apis: Vec<&str>,
|
|
||||||
logger: Arc<RotatingLogger>,
|
|
||||||
) -> RpcServer {
|
|
||||||
use rpc::v1::*;
|
|
||||||
|
|
||||||
let server = rpc::RpcServer::new();
|
|
||||||
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, &secret_store, &miner).to_delegate());
|
|
||||||
server.add_delegate(EthFilterClient::new(&client, &miner).to_delegate());
|
|
||||||
},
|
|
||||||
"personal" => server.add_delegate(PersonalClient::new(&secret_store).to_delegate()),
|
|
||||||
"ethcore" => server.add_delegate(EthcoreClient::new(&miner, logger.clone()).to_delegate()),
|
|
||||||
_ => {
|
|
||||||
die!("{}: Invalid API name to be enabled.", api);
|
|
||||||
},
|
|
||||||
}
|
|
||||||
}
|
|
||||||
let start_result = server.start_http(url, cors_domain);
|
|
||||||
match start_result {
|
|
||||||
Err(rpc::RpcServerError::IoError(err)) => die_with_io_error(err),
|
|
||||||
Err(e) => die!("{:?}", e),
|
|
||||||
Ok(server) => server,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[cfg(feature = "webapp")]
|
#[cfg(feature = "webapp")]
|
||||||
fn setup_webapp_server(
|
fn setup_webapp_server(
|
||||||
@ -364,7 +288,7 @@ fn setup_webapp_server(
|
|||||||
auth: Option<(String, String)>,
|
auth: Option<(String, String)>,
|
||||||
logger: Arc<RotatingLogger>,
|
logger: Arc<RotatingLogger>,
|
||||||
) -> WebappServer {
|
) -> WebappServer {
|
||||||
use rpc::v1::*;
|
use ethcore_rpc::v1::*;
|
||||||
|
|
||||||
let server = webapp::ServerBuilder::new();
|
let server = webapp::ServerBuilder::new();
|
||||||
server.add_delegate(Web3Client::new().to_delegate());
|
server.add_delegate(Web3Client::new().to_delegate());
|
||||||
@ -389,22 +313,6 @@ fn setup_webapp_server(
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(not(feature = "rpc"))]
|
|
||||||
struct RpcServer;
|
|
||||||
|
|
||||||
#[cfg(not(feature = "rpc"))]
|
|
||||||
fn setup_rpc_server(
|
|
||||||
_client: Arc<Client>,
|
|
||||||
_sync: Arc<EthSync>,
|
|
||||||
_secret_store: Arc<AccountService>,
|
|
||||||
_miner: Arc<Miner>,
|
|
||||||
_url: &SocketAddr,
|
|
||||||
_cors_domain: Option<String>,
|
|
||||||
_apis: Vec<&str>,
|
|
||||||
_logger: Arc<RotatingLogger>,
|
|
||||||
) -> ! {
|
|
||||||
die!("Your Parity version has been compiled without JSON-RPC support.")
|
|
||||||
}
|
|
||||||
|
|
||||||
#[cfg(not(feature = "webapp"))]
|
#[cfg(not(feature = "webapp"))]
|
||||||
struct WebappServer;
|
struct WebappServer;
|
||||||
@ -704,7 +612,7 @@ impl Configuration {
|
|||||||
let panic_handler = PanicHandler::new_in_arc();
|
let panic_handler = PanicHandler::new_in_arc();
|
||||||
|
|
||||||
// Setup logging
|
// Setup logging
|
||||||
let logger = setup_log(&self.args.flag_logging);
|
let logger = setup_log::setup_log(&self.args.flag_logging);
|
||||||
// Raise fdlimit
|
// Raise fdlimit
|
||||||
unsafe { ::fdlimit::raise_fd_limit(); }
|
unsafe { ::fdlimit::raise_fd_limit(); }
|
||||||
|
|
||||||
@ -749,7 +657,7 @@ impl Configuration {
|
|||||||
let addr = SocketAddr::from_str(&url).unwrap_or_else(|_| die!("{}: Invalid JSONRPC listen host/port given.", url));
|
let addr = SocketAddr::from_str(&url).unwrap_or_else(|_| die!("{}: Invalid JSONRPC listen host/port given.", url));
|
||||||
let cors_domain = self.args.flag_jsonrpc_cors.clone().or(self.args.flag_rpccorsdomain.clone());
|
let cors_domain = self.args.flag_jsonrpc_cors.clone().or(self.args.flag_rpccorsdomain.clone());
|
||||||
|
|
||||||
Some(setup_rpc_server(
|
Some(rpc::setup_rpc_server(
|
||||||
service.client(),
|
service.client(),
|
||||||
sync.clone(),
|
sync.clone(),
|
||||||
account_service.clone(),
|
account_service.clone(),
|
||||||
@ -828,31 +736,7 @@ fn wait_for_exit(panic_handler: Arc<PanicHandler>, _rpc_server: Option<RpcServer
|
|||||||
info!("Finishing work, please wait...");
|
info!("Finishing work, please wait...");
|
||||||
}
|
}
|
||||||
|
|
||||||
fn die_with_error(e: ethcore::error::Error) -> ! {
|
|
||||||
use ethcore::error::Error;
|
|
||||||
|
|
||||||
match e {
|
|
||||||
Error::Util(UtilError::StdIo(e)) => die_with_io_error(e),
|
|
||||||
_ => die!("{:?}", e),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
fn die_with_io_error(e: std::io::Error) -> ! {
|
|
||||||
match e.kind() {
|
|
||||||
std::io::ErrorKind::PermissionDenied => {
|
|
||||||
die!("No permissions to bind to specified port.")
|
|
||||||
},
|
|
||||||
std::io::ErrorKind::AddrInUse => {
|
|
||||||
die!("Specified address is already in use. Please make sure that nothing is listening on the same port or try using a different one.")
|
|
||||||
},
|
|
||||||
std::io::ErrorKind::AddrNotAvailable => {
|
|
||||||
die!("Could not use specified interface or given address is invalid.")
|
|
||||||
},
|
|
||||||
_ => die!("{:?}", e),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
|
|
||||||
Configuration::parse().execute();
|
Configuration::parse().execute();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
85
parity/rpc.rs
Normal file
85
parity/rpc.rs
Normal file
@ -0,0 +1,85 @@
|
|||||||
|
// Copyright 2015, 2016 Ethcore (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::sync::Arc;
|
||||||
|
use std::net::SocketAddr;
|
||||||
|
use ethcore::client::Client;
|
||||||
|
use ethsync::EthSync;
|
||||||
|
use ethminer::Miner;
|
||||||
|
use util::RotatingLogger;
|
||||||
|
use util::keys::store::{AccountService};
|
||||||
|
use die::*;
|
||||||
|
|
||||||
|
#[cfg(feature = "rpc")]
|
||||||
|
pub use ethcore_rpc::Server as RpcServer;
|
||||||
|
#[cfg(feature = "rpc")]
|
||||||
|
use ethcore_rpc::{RpcServerError, RpcServer as Server};
|
||||||
|
|
||||||
|
#[cfg(not(feature = "rpc"))]
|
||||||
|
pub struct RpcServer;
|
||||||
|
|
||||||
|
#[cfg(not(feature = "rpc"))]
|
||||||
|
pub fn setup_rpc_server(
|
||||||
|
_client: Arc<Client>,
|
||||||
|
_sync: Arc<EthSync>,
|
||||||
|
_secret_store: Arc<AccountService>,
|
||||||
|
_miner: Arc<Miner>,
|
||||||
|
_url: &SocketAddr,
|
||||||
|
_cors_domain: Option<String>,
|
||||||
|
_apis: Vec<&str>,
|
||||||
|
_logger: Arc<RotatingLogger>,
|
||||||
|
) -> ! {
|
||||||
|
die!("Your Parity version has been compiled without JSON-RPC support.")
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(feature = "rpc")]
|
||||||
|
pub fn setup_rpc_server(
|
||||||
|
client: Arc<Client>,
|
||||||
|
sync: Arc<EthSync>,
|
||||||
|
secret_store: Arc<AccountService>,
|
||||||
|
miner: Arc<Miner>,
|
||||||
|
url: &SocketAddr,
|
||||||
|
cors_domain: Option<String>,
|
||||||
|
apis: Vec<&str>,
|
||||||
|
logger: Arc<RotatingLogger>,
|
||||||
|
) -> RpcServer {
|
||||||
|
use ethcore_rpc::v1::*;
|
||||||
|
|
||||||
|
let server = Server::new();
|
||||||
|
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, &secret_store, &miner).to_delegate());
|
||||||
|
server.add_delegate(EthFilterClient::new(&client, &miner).to_delegate());
|
||||||
|
},
|
||||||
|
"personal" => server.add_delegate(PersonalClient::new(&secret_store).to_delegate()),
|
||||||
|
"ethcore" => server.add_delegate(EthcoreClient::new(&miner, logger.clone()).to_delegate()),
|
||||||
|
_ => {
|
||||||
|
die!("{}: Invalid API name to be enabled.", api);
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
let start_result = server.start_http(url, cors_domain);
|
||||||
|
match start_result {
|
||||||
|
Err(RpcServerError::IoError(err)) => die_with_io_error(err),
|
||||||
|
Err(e) => die!("{:?}", e),
|
||||||
|
Ok(server) => server,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
60
parity/setup_log.rs
Normal file
60
parity/setup_log.rs
Normal file
@ -0,0 +1,60 @@
|
|||||||
|
// Copyright 2015, 2016 Ethcore (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::env;
|
||||||
|
use std::sync::Arc;
|
||||||
|
use time;
|
||||||
|
use env_logger::LogBuilder;
|
||||||
|
use util::{RotatingLogger};
|
||||||
|
|
||||||
|
/// Sets up the logger
|
||||||
|
pub fn setup_log(init: &Option<String>) -> Arc<RotatingLogger> {
|
||||||
|
use rlog::*;
|
||||||
|
|
||||||
|
let mut levels = String::new();
|
||||||
|
let mut builder = LogBuilder::new();
|
||||||
|
builder.filter(None, LogLevelFilter::Info);
|
||||||
|
|
||||||
|
if env::var("RUST_LOG").is_ok() {
|
||||||
|
let lvl = &env::var("RUST_LOG").unwrap();
|
||||||
|
levels.push_str(&lvl);
|
||||||
|
levels.push_str(",");
|
||||||
|
builder.parse(lvl);
|
||||||
|
}
|
||||||
|
|
||||||
|
if let Some(ref s) = *init {
|
||||||
|
levels.push_str(s);
|
||||||
|
builder.parse(s);
|
||||||
|
}
|
||||||
|
|
||||||
|
let logs = Arc::new(RotatingLogger::new(levels));
|
||||||
|
let log2 = logs.clone();
|
||||||
|
let format = move |record: &LogRecord| {
|
||||||
|
let timestamp = time::strftime("%Y-%m-%d %H:%M:%S %Z", &time::now()).unwrap();
|
||||||
|
let format = if max_log_level() <= LogLevelFilter::Info {
|
||||||
|
format!("{}{}", timestamp, record.args())
|
||||||
|
} else {
|
||||||
|
format!("{}{}:{}: {}", timestamp, record.level(), record.target(), record.args())
|
||||||
|
};
|
||||||
|
log2.append(format.clone());
|
||||||
|
format
|
||||||
|
};
|
||||||
|
builder.format(format);
|
||||||
|
builder.init().unwrap();
|
||||||
|
logs
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in New Issue
Block a user