diff --git a/rpc/src/v1/helpers/external_miner.rs b/miner/src/external.rs similarity index 58% rename from rpc/src/v1/helpers/external_miner.rs rename to miner/src/external.rs index 4cbda8928..ece91877d 100644 --- a/rpc/src/v1/helpers/external_miner.rs +++ b/miner/src/external.rs @@ -15,7 +15,7 @@ // along with Parity. If not, see . use std::collections::HashMap; -use std::sync::RwLock; +use std::sync::{Arc, RwLock}; use util::numbers::U256; use util::hash::H256; @@ -33,13 +33,22 @@ pub trait ExternalMinerService: Send + Sync { /// External Miner. pub struct ExternalMiner { - hashrates: RwLock>, + hashrates: Arc>>, } impl Default for ExternalMiner { fn default() -> Self { ExternalMiner { - hashrates: RwLock::new(HashMap::new()), + hashrates: Arc::new(RwLock::new(HashMap::new())), + } + } +} + +impl ExternalMiner { + /// Creates new external miner with prefilled hashrates. + pub fn new(hashrates: Arc>>) -> Self { + ExternalMiner { + hashrates: hashrates } } } @@ -57,3 +66,43 @@ impl ExternalMinerService for ExternalMiner { !self.hashrates.read().unwrap().is_empty() } } + +#[cfg(test)] +mod tests { + use super::*; + use util::{H256, U256}; + + fn miner() -> ExternalMiner { + ExternalMiner::default() + } + + #[test] + fn should_return_that_is_mining_if_there_is_at_least_one_entry() { + // given + let m = miner(); + assert_eq!(m.is_mining(), false); + + // when + m.submit_hashrate(U256::from(10), H256::from(1)); + + // then + assert_eq!(m.is_mining(), true); + } + + #[test] + fn should_sum_up_hashrate() { + // given + let m = miner(); + assert_eq!(m.hashrate(), U256::from(0)); + m.submit_hashrate(U256::from(10), H256::from(1)); + assert_eq!(m.hashrate(), U256::from(10)); + + // when + m.submit_hashrate(U256::from(15), H256::from(1)); + m.submit_hashrate(U256::from(20), H256::from(2)); + + + // then + assert_eq!(m.hashrate(), U256::from(35)); + } +} diff --git a/miner/src/lib.rs b/miner/src/lib.rs index bcfad253e..61f54eec7 100644 --- a/miner/src/lib.rs +++ b/miner/src/lib.rs @@ -27,19 +27,13 @@ //! extern crate ethcore_util as util; //! extern crate ethcore; //! extern crate ethminer; -//! use std::ops::Deref; //! use std::env; -//! use std::sync::Arc; //! use util::network::{NetworkService, NetworkConfiguration}; -//! use ethcore::client::{Client, ClientConfig, BlockChainClient}; +//! use ethcore::client::{Client, ClientConfig}; //! use ethcore::ethereum; //! use ethminer::{Miner, MinerService}; //! //! fn main() { -//! let mut service = NetworkService::start(NetworkConfiguration::new()).unwrap(); -//! let dir = env::temp_dir(); -//! let client = Client::new(ClientConfig::default(), ethereum::new_frontier(), &dir, service.io().channel()); -//! //! let miner: Miner = Miner::default(); //! // get status //! assert_eq!(miner.status().transactions_in_pending_queue, 0); @@ -59,10 +53,12 @@ extern crate env_logger; extern crate rayon; mod miner; +mod external; mod transaction_queue; pub use transaction_queue::{TransactionQueue, AccountDetails, TransactionImportResult}; pub use miner::{Miner}; +pub use external::{ExternalMiner, ExternalMinerService}; use util::{H256, U256, Address, Bytes}; use ethcore::client::{BlockChainClient}; diff --git a/parity/main.rs b/parity/main.rs index 267ae3d54..2f0116887 100644 --- a/parity/main.rs +++ b/parity/main.rs @@ -69,7 +69,7 @@ use util::*; use util::panics::{MayPanic, ForwardPanic, PanicHandler}; use ethcore::service::ClientService; use ethsync::EthSync; -use ethminer::{Miner, MinerService}; +use ethminer::{Miner, MinerService, ExternalMiner}; use daemonize::Daemonize; use die::*; @@ -153,6 +153,8 @@ fn execute_client(conf: Configuration) { miner.set_minimal_gas_price(conf.gas_price()); miner.set_transactions_limit(conf.args.flag_tx_limit); + let external_miner = Arc::new(ExternalMiner::default()); + // Sync let sync = EthSync::register(service.network(), sync_config, client.clone(), miner.clone()); @@ -168,6 +170,7 @@ fn execute_client(conf: Configuration) { sync: sync.clone(), secret_store: account_service.clone(), miner: miner.clone(), + external_miner: external_miner.clone(), logger: logger.clone() }); @@ -182,6 +185,7 @@ fn execute_client(conf: Configuration) { sync: sync.clone(), secret_store: account_service.clone(), miner: miner.clone(), + external_miner: external_miner.clone(), logger: logger.clone() }); diff --git a/parity/rpc.rs b/parity/rpc.rs index b2e6391d8..e147f3d79 100644 --- a/parity/rpc.rs +++ b/parity/rpc.rs @@ -20,7 +20,7 @@ use std::sync::Arc; use std::net::SocketAddr; use ethcore::client::Client; use ethsync::EthSync; -use ethminer::Miner; +use ethminer::{Miner, ExternalMiner}; use util::RotatingLogger; use util::keys::store::{AccountService}; use die::*; @@ -45,6 +45,7 @@ pub struct Dependencies { pub sync: Arc, pub secret_store: Arc, pub miner: Arc, + pub external_miner: Arc, pub logger: Arc, } @@ -90,7 +91,7 @@ pub fn setup_rpc_server( "web3" => server.add_delegate(Web3Client::new().to_delegate()), "net" => server.add_delegate(NetClient::new(&deps.sync).to_delegate()), "eth" => { - server.add_delegate(EthClient::new(&deps.client, &deps.sync, &deps.secret_store, &deps.miner).to_delegate()); + server.add_delegate(EthClient::new(&deps.client, &deps.sync, &deps.secret_store, &deps.miner, &deps.external_miner).to_delegate()); server.add_delegate(EthFilterClient::new(&deps.client, &deps.miner).to_delegate()); }, "personal" => server.add_delegate(PersonalClient::new(&deps.secret_store).to_delegate()), diff --git a/parity/webapp.rs b/parity/webapp.rs index 74e8c2e51..a94ffc845 100644 --- a/parity/webapp.rs +++ b/parity/webapp.rs @@ -19,7 +19,7 @@ use std::str::FromStr; use std::net::SocketAddr; use ethcore::client::Client; use ethsync::EthSync; -use ethminer::Miner; +use ethminer::{Miner, ExternalMiner}; use util::RotatingLogger; use util::keys::store::{AccountService}; use die::*; @@ -42,6 +42,7 @@ pub struct Dependencies { pub sync: Arc, pub secret_store: Arc, pub miner: Arc, + pub external_miner: Arc, pub logger: Arc, } @@ -93,7 +94,7 @@ pub fn setup_webapp_server( let server = webapp::ServerBuilder::new(); server.add_delegate(Web3Client::new().to_delegate()); server.add_delegate(NetClient::new(&deps.sync).to_delegate()); - server.add_delegate(EthClient::new(&deps.client, &deps.sync, &deps.secret_store, &deps.miner).to_delegate()); + server.add_delegate(EthClient::new(&deps.client, &deps.sync, &deps.secret_store, &deps.miner, &deps.external_miner).to_delegate()); server.add_delegate(EthFilterClient::new(&deps.client, &deps.miner).to_delegate()); server.add_delegate(PersonalClient::new(&deps.secret_store).to_delegate()); server.add_delegate(EthcoreClient::new(&deps.miner, deps.logger).to_delegate()); diff --git a/rpc/src/v1/helpers/mod.rs b/rpc/src/v1/helpers/mod.rs index 8c574cff6..b1a5c05ba 100644 --- a/rpc/src/v1/helpers/mod.rs +++ b/rpc/src/v1/helpers/mod.rs @@ -16,8 +16,6 @@ mod poll_manager; mod poll_filter; -pub mod external_miner; pub use self::poll_manager::PollManager; pub use self::poll_filter::PollFilter; -pub use self::external_miner::{ExternalMinerService, ExternalMiner}; diff --git a/rpc/src/v1/impls/eth.rs b/rpc/src/v1/impls/eth.rs index 303486bfa..5a585ae87 100644 --- a/rpc/src/v1/impls/eth.rs +++ b/rpc/src/v1/impls/eth.rs @@ -22,7 +22,7 @@ use std::collections::HashSet; use std::sync::{Arc, Weak, Mutex}; use std::ops::Deref; use ethsync::{SyncProvider, SyncState}; -use ethminer::{MinerService, AccountDetails}; +use ethminer::{MinerService, AccountDetails, ExternalMinerService}; use jsonrpc_core::*; use util::numbers::*; use util::sha3::*; @@ -36,12 +36,12 @@ use ethcore::transaction::{Transaction as EthTransaction, SignedTransaction, Act use self::ethash::SeedHashCompute; use v1::traits::{Eth, EthFilter}; use v1::types::{Block, BlockTransactions, BlockNumber, Bytes, SyncStatus, SyncInfo, Transaction, TransactionRequest, CallRequest, OptionalValue, Index, Filter, Log, Receipt}; -use v1::helpers::{PollFilter, PollManager, ExternalMinerService, ExternalMiner}; +use v1::helpers::{PollFilter, PollManager}; use util::keys::store::AccountProvider; use serde; /// Eth rpc implementation. -pub struct EthClient +pub struct EthClient where C: BlockChainClient, S: SyncProvider, A: AccountProvider, @@ -51,22 +51,10 @@ pub struct EthClient sync: Weak, accounts: Weak, miner: Weak, - external_miner: EM, + external_miner: Arc, seed_compute: Mutex, } -impl EthClient - where C: BlockChainClient, - S: SyncProvider, - A: AccountProvider, - M: MinerService { - - /// Creates new EthClient. - pub fn new(client: &Arc, sync: &Arc, accounts: &Arc, miner: &Arc) -> Self { - EthClient::new_with_external_miner(client, sync, accounts, miner, ExternalMiner::default()) - } -} - impl EthClient where C: BlockChainClient, S: SyncProvider, @@ -74,15 +62,15 @@ impl EthClient M: MinerService, EM: ExternalMinerService { - /// Creates new EthClient with custom external miner. - pub fn new_with_external_miner(client: &Arc, sync: &Arc, accounts: &Arc, miner: &Arc, em: EM) + /// Creates new EthClient. + pub fn new(client: &Arc, sync: &Arc, accounts: &Arc, miner: &Arc, em: &Arc) -> EthClient { EthClient { client: Arc::downgrade(client), sync: Arc::downgrade(sync), miner: Arc::downgrade(miner), accounts: Arc::downgrade(accounts), - external_miner: em, + external_miner: em.clone(), seed_compute: Mutex::new(SeedHashCompute::new()), } } diff --git a/rpc/src/v1/tests/eth.rs b/rpc/src/v1/tests/eth.rs index bde351486..e0d6a86a0 100644 --- a/rpc/src/v1/tests/eth.rs +++ b/rpc/src/v1/tests/eth.rs @@ -24,8 +24,9 @@ use ethcore::client::{TestBlockChainClient, EachBlockWith, Executed, Transaction use ethcore::log_entry::{LocalizedLogEntry, LogEntry}; use ethcore::receipt::LocalizedReceipt; use ethcore::transaction::{Transaction, Action}; +use ethminer::ExternalMiner; use v1::{Eth, EthClient}; -use v1::tests::helpers::{TestAccount, TestAccountProvider, TestSyncProvider, Config, TestMinerService, TestExternalMiner}; +use v1::tests::helpers::{TestAccount, TestAccountProvider, TestSyncProvider, Config, TestMinerService}; fn blockchain_client() -> Arc { let client = TestBlockChainClient::new(); @@ -66,8 +67,8 @@ impl Default for EthTester { let ap = accounts_provider(); let miner = miner_service(); let hashrates = Arc::new(RwLock::new(HashMap::new())); - let external_miner = TestExternalMiner::new(hashrates.clone()); - let eth = EthClient::new_with_external_miner(&client, &sync, &ap, &miner, external_miner).to_delegate(); + let external_miner = Arc::new(ExternalMiner::new(hashrates.clone())); + let eth = EthClient::new(&client, &sync, &ap, &miner, &external_miner).to_delegate(); let io = IoHandler::new(); io.add_delegate(eth); EthTester { diff --git a/rpc/src/v1/tests/helpers/external_miner.rs b/rpc/src/v1/tests/helpers/external_miner.rs deleted file mode 100644 index 1799c36c5..000000000 --- a/rpc/src/v1/tests/helpers/external_miner.rs +++ /dev/null @@ -1,50 +0,0 @@ -// 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::collections::HashMap; -use std::sync::{Arc, RwLock}; -use util::numbers::U256; -use util::hash::H256; -use v1::helpers::ExternalMinerService; - -/// Test ExternalMinerService; -pub struct TestExternalMiner { - /// External miners hashrates. - pub hashrates: Arc>> -} - -impl TestExternalMiner { - /// Creates new external miner. - pub fn new(hashrates: Arc>>) -> Self { - TestExternalMiner { - hashrates: hashrates, - } - } -} - -impl ExternalMinerService for TestExternalMiner { - fn submit_hashrate(&self, hashrate: U256, id: H256) { - self.hashrates.write().unwrap().insert(id, hashrate); - } - - fn hashrate(&self) -> U256 { - self.hashrates.read().unwrap().iter().fold(U256::from(0), |sum, (_, v)| sum + *v) - } - - fn is_mining(&self) -> bool { - !self.hashrates.read().unwrap().is_empty() - } -} diff --git a/rpc/src/v1/tests/helpers/mod.rs b/rpc/src/v1/tests/helpers/mod.rs index c9db61f6d..0e60e179e 100644 --- a/rpc/src/v1/tests/helpers/mod.rs +++ b/rpc/src/v1/tests/helpers/mod.rs @@ -19,9 +19,7 @@ mod account_provider; mod sync_provider; mod miner_service; -mod external_miner; pub use self::account_provider::{TestAccount, TestAccountProvider}; pub use self::sync_provider::{Config, TestSyncProvider}; pub use self::miner_service::{TestMinerService}; -pub use self::external_miner::TestExternalMiner;