Port a couple more RPC APIs to the new auto args (#2325)

* add auto-args deserialization for RPC

* make block param member public

* change BlockParam to a more generic Trailing<T> mechanism

* define work type

* build_rpc_trait macro, implement eth protocol

* fix up tests

* move eth_filter API to new macro

* port ethcore module to new rpc macro

* port ethcore_set to auto_args

* port net RPC to auto_args

* port rpc meta api to new

* skeleton for async RPC auto_args

* macro implementations for strongly-typed async RPC wrapper

* clarify docs

* reflect new required Rust version in README

[ci skip]
This commit is contained in:
Robert Habermeier 2016-10-04 19:05:46 +02:00 committed by Arkadiy Paronyan
parent 6e477951ba
commit b7814fa65c
14 changed files with 534 additions and 405 deletions

View File

@ -5,6 +5,7 @@
[Internal Documentation][doc-url]
Be sure to check out [our wiki][wiki-url] for more information.
[travis-image]: https://travis-ci.org/ethcore/parity.svg?branch=master
@ -18,8 +19,11 @@ Be sure to check out [our wiki][wiki-url] for more information.
[doc-url]: https://ethcore.github.io/parity/ethcore/index.html
[wiki-url]: https://github.com/ethcore/parity/wiki
**Requires Rust version 1.12.0 to build**
----
## About Parity
Parity's goal is to be the fastest, lightest, and most secure Ethereum client. We are developing Parity using the sophisticated and
@ -96,9 +100,9 @@ and Parity will begin syncing the Ethereum blockchain.
### Using systemd service file
To start Parity as a regular user using systemd init:
1. Copy ```parity/scripts/parity.service``` to your
systemd user directory (usually ```~/.config/systemd/user```).
2. To pass any argument to Parity, write a ```~/.parity/parity.conf``` file this way:
```ARGS="ARG1 ARG2 ARG3"```.
1. Copy `parity/scripts/parity.service` to your
systemd user directory (usually `~/.config/systemd/user`).
2. To pass any argument to Parity, write a `~/.parity/parity.conf` file this way:
`ARGS="ARG1 ARG2 ARG3"`.
Example: ```ARGS="ui --geth --identity MyMachine"```.
Example: `ARGS="ui --geth --identity MyMachine"`.

View File

@ -31,16 +31,32 @@ use serde::{Serialize, Deserialize};
/// function `to_delegate` which will automatically wrap each strongly-typed
/// function in a wrapper which handles parameter and output type serialization.
///
/// Every function must have a `#[name("rpc_nameHere")]` attribute after
/// its documentation, and no other attributes. All function names are
/// allowed except for `to_delegate`, which is auto-generated.
/// RPC functions may come in a couple forms: async and synchronous.
/// These are parsed with the custom `#[rpc]` attribute, which must follow
/// documentation.
///
/// ## The #[rpc] attribute
///
/// Valid forms:
/// - `#[rpc(name = "name_here")]` (a synchronous rpc function which should be bound to the given name)
/// - `#[rpc(async, name = "name_here")]` (an async rpc function which should be bound to the given name)
///
/// Synchronous function format:
/// `fn foo(&self, Param1, Param2, Param3) -> Out`.
///
/// Asynchronous RPC functions must come in this form:
/// `fn foo(&self, Param1, Param2, Param3, Ready<Out>);
///
/// Anything else will be rejected by the code generator.
macro_rules! build_rpc_trait {
// entry-point. todo: make another for traits w/ bounds.
(
$(#[$t_attr: meta])*
pub trait $name: ident {
$(
$(#[doc=$m_doc: expr])* #[name($rpc_name: expr)]
fn $method: ident (&self $(, $param: ty)*) -> $out: ty;
$( #[doc=$m_doc:expr] )*
#[ rpc( $($t:tt)* ) ]
fn $m_name: ident ( $($p: tt)* ) $( -> Result<$out: ty, Error> )* ;
)*
}
) => {
@ -48,7 +64,7 @@ macro_rules! build_rpc_trait {
pub trait $name: Sized + Send + Sync + 'static {
$(
$(#[doc=$m_doc])*
fn $method(&self $(, $param)*) -> $out;
fn $m_name ( $($p)* ) $( -> Result<$out, Error> )* ;
)*
/// Transform this into an `IoDelegate`, automatically wrapping
@ -56,14 +72,33 @@ macro_rules! build_rpc_trait {
fn to_delegate(self) -> ::jsonrpc_core::IoDelegate<Self> {
let mut del = ::jsonrpc_core::IoDelegate::new(self.into());
$(
del.add_method($rpc_name, move |base, params| {
($name::$method as fn(&_ $(, $param)*) -> $out).wrap_rpc(base, params)
});
build_rpc_trait!(WRAP del =>
( $($t)* )
fn $m_name ( $($p)* ) $( -> Result<$out, Error> )*
);
)*
del
}
}
}
};
( WRAP $del: expr =>
(name = $name: expr)
fn $method: ident (&self $(, $param: ty)*) -> Result<$out: ty, Error>
) => {
$del.add_method($name, move |base, params| {
(Self::$method as fn(&_ $(, $param)*) -> Result<$out, Error>).wrap_rpc(base, params)
})
};
( WRAP $del: expr =>
(async, name = $name: expr)
fn $method: ident (&self, Ready<$out: ty> $(, $param: ty)*)
) => {
$del.add_async_method($name, move |base, params, ready| {
(Self::$method as fn(&_, Ready<$out> $(, $param)*)).wrap_rpc(base, params, ready)
})
};
}
/// A wrapper type without an implementation of `Deserialize`
@ -71,11 +106,35 @@ macro_rules! build_rpc_trait {
/// that take a trailing default parameter.
pub struct Trailing<T: Default + Deserialize>(pub T);
/// A wrapper type for `jsonrpc_core`'s weakly-typed `Ready` struct.
pub struct Ready<T: Serialize> {
inner: ::jsonrpc_core::Ready,
_marker: ::std::marker::PhantomData<T>,
}
impl<T: Serialize> From<::jsonrpc_core::Ready> for Ready<T> {
fn from(ready: ::jsonrpc_core::Ready) -> Self {
Ready { inner: ready, _marker: ::std::marker::PhantomData }
}
}
impl<T: Serialize> Ready<T> {
/// Respond withthe asynchronous result.
pub fn ready(self, result: Result<T, Error>) {
self.inner.ready(result.map(to_value))
}
}
/// Wrapper trait for synchronous RPC functions.
pub trait Wrap<B: Send + Sync + 'static> {
fn wrap_rpc(&self, base: &B, params: Params) -> Result<Value, Error>;
}
/// Wrapper trait for asynchronous RPC functions.
pub trait WrapAsync<B: Send + Sync + 'static> {
fn wrap_rpc(&self, base: &B, params: Params, ready: ::jsonrpc_core::Ready);
}
// special impl for no parameters.
impl<B, OUT> Wrap<B> for fn(&B) -> Result<OUT, Error>
where B: Send + Sync + 'static, OUT: Serialize
@ -87,10 +146,23 @@ impl<B, OUT> Wrap<B> for fn(&B) -> Result<OUT, Error>
}
}
impl<B, OUT> WrapAsync<B> for fn(&B, Ready<OUT>)
where B: Send + Sync + 'static, OUT: Serialize
{
fn wrap_rpc(&self, base: &B, params: Params, ready: ::jsonrpc_core::Ready) {
match ::v1::helpers::params::expect_no_params(params) {
Ok(()) => (self)(base, ready.into()),
Err(e) => ready.ready(Err(e)),
}
}
}
// creates a wrapper implementation which deserializes the parameters,
// calls the function with concrete type, and serializes the output.
macro_rules! wrap {
($($x: ident),+) => {
// synchronous implementation
impl <
BASE: Send + Sync + 'static,
OUT: Serialize,
@ -102,6 +174,20 @@ macro_rules! wrap {
}).map(to_value)
}
}
// asynchronous implementation
impl <
BASE: Send + Sync + 'static,
OUT: Serialize,
$($x: Deserialize,)+
> WrapAsync<BASE> for fn(&BASE, Ready<OUT>, $($x,)+ ) {
fn wrap_rpc(&self, base: &BASE, params: Params, ready: ::jsonrpc_core::Ready) {
match from_params::<($($x,)+)>(params) {
Ok(($($x,)+)) => (self)(base, ready.into(), $($x,)+),
Err(e) => ready.ready(Err(e)),
}
}
}
}
}
@ -126,10 +212,34 @@ impl<B, OUT, T> Wrap<B> for fn(&B, Trailing<T>) -> Result<OUT, Error>
}
}
impl<B, OUT, T> WrapAsync<B> for fn(&B, Ready<OUT>, Trailing<T>)
where B: Send + Sync + 'static, OUT: Serialize, T: Default + Deserialize
{
fn wrap_rpc(&self, base: &B, params: Params, ready: ::jsonrpc_core::Ready) {
let len = match params {
Params::Array(ref v) => v.len(),
Params::None => 0,
_ => return ready.ready(Err(errors::invalid_params("not an array", ""))),
};
let id = match len {
0 => Ok((T::default(),)),
1 => from_params::<(T,)>(params),
_ => Err(Error::invalid_params()),
};
match id {
Ok((id,)) => (self)(base, ready.into(), Trailing(id)),
Err(e) => ready.ready(Err(e)),
}
}
}
// similar to `wrap!`, but handles a single default trailing parameter
// accepts an additional argument indicating the number of non-trailing parameters.
macro_rules! wrap_with_trailing {
($num: expr, $($x: ident),+) => {
// synchronous implementation
impl <
BASE: Send + Sync + 'static,
OUT: Serialize,
@ -155,6 +265,35 @@ macro_rules! wrap_with_trailing {
(self)(base, $($x,)+ Trailing(id)).map(to_value)
}
}
// asynchronous implementation
impl <
BASE: Send + Sync + 'static,
OUT: Serialize,
$($x: Deserialize,)+
TRAILING: Default + Deserialize,
> WrapAsync<BASE> for fn(&BASE, Ready<OUT>, $($x,)+ Trailing<TRAILING>) {
fn wrap_rpc(&self, base: &BASE, params: Params, ready: ::jsonrpc_core::Ready) {
let len = match params {
Params::Array(ref v) => v.len(),
Params::None => 0,
_ => return ready.ready(Err(errors::invalid_params("not an array", ""))),
};
let params = match len - $num {
0 => from_params::<($($x,)+)>(params)
.map(|($($x,)+)| ($($x,)+ TRAILING::default())),
1 => from_params::<($($x,)+ TRAILING)>(params)
.map(|($($x,)+ id)| ($($x,)+ id)),
_ => Err(Error::invalid_params()),
};
match params {
Ok(($($x,)+ id)) => (self)(base, ready.into(), $($x,)+ Trailing(id)),
Err(e) => ready.ready(Err(e))
}
}
}
}
}

