Shared instance of ExternalMiner
This commit is contained in:
parent
3e280a3386
commit
f5c2bea134
@ -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));
|
||||||
|
}
|
||||||
|
}
|
@ -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};
|
||||||
|
@ -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,8 @@ 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());
|
||||||
|
|
||||||
// Sync
|
// Sync
|
||||||
let sync = EthSync::register(service.network(), sync_config, client.clone(), miner.clone());
|
let sync = EthSync::register(service.network(), sync_config, client.clone(), miner.clone());
|
||||||
|
|
||||||
@ -168,6 +170,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()
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -182,6 +185,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()
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -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 die::*;
|
use die::*;
|
||||||
@ -45,6 +45,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>,
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -90,7 +91,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()),
|
||||||
|
@ -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 die::*;
|
use die::*;
|
||||||
@ -42,6 +42,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>,
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -93,7 +94,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).to_delegate());
|
server.add_delegate(EthcoreClient::new(&deps.miner, deps.logger).to_delegate());
|
||||||
|
@ -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};
|
|
||||||
|
@ -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()),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -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 {
|
||||||
|
@ -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()
|
|
||||||
}
|
|
||||||
}
|
|
@ -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;
|
|
||||||
|
Loading…
Reference in New Issue
Block a user