From c6e3d40ec285011022da922a98ea9b7cdeb644db Mon Sep 17 00:00:00 2001 From: arkpar Date: Tue, 27 Jun 2017 14:17:32 +0200 Subject: [PATCH] --reseal-on-uncle --- ethcore/src/client/client.rs | 26 ++++++++++++++++++++++++++ ethcore/src/client/test_client.rs | 6 +++++- ethcore/src/client/traits.rs | 5 ++++- ethcore/src/miner/miner.rs | 11 +++++++---- parity/cli/mod.rs | 5 +++++ parity/cli/usage.txt | 3 +++ parity/configuration.rs | 1 + rpc/src/v1/tests/eth.rs | 1 + 8 files changed, 52 insertions(+), 6 deletions(-) diff --git a/ethcore/src/client/client.rs b/ethcore/src/client/client.rs index a42b5723ede..5771c89f41f 100644 --- a/ethcore/src/client/client.rs +++ b/ethcore/src/client/client.rs @@ -1652,6 +1652,32 @@ impl MiningBlockChainClient for Client { open_block } + fn reopen_block(&self, block: ClosedBlock) -> OpenBlock { + let engine = &*self.engine; + let mut block = block.reopen(engine); + let max_uncles = engine.maximum_uncle_count(); + if block.uncles().len() < max_uncles { + let chain = self.chain.read(); + let h = chain.best_block_hash(); + // Add new uncles + let uncles = chain + .find_uncle_headers(&h, engine.maximum_uncle_age()) + .unwrap_or_else(Vec::new); + + for uncle in uncles { + if !block.uncles().iter().any(|header| header.hash() == uncle.hash()) { + block.push_uncle(uncle).expect("pushing up to maximum_uncle_count; + push_uncle is not ok only if more than maximum_uncle_count is pushed; + so all push_uncle are Ok; + qed"); + if block.uncles().len() >= max_uncles { break } + } + } + + } + block + } + fn vm_factory(&self) -> &EvmFactory { &self.factories.vm } diff --git a/ethcore/src/client/test_client.rs b/ethcore/src/client/test_client.rs index 19c208b4590..b020a154738 100644 --- a/ethcore/src/client/test_client.rs +++ b/ethcore/src/client/test_client.rs @@ -43,7 +43,7 @@ use types::mode::Mode; use types::pruning_info::PruningInfo; use verification::queue::QueueInfo; -use block::{OpenBlock, SealedBlock}; +use block::{OpenBlock, SealedBlock, ClosedBlock}; use executive::Executed; use error::CallError; use trace::LocalizedTrace; @@ -379,6 +379,10 @@ impl MiningBlockChainClient for TestBlockChainClient { open_block } + fn reopen_block(&self, block: ClosedBlock) -> OpenBlock { + block.reopen(&*self.spec.engine) + } + fn vm_factory(&self) -> &EvmFactory { &self.vm_factory } diff --git a/ethcore/src/client/traits.rs b/ethcore/src/client/traits.rs index d6564261079..1be7ab174f3 100644 --- a/ethcore/src/client/traits.rs +++ b/ethcore/src/client/traits.rs @@ -19,7 +19,7 @@ use util::{U256, Address, H256, H2048, Bytes, Itertools}; use util::hashdb::DBValue; use blockchain::TreeRoute; use verification::queue::QueueInfo as BlockQueueInfo; -use block::{OpenBlock, SealedBlock}; +use block::{OpenBlock, SealedBlock, ClosedBlock}; use header::{BlockNumber}; use transaction::{LocalizedTransaction, PendingTransaction, SignedTransaction}; use transaction_import::TransactionImportResult; @@ -288,6 +288,9 @@ pub trait MiningBlockChainClient: BlockChainClient { extra_data: Bytes ) -> OpenBlock; + /// Reopens an OpenBlock and updates uncles. + fn reopen_block(&self, block: ClosedBlock) -> OpenBlock; + /// Returns EvmFactory. fn vm_factory(&self) -> &EvmFactory; diff --git a/ethcore/src/miner/miner.rs b/ethcore/src/miner/miner.rs index e5edc6d050f..5287cbff530 100644 --- a/ethcore/src/miner/miner.rs +++ b/ethcore/src/miner/miner.rs @@ -88,6 +88,8 @@ pub struct MinerOptions { pub reseal_on_external_tx: bool, /// Reseal on receipt of new local transactions. pub reseal_on_own_tx: bool, + /// Reseal when new uncle block has been imported. + pub reseal_on_uncle: bool, /// Minimum period between transaction-inspired reseals. pub reseal_min_period: Duration, /// Maximum period between blocks (enables force sealing after that). @@ -119,6 +121,7 @@ impl Default for MinerOptions { force_sealing: false, reseal_on_external_tx: false, reseal_on_own_tx: true, + reseal_on_uncle: false, tx_gas_limit: !U256::zero(), tx_queue_size: 1024, tx_queue_gas_limit: GasLimit::Auto, @@ -344,7 +347,7 @@ impl Miner { Some(old_block) => { trace!(target: "miner", "prepare_block: Already have previous work; updating and returning"); // add transactions to old_block - old_block.reopen(&*self.engine) + chain.reopen_block(old_block) } None => { // block not found - create it. @@ -363,7 +366,6 @@ impl Miner { let mut transactions_to_penalize = HashSet::new(); let block_number = open_block.block().fields().header.number(); - // TODO Push new uncles too. let mut tx_count: usize = 0; let tx_total = transactions.len(); for tx in transactions { @@ -1150,7 +1152,7 @@ impl MinerService for Miner { }) } - fn chain_new_blocks(&self, chain: &MiningBlockChainClient, _imported: &[H256], _invalid: &[H256], enacted: &[H256], retracted: &[H256]) { + fn chain_new_blocks(&self, chain: &MiningBlockChainClient, imported: &[H256], _invalid: &[H256], enacted: &[H256], retracted: &[H256]) { trace!(target: "miner", "chain_new_blocks"); // 1. We ignore blocks that were `imported` (because it means that they are not in canon-chain, and transactions @@ -1189,7 +1191,7 @@ impl MinerService for Miner { transaction_queue.remove_old(&fetch_account, time); } - if enacted.len() > 0 { + if enacted.len() > 0 || (imported.len() > 0 && self.options.reseal_on_uncle) { // -------------------------------------------------------------------------- // | NOTE Code below requires transaction_queue and sealing_work locks. | // | Make sure to release the locks before calling that method. | @@ -1308,6 +1310,7 @@ mod tests { force_sealing: false, reseal_on_external_tx: false, reseal_on_own_tx: true, + reseal_on_uncle: false, reseal_min_period: Duration::from_secs(5), reseal_max_period: Duration::from_secs(120), tx_gas_limit: !U256::zero(), diff --git a/parity/cli/mod.rs b/parity/cli/mod.rs index 5aea2600032..4dce99b93bd 100644 --- a/parity/cli/mod.rs +++ b/parity/cli/mod.rs @@ -250,6 +250,8 @@ usage! { or |c: &Config| otry!(c.mining).force_sealing.clone(), flag_reseal_on_txs: String = "own", or |c: &Config| otry!(c.mining).reseal_on_txs.clone(), + flag_reseal_on_uncle: bool = false, + or |c: &Config| otry!(c.mining).reseal_on_uncle.clone(), flag_reseal_min_period: u64 = 2000u64, or |c: &Config| otry!(c.mining).reseal_min_period.clone(), flag_reseal_max_period: u64 = 120000u64, @@ -524,6 +526,7 @@ struct Mining { author: Option, engine_signer: Option, force_sealing: Option, + reseal_on_uncle: Option, reseal_on_txs: Option, reseal_min_period: Option, reseal_max_period: Option, @@ -788,6 +791,7 @@ mod tests { flag_reseal_on_txs: "all".into(), flag_reseal_min_period: 4000u64, flag_reseal_max_period: 60000u64, + flag_reseal_on_uncle: false, flag_work_queue_size: 20usize, flag_tx_gas_limit: Some("6283184".into()), flag_tx_time_limit: Some(100u64), @@ -1012,6 +1016,7 @@ mod tests { engine_signer: Some("0xdeadbeefcafe0000000000000000000000000001".into()), force_sealing: Some(true), reseal_on_txs: Some("all".into()), + reseal_on_uncle: None, reseal_min_period: Some(4000), reseal_max_period: Some(60000), work_queue_size: None, diff --git a/parity/cli/usage.txt b/parity/cli/usage.txt index 40be1856f6d..5020f00badf 100644 --- a/parity/cli/usage.txt +++ b/parity/cli/usage.txt @@ -262,6 +262,9 @@ Sealing/Mining Options: ext - reseal only on a new external transaction; all - reseal on all new transactions (default: {flag_reseal_on_txs}). + --reseal-on-uncle Force the node to author new blocks when a new uncle + block is imported. + (default: {flag_reseal_on_uncle}) --reseal-min-period MS Specify the minimum time between reseals from incoming transactions. MS is time measured in milliseconds (default: {flag_reseal_min_period}). diff --git a/parity/configuration.rs b/parity/configuration.rs index adad91e1acf..346c7e5c726 100644 --- a/parity/configuration.rs +++ b/parity/configuration.rs @@ -522,6 +522,7 @@ impl Configuration { force_sealing: self.args.flag_force_sealing, reseal_on_external_tx: reseal.external, reseal_on_own_tx: reseal.own, + reseal_on_uncle: self.args.flag_reseal_on_uncle, tx_gas_limit: match self.args.flag_tx_gas_limit { Some(ref d) => to_u256(d)?, None => U256::max_value(), diff --git a/rpc/src/v1/tests/eth.rs b/rpc/src/v1/tests/eth.rs index 5f70271eeaa..8fc5dfe2bd8 100644 --- a/rpc/src/v1/tests/eth.rs +++ b/rpc/src/v1/tests/eth.rs @@ -57,6 +57,7 @@ fn miner_service(spec: &Spec, accounts: Arc) -> Arc { force_sealing: true, reseal_on_external_tx: true, reseal_on_own_tx: true, + reseal_on_uncle: false, tx_queue_size: 1024, tx_gas_limit: !U256::zero(), tx_queue_strategy: PrioritizationStrategy::GasPriceOnly,