Merge pull request #771 from ethcore/tx_queue_timeout
Disable preparing work package if miners don't ask for it.
This commit is contained in:
commit
dcb23de65c
@ -233,11 +233,11 @@ impl BlockChainClient for TestBlockChainClient {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn prepare_sealing(&self, _author: Address, _gas_floor_target: U256, _extra_data: Bytes, _transactions: Vec<SignedTransaction>) -> Option<(ClosedBlock, HashSet<H256>)> {
|
fn prepare_sealing(&self, _author: Address, _gas_floor_target: U256, _extra_data: Bytes, _transactions: Vec<SignedTransaction>) -> Option<(ClosedBlock, HashSet<H256>)> {
|
||||||
unimplemented!()
|
None
|
||||||
}
|
}
|
||||||
|
|
||||||
fn try_seal(&self, _block: ClosedBlock, _seal: Vec<Bytes>) -> Result<SealedBlock, ClosedBlock> {
|
fn try_seal(&self, block: ClosedBlock, _seal: Vec<Bytes>) -> Result<SealedBlock, ClosedBlock> {
|
||||||
unimplemented!()
|
Err(block)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn block_header(&self, id: BlockId) -> Option<Bytes> {
|
fn block_header(&self, id: BlockId) -> Option<Bytes> {
|
||||||
|
@ -45,7 +45,6 @@
|
|||||||
//! assert_eq!(miner.status().transactions_in_pending_queue, 0);
|
//! assert_eq!(miner.status().transactions_in_pending_queue, 0);
|
||||||
//!
|
//!
|
||||||
//! // Check block for sealing
|
//! // Check block for sealing
|
||||||
//! miner.prepare_sealing(client.deref());
|
|
||||||
//! assert!(miner.sealing_block(client.deref()).lock().unwrap().is_some());
|
//! assert!(miner.sealing_block(client.deref()).lock().unwrap().is_some());
|
||||||
//! }
|
//! }
|
||||||
//! ```
|
//! ```
|
||||||
|
@ -34,6 +34,7 @@ pub struct Miner {
|
|||||||
|
|
||||||
// for sealing...
|
// for sealing...
|
||||||
sealing_enabled: AtomicBool,
|
sealing_enabled: AtomicBool,
|
||||||
|
sealing_block_last_request: Mutex<u64>,
|
||||||
sealing_block: Mutex<Option<ClosedBlock>>,
|
sealing_block: Mutex<Option<ClosedBlock>>,
|
||||||
gas_floor_target: RwLock<U256>,
|
gas_floor_target: RwLock<U256>,
|
||||||
author: RwLock<Address>,
|
author: RwLock<Address>,
|
||||||
@ -46,6 +47,7 @@ impl Default for Miner {
|
|||||||
Miner {
|
Miner {
|
||||||
transaction_queue: Mutex::new(TransactionQueue::new()),
|
transaction_queue: Mutex::new(TransactionQueue::new()),
|
||||||
sealing_enabled: AtomicBool::new(false),
|
sealing_enabled: AtomicBool::new(false),
|
||||||
|
sealing_block_last_request: Mutex::new(0),
|
||||||
sealing_block: Mutex::new(None),
|
sealing_block: Mutex::new(None),
|
||||||
gas_floor_target: RwLock::new(U256::zero()),
|
gas_floor_target: RwLock::new(U256::zero()),
|
||||||
author: RwLock::new(Address::default()),
|
author: RwLock::new(Address::default()),
|
||||||
@ -96,7 +98,7 @@ impl Miner {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Prepares new block for sealing including top transactions from queue.
|
/// Prepares new block for sealing including top transactions from queue.
|
||||||
pub fn prepare_sealing(&self, chain: &BlockChainClient) {
|
fn prepare_sealing(&self, chain: &BlockChainClient) {
|
||||||
let transactions = self.transaction_queue.lock().unwrap().top_transactions();
|
let transactions = self.transaction_queue.lock().unwrap().top_transactions();
|
||||||
let b = chain.prepare_sealing(
|
let b = chain.prepare_sealing(
|
||||||
self.author(),
|
self.author(),
|
||||||
@ -125,6 +127,8 @@ impl Miner {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const SEALING_TIMEOUT_IN_BLOCKS : u64 = 5;
|
||||||
|
|
||||||
impl MinerService for Miner {
|
impl MinerService for Miner {
|
||||||
|
|
||||||
fn clear_and_reset(&self, chain: &BlockChainClient) {
|
fn clear_and_reset(&self, chain: &BlockChainClient) {
|
||||||
@ -154,7 +158,17 @@ impl MinerService for Miner {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn update_sealing(&self, chain: &BlockChainClient) {
|
fn update_sealing(&self, chain: &BlockChainClient) {
|
||||||
if self.sealing_enabled.load(atomic::Ordering::Relaxed) {
|
let should_disable_sealing = {
|
||||||
|
let current_no = chain.chain_info().best_block_number;
|
||||||
|
let last_request = self.sealing_block_last_request.lock().unwrap();
|
||||||
|
let is_greater = current_no > *last_request;
|
||||||
|
is_greater && current_no - *last_request > SEALING_TIMEOUT_IN_BLOCKS
|
||||||
|
};
|
||||||
|
|
||||||
|
if should_disable_sealing {
|
||||||
|
self.sealing_enabled.store(false, atomic::Ordering::Relaxed);
|
||||||
|
*self.sealing_block.lock().unwrap() = None;
|
||||||
|
} else if self.sealing_enabled.load(atomic::Ordering::Relaxed) {
|
||||||
self.prepare_sealing(chain);
|
self.prepare_sealing(chain);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -162,9 +176,10 @@ impl MinerService for Miner {
|
|||||||
fn sealing_block(&self, chain: &BlockChainClient) -> &Mutex<Option<ClosedBlock>> {
|
fn sealing_block(&self, chain: &BlockChainClient) -> &Mutex<Option<ClosedBlock>> {
|
||||||
if self.sealing_block.lock().unwrap().is_none() {
|
if self.sealing_block.lock().unwrap().is_none() {
|
||||||
self.sealing_enabled.store(true, atomic::Ordering::Relaxed);
|
self.sealing_enabled.store(true, atomic::Ordering::Relaxed);
|
||||||
// TODO: Above should be on a timer that resets after two blocks have arrived without being asked for.
|
|
||||||
self.prepare_sealing(chain);
|
self.prepare_sealing(chain);
|
||||||
}
|
}
|
||||||
|
*self.sealing_block_last_request.lock().unwrap() = chain.chain_info().best_block_number;
|
||||||
&self.sealing_block
|
&self.sealing_block
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -249,3 +264,42 @@ impl MinerService for Miner {
|
|||||||
self.update_sealing(chain);
|
self.update_sealing(chain);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
mod tests {
|
||||||
|
|
||||||
|
use MinerService;
|
||||||
|
use super::{Miner};
|
||||||
|
use ethcore::client::{TestBlockChainClient, EachBlockWith};
|
||||||
|
|
||||||
|
// TODO [ToDr] To uncomment client is cleaned from mining stuff.
|
||||||
|
#[ignore]
|
||||||
|
#[test]
|
||||||
|
fn should_prepare_block_to_seal() {
|
||||||
|
// given
|
||||||
|
let client = TestBlockChainClient::default();
|
||||||
|
let miner = Miner::default();
|
||||||
|
|
||||||
|
// when
|
||||||
|
let res = miner.sealing_block(&client);
|
||||||
|
|
||||||
|
// then
|
||||||
|
assert!(res.lock().unwrap().is_some(), "Expected closed block");
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn should_reset_seal_after_couple_of_blocks() {
|
||||||
|
// given
|
||||||
|
let client = TestBlockChainClient::default();
|
||||||
|
let miner = Miner::default();
|
||||||
|
let res = miner.sealing_block(&client);
|
||||||
|
// TODO [ToDr] Uncomment after fixing TestBlockChainClient
|
||||||
|
// assert!(res.lock().unwrap().is_some(), "Expected closed block");
|
||||||
|
|
||||||
|
// when
|
||||||
|
client.add_blocks(10, EachBlockWith::Uncle);
|
||||||
|
|
||||||
|
// then
|
||||||
|
assert!(res.lock().unwrap().is_none(), "Expected to remove sealed block");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user