Allow configuration of when to reseal blocks.

This commit is contained in:
Gav Wood 2016-06-27 17:23:54 +02:00
parent 1fdbfa14ad
commit 6c1802e412
7 changed files with 65 additions and 13 deletions

View File

@ -29,6 +29,27 @@ use spec::Spec;
use engine::Engine; use engine::Engine;
use miner::{MinerService, MinerStatus, TransactionQueue, AccountDetails, TransactionImportResult, TransactionOrigin}; use miner::{MinerService, MinerStatus, TransactionQueue, AccountDetails, TransactionImportResult, TransactionOrigin};
/// Configures the behaviour of the miner.
#[derive(Debug)]
pub struct MinerOptions {
/// Force the miner to reseal, even when nobody has asked for work.
pub force_sealing: bool,
/// Reseal on receipt of new external transactions.
pub reseal_on_external_tx: bool,
/// Reseal on receipt of new local transactions.
pub reseal_on_own_tx: bool,
}
impl Default for MinerOptions {
fn default() -> Self {
MinerOptions {
force_sealing: false,
reseal_on_external_tx: true,
reseal_on_own_tx: true,
}
}
}
/// Keeps track of transactions using priority queue and holds currently mined block. /// Keeps track of transactions using priority queue and holds currently mined block.
pub struct Miner { pub struct Miner {
// NOTE [ToDr] When locking always lock in this order! // NOTE [ToDr] When locking always lock in this order!
@ -36,7 +57,7 @@ pub struct Miner {
sealing_work: Mutex<UsingQueue<ClosedBlock>>, sealing_work: Mutex<UsingQueue<ClosedBlock>>,
// for sealing... // for sealing...
force_sealing: bool, options: MinerOptions,
sealing_enabled: AtomicBool, sealing_enabled: AtomicBool,
sealing_block_last_request: Mutex<u64>, sealing_block_last_request: Mutex<u64>,
gas_range_target: RwLock<(U256, U256)>, gas_range_target: RwLock<(U256, U256)>,
@ -52,7 +73,7 @@ impl Miner {
pub fn with_spec(spec: Spec) -> Miner { pub fn with_spec(spec: Spec) -> Miner {
Miner { Miner {
transaction_queue: Mutex::new(TransactionQueue::new()), transaction_queue: Mutex::new(TransactionQueue::new()),
force_sealing: false, options: Default::default(),
sealing_enabled: AtomicBool::new(false), sealing_enabled: AtomicBool::new(false),
sealing_block_last_request: Mutex::new(0), sealing_block_last_request: Mutex::new(0),
sealing_work: Mutex::new(UsingQueue::new(5)), sealing_work: Mutex::new(UsingQueue::new(5)),
@ -65,11 +86,11 @@ impl Miner {
} }
/// Creates new instance of miner /// Creates new instance of miner
pub fn new(force_sealing: bool, spec: Spec, accounts: Option<Arc<AccountProvider>>) -> Arc<Miner> { pub fn new(options: MinerOptions, spec: Spec, accounts: Option<Arc<AccountProvider>>) -> Arc<Miner> {
Arc::new(Miner { Arc::new(Miner {
transaction_queue: Mutex::new(TransactionQueue::new()), transaction_queue: Mutex::new(TransactionQueue::new()),
force_sealing: force_sealing, sealing_enabled: AtomicBool::new(options.force_sealing),
sealing_enabled: AtomicBool::new(force_sealing), options: options,
sealing_block_last_request: Mutex::new(0), sealing_block_last_request: Mutex::new(0),
sealing_work: Mutex::new(UsingQueue::new(5)), sealing_work: Mutex::new(UsingQueue::new(5)),
gas_range_target: RwLock::new((U256::zero(), U256::zero())), gas_range_target: RwLock::new((U256::zero(), U256::zero())),
@ -385,7 +406,7 @@ impl MinerService for Miner {
.map(|tx| transaction_queue.add(tx, &fetch_account, TransactionOrigin::External)) .map(|tx| transaction_queue.add(tx, &fetch_account, TransactionOrigin::External))
.collect() .collect()
}; };
if !results.is_empty() { if !results.is_empty() && self.options.reseal_on_external_tx {
self.update_sealing(chain); self.update_sealing(chain);
} }
results results
@ -420,7 +441,7 @@ impl MinerService for Miner {
import import
}; };
if imported.is_ok() { if imported.is_ok() && self.options.reseal_on_own_tx {
// Make sure to do it after transaction is imported and lock is droped. // Make sure to do it after transaction is imported and lock is droped.
// We need to create pending block and enable sealing // We need to create pending block and enable sealing
let prepared = self.enable_and_prepare_sealing(chain); let prepared = self.enable_and_prepare_sealing(chain);
@ -494,7 +515,7 @@ impl MinerService for Miner {
let current_no = chain.chain_info().best_block_number; let current_no = chain.chain_info().best_block_number;
let has_local_transactions = self.transaction_queue.lock().unwrap().has_local_pending_transactions(); let has_local_transactions = self.transaction_queue.lock().unwrap().has_local_pending_transactions();
let last_request = *self.sealing_block_last_request.lock().unwrap(); let last_request = *self.sealing_block_last_request.lock().unwrap();
let should_disable_sealing = !self.force_sealing let should_disable_sealing = !self.options.force_sealing
&& !has_local_transactions && !has_local_transactions
&& current_no > last_request && current_no > last_request
&& current_no - last_request > SEALING_TIMEOUT_IN_BLOCKS; && current_no - last_request > SEALING_TIMEOUT_IN_BLOCKS;

View File

@ -47,7 +47,7 @@ mod external;
mod transaction_queue; mod transaction_queue;
pub use self::transaction_queue::{TransactionQueue, AccountDetails, TransactionImportResult, TransactionOrigin}; pub use self::transaction_queue::{TransactionQueue, AccountDetails, TransactionImportResult, TransactionOrigin};
pub use self::miner::{Miner}; pub use self::miner::{Miner, MinerOptions};
pub use self::external::{ExternalMiner, ExternalMinerService}; pub use self::external::{ExternalMiner, ExternalMinerService};
use std::collections::BTreeMap; use std::collections::BTreeMap;

View File

@ -133,6 +133,12 @@ Sealing/Mining Options:
NOTE: MINING WILL NOT WORK WITHOUT THIS OPTION. NOTE: MINING WILL NOT WORK WITHOUT THIS OPTION.
--force-sealing Force the node to author new blocks as if it were --force-sealing Force the node to author new blocks as if it were
always sealing/mining. always sealing/mining.
--reseal-on-txs Specify which transactions should force the node
to reseal a block. One of:
none - never reseal on new transactions;
own - reseal only on a new local transaction;
ext - reseal only on a new external transaction;
all - reseal on all new transactions [default: all].
--usd-per-tx USD Amount of USD to be paid for a basic transaction --usd-per-tx USD Amount of USD to be paid for a basic transaction
[default: 0.005]. The minimum gas price is set [default: 0.005]. The minimum gas price is set
accordingly. accordingly.
@ -283,6 +289,7 @@ pub struct Args {
pub flag_signer_path: String, pub flag_signer_path: String,
pub flag_no_token: bool, pub flag_no_token: bool,
pub flag_force_sealing: bool, pub flag_force_sealing: bool,
pub flag_reseal_on_txs: String,
pub flag_author: Option<String>, pub flag_author: Option<String>,
pub flag_usd_per_tx: String, pub flag_usd_per_tx: String,
pub flag_usd_per_eth: String, pub flag_usd_per_eth: String,

View File

@ -27,6 +27,7 @@ use util::*;
use ethcore::account_provider::AccountProvider; use ethcore::account_provider::AccountProvider;
use util::network_settings::NetworkSettings; use util::network_settings::NetworkSettings;
use ethcore::client::{append_path, get_db_path, ClientConfig, Switch, VMType}; use ethcore::client::{append_path, get_db_path, ClientConfig, Switch, VMType};
use ethcore::miner::MinerOptions;
use ethcore::ethereum; use ethcore::ethereum;
use ethcore::spec::Spec; use ethcore::spec::Spec;
use ethsync::SyncConfig; use ethsync::SyncConfig;
@ -67,6 +68,21 @@ impl Configuration {
self.args.flag_maxpeers.unwrap_or(self.args.flag_peers) as u32 self.args.flag_maxpeers.unwrap_or(self.args.flag_peers) as u32
} }
pub fn miner_options(&self) -> MinerOptions {
let (own, ext) = match self.args.flag_reseal_on_txs.as_str() {
"none" => (false, false),
"own" => (true, false),
"ext" => (false, true),
"all" => (true, true),
x => die!("{}: Invalid value for --reseal option. Use --help for more information.", x)
};
MinerOptions {
force_sealing: self.args.flag_force_sealing,
reseal_on_external_tx: ext,
reseal_on_own_tx: own,
}
}
pub fn author(&self) -> Option<Address> { pub fn author(&self) -> Option<Address> {
self.args.flag_etherbase.as_ref() self.args.flag_etherbase.as_ref()
.or(self.args.flag_author.as_ref()) .or(self.args.flag_author.as_ref())

View File

@ -208,7 +208,7 @@ fn execute_client(conf: Configuration, spec: Spec, client_config: ClientConfig)
let account_service = Arc::new(conf.account_service()); let account_service = Arc::new(conf.account_service());
// Miner // Miner
let miner = Miner::new(conf.args.flag_force_sealing, conf.spec(), Some(account_service.clone())); let miner = Miner::new(conf.miner_options(), conf.spec(), Some(account_service.clone()));
miner.set_author(conf.author().unwrap_or_default()); miner.set_author(conf.author().unwrap_or_default());
miner.set_gas_floor_target(conf.gas_floor_target()); miner.set_gas_floor_target(conf.gas_floor_target());
miner.set_gas_ceil_target(conf.gas_ceil_target()); miner.set_gas_ceil_target(conf.gas_ceil_target());

View File

@ -24,7 +24,7 @@ use ethcore::spec::{Genesis, Spec};
use ethcore::block::Block; use ethcore::block::Block;
use ethcore::views::BlockView; use ethcore::views::BlockView;
use ethcore::ethereum; use ethcore::ethereum;
use ethcore::miner::{MinerService, ExternalMiner, Miner}; use ethcore::miner::{MinerOptions, MinerService, ExternalMiner, Miner};
use ethcore::account_provider::AccountProvider; use ethcore::account_provider::AccountProvider;
use devtools::RandomTempPath; use devtools::RandomTempPath;
use util::Hashable; use util::Hashable;
@ -49,7 +49,15 @@ fn sync_provider() -> Arc<TestSyncProvider> {
} }
fn miner_service(spec: Spec, accounts: Arc<AccountProvider>) -> Arc<Miner> { fn miner_service(spec: Spec, accounts: Arc<AccountProvider>) -> Arc<Miner> {
Miner::new(true, spec, Some(accounts)) Miner::new(
MinerOptions {
force_sealing: true,
reseal_on_external_tx: true,
reseal_on_own_tx: true,
},
spec,
Some(accounts)
)
} }
fn make_spec(chain: &BlockChain) -> Spec { fn make_spec(chain: &BlockChain) -> Spec {

View File

@ -44,7 +44,7 @@
//! let mut service = NetworkService::new(NetworkConfiguration::new()).unwrap(); //! let mut service = NetworkService::new(NetworkConfiguration::new()).unwrap();
//! service.start().unwrap(); //! service.start().unwrap();
//! let dir = env::temp_dir(); //! let dir = env::temp_dir();
//! let miner = Miner::new(false, ethereum::new_frontier(true), None); //! let miner = Miner::new(MinerOptions::default(), ethereum::new_frontier(true), None);
//! let client = Client::new( //! let client = Client::new(
//! ClientConfig::default(), //! ClientConfig::default(),
//! ethereum::new_frontier(true), //! ethereum::new_frontier(true),