Silent running operating modes (#1477)
* Command=line options. * Keep alive for the eth protocol. * Wire up final pieces. * No network when dark. * Passive and dark mode work. * Ensure all RPCs keep alive. * Fix tests. * Fix minor bug. * Minor whitespace. * Split out some of the sleep-state. * Fix help text.
This commit is contained in:
@@ -241,6 +241,19 @@ fn no_author_err() -> Error {
|
||||
}
|
||||
}
|
||||
|
||||
impl<C, S, M, EM> EthClient<C, S, M, EM> where
|
||||
C: MiningBlockChainClient + 'static,
|
||||
S: SyncProvider + 'static,
|
||||
M: MinerService + 'static,
|
||||
EM: ExternalMinerService + 'static {
|
||||
|
||||
fn active(&self) -> Result<(), Error> {
|
||||
// TODO: only call every 30s at most.
|
||||
take_weak!(self.client).keep_alive();
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
impl<C, S, M, EM> Eth for EthClient<C, S, M, EM> where
|
||||
C: MiningBlockChainClient + 'static,
|
||||
S: SyncProvider + 'static,
|
||||
@@ -248,6 +261,7 @@ impl<C, S, M, EM> Eth for EthClient<C, S, M, EM> where
|
||||
EM: ExternalMinerService + 'static {
|
||||
|
||||
fn protocol_version(&self, params: Params) -> Result<Value, Error> {
|
||||
try!(self.active());
|
||||
match params {
|
||||
Params::None => Ok(Value::String(format!("{}", take_weak!(self.sync).status().protocol_version).to_owned())),
|
||||
_ => Err(Error::invalid_params())
|
||||
@@ -255,6 +269,7 @@ impl<C, S, M, EM> Eth for EthClient<C, S, M, EM> where
|
||||
}
|
||||
|
||||
fn syncing(&self, params: Params) -> Result<Value, Error> {
|
||||
try!(self.active());
|
||||
match params {
|
||||
Params::None => {
|
||||
let status = take_weak!(self.sync).status();
|
||||
@@ -281,6 +296,7 @@ impl<C, S, M, EM> Eth for EthClient<C, S, M, EM> where
|
||||
}
|
||||
|
||||
fn author(&self, params: Params) -> Result<Value, Error> {
|
||||
try!(self.active());
|
||||
match params {
|
||||
Params::None => to_value(&take_weak!(self.miner).author()),
|
||||
_ => Err(Error::invalid_params()),
|
||||
@@ -288,6 +304,7 @@ impl<C, S, M, EM> Eth for EthClient<C, S, M, EM> where
|
||||
}
|
||||
|
||||
fn is_mining(&self, params: Params) -> Result<Value, Error> {
|
||||
try!(self.active());
|
||||
match params {
|
||||
Params::None => to_value(&self.external_miner.is_mining()),
|
||||
_ => Err(Error::invalid_params())
|
||||
@@ -295,6 +312,7 @@ impl<C, S, M, EM> Eth for EthClient<C, S, M, EM> where
|
||||
}
|
||||
|
||||
fn hashrate(&self, params: Params) -> Result<Value, Error> {
|
||||
try!(self.active());
|
||||
match params {
|
||||
Params::None => to_value(&self.external_miner.hashrate()),
|
||||
_ => Err(Error::invalid_params())
|
||||
@@ -302,6 +320,7 @@ impl<C, S, M, EM> Eth for EthClient<C, S, M, EM> where
|
||||
}
|
||||
|
||||
fn gas_price(&self, params: Params) -> Result<Value, Error> {
|
||||
try!(self.active());
|
||||
match params {
|
||||
Params::None => {
|
||||
let (client, miner) = (take_weak!(self.client), take_weak!(self.miner));
|
||||
@@ -312,11 +331,13 @@ impl<C, S, M, EM> Eth for EthClient<C, S, M, EM> where
|
||||
}
|
||||
|
||||
fn accounts(&self, _: Params) -> Result<Value, Error> {
|
||||
try!(self.active());
|
||||
let store = take_weak!(self.accounts);
|
||||
to_value(&store.accounts())
|
||||
}
|
||||
|
||||
fn block_number(&self, params: Params) -> Result<Value, Error> {
|
||||
try!(self.active());
|
||||
match params {
|
||||
Params::None => to_value(&U256::from(take_weak!(self.client).chain_info().best_block_number)),
|
||||
_ => Err(Error::invalid_params())
|
||||
@@ -324,6 +345,7 @@ impl<C, S, M, EM> Eth for EthClient<C, S, M, EM> where
|
||||
}
|
||||
|
||||
fn balance(&self, params: Params) -> Result<Value, Error> {
|
||||
try!(self.active());
|
||||
from_params_default_second(params)
|
||||
.and_then(|(address, block_number,)| match block_number {
|
||||
BlockNumber::Pending => to_value(&take_weak!(self.miner).balance(take_weak!(self.client).deref(), &address)),
|
||||
@@ -332,6 +354,7 @@ impl<C, S, M, EM> Eth for EthClient<C, S, M, EM> where
|
||||
}
|
||||
|
||||
fn storage_at(&self, params: Params) -> Result<Value, Error> {
|
||||
try!(self.active());
|
||||
from_params_default_third::<Address, U256>(params)
|
||||
.and_then(|(address, position, block_number,)| match block_number {
|
||||
BlockNumber::Pending => to_value(&U256::from(take_weak!(self.miner).storage_at(&*take_weak!(self.client), &address, &H256::from(position)))),
|
||||
@@ -343,6 +366,7 @@ impl<C, S, M, EM> Eth for EthClient<C, S, M, EM> where
|
||||
}
|
||||
|
||||
fn transaction_count(&self, params: Params) -> Result<Value, Error> {
|
||||
try!(self.active());
|
||||
from_params_default_second(params)
|
||||
.and_then(|(address, block_number,)| match block_number {
|
||||
BlockNumber::Pending => to_value(&take_weak!(self.miner).nonce(take_weak!(self.client).deref(), &address)),
|
||||
@@ -351,6 +375,7 @@ impl<C, S, M, EM> Eth for EthClient<C, S, M, EM> where
|
||||
}
|
||||
|
||||
fn block_transaction_count_by_hash(&self, params: Params) -> Result<Value, Error> {
|
||||
try!(self.active());
|
||||
from_params::<(H256,)>(params)
|
||||
.and_then(|(hash,)| // match
|
||||
take_weak!(self.client).block(BlockID::Hash(hash))
|
||||
@@ -358,6 +383,7 @@ impl<C, S, M, EM> Eth for EthClient<C, S, M, EM> where
|
||||
}
|
||||
|
||||
fn block_transaction_count_by_number(&self, params: Params) -> Result<Value, Error> {
|
||||
try!(self.active());
|
||||
from_params::<(BlockNumber,)>(params)
|
||||
.and_then(|(block_number,)| match block_number {
|
||||
BlockNumber::Pending => to_value(
|
||||
@@ -369,6 +395,7 @@ impl<C, S, M, EM> Eth for EthClient<C, S, M, EM> where
|
||||
}
|
||||
|
||||
fn block_uncles_count_by_hash(&self, params: Params) -> Result<Value, Error> {
|
||||
try!(self.active());
|
||||
from_params::<(H256,)>(params)
|
||||
.and_then(|(hash,)|
|
||||
take_weak!(self.client).block(BlockID::Hash(hash))
|
||||
@@ -376,6 +403,7 @@ impl<C, S, M, EM> Eth for EthClient<C, S, M, EM> where
|
||||
}
|
||||
|
||||
fn block_uncles_count_by_number(&self, params: Params) -> Result<Value, Error> {
|
||||
try!(self.active());
|
||||
from_params::<(BlockNumber,)>(params)
|
||||
.and_then(|(block_number,)| match block_number {
|
||||
BlockNumber::Pending => to_value(&U256::from(0)),
|
||||
@@ -385,6 +413,7 @@ impl<C, S, M, EM> Eth for EthClient<C, S, M, EM> where
|
||||
}
|
||||
|
||||
fn code_at(&self, params: Params) -> Result<Value, Error> {
|
||||
try!(self.active());
|
||||
from_params_default_second(params)
|
||||
.and_then(|(address, block_number,)| match block_number {
|
||||
BlockNumber::Pending => to_value(&take_weak!(self.miner).code(take_weak!(self.client).deref(), &address).map_or_else(Bytes::default, Bytes::new)),
|
||||
@@ -394,16 +423,19 @@ impl<C, S, M, EM> Eth for EthClient<C, S, M, EM> where
|
||||
}
|
||||
|
||||
fn block_by_hash(&self, params: Params) -> Result<Value, Error> {
|
||||
try!(self.active());
|
||||
from_params::<(H256, bool)>(params)
|
||||
.and_then(|(hash, include_txs)| self.block(BlockID::Hash(hash), include_txs))
|
||||
}
|
||||
|
||||
fn block_by_number(&self, params: Params) -> Result<Value, Error> {
|
||||
try!(self.active());
|
||||
from_params::<(BlockNumber, bool)>(params)
|
||||
.and_then(|(number, include_txs)| self.block(number.into(), include_txs))
|
||||
}
|
||||
|
||||
fn transaction_by_hash(&self, params: Params) -> Result<Value, Error> {
|
||||
try!(self.active());
|
||||
from_params::<(H256,)>(params)
|
||||
.and_then(|(hash,)| {
|
||||
let miner = take_weak!(self.miner);
|
||||
@@ -415,16 +447,19 @@ impl<C, S, M, EM> Eth for EthClient<C, S, M, EM> where
|
||||
}
|
||||
|
||||
fn transaction_by_block_hash_and_index(&self, params: Params) -> Result<Value, Error> {
|
||||
try!(self.active());
|
||||
from_params::<(H256, Index)>(params)
|
||||
.and_then(|(hash, index)| self.transaction(TransactionID::Location(BlockID::Hash(hash), index.value())))
|
||||
}
|
||||
|
||||
fn transaction_by_block_number_and_index(&self, params: Params) -> Result<Value, Error> {
|
||||
try!(self.active());
|
||||
from_params::<(BlockNumber, Index)>(params)
|
||||
.and_then(|(number, index)| self.transaction(TransactionID::Location(number.into(), index.value())))
|
||||
}
|
||||
|
||||
fn transaction_receipt(&self, params: Params) -> Result<Value, Error> {
|
||||
try!(self.active());
|
||||
from_params::<(H256,)>(params)
|
||||
.and_then(|(hash,)| {
|
||||
let miner = take_weak!(self.miner);
|
||||
@@ -440,16 +475,19 @@ impl<C, S, M, EM> Eth for EthClient<C, S, M, EM> where
|
||||
}
|
||||
|
||||
fn uncle_by_block_hash_and_index(&self, params: Params) -> Result<Value, Error> {
|
||||
try!(self.active());
|
||||
from_params::<(H256, Index)>(params)
|
||||
.and_then(|(hash, index)| self.uncle(UncleID { block: BlockID::Hash(hash), position: index.value() }))
|
||||
}
|
||||
|
||||
fn uncle_by_block_number_and_index(&self, params: Params) -> Result<Value, Error> {
|
||||
try!(self.active());
|
||||
from_params::<(BlockNumber, Index)>(params)
|
||||
.and_then(|(number, index)| self.uncle(UncleID { block: number.into(), position: index.value() }))
|
||||
}
|
||||
|
||||
fn compilers(&self, params: Params) -> Result<Value, Error> {
|
||||
try!(self.active());
|
||||
match params {
|
||||
Params::None => to_value(&vec![] as &Vec<String>),
|
||||
_ => Err(Error::invalid_params())
|
||||
@@ -457,6 +495,7 @@ impl<C, S, M, EM> Eth for EthClient<C, S, M, EM> where
|
||||
}
|
||||
|
||||
fn logs(&self, params: Params) -> Result<Value, Error> {
|
||||
try!(self.active());
|
||||
from_params::<(Filter,)>(params)
|
||||
.and_then(|(filter,)| {
|
||||
let include_pending = filter.to_block == Some(BlockNumber::Pending);
|
||||
@@ -476,6 +515,7 @@ impl<C, S, M, EM> Eth for EthClient<C, S, M, EM> where
|
||||
}
|
||||
|
||||
fn work(&self, params: Params) -> Result<Value, Error> {
|
||||
try!(self.active());
|
||||
match params {
|
||||
Params::None => {
|
||||
let client = take_weak!(self.client);
|
||||
@@ -512,6 +552,7 @@ impl<C, S, M, EM> Eth for EthClient<C, S, M, EM> where
|
||||
}
|
||||
|
||||
fn submit_work(&self, params: Params) -> Result<Value, Error> {
|
||||
try!(self.active());
|
||||
from_params::<(H64, H256, H256)>(params).and_then(|(nonce, pow_hash, mix_hash)| {
|
||||
trace!(target: "miner", "submit_work: Decoded: nonce={}, pow_hash={}, mix_hash={}", nonce, pow_hash, mix_hash);
|
||||
let miner = take_weak!(self.miner);
|
||||
@@ -523,6 +564,7 @@ impl<C, S, M, EM> Eth for EthClient<C, S, M, EM> where
|
||||
}
|
||||
|
||||
fn submit_hashrate(&self, params: Params) -> Result<Value, Error> {
|
||||
try!(self.active());
|
||||
from_params::<(U256, H256)>(params).and_then(|(rate, id)| {
|
||||
self.external_miner.submit_hashrate(rate, id);
|
||||
to_value(&true)
|
||||
@@ -530,6 +572,7 @@ impl<C, S, M, EM> Eth for EthClient<C, S, M, EM> where
|
||||
}
|
||||
|
||||
fn send_raw_transaction(&self, params: Params) -> Result<Value, Error> {
|
||||
try!(self.active());
|
||||
from_params::<(Bytes, )>(params)
|
||||
.and_then(|(raw_transaction, )| {
|
||||
let raw_transaction = raw_transaction.to_vec();
|
||||
@@ -541,6 +584,7 @@ impl<C, S, M, EM> Eth for EthClient<C, S, M, EM> where
|
||||
}
|
||||
|
||||
fn call(&self, params: Params) -> Result<Value, Error> {
|
||||
try!(self.active());
|
||||
trace!(target: "jsonrpc", "call: {:?}", params);
|
||||
from_params_default_second(params)
|
||||
.and_then(|(request, block_number,)| {
|
||||
@@ -555,6 +599,7 @@ impl<C, S, M, EM> Eth for EthClient<C, S, M, EM> where
|
||||
}
|
||||
|
||||
fn estimate_gas(&self, params: Params) -> Result<Value, Error> {
|
||||
try!(self.active());
|
||||
from_params_default_second(params)
|
||||
.and_then(|(request, block_number,)| {
|
||||
let signed = try!(self.sign_call(request));
|
||||
@@ -568,14 +613,17 @@ impl<C, S, M, EM> Eth for EthClient<C, S, M, EM> where
|
||||
}
|
||||
|
||||
fn compile_lll(&self, _: Params) -> Result<Value, Error> {
|
||||
try!(self.active());
|
||||
rpc_unimplemented!()
|
||||
}
|
||||
|
||||
fn compile_serpent(&self, _: Params) -> Result<Value, Error> {
|
||||
try!(self.active());
|
||||
rpc_unimplemented!()
|
||||
}
|
||||
|
||||
fn compile_solidity(&self, _: Params) -> Result<Value, Error> {
|
||||
try!(self.active());
|
||||
rpc_unimplemented!()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -52,6 +52,12 @@ impl<C, M> EthFilterClient<C, M> where
|
||||
polls: Mutex::new(PollManager::new()),
|
||||
}
|
||||
}
|
||||
|
||||
fn active(&self) -> Result<(), Error> {
|
||||
// TODO: only call every 30s at most.
|
||||
take_weak!(self.client).keep_alive();
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
impl<C, M> EthFilter for EthFilterClient<C, M> where
|
||||
@@ -59,6 +65,7 @@ impl<C, M> EthFilter for EthFilterClient<C, M> where
|
||||
M: MinerService + 'static {
|
||||
|
||||
fn new_filter(&self, params: Params) -> Result<Value, Error> {
|
||||
try!(self.active());
|
||||
from_params::<(Filter,)>(params)
|
||||
.and_then(|(filter,)| {
|
||||
let mut polls = self.polls.lock().unwrap();
|
||||
@@ -69,6 +76,7 @@ impl<C, M> EthFilter for EthFilterClient<C, M> where
|
||||
}
|
||||
|
||||
fn new_block_filter(&self, params: Params) -> Result<Value, Error> {
|
||||
try!(self.active());
|
||||
match params {
|
||||
Params::None => {
|
||||
let mut polls = self.polls.lock().unwrap();
|
||||
@@ -80,6 +88,7 @@ impl<C, M> EthFilter for EthFilterClient<C, M> where
|
||||
}
|
||||
|
||||
fn new_pending_transaction_filter(&self, params: Params) -> Result<Value, Error> {
|
||||
try!(self.active());
|
||||
match params {
|
||||
Params::None => {
|
||||
let mut polls = self.polls.lock().unwrap();
|
||||
@@ -93,6 +102,7 @@ impl<C, M> EthFilter for EthFilterClient<C, M> where
|
||||
}
|
||||
|
||||
fn filter_changes(&self, params: Params) -> Result<Value, Error> {
|
||||
try!(self.active());
|
||||
let client = take_weak!(self.client);
|
||||
from_params::<(Index,)>(params)
|
||||
.and_then(|(index,)| {
|
||||
@@ -181,6 +191,7 @@ impl<C, M> EthFilter for EthFilterClient<C, M> where
|
||||
}
|
||||
|
||||
fn filter_logs(&self, params: Params) -> Result<Value, Error> {
|
||||
try!(self.active());
|
||||
from_params::<(Index,)>(params)
|
||||
.and_then(|(index,)| {
|
||||
let mut polls = self.polls.lock().unwrap();
|
||||
@@ -206,6 +217,7 @@ impl<C, M> EthFilter for EthFilterClient<C, M> where
|
||||
}
|
||||
|
||||
fn uninstall_filter(&self, params: Params) -> Result<Value, Error> {
|
||||
try!(self.active());
|
||||
from_params::<(Index,)>(params)
|
||||
.and_then(|(index,)| {
|
||||
self.polls.lock().unwrap().remove_poll(&index.value());
|
||||
|
||||
@@ -61,6 +61,12 @@ impl<C, M> EthSigningQueueClient<C, M> where C: MiningBlockChainClient, M: Miner
|
||||
miner: Arc::downgrade(miner),
|
||||
}
|
||||
}
|
||||
|
||||
fn active(&self) -> Result<(), Error> {
|
||||
// TODO: only call every 30s at most.
|
||||
take_weak!(self.client).keep_alive();
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
impl<C, M> EthSigning for EthSigningQueueClient<C, M>
|
||||
@@ -68,12 +74,14 @@ impl<C, M> EthSigning for EthSigningQueueClient<C, M>
|
||||
{
|
||||
|
||||
fn sign(&self, _params: Params) -> Result<Value, Error> {
|
||||
try!(self.active());
|
||||
warn!("Invoking eth_sign is not yet supported with signer enabled.");
|
||||
// TODO [ToDr] Implement sign when rest of the signing queue is ready.
|
||||
rpc_unimplemented!()
|
||||
}
|
||||
|
||||
fn send_transaction(&self, params: Params) -> Result<Value, Error> {
|
||||
try!(self.active());
|
||||
from_params::<(TransactionRequest, )>(params)
|
||||
.and_then(|(mut request, )| {
|
||||
let accounts = take_weak!(self.accounts);
|
||||
@@ -118,6 +126,12 @@ impl<C, M> EthSigningUnsafeClient<C, M> where
|
||||
accounts: Arc::downgrade(accounts),
|
||||
}
|
||||
}
|
||||
|
||||
fn active(&self) -> Result<(), Error> {
|
||||
// TODO: only call every 30s at most.
|
||||
take_weak!(self.client).keep_alive();
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
impl<C, M> EthSigning for EthSigningUnsafeClient<C, M> where
|
||||
@@ -125,12 +139,14 @@ impl<C, M> EthSigning for EthSigningUnsafeClient<C, M> where
|
||||
M: MinerService + 'static {
|
||||
|
||||
fn sign(&self, params: Params) -> Result<Value, Error> {
|
||||
try!(self.active());
|
||||
from_params::<(Address, H256)>(params).and_then(|(addr, msg)| {
|
||||
to_value(&take_weak!(self.accounts).sign(addr, msg).unwrap_or(H520::zero()))
|
||||
})
|
||||
}
|
||||
|
||||
fn send_transaction(&self, params: Params) -> Result<Value, Error> {
|
||||
try!(self.active());
|
||||
from_params::<(TransactionRequest, )>(params)
|
||||
.and_then(|(request, )| {
|
||||
let sender = request.from;
|
||||
|
||||
@@ -52,56 +52,74 @@ impl<C, M> EthcoreClient<C, M> where C: MiningBlockChainClient, M: MinerService
|
||||
confirmations_queue: queue,
|
||||
}
|
||||
}
|
||||
|
||||
fn active(&self) -> Result<(), Error> {
|
||||
// TODO: only call every 30s at most.
|
||||
take_weak!(self.client).keep_alive();
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
impl<C, M> Ethcore for EthcoreClient<C, M> where M: MinerService + 'static, C: MiningBlockChainClient + 'static {
|
||||
|
||||
fn transactions_limit(&self, _: Params) -> Result<Value, Error> {
|
||||
try!(self.active());
|
||||
to_value(&take_weak!(self.miner).transactions_limit())
|
||||
}
|
||||
|
||||
fn min_gas_price(&self, _: Params) -> Result<Value, Error> {
|
||||
try!(self.active());
|
||||
to_value(&take_weak!(self.miner).minimal_gas_price())
|
||||
}
|
||||
|
||||
fn extra_data(&self, _: Params) -> Result<Value, Error> {
|
||||
try!(self.active());
|
||||
to_value(&Bytes::new(take_weak!(self.miner).extra_data()))
|
||||
}
|
||||
|
||||
fn gas_floor_target(&self, _: Params) -> Result<Value, Error> {
|
||||
try!(self.active());
|
||||
to_value(&take_weak!(self.miner).gas_floor_target())
|
||||
}
|
||||
|
||||
fn gas_ceil_target(&self, _: Params) -> Result<Value, Error> {
|
||||
try!(self.active());
|
||||
to_value(&take_weak!(self.miner).gas_ceil_target())
|
||||
}
|
||||
|
||||
fn dev_logs(&self, _params: Params) -> Result<Value, Error> {
|
||||
try!(self.active());
|
||||
let logs = self.logger.logs();
|
||||
to_value(&logs.deref().as_slice())
|
||||
}
|
||||
|
||||
fn dev_logs_levels(&self, _params: Params) -> Result<Value, Error> {
|
||||
try!(self.active());
|
||||
to_value(&self.logger.levels())
|
||||
}
|
||||
|
||||
fn net_chain(&self, _params: Params) -> Result<Value, Error> {
|
||||
try!(self.active());
|
||||
to_value(&self.settings.chain)
|
||||
}
|
||||
|
||||
fn net_max_peers(&self, _params: Params) -> Result<Value, Error> {
|
||||
try!(self.active());
|
||||
to_value(&self.settings.max_peers)
|
||||
}
|
||||
|
||||
fn net_port(&self, _params: Params) -> Result<Value, Error> {
|
||||
try!(self.active());
|
||||
to_value(&self.settings.network_port)
|
||||
}
|
||||
|
||||
fn node_name(&self, _params: Params) -> Result<Value, Error> {
|
||||
try!(self.active());
|
||||
to_value(&self.settings.name)
|
||||
}
|
||||
|
||||
fn rpc_settings(&self, _params: Params) -> Result<Value, Error> {
|
||||
try!(self.active());
|
||||
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()));
|
||||
@@ -110,6 +128,7 @@ impl<C, M> Ethcore for EthcoreClient<C, M> where M: MinerService + 'static, C: M
|
||||
}
|
||||
|
||||
fn default_extra_data(&self, params: Params) -> Result<Value, Error> {
|
||||
try!(self.active());
|
||||
match params {
|
||||
Params::None => to_value(&Bytes::new(version_data())),
|
||||
_ => Err(Error::invalid_params()),
|
||||
@@ -117,6 +136,7 @@ impl<C, M> Ethcore for EthcoreClient<C, M> where M: MinerService + 'static, C: M
|
||||
}
|
||||
|
||||
fn gas_price_statistics(&self, params: Params) -> Result<Value, Error> {
|
||||
try!(self.active());
|
||||
match params {
|
||||
Params::None => match take_weak!(self.client).gas_price_statistics(100, 8) {
|
||||
Ok(stats) => to_value(&stats
|
||||
@@ -130,6 +150,7 @@ impl<C, M> Ethcore for EthcoreClient<C, M> where M: MinerService + 'static, C: M
|
||||
}
|
||||
|
||||
fn unsigned_transactions_count(&self, _params: Params) -> Result<Value, Error> {
|
||||
try!(self.active());
|
||||
match self.confirmations_queue {
|
||||
None => Err(Error {
|
||||
code: ErrorCode::ServerError(error_codes::SIGNER_DISABLED),
|
||||
|
||||
@@ -20,31 +20,46 @@ use util::network::{NetworkService, NonReservedPeerMode};
|
||||
use std::sync::{Arc, Weak};
|
||||
use jsonrpc_core::*;
|
||||
use ethcore::miner::MinerService;
|
||||
use ethcore::client::MiningBlockChainClient;
|
||||
use ethcore::service::SyncMessage;
|
||||
use v1::traits::EthcoreSet;
|
||||
use v1::types::Bytes;
|
||||
|
||||
/// Ethcore-specific rpc interface for operations altering the settings.
|
||||
pub struct EthcoreSetClient<M> where
|
||||
pub struct EthcoreSetClient<C, M> where
|
||||
C: MiningBlockChainClient,
|
||||
M: MinerService {
|
||||
|
||||
client: Weak<C>,
|
||||
miner: Weak<M>,
|
||||
net: Weak<NetworkService<SyncMessage>>,
|
||||
}
|
||||
|
||||
impl<M> EthcoreSetClient<M> where M: MinerService {
|
||||
impl<C, M> EthcoreSetClient<C, M> where
|
||||
C: MiningBlockChainClient,
|
||||
M: MinerService {
|
||||
/// Creates new `EthcoreSetClient`.
|
||||
pub fn new(miner: &Arc<M>, net: &Arc<NetworkService<SyncMessage>>) -> Self {
|
||||
pub fn new(client: &Arc<C>, miner: &Arc<M>, net: &Arc<NetworkService<SyncMessage>>) -> Self {
|
||||
EthcoreSetClient {
|
||||
client: Arc::downgrade(client),
|
||||
miner: Arc::downgrade(miner),
|
||||
net: Arc::downgrade(net),
|
||||
}
|
||||
}
|
||||
|
||||
fn active(&self) -> Result<(), Error> {
|
||||
// TODO: only call every 30s at most.
|
||||
take_weak!(self.client).keep_alive();
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
impl<M> EthcoreSet for EthcoreSetClient<M> where M: MinerService + 'static {
|
||||
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> {
|
||||
try!(self.active());
|
||||
from_params::<(U256,)>(params).and_then(|(gas_price,)| {
|
||||
take_weak!(self.miner).set_minimal_gas_price(gas_price);
|
||||
to_value(&true)
|
||||
@@ -52,6 +67,7 @@ impl<M> EthcoreSet for EthcoreSetClient<M> where M: MinerService + 'static {
|
||||
}
|
||||
|
||||
fn set_gas_floor_target(&self, params: Params) -> Result<Value, Error> {
|
||||
try!(self.active());
|
||||
from_params::<(U256,)>(params).and_then(|(target,)| {
|
||||
take_weak!(self.miner).set_gas_floor_target(target);
|
||||
to_value(&true)
|
||||
@@ -59,6 +75,7 @@ impl<M> EthcoreSet for EthcoreSetClient<M> where M: MinerService + 'static {
|
||||
}
|
||||
|
||||
fn set_gas_ceil_target(&self, params: Params) -> Result<Value, Error> {
|
||||
try!(self.active());
|
||||
from_params::<(U256,)>(params).and_then(|(target,)| {
|
||||
take_weak!(self.miner).set_gas_ceil_target(target);
|
||||
to_value(&true)
|
||||
@@ -66,6 +83,7 @@ impl<M> EthcoreSet for EthcoreSetClient<M> where M: MinerService + 'static {
|
||||
}
|
||||
|
||||
fn set_extra_data(&self, params: Params) -> Result<Value, Error> {
|
||||
try!(self.active());
|
||||
from_params::<(Bytes,)>(params).and_then(|(extra_data,)| {
|
||||
take_weak!(self.miner).set_extra_data(extra_data.to_vec());
|
||||
to_value(&true)
|
||||
@@ -73,6 +91,7 @@ impl<M> EthcoreSet for EthcoreSetClient<M> where M: MinerService + 'static {
|
||||
}
|
||||
|
||||
fn set_author(&self, params: Params) -> Result<Value, Error> {
|
||||
try!(self.active());
|
||||
from_params::<(Address,)>(params).and_then(|(author,)| {
|
||||
take_weak!(self.miner).set_author(author);
|
||||
to_value(&true)
|
||||
@@ -80,6 +99,7 @@ impl<M> EthcoreSet for EthcoreSetClient<M> where M: MinerService + 'static {
|
||||
}
|
||||
|
||||
fn set_transactions_limit(&self, params: Params) -> Result<Value, Error> {
|
||||
try!(self.active());
|
||||
from_params::<(usize,)>(params).and_then(|(limit,)| {
|
||||
take_weak!(self.miner).set_transactions_limit(limit);
|
||||
to_value(&true)
|
||||
@@ -87,6 +107,7 @@ impl<M> EthcoreSet for EthcoreSetClient<M> where M: MinerService + 'static {
|
||||
}
|
||||
|
||||
fn set_tx_gas_limit(&self, params: Params) -> Result<Value, Error> {
|
||||
try!(self.active());
|
||||
from_params::<(U256,)>(params).and_then(|(limit,)| {
|
||||
take_weak!(self.miner).set_tx_gas_limit(limit.into());
|
||||
to_value(&true)
|
||||
@@ -94,6 +115,7 @@ impl<M> EthcoreSet for EthcoreSetClient<M> where M: MinerService + 'static {
|
||||
}
|
||||
|
||||
fn add_reserved_peer(&self, params: Params) -> Result<Value, Error> {
|
||||
try!(self.active());
|
||||
from_params::<(String,)>(params).and_then(|(peer,)| {
|
||||
match take_weak!(self.net).add_reserved_peer(&peer) {
|
||||
Ok(()) => to_value(&true),
|
||||
@@ -103,6 +125,7 @@ impl<M> EthcoreSet for EthcoreSetClient<M> where M: MinerService + 'static {
|
||||
}
|
||||
|
||||
fn remove_reserved_peer(&self, params: Params) -> Result<Value, Error> {
|
||||
try!(self.active());
|
||||
from_params::<(String,)>(params).and_then(|(peer,)| {
|
||||
match take_weak!(self.net).remove_reserved_peer(&peer) {
|
||||
Ok(()) => to_value(&true),
|
||||
@@ -112,11 +135,13 @@ impl<M> EthcoreSet for EthcoreSetClient<M> where M: MinerService + 'static {
|
||||
}
|
||||
|
||||
fn drop_non_reserved_peers(&self, _: Params) -> Result<Value, Error> {
|
||||
try!(self.active());
|
||||
take_weak!(self.net).set_non_reserved_mode(NonReservedPeerMode::Deny);
|
||||
to_value(&true)
|
||||
}
|
||||
|
||||
fn accept_non_reserved_peers(&self, _: Params) -> Result<Value, Error> {
|
||||
try!(self.active());
|
||||
take_weak!(self.net).set_non_reserved_mode(NonReservedPeerMode::Accept);
|
||||
to_value(&true)
|
||||
}
|
||||
|
||||
@@ -43,22 +43,31 @@ impl<C, M> PersonalClient<C, M> where C: MiningBlockChainClient, M: MinerService
|
||||
signer_port: signer_port,
|
||||
}
|
||||
}
|
||||
|
||||
fn active(&self) -> Result<(), Error> {
|
||||
// TODO: only call every 30s at most.
|
||||
take_weak!(self.client).keep_alive();
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
impl<C: 'static, M: 'static> Personal for PersonalClient<C, M> where C: MiningBlockChainClient, M: MinerService {
|
||||
|
||||
fn signer_enabled(&self, _: Params) -> Result<Value, Error> {
|
||||
try!(self.active());
|
||||
self.signer_port
|
||||
.map(|v| to_value(&v))
|
||||
.unwrap_or_else(|| to_value(&false))
|
||||
}
|
||||
|
||||
fn accounts(&self, _: Params) -> Result<Value, Error> {
|
||||
try!(self.active());
|
||||
let store = take_weak!(self.accounts);
|
||||
to_value(&store.accounts())
|
||||
}
|
||||
|
||||
fn new_account(&self, params: Params) -> Result<Value, Error> {
|
||||
try!(self.active());
|
||||
from_params::<(String, )>(params).and_then(
|
||||
|(pass, )| {
|
||||
let store = take_weak!(self.accounts);
|
||||
@@ -71,6 +80,7 @@ impl<C: 'static, M: 'static> Personal for PersonalClient<C, M> where C: MiningBl
|
||||
}
|
||||
|
||||
fn unlock_account(&self, params: Params) -> Result<Value, Error> {
|
||||
try!(self.active());
|
||||
from_params::<(Address, String, u64)>(params).and_then(
|
||||
|(account, account_pass, _)|{
|
||||
let store = take_weak!(self.accounts);
|
||||
@@ -82,6 +92,7 @@ impl<C: 'static, M: 'static> Personal for PersonalClient<C, M> where C: MiningBl
|
||||
}
|
||||
|
||||
fn sign_and_send_transaction(&self, params: Params) -> Result<Value, Error> {
|
||||
try!(self.active());
|
||||
from_params::<(TransactionRequest, String)>(params)
|
||||
.and_then(|(request, password)| {
|
||||
let sender = request.from;
|
||||
|
||||
@@ -46,16 +46,24 @@ impl<C: 'static, M: 'static> SignerClient<C, M> where C: MiningBlockChainClient,
|
||||
miner: Arc::downgrade(miner),
|
||||
}
|
||||
}
|
||||
|
||||
fn active(&self) -> Result<(), Error> {
|
||||
// TODO: only call every 30s at most.
|
||||
take_weak!(self.client).keep_alive();
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
impl<C: 'static, M: 'static> PersonalSigner for SignerClient<C, M> where C: MiningBlockChainClient, M: MinerService {
|
||||
|
||||
fn transactions_to_confirm(&self, _params: Params) -> Result<Value, Error> {
|
||||
try!(self.active());
|
||||
let queue = take_weak!(self.queue);
|
||||
to_value(&queue.requests())
|
||||
}
|
||||
|
||||
fn confirm_transaction(&self, params: Params) -> Result<Value, Error> {
|
||||
try!(self.active());
|
||||
from_params::<(U256, TransactionModification, String)>(params).and_then(
|
||||
|(id, modification, pass)| {
|
||||
let accounts = take_weak!(self.accounts);
|
||||
@@ -87,6 +95,7 @@ impl<C: 'static, M: 'static> PersonalSigner for SignerClient<C, M> where C: Mini
|
||||
}
|
||||
|
||||
fn reject_transaction(&self, params: Params) -> Result<Value, Error> {
|
||||
try!(self.active());
|
||||
from_params::<(U256, )>(params).and_then(
|
||||
|(id, )| {
|
||||
let queue = take_weak!(self.queue);
|
||||
|
||||
@@ -55,10 +55,17 @@ impl<C, M> TracesClient<C, M> where C: BlockChainClient, M: MinerService {
|
||||
data: request.data.map_or_else(Vec::new, |d| d.to_vec())
|
||||
}.fake_sign(from))
|
||||
}
|
||||
|
||||
fn active(&self) -> Result<(), Error> {
|
||||
// TODO: only call every 30s at most.
|
||||
take_weak!(self.client).keep_alive();
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
impl<C, M> Traces for TracesClient<C, M> where C: BlockChainClient + 'static, M: MinerService + 'static {
|
||||
fn filter(&self, params: Params) -> Result<Value, Error> {
|
||||
try!(self.active());
|
||||
from_params::<(TraceFilter,)>(params)
|
||||
.and_then(|(filter, )| {
|
||||
let client = take_weak!(self.client);
|
||||
@@ -69,6 +76,7 @@ impl<C, M> Traces for TracesClient<C, M> where C: BlockChainClient + 'static, M:
|
||||
}
|
||||
|
||||
fn block_traces(&self, params: Params) -> Result<Value, Error> {
|
||||
try!(self.active());
|
||||
from_params::<(BlockNumber,)>(params)
|
||||
.and_then(|(block_number,)| {
|
||||
let client = take_weak!(self.client);
|
||||
@@ -79,6 +87,7 @@ impl<C, M> Traces for TracesClient<C, M> where C: BlockChainClient + 'static, M:
|
||||
}
|
||||
|
||||
fn transaction_traces(&self, params: Params) -> Result<Value, Error> {
|
||||
try!(self.active());
|
||||
from_params::<(H256,)>(params)
|
||||
.and_then(|(transaction_hash,)| {
|
||||
let client = take_weak!(self.client);
|
||||
@@ -89,6 +98,7 @@ impl<C, M> Traces for TracesClient<C, M> where C: BlockChainClient + 'static, M:
|
||||
}
|
||||
|
||||
fn trace(&self, params: Params) -> Result<Value, Error> {
|
||||
try!(self.active());
|
||||
from_params::<(H256, Vec<Index>)>(params)
|
||||
.and_then(|(transaction_hash, address)| {
|
||||
let client = take_weak!(self.client);
|
||||
@@ -103,6 +113,7 @@ impl<C, M> Traces for TracesClient<C, M> where C: BlockChainClient + 'static, M:
|
||||
}
|
||||
|
||||
fn call(&self, params: Params) -> Result<Value, Error> {
|
||||
try!(self.active());
|
||||
trace!(target: "jsonrpc", "call: {:?}", params);
|
||||
from_params(params)
|
||||
.and_then(|(request, flags)| {
|
||||
|
||||
@@ -20,6 +20,7 @@ use jsonrpc_core::IoHandler;
|
||||
use v1::{EthcoreSet, EthcoreSetClient};
|
||||
use ethcore::miner::MinerService;
|
||||
use ethcore::service::SyncMessage;
|
||||
use ethcore::client::TestBlockChainClient;
|
||||
use v1::tests::helpers::TestMinerService;
|
||||
use util::numbers::*;
|
||||
use util::network::{NetworkConfiguration, NetworkService};
|
||||
@@ -29,20 +30,25 @@ fn miner_service() -> Arc<TestMinerService> {
|
||||
Arc::new(TestMinerService::default())
|
||||
}
|
||||
|
||||
fn client_service() -> Arc<TestBlockChainClient> {
|
||||
Arc::new(TestBlockChainClient::default())
|
||||
}
|
||||
|
||||
fn network_service() -> Arc<NetworkService<SyncMessage>> {
|
||||
Arc::new(NetworkService::new(NetworkConfiguration::new()).unwrap())
|
||||
}
|
||||
|
||||
fn ethcore_set_client(miner: &Arc<TestMinerService>, net: &Arc<NetworkService<SyncMessage>>) -> EthcoreSetClient<TestMinerService> {
|
||||
EthcoreSetClient::new(miner, net)
|
||||
fn ethcore_set_client(client: &Arc<TestBlockChainClient>, miner: &Arc<TestMinerService>, net: &Arc<NetworkService<SyncMessage>>) -> EthcoreSetClient<TestBlockChainClient, TestMinerService> {
|
||||
EthcoreSetClient::new(client, miner, net)
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn rpc_ethcore_set_min_gas_price() {
|
||||
let miner = miner_service();
|
||||
let client = client_service();
|
||||
let network = network_service();
|
||||
let io = IoHandler::new();
|
||||
io.add_delegate(ethcore_set_client(&miner, &network).to_delegate());
|
||||
io.add_delegate(ethcore_set_client(&client, &miner, &network).to_delegate());
|
||||
|
||||
let request = r#"{"jsonrpc": "2.0", "method": "ethcore_setMinGasPrice", "params":["0xcd1722f3947def4cf144679da39c4c32bdc35681"], "id": 1}"#;
|
||||
let response = r#"{"jsonrpc":"2.0","result":true,"id":1}"#;
|
||||
@@ -50,12 +56,14 @@ fn rpc_ethcore_set_min_gas_price() {
|
||||
assert_eq!(io.handle_request(request), Some(response.to_owned()));
|
||||
assert_eq!(miner.minimal_gas_price(), U256::from_str("cd1722f3947def4cf144679da39c4c32bdc35681").unwrap());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn rpc_ethcore_set_gas_floor_target() {
|
||||
let miner = miner_service();
|
||||
let client = client_service();
|
||||
let network = network_service();
|
||||
let io = IoHandler::new();
|
||||
io.add_delegate(ethcore_set_client(&miner, &network).to_delegate());
|
||||
io.add_delegate(ethcore_set_client(&client, &miner, &network).to_delegate());
|
||||
|
||||
let request = r#"{"jsonrpc": "2.0", "method": "ethcore_setGasFloorTarget", "params":["0xcd1722f3947def4cf144679da39c4c32bdc35681"], "id": 1}"#;
|
||||
let response = r#"{"jsonrpc":"2.0","result":true,"id":1}"#;
|
||||
@@ -67,9 +75,10 @@ fn rpc_ethcore_set_gas_floor_target() {
|
||||
#[test]
|
||||
fn rpc_ethcore_set_extra_data() {
|
||||
let miner = miner_service();
|
||||
let client = client_service();
|
||||
let network = network_service();
|
||||
let io = IoHandler::new();
|
||||
io.add_delegate(ethcore_set_client(&miner, &network).to_delegate());
|
||||
io.add_delegate(ethcore_set_client(&client, &miner, &network).to_delegate());
|
||||
|
||||
let request = r#"{"jsonrpc": "2.0", "method": "ethcore_setExtraData", "params":["0xcd1722f3947def4cf144679da39c4c32bdc35681"], "id": 1}"#;
|
||||
let response = r#"{"jsonrpc":"2.0","result":true,"id":1}"#;
|
||||
@@ -81,9 +90,10 @@ fn rpc_ethcore_set_extra_data() {
|
||||
#[test]
|
||||
fn rpc_ethcore_set_author() {
|
||||
let miner = miner_service();
|
||||
let client = client_service();
|
||||
let network = network_service();
|
||||
let io = IoHandler::new();
|
||||
io.add_delegate(ethcore_set_client(&miner, &network).to_delegate());
|
||||
io.add_delegate(ethcore_set_client(&client, &miner, &network).to_delegate());
|
||||
|
||||
let request = r#"{"jsonrpc": "2.0", "method": "ethcore_setAuthor", "params":["0xcd1722f3947def4cf144679da39c4c32bdc35681"], "id": 1}"#;
|
||||
let response = r#"{"jsonrpc":"2.0","result":true,"id":1}"#;
|
||||
@@ -95,9 +105,10 @@ fn rpc_ethcore_set_author() {
|
||||
#[test]
|
||||
fn rpc_ethcore_set_transactions_limit() {
|
||||
let miner = miner_service();
|
||||
let client = client_service();
|
||||
let network = network_service();
|
||||
let io = IoHandler::new();
|
||||
io.add_delegate(ethcore_set_client(&miner, &network).to_delegate());
|
||||
io.add_delegate(ethcore_set_client(&client, &miner, &network).to_delegate());
|
||||
|
||||
let request = r#"{"jsonrpc": "2.0", "method": "ethcore_setTransactionsLimit", "params":[10240240], "id": 1}"#;
|
||||
let response = r#"{"jsonrpc":"2.0","result":true,"id":1}"#;
|
||||
|
||||
Reference in New Issue
Block a user