diff --git a/src/bin/client/ethrpc.rs b/src/bin/client/ethrpc.rs index d46a91559..735250d87 100644 --- a/src/bin/client/ethrpc.rs +++ b/src/bin/client/ethrpc.rs @@ -5,17 +5,56 @@ use std::sync::{Arc, RwLock}; use self::jsonrpc_core::{IoHandler, IoDelegate, Params, Value, Error, ErrorCode}; use ethcore::client::*; -struct Eth { - client: Arc> +macro_rules! rpcerr { + () => (Err(Error::new(ErrorCode::InternalError))) } -impl Eth { - fn new(client: Arc>) -> Self { - Eth { +/// This could be a part of `jsonrpc_core`. Unfortunately, +/// "only traits defined in the current crate can be implemented for a type parameter". +pub trait IntoDelegate where T: Send + Sync + 'static { + /// This function should be called to translate custom type into IoDelegate + fn into_delegate(self) -> IoDelegate; +} + +/// eth rpc interface +pub trait Eth { + /// returns protocol version + fn protocol_version(&self, _: Params) -> Result { rpcerr!() } + + /// returns block author + fn author(&self, _: Params) -> Result { rpcerr!() } + + /// returns current gas_price + fn gas_price(&self, _: Params) -> Result { rpcerr!() } + + /// returns highest block number + fn block_number(&self, _: Params) -> Result { rpcerr!() } +} + +impl IntoDelegate for D where D: Eth + Send + Sync + 'static { + fn into_delegate(self) -> IoDelegate { + let mut delegate = IoDelegate::new(Arc::new(self)); + delegate.add_method("eth_protocolVersion", D::protocol_version); + delegate.add_method("eth_coinbase", D::author); + delegate.add_method("eth_gasPrice", D::gas_price); + delegate.add_method("eth_blockNumber", D::block_number); + delegate + } +} + +pub struct EthClient { + client: Arc>, +} + +impl EthClient { + pub fn new(client: Arc>) -> Self { + EthClient { client: client } } +} +impl Eth for EthClient { fn block_number(&self, params: Params) -> Result { match params { Params::None => Ok(Value::U64(self.client.read().unwrap().chain_info().best_block_number)), @@ -24,30 +63,26 @@ impl Eth { } } -struct EthRpc; - -impl EthRpc { - fn build_handler(client: Arc>) -> IoHandler { - let mut handler = IoHandler::new(); - let mut eth = IoDelegate::new(Arc::new(Eth::new(client))); - eth.add_method("eth_blockNumber", Eth::block_number); - handler.add_delegate(eth); - handler - } -} pub struct HttpServer { - server: jsonrpc_http_server::Server + handler: IoHandler, + threads: usize } impl HttpServer { - pub fn new(client: Arc>, threads: usize) -> HttpServer { + pub fn new(threads: usize) -> HttpServer { HttpServer { - server: jsonrpc_http_server::Server::new(EthRpc::build_handler(client), threads) + handler: IoHandler::new(), + threads: threads } } + pub fn add_delegate(&mut self, delegate: I) where D: Send + Sync + 'static, I: IntoDelegate { + self.handler.add_delegate(delegate.into_delegate()); + } + pub fn start_async(self, addr: &str) { - self.server.start_async(addr) + let server = jsonrpc_http_server::Server::new(self.handler, self.threads); + server.start_async(addr) } } diff --git a/src/bin/client/main.rs b/src/bin/client/main.rs index bf1b82909..3dd9b9c5c 100644 --- a/src/bin/client/main.rs +++ b/src/bin/client/main.rs @@ -32,7 +32,8 @@ fn setup_log() { #[cfg(feature = "rpc")] fn setup_rpc_server(client: Arc>) { - let server = ethrpc::HttpServer::new(client, 1); + let mut server = ethrpc::HttpServer::new(1); + server.add_delegate(ethrpc::EthClient::new(client)); server.start_async("127.0.0.1:3030"); }