New jsonrpc-core with futures and metadata support (#3859)
* Bumping serde & serde_json * Super-initial usage of new jsonrpc * Single event loop for jsonrpc * Metadata * Supporting metadata extraction for eth_accounts * Fixing Cargo.lock * Removing uneccessary clones * Fixing unused import * Unused import * Fixing test
This commit is contained in:
@@ -22,9 +22,9 @@ use ethcore::client::Client;
|
||||
use ethsync::SyncProvider;
|
||||
use helpers::replace_home;
|
||||
use dir::default_data_path;
|
||||
use jsonrpc_core::reactor::Remote;
|
||||
use rpc_apis::SignerService;
|
||||
use hash_fetch::fetch::Client as FetchClient;
|
||||
use parity_reactor::Remote;
|
||||
|
||||
#[derive(Debug, PartialEq, Clone)]
|
||||
pub struct Configuration {
|
||||
@@ -130,6 +130,8 @@ mod server {
|
||||
use rpc_apis;
|
||||
use ethcore_rpc::is_major_importing;
|
||||
use hash_fetch::urlhint::ContractClient;
|
||||
use jsonrpc_core::reactor::RpcHandler;
|
||||
use parity_reactor;
|
||||
|
||||
pub use ethcore_dapps::Server as WebappServer;
|
||||
|
||||
@@ -146,8 +148,9 @@ mod server {
|
||||
let server = dapps::ServerBuilder::new(
|
||||
&dapps_path,
|
||||
Arc::new(Registrar { client: deps.client.clone() }),
|
||||
deps.remote.clone(),
|
||||
parity_reactor::Remote::new(deps.remote.clone()),
|
||||
);
|
||||
|
||||
let sync = deps.sync.clone();
|
||||
let client = deps.client.clone();
|
||||
let signer = deps.signer.clone();
|
||||
@@ -156,15 +159,17 @@ mod server {
|
||||
.sync_status(Arc::new(move || is_major_importing(Some(sync.status().state), client.queue_info())))
|
||||
.web_proxy_tokens(Arc::new(move |token| signer.is_valid_web_proxy_access_token(&token)))
|
||||
.extra_dapps(&extra_dapps)
|
||||
.signer_address(deps.signer.address());
|
||||
.signer_address(deps.signer.address())
|
||||
.allowed_hosts(allowed_hosts);
|
||||
|
||||
let server = rpc_apis::setup_rpc(server, deps.apis.clone(), rpc_apis::ApiSet::UnsafeContext);
|
||||
let apis = rpc_apis::setup_rpc(Default::default(), deps.apis.clone(), rpc_apis::ApiSet::UnsafeContext);
|
||||
let handler = RpcHandler::new(Arc::new(apis), deps.remote);
|
||||
let start_result = match auth {
|
||||
None => {
|
||||
server.start_unsecured_http(url, allowed_hosts)
|
||||
server.start_unsecured_http(url, handler)
|
||||
},
|
||||
Some((username, password)) => {
|
||||
server.start_basic_auth_http(url, allowed_hosts, &username, &password)
|
||||
server.start_basic_auth_http(url, &username, &password, handler)
|
||||
},
|
||||
};
|
||||
|
||||
@@ -175,8 +180,9 @@ mod server {
|
||||
},
|
||||
Err(e) => Err(format!("WebApps error: {:?}", e)),
|
||||
Ok(server) => {
|
||||
let ph = deps.panic_handler;
|
||||
server.set_panic_handler(move || {
|
||||
deps.panic_handler.notify_all("Panic in WebApp thread.".to_owned());
|
||||
ph.notify_all("Panic in WebApp thread.".to_owned());
|
||||
});
|
||||
Ok(server)
|
||||
},
|
||||
|
||||
@@ -41,6 +41,7 @@ extern crate ethcore_ipc as ipc;
|
||||
extern crate ethcore_ipc_nano as nanoipc;
|
||||
extern crate serde;
|
||||
extern crate serde_json;
|
||||
extern crate jsonrpc_core;
|
||||
extern crate rlp;
|
||||
extern crate ethcore_light as light;
|
||||
extern crate parity_hash_fetch as hash_fetch;
|
||||
|
||||
@@ -19,11 +19,14 @@ use std::sync::Arc;
|
||||
use std::net::SocketAddr;
|
||||
use std::io;
|
||||
use io::PanicHandler;
|
||||
use ethcore_rpc::{RpcServerError, RpcServer as Server, IpcServerError};
|
||||
|
||||
use dir::default_data_path;
|
||||
use ethcore_rpc::{self as rpc, RpcServerError, IpcServerError, Metadata};
|
||||
use helpers::parity_ipc_path;
|
||||
use jsonrpc_core::MetaIoHandler;
|
||||
use jsonrpc_core::reactor::{RpcHandler, Remote};
|
||||
use rpc_apis;
|
||||
use rpc_apis::ApiSet;
|
||||
use helpers::parity_ipc_path;
|
||||
use dir::default_data_path;
|
||||
|
||||
pub use ethcore_rpc::{IpcServer, Server as HttpServer};
|
||||
|
||||
@@ -81,6 +84,7 @@ impl fmt::Display for IpcConfiguration {
|
||||
pub struct Dependencies {
|
||||
pub panic_handler: Arc<PanicHandler>,
|
||||
pub apis: Arc<rpc_apis::Dependencies>,
|
||||
pub remote: Remote,
|
||||
}
|
||||
|
||||
pub fn new_http(conf: HttpConfiguration, deps: &Dependencies) -> Result<Option<HttpServer>, String> {
|
||||
@@ -93,9 +97,8 @@ pub fn new_http(conf: HttpConfiguration, deps: &Dependencies) -> Result<Option<H
|
||||
Ok(Some(setup_http_rpc_server(deps, &addr, conf.cors, conf.hosts, conf.apis)?))
|
||||
}
|
||||
|
||||
fn setup_rpc_server(apis: ApiSet, deps: &Dependencies) -> Result<Server, String> {
|
||||
let server = Server::new();
|
||||
Ok(rpc_apis::setup_rpc(server, deps.apis.clone(), apis))
|
||||
fn setup_apis(apis: ApiSet, deps: &Dependencies) -> MetaIoHandler<Metadata> {
|
||||
rpc_apis::setup_rpc(MetaIoHandler::default(), deps.apis.clone(), apis)
|
||||
}
|
||||
|
||||
pub fn setup_http_rpc_server(
|
||||
@@ -105,9 +108,10 @@ pub fn setup_http_rpc_server(
|
||||
allowed_hosts: Option<Vec<String>>,
|
||||
apis: ApiSet
|
||||
) -> Result<HttpServer, String> {
|
||||
let server = setup_rpc_server(apis, dependencies)?;
|
||||
let apis = setup_apis(apis, dependencies);
|
||||
let handler = RpcHandler::new(Arc::new(apis), dependencies.remote.clone());
|
||||
let ph = dependencies.panic_handler.clone();
|
||||
let start_result = server.start_http(url, cors_domains, allowed_hosts, ph);
|
||||
let start_result = rpc::start_http(url, cors_domains, allowed_hosts, ph, handler);
|
||||
match start_result {
|
||||
Err(RpcServerError::IoError(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)),
|
||||
@@ -118,14 +122,15 @@ pub fn setup_http_rpc_server(
|
||||
}
|
||||
}
|
||||
|
||||
pub fn new_ipc(conf: IpcConfiguration, deps: &Dependencies) -> Result<Option<IpcServer>, String> {
|
||||
pub fn new_ipc(conf: IpcConfiguration, deps: &Dependencies) -> Result<Option<IpcServer<Metadata>>, String> {
|
||||
if !conf.enabled { return Ok(None); }
|
||||
Ok(Some(setup_ipc_rpc_server(deps, &conf.socket_addr, conf.apis)?))
|
||||
}
|
||||
|
||||
pub fn setup_ipc_rpc_server(dependencies: &Dependencies, addr: &str, apis: ApiSet) -> Result<IpcServer, String> {
|
||||
let server = setup_rpc_server(apis, dependencies)?;
|
||||
match server.start_ipc(addr) {
|
||||
pub fn setup_ipc_rpc_server(dependencies: &Dependencies, addr: &str, apis: ApiSet) -> Result<IpcServer<Metadata>, String> {
|
||||
let apis = setup_apis(apis, dependencies);
|
||||
let handler = RpcHandler::new(Arc::new(apis), dependencies.remote.clone());
|
||||
match rpc::start_ipc(addr, handler) {
|
||||
Err(IpcServerError::Io(io_error)) => Err(format!("RPC io error: {}", io_error)),
|
||||
Err(any_error) => Err(format!("Rpc error: {:?}", any_error)),
|
||||
Ok(server) => Ok(server)
|
||||
|
||||
@@ -20,16 +20,16 @@ use std::cmp::PartialEq;
|
||||
use std::str::FromStr;
|
||||
use std::sync::Arc;
|
||||
use util::RotatingLogger;
|
||||
use jsonrpc_core::{MetaIoHandler};
|
||||
use ethcore::miner::{Miner, ExternalMiner};
|
||||
use ethcore::client::Client;
|
||||
use ethcore::account_provider::AccountProvider;
|
||||
use ethcore::snapshot::SnapshotService;
|
||||
use ethsync::{ManageNetwork, SyncProvider};
|
||||
use ethcore_rpc::{Extendable, NetworkSettings};
|
||||
use ethcore_rpc::{Metadata, NetworkSettings};
|
||||
pub use ethcore_rpc::SignerService;
|
||||
use updater::Updater;
|
||||
use hash_fetch::fetch::Client as FetchClient;
|
||||
use parity_reactor::Remote;
|
||||
|
||||
#[derive(Debug, PartialEq, Clone, Eq, Hash)]
|
||||
pub enum Api {
|
||||
@@ -125,7 +125,6 @@ pub struct Dependencies {
|
||||
pub dapps_interface: Option<String>,
|
||||
pub dapps_port: Option<u16>,
|
||||
pub fetch: FetchClient,
|
||||
pub remote: Remote,
|
||||
}
|
||||
|
||||
fn to_modules(apis: &[Api]) -> BTreeMap<String, String> {
|
||||
@@ -170,18 +169,20 @@ impl ApiSet {
|
||||
}
|
||||
|
||||
macro_rules! add_signing_methods {
|
||||
($namespace:ident, $server:expr, $deps:expr) => {
|
||||
let server = &$server;
|
||||
let deps = &$deps;
|
||||
if deps.signer_service.is_enabled() {
|
||||
server.add_delegate($namespace::to_delegate(SigningQueueClient::new(&deps.signer_service, &deps.client, &deps.miner, &deps.secret_store)))
|
||||
} else {
|
||||
server.add_delegate($namespace::to_delegate(SigningUnsafeClient::new(&deps.client, &deps.secret_store, &deps.miner)))
|
||||
($namespace:ident, $handler:expr, $deps:expr) => {
|
||||
{
|
||||
let handler = &mut $handler;
|
||||
let deps = &$deps;
|
||||
if deps.signer_service.is_enabled() {
|
||||
handler.extend_with($namespace::to_delegate(SigningQueueClient::new(&deps.signer_service, &deps.client, &deps.miner, &deps.secret_store)))
|
||||
} else {
|
||||
handler.extend_with($namespace::to_delegate(SigningUnsafeClient::new(&deps.client, &deps.secret_store, &deps.miner)))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn setup_rpc<T: Extendable>(server: T, deps: Arc<Dependencies>, apis: ApiSet) -> T {
|
||||
pub fn setup_rpc(mut handler: MetaIoHandler<Metadata>, deps: Arc<Dependencies>, apis: ApiSet) -> MetaIoHandler<Metadata> {
|
||||
use ethcore_rpc::v1::*;
|
||||
|
||||
// it's turned into vector, cause ont of the cases requires &[]
|
||||
@@ -189,10 +190,10 @@ pub fn setup_rpc<T: Extendable>(server: T, deps: Arc<Dependencies>, apis: ApiSet
|
||||
for api in &apis {
|
||||
match *api {
|
||||
Api::Web3 => {
|
||||
server.add_delegate(Web3Client::new().to_delegate());
|
||||
handler.extend_with(Web3Client::new().to_delegate());
|
||||
},
|
||||
Api::Net => {
|
||||
server.add_delegate(NetClient::new(&deps.sync).to_delegate());
|
||||
handler.extend_with(NetClient::new(&deps.sync).to_delegate());
|
||||
},
|
||||
Api::Eth => {
|
||||
let client = EthClient::new(
|
||||
@@ -207,25 +208,25 @@ pub fn setup_rpc<T: Extendable>(server: T, deps: Arc<Dependencies>, apis: ApiSet
|
||||
send_block_number_in_get_work: !deps.geth_compatibility,
|
||||
}
|
||||
);
|
||||
server.add_delegate(client.to_delegate());
|
||||
handler.extend_with(client.to_delegate());
|
||||
|
||||
let filter_client = EthFilterClient::new(&deps.client, &deps.miner);
|
||||
server.add_delegate(filter_client.to_delegate());
|
||||
handler.extend_with(filter_client.to_delegate());
|
||||
|
||||
add_signing_methods!(EthSigning, server, deps);
|
||||
add_signing_methods!(EthSigning, handler, deps);
|
||||
},
|
||||
Api::Personal => {
|
||||
server.add_delegate(PersonalClient::new(&deps.secret_store, &deps.client, &deps.miner, deps.geth_compatibility).to_delegate());
|
||||
handler.extend_with(PersonalClient::new(&deps.secret_store, &deps.client, &deps.miner, deps.geth_compatibility).to_delegate());
|
||||
},
|
||||
Api::Signer => {
|
||||
server.add_delegate(SignerClient::new(&deps.secret_store, &deps.client, &deps.miner, &deps.signer_service).to_delegate());
|
||||
handler.extend_with(SignerClient::new(&deps.secret_store, &deps.client, &deps.miner, &deps.signer_service).to_delegate());
|
||||
},
|
||||
Api::Parity => {
|
||||
let signer = match deps.signer_service.is_enabled() {
|
||||
true => Some(deps.signer_service.clone()),
|
||||
false => None,
|
||||
};
|
||||
server.add_delegate(ParityClient::new(
|
||||
handler.extend_with(ParityClient::new(
|
||||
&deps.client,
|
||||
&deps.miner,
|
||||
&deps.sync,
|
||||
@@ -239,32 +240,31 @@ pub fn setup_rpc<T: Extendable>(server: T, deps: Arc<Dependencies>, apis: ApiSet
|
||||
deps.dapps_port,
|
||||
).to_delegate());
|
||||
|
||||
add_signing_methods!(EthSigning, server, deps);
|
||||
add_signing_methods!(ParitySigning, server, deps);
|
||||
add_signing_methods!(EthSigning, handler, deps);
|
||||
add_signing_methods!(ParitySigning, handler, deps);
|
||||
},
|
||||
Api::ParityAccounts => {
|
||||
server.add_delegate(ParityAccountsClient::new(&deps.secret_store, &deps.client).to_delegate());
|
||||
handler.extend_with(ParityAccountsClient::new(&deps.secret_store, &deps.client).to_delegate());
|
||||
},
|
||||
Api::ParitySet => {
|
||||
server.add_delegate(ParitySetClient::new(
|
||||
handler.extend_with(ParitySetClient::new(
|
||||
&deps.client,
|
||||
&deps.miner,
|
||||
&deps.updater,
|
||||
&deps.net_service,
|
||||
deps.fetch.clone(),
|
||||
deps.remote.clone(),
|
||||
).to_delegate())
|
||||
},
|
||||
Api::Traces => {
|
||||
server.add_delegate(TracesClient::new(&deps.client, &deps.miner).to_delegate())
|
||||
handler.extend_with(TracesClient::new(&deps.client, &deps.miner).to_delegate())
|
||||
},
|
||||
Api::Rpc => {
|
||||
let modules = to_modules(&apis);
|
||||
server.add_delegate(RpcClient::new(modules).to_delegate());
|
||||
handler.extend_with(RpcClient::new(modules).to_delegate());
|
||||
}
|
||||
}
|
||||
}
|
||||
server
|
||||
handler
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
|
||||
@@ -347,7 +347,6 @@ pub fn execute(cmd: RunCmd, can_restart: bool, logger: Arc<RotatingLogger>) -> R
|
||||
);
|
||||
service.add_notify(updater.clone());
|
||||
|
||||
|
||||
// set up dependencies for rpc servers
|
||||
let signer_path = cmd.signer_conf.signer_path.clone();
|
||||
let deps_for_rpc_apis = Arc::new(rpc_apis::Dependencies {
|
||||
@@ -375,12 +374,12 @@ 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 {
|
||||
panic_handler: panic_handler.clone(),
|
||||
apis: deps_for_rpc_apis.clone(),
|
||||
remote: event_loop.raw_remote(),
|
||||
};
|
||||
|
||||
// start rpc servers
|
||||
@@ -393,7 +392,7 @@ pub fn execute(cmd: RunCmd, can_restart: bool, logger: Arc<RotatingLogger>) -> R
|
||||
apis: deps_for_rpc_apis.clone(),
|
||||
client: client.clone(),
|
||||
sync: sync_provider.clone(),
|
||||
remote: event_loop.remote(),
|
||||
remote: event_loop.raw_remote(),
|
||||
fetch: fetch.clone(),
|
||||
signer: deps_for_rpc_apis.signer_service.clone(),
|
||||
};
|
||||
@@ -403,6 +402,7 @@ pub fn execute(cmd: RunCmd, can_restart: bool, logger: Arc<RotatingLogger>) -> R
|
||||
let signer_deps = signer::Dependencies {
|
||||
panic_handler: panic_handler.clone(),
|
||||
apis: deps_for_rpc_apis.clone(),
|
||||
remote: event_loop.raw_remote(),
|
||||
};
|
||||
let signer_server = signer::start(cmd.signer_conf.clone(), signer_deps)?;
|
||||
|
||||
|
||||
@@ -22,8 +22,9 @@ use io::{ForwardPanic, PanicHandler};
|
||||
use util::path::restrict_permissions_owner;
|
||||
use rpc_apis;
|
||||
use ethcore_signer as signer;
|
||||
use helpers::replace_home;
|
||||
use dir::default_data_path;
|
||||
use helpers::replace_home;
|
||||
use jsonrpc_core::reactor::{RpcHandler, Remote};
|
||||
pub use ethcore_signer::Server as SignerServer;
|
||||
|
||||
const CODES_FILENAME: &'static str = "authcodes";
|
||||
@@ -53,6 +54,7 @@ impl Default for Configuration {
|
||||
pub struct Dependencies {
|
||||
pub panic_handler: Arc<PanicHandler>,
|
||||
pub apis: Arc<rpc_apis::Dependencies>,
|
||||
pub remote: Remote,
|
||||
}
|
||||
|
||||
pub struct NewToken {
|
||||
@@ -124,8 +126,9 @@ fn do_start(conf: Configuration, deps: Dependencies) -> Result<SignerServer, Str
|
||||
info!("If you do not intend this, exit now.");
|
||||
}
|
||||
let server = server.skip_origin_validation(conf.skip_origin_validation);
|
||||
let server = rpc_apis::setup_rpc(server, deps.apis, rpc_apis::ApiSet::SafeContext);
|
||||
server.start(addr)
|
||||
let apis = rpc_apis::setup_rpc(Default::default(), deps.apis, rpc_apis::ApiSet::SafeContext);
|
||||
let handler = RpcHandler::new(Arc::new(apis), deps.remote);
|
||||
server.start(addr, handler)
|
||||
};
|
||||
|
||||
match start_result {
|
||||
|
||||
Reference in New Issue
Block a user