refactoring to hold miner within the client

This commit is contained in:
Nikolay Volf 2016-05-31 19:01:37 +02:00
parent 0cd8644292
commit 4f732972bc
8 changed files with 42 additions and 47 deletions

View File

@ -29,6 +29,7 @@ ethcore-devtools = { path = "../devtools" }
ethjson = { path = "../json" } ethjson = { path = "../json" }
bloomchain = "0.1" bloomchain = "0.1"
"ethcore-ipc" = { path = "../ipc/rpc" } "ethcore-ipc" = { path = "../ipc/rpc" }
ethminer = { path = "../miner" }
[features] [features]
jit = ["evmjit"] jit = ["evmjit"]

View File

@ -90,6 +90,7 @@ pub struct Client<V = CanonVerifier> where V: Verifier {
panic_handler: Arc<PanicHandler>, panic_handler: Arc<PanicHandler>,
verifier: PhantomData<V>, verifier: PhantomData<V>,
vm_factory: Arc<EvmFactory>, vm_factory: Arc<EvmFactory>,
miner: Arc<MinerService>,
} }
const HISTORY: u64 = 1200; const HISTORY: u64 = 1200;
@ -126,7 +127,13 @@ pub fn append_path(path: &Path, item: &str) -> String {
impl<V> Client<V> where V: Verifier { impl<V> Client<V> where V: Verifier {
/// Create a new client with given spec and DB path and custom 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<NetSyncMessage> ) -> Result<Arc<Client<V>>, ClientError> { pub fn new_with_verifier(
config: ClientConfig,
spec: Spec,
path: &Path,
message_channel: IoChannel<NetSyncMessage>)
-> Result<Arc<Client<V>>, ClientError>
{
let path = get_db_path(path, config.pruning, spec.genesis_header().hash()); let path = get_db_path(path, config.pruning, spec.genesis_header().hash());
let gb = spec.genesis_block(); let gb = spec.genesis_block();
let chain = Arc::new(BlockChain::new(config.blockchain, &gb, &path)); let chain = Arc::new(BlockChain::new(config.blockchain, &gb, &path));
@ -328,18 +335,13 @@ impl<V> Client<V> where V: Verifier {
{ {
if !imported_blocks.is_empty() && self.block_queue.queue_info().is_empty() { if !imported_blocks.is_empty() && self.block_queue.queue_info().is_empty() {
let (enacted, retracted) = self.calculate_enacted_retracted(import_results); let (enacted, retracted) = self.calculate_enacted_retracted(import_results);
io.send(NetworkIoMessage::User(SyncMessage::NewChainBlocks { self.miner.chain_new_blocks(imported_blocks, invalid_blocks, enacted, retracted);
imported: imported_blocks,
invalid: invalid_blocks,
enacted: enacted,
retracted: retracted,
})).unwrap();
} }
} }
{ {
if self.chain_info().best_block_hash != original_best { 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<V> ExtendedBlockChainClient for Client<V> where V: Verifier {
} }
} }
impl MiningClient for Client {
fn import_transactions(&self, transactions: Vec<SignedTransaction>) -> Vec<Result<TransactionImportResult, Error>> {
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<SignedTransaction> {
self.miner.all_transactions()
}
}
impl MayPanic for Client { impl MayPanic for Client {
fn on_panic<F>(&self, closure: F) where F: OnPanicListener { fn on_panic<F>(&self, closure: F) where F: OnPanicListener {
self.panic_handler.on_panic(closure); self.panic_handler.on_panic(closure);

View File

@ -178,12 +178,19 @@ pub trait BlockChainClient : Sync + Send {
/// Extended client interface used for mining /// Extended client interface used for mining
pub trait ExtendedBlockChainClient : BlockChainClient { 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. /// 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<Bytes>) -> Result<SealedBlock, LockedBlock>; fn try_seal(&self, block: LockedBlock, seal: Vec<Bytes>) -> Result<SealedBlock, LockedBlock>;
// TODO [todr] Should be moved to miner crate eventually.
/// Returns ClosedBlock prepared for sealing. /// Returns ClosedBlock prepared for sealing.
fn prepare_sealing(&self, author: Address, gas_floor_target: U256, extra_data: Bytes, transactions: Vec<SignedTransaction>) fn prepare_sealing(&self, author: Address, gas_floor_target: U256, extra_data: Bytes, transactions: Vec<SignedTransaction>)
-> (Option<ClosedBlock>, HashSet<H256>); -> (Option<ClosedBlock>, HashSet<H256>);
} }
/// Extended client interface that supports mining
pub trait MiningClient : BlockChainClient {
/// import transactions from network/other 3rd party
fn import_transactions(&self, transactions: Vec<SignedTransaction>) -> Vec<Result<TransactionImportResult, Error>>;
/// list all transactions
fn all_transactions(&self) -> Vec<SignedTransaction>;
}

View File

@ -903,7 +903,7 @@ impl ChainSync {
nonce: chain.latest_nonce(a), nonce: chain.latest_nonce(a),
balance: chain.latest_balance(a), balance: chain.latest_balance(a),
}; };
let _ = self.miner.import_transactions(transactions, fetch_account); let _ = io.chain().import_transactions(transactions, fetch_account);
Ok(()) Ok(())
} }
@ -1226,7 +1226,7 @@ impl ChainSync {
return 0; return 0;
} }
let mut transactions = self.miner.all_transactions(); let mut transactions = io.chain().all_transactions();
if transactions.is_empty() { if transactions.is_empty() {
return 0; return 0;
} }
@ -1275,24 +1275,6 @@ impl ChainSync {
pub fn maintain_sync(&mut self, io: &mut SyncIo) { pub fn maintain_sync(&mut self, io: &mut SyncIo) {
self.check_resume(io); 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)] #[cfg(test)]

View File

@ -14,7 +14,7 @@
// You should have received a copy of the GNU General Public License // You should have received a copy of the GNU General Public License
// along with Parity. If not, see <http://www.gnu.org/licenses/>. // along with Parity. If not, see <http://www.gnu.org/licenses/>.
use ethcore::client::BlockChainClient; use ethcore::client::MiningClient;
use util::{NetworkContext, PeerId, PacketId,}; use util::{NetworkContext, PeerId, PacketId,};
use util::error::UtilError; use util::error::UtilError;
use ethcore::service::SyncMessage; use ethcore::service::SyncMessage;
@ -32,7 +32,7 @@ pub trait SyncIo {
/// Send a packet to a peer. /// Send a packet to a peer.
fn send(&mut self, peer_id: PeerId, packet_id: PacketId, data: Vec<u8>) -> Result<(), UtilError>; fn send(&mut self, peer_id: PeerId, packet_id: PacketId, data: Vec<u8>) -> Result<(), UtilError>;
/// Get the blockchain /// Get the blockchain
fn chain(&self) -> &BlockChainClient; fn chain(&self) -> &MiningClient;
/// Returns peer client identifier string /// Returns peer client identifier string
fn peer_info(&self, peer_id: PeerId) -> String { fn peer_info(&self, peer_id: PeerId) -> String {
peer_id.to_string() peer_id.to_string()
@ -46,12 +46,12 @@ pub trait SyncIo {
/// Wraps `NetworkContext` and the blockchain client /// Wraps `NetworkContext` and the blockchain client
pub struct NetSyncIo<'s, 'h> where 'h: 's { pub struct NetSyncIo<'s, 'h> where 'h: 's {
network: &'s NetworkContext<'h, SyncMessage>, network: &'s NetworkContext<'h, SyncMessage>,
chain: &'s BlockChainClient chain: &'s MiningClient
} }
impl<'s, 'h> NetSyncIo<'s, 'h> { impl<'s, 'h> NetSyncIo<'s, 'h> {
/// Creates a new instance from the `NetworkContext` and the blockchain client reference. /// 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 { NetSyncIo {
network: network, network: network,
chain: chain, chain: chain,

View File

@ -166,16 +166,5 @@ impl NetworkProtocolHandler<SyncMessage> for EthSync {
} }
fn message(&self, io: &NetworkContext<SyncMessage>, message: &SyncMessage) { fn message(&self, io: &NetworkContext<SyncMessage>, 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 */},
}
} }
} }

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 util::*; use util::*;
use ethcore::client::{BlockChainClient, BlockID, EachBlockWith}; use ethcore::client::{MiningClient, BlockID, EachBlockWith};
use chain::{SyncState}; use chain::{SyncState};
use super::helpers::*; use super::helpers::*;

View File

@ -63,7 +63,7 @@ impl<'p> SyncIo for TestIo<'p> {
Ok(()) Ok(())
} }
fn chain(&self) -> &BlockChainClient { fn chain(&self) -> &MiningClient {
self.chain self.chain
} }
} }