diff --git a/ethcore/Cargo.toml b/ethcore/Cargo.toml index 34a010794..f63eb957c 100644 --- a/ethcore/Cargo.toml +++ b/ethcore/Cargo.toml @@ -29,6 +29,7 @@ ethcore-devtools = { path = "../devtools" } ethjson = { path = "../json" } bloomchain = "0.1" "ethcore-ipc" = { path = "../ipc/rpc" } +ethminer = { path = "../miner" } [features] jit = ["evmjit"] diff --git a/ethcore/src/client/client.rs b/ethcore/src/client/client.rs index 8f6d607ba..7a616fdbc 100644 --- a/ethcore/src/client/client.rs +++ b/ethcore/src/client/client.rs @@ -90,6 +90,7 @@ pub struct Client where V: Verifier { panic_handler: Arc, verifier: PhantomData, vm_factory: Arc, + miner: Arc, } const HISTORY: u64 = 1200; @@ -126,7 +127,13 @@ pub fn append_path(path: &Path, item: &str) -> String { impl Client where V: Verifier { /// Create a new client with given spec and DB path and custom verifier. - pub fn new_with_verifier(config: ClientConfig, spec: Spec, path: &Path, message_channel: IoChannel ) -> Result>, ClientError> { + pub fn new_with_verifier( + config: ClientConfig, + spec: Spec, + path: &Path, + message_channel: IoChannel) + -> Result>, ClientError> + { let path = get_db_path(path, config.pruning, spec.genesis_header().hash()); let gb = spec.genesis_block(); let chain = Arc::new(BlockChain::new(config.blockchain, &gb, &path)); @@ -328,18 +335,13 @@ impl Client where V: Verifier { { if !imported_blocks.is_empty() && self.block_queue.queue_info().is_empty() { let (enacted, retracted) = self.calculate_enacted_retracted(import_results); - io.send(NetworkIoMessage::User(SyncMessage::NewChainBlocks { - imported: imported_blocks, - invalid: invalid_blocks, - enacted: enacted, - retracted: retracted, - })).unwrap(); + self.miner.chain_new_blocks(imported_blocks, invalid_blocks, enacted, retracted); } } { if self.chain_info().best_block_hash != original_best { - io.send(NetworkIoMessage::User(SyncMessage::NewChainHead)).unwrap(); + self.miner.update_sealing(&self); } } @@ -778,6 +780,20 @@ impl ExtendedBlockChainClient for Client where V: Verifier { } } +impl MiningClient for Client { + fn import_transactions(&self, transactions: Vec) -> Vec> { + let fetch_account = |a: &Address| AccountDetails { + nonce: self.latest_nonce(a), + balance: self.latest_balance(a), + }; + self.miner.import_transactions(transactions, fetch_account) + } + + fn all_transactions(&self) -> Vec { + self.miner.all_transactions() + } +} + impl MayPanic for Client { fn on_panic(&self, closure: F) where F: OnPanicListener { self.panic_handler.on_panic(closure); diff --git a/ethcore/src/client/mod.rs b/ethcore/src/client/mod.rs index 5537f8e66..dfef54a40 100644 --- a/ethcore/src/client/mod.rs +++ b/ethcore/src/client/mod.rs @@ -178,12 +178,19 @@ pub trait BlockChainClient : Sync + Send { /// Extended client interface used for mining pub trait ExtendedBlockChainClient : BlockChainClient { - // TODO [todr] Should be moved to miner crate eventually. /// Attempts to seal given block. Returns `SealedBlock` on success and the same block in case of error. fn try_seal(&self, block: LockedBlock, seal: Vec) -> Result; - // TODO [todr] Should be moved to miner crate eventually. /// Returns ClosedBlock prepared for sealing. fn prepare_sealing(&self, author: Address, gas_floor_target: U256, extra_data: Bytes, transactions: Vec) -> (Option, HashSet); } + +/// Extended client interface that supports mining +pub trait MiningClient : BlockChainClient { + /// import transactions from network/other 3rd party + fn import_transactions(&self, transactions: Vec) -> Vec>; + + /// list all transactions + fn all_transactions(&self) -> Vec; +} diff --git a/sync/src/chain.rs b/sync/src/chain.rs index 2f31f1d47..a0d0ba1fa 100644 --- a/sync/src/chain.rs +++ b/sync/src/chain.rs @@ -903,7 +903,7 @@ impl ChainSync { nonce: chain.latest_nonce(a), balance: chain.latest_balance(a), }; - let _ = self.miner.import_transactions(transactions, fetch_account); + let _ = io.chain().import_transactions(transactions, fetch_account); Ok(()) } @@ -1226,7 +1226,7 @@ impl ChainSync { return 0; } - let mut transactions = self.miner.all_transactions(); + let mut transactions = io.chain().all_transactions(); if transactions.is_empty() { return 0; } @@ -1275,24 +1275,6 @@ impl ChainSync { pub fn maintain_sync(&mut self, io: &mut SyncIo) { self.check_resume(io); } - - /// called when block is imported to chain, updates transactions queue and propagates the blocks - pub fn chain_new_blocks(&mut self, io: &mut SyncIo, imported: &[H256], invalid: &[H256], enacted: &[H256], retracted: &[H256]) { - if io.is_chain_queue_empty() { - // Notify miner - self.miner.chain_new_blocks(io.chain(), imported, invalid, enacted, retracted); - // Propagate latests blocks - self.propagate_latest_blocks(io); - } - if !invalid.is_empty() { - trace!(target: "sync", "Bad blocks in the queue, restarting"); - self.restart_on_bad_block(io); - } - } - - pub fn chain_new_head(&mut self, io: &mut SyncIo) { - self.miner.update_sealing(io.chain()); - } } #[cfg(test)] diff --git a/sync/src/io.rs b/sync/src/io.rs index 84697a021..49cccd7ca 100644 --- a/sync/src/io.rs +++ b/sync/src/io.rs @@ -14,7 +14,7 @@ // You should have received a copy of the GNU General Public License // along with Parity. If not, see . -use ethcore::client::BlockChainClient; +use ethcore::client::MiningClient; use util::{NetworkContext, PeerId, PacketId,}; use util::error::UtilError; use ethcore::service::SyncMessage; @@ -32,7 +32,7 @@ pub trait SyncIo { /// Send a packet to a peer. fn send(&mut self, peer_id: PeerId, packet_id: PacketId, data: Vec) -> Result<(), UtilError>; /// Get the blockchain - fn chain(&self) -> &BlockChainClient; + fn chain(&self) -> &MiningClient; /// Returns peer client identifier string fn peer_info(&self, peer_id: PeerId) -> String { peer_id.to_string() @@ -46,12 +46,12 @@ pub trait SyncIo { /// Wraps `NetworkContext` and the blockchain client pub struct NetSyncIo<'s, 'h> where 'h: 's { network: &'s NetworkContext<'h, SyncMessage>, - chain: &'s BlockChainClient + chain: &'s MiningClient } impl<'s, 'h> NetSyncIo<'s, 'h> { /// Creates a new instance from the `NetworkContext` and the blockchain client reference. - pub fn new(network: &'s NetworkContext<'h, SyncMessage>, chain: &'s BlockChainClient) -> NetSyncIo<'s, 'h> { + pub fn new(network: &'s NetworkContext<'h, SyncMessage>, chain: &'s MiningClient) -> NetSyncIo<'s, 'h> { NetSyncIo { network: network, chain: chain, diff --git a/sync/src/lib.rs b/sync/src/lib.rs index c8dc93db6..6b72a24fc 100644 --- a/sync/src/lib.rs +++ b/sync/src/lib.rs @@ -166,16 +166,5 @@ impl NetworkProtocolHandler for EthSync { } fn message(&self, io: &NetworkContext, message: &SyncMessage) { - match *message { - SyncMessage::NewChainBlocks { ref imported, ref invalid, ref enacted, ref retracted } => { - let mut sync_io = NetSyncIo::new(io, self.chain.deref()); - self.sync.write().unwrap().chain_new_blocks(&mut sync_io, imported, invalid, enacted, retracted); - }, - SyncMessage::NewChainHead => { - let mut sync_io = NetSyncIo::new(io, self.chain.deref()); - self.sync.write().unwrap().chain_new_head(&mut sync_io); - }, - _ => {/* Ignore other messages */}, - } } } diff --git a/sync/src/tests/chain.rs b/sync/src/tests/chain.rs index 09e83e358..463771ffe 100644 --- a/sync/src/tests/chain.rs +++ b/sync/src/tests/chain.rs @@ -15,7 +15,7 @@ // along with Parity. If not, see . use util::*; -use ethcore::client::{BlockChainClient, BlockID, EachBlockWith}; +use ethcore::client::{MiningClient, BlockID, EachBlockWith}; use chain::{SyncState}; use super::helpers::*; diff --git a/sync/src/tests/helpers.rs b/sync/src/tests/helpers.rs index d1ffde0f0..70ddb78db 100644 --- a/sync/src/tests/helpers.rs +++ b/sync/src/tests/helpers.rs @@ -63,7 +63,7 @@ impl<'p> SyncIo for TestIo<'p> { Ok(()) } - fn chain(&self) -> &BlockChainClient { + fn chain(&self) -> &MiningClient { self.chain } }