View File

@ -18,7 +18,7 @@
use std::{fs, io};
use std::sync::{mpsc, Arc, Weak};
use std::str::FromStr;
use std::collections::{BTreeMap};
use util::{RotatingLogger, Address, Mutex, sha3};
use util::misc::version_data;
@ -31,11 +31,11 @@ use ethcore::miner::MinerService;
use ethcore::client::{MiningBlockChainClient};
use ethcore::ids::BlockID;
use jsonrpc_core::{from_params, to_value, Value, Error, Params, Ready};
use jsonrpc_core::Error;
use v1::traits::Ethcore;
use v1::types::{Bytes, U256, H160, H256, H512, Peers, Transaction};
use v1::types::{Bytes, U256, H160, H256, H512, Peers, Transaction, RpcSettings};
use v1::helpers::{errors, SigningQueue, SignerService, NetworkSettings};
use v1::helpers::params::expect_no_params;
use v1::helpers::auto_args::Ready;
/// Ethcore implementation.
pub struct EthcoreClient<C, M, S: ?Sized, F=FetchClient> where
@ -113,180 +113,168 @@ impl<C, M, S: ?Sized, F> Ethcore for EthcoreClient<C, M, S, F> where
S: SyncProvider + 'static,
F: Fetch + 'static {
fn transactions_limit(&self, params: Params) -> Result<Value, Error> {
fn transactions_limit(&self) -> Result<usize, Error> {
try!(self.active());
try!(expect_no_params(params));
Ok(to_value(&take_weak!(self.miner).transactions_limit()))
Ok(take_weak!(self.miner).transactions_limit())
}
fn min_gas_price(&self, params: Params) -> Result<Value, Error> {
fn min_gas_price(&self) -> Result<U256, Error> {
try!(self.active());
try!(expect_no_params(params));
Ok(to_value(&U256::from(take_weak!(self.miner).minimal_gas_price())))
Ok(U256::from(take_weak!(self.miner).minimal_gas_price()))
}
fn extra_data(&self, params: Params) -> Result<Value, Error> {
fn extra_data(&self) -> Result<Bytes, Error> {
try!(self.active());
try!(expect_no_params(params));
Ok(to_value(&Bytes::new(take_weak!(self.miner).extra_data())))
Ok(Bytes::new(take_weak!(self.miner).extra_data()))
}
fn gas_floor_target(&self, params: Params) -> Result<Value, Error> {
fn gas_floor_target(&self) -> Result<U256, Error> {
try!(self.active());
try!(expect_no_params(params));
Ok(to_value(&U256::from(take_weak!(self.miner).gas_floor_target())))
Ok(U256::from(take_weak!(self.miner).gas_floor_target()))
}
fn gas_ceil_target(&self, params: Params) -> Result<Value, Error> {
fn gas_ceil_target(&self) -> Result<U256, Error> {
try!(self.active());
try!(expect_no_params(params));
Ok(to_value(&U256::from(take_weak!(self.miner).gas_ceil_target())))
Ok(U256::from(take_weak!(self.miner).gas_ceil_target()))
}
fn dev_logs(&self, params: Params) -> Result<Value, Error> {
fn dev_logs(&self) -> Result<Vec<String>, Error> {
try!(self.active());
try!(expect_no_params(params));
let logs = self.logger.logs();
Ok(to_value(&logs.as_slice()))
Ok(logs.as_slice().to_owned())
}
fn dev_logs_levels(&self, params: Params) -> Result<Value, Error> {
fn dev_logs_levels(&self) -> Result<String, Error> {
try!(self.active());
try!(expect_no_params(params));
Ok(to_value(&self.logger.levels()))
Ok(self.logger.levels().to_owned())
}
fn net_chain(&self, params: Params) -> Result<Value, Error> {
fn net_chain(&self) -> Result<String, Error> {
try!(self.active());
try!(expect_no_params(params));
Ok(to_value(&self.settings.chain))
Ok(self.settings.chain.clone())
}
fn net_peers(&self, params: Params) -> Result<Value, Error> {
fn net_peers(&self) -> Result<Peers, Error> {
try!(self.active());
try!(expect_no_params(params));
let sync_status = take_weak!(self.sync).status();
let net_config = take_weak!(self.net).network_config();
Ok(to_value(&Peers {
Ok(Peers {
active: sync_status.num_active_peers,
connected: sync_status.num_peers,
max: sync_status.current_max_peers(net_config.min_peers, net_config.max_peers),
}))
})
}
fn net_port(&self, params: Params) -> Result<Value, Error> {
fn net_port(&self) -> Result<u16, Error> {
try!(self.active());
try!(expect_no_params(params));
Ok(to_value(&self.settings.network_port))
Ok(self.settings.network_port)
}
fn node_name(&self, params: Params) -> Result<Value, Error> {
fn node_name(&self) -> Result<String, Error> {
try!(self.active());
try!(expect_no_params(params));
Ok(to_value(&self.settings.name))
Ok(self.settings.name.clone())
}
fn registry_address(&self, params: Params) -> Result<Value, Error> {
fn registry_address(&self) -> Result<Option<H160>, Error> {
try!(self.active());
try!(expect_no_params(params));
let r = take_weak!(self.client)
.additional_params()
.get("registrar")
.and_then(|s| Address::from_str(s).ok())
.map(|s| H160::from(s));
Ok(to_value(&r))
Ok(
take_weak!(self.client)
.additional_params()
.get("registrar")
.and_then(|s| Address::from_str(s).ok())
.map(|s| H160::from(s))
)
}
fn rpc_settings(&self, params: Params) -> Result<Value, Error> {
fn rpc_settings(&self) -> Result<RpcSettings, Error> {
try!(self.active());
try!(expect_no_params(params));
let mut map = BTreeMap::new();
map.insert("enabled".to_owned(), Value::Bool(self.settings.rpc_enabled));
map.insert("interface".to_owned(), Value::String(self.settings.rpc_interface.clone()));
map.insert("port".to_owned(), Value::U64(self.settings.rpc_port as u64));
Ok(Value::Object(map))
Ok(RpcSettings {
enabled: self.settings.rpc_enabled,
interface: self.settings.rpc_interface.clone(),
port: self.settings.rpc_port as u64,
})
}
fn default_extra_data(&self, params: Params) -> Result<Value, Error> {
fn default_extra_data(&self) -> Result<Bytes, Error> {
try!(self.active());
try!(expect_no_params(params));
Ok(to_value(&Bytes::new(version_data())))
Ok(Bytes::new(version_data()))
}
fn gas_price_statistics(&self, params: Params) -> Result<Value, Error> {
fn gas_price_statistics(&self) -> Result<Vec<U256>, Error> {
try!(self.active());
try!(expect_no_params(params));
match take_weak!(self.client).gas_price_statistics(100, 8) {
Ok(stats) => Ok(to_value(&stats
.into_iter()
.map(|x| to_value(&U256::from(x)))
.collect::<Vec<_>>())),
Ok(stats) => Ok(stats.into_iter().map(Into::into).collect()),
_ => Err(Error::internal_error()),
}
}
fn unsigned_transactions_count(&self, params: Params) -> Result<Value, Error> {
fn unsigned_transactions_count(&self) -> Result<usize, Error> {
try!(self.active());
try!(expect_no_params(params));
match self.signer {
None => Err(errors::signer_disabled()),
Some(ref signer) => Ok(to_value(&signer.len())),
Some(ref signer) => Ok(signer.len()),
}
}
fn generate_secret_phrase(&self, params: Params) -> Result<Value, Error> {
fn generate_secret_phrase(&self) -> Result<String, Error> {
try!(self.active());
try!(expect_no_params(params));
Ok(to_value(&random_phrase(12)))
Ok(random_phrase(12))
}
fn phrase_to_address(&self, params: Params) -> Result<Value, Error> {
fn phrase_to_address(&self, phrase: String) -> Result<H160, Error> {
try!(self.active());
from_params::<(String,)>(params).map(|(phrase,)|
to_value(&H160::from(Brain::new(phrase).generate().unwrap().address()))
)
Ok(Brain::new(phrase).generate().unwrap().address().into())
}
fn list_accounts(&self, params: Params) -> Result<Value, Error> {
fn list_accounts(&self) -> Result<Option<Vec<H160>>, Error> {
try!(self.active());
try!(expect_no_params(params));
take_weak!(self.client)
Ok(take_weak!(self.client)
.list_accounts(BlockID::Latest)
.map(|a| Ok(to_value(&a.into_iter().map(Into::into).collect::<Vec<H160>>())))
.unwrap_or(Ok(Value::Null))
.map(|a| a.into_iter().map(Into::into).collect()))
}
fn list_storage_keys(&self, params: Params) -> Result<Value, Error> {
fn list_storage_keys(&self, _address: H160) -> Result<Option<Vec<H256>>, Error> {
try!(self.active());
from_params::<(H160,)>(params).and_then(|(_addr,)|
Ok(Value::Null)
)
// TODO: implement this
Ok(None)
}
fn encrypt_message(&self, params: Params) -> Result<Value, Error> {
fn encrypt_message(&self, key: H512, phrase: Bytes) -> Result<Bytes, Error> {
try!(self.active());
from_params::<(H512, Bytes)>(params).and_then(|(key, phrase)| {
let s = try!(ecies::encrypt(&key.into(), &[0; 0], &phrase.0).map_err(|_| Error::internal_error()));
Ok(to_value(&Bytes::from(s)))
})
ecies::encrypt(&key.into(), &[0; 0], &phrase.0)
.map_err(|_| Error::internal_error())
.map(Into::into)
}
fn pending_transactions(&self, params: Params) -> Result<Value, Error> {
fn pending_transactions(&self) -> Result<Vec<Transaction>, Error> {
try!(self.active());
try!(expect_no_params(params));
Ok(to_value(&take_weak!(self.miner).all_transactions().into_iter().map(Into::into).collect::<Vec<Transaction>>()))
Ok(take_weak!(self.miner).all_transactions().into_iter().map(Into::into).collect::<Vec<_>>())
}
fn hash_content(&self, params: Params, ready: Ready) {
let res = self.active().and_then(|_| from_params::<(String,)>(params));
fn hash_content(&self, ready: Ready<H256>, url: String) {
let res = self.active();
let hash_content = |result| {
let path = try!(result);
@ -301,15 +289,15 @@ impl<C, M, S: ?Sized, F> Ethcore for EthcoreClient<C, M, S, F> where
match res {
Err(e) => ready.ready(Err(e)),
Ok((url, )) => {
Ok(()) => {
let (tx, rx) = mpsc::channel();
let res = self.fetch.lock().request_async(&url, Default::default(), Box::new(move |result| {
let result = hash_content(result)
.map_err(errors::from_fetch_error)
.map(|hash| to_value(H256::from(hash)));
.map(Into::into);
// Receive ready and invoke with result.
let ready: Ready = rx.try_recv().expect("When on_done is invoked ready object is always sent.");
let ready: Ready<H256> = rx.try_recv().expect("When on_done is invoked ready object is always sent.");
ready.ready(result);
}));

View File

@ -21,7 +21,6 @@ use ethcore::miner::MinerService;
use ethcore::client::MiningBlockChainClient;
use ethsync::ManageNetwork;
use v1::helpers::errors;
use v1::helpers::params::expect_no_params;
use v1::traits::EthcoreSet;
use v1::types::{Bytes, H160, U256};
@ -58,105 +57,94 @@ impl<C, M> EthcoreSet for EthcoreSetClient<C, M> where
C: MiningBlockChainClient + 'static,
M: MinerService + 'static {
fn set_min_gas_price(&self, params: Params) -> Result<Value, Error> {
fn set_min_gas_price(&self, gas_price: U256) -> Result<bool, Error> {
try!(self.active());
from_params::<(U256,)>(params).and_then(|(gas_price,)| {
take_weak!(self.miner).set_minimal_gas_price(gas_price.into());
Ok(to_value(&true))
})
take_weak!(self.miner).set_minimal_gas_price(gas_price.into());
Ok(true)
}
fn set_gas_floor_target(&self, params: Params) -> Result<Value, Error> {
fn set_gas_floor_target(&self, target: U256) -> Result<bool, Error> {
try!(self.active());
from_params::<(U256,)>(params).and_then(|(target,)| {
take_weak!(self.miner).set_gas_floor_target(target.into());
Ok(to_value(&true))
})
take_weak!(self.miner).set_gas_floor_target(target.into());
Ok(true)
}
fn set_gas_ceil_target(&self, params: Params) -> Result<Value, Error> {
fn set_gas_ceil_target(&self, target: U256) -> Result<bool, Error> {
try!(self.active());
from_params::<(U256,)>(params).and_then(|(target,)| {
take_weak!(self.miner).set_gas_ceil_target(target.into());
Ok(to_value(&true))
})
take_weak!(self.miner).set_gas_ceil_target(target.into());
Ok(true)
}
fn set_extra_data(&self, params: Params) -> Result<Value, Error> {
fn set_extra_data(&self, extra_data: Bytes) -> Result<bool, Error> {
try!(self.active());
from_params::<(Bytes,)>(params).and_then(|(extra_data,)| {
take_weak!(self.miner).set_extra_data(extra_data.to_vec());
Ok(to_value(&true))
})
take_weak!(self.miner).set_extra_data(extra_data.to_vec());
Ok(true)
}
fn set_author(&self, params: Params) -> Result<Value, Error> {
fn set_author(&self, author: H160) -> Result<bool, Error> {
try!(self.active());
from_params::<(H160,)>(params).and_then(|(author,)| {
take_weak!(self.miner).set_author(author.into());
Ok(to_value(&true))
})
take_weak!(self.miner).set_author(author.into());
Ok(true)
}
fn set_transactions_limit(&self, params: Params) -> Result<Value, Error> {
fn set_transactions_limit(&self, limit: usize) -> Result<bool, Error> {
try!(self.active());
from_params::<(usize,)>(params).and_then(|(limit,)| {
take_weak!(self.miner).set_transactions_limit(limit);
Ok(to_value(&true))
})
take_weak!(self.miner).set_transactions_limit(limit);
Ok(true)
}
fn set_tx_gas_limit(&self, params: Params) -> Result<Value, Error> {
fn set_tx_gas_limit(&self, limit: U256) -> Result<bool, Error> {
try!(self.active());
from_params::<(U256,)>(params).and_then(|(limit,)| {
take_weak!(self.miner).set_tx_gas_limit(limit.into());
Ok(to_value(&true))
})
take_weak!(self.miner).set_tx_gas_limit(limit.into());
Ok(true)
}
fn add_reserved_peer(&self, params: Params) -> Result<Value, Error> {
fn add_reserved_peer(&self, peer: String) -> Result<bool, Error> {
try!(self.active());
from_params::<(String,)>(params).and_then(|(peer,)| {
match take_weak!(self.net).add_reserved_peer(peer) {
Ok(()) => Ok(to_value(&true)),
Err(e) => Err(errors::invalid_params("Peer address", e)),
}
})
match take_weak!(self.net).add_reserved_peer(peer) {
Ok(()) => Ok(true),
Err(e) => Err(errors::invalid_params("Peer address", e)),
}
}
fn remove_reserved_peer(&self, params: Params) -> Result<Value, Error> {
fn remove_reserved_peer(&self, peer: String) -> Result<bool, Error> {
try!(self.active());
from_params::<(String,)>(params).and_then(|(peer,)| {
match take_weak!(self.net).remove_reserved_peer(peer) {
Ok(()) => Ok(to_value(&true)),
Err(e) => Err(errors::invalid_params("Peer address", e)),
}
})
match take_weak!(self.net).remove_reserved_peer(peer) {
Ok(()) => Ok(true),
Err(e) => Err(errors::invalid_params("Peer address", e)),
}
}
fn drop_non_reserved_peers(&self, params: Params) -> Result<Value, Error> {
fn drop_non_reserved_peers(&self) -> Result<bool, Error> {
try!(self.active());
try!(expect_no_params(params));
take_weak!(self.net).deny_unreserved_peers();
Ok(to_value(&true))
Ok(true)
}
fn accept_non_reserved_peers(&self, params: Params) -> Result<Value, Error> {
fn accept_non_reserved_peers(&self) -> Result<bool, Error> {
try!(self.active());
try!(expect_no_params(params));
take_weak!(self.net).accept_unreserved_peers();
Ok(to_value(&true))
Ok(true)
}
fn start_network(&self, params: Params) -> Result<Value, Error> {
try!(expect_no_params(params));
fn start_network(&self) -> Result<bool, Error> {
take_weak!(self.net).start_network();
Ok(Value::Bool(true))
Ok(true)
}
fn stop_network(&self, params: Params) -> Result<Value, Error> {
try!(expect_no_params(params));
fn stop_network(&self) -> Result<bool, Error> {
take_weak!(self.net).stop_network();
Ok(Value::Bool(true))
Ok(true)
}
}

View File

@ -16,10 +16,9 @@
//! Net rpc implementation.
use std::sync::{Arc, Weak};
use jsonrpc_core::*;
use jsonrpc_core::Error;
use ethsync::SyncProvider;
use v1::traits::Net;
use v1::helpers::params::expect_no_params;
/// Net rpc implementation.
pub struct NetClient<S: ?Sized> where S: SyncProvider {
@ -36,20 +35,19 @@ impl<S: ?Sized> NetClient<S> where S: SyncProvider {
}
impl<S: ?Sized> Net for NetClient<S> where S: SyncProvider + 'static {
fn version(&self, params: Params) -> Result<Value, Error> {
try!(expect_no_params(params));
Ok(Value::String(format!("{}", take_weak!(self.sync).status().network_id).to_owned()))
fn version(&self) -> Result<String, Error> {
Ok(format!("{}", take_weak!(self.sync).status().network_id).to_owned())
}
fn peer_count(&self, params: Params) -> Result<Value, Error> {
try!(expect_no_params(params));
Ok(Value::String(format!("0x{:x}", take_weak!(self.sync).status().num_peers as u64).to_owned()))
fn peer_count(&self) -> Result<String, Error> {
Ok(format!("0x{:x}", take_weak!(self.sync).status().num_peers as u64).to_owned())
}
fn is_listening(&self, params: Params) -> Result<Value, Error> {
try!(expect_no_params(params));
fn is_listening(&self) -> Result<bool, Error> {
// right now (11 march 2016), we are always listening for incoming connections
Ok(Value::Bool(true))
//
// (this may not be true now -- 26 september 2016)
Ok(true)
}
}

View File

@ -16,9 +16,8 @@
//! RPC generic methods implementation.
use std::collections::BTreeMap;
use jsonrpc_core::*;
use jsonrpc_core::Error;
use v1::traits::Rpc;
use v1::helpers::params::expect_no_params;
/// RPC generic methods implementation.
pub struct RpcClient {
@ -40,26 +39,26 @@ impl RpcClient {
}
impl Rpc for RpcClient {
fn rpc_modules(&self, params: Params) -> Result<Value, Error> {
try!(expect_no_params(params));
fn rpc_modules(&self) -> Result<BTreeMap<String, String>, Error> {
let modules = self.modules.iter()
.fold(BTreeMap::new(), |mut map, (k, v)| {
map.insert(k.to_owned(), Value::String(v.to_owned()));
map.insert(k.to_owned(), v.to_owned());
map
});
Ok(Value::Object(modules))
Ok(modules)
}
fn modules(&self, params: Params) -> Result<Value, Error> {
try!(expect_no_params(params));
fn modules(&self) -> Result<BTreeMap<String, String>, Error> {
let modules = self.modules.iter()
.filter(|&(k, _v)| {
self.valid_apis.contains(k)
})
.fold(BTreeMap::new(), |mut map, (k, v)| {
map.insert(k.to_owned(), Value::String(v.to_owned()));
map.insert(k.to_owned(), v.to_owned());
map
});
Ok(Value::Object(modules))
Ok(modules)
}
}

View File

@ -115,4 +115,4 @@ fn rpc_ethcore_set_transactions_limit() {
assert_eq!(io.handle_request_sync(request), Some(response.to_owned()));
assert_eq!(miner.transactions_limit(), 10_240_240);
}
}

View File

@ -28,174 +28,173 @@ build_rpc_trait! {
/// Eth rpc interface.
pub trait Eth {
/// Returns protocol version encoded as a string (quotes are necessary).
#[name("eth_protocolVersion")]
#[rpc(name = "eth_protocolVersion")]
fn protocol_version(&self) -> Result<String, Error>;
/// Returns an object with data about the sync status or false. (wtf?)
#[name("eth_syncing")]
#[rpc(name = "eth_syncing")]
fn syncing(&self) -> Result<SyncStatus, Error>;
/// Returns the number of hashes per second that the node is mining with.
#[name("eth_hashrate")]
#[rpc(name = "eth_hashrate")]
fn hashrate(&self) -> Result<U256, Error>;
/// Returns block author.
#[name("eth_coinbase")]
#[rpc(name = "eth_coinbase")]
fn author(&self) -> Result<H160, Error>;
/// Returns true if client is actively mining new blocks.
#[name("eth_mining")]
#[rpc(name = "eth_mining")]
fn is_mining(&self) -> Result<bool, Error>;
/// Returns current gas_price.
#[name("eth_gasPrice")]
#[rpc(name = "eth_gasPrice")]
fn gas_price(&self) -> Result<U256, Error>;
/// Returns accounts list.
#[name("eth_accounts")]
#[rpc(name = "eth_accounts")]
fn accounts(&self) -> Result<Vec<H160>, Error>;
/// Returns highest block number.
#[name("eth_blockNumber")]
#[rpc(name = "eth_blockNumber")]
fn block_number(&self) -> Result<U256, Error>;
/// Returns balance of the given account.
#[name("eth_getBalance")]
#[rpc(name = "eth_getBalance")]
fn balance(&self, H160, Trailing<BlockNumber>) -> Result<U256, Error>;
/// Returns content of the storage at given address.
#[name("eth_getStorageAt")]
#[rpc(name = "eth_getStorageAt")]
fn storage_at(&self, H160, U256, Trailing<BlockNumber>) -> Result<H256, Error>;
/// Returns block with given hash.
#[name("eth_getBlockByHash")]
#[rpc(name = "eth_getBlockByHash")]
fn block_by_hash(&self, H256, bool) -> Result<Option<Block>, Error>;
/// Returns block with given number.
#[name("eth_getBlockByNumber")]
#[rpc(name = "eth_getBlockByNumber")]
fn block_by_number(&self, BlockNumber, bool) -> Result<Option<Block>, Error>;
/// Returns the number of transactions sent from given address at given time (block number).
#[name("eth_getTransactionCount")]
#[rpc(name = "eth_getTransactionCount")]
fn transaction_count(&self, H160, Trailing<BlockNumber>) -> Result<U256, Error>;
/// Returns the number of transactions in a block with given hash.
#[name("eth_getBlockTransactionCountByHash")]
#[rpc(name = "eth_getBlockTransactionCountByHash")]
fn block_transaction_count_by_hash(&self, H256) -> Result<Option<U256>, Error>;
/// Returns the number of transactions in a block with given block number.
#[name("eth_getBlockTransactionCountByNumber")]
#[rpc(name = "eth_getBlockTransactionCountByNumber")]
fn block_transaction_count_by_number(&self, BlockNumber) -> Result<Option<U256>, Error>;
/// Returns the number of uncles in a block with given hash.
#[name("eth_getUncleCountByBlockHash")]
#[rpc(name = "eth_getUncleCountByBlockHash")]
fn block_uncles_count_by_hash(&self, H256) -> Result<Option<U256>, Error>;
/// Returns the number of uncles in a block with given block number.
#[name("eth_getUncleCountByBlockNumber")]
#[rpc(name = "eth_getUncleCountByBlockNumber")]
fn block_uncles_count_by_number(&self, BlockNumber) -> Result<Option<U256>, Error>;
/// Returns the code at given address at given time (block number).
#[name("eth_getCode")]
#[rpc(name = "eth_getCode")]
fn code_at(&self, H160, Trailing<BlockNumber>) -> Result<Bytes, Error>;
/// Sends signed transaction, returning its hash.
#[name("eth_sendRawTransaction")]
#[rpc(name = "eth_sendRawTransaction")]
fn send_raw_transaction(&self, Bytes) -> Result<H256, Error>;
/// Call contract, returning the output data.
#[name("eth_call")]
#[rpc(name = "eth_call")]
fn call(&self, CallRequest, Trailing<BlockNumber>) -> Result<Bytes, Error>;
/// Estimate gas needed for execution of given contract.
#[name("eth_estimateGas")]
#[rpc(name = "eth_estimateGas")]
fn estimate_gas(&self, CallRequest, Trailing<BlockNumber>) -> Result<U256, Error>;
/// Get transaction by its hash.
#[name("eth_getTransactionByHash")]
#[rpc(name = "eth_getTransactionByHash")]
fn transaction_by_hash(&self, H256) -> Result<Option<Transaction>, Error>;
/// Returns transaction at given block hash and index.
#[name("eth_getTransactionByBlockHashAndIndex")]
#[rpc(name = "eth_getTransactionByBlockHashAndIndex")]
fn transaction_by_block_hash_and_index(&self, H256, Index) -> Result<Option<Transaction>, Error>;
/// Returns transaction by given block number and index.
#[name("eth_getTransactionByBlockNumberAndIndex")]
#[rpc(name = "eth_getTransactionByBlockNumberAndIndex")]
fn transaction_by_block_number_and_index(&self, BlockNumber, Index) -> Result<Option<Transaction>, Error>;
/// Returns transaction receipt.
#[name("eth_getTransactionReceipt")]
#[rpc(name = "eth_getTransactionReceipt")]
fn transaction_receipt(&self, H256) -> Result<Option<Receipt>, Error>;
/// Returns an uncles at given block and index.
#[name("eth_getUncleByBlockHashAndIndex")]
#[rpc(name = "eth_getUncleByBlockHashAndIndex")]
fn uncle_by_block_hash_and_index(&self, H256, Index) -> Result<Option<Block>, Error>;
/// Returns an uncles at given block and index.
#[name("eth_getUncleByBlockNumberAndIndex")]
#[rpc(name = "eth_getUncleByBlockNumberAndIndex")]
fn uncle_by_block_number_and_index(&self, BlockNumber, Index) -> Result<Option<Block>, Error>;
/// Returns available compilers.
#[name("eth_getCompilers")]
#[rpc(name = "eth_getCompilers")]
fn compilers(&self) -> Result<Vec<String>, Error>;
/// Compiles lll code.
#[name("eth_compileLLL")]
#[rpc(name = "eth_compileLLL")]
fn compile_lll(&self, String) -> Result<Bytes, Error>;
/// Compiles solidity.
#[name("eth_compileSolidity")]
#[rpc(name = "eth_compileSolidity")]
fn compile_solidity(&self, String) -> Result<Bytes, Error>;
/// Compiles serpent.
#[name("eth_compileSerpent")]
#[rpc(name = "eth_compileSerpent")]
fn compile_serpent(&self, String) -> Result<Bytes, Error>;
/// Returns logs matching given filter object.
#[name("eth_getLogs")]
#[rpc(name = "eth_getLogs")]
fn logs(&self, Filter) -> Result<Vec<Log>, Error>;
/// Returns the hash of the current block, the seedHash, and the boundary condition to be met.
#[name("eth_getWork")]
#[rpc(name = "eth_getWork")]
fn work(&self, Trailing<u64>) -> Result<Work, Error>;
/// Used for submitting a proof-of-work solution.
#[name("eth_submitWork")]
#[rpc(name = "eth_submitWork")]
fn submit_work(&self, H64, H256, H256) -> Result<bool, Error>;
/// Used for submitting mining hashrate.
#[name("eth_submitHashrate")]
#[rpc(name = "eth_submitHashrate")]
fn submit_hashrate(&self, U256, H256) -> Result<bool, Error>;
}
}
build_rpc_trait! {
/// Eth filters rpc api (polling).
// TODO: do filters api properly
pub trait EthFilter {
/// Returns id of new filter.
#[name("eth_newFilter")]
#[rpc(name = "eth_newFilter")]
fn new_filter(&self, Filter) -> Result<U256, Error>;
/// Returns id of new block filter.
#[name("eth_newBlockFilter")]
#[rpc(name = "eth_newBlockFilter")]
fn new_block_filter(&self) -> Result<U256, Error>;
/// Returns id of new block filter.
#[name("eth_newPendingTransactionFilter")]
#[rpc(name = "eth_newPendingTransactionFilter")]
fn new_pending_transaction_filter(&self) -> Result<U256, Error>;
/// Returns filter changes since last poll.
#[name("eth_getFilterChanges")]
#[rpc(name = "eth_getFilterChanges")]
fn filter_changes(&self, Index) -> Result<FilterChanges, Error>;
/// Returns all logs matching given filter (in a range 'from' - 'to').
#[name("eth_getFilterLogs")]
#[rpc(name = "eth_getFilterLogs")]
fn filter_logs(&self, Index) -> Result<Vec<Log>, Error>;
/// Uninstalls filter.
#[name("eth_uninstallFilter")]
#[rpc(name = "eth_uninstallFilter")]
fn uninstall_filter(&self, Index) -> Result<bool, Error>;
}
}

View File

@ -15,113 +15,107 @@
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
//! Ethcore-specific rpc interface.
use std::sync::Arc;
use jsonrpc_core::*;
use jsonrpc_core::Error;
/// Ethcore-specific rpc interface.
pub trait Ethcore: Sized + Send + Sync + 'static {
use v1::helpers::auto_args::{Wrap, WrapAsync, Ready};
use v1::types::{H160, H256, H512, U256, Bytes, Peers, Transaction, RpcSettings};
/// Returns current transactions limit.
fn transactions_limit(&self, _: Params) -> Result<Value, Error>;
build_rpc_trait! {
/// Ethcore-specific rpc interface.
pub trait Ethcore {
/// Returns current transactions limit.
#[rpc(name = "ethcore_transactionsLimit")]
fn transactions_limit(&self) -> Result<usize, Error>;
/// Returns mining extra data.
fn extra_data(&self, _: Params) -> Result<Value, Error>;
/// Returns mining extra data.
#[rpc(name = "ethcore_extraData")]
fn extra_data(&self) -> Result<Bytes, Error>;
/// Returns mining gas floor target.
fn gas_floor_target(&self, _: Params) -> Result<Value, Error>;
/// Returns mining gas floor target.
#[rpc(name = "ethcore_gasFloorTarget")]
fn gas_floor_target(&self) -> Result<U256, Error>;
/// Returns mining gas floor cap.
fn gas_ceil_target(&self, _: Params) -> Result<Value, Error>;
/// Returns mining gas floor cap.
#[rpc(name = "ethcore_gasCeilTarget")]
fn gas_ceil_target(&self) -> Result<U256, Error>;
/// Returns minimal gas price for transaction to be included in queue.
fn min_gas_price(&self, _: Params) -> Result<Value, Error>;
/// Returns minimal gas price for transaction to be included in queue.
#[rpc(name = "ethcore_minGasPrice")]
fn min_gas_price(&self) -> Result<U256, Error>;
/// Returns latest logs
fn dev_logs(&self, _: Params) -> Result<Value, Error>;
/// Returns latest logs
#[rpc(name = "ethcore_devLogs")]
fn dev_logs(&self) -> Result<Vec<String>, Error>;
/// Returns logs levels
fn dev_logs_levels(&self, _: Params) -> Result<Value, Error>;
/// Returns logs levels
#[rpc(name = "ethcore_devLogsLevels")]
fn dev_logs_levels(&self) -> Result<String, Error>;
/// Returns chain name
fn net_chain(&self, _: Params) -> Result<Value, Error>;
/// Returns chain name
#[rpc(name = "ethcore_netChain")]
fn net_chain(&self) -> Result<String, Error>;
/// Returns peers details
fn net_peers(&self, _: Params) -> Result<Value, Error>;
/// Returns peers details
#[rpc(name = "ethcore_netPeers")]
fn net_peers(&self) -> Result<Peers, Error>;
/// Returns network port
fn net_port(&self, _: Params) -> Result<Value, Error>;
/// Returns network port
#[rpc(name = "ethcore_netPort")]
fn net_port(&self) -> Result<u16, Error>;
/// Returns rpc settings
fn rpc_settings(&self, _: Params) -> Result<Value, Error>;
/// Returns rpc settings
#[rpc(name = "ethcore_rpcSettings")]
fn rpc_settings(&self) -> Result<RpcSettings, Error>;
/// Returns node name
fn node_name(&self, _: Params) -> Result<Value, Error>;
/// Returns node name
#[rpc(name = "ethcore_nodeName")]
fn node_name(&self) -> Result<String, Error>;
/// Returns default extra data
fn default_extra_data(&self, _: Params) -> Result<Value, Error>;
/// Returns default extra data
#[rpc(name = "ethcore_defaultExtraData")]
fn default_extra_data(&self) -> Result<Bytes, Error>;
/// Returns distribution of gas price in latest blocks.
fn gas_price_statistics(&self, _: Params) -> Result<Value, Error>;
/// Returns distribution of gas price in latest blocks.
#[rpc(name = "ethcore_gasPriceStatistics")]
fn gas_price_statistics(&self) -> Result<Vec<U256>, Error>;
/// Returns number of unsigned transactions waiting in the signer queue (if signer enabled)
/// Returns error when signer is disabled
fn unsigned_transactions_count(&self, _: Params) -> Result<Value, Error>;
/// Returns number of unsigned transactions waiting in the signer queue (if signer enabled)
/// Returns error when signer is disabled
#[rpc(name = "ethcore_unsignedTransactionsCount")]
fn unsigned_transactions_count(&self) -> Result<usize, Error>;
/// Returns a cryptographically random phrase sufficient for securely seeding a secret key.
fn generate_secret_phrase(&self, _: Params) -> Result<Value, Error>;
/// Returns a cryptographically random phrase sufficient for securely seeding a secret key.
#[rpc(name = "ethcore_generateSecretPhrase")]
fn generate_secret_phrase(&self) -> Result<String, Error>;
/// Returns whatever address would be derived from the given phrase if it were to seed a brainwallet.
fn phrase_to_address(&self, _: Params) -> Result<Value, Error>;
/// Returns whatever address would be derived from the given phrase if it were to seed a brainwallet.
#[rpc(name = "ethcore_phraseToAddress")]
fn phrase_to_address(&self, String) -> Result<H160, Error>;
/// Returns the value of the registrar for this network.
fn registry_address(&self, _: Params) -> Result<Value, Error>;
/// Returns the value of the registrar for this network.
#[rpc(name = "ethcore_registryAddress")]
fn registry_address(&self) -> Result<Option<H160>, Error>;
/// Returns all addresses if Fat DB is enabled (`--fat-db`), or null if not.
/// Takes no parameters.
fn list_accounts(&self, _: Params) -> Result<Value, Error>;
/// Returns all addresses if Fat DB is enabled (`--fat-db`), or null if not.
#[rpc(name = "ethcore_listAccounts")]
fn list_accounts(&self) -> Result<Option<Vec<H160>>, Error>;
/// Returns all storage keys of the given address (first parameter) if Fat DB is enabled (`--fat-db`),
/// or null if not.
fn list_storage_keys(&self, _: Params) -> Result<Value, Error>;
/// Returns all storage keys of the given address (first parameter) if Fat DB is enabled (`--fat-db`),
/// or null if not.
#[rpc(name = "ethcore_listStorageKeys")]
fn list_storage_keys(&self, H160) -> Result<Option<Vec<H256>>, Error>;
/// Encrypt some data with a public key under ECIES.
/// First parameter is the 512-byte destination public key, second is the message.
fn encrypt_message(&self, _: Params) -> Result<Value, Error>;
/// Encrypt some data with a public key under ECIES.
/// First parameter is the 512-byte destination public key, second is the message.
#[rpc(name = "ethcore_encryptMessage")]
fn encrypt_message(&self, H512, Bytes) -> Result<Bytes, Error>;
/// Returns all pending (current) transactions from transaction queue.
fn pending_transactions(&self, _: Params) -> Result<Value, Error>;
/// Returns all pending transactions from transaction queue.
#[rpc(name = "ethcore_pendingTransactions")]
fn pending_transactions(&self) -> Result<Vec<Transaction>, Error>;
/// Hash a file content under given URL.
fn hash_content(&self, _: Params, _: Ready);
/// 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("ethcore_extraData", Ethcore::extra_data);
delegate.add_method("ethcore_gasFloorTarget", Ethcore::gas_floor_target);
delegate.add_method("ethcore_gasCeilTarget", Ethcore::gas_ceil_target);
delegate.add_method("ethcore_minGasPrice", Ethcore::min_gas_price);
delegate.add_method("ethcore_transactionsLimit", Ethcore::transactions_limit);
delegate.add_method("ethcore_devLogs", Ethcore::dev_logs);
delegate.add_method("ethcore_devLogsLevels", Ethcore::dev_logs_levels);
delegate.add_method("ethcore_netChain", Ethcore::net_chain);
delegate.add_method("ethcore_netPeers", Ethcore::net_peers);
delegate.add_method("ethcore_netPort", Ethcore::net_port);
delegate.add_method("ethcore_rpcSettings", Ethcore::rpc_settings);
delegate.add_method("ethcore_nodeName", Ethcore::node_name);
delegate.add_method("ethcore_defaultExtraData", Ethcore::default_extra_data);
delegate.add_method("ethcore_gasPriceStatistics", Ethcore::gas_price_statistics);
delegate.add_method("ethcore_unsignedTransactionsCount", Ethcore::unsigned_transactions_count);
delegate.add_method("ethcore_generateSecretPhrase", Ethcore::generate_secret_phrase);
delegate.add_method("ethcore_phraseToAddress", Ethcore::phrase_to_address);
delegate.add_method("ethcore_registryAddress", Ethcore::registry_address);
delegate.add_method("ethcore_listAccounts", Ethcore::list_accounts);
delegate.add_method("ethcore_listStorageKeys", Ethcore::list_storage_keys);
delegate.add_method("ethcore_encryptMessage", Ethcore::encrypt_message);
delegate.add_method("ethcore_pendingTransactions", Ethcore::pending_transactions);
delegate.add_async_method("ethcore_hashContent", Ethcore::hash_content);
delegate
/// Hash a file content under given URL.
#[rpc(async, name = "ethcore_hashContent")]
fn hash_content(&self, Ready<H256>, String);
}
}
}

View File

@ -16,66 +16,64 @@
//! Ethcore-specific rpc interface for operations altering the settings.
use std::sync::Arc;
use jsonrpc_core::*;
use jsonrpc_core::Error;
/// Ethcore-specific rpc interface for operations altering the settings.
pub trait EthcoreSet: Sized + Send + Sync + 'static {
use v1::helpers::auto_args::Wrap;
use v1::types::{Bytes, H160, U256};
/// Sets new minimal gas price for mined blocks.
fn set_min_gas_price(&self, _: Params) -> Result<Value, Error>;
build_rpc_trait! {
/// Ethcore-specific rpc interface for operations altering the settings.
pub trait EthcoreSet {
/// Sets new minimal gas price for mined blocks.
#[rpc(name = "ethcore_setMinGasPrice")]
fn set_min_gas_price(&self, U256) -> Result<bool, Error>;
/// Sets new gas floor target for mined blocks.
fn set_gas_floor_target(&self, _: Params) -> Result<Value, Error>;
/// Sets new gas floor target for mined blocks.
#[rpc(name = "ethcore_setGasFloorTarget")]
fn set_gas_floor_target(&self, U256) -> Result<bool, Error>;
/// Sets new gas ceiling target for mined blocks.
fn set_gas_ceil_target(&self, _: Params) -> Result<Value, Error>;
/// Sets new gas ceiling target for mined blocks.
#[rpc(name = "ethcore_setGasCeilTarget")]
fn set_gas_ceil_target(&self, U256) -> Result<bool, Error>;
/// Sets new extra data for mined blocks.
fn set_extra_data(&self, _: Params) -> Result<Value, Error>;
/// Sets new extra data for mined blocks.
#[rpc(name = "ethcore_setExtraData")]
fn set_extra_data(&self, Bytes) -> Result<bool, Error>;
/// Sets new author for mined block.
fn set_author(&self, _: Params) -> Result<Value, Error>;
/// Sets new author for mined block.
#[rpc(name = "ethcore_setAuthor")]
fn set_author(&self, H160) -> Result<bool, Error>;
/// Sets the limits for transaction queue.
fn set_transactions_limit(&self, _: Params) -> Result<Value, Error>;
/// Sets the limits for transaction queue.
#[rpc(name = "ethcore_setTransactionsLimit")]
fn set_transactions_limit(&self, usize) -> Result<bool, Error>;
/// Sets the maximum amount of gas a single transaction may consume.
fn set_tx_gas_limit(&self, _: Params) -> Result<Value, Error>;
/// Sets the maximum amount of gas a single transaction may consume.
#[rpc(name = "ethcore_setMaxTransactionGas")]
fn set_tx_gas_limit(&self, U256) -> Result<bool, Error>;
/// Add a reserved peer.
fn add_reserved_peer(&self, _: Params) -> Result<Value, Error>;
/// Add a reserved peer.
#[rpc(name = "ethcore_addReservedPeer")]
fn add_reserved_peer(&self, String) -> Result<bool, Error>;
/// Remove a reserved peer.
fn remove_reserved_peer(&self, _: Params) -> Result<Value, Error>;
/// Remove a reserved peer.
#[rpc(name = "ethcore_removeReservedPeer")]
fn remove_reserved_peer(&self, String) -> Result<bool, Error>;
/// Drop all non-reserved peers.
fn drop_non_reserved_peers(&self, _: Params) -> Result<Value, Error>;
/// Drop all non-reserved peers.
#[rpc(name = "ethcore_dropNonReservedPeers")]
fn drop_non_reserved_peers(&self) -> Result<bool, Error>;
/// Accept non-reserved peers (default behavior)
fn accept_non_reserved_peers(&self, _: Params) -> Result<Value, Error>;
/// Accept non-reserved peers (default behavior)
#[rpc(name = "ethcore_acceptNonReservedPeers")]
fn accept_non_reserved_peers(&self) -> Result<bool, Error>;
/// Start the network.
fn start_network(&self, _: Params) -> Result<Value, Error>;
/// Start the network.
#[rpc(name = "ethcore_startNetwork")]
fn start_network(&self) -> Result<bool, Error>;
/// Stop the network.
fn stop_network(&self, _: Params) -> Result<Value, Error>;
/// 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("ethcore_setMinGasPrice", EthcoreSet::set_min_gas_price);
delegate.add_method("ethcore_setGasFloorTarget", EthcoreSet::set_gas_floor_target);
delegate.add_method("ethcore_setGasCeilTarget", EthcoreSet::set_gas_ceil_target);
delegate.add_method("ethcore_setExtraData", EthcoreSet::set_extra_data);
delegate.add_method("ethcore_setAuthor", EthcoreSet::set_author);
delegate.add_method("ethcore_setMaxTransactionGas", EthcoreSet::set_tx_gas_limit);
delegate.add_method("ethcore_setTransactionsLimit", EthcoreSet::set_transactions_limit);
delegate.add_method("ethcore_addReservedPeer", EthcoreSet::add_reserved_peer);
delegate.add_method("ethcore_removeReservedPeer", EthcoreSet::remove_reserved_peer);
delegate.add_method("ethcore_dropNonReservedPeers", EthcoreSet::drop_non_reserved_peers);
delegate.add_method("ethcore_acceptNonReservedPeers", EthcoreSet::accept_non_reserved_peers);
delegate
/// Stop the network.
#[rpc(name = "ethcore_stopNetwork")]
fn stop_network(&self) -> Result<bool, Error>;
}
}
}

View File

@ -15,27 +15,24 @@
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
//! Net rpc interface.
use std::sync::Arc;
use jsonrpc_core::*;
use jsonrpc_core::Error;
/// Net rpc interface.
pub trait Net: Sized + Send + Sync + 'static {
/// Returns protocol version.
fn version(&self, _: Params) -> Result<Value, Error>;
use v1::helpers::auto_args::Wrap;
/// Returns number of peers connected to node.
fn peer_count(&self, _: Params) -> Result<Value, Error>;
build_rpc_trait! {
/// Net rpc interface.
pub trait Net {
/// Returns protocol version.
#[rpc(name = "net_version")]
fn version(&self) -> Result<String, Error>;
/// Returns true if client is actively listening for network connections.
/// Otherwise false.
fn is_listening(&self, _: Params) -> Result<Value, Error>;
/// Returns number of peers connected to node.
#[rpc(name = "net_peerCount")]
fn peer_count(&self) -> Result<String, Error>;
/// 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.add_method("net_listening", Net::is_listening);
delegate
/// Returns true if client is actively listening for network connections.
/// Otherwise false.
#[rpc(name = "net_listening")]
fn is_listening(&self) -> Result<bool, Error>;
}
}
}

View File

@ -16,26 +16,21 @@
//! RPC interface.
use std::sync::Arc;
use jsonrpc_core::*;
use jsonrpc_core::Error;
/// RPC Interface.
pub trait Rpc: Sized + Send + Sync + 'static {
use v1::helpers::auto_args::Wrap;
/// Returns supported modules for Geth 1.3.6
fn modules(&self, _: Params) -> Result<Value, Error>;
use std::collections::BTreeMap;
/// Returns supported modules for Geth 1.4.0
fn rpc_modules(&self, _: Params) -> Result<Value, Error>;
build_rpc_trait! {
/// RPC Interface.
pub trait Rpc {
/// Returns supported modules for Geth 1.3.6
#[rpc(name = "modules")]
fn modules(&self) -> Result<BTreeMap<String, String>, Error>;
/// Should be used to convert object to io delegate.
fn to_delegate(self) -> IoDelegate<Self> {
let mut delegate = IoDelegate::new(Arc::new(self));
// Geth 1.3.6 compatibility
delegate.add_method("modules", Rpc::modules);
// Geth 1.4.0 compatibility
delegate.add_method("rpc_modules", Rpc::rpc_modules);
delegate
/// Returns supported modules for Geth 1.4.0
#[rpc(name = "rpc_modules")]
fn rpc_modules(&self) -> Result<BTreeMap<String, String>, Error>;
}
}
}

View File

@ -27,6 +27,7 @@ mod sync;
mod transaction;
mod transaction_request;
mod receipt;
mod rpc_settings;
mod trace;
mod trace_filter;
mod uint;
@ -45,6 +46,7 @@ pub use self::sync::{SyncStatus, SyncInfo, Peers};
pub use self::transaction::Transaction;
pub use self::transaction_request::TransactionRequest;
pub use self::receipt::Receipt;
pub use self::rpc_settings::RpcSettings;
pub use self::trace::{LocalizedTrace, TraceResults};
pub use self::trace_filter::TraceFilter;
pub use self::uint::U256;

View File

@ -0,0 +1,28 @@
// 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/>.
//! RPC Settings data.
/// Values of RPC settings.
#[derive(Serialize, Deserialize)]
pub struct RpcSettings {
/// Whether RPC is enabled.
pub enabled: bool,
/// The interface being listened on.
pub interface: String,
/// The port being listened on.
pub port: u64,
}