Parameter to allow user to force the sealing mechanism (#918)

* Allow block sealing mechanism to be forced, even when not mining.

* Fix deadlock in dispatch_transaction. Fix tests.

* Horrible workaround for transaction importing.

* Reduce tracing. Cleanups.

* Remove logging.

* Remove broken code inherited from dodgy implementation.

* pre-query tx queue nonce also if any

* remove outside nonce queries

* remove queue nonces
This commit is contained in:
Gav Wood
2016-04-11 11:52:33 -07:00
parent edf4735542
commit c48374dbc6
7 changed files with 38 additions and 17 deletions

View File

@@ -30,6 +30,7 @@ pub struct Miner {
transaction_queue: Mutex<TransactionQueue>,
// for sealing...
force_sealing: bool,
sealing_enabled: AtomicBool,
sealing_block_last_request: Mutex<u64>,
sealing_work: Mutex<UsingQueue<ClosedBlock>>,
@@ -42,6 +43,7 @@ impl Default for Miner {
fn default() -> Miner {
Miner {
transaction_queue: Mutex::new(TransactionQueue::new()),
force_sealing: false,
sealing_enabled: AtomicBool::new(false),
sealing_block_last_request: Mutex::new(0),
sealing_work: Mutex::new(UsingQueue::new(5)),
@@ -54,8 +56,17 @@ impl Default for Miner {
impl Miner {
/// Creates new instance of miner
pub fn new() -> Arc<Miner> {
Arc::new(Miner::default())
pub fn new(force_sealing: bool) -> Arc<Miner> {
Arc::new(Miner {
transaction_queue: Mutex::new(TransactionQueue::new()),
force_sealing: force_sealing,
sealing_enabled: AtomicBool::new(force_sealing),
sealing_block_last_request: Mutex::new(0),
sealing_work: Mutex::new(UsingQueue::new(5)),
gas_floor_target: RwLock::new(U256::zero()),
author: RwLock::new(Address::default()),
extra_data: RwLock::new(Vec::new()),
})
}
/// Get the author that we will seal blocks as.
@@ -241,7 +252,7 @@ impl MinerService for Miner {
if self.sealing_enabled.load(atomic::Ordering::Relaxed) {
let current_no = chain.chain_info().best_block_number;
let last_request = *self.sealing_block_last_request.lock().unwrap();
let should_disable_sealing = current_no > last_request && current_no - last_request > SEALING_TIMEOUT_IN_BLOCKS;
let should_disable_sealing = !self.force_sealing && current_no > last_request && current_no - last_request > SEALING_TIMEOUT_IN_BLOCKS;
if should_disable_sealing {
trace!(target: "miner", "Miner sleeping (current {}, last {})", current_no, last_request);

View File

@@ -383,19 +383,19 @@ impl TransactionQueue {
}
let vtx = try!(VerifiedTransaction::new(tx));
let account = fetch_account(&vtx.sender());
let client_account = fetch_account(&vtx.sender());
let cost = vtx.transaction.value + vtx.transaction.gas_price * vtx.transaction.gas;
if account.balance < cost {
if client_account.balance < cost {
trace!(target: "miner", "Dropping transaction without sufficient balance: {:?} ({} < {})",
vtx.hash(), account.balance, cost);
vtx.hash(), client_account.balance, cost);
return Err(Error::Transaction(TransactionError::InsufficientBalance {
cost: cost,
balance: account.balance
balance: client_account.balance
}));
}
self.import_tx(vtx, account.nonce).map_err(Error::Transaction)
self.import_tx(vtx, client_account.nonce).map_err(Error::Transaction)
}
/// Removes all transactions identified by hashes given in slice
@@ -1188,6 +1188,7 @@ mod test {
#[test]
fn should_replace_same_transaction_when_has_higher_fee() {
init_log();
// given
let mut txq = TransactionQueue::new();
let keypair = KeyPair::create().unwrap();
@@ -1264,7 +1265,7 @@ mod test {
#[test]
fn should_return_none_when_transaction_from_given_address_does_not_exist() {
// given
let mut txq = TransactionQueue::new();
let txq = TransactionQueue::new();
// then
assert_eq!(txq.last_nonce(&Address::default()), None);
@@ -1277,7 +1278,7 @@ mod test {
let tx = new_tx();
let from = tx.sender().unwrap();
let nonce = tx.nonce;
let details = |a: &Address| AccountDetails { nonce: nonce, balance: !U256::zero() };
let details = |_a: &Address| AccountDetails { nonce: nonce, balance: !U256::zero() };
// when
txq.add(tx, &details).unwrap();