rpc and bin moved to its own crates

This commit is contained in:
debris
2016-01-26 13:14:22 +01:00
parent d27c7f3902
commit 3ac40b68f8
15 changed files with 61 additions and 27 deletions

View File

@@ -1,166 +0,0 @@
#![feature(plugin)]
#![plugin(docopt_macros)]
// required for serde, move it to a separate library
#![feature(custom_derive, custom_attribute)]
extern crate docopt;
extern crate rustc_serialize;
extern crate ethcore_util as util;
extern crate ethcore;
extern crate log;
extern crate env_logger;
extern crate ctrlc;
#[cfg(feature = "rpc")]
mod rpc;
use std::env;
use log::{LogLevelFilter};
use env_logger::LogBuilder;
use ctrlc::CtrlC;
use util::*;
use ethcore::client::*;
use ethcore::service::{ClientService, NetSyncMessage};
use ethcore::ethereum;
use ethcore::blockchain::CacheSize;
use ethcore::sync::EthSync;
docopt!(Args derive Debug, "
Parity. Ethereum Client.
Usage:
parity [options]
parity [options] <enode>...
Options:
-l --logging LOGGING Specify the logging level
-h --help Show this screen.
");
fn setup_log(init: &String) {
let mut builder = LogBuilder::new();
builder.filter(None, LogLevelFilter::Info);
if env::var("RUST_LOG").is_ok() {
builder.parse(&env::var("RUST_LOG").unwrap());
}
builder.parse(init);
builder.init().unwrap();
}
#[cfg(feature = "rpc")]
fn setup_rpc_server(client: Arc<Client>) {
use self::rpc::*;
let mut server = HttpServer::new(1);
server.add_delegate(Web3Client::new().to_delegate());
server.add_delegate(EthClient::new(client.clone()).to_delegate());
server.add_delegate(EthFilterClient::new(client).to_delegate());
server.add_delegate(NetClient::new().to_delegate());
server.start_async("127.0.0.1:3030");
}
#[cfg(not(feature = "rpc"))]
fn setup_rpc_server(_client: Arc<Client>) {
}
fn main() {
let args: Args = Args::docopt().decode().unwrap_or_else(|e| e.exit());
setup_log(&args.flag_logging);
let spec = ethereum::new_frontier();
let init_nodes = match args.arg_enode.len() {
0 => spec.nodes().clone(),
_ => args.arg_enode.clone(),
};
let mut net_settings = NetworkConfiguration::new();
net_settings.boot_nodes = init_nodes;
let mut service = ClientService::start(spec, net_settings).unwrap();
setup_rpc_server(service.client());
let io_handler = Arc::new(ClientIoHandler { client: service.client(), info: Default::default(), sync: service.sync() });
service.io().register_handler(io_handler).expect("Error registering IO handler");
let exit = Arc::new(Condvar::new());
let e = exit.clone();
CtrlC::set_handler(move || { e.notify_all(); });
let mutex = Mutex::new(());
let _ = exit.wait(mutex.lock().unwrap()).unwrap();
}
struct Informant {
chain_info: RwLock<Option<BlockChainInfo>>,
cache_info: RwLock<Option<CacheSize>>,
report: RwLock<Option<ClientReport>>,
}
impl Default for Informant {
fn default() -> Self {
Informant {
chain_info: RwLock::new(None),
cache_info: RwLock::new(None),
report: RwLock::new(None),
}
}
}
impl Informant {
pub fn tick(&self, client: &Client, sync: &EthSync) {
// 5 seconds betwen calls. TODO: calculate this properly.
let dur = 5usize;
let chain_info = client.chain_info();
let queue_info = client.queue_info();
let cache_info = client.cache_info();
let report = client.report();
let sync_info = sync.status();
if let (_, &Some(ref last_cache_info), &Some(ref last_report)) = (self.chain_info.read().unwrap().deref(), self.cache_info.read().unwrap().deref(), self.report.read().unwrap().deref()) {
println!("[ {} {} ]---[ {} blk/s | {} tx/s | {} gas/s //··· {}/{} peers, {} downloaded, {}+{} queued ···// {} ({}) bl {} ({}) ex ]",
chain_info.best_block_number,
chain_info.best_block_hash,
(report.blocks_imported - last_report.blocks_imported) / dur,
(report.transactions_applied - last_report.transactions_applied) / dur,
(report.gas_processed - last_report.gas_processed) / From::from(dur),
sync_info.num_active_peers,
sync_info.num_peers,
sync_info.blocks_received,
queue_info.unverified_queue_size,
queue_info.verified_queue_size,
cache_info.blocks,
cache_info.blocks as isize - last_cache_info.blocks as isize,
cache_info.block_details,
cache_info.block_details as isize - last_cache_info.block_details as isize
);
}
*self.chain_info.write().unwrap().deref_mut() = Some(chain_info);
*self.cache_info.write().unwrap().deref_mut() = Some(cache_info);
*self.report.write().unwrap().deref_mut() = Some(report);
}
}
const INFO_TIMER: TimerToken = 0;
struct ClientIoHandler {
client: Arc<Client>,
sync: Arc<EthSync>,
info: Informant,
}
impl IoHandler<NetSyncMessage> for ClientIoHandler {
fn initialize(&self, io: &IoContext<NetSyncMessage>) {
io.register_timer(INFO_TIMER, 5000).expect("Error registering timer");
}
fn timeout(&self, _io: &IoContext<NetSyncMessage>, timer: TimerToken) {
if INFO_TIMER == timer {
self.info.tick(&self.client, &self.sync);
}
}
}

View File

@@ -1,96 +0,0 @@
use std::sync::Arc;
use rustc_serialize::hex::ToHex;
use util::hash::*;
use ethcore::client::*;
use rpc::jsonrpc_core::*;
use rpc::{Eth, EthFilter};
pub struct EthClient {
client: Arc<Client>,
}
impl EthClient {
pub fn new(client: Arc<Client>) -> Self {
EthClient {
client: client
}
}
}
impl Eth for EthClient {
fn protocol_version(&self, params: Params) -> Result<Value, Error> {
match params {
Params::None => Ok(Value::U64(63)),
_ => Err(Error::invalid_params())
}
}
fn author(&self, params: Params) -> Result<Value, Error> {
match params {
Params::None => Ok(Value::String(Address::new().to_hex())),
_ => Err(Error::invalid_params())
}
}
fn gas_price(&self, params: Params) -> Result<Value, Error> {
match params {
Params::None => Ok(Value::U64(0)),
_ => Err(Error::invalid_params())
}
}
fn block_number(&self, params: Params) -> Result<Value, Error> {
match params {
Params::None => Ok(Value::U64(self.client.chain_info().best_block_number)),
_ => Err(Error::invalid_params())
}
}
fn is_mining(&self, params: Params) -> Result<Value, Error> {
match params {
Params::None => Ok(Value::Bool(false)),
_ => Err(Error::invalid_params())
}
}
fn hashrate(&self, params: Params) -> Result<Value, Error> {
match params {
Params::None => Ok(Value::U64(0)),
_ => Err(Error::invalid_params())
}
}
fn block_transaction_count(&self, _: Params) -> Result<Value, Error> {
Ok(Value::U64(0))
}
fn block(&self, _: Params) -> Result<Value, Error> {
Ok(Value::Null)
}
}
pub struct EthFilterClient {
client: Arc<Client>
}
impl EthFilterClient {
pub fn new(client: Arc<Client>) -> Self {
EthFilterClient {
client: client
}
}
}
impl EthFilter for EthFilterClient {
fn new_block_filter(&self, _params: Params) -> Result<Value, Error> {
Ok(Value::U64(0))
}
fn new_pending_transaction_filter(&self, _params: Params) -> Result<Value, Error> {
Ok(Value::U64(1))
}
fn filter_changes(&self, _: Params) -> Result<Value, Error> {
Ok(Value::Array(vec![Value::String(self.client.chain_info().best_block_hash.to_hex())]))
}
}

View File

@@ -1,8 +0,0 @@
//! Ethereum rpc interface implementation.
mod web3;
mod eth;
mod net;
pub use self::web3::Web3Client;
pub use self::eth::{EthClient, EthFilterClient};
pub use self::net::NetClient;

View File

@@ -1,19 +0,0 @@
//! Net rpc implementation.
use rpc::jsonrpc_core::*;
use rpc::Net;
pub struct NetClient;
impl NetClient {
pub fn new() -> Self { NetClient }
}
impl Net for NetClient {
fn version(&self, _: Params) -> Result<Value, Error> {
Ok(Value::U64(63))
}
fn peer_count(&self, _params: Params) -> Result<Value, Error> {
Ok(Value::U64(0))
}
}

View File

@@ -1,17 +0,0 @@
use rpc::jsonrpc_core::*;
use rpc::Web3;
pub struct Web3Client;
impl Web3Client {
pub fn new() -> Self { Web3Client }
}
impl Web3 for Web3Client {
fn client_version(&self, params: Params) -> Result<Value, Error> {
match params {
Params::None => Ok(Value::String("parity/0.1.0/-/rust1.7-nightly".to_string())),
_ => Err(Error::invalid_params())
}
}
}

View File

@@ -1,39 +0,0 @@
extern crate jsonrpc_core;
extern crate jsonrpc_http_server;
use self::jsonrpc_core::{IoHandler, IoDelegate};
macro_rules! rpcerr {
() => (Err(Error::internal_error()))
}
pub mod traits;
mod impls;
mod types;
pub use self::traits::{Web3, Eth, EthFilter, Net};
pub use self::impls::*;
pub struct HttpServer {
handler: IoHandler,
threads: usize
}
impl HttpServer {
pub fn new(threads: usize) -> HttpServer {
HttpServer {
handler: IoHandler::new(),
threads: threads
}
}
pub fn add_delegate<D>(&mut self, delegate: IoDelegate<D>) where D: Send + Sync + 'static {
self.handler.add_delegate(delegate);
}
pub fn start_async(self, addr: &str) {
let server = jsonrpc_http_server::Server::new(self.handler, self.threads);
server.start_async(addr)
}
}

View File

@@ -1,65 +0,0 @@
//! Eth rpc interface.
use std::sync::Arc;
use rpc::jsonrpc_core::*;
/// Eth rpc interface.
pub trait Eth: Sized + Send + Sync + 'static {
/// Returns protocol version.
fn protocol_version(&self, _: Params) -> Result<Value, Error> { rpcerr!() }
/// Returns block author.
fn author(&self, _: Params) -> Result<Value, Error> { rpcerr!() }
/// Returns current gas_price.
fn gas_price(&self, _: Params) -> Result<Value, Error> { rpcerr!() }
/// Returns highest block number.
fn block_number(&self, _: Params) -> Result<Value, Error> { rpcerr!() }
/// Returns block with given index / hash.
fn block(&self, _: Params) -> Result<Value, Error> { rpcerr!() }
/// Returns true if client is actively mining new blocks.
fn is_mining(&self, _: Params) -> Result<Value, Error> { rpcerr!() }
/// Returns the number of hashes per second that the node is mining with.
fn hashrate(&self, _: Params) -> Result<Value, Error> { rpcerr!() }
/// Returns the number of transactions in a block.
fn block_transaction_count(&self, _: Params) -> Result<Value, Error> { rpcerr!() }
/// Should be used to convert object to io delegate.
fn to_delegate(self) -> IoDelegate<Self> {
let mut delegate = IoDelegate::new(Arc::new(self));
delegate.add_method("eth_protocolVersion", Eth::protocol_version);
delegate.add_method("eth_coinbase", Eth::author);
delegate.add_method("eth_gasPrice", Eth::gas_price);
delegate.add_method("eth_blockNumber", Eth::block_number);
delegate.add_method("eth_getBlockByNumber", Eth::block);
delegate.add_method("eth_mining", Eth::is_mining);
delegate.add_method("eth_hashrate", Eth::hashrate);
delegate.add_method("eth_getBlockTransactionCountByNumber", Eth::block_transaction_count);
delegate
}
}
// TODO: do filters api properly if we commit outselves to polling again...
pub trait EthFilter: Sized + Send + Sync + 'static {
/// Returns id of new block filter
fn new_block_filter(&self, _: Params) -> Result<Value, Error> { rpcerr!() }
/// Returns id of new block filter
fn new_pending_transaction_filter(&self, _: Params) -> Result<Value, Error> { rpcerr!() }
/// Returns filter changes since last poll
fn filter_changes(&self, _: Params) -> Result<Value, Error> { rpcerr!() }
/// Should be used to convert object to io delegate.
fn to_delegate(self) -> IoDelegate<Self> {
let mut delegate = IoDelegate::new(Arc::new(self));
delegate.add_method("eth_newBlockFilter", EthFilter::new_block_filter);
delegate.add_method("eth_newPendingTransactionFilter", EthFilter::new_pending_transaction_filter);
delegate.add_method("eth_getFilterChanges", EthFilter::filter_changes);
delegate
}
}

View File

@@ -1,8 +0,0 @@
//! Ethereum rpc interfaces.
pub mod web3;
pub mod eth;
pub mod net;
pub use self::web3::Web3;
pub use self::eth::{Eth, EthFilter};
pub use self::net::Net;

View File

@@ -1,20 +0,0 @@
//! Net rpc interface.
use std::sync::Arc;
use rpc::jsonrpc_core::*;
/// Net rpc interface.
pub trait Net: Sized + Send + Sync + 'static {
/// Returns protocol version.
fn version(&self, _: Params) -> Result<Value, Error> { rpcerr!() }
/// Returns number of peers connected to node.
fn peer_count(&self, _: Params) -> Result<Value, Error> { rpcerr!() }
/// Should be used to convert object to io delegate.
fn to_delegate(self) -> IoDelegate<Self> {
let mut delegate = IoDelegate::new(Arc::new(self));
delegate.add_method("net_version", Net::version);
delegate.add_method("net_peerCount", Net::peer_count);
delegate
}
}

View File

@@ -1,16 +0,0 @@
//! Web3 rpc interface.
use std::sync::Arc;
use rpc::jsonrpc_core::*;
/// Web3 rpc interface.
pub trait Web3: Sized + Send + Sync + 'static {
/// Returns current client version.
fn client_version(&self, _: Params) -> Result<Value, Error> { rpcerr!() }
/// Should be used to convert object to io delegate.
fn to_delegate(self) -> IoDelegate<Self> {
let mut delegate = IoDelegate::new(Arc::new(self));
delegate.add_method("web3_clientVersion", Web3::client_version);
delegate
}
}

View File

@@ -1,41 +0,0 @@
use util::hash::*;
use util::uint::*;
#[derive(Default, Serialize)]
pub struct Block {
hash: H256,
#[serde(rename="parentHash")]
parent_hash: H256,
#[serde(rename="sha3Uncles")]
uncles_hash: H256,
author: Address,
// TODO: get rid of this one
miner: Address,
#[serde(rename="stateRoot")]
state_root: H256,
#[serde(rename="transactionsRoot")]
transactions_root: H256,
#[serde(rename="receiptsRoot")]
receipts_root: H256,
number: u64,
#[serde(rename="gasUsed")]
gas_used: U256,
#[serde(rename="gasLimit")]
gas_limit: U256,
// TODO: figure out how to properly serialize bytes
//#[serde(rename="extraData")]
//extra_data: Vec<u8>,
#[serde(rename="logsBloom")]
logs_bloom: H2048,
timestamp: u64
}
#[test]
fn test_block_serialize() {
use serde_json;
let block = Block::default();
let serialized = serde_json::to_string(&block).unwrap();
println!("s: {:?}", serialized);
assert!(false);
}

View File

@@ -1 +0,0 @@
mod block;