From 3fe21f5931d82ec674fb86a7fdb699b4defc8568 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tomasz=20Drwi=C4=99ga?= Date: Mon, 11 Apr 2016 21:06:32 +0200 Subject: [PATCH] Ethcore-specific RPC methods (#923) * Ethcore-specific rpc methods * Initializing ethcore-rpc --- miner/src/lib.rs | 3 ++ miner/src/miner.rs | 22 +++------ parity/main.rs | 8 ++-- rpc/src/v1/impls/ethcore.rs | 47 ++++++++++++++++++++ rpc/src/v1/impls/mod.rs | 3 ++ rpc/src/v1/mod.rs | 2 +- rpc/src/v1/tests/ethcore.rs | 54 +++++++++++++++++++++++ rpc/src/v1/tests/helpers/miner_service.rs | 8 ++++ rpc/src/v1/tests/mod.rs | 2 + rpc/src/v1/traits/ethcore.rs | 36 +++++++++++++++ rpc/src/v1/traits/mod.rs | 2 + 11 files changed, 168 insertions(+), 19 deletions(-) create mode 100644 rpc/src/v1/impls/ethcore.rs create mode 100644 rpc/src/v1/tests/ethcore.rs create mode 100644 rpc/src/v1/traits/ethcore.rs diff --git a/miner/src/lib.rs b/miner/src/lib.rs index c6e07a953..005a37a28 100644 --- a/miner/src/lib.rs +++ b/miner/src/lib.rs @@ -82,6 +82,9 @@ pub trait MinerService : Send + Sync { /// Get the extra_data that we will seal blocks wuth. fn extra_data(&self) -> Bytes { vec![] } + /// Get the gas limit we wish to target when sealing a new block. + fn gas_floor_target(&self) -> U256; + /// Imports transactions to transaction queue. fn import_transactions(&self, transactions: Vec, fetch_account: T) -> Vec> where T: Fn(&Address) -> AccountDetails; diff --git a/miner/src/miner.rs b/miner/src/miner.rs index 8b3e7f4e4..1b00aeed6 100644 --- a/miner/src/miner.rs +++ b/miner/src/miner.rs @@ -69,21 +69,6 @@ impl Miner { }) } - /// Get the author that we will seal blocks as. - fn author(&self) -> Address { - *self.author.read().unwrap() - } - - /// Get the extra_data that we will seal blocks wuth. - fn extra_data(&self) -> Bytes { - self.extra_data.read().unwrap().clone() - } - - /// Get the extra_data that we will seal blocks wuth. - fn gas_floor_target(&self) -> U256 { - *self.gas_floor_target.read().unwrap() - } - /// Set the author that we will seal blocks as. pub fn set_author(&self, author: Address) { *self.author.write().unwrap() = author; @@ -215,14 +200,21 @@ impl MinerService for Miner { *self.transaction_queue.lock().unwrap().minimal_gas_price() * x!(110) / x!(100) } + /// Get the author that we will seal blocks as. fn author(&self) -> Address { *self.author.read().unwrap() } + /// Get the extra_data that we will seal blocks with. fn extra_data(&self) -> Bytes { self.extra_data.read().unwrap().clone() } + /// Get the gas limit we wish to target when sealing a new block. + fn gas_floor_target(&self) -> U256 { + *self.gas_floor_target.read().unwrap() + } + fn import_transactions(&self, transactions: Vec, fetch_account: T) -> Vec> where T: Fn(&Address) -> AccountDetails { let mut transaction_queue = self.transaction_queue.lock().unwrap(); diff --git a/parity/main.rs b/parity/main.rs index 6fa0c5f00..e2e4c9c37 100644 --- a/parity/main.rs +++ b/parity/main.rs @@ -136,7 +136,7 @@ API and Console Options: --jsonrpc-apis APIS Specify the APIs available through the JSONRPC interface. APIS is a comma-delimited list of API name. Possible name are web3, eth and net. - [default: web3,eth,net,personal]. + [default: web3,eth,net,personal,ethcore]. -w --webapp Enable the web applications server (e.g. status page). --webapp-port PORT Specify the port portion of the WebApps server @@ -312,11 +312,12 @@ fn setup_rpc_server( "eth" => { server.add_delegate(EthClient::new(&client, &sync, &secret_store, &miner).to_delegate()); server.add_delegate(EthFilterClient::new(&client, &miner).to_delegate()); - } + }, "personal" => server.add_delegate(PersonalClient::new(&secret_store).to_delegate()), + "ethcore" => server.add_delegate(EthcoreClient::new(&miner).to_delegate()), _ => { die!("{}: Invalid API name to be enabled.", api); - } + }, } } let start_result = server.start_http(url, cors_domain); @@ -344,6 +345,7 @@ fn setup_webapp_server( server.add_delegate(EthClient::new(&client, &sync, &secret_store, &miner).to_delegate()); server.add_delegate(EthFilterClient::new(&client, &miner).to_delegate()); server.add_delegate(PersonalClient::new(&secret_store).to_delegate()); + server.add_delegate(EthcoreClient::new(&miner).to_delegate()); let start_result = match auth { None => { server.start_unsecure_http(url, ::num_cpus::get()) diff --git a/rpc/src/v1/impls/ethcore.rs b/rpc/src/v1/impls/ethcore.rs new file mode 100644 index 000000000..e46503037 --- /dev/null +++ b/rpc/src/v1/impls/ethcore.rs @@ -0,0 +1,47 @@ +// 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 . + +//! Ethcore-specific rpc implementation. +use std::sync::{Arc, Weak}; +use jsonrpc_core::*; +use ethminer::{MinerService}; +use v1::traits::Ethcore; +use v1::types::Bytes; + +/// Ethcore implementation. +pub struct EthcoreClient + where M: MinerService { + miner: Weak, +} + +impl EthcoreClient where M: MinerService { + /// Creates new `EthcoreClient`. + pub fn new(miner: &Arc) -> Self { + EthcoreClient { + miner: Arc::downgrade(miner) + } + } +} + +impl Ethcore for EthcoreClient where M: MinerService + 'static { + fn extra_data(&self, _: Params) -> Result { + to_value(&Bytes::new(take_weak!(self.miner).extra_data())) + } + + fn gas_floor_target(&self, _: Params) -> Result { + to_value(&take_weak!(self.miner).gas_floor_target()) + } +} diff --git a/rpc/src/v1/impls/mod.rs b/rpc/src/v1/impls/mod.rs index 10d451e9f..e504f3126 100644 --- a/rpc/src/v1/impls/mod.rs +++ b/rpc/src/v1/impls/mod.rs @@ -29,8 +29,11 @@ mod web3; mod eth; mod net; mod personal; +mod ethcore; pub use self::web3::Web3Client; pub use self::eth::{EthClient, EthFilterClient}; pub use self::net::NetClient; pub use self::personal::PersonalClient; +pub use self::ethcore::EthcoreClient; + diff --git a/rpc/src/v1/mod.rs b/rpc/src/v1/mod.rs index c81f58156..b5ab73084 100644 --- a/rpc/src/v1/mod.rs +++ b/rpc/src/v1/mod.rs @@ -25,5 +25,5 @@ mod helpers; pub mod tests; -pub use self::traits::{Web3, Eth, EthFilter, Personal, Net}; +pub use self::traits::{Web3, Eth, EthFilter, Personal, Net, Ethcore}; pub use self::impls::*; diff --git a/rpc/src/v1/tests/ethcore.rs b/rpc/src/v1/tests/ethcore.rs new file mode 100644 index 000000000..75c964a83 --- /dev/null +++ b/rpc/src/v1/tests/ethcore.rs @@ -0,0 +1,54 @@ +// 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 . + +use std::sync::Arc; +use jsonrpc_core::IoHandler; +use v1::{Ethcore, EthcoreClient}; +use v1::tests::helpers::{TestMinerService}; +use util::numbers::*; + + +fn miner_service() -> Arc { + Arc::new(TestMinerService::default()) +} + +#[test] +fn rpc_ethcore_extra_data() { + let miner = miner_service(); + let ethcore = EthcoreClient::new(&miner).to_delegate(); + let io = IoHandler::new(); + io.add_delegate(ethcore); + + let request = r#"{"jsonrpc": "2.0", "method": "ethcore_extraData", "params": [], "id": 1}"#; + let response = r#"{"jsonrpc":"2.0","result":"0x01020304","id":1}"#; + + assert_eq!(io.handle_request(request), Some(response.to_owned())); +} + + +#[test] +fn rpc_ethcore_gas_floor_target() { + let miner = miner_service(); + let ethcore = EthcoreClient::new(&miner).to_delegate(); + let io = IoHandler::new(); + io.add_delegate(ethcore); + + let request = r#"{"jsonrpc": "2.0", "method": "ethcore_gasFloorTarget", "params": [], "id": 1}"#; + let response = r#"{"jsonrpc":"2.0","result":"0x3039","id":1}"#; + + assert_eq!(io.handle_request(request), Some(response.to_owned())); +} + diff --git a/rpc/src/v1/tests/helpers/miner_service.rs b/rpc/src/v1/tests/helpers/miner_service.rs index 815085d3b..5cea555a9 100644 --- a/rpc/src/v1/tests/helpers/miner_service.rs +++ b/rpc/src/v1/tests/helpers/miner_service.rs @@ -111,4 +111,12 @@ impl MinerService for TestMinerService { fn submit_seal(&self, _chain: &BlockChainClient, _pow_hash: H256, _seal: Vec) -> Result<(), Error> { unimplemented!(); } + + fn extra_data(&self) -> Bytes { + vec![1, 2, 3, 4] + } + + fn gas_floor_target(&self) -> U256 { + U256::from(12345) + } } diff --git a/rpc/src/v1/tests/mod.rs b/rpc/src/v1/tests/mod.rs index 7a6340ce1..e09b09db1 100644 --- a/rpc/src/v1/tests/mod.rs +++ b/rpc/src/v1/tests/mod.rs @@ -25,3 +25,5 @@ mod net; mod web3; #[cfg(test)] mod personal; +#[cfg(test)] +mod ethcore; diff --git a/rpc/src/v1/traits/ethcore.rs b/rpc/src/v1/traits/ethcore.rs new file mode 100644 index 000000000..bb10d62c3 --- /dev/null +++ b/rpc/src/v1/traits/ethcore.rs @@ -0,0 +1,36 @@ +// 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 . + +//! Ethcore-specific rpc interface. +use std::sync::Arc; +use jsonrpc_core::*; + +/// Ethcore-specific rpc interface. +pub trait Ethcore: Sized + Send + Sync + 'static { + /// Returns mining extra data. + fn extra_data(&self, _: Params) -> Result { rpc_unimplemented!() } + + /// Returns mining gas floor target. + fn gas_floor_target(&self, _: Params) -> Result { rpc_unimplemented!() } + + /// Should be used to convert object to io delegate. + fn to_delegate(self) -> IoDelegate { + 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 + } +} diff --git a/rpc/src/v1/traits/mod.rs b/rpc/src/v1/traits/mod.rs index 0a95cb050..a15c8b8c9 100644 --- a/rpc/src/v1/traits/mod.rs +++ b/rpc/src/v1/traits/mod.rs @@ -24,8 +24,10 @@ pub mod web3; pub mod eth; pub mod net; pub mod personal; +pub mod ethcore; pub use self::web3::Web3; pub use self::eth::{Eth, EthFilter}; pub use self::net::Net; pub use self::personal::Personal; +pub use self::ethcore::Ethcore;