diff --git a/miner/src/lib.rs b/miner/src/lib.rs index 005a37a28..27f914181 100644 --- a/miner/src/lib.rs +++ b/miner/src/lib.rs @@ -64,7 +64,7 @@ mod transaction_queue; pub use transaction_queue::{TransactionQueue, AccountDetails}; pub use miner::{Miner}; -use util::{H256, U256, Address, FixedHash, Bytes}; +use util::{H256, U256, Address, Bytes}; use ethcore::client::{BlockChainClient}; use ethcore::block::{ClosedBlock}; use ethcore::error::{Error}; @@ -77,14 +77,29 @@ pub trait MinerService : Send + Sync { fn status(&self) -> MinerStatus; /// Get the author that we will seal blocks as. - fn author(&self) -> Address { Address::zero() } + fn author(&self) -> Address; - /// Get the extra_data that we will seal blocks wuth. - fn extra_data(&self) -> Bytes { vec![] } + /// Set the author that we will seal blocks as. + fn set_author(&self, author: Address); + + /// Get the extra_data that we will seal blocks with. + fn extra_data(&self) -> Bytes; + + /// Set the extra_data that we will seal blocks with. + fn set_extra_data(&self, extra_data: Bytes); + + /// Get current minimal gas price for transactions accepted to queue. + fn minimal_gas_price(&self) -> U256; + + /// Set minimal gas price of transaction to be accepted for mining. + fn set_minimal_gas_price(&self, min_gas_price: U256); /// Get the gas limit we wish to target when sealing a new block. fn gas_floor_target(&self) -> U256; + /// Set the gas limit we wish to target when sealing a new block. + fn set_gas_floor_target(&self, target: 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 1b00aeed6..7f7dc2980 100644 --- a/miner/src/miner.rs +++ b/miner/src/miner.rs @@ -69,26 +69,6 @@ impl Miner { }) } - /// Set the author that we will seal blocks as. - pub fn set_author(&self, author: Address) { - *self.author.write().unwrap() = author; - } - - /// Set the extra_data that we will seal blocks with. - pub fn set_extra_data(&self, extra_data: Bytes) { - *self.extra_data.write().unwrap() = extra_data; - } - - /// Set the gas limit we wish to target when sealing a new block. - pub fn set_gas_floor_target(&self, target: U256) { - *self.gas_floor_target.write().unwrap() = target; - } - - /// Set minimal gas price of transaction to be accepted for mining. - pub fn set_minimal_gas_price(&self, min_gas_price: U256) { - self.transaction_queue.lock().unwrap().set_minimal_gas_price(min_gas_price); - } - /// Prepares new block for sealing including top transactions from queue. #[cfg_attr(feature="dev", allow(match_same_arms))] fn prepare_sealing(&self, chain: &BlockChainClient) { @@ -195,6 +175,27 @@ impl MinerService for Miner { } } + fn set_author(&self, author: Address) { + *self.author.write().unwrap() = author; + } + + fn set_extra_data(&self, extra_data: Bytes) { + *self.extra_data.write().unwrap() = extra_data; + } + + /// Set the gas limit we wish to target when sealing a new block. + fn set_gas_floor_target(&self, target: U256) { + *self.gas_floor_target.write().unwrap() = target; + } + + fn set_minimal_gas_price(&self, min_gas_price: U256) { + self.transaction_queue.lock().unwrap().set_minimal_gas_price(min_gas_price); + } + + fn minimal_gas_price(&self) -> U256 { + *self.transaction_queue.lock().unwrap().minimal_gas_price() + } + fn sensible_gas_price(&self) -> U256 { // 10% above our minimum. *self.transaction_queue.lock().unwrap().minimal_gas_price() * x!(110) / x!(100) diff --git a/rpc/src/v1/impls/ethcore.rs b/rpc/src/v1/impls/ethcore.rs index e46503037..d9764842c 100644 --- a/rpc/src/v1/impls/ethcore.rs +++ b/rpc/src/v1/impls/ethcore.rs @@ -15,6 +15,7 @@ // along with Parity. If not, see . //! Ethcore-specific rpc implementation. +use util::{U256, Address}; use std::sync::{Arc, Weak}; use jsonrpc_core::*; use ethminer::{MinerService}; @@ -37,6 +38,39 @@ impl EthcoreClient where M: MinerService { } impl Ethcore for EthcoreClient where M: MinerService + 'static { + + fn set_min_gas_price(&self, params: Params) -> Result { + from_params::<(U256,)>(params).and_then(|(gas_price,)| { + take_weak!(self.miner).set_minimal_gas_price(gas_price); + to_value(&true) + }) + } + + fn set_gas_floor_target(&self, params: Params) -> Result { + from_params::<(U256,)>(params).and_then(|(gas_floor_target,)| { + take_weak!(self.miner).set_gas_floor_target(gas_floor_target); + to_value(&true) + }) + } + + fn set_extra_data(&self, params: Params) -> Result { + from_params::<(Bytes,)>(params).and_then(|(extra_data,)| { + take_weak!(self.miner).set_extra_data(extra_data.to_vec()); + to_value(&true) + }) + } + + fn set_author(&self, params: Params) -> Result { + from_params::<(Address,)>(params).and_then(|(author,)| { + take_weak!(self.miner).set_author(author); + to_value(&true) + }) + } + + fn min_gas_price(&self, _: Params) -> Result { + to_value(&take_weak!(self.miner).minimal_gas_price()) + } + fn extra_data(&self, _: Params) -> Result { to_value(&Bytes::new(take_weak!(self.miner).extra_data())) } diff --git a/rpc/src/v1/tests/ethcore.rs b/rpc/src/v1/tests/ethcore.rs index 75c964a83..06d4ffc1c 100644 --- a/rpc/src/v1/tests/ethcore.rs +++ b/rpc/src/v1/tests/ethcore.rs @@ -15,10 +15,13 @@ // along with Parity. If not, see . use std::sync::Arc; +use std::str::FromStr; use jsonrpc_core::IoHandler; use v1::{Ethcore, EthcoreClient}; -use v1::tests::helpers::{TestMinerService}; +use ethminer::MinerService; +use v1::tests::helpers::TestMinerService; use util::numbers::*; +use rustc_serialize::hex::FromHex; fn miner_service() -> Arc { @@ -52,3 +55,71 @@ fn rpc_ethcore_gas_floor_target() { assert_eq!(io.handle_request(request), Some(response.to_owned())); } +#[test] +fn rpc_ethcore_min_gas_price() { + 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_minGasPrice", "params": [], "id": 1}"#; + let response = r#"{"jsonrpc":"2.0","result":"0x01312d00","id":1}"#; + + assert_eq!(io.handle_request(request), Some(response.to_owned())); +} + +#[test] +fn rpc_ethcore_set_min_gas_price() { + 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_setMinGasPrice", "params":["0xcd1722f3947def4cf144679da39c4c32bdc35681"], "id": 1}"#; + let response = r#"{"jsonrpc":"2.0","result":true,"id":1}"#; + + 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 ethcore = EthcoreClient::new(&miner).to_delegate(); + let io = IoHandler::new(); + io.add_delegate(ethcore); + + let request = r#"{"jsonrpc": "2.0", "method": "ethcore_setGasFloorTarget", "params":["0xcd1722f3947def4cf144679da39c4c32bdc35681"], "id": 1}"#; + let response = r#"{"jsonrpc":"2.0","result":true,"id":1}"#; + + assert_eq!(io.handle_request(request), Some(response.to_owned())); + assert_eq!(miner.gas_floor_target(), U256::from_str("cd1722f3947def4cf144679da39c4c32bdc35681").unwrap()); +} + +#[test] +fn rpc_ethcore_set_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_setExtraData", "params":["0xcd1722f3947def4cf144679da39c4c32bdc35681"], "id": 1}"#; + let response = r#"{"jsonrpc":"2.0","result":true,"id":1}"#; + + assert_eq!(io.handle_request(request), Some(response.to_owned())); + assert_eq!(miner.extra_data(), "cd1722f3947def4cf144679da39c4c32bdc35681".from_hex().unwrap()); +} + +#[test] +fn rpc_ethcore_set_author() { + 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_setAuthor", "params":["0xcd1722f3947def4cf144679da39c4c32bdc35681"], "id": 1}"#; + let response = r#"{"jsonrpc":"2.0","result":true,"id":1}"#; + + assert_eq!(io.handle_request(request), Some(response.to_owned())); + assert_eq!(miner.author(), Address::from_str("cd1722f3947def4cf144679da39c4c32bdc35681").unwrap()); +} diff --git a/rpc/src/v1/tests/helpers/miner_service.rs b/rpc/src/v1/tests/helpers/miner_service.rs index 5cea555a9..b2e546b2b 100644 --- a/rpc/src/v1/tests/helpers/miner_service.rs +++ b/rpc/src/v1/tests/helpers/miner_service.rs @@ -16,7 +16,7 @@ //! Test implementation of miner service. -use util::{Address, H256, Bytes, U256}; +use util::{Address, H256, Bytes, U256, FixedHash}; use util::standard::*; use ethcore::error::Error; use ethcore::client::BlockChainClient; @@ -34,6 +34,11 @@ pub struct TestMinerService { pub pending_transactions: Mutex>, /// Last nonces. pub last_nonces: RwLock>, + + min_gas_price: RwLock, + gas_floor_target: RwLock, + author: RwLock
, + extra_data: RwLock, } impl Default for TestMinerService { @@ -43,6 +48,10 @@ impl Default for TestMinerService { latest_closed_block: Mutex::new(None), pending_transactions: Mutex::new(HashMap::new()), last_nonces: RwLock::new(HashMap::new()), + min_gas_price: RwLock::new(U256::from(20_000_000)), + gas_floor_target: RwLock::new(U256::from(12345)), + author: RwLock::new(Address::zero()), + extra_data: RwLock::new(vec![1, 2, 3, 4]), } } } @@ -58,6 +67,39 @@ impl MinerService for TestMinerService { } } + fn set_author(&self, author: Address) { + *self.author.write().unwrap() = author; + } + + fn set_extra_data(&self, extra_data: Bytes) { + *self.extra_data.write().unwrap() = extra_data; + } + + /// Set the gas limit we wish to target when sealing a new block. + fn set_gas_floor_target(&self, target: U256) { + *self.gas_floor_target.write().unwrap() = target; + } + + fn set_minimal_gas_price(&self, min_gas_price: U256) { + *self.min_gas_price.write().unwrap() = min_gas_price; + } + + fn author(&self) -> Address { + *self.author.read().unwrap() + } + + fn minimal_gas_price(&self) -> U256 { + *self.min_gas_price.read().unwrap() + } + + fn extra_data(&self) -> Bytes { + self.extra_data.read().unwrap().clone() + } + + fn gas_floor_target(&self) -> U256 { + *self.gas_floor_target.read().unwrap() + } + /// Imports transactions to transaction queue. fn import_transactions(&self, transactions: Vec, _fetch_account: T) -> Vec> where T: Fn(&Address) -> AccountDetails { @@ -111,12 +153,4 @@ 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/traits/ethcore.rs b/rpc/src/v1/traits/ethcore.rs index bb10d62c3..fb96ef035 100644 --- a/rpc/src/v1/traits/ethcore.rs +++ b/rpc/src/v1/traits/ethcore.rs @@ -20,17 +20,39 @@ use jsonrpc_core::*; /// Ethcore-specific rpc interface. pub trait Ethcore: Sized + Send + Sync + 'static { + + /// Sets new minimal gas price for mined blocks. + fn set_min_gas_price(&self, _: Params) -> Result { rpc_unimplemented!() } + + /// Sets new gas floor target for mined blocks. + fn set_gas_floor_target(&self, _: Params) -> Result { rpc_unimplemented!() } + + /// Sets new extra data for mined blocks. + fn set_extra_data(&self, _: Params) -> Result { rpc_unimplemented!() } + + /// Sets new author for mined block. + fn set_author(&self, _: Params) -> Result { rpc_unimplemented!() } + /// 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!() } + /// Returns minimal gas price for transaction to be included in queue. + fn min_gas_price(&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_setMinGasPrice", Ethcore::set_min_gas_price); + delegate.add_method("ethcore_setGasFloorTarget", Ethcore::set_gas_floor_target); + delegate.add_method("ethcore_setExtraData", Ethcore::set_extra_data); + delegate.add_method("ethcore_setAuthor", Ethcore::set_author); + delegate.add_method("ethcore_extraData", Ethcore::extra_data); delegate.add_method("ethcore_gasFloorTarget", Ethcore::gas_floor_target); + delegate.add_method("ethcore_minGasPrice", Ethcore::min_gas_price); delegate } }