Skip to content
This repository has been archived by the owner on Nov 6, 2020. It is now read-only.

Commit

Permalink
TX queue gas limit config and allow local transactions over the gas l…
Browse files Browse the repository at this point in the history
…imit (#2553)

* Gas limit config; Allow local transactions over the limit

* Fix typo

[ci:skip]
  • Loading branch information
arkpar committed Oct 12, 2016
1 parent 8fba01a commit 3f6b638
Show file tree
Hide file tree
Showing 7 changed files with 64 additions and 12 deletions.
27 changes: 24 additions & 3 deletions ethcore/src/miner/miner.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand All @@ -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 {
Expand All @@ -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,
}
}
}
Expand Down Expand Up @@ -210,8 +224,12 @@ impl Miner {
/// Creates new instance of miner
pub fn new(options: MinerOptions, gas_pricer: GasPricer, 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 };
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,
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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,
Expand Down
2 changes: 1 addition & 1 deletion ethcore/src/miner/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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;

Expand Down
26 changes: 21 additions & 5 deletions ethcore/src/miner/transaction_queue.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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`."))
Expand Down Expand Up @@ -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();
Expand Down
5 changes: 5 additions & 0 deletions parity/cli.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -379,6 +383,7 @@ pub struct Args {
pub flag_extra_data: Option<String>,
pub flag_tx_queue_size: usize,
pub flag_tx_queue_strategy: String,
pub flag_tx_queue_gas: String,
pub flag_notify_work: Option<String>,
pub flag_logging: Option<String>,
pub flag_version: bool,
Expand Down
3 changes: 2 additions & 1 deletion parity/configuration.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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,
Expand Down
10 changes: 9 additions & 1 deletion parity/helpers.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -94,6 +94,14 @@ pub fn to_pending_set(s: &str) -> Result<PendingSet, String> {
}
}

pub fn to_gas_limit(s: &str) -> Result<GasLimit, String> {
match s {
"auto" => Ok(GasLimit::Auto),
"off" => Ok(GasLimit::None),
other => Ok(GasLimit::Fixed(try!(to_u256(other)))),
}
}

pub fn to_address(s: Option<String>) -> Result<Address, String> {
match s {
Some(ref a) => clean_0x(a).parse().map_err(|_| format!("Invalid address: {:?}", a)),
Expand Down
3 changes: 2 additions & 1 deletion rpc/src/v1/tests/eth.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -60,6 +60,7 @@ fn miner_service(spec: &Spec, accounts: Arc<AccountProvider>) -> Arc<Miner> {
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,
Expand Down

0 comments on commit 3f6b638

Please sign in to comment.