separate block preparation methods
This commit is contained in:
parent
53b22da1c1
commit
4e75686ef8
@ -24,7 +24,7 @@ use views::{BlockView, HeaderView};
|
|||||||
use state::State;
|
use state::State;
|
||||||
use client::{MiningBlockChainClient, Executive, Executed, EnvInfo, TransactOptions, BlockID, CallAnalytics};
|
use client::{MiningBlockChainClient, Executive, Executed, EnvInfo, TransactOptions, BlockID, CallAnalytics};
|
||||||
use executive::contract_address;
|
use executive::contract_address;
|
||||||
use block::{ClosedBlock, IsBlock, Block};
|
use block::{ClosedBlock, SealedBlock, IsBlock, Block};
|
||||||
use error::*;
|
use error::*;
|
||||||
use transaction::{Action, SignedTransaction};
|
use transaction::{Action, SignedTransaction};
|
||||||
use receipt::{Receipt, RichReceipt};
|
use receipt::{Receipt, RichReceipt};
|
||||||
@ -242,12 +242,7 @@ impl Miner {
|
|||||||
self.sealing_work.lock().queue.peek_last_ref().map(|b| b.base().clone())
|
self.sealing_work.lock().queue.peek_last_ref().map(|b| b.base().clone())
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Prepares new block for sealing including top transactions from queue.
|
fn prepare_block(&self, chain: &MiningBlockChainClient) -> (ClosedBlock, Option<H256>) {
|
||||||
#[cfg_attr(feature="dev", allow(match_same_arms))]
|
|
||||||
#[cfg_attr(feature="dev", allow(cyclomatic_complexity))]
|
|
||||||
fn prepare_sealing(&self, chain: &MiningBlockChainClient) {
|
|
||||||
trace!(target: "miner", "prepare_sealing: entering");
|
|
||||||
|
|
||||||
{
|
{
|
||||||
trace!(target: "miner", "recalibrating...");
|
trace!(target: "miner", "recalibrating...");
|
||||||
let txq = self.transaction_queue.clone();
|
let txq = self.transaction_queue.clone();
|
||||||
@ -334,8 +329,12 @@ impl Miner {
|
|||||||
queue.remove_invalid(&hash, &fetch_account);
|
queue.remove_invalid(&hash, &fetch_account);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
(block, original_work_hash)
|
||||||
|
}
|
||||||
|
|
||||||
if !block.transactions().is_empty() {
|
/// Attempts to perform internal sealing to return Ok(sealed),
|
||||||
|
/// Err(Some(block)) returns for unsuccesful sealing while Err(None) indicates misspecified engine.
|
||||||
|
fn seal_block_internally(&self, block: ClosedBlock) -> Result<SealedBlock, Option<ClosedBlock>> {
|
||||||
trace!(target: "miner", "prepare_sealing: block has transaction - attempting internal seal.");
|
trace!(target: "miner", "prepare_sealing: block has transaction - attempting internal seal.");
|
||||||
// block with transactions - see if we can seal immediately.
|
// block with transactions - see if we can seal immediately.
|
||||||
let s = self.engine.generate_seal(block.block(), match self.accounts {
|
let s = self.engine.generate_seal(block.block(), match self.accounts {
|
||||||
@ -344,21 +343,30 @@ impl Miner {
|
|||||||
});
|
});
|
||||||
if let Some(seal) = s {
|
if let Some(seal) = s {
|
||||||
trace!(target: "miner", "prepare_sealing: managed internal seal. importing...");
|
trace!(target: "miner", "prepare_sealing: managed internal seal. importing...");
|
||||||
if let Ok(sealed) = block.lock().try_seal(&*self.engine, seal) {
|
block.lock().try_seal(&*self.engine, seal).or_else(|_| {
|
||||||
if let Ok(_) = chain.import_block(sealed.rlp_bytes()) {
|
|
||||||
trace!(target: "miner", "prepare_sealing: sealed internally and imported. leaving.");
|
|
||||||
} else {
|
|
||||||
warn!("prepare_sealing: ERROR: could not import internally sealed block. WTF?");
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
warn!("prepare_sealing: ERROR: try_seal failed when given internally generated seal. WTF?");
|
warn!("prepare_sealing: ERROR: try_seal failed when given internally generated seal. WTF?");
|
||||||
}
|
Err(None)
|
||||||
return;
|
})
|
||||||
} else {
|
} else {
|
||||||
trace!(target: "miner", "prepare_sealing: unable to generate seal internally");
|
trace!(target: "miner", "prepare_sealing: unable to generate seal internally");
|
||||||
|
Err(Some(block))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn seal_and_import_block_internally(&self, chain: &MiningBlockChainClient) -> bool {
|
||||||
|
let (block, _) = self.prepare_block(chain);
|
||||||
|
|
||||||
|
if !block.transactions().is_empty() {
|
||||||
|
if let Ok(sealed) = self.seal_block_internally(block) {
|
||||||
|
if chain.import_block(sealed.rlp_bytes()).is_ok() {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
false
|
||||||
|
}
|
||||||
|
|
||||||
|
fn prepare_work(&self, block: ClosedBlock, original_work_hash: Option<H256>) {
|
||||||
let (work, is_new) = {
|
let (work, is_new) = {
|
||||||
let mut sealing_work = self.sealing_work.lock();
|
let mut sealing_work = self.sealing_work.lock();
|
||||||
let last_work_hash = sealing_work.queue.peek_last_ref().map(|pb| pb.block().fields().header.hash());
|
let last_work_hash = sealing_work.queue.peek_last_ref().map(|pb| pb.block().fields().header.hash());
|
||||||
@ -386,6 +394,30 @@ impl Miner {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Prepares new block for sealing including top transactions from queue.
|
||||||
|
#[cfg_attr(feature="dev", allow(match_same_arms))]
|
||||||
|
#[cfg_attr(feature="dev", allow(cyclomatic_complexity))]
|
||||||
|
fn prepare_block_and_work(&self, chain: &MiningBlockChainClient) {
|
||||||
|
trace!(target: "miner", "prepare_sealing: entering");
|
||||||
|
|
||||||
|
let (block, original_work_hash) = self.prepare_block(chain);
|
||||||
|
|
||||||
|
let block = if !block.transactions().is_empty() {
|
||||||
|
let block_opt = self.seal_block_internally(block).map(|sealed|
|
||||||
|
match chain.import_block(sealed.rlp_bytes()) {
|
||||||
|
Ok(_) => trace!(target: "miner", "prepare_sealing: sealed internally and imported. leaving."),
|
||||||
|
_ => warn!("prepare_sealing: ERROR: could not import internally sealed block. WTF?"),
|
||||||
|
}
|
||||||
|
).err().unwrap_or(None);
|
||||||
|
if block_opt.is_none() { return; }
|
||||||
|
block_opt.unwrap()
|
||||||
|
} else {
|
||||||
|
block
|
||||||
|
};
|
||||||
|
|
||||||
|
self.prepare_work(block, original_work_hash);
|
||||||
|
}
|
||||||
|
|
||||||
fn update_gas_limit(&self, chain: &MiningBlockChainClient) {
|
fn update_gas_limit(&self, chain: &MiningBlockChainClient) {
|
||||||
let gas_limit = HeaderView::new(&chain.best_block_header()).gas_limit();
|
let gas_limit = HeaderView::new(&chain.best_block_header()).gas_limit();
|
||||||
let mut queue = self.transaction_queue.lock();
|
let mut queue = self.transaction_queue.lock();
|
||||||
@ -411,7 +443,7 @@ impl Miner {
|
|||||||
// | NOTE Code below requires transaction_queue and sealing_work locks. |
|
// | NOTE Code below requires transaction_queue and sealing_work locks. |
|
||||||
// | Make sure to release the locks before calling that method. |
|
// | Make sure to release the locks before calling that method. |
|
||||||
// --------------------------------------------------------------------------
|
// --------------------------------------------------------------------------
|
||||||
self.prepare_sealing(chain);
|
self.prepare_block_and_work(chain);
|
||||||
}
|
}
|
||||||
let mut sealing_block_last_request = self.sealing_block_last_request.lock();
|
let mut sealing_block_last_request = self.sealing_block_last_request.lock();
|
||||||
let best_number = chain.chain_info().best_block_number;
|
let best_number = chain.chain_info().best_block_number;
|
||||||
@ -804,7 +836,7 @@ impl MinerService for Miner {
|
|||||||
// | NOTE Code below requires transaction_queue and sealing_work locks. |
|
// | NOTE Code below requires transaction_queue and sealing_work locks. |
|
||||||
// | Make sure to release the locks before calling that method. |
|
// | Make sure to release the locks before calling that method. |
|
||||||
// --------------------------------------------------------------------------
|
// --------------------------------------------------------------------------
|
||||||
self.prepare_sealing(chain);
|
self.prepare_block_and_work(chain);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user