Skip to content
This repository has been archived by the owner on Nov 6, 2020. It is now read-only.

Disable preparing work package if miners don't ask for it. #771

Merged
merged 6 commits into from
Mar 20, 2016
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
6 changes: 3 additions & 3 deletions ethcore/src/client/test_client.rs
Original file line number Diff line number Diff line change
Expand Up @@ -219,11 +219,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>)> {
unimplemented!()
None
}

fn try_seal(&self, _block: ClosedBlock, _seal: Vec<Bytes>) -> Result<SealedBlock, ClosedBlock> {
unimplemented!()
fn try_seal(&self, block: ClosedBlock, _seal: Vec<Bytes>) -> Result<SealedBlock, ClosedBlock> {
Err(block)
}

fn block_header(&self, id: BlockId) -> Option<Bytes> {
Expand Down
1 change: 0 additions & 1 deletion miner/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,6 @@
//! assert_eq!(miner.status().transactions_in_pending_queue, 0);
//!
//! // Check block for sealing
//! miner.prepare_sealing(client.deref());
//! assert!(miner.sealing_block(client.deref()).lock().unwrap().is_some());
//! }
//! ```
Expand Down
60 changes: 57 additions & 3 deletions miner/src/miner.rs
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ pub struct Miner {

// for sealing...
sealing_enabled: AtomicBool,
sealing_block_last_request: Mutex<u64>,
sealing_block: Mutex<Option<ClosedBlock>>,
gas_floor_target: RwLock<U256>,
author: RwLock<Address>,
Expand All @@ -46,6 +47,7 @@ impl Default for Miner {
Miner {
transaction_queue: Mutex::new(TransactionQueue::new()),
sealing_enabled: AtomicBool::new(false),
sealing_block_last_request: Mutex::new(0),
sealing_block: Mutex::new(None),
gas_floor_target: RwLock::new(U256::zero()),
author: RwLock::new(Address::default()),
Expand Down Expand Up @@ -96,7 +98,7 @@ impl Miner {
}

/// 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 b = chain.prepare_sealing(
self.author(),
Expand Down Expand Up @@ -125,6 +127,8 @@ impl Miner {
}
}

const SEALING_TIMEOUT_IN_BLOCKS : u64 = 5;

impl MinerService for Miner {

fn clear_and_reset(&self, chain: &BlockChainClient) {
Expand Down Expand Up @@ -154,17 +158,28 @@ impl MinerService for Miner {
}

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);
}
}

fn sealing_block(&self, chain: &BlockChainClient) -> &Mutex<Option<ClosedBlock>> {
if self.sealing_block.lock().unwrap().is_none() {
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.sealing_block_last_request.lock().unwrap() = chain.chain_info().best_block_number;
&self.sealing_block
}

Expand Down Expand Up @@ -249,3 +264,42 @@ impl MinerService for Miner {
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");
}
}