Merge pull request #984 from ethcore/rpc-shared-miner

RPC shared external miner
This commit is contained in:
Nikolay Volf 2016-04-22 16:46:36 +03:00
commit 3c6669bd98
10 changed files with 76 additions and 91 deletions

View File

@ -15,7 +15,7 @@
// along with Parity. If not, see <http://www.gnu.org/licenses/>. // along with Parity. If not, see <http://www.gnu.org/licenses/>.
use std::collections::HashMap; use std::collections::HashMap;
use std::sync::RwLock; use std::sync::{Arc, RwLock};
use util::numbers::U256; use util::numbers::U256;
use util::hash::H256; use util::hash::H256;
@ -33,13 +33,22 @@ pub trait ExternalMinerService: Send + Sync {
/// External Miner. /// External Miner.
pub struct ExternalMiner { pub struct ExternalMiner {
hashrates: RwLock<HashMap<H256, U256>>, hashrates: Arc<RwLock<HashMap<H256, U256>>>,
} }
impl Default for ExternalMiner { impl Default for ExternalMiner {
fn default() -> Self { fn default() -> Self {
ExternalMiner { 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<RwLock<HashMap<H256, U256>>>) -> Self {
ExternalMiner {
hashrates: hashrates
} }
} }
} }
@ -57,3 +66,43 @@ impl ExternalMinerService for ExternalMiner {
!self.hashrates.read().unwrap().is_empty() !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));
}
}

View File

@ -27,19 +27,13 @@
//! extern crate ethcore_util as util; //! extern crate ethcore_util as util;
//! extern crate ethcore; //! extern crate ethcore;
//! extern crate ethminer; //! extern crate ethminer;
//! use std::ops::Deref;
//! use std::env; //! use std::env;
//! use std::sync::Arc;
//! use util::network::{NetworkService, NetworkConfiguration}; //! use util::network::{NetworkService, NetworkConfiguration};
//! use ethcore::client::{Client, ClientConfig, BlockChainClient}; //! use ethcore::client::{Client, ClientConfig};
//! use ethcore::ethereum; //! use ethcore::ethereum;
//! use ethminer::{Miner, MinerService}; //! use ethminer::{Miner, MinerService};
//! //!
//! fn main() { //! 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(); //! let miner: Miner = Miner::default();
//! // get status //! // get status
//! assert_eq!(miner.status().transactions_in_pending_queue, 0); //! assert_eq!(miner.status().transactions_in_pending_queue, 0);
@ -59,10 +53,12 @@ extern crate env_logger;
extern crate rayon; extern crate rayon;
mod miner; mod miner;
mod external;
mod transaction_queue; mod transaction_queue;
pub use transaction_queue::{TransactionQueue, AccountDetails, TransactionImportResult}; pub use transaction_queue::{TransactionQueue, AccountDetails, TransactionImportResult};
pub use miner::{Miner}; pub use miner::{Miner};
pub use external::{ExternalMiner, ExternalMinerService};
use util::{H256, U256, Address, Bytes}; use util::{H256, U256, Address, Bytes};
use ethcore::client::{BlockChainClient}; use ethcore::client::{BlockChainClient};

View File

@ -69,7 +69,7 @@ use util::*;
use util::panics::{MayPanic, ForwardPanic, PanicHandler}; use util::panics::{MayPanic, ForwardPanic, PanicHandler};
use ethcore::service::ClientService; use ethcore::service::ClientService;
use ethsync::EthSync; use ethsync::EthSync;
use ethminer::{Miner, MinerService}; use ethminer::{Miner, MinerService, ExternalMiner};
use daemonize::Daemonize; use daemonize::Daemonize;
use die::*; use die::*;
@ -153,6 +153,7 @@ fn execute_client(conf: Configuration) {
miner.set_minimal_gas_price(conf.gas_price()); miner.set_minimal_gas_price(conf.gas_price());
miner.set_transactions_limit(conf.args.flag_tx_limit); miner.set_transactions_limit(conf.args.flag_tx_limit);
let external_miner = Arc::new(ExternalMiner::default());
let network_settings = Arc::new(conf.network_settings()); let network_settings = Arc::new(conf.network_settings());
// Sync // Sync
@ -170,6 +171,7 @@ fn execute_client(conf: Configuration) {
sync: sync.clone(), sync: sync.clone(),
secret_store: account_service.clone(), secret_store: account_service.clone(),
miner: miner.clone(), miner: miner.clone(),
external_miner: external_miner.clone(),
logger: logger.clone(), logger: logger.clone(),
settings: network_settings.clone(), settings: network_settings.clone(),
}); });
@ -185,6 +187,7 @@ fn execute_client(conf: Configuration) {
sync: sync.clone(), sync: sync.clone(),
secret_store: account_service.clone(), secret_store: account_service.clone(),
miner: miner.clone(), miner: miner.clone(),
external_miner: external_miner.clone(),
logger: logger.clone(), logger: logger.clone(),
settings: network_settings.clone(), settings: network_settings.clone(),
}); });

View File

@ -20,7 +20,7 @@ use std::sync::Arc;
use std::net::SocketAddr; use std::net::SocketAddr;
use ethcore::client::Client; use ethcore::client::Client;
use ethsync::EthSync; use ethsync::EthSync;
use ethminer::Miner; use ethminer::{Miner, ExternalMiner};
use util::RotatingLogger; use util::RotatingLogger;
use util::keys::store::{AccountService}; use util::keys::store::{AccountService};
use util::network_settings::NetworkSettings; use util::network_settings::NetworkSettings;
@ -46,6 +46,7 @@ pub struct Dependencies {
pub sync: Arc<EthSync>, pub sync: Arc<EthSync>,
pub secret_store: Arc<AccountService>, pub secret_store: Arc<AccountService>,
pub miner: Arc<Miner>, pub miner: Arc<Miner>,
pub external_miner: Arc<ExternalMiner>,
pub logger: Arc<RotatingLogger>, pub logger: Arc<RotatingLogger>,
pub settings: Arc<NetworkSettings>, pub settings: Arc<NetworkSettings>,
} }
@ -92,7 +93,7 @@ pub fn setup_rpc_server(
"web3" => server.add_delegate(Web3Client::new().to_delegate()), "web3" => server.add_delegate(Web3Client::new().to_delegate()),
"net" => server.add_delegate(NetClient::new(&deps.sync).to_delegate()), "net" => server.add_delegate(NetClient::new(&deps.sync).to_delegate()),
"eth" => { "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()); server.add_delegate(EthFilterClient::new(&deps.client, &deps.miner).to_delegate());
}, },
"personal" => server.add_delegate(PersonalClient::new(&deps.secret_store).to_delegate()), "personal" => server.add_delegate(PersonalClient::new(&deps.secret_store).to_delegate()),

View File

@ -19,7 +19,7 @@ use std::str::FromStr;
use std::net::SocketAddr; use std::net::SocketAddr;
use ethcore::client::Client; use ethcore::client::Client;
use ethsync::EthSync; use ethsync::EthSync;
use ethminer::Miner; use ethminer::{Miner, ExternalMiner};
use util::RotatingLogger; use util::RotatingLogger;
use util::keys::store::{AccountService}; use util::keys::store::{AccountService};
use util::network_settings::NetworkSettings; use util::network_settings::NetworkSettings;
@ -43,6 +43,7 @@ pub struct Dependencies {
pub sync: Arc<EthSync>, pub sync: Arc<EthSync>,
pub secret_store: Arc<AccountService>, pub secret_store: Arc<AccountService>,
pub miner: Arc<Miner>, pub miner: Arc<Miner>,
pub external_miner: Arc<ExternalMiner>,
pub logger: Arc<RotatingLogger>, pub logger: Arc<RotatingLogger>,
pub settings: Arc<NetworkSettings>, pub settings: Arc<NetworkSettings>,
} }
@ -95,7 +96,7 @@ pub fn setup_webapp_server(
let server = webapp::ServerBuilder::new(); let server = webapp::ServerBuilder::new();
server.add_delegate(Web3Client::new().to_delegate()); server.add_delegate(Web3Client::new().to_delegate());
server.add_delegate(NetClient::new(&deps.sync).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(EthFilterClient::new(&deps.client, &deps.miner).to_delegate());
server.add_delegate(PersonalClient::new(&deps.secret_store).to_delegate()); server.add_delegate(PersonalClient::new(&deps.secret_store).to_delegate());
server.add_delegate(EthcoreClient::new(&deps.miner, deps.logger, deps.settings).to_delegate()); server.add_delegate(EthcoreClient::new(&deps.miner, deps.logger, deps.settings).to_delegate());

View File

@ -16,8 +16,6 @@
mod poll_manager; mod poll_manager;
mod poll_filter; mod poll_filter;
pub mod external_miner;
pub use self::poll_manager::PollManager; pub use self::poll_manager::PollManager;
pub use self::poll_filter::PollFilter; pub use self::poll_filter::PollFilter;
pub use self::external_miner::{ExternalMinerService, ExternalMiner};

View File

@ -22,7 +22,7 @@ use std::collections::HashSet;
use std::sync::{Arc, Weak, Mutex}; use std::sync::{Arc, Weak, Mutex};
use std::ops::Deref; use std::ops::Deref;
use ethsync::{SyncProvider, SyncState}; use ethsync::{SyncProvider, SyncState};
use ethminer::{MinerService, AccountDetails}; use ethminer::{MinerService, AccountDetails, ExternalMinerService};
use jsonrpc_core::*; use jsonrpc_core::*;
use util::numbers::*; use util::numbers::*;
use util::sha3::*; use util::sha3::*;
@ -36,12 +36,12 @@ use ethcore::transaction::{Transaction as EthTransaction, SignedTransaction, Act
use self::ethash::SeedHashCompute; use self::ethash::SeedHashCompute;
use v1::traits::{Eth, EthFilter}; use v1::traits::{Eth, EthFilter};
use v1::types::{Block, BlockTransactions, BlockNumber, Bytes, SyncStatus, SyncInfo, Transaction, TransactionRequest, CallRequest, OptionalValue, Index, Filter, Log, Receipt}; 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 util::keys::store::AccountProvider;
use serde; use serde;
/// Eth rpc implementation. /// Eth rpc implementation.
pub struct EthClient<C, S, A, M, EM = ExternalMiner> pub struct EthClient<C, S, A, M, EM>
where C: BlockChainClient, where C: BlockChainClient,
S: SyncProvider, S: SyncProvider,
A: AccountProvider, A: AccountProvider,
@ -51,22 +51,10 @@ pub struct EthClient<C, S, A, M, EM = ExternalMiner>
sync: Weak<S>, sync: Weak<S>,
accounts: Weak<A>, accounts: Weak<A>,
miner: Weak<M>, miner: Weak<M>,
external_miner: EM, external_miner: Arc<EM>,
seed_compute: Mutex<SeedHashCompute>, seed_compute: Mutex<SeedHashCompute>,
} }
impl<C, S, A, M> EthClient<C, S, A, M, ExternalMiner>
where C: BlockChainClient,
S: SyncProvider,
A: AccountProvider,
M: MinerService {
/// Creates new EthClient.
pub fn new(client: &Arc<C>, sync: &Arc<S>, accounts: &Arc<A>, miner: &Arc<M>) -> Self {
EthClient::new_with_external_miner(client, sync, accounts, miner, ExternalMiner::default())
}
}
impl<C, S, A, M, EM> EthClient<C, S, A, M, EM> impl<C, S, A, M, EM> EthClient<C, S, A, M, EM>
where C: BlockChainClient, where C: BlockChainClient,
S: SyncProvider, S: SyncProvider,
@ -74,15 +62,15 @@ impl<C, S, A, M, EM> EthClient<C, S, A, M, EM>
M: MinerService, M: MinerService,
EM: ExternalMinerService { EM: ExternalMinerService {
/// Creates new EthClient with custom external miner. /// Creates new EthClient.
pub fn new_with_external_miner(client: &Arc<C>, sync: &Arc<S>, accounts: &Arc<A>, miner: &Arc<M>, em: EM) pub fn new(client: &Arc<C>, sync: &Arc<S>, accounts: &Arc<A>, miner: &Arc<M>, em: &Arc<EM>)
-> EthClient<C, S, A, M, EM> { -> EthClient<C, S, A, M, EM> {
EthClient { EthClient {
client: Arc::downgrade(client), client: Arc::downgrade(client),
sync: Arc::downgrade(sync), sync: Arc::downgrade(sync),
miner: Arc::downgrade(miner), miner: Arc::downgrade(miner),
accounts: Arc::downgrade(accounts), accounts: Arc::downgrade(accounts),
external_miner: em, external_miner: em.clone(),
seed_compute: Mutex::new(SeedHashCompute::new()), seed_compute: Mutex::new(SeedHashCompute::new()),
} }
} }

View File

@ -24,8 +24,9 @@ use ethcore::client::{TestBlockChainClient, EachBlockWith, Executed, Transaction
use ethcore::log_entry::{LocalizedLogEntry, LogEntry}; use ethcore::log_entry::{LocalizedLogEntry, LogEntry};
use ethcore::receipt::LocalizedReceipt; use ethcore::receipt::LocalizedReceipt;
use ethcore::transaction::{Transaction, Action}; use ethcore::transaction::{Transaction, Action};
use ethminer::ExternalMiner;
use v1::{Eth, EthClient}; 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<TestBlockChainClient> { fn blockchain_client() -> Arc<TestBlockChainClient> {
let client = TestBlockChainClient::new(); let client = TestBlockChainClient::new();
@ -66,8 +67,8 @@ impl Default for EthTester {
let ap = accounts_provider(); let ap = accounts_provider();
let miner = miner_service(); let miner = miner_service();
let hashrates = Arc::new(RwLock::new(HashMap::new())); let hashrates = Arc::new(RwLock::new(HashMap::new()));
let external_miner = TestExternalMiner::new(hashrates.clone()); let external_miner = Arc::new(ExternalMiner::new(hashrates.clone()));
let eth = EthClient::new_with_external_miner(&client, &sync, &ap, &miner, external_miner).to_delegate(); let eth = EthClient::new(&client, &sync, &ap, &miner, &external_miner).to_delegate();
let io = IoHandler::new(); let io = IoHandler::new();
io.add_delegate(eth); io.add_delegate(eth);
EthTester { EthTester {

View File

@ -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 <http://www.gnu.org/licenses/>.
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<RwLock<HashMap<H256, U256>>>
}
impl TestExternalMiner {
/// Creates new external miner.
pub fn new(hashrates: Arc<RwLock<HashMap<H256, U256>>>) -> 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()
}
}

View File

@ -19,9 +19,7 @@
mod account_provider; mod account_provider;
mod sync_provider; mod sync_provider;
mod miner_service; mod miner_service;
mod external_miner;
pub use self::account_provider::{TestAccount, TestAccountProvider}; pub use self::account_provider::{TestAccount, TestAccountProvider};
pub use self::sync_provider::{Config, TestSyncProvider}; pub use self::sync_provider::{Config, TestSyncProvider};
pub use self::miner_service::{TestMinerService}; pub use self::miner_service::{TestMinerService};
pub use self::external_miner::TestExternalMiner;