diff --git a/miner/src/lib.rs b/miner/src/lib.rs index 36b040b78..591b73402 100644 --- a/miner/src/lib.rs +++ b/miner/src/lib.rs @@ -18,6 +18,37 @@ #![cfg_attr(feature="dev", feature(plugin))] #![cfg_attr(feature="dev", plugin(clippy))] +//! Miner module +//! Keeps track of transactions and mined block. +//! +//! Usage example: +//! +//! ```rust +//! extern crate ethcore_util as util; +//! extern crate ethcore; +//! extern crate ethminer; +//! use std::env; +//! use std::sync::Arc; +//! use util::network::{NetworkService, NetworkConfiguration}; +//! use ethcore::client::{Client, ClientConfig}; +//! use ethcore::ethereum; +//! use ethminer::{Miner, MinerService}; +//! +//! fn main() { +//! let dir = env::temp_dir(); +//! let client = Client::new(ClientConfig::default(), ethereum::new_frontier(), &dir, service.io().channel()).unwrap(); +//! +//! let miner: Miner = Miner::default(); +//! // get status +//! assert_eq!(miner.status().transaction_queue_pending, 0); +//! +//! // Check block for sealing +//! miner.prepare_sealing(&client); +//! assert_eq!(miner.sealing_block(&client).lock().unwrap().is_some()); +//! } +//! ``` + + #[macro_use] extern crate log; #[macro_use] @@ -29,28 +60,5 @@ extern crate rayon; mod miner; mod transaction_queue; -use std::ops::*; -use std::sync::*; pub use miner::{Miner, MinerService}; - -pub struct EthMiner { - miner: Miner, -} - -impl EthMiner { - /// Creates and register protocol with the network service - pub fn new() -> Arc { - Arc::new(EthMiner { - miner: Miner::new(), - }) - } -} - -impl Deref for EthMiner { - type Target = Miner; - - fn deref(&self) -> &Self::Target { - &self.miner - } -} diff --git a/miner/src/miner.rs b/miner/src/miner.rs index 64d3c9083..f5ad32d2d 100644 --- a/miner/src/miner.rs +++ b/miner/src/miner.rs @@ -24,21 +24,28 @@ use ethcore::error::*; use ethcore::transaction::SignedTransaction; use transaction_queue::{TransactionQueue}; +/// Miner external API pub trait MinerService { + + /// Returns miner's status. fn status(&self) -> MinerStatus; + /// Imports transactions to transaction queue. fn import_transactions(&self, transactions: Vec, fetch_nonce: T) where T: Fn(&Address) -> U256; - /// called when blocks are imported to chain, updates transactions queue - fn chain_new_blocks(&self, chain: &BlockChainClient, good: &[H256], bad: &[H256], _retracted: &[H256]); - /// Set the author that we will seal blocks as. fn set_author(&self, author: Address); /// Set the extra_data that we will seal blocks with. fn set_extra_data(&self, extra_data: Bytes); + /// Removes all transactions from the queue and restart mining operation. + fn clear_and_reset(&self, chain: &BlockChainClient); + + /// called when blocks are imported to chain, updates transactions queue. + fn chain_new_blocks(&self, chain: &BlockChainClient, good: &[H256], bad: &[H256], _retracted: &[H256]); + /// New chain head event. Restart mining operation. fn prepare_sealing(&self, chain: &BlockChainClient); @@ -50,11 +57,15 @@ pub trait MinerService { fn submit_seal(&self, chain: &BlockChainClient, pow_hash: H256, seal: Vec) -> Result<(), Error>; } +/// Mining status pub struct MinerStatus { + /// Number of transactions in queue with state `pending` (ready to be included in block) pub transaction_queue_pending: usize, + /// Number of transactions in queue with state `future` (not yet ready to be included in block) pub transaction_queue_future: usize, } +/// Keeps track of transactions using priority queue and holds currently mined block. pub struct Miner { transaction_queue: Mutex, @@ -65,9 +76,8 @@ pub struct Miner { extra_data: RwLock, } -impl Miner { - /// Creates new instance of miner - pub fn new() -> Miner { +impl Default for Miner { + fn default() -> Miner { Miner { transaction_queue: Mutex::new(TransactionQueue::new()), sealing_enabled: AtomicBool::new(false), @@ -76,6 +86,13 @@ impl Miner { extra_data: RwLock::new(Vec::new()), } } +} + +impl Miner { + /// Creates new instance of miner + pub fn new() -> Arc { + Arc::new(Miner::default()) + } /// Get the author that we will seal blocks as. fn author(&self) -> Address { @@ -90,6 +107,11 @@ impl Miner { impl MinerService for Miner { + fn clear_and_reset(&self, chain: &BlockChainClient) { + self.transaction_queue.lock().unwrap().clear(); + self.prepare_sealing(chain); + } + fn status(&self) -> MinerStatus { let status = self.transaction_queue.lock().unwrap().status(); MinerStatus { diff --git a/parity/main.rs b/parity/main.rs index 89668a456..d75bdcb57 100644 --- a/parity/main.rs +++ b/parity/main.rs @@ -50,7 +50,7 @@ use ethcore::client::*; use ethcore::service::{ClientService, NetSyncMessage}; use ethcore::ethereum; use ethsync::{EthSync, SyncConfig}; -use ethminer::{EthMiner, MinerService}; +use ethminer::{Miner, MinerService}; use docopt::Docopt; use daemonize::Daemonize; use number_prefix::{binary_prefix, Standalone, Prefixed}; @@ -192,7 +192,7 @@ fn setup_log(init: &Option) { } #[cfg(feature = "rpc")] -fn setup_rpc_server(client: Arc, sync: Arc, miner: Arc, url: &str, cors_domain: &str, apis: Vec<&str>) { +fn setup_rpc_server(client: Arc, sync: Arc, miner: Arc, url: &str, cors_domain: &str, apis: Vec<&str>) { use rpc::v1::*; let mut server = rpc::HttpServer::new(1); @@ -382,7 +382,7 @@ impl Configuration { let client = service.client(); // Miner - let miner = EthMiner::new(); + let miner = Miner::new(); miner.set_author(self.author()); miner.set_extra_data(self.extra_data()); diff --git a/rpc/src/v1/impls/eth.rs b/rpc/src/v1/impls/eth.rs index d40761b09..a9ee389f8 100644 --- a/rpc/src/v1/impls/eth.rs +++ b/rpc/src/v1/impls/eth.rs @@ -19,7 +19,7 @@ use std::collections::HashMap; use std::sync::{Arc, Weak, Mutex, RwLock}; use std::ops::Deref; use ethsync::{EthSync, SyncState}; -use ethminer::{EthMiner, MinerService}; +use ethminer::{Miner, MinerService}; use jsonrpc_core::*; use util::numbers::*; use util::sha3::*; @@ -38,13 +38,13 @@ use v1::helpers::{PollFilter, PollManager}; pub struct EthClient { client: Weak, sync: Weak, - miner: Weak, + miner: Weak, hashrates: RwLock>, } impl EthClient { /// Creates new EthClient. - pub fn new(client: &Arc, sync: &Arc, miner: &Arc) -> Self { + pub fn new(client: &Arc, sync: &Arc, miner: &Arc) -> Self { EthClient { client: Arc::downgrade(client), sync: Arc::downgrade(sync), diff --git a/sync/src/chain.rs b/sync/src/chain.rs index cb584f51d..4c7b0893a 100644 --- a/sync/src/chain.rs +++ b/sync/src/chain.rs @@ -38,7 +38,7 @@ use range_collection::{RangeCollection, ToUsize, FromUsize}; use ethcore::error::*; use ethcore::transaction::SignedTransaction; use ethcore::block::Block; -use ethminer::{EthMiner, MinerService}; +use ethminer::{Miner, MinerService}; use io::SyncIo; use time; use super::SyncConfig; @@ -212,14 +212,14 @@ pub struct ChainSync { /// Network ID network_id: U256, /// Miner - miner: Arc, + miner: Arc, } type RlpResponseResult = Result, PacketDecodeError>; impl ChainSync { /// Create a new instance of syncing strategy. - pub fn new(config: SyncConfig, miner: Arc) -> ChainSync { + pub fn new(config: SyncConfig, miner: Arc) -> ChainSync { ChainSync { state: SyncState::NotSynced, starting_block: 0, @@ -1285,7 +1285,7 @@ mod tests { use super::{PeerInfo, PeerAsking}; use ethcore::header::*; use ethcore::client::*; - use ethminer::{EthMiner, MinerService}; + use ethminer::{Miner, MinerService}; fn get_dummy_block(order: u32, parent_hash: H256) -> Bytes { let mut header = Header::new(); @@ -1395,7 +1395,7 @@ mod tests { } fn dummy_sync_with_peer(peer_latest_hash: H256) -> ChainSync { - let mut sync = ChainSync::new(SyncConfig::default(), EthMiner::new()); + let mut sync = ChainSync::new(SyncConfig::default(), Miner::new()); sync.peers.insert(0, PeerInfo { protocol_version: 0, diff --git a/sync/src/lib.rs b/sync/src/lib.rs index be01d2b7b..dd331b5da 100644 --- a/sync/src/lib.rs +++ b/sync/src/lib.rs @@ -65,7 +65,7 @@ use util::TimerToken; use util::{U256, ONE_U256}; use ethcore::client::Client; use ethcore::service::SyncMessage; -use ethminer::EthMiner; +use ethminer::Miner; use io::NetSyncIo; use chain::ChainSync; @@ -105,7 +105,7 @@ pub use self::chain::{SyncStatus, SyncState}; impl EthSync { /// Creates and register protocol with the network service - pub fn register(service: &mut NetworkService, config: SyncConfig, chain: Arc, miner: Arc) -> Arc { + pub fn register(service: &mut NetworkService, config: SyncConfig, chain: Arc, miner: Arc) -> Arc { let sync = Arc::new(EthSync { chain: chain, sync: RwLock::new(ChainSync::new(config, miner)), diff --git a/sync/src/tests/helpers.rs b/sync/src/tests/helpers.rs index 9a4dd2814..52a1feba4 100644 --- a/sync/src/tests/helpers.rs +++ b/sync/src/tests/helpers.rs @@ -19,7 +19,7 @@ use ethcore::client::{BlockChainClient, BlockStatus, TreeRoute, BlockChainInfo, use ethcore::header::{Header as BlockHeader, BlockNumber}; use ethcore::block::*; use ethcore::error::*; -use ethminer::EthMiner; +use ethminer::Miner; use io::SyncIo; use chain::ChainSync; use ::SyncConfig; @@ -392,7 +392,7 @@ impl TestNet { for _ in 0..n { net.peers.push(TestPeer { chain: TestBlockChainClient::new(), - sync: ChainSync::new(SyncConfig::default(), EthMiner::new()), + sync: ChainSync::new(SyncConfig::default(), Miner::new()), queue: VecDeque::new(), }); }