From 1fdb033db4f9f62f2ef153272cc7fdbe76a10abf Mon Sep 17 00:00:00 2001 From: Arkadiy Paronyan Date: Wed, 12 Oct 2016 17:33:59 +0200 Subject: [PATCH] Backports to beta (#2592) * TX queue gas limit config and allow local transactions over the gas limit (#2553) * Gas limit config; Allow local transactions over the limit * Fix typo [ci:skip] * v1.3.7 --- Cargo.lock | 26 ++++++++++++------------- Cargo.toml | 2 +- ethcore/src/miner/miner.rs | 27 +++++++++++++++++++++++--- ethcore/src/miner/mod.rs | 2 +- ethcore/src/miner/transaction_queue.rs | 26 ++++++++++++++++++++----- nsis/installer.nsi | 2 +- parity/cli.rs | 5 +++++ parity/configuration.rs | 3 ++- parity/helpers.rs | 10 +++++++++- rpc/src/v1/tests/eth.rs | 3 ++- util/Cargo.toml | 2 +- 11 files changed, 80 insertions(+), 28 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 3c67ba21f..0ad729658 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1,6 +1,6 @@ [root] name = "parity" -version = "1.3.6" +version = "1.3.7" dependencies = [ "ansi_term 0.7.2 (registry+https://github.com/rust-lang/crates.io-index)", "clippy 0.0.80 (registry+https://github.com/rust-lang/crates.io-index)", @@ -20,7 +20,7 @@ dependencies = [ "ethcore-logger 1.3.0", "ethcore-rpc 1.3.0", "ethcore-signer 1.3.0", - "ethcore-util 1.3.6", + "ethcore-util 1.3.7", "ethsync 1.3.0", "fdlimit 0.1.0", "hyper 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)", @@ -270,7 +270,7 @@ dependencies = [ "ethcore-ipc 1.3.0", "ethcore-ipc-codegen 1.3.0", "ethcore-ipc-nano 1.3.0", - "ethcore-util 1.3.6", + "ethcore-util 1.3.7", "ethjson 0.1.0", "ethstore 0.1.0", "evmjit 1.3.0", @@ -294,7 +294,7 @@ version = "1.3.0" dependencies = [ "clippy 0.0.80 (registry+https://github.com/rust-lang/crates.io-index)", "ethcore-rpc 1.3.0", - "ethcore-util 1.3.6", + "ethcore-util 1.3.7", "hyper 0.9.4 (git+https://github.com/ethcore/hyper)", "jsonrpc-core 2.1.1 (registry+https://github.com/rust-lang/crates.io-index)", "jsonrpc-http-server 6.1.0 (git+https://github.com/ethcore/jsonrpc-http-server.git)", @@ -336,7 +336,7 @@ name = "ethcore-ipc" version = "1.3.0" dependencies = [ "ethcore-devtools 1.3.0", - "ethcore-util 1.3.6", + "ethcore-util 1.3.7", "nanomsg 0.5.1 (git+https://github.com/ethcore/nanomsg.rs.git)", "semver 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -381,7 +381,7 @@ dependencies = [ "ethcore-ipc 1.3.0", "ethcore-ipc-codegen 1.3.0", "ethcore-ipc-nano 1.3.0", - "ethcore-util 1.3.6", + "ethcore-util 1.3.7", "log 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)", "nanomsg 0.5.1 (git+https://github.com/ethcore/nanomsg.rs.git)", "semver 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", @@ -393,7 +393,7 @@ name = "ethcore-logger" version = "1.3.0" dependencies = [ "env_logger 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)", - "ethcore-util 1.3.6", + "ethcore-util 1.3.7", "isatty 0.1.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)", @@ -408,7 +408,7 @@ dependencies = [ "ansi_term 0.7.2 (registry+https://github.com/rust-lang/crates.io-index)", "ethcore-devtools 1.3.0", "ethcore-io 1.3.0", - "ethcore-util 1.3.6", + "ethcore-util 1.3.7", "igd 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)", "libc 0.2.12 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)", @@ -432,7 +432,7 @@ dependencies = [ "ethcore-devtools 1.3.0", "ethcore-io 1.3.0", "ethcore-ipc 1.3.0", - "ethcore-util 1.3.6", + "ethcore-util 1.3.7", "ethjson 0.1.0", "ethsync 1.3.0", "json-ipc-server 0.2.4 (git+https://github.com/ethcore/json-ipc-server.git?branch=beta)", @@ -455,7 +455,7 @@ dependencies = [ "env_logger 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)", "ethcore-io 1.3.0", "ethcore-rpc 1.3.0", - "ethcore-util 1.3.6", + "ethcore-util 1.3.7", "jsonrpc-core 2.1.1 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)", "parity-dapps-signer 1.4.0 (git+https://github.com/ethcore/parity-ui.git)", @@ -466,7 +466,7 @@ dependencies = [ [[package]] name = "ethcore-util" -version = "1.3.6" +version = "1.3.7" dependencies = [ "ansi_term 0.7.2 (registry+https://github.com/rust-lang/crates.io-index)", "arrayvec 0.3.16 (registry+https://github.com/rust-lang/crates.io-index)", @@ -499,7 +499,7 @@ dependencies = [ name = "ethjson" version = "0.1.0" dependencies = [ - "ethcore-util 1.3.6", + "ethcore-util 1.3.7", "rustc-serialize 0.3.19 (registry+https://github.com/rust-lang/crates.io-index)", "serde 0.7.9 (registry+https://github.com/rust-lang/crates.io-index)", "serde_codegen 0.7.9 (registry+https://github.com/rust-lang/crates.io-index)", @@ -547,7 +547,7 @@ dependencies = [ "ethcore-ipc-codegen 1.3.0", "ethcore-ipc-nano 1.3.0", "ethcore-network 1.3.0", - "ethcore-util 1.3.6", + "ethcore-util 1.3.7", "heapsize 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)", "parking_lot 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)", diff --git a/Cargo.toml b/Cargo.toml index 85f868672..63f7b2e9a 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,7 +1,7 @@ [package] description = "Ethcore client." name = "parity" -version = "1.3.6" +version = "1.3.7" license = "GPL-3.0" authors = ["Ethcore "] build = "build.rs" diff --git a/ethcore/src/miner/miner.rs b/ethcore/src/miner/miner.rs index e55d8f709..a18f1e3cb 100644 --- a/ethcore/src/miner/miner.rs +++ b/ethcore/src/miner/miner.rs @@ -48,6 +48,17 @@ pub enum PendingSet { SealingOrElseQueue, } +/// Type of the gas limit to apply to the transaction queue. +#[derive(Debug, PartialEq)] +pub enum GasLimit { + /// Depends on the block gas limit and is updated with every block. + Auto, + /// No limit. + None, + /// Set to a fixed gas value. + Fixed(U256), +} + /// Configures the behaviour of the miner. #[derive(Debug, PartialEq)] pub struct MinerOptions { @@ -73,6 +84,8 @@ pub struct MinerOptions { pub work_queue_size: usize, /// Can we submit two different solutions for the same block and expect both to result in an import? pub enable_resubmission: bool, + /// Global gas limit for all transaction in the queue except for local and retracted. + pub tx_queue_gas_limit: GasLimit, } impl Default for MinerOptions { @@ -89,6 +102,7 @@ impl Default for MinerOptions { reseal_min_period: Duration::from_secs(2), work_queue_size: 20, enable_resubmission: true, + tx_queue_gas_limit: GasLimit::Auto, } } } @@ -210,8 +224,12 @@ impl Miner { /// Creates new instance of miner pub fn new(options: MinerOptions, gas_pricer: GasPricer, spec: &Spec, accounts: Option>) -> Arc { let work_poster = if !options.new_work_notify.is_empty() { Some(WorkPoster::new(&options.new_work_notify)) } else { None }; + let gas_limit = match options.tx_queue_gas_limit { + GasLimit::Fixed(ref limit) => *limit, + _ => !U256::zero(), + }; let txq = Arc::new(Mutex::new(TransactionQueue::with_limits( - options.tx_queue_strategy, options.tx_queue_size, !U256::zero(), options.tx_gas_limit + options.tx_queue_strategy, options.tx_queue_size, gas_limit, options.tx_gas_limit ))); Arc::new(Miner { transaction_queue: txq, @@ -402,8 +420,10 @@ impl Miner { let gas_limit = HeaderView::new(&chain.best_block_header()).gas_limit(); let mut queue = self.transaction_queue.lock(); queue.set_gas_limit(gas_limit); - // Set total qx queue gas limit to be 2x the block gas limit. - queue.set_total_gas_limit(gas_limit << 1); + if let GasLimit::Auto = self.options.tx_queue_gas_limit { + // Set total tx queue gas limit to be 2x the block gas limit. + queue.set_total_gas_limit(gas_limit << 1); + } } /// Returns true if we had to prepare new pending block @@ -1023,6 +1043,7 @@ mod tests { tx_gas_limit: !U256::zero(), tx_queue_size: 1024, tx_queue_strategy: PrioritizationStrategy::GasFactorAndGasPrice, + tx_queue_gas_limit: GasLimit::None, pending_set: PendingSet::AlwaysSealing, work_queue_size: 5, enable_resubmission: true, diff --git a/ethcore/src/miner/mod.rs b/ethcore/src/miner/mod.rs index ad00d9f7d..5fe8dbf44 100644 --- a/ethcore/src/miner/mod.rs +++ b/ethcore/src/miner/mod.rs @@ -48,7 +48,7 @@ mod work_notify; mod price_info; pub use self::transaction_queue::{TransactionQueue, PrioritizationStrategy, AccountDetails, TransactionOrigin}; -pub use self::miner::{Miner, MinerOptions, PendingSet, GasPricer, GasPriceCalibratorOptions}; +pub use self::miner::{Miner, MinerOptions, PendingSet, GasPricer, GasPriceCalibratorOptions, GasLimit}; pub use self::external::{ExternalMiner, ExternalMinerService}; pub use client::TransactionImportResult; diff --git a/ethcore/src/miner/transaction_queue.rs b/ethcore/src/miner/transaction_queue.rs index 1b0c14a5e..bfbe2c645 100644 --- a/ethcore/src/miner/transaction_queue.rs +++ b/ethcore/src/miner/transaction_queue.rs @@ -310,7 +310,9 @@ impl TransactionSet { let r = gas.overflowing_add(order.gas); if r.1 { return false } gas = r.0; - count <= self.limit && gas <= self.gas_limit + // Own and retracted transactions are allowed to go above the gas limit, bot not above the count limit. + (gas <= self.gas_limit || order.origin == TransactionOrigin::Local || order.origin == TransactionOrigin::RetractedBlock) && + count <= self.limit }) .map(|order| by_hash.get(&order.hash) .expect("All transactions in `self.by_priority` and `self.by_address` are kept in sync with `by_hash`.")) @@ -1757,13 +1759,27 @@ mod test { #[test] fn should_limit_by_gas() { let mut txq = TransactionQueue::with_limits(PrioritizationStrategy::GasPriceOnly, 100, default_gas_val() * U256::from(2), !U256::zero()); - let (tx1, _) = new_txs_with_gas_price_diff(U256::from(4), U256::from(1)); - let (tx3, _) = new_txs_with_gas_price_diff(U256::from(4), U256::from(2)); - txq.add(tx1.clone(), &default_nonce, TransactionOrigin::External).unwrap(); - txq.add(tx3.clone(), &default_nonce, TransactionOrigin::External).unwrap(); + let (tx1, tx2) = new_txs_with_gas_price_diff(U256::from(1), U256::from(1)); + let (tx3, tx4) = new_txs_with_gas_price_diff(U256::from(1), U256::from(2)); + txq.add(tx1.clone(), &default_nonce, TransactionOrigin::External).ok(); + txq.add(tx2.clone(), &default_nonce, TransactionOrigin::External).ok(); + txq.add(tx3.clone(), &default_nonce, TransactionOrigin::External).ok(); + txq.add(tx4.clone(), &default_nonce, TransactionOrigin::External).ok(); assert_eq!(txq.status().pending, 2); } + #[test] + fn should_keep_own_transactions_above_gas_limit() { + let mut txq = TransactionQueue::with_limits(PrioritizationStrategy::GasPriceOnly, 100, default_gas_val() * U256::from(2), !U256::zero()); + let (tx1, tx2) = new_txs_with_gas_price_diff(U256::from(1), U256::from(1)); + let (tx3, tx4) = new_txs_with_gas_price_diff(U256::from(1), U256::from(2)); + txq.add(tx1.clone(), &default_nonce, TransactionOrigin::Local).unwrap(); + txq.add(tx2.clone(), &default_nonce, TransactionOrigin::Local).unwrap(); + txq.add(tx3.clone(), &default_nonce, TransactionOrigin::Local).unwrap(); + txq.add(tx4.clone(), &default_nonce, TransactionOrigin::Local).unwrap(); + assert_eq!(txq.status().pending, 4); + } + #[test] fn should_drop_transactions_with_old_nonces() { let mut txq = TransactionQueue::default(); diff --git a/nsis/installer.nsi b/nsis/installer.nsi index 31f7a8d4a..80a558883 100644 --- a/nsis/installer.nsi +++ b/nsis/installer.nsi @@ -4,7 +4,7 @@ !define DESCRIPTION "Fast, light, robust Ethereum implementation" !define VERSIONMAJOR 1 !define VERSIONMINOR 3 -!define VERSIONBUILD 6 +!define VERSIONBUILD 7 !addplugindir .\ diff --git a/parity/cli.rs b/parity/cli.rs index db44dbe80..0385828ea 100644 --- a/parity/cli.rs +++ b/parity/cli.rs @@ -200,6 +200,10 @@ Sealing/Mining Options: gas_price - Prioritize txs with high gas price; gas_factor - Prioritize txs using gas price and gas limit ratio [default: gas_factor]. + --tx-queue-gas LIMIT Maximum amount of total gas for external transactions in + the queue. LIMIT can be either an amount of gas or + 'auto' or 'off'. 'auto' sets the limit to be 2x + the current block gas limit. [default: auto]. --remove-solved Move solved blocks from the work package queue instead of cloning them. This gives a slightly faster import speed, but means that extra solutions @@ -379,6 +383,7 @@ pub struct Args { pub flag_extra_data: Option, pub flag_tx_queue_size: usize, pub flag_tx_queue_strategy: String, + pub flag_tx_queue_gas: String, pub flag_notify_work: Option, pub flag_logging: Option, pub flag_version: bool, diff --git a/parity/configuration.rs b/parity/configuration.rs index 53fef8a25..eac1baff1 100644 --- a/parity/configuration.rs +++ b/parity/configuration.rs @@ -31,7 +31,7 @@ use rpc::{IpcConfiguration, HttpConfiguration}; use ethcore_rpc::NetworkSettings; use cache::CacheConfig; use helpers::{to_duration, to_mode, to_block_id, to_u256, to_pending_set, to_price, replace_home, -geth_ipc_path, parity_ipc_path, to_bootnodes, to_addresses, to_address}; +geth_ipc_path, parity_ipc_path, to_bootnodes, to_addresses, to_address, to_gas_limit}; use params::{ResealPolicy, AccountsConfig, GasPricerConfig, MinerExtras}; use ethcore_logger::Config as LogConfig; use dir::Directories; @@ -342,6 +342,7 @@ impl Configuration { }, tx_queue_size: self.args.flag_tx_queue_size, tx_queue_strategy: try!(self.transaction_queue_strategy()), + tx_queue_gas_limit: try!(to_gas_limit(&self.args.flag_tx_queue_gas)), pending_set: try!(to_pending_set(&self.args.flag_relay_set)), reseal_min_period: Duration::from_millis(self.args.flag_reseal_min_period), work_queue_size: self.args.flag_work_queue_size, diff --git a/parity/helpers.rs b/parity/helpers.rs index d0688d3de..15539881f 100644 --- a/parity/helpers.rs +++ b/parity/helpers.rs @@ -22,7 +22,7 @@ use std::fs::File; use util::{clean_0x, U256, Uint, Address, path, H256, CompactionProfile}; use util::journaldb::Algorithm; use ethcore::client::{Mode, BlockID, Switch, VMType, DatabaseCompactionProfile, ClientConfig}; -use ethcore::miner::PendingSet; +use ethcore::miner::{PendingSet, GasLimit}; use cache::CacheConfig; use dir::Directories; use params::Pruning; @@ -94,6 +94,14 @@ pub fn to_pending_set(s: &str) -> Result { } } +pub fn to_gas_limit(s: &str) -> Result { + match s { + "auto" => Ok(GasLimit::Auto), + "off" => Ok(GasLimit::None), + other => Ok(GasLimit::Fixed(try!(to_u256(other)))), + } +} + pub fn to_address(s: Option) -> Result { match s { Some(ref a) => clean_0x(a).parse().map_err(|_| format!("Invalid address: {:?}", a)), diff --git a/rpc/src/v1/tests/eth.rs b/rpc/src/v1/tests/eth.rs index a5851878a..bfb812f29 100644 --- a/rpc/src/v1/tests/eth.rs +++ b/rpc/src/v1/tests/eth.rs @@ -25,7 +25,7 @@ use ethcore::spec::{Genesis, Spec}; use ethcore::block::Block; use ethcore::views::BlockView; use ethcore::ethereum; -use ethcore::miner::{MinerOptions, GasPricer, MinerService, ExternalMiner, Miner, PendingSet, PrioritizationStrategy}; +use ethcore::miner::{MinerOptions, GasPricer, MinerService, ExternalMiner, Miner, PendingSet, PrioritizationStrategy, GasLimit}; use ethcore::account_provider::AccountProvider; use devtools::RandomTempPath; use util::Hashable; @@ -60,6 +60,7 @@ fn miner_service(spec: &Spec, accounts: Arc) -> Arc { tx_queue_size: 1024, tx_gas_limit: !U256::zero(), tx_queue_strategy: PrioritizationStrategy::GasPriceOnly, + tx_queue_gas_limit: GasLimit::None, pending_set: PendingSet::SealingOrElseQueue, reseal_min_period: Duration::from_secs(0), work_queue_size: 50, diff --git a/util/Cargo.toml b/util/Cargo.toml index ae8643c7d..fd84feb53 100644 --- a/util/Cargo.toml +++ b/util/Cargo.toml @@ -3,7 +3,7 @@ description = "Ethcore utility library" homepage = "http://ethcore.io" license = "GPL-3.0" name = "ethcore-util" -version = "1.3.6" +version = "1.3.7" authors = ["Ethcore "] build = "build.rs"