HTTP work notifier

This commit is contained in:
arkpar 2016-06-29 20:04:52 +02:00
parent 7c27f9dfed
commit 5958c87e56
8 changed files with 42 additions and 18 deletions

7
Cargo.lock generated
View File

@ -261,6 +261,7 @@ dependencies = [
"ethjson 0.1.0", "ethjson 0.1.0",
"ethstore 0.1.0", "ethstore 0.1.0",
"heapsize 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)", "heapsize 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)",
"hyper 0.9.4 (git+https://github.com/ethcore/hyper)",
"lazy_static 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", "lazy_static 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
"log 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
"num_cpus 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)", "num_cpus 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)",
@ -547,7 +548,7 @@ dependencies = [
[[package]] [[package]]
name = "hyper" name = "hyper"
version = "0.9.4" version = "0.9.4"
source = "git+https://github.com/ethcore/hyper#7ccfcb2aa7e6aa6300efa8cebd6a0e6ce55582ea" source = "git+https://github.com/ethcore/hyper#9e346c1d4bc30cd4142dea9d8a0b117d30858ca4"
dependencies = [ dependencies = [
"cookie 0.2.4 (registry+https://github.com/rust-lang/crates.io-index)", "cookie 0.2.4 (registry+https://github.com/rust-lang/crates.io-index)",
"httparse 1.1.2 (registry+https://github.com/rust-lang/crates.io-index)", "httparse 1.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
@ -556,7 +557,7 @@ dependencies = [
"mime 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", "mime 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
"rotor 0.6.3 (git+https://github.com/ethcore/rotor)", "rotor 0.6.3 (git+https://github.com/ethcore/rotor)",
"rustc-serialize 0.3.19 (registry+https://github.com/rust-lang/crates.io-index)", "rustc-serialize 0.3.19 (registry+https://github.com/rust-lang/crates.io-index)",
"spmc 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", "spmc 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
"time 0.1.35 (registry+https://github.com/rust-lang/crates.io-index)", "time 0.1.35 (registry+https://github.com/rust-lang/crates.io-index)",
"traitobject 0.0.1 (registry+https://github.com/rust-lang/crates.io-index)", "traitobject 0.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
"typeable 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", "typeable 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
@ -1222,7 +1223,7 @@ dependencies = [
[[package]] [[package]]
name = "spmc" name = "spmc"
version = "0.2.0" version = "0.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]] [[package]]

View File

@ -32,6 +32,10 @@ bloomchain = "0.1"
rayon = "0.3.1" rayon = "0.3.1"
ethstore = { path = "../ethstore" } ethstore = { path = "../ethstore" }
[dependencies.hyper]
git = "https://github.com/ethcore/hyper"
default-features = false
[features] [features]
jit = ["evmjit"] jit = ["evmjit"]
evm-debug = [] evm-debug = []

View File

@ -14,9 +14,7 @@
// You should have received a copy of the GNU General Public License // You should have received a copy of the GNU General Public License
// along with Parity. If not, see <http://www.gnu.org/licenses/>. // along with Parity. If not, see <http://www.gnu.org/licenses/>.
extern crate ethash; use ethash::{quick_get_difficulty, EthashManager, H256 as EH256};
use self::ethash::{quick_get_difficulty, EthashManager, H256 as EH256};
use common::*; use common::*;
use block::*; use block::*;
use spec::CommonParams; use spec::CommonParams;

View File

@ -91,6 +91,8 @@ extern crate ethjson;
extern crate bloomchain; extern crate bloomchain;
#[macro_use] extern crate ethcore_ipc as ipc; #[macro_use] extern crate ethcore_ipc as ipc;
extern crate rayon; extern crate rayon;
extern crate hyper;
extern crate ethash;
pub extern crate ethstore; pub extern crate ethstore;
#[cfg(test)] extern crate ethcore_devtools as devtools; #[cfg(test)] extern crate ethcore_devtools as devtools;

View File

@ -28,6 +28,7 @@ use receipt::{Receipt};
use spec::Spec; 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};
use miner::work_notify::WorkPoster;
/// Different possible definitions for pending transaction set. /// Different possible definitions for pending transaction set.
#[derive(Debug)] #[derive(Debug)]
@ -90,6 +91,7 @@ pub struct Miner {
spec: Spec, spec: Spec,
accounts: Option<Arc<AccountProvider>>, accounts: Option<Arc<AccountProvider>>,
work_poster: Option<WorkPoster>,
} }
impl Miner { impl Miner {
@ -106,14 +108,16 @@ impl Miner {
extra_data: RwLock::new(Vec::new()), extra_data: RwLock::new(Vec::new()),
accounts: None, accounts: None,
spec: spec, spec: spec,
work_poster: None,
} }
} }
/// Creates new instance of miner /// Creates new instance of miner
pub fn new(options: MinerOptions, spec: Spec, accounts: Option<Arc<AccountProvider>>) -> Arc<Miner> { pub fn new(options: MinerOptions, spec: Spec, accounts: Option<Arc<AccountProvider>>) -> Arc<Miner> {
let work_poster = if !options.new_work_notify.is_empty() { Some(WorkPoster::new(&options.new_work_notify)) } else { None };
Arc::new(Miner { Arc::new(Miner {
transaction_queue: Mutex::new(TransactionQueue::with_limits(options.tx_queue_size, options.tx_gas_limit)), transaction_queue: Mutex::new(TransactionQueue::with_limits(options.tx_queue_size, options.tx_gas_limit)),
sealing_enabled: AtomicBool::new(options.force_sealing), sealing_enabled: AtomicBool::new(options.force_sealing || !options.new_work_notify.is_empty()),
options: options, 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)),
@ -122,6 +126,7 @@ impl Miner {
extra_data: RwLock::new(Vec::new()), extra_data: RwLock::new(Vec::new()),
accounts: accounts, accounts: accounts,
spec: spec, spec: spec,
work_poster: work_poster,
}) })
} }
@ -129,6 +134,10 @@ impl Miner {
self.spec.engine.deref() self.spec.engine.deref()
} }
fn forced_sealing(&self) -> bool {
self.options.force_sealing || !self.options.new_work_notify.is_empty()
}
/// Prepares new block for sealing including top transactions from queue. /// Prepares new block for sealing including top transactions from queue.
#[cfg_attr(feature="dev", allow(match_same_arms))] #[cfg_attr(feature="dev", allow(match_same_arms))]
#[cfg_attr(feature="dev", allow(cyclomatic_complexity))] #[cfg_attr(feature="dev", allow(cyclomatic_complexity))]
@ -230,13 +239,22 @@ impl Miner {
} }
} }
let work = {
let mut sealing_work = self.sealing_work.lock().unwrap(); let mut sealing_work = self.sealing_work.lock().unwrap();
if sealing_work.peek_last_ref().map_or(true, |pb| pb.block().fields().header.hash() != block.block().fields().header.hash()) { let work = if sealing_work.peek_last_ref().map_or(true, |pb| pb.block().fields().header.hash() != block.block().fields().header.hash()) {
trace!(target: "miner", "Pushing a new, refreshed or borrowed pending {}...", block.block().fields().header.hash()); trace!(target: "miner", "Pushing a new, refreshed or borrowed pending {}...", block.block().fields().header.hash());
let pow_hash = block.block().fields().header.hash();
let number = block.block().fields().header.number();
let difficulty = *block.block().fields().header.difficulty();
sealing_work.push(block); sealing_work.push(block);
} Some((pow_hash, difficulty, number))
} else {
None
};
trace!(target: "miner", "prepare_sealing: leaving (last={:?})", sealing_work.peek_last_ref().map(|b| b.block().fields().header.hash())); trace!(target: "miner", "prepare_sealing: leaving (last={:?})", sealing_work.peek_last_ref().map(|b| b.block().fields().header.hash()));
work
};
work.map(|(pow_hash, difficulty, number)| self.work_poster.as_ref().map(|ref p| p.notify(pow_hash, difficulty, number)));
} }
fn update_gas_limit(&self, chain: &MiningBlockChainClient) { fn update_gas_limit(&self, chain: &MiningBlockChainClient) {
@ -552,7 +570,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.options.force_sealing let should_disable_sealing = !self.forced_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

@ -45,6 +45,7 @@
mod miner; mod miner;
mod external; mod external;
mod transaction_queue; mod transaction_queue;
mod work_notify;
pub use self::transaction_queue::{TransactionQueue, AccountDetails, TransactionImportResult, TransactionOrigin}; pub use self::transaction_queue::{TransactionQueue, AccountDetails, TransactionImportResult, TransactionOrigin};
pub use self::miner::{Miner, MinerOptions, PendingSet}; pub use self::miner::{Miner, MinerOptions, PendingSet};

View File

@ -313,7 +313,7 @@ pub struct Args {
pub flag_gas_cap: String, pub flag_gas_cap: String,
pub flag_extra_data: Option<String>, pub flag_extra_data: Option<String>,
pub flag_tx_queue_size: usize, pub flag_tx_queue_size: usize,
pub flag_work_notify: Option<String>, pub flag_notify_work: Option<String>,
pub flag_logging: Option<String>, pub flag_logging: Option<String>,
pub flag_version: bool, pub flag_version: bool,
pub flag_from: String, pub flag_from: String,

View File

@ -83,8 +83,8 @@ impl Configuration {
) )
} }
pub fn work_notify(&self) -> Vec<String> { fn work_notify(&self) -> Vec<String> {
self.args.flag_work_notify.as_ref().map_or_else(Vec::new, |s| s.split(',').map(|s| s.to_owned()).collect()) self.args.flag_notify_work.as_ref().map_or_else(Vec::new, |s| s.split(',').map(|s| s.to_owned()).collect())
} }
pub fn miner_options(&self) -> MinerOptions { pub fn miner_options(&self) -> MinerOptions {