diff --git a/Cargo.toml b/Cargo.toml index 04c4bf956..32be356c6 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -20,10 +20,13 @@ time = "0.1" evmjit = { path = "rust-evmjit", optional = true } ethash = { path = "ethash" } num_cpus = "0.2" +jsonrpc-core = { version = "1.0", optional = true } +jsonrpc-http-server = { version = "1.0", optional = true } [features] jit = ["evmjit"] evm_debug = [] +rpc = ["jsonrpc-core", "jsonrpc-http-server"] [[bin]] name = "client" diff --git a/src/bin/client/ethrpc.rs b/src/bin/client/ethrpc.rs new file mode 100644 index 000000000..d46a91559 --- /dev/null +++ b/src/bin/client/ethrpc.rs @@ -0,0 +1,53 @@ +extern crate jsonrpc_core; +extern crate jsonrpc_http_server; + +use std::sync::{Arc, RwLock}; +use self::jsonrpc_core::{IoHandler, IoDelegate, Params, Value, Error, ErrorCode}; +use ethcore::client::*; + +struct Eth { + client: Arc> +} + +impl Eth { + fn new(client: Arc>) -> Self { + Eth { + client: client + } + } + + fn block_number(&self, params: Params) -> Result { + match params { + Params::None => Ok(Value::U64(self.client.read().unwrap().chain_info().best_block_number)), + _ => Err(Error::new(ErrorCode::InvalidParams)), + } + } +} + +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 +} + +impl HttpServer { + pub fn new(client: Arc>, threads: usize) -> HttpServer { + HttpServer { + server: jsonrpc_http_server::Server::new(EthRpc::build_handler(client), threads) + } + } + + pub fn start_async(self, addr: &str) { + self.server.start_async(addr) + } +} diff --git a/src/bin/client/main.rs b/src/bin/client/main.rs index 3335d8a72..bf1b82909 100644 --- a/src/bin/client/main.rs +++ b/src/bin/client/main.rs @@ -4,6 +4,9 @@ extern crate rustc_serialize; extern crate log; extern crate env_logger; +#[cfg(feature = "rpc")] +mod ethrpc; + use std::io::stdin; use std::env; use log::{LogLevelFilter}; @@ -26,10 +29,22 @@ fn setup_log() { builder.init().unwrap(); } + +#[cfg(feature = "rpc")] +fn setup_rpc_server(client: Arc>) { + let server = ethrpc::HttpServer::new(client, 1); + server.start_async("127.0.0.1:3030"); +} + +#[cfg(not(feature = "rpc"))] +fn setup_rpc_server(_client: Arc>) { +} + fn main() { setup_log(); let spec = ethereum::new_frontier(); let mut service = ClientService::start(spec).unwrap(); + setup_rpc_server(service.client()); let io_handler = Box::new(ClientIoHandler { client: service.client(), timer: 0, info: Default::default() }); service.io().register_handler(io_handler).expect("Error registering IO handler"); loop {