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:
parent
edf4735542
commit
c48374dbc6
@ -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);
|
||||
|
@ -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();
|
||||
|
@ -152,6 +152,8 @@ API and Console Options:
|
||||
conjunction with --webapp-user.
|
||||
|
||||
Sealing/Mining Options:
|
||||
--force-sealing Force the node to author new blocks as if it were
|
||||
always sealing/mining.
|
||||
--usd-per-tx USD Amount of USD to be paid for a basic transaction
|
||||
[default: 0.005]. The minimum gas price is set
|
||||
accordingly.
|
||||
@ -239,6 +241,7 @@ struct Args {
|
||||
flag_webapp_interface: String,
|
||||
flag_webapp_user: Option<String>,
|
||||
flag_webapp_pass: Option<String>,
|
||||
flag_force_sealing: bool,
|
||||
flag_author: String,
|
||||
flag_usd_per_tx: String,
|
||||
flag_usd_per_eth: String,
|
||||
@ -657,7 +660,7 @@ impl Configuration {
|
||||
let client = service.client();
|
||||
|
||||
// Miner
|
||||
let miner = Miner::new();
|
||||
let miner = Miner::new(self.args.flag_force_sealing);
|
||||
miner.set_author(self.author());
|
||||
miner.set_gas_floor_target(self.gas_floor_target());
|
||||
miner.set_extra_data(self.extra_data());
|
||||
|
@ -26,6 +26,7 @@ use ethminer::{MinerService, AccountDetails};
|
||||
use jsonrpc_core::*;
|
||||
use util::numbers::*;
|
||||
use util::sha3::*;
|
||||
use util::bytes::{ToPretty};
|
||||
use util::rlp::{encode, UntrustedRlp, View};
|
||||
use ethcore::client::*;
|
||||
use ethcore::block::IsBlock;
|
||||
@ -191,9 +192,13 @@ impl<C, S, A, M, EM> EthClient<C, S, A, M, EM>
|
||||
|
||||
let import = {
|
||||
let client = take_weak!(self.client);
|
||||
take_weak!(self.miner).import_transactions(vec![signed_transaction], |a: &Address| AccountDetails {
|
||||
nonce: client.nonce(a),
|
||||
balance: client.balance(a),
|
||||
let miner = take_weak!(self.miner);
|
||||
|
||||
miner.import_transactions(vec![signed_transaction], |a: &Address| {
|
||||
AccountDetails {
|
||||
nonce: client.nonce(&a),
|
||||
balance: client.balance(&a),
|
||||
}
|
||||
})
|
||||
};
|
||||
|
||||
@ -499,6 +504,7 @@ impl<C, S, A, M, EM> Eth for EthClient<C, S, A, M, EM>
|
||||
data: request.data.map_or_else(Vec::new, |d| d.to_vec()),
|
||||
}.sign(&secret)
|
||||
};
|
||||
trace!(target: "miner", "send_transaction: dispatching tx: {}", encode(&signed_transaction).to_vec().pretty());
|
||||
self.dispatch_transaction(signed_transaction)
|
||||
},
|
||||
Err(_) => { to_value(&H256::zero()) }
|
||||
|
@ -1476,7 +1476,7 @@ mod tests {
|
||||
}
|
||||
|
||||
fn dummy_sync_with_peer(peer_latest_hash: H256) -> ChainSync {
|
||||
let mut sync = ChainSync::new(SyncConfig::default(), Miner::new());
|
||||
let mut sync = ChainSync::new(SyncConfig::default(), Miner::new(false));
|
||||
sync.peers.insert(0,
|
||||
PeerInfo {
|
||||
protocol_version: 0,
|
||||
|
@ -45,7 +45,7 @@
|
||||
//! let mut service = NetworkService::start(NetworkConfiguration::new()).unwrap();
|
||||
//! let dir = env::temp_dir();
|
||||
//! let client = Client::new(ClientConfig::default(), ethereum::new_frontier(), &dir, service.io().channel()).unwrap();
|
||||
//! let miner = Miner::new();
|
||||
//! let miner = Miner::new(false);
|
||||
//! EthSync::register(&mut service, SyncConfig::default(), client, miner);
|
||||
//! }
|
||||
//! ```
|
||||
|
@ -93,7 +93,7 @@ impl TestNet {
|
||||
for _ in 0..n {
|
||||
net.peers.push(TestPeer {
|
||||
chain: TestBlockChainClient::new(),
|
||||
sync: ChainSync::new(SyncConfig::default(), Miner::new()),
|
||||
sync: ChainSync::new(SyncConfig::default(), Miner::new(false)),
|
||||
queue: VecDeque::new(),
|
||||
});
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user