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

Commit 3f6b638

Browse files
committed
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]
1 parent 8fba01a commit 3f6b638

File tree

7 files changed

+64
-12
lines changed

7 files changed

+64
-12
lines changed

ethcore/src/miner/miner.rs

+24-3
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,17 @@ pub enum PendingSet {
4848
SealingOrElseQueue,
4949
}
5050

51+
/// Type of the gas limit to apply to the transaction queue.
52+
#[derive(Debug, PartialEq)]
53+
pub enum GasLimit {
54+
/// Depends on the block gas limit and is updated with every block.
55+
Auto,
56+
/// No limit.
57+
None,
58+
/// Set to a fixed gas value.
59+
Fixed(U256),
60+
}
61+
5162
/// Configures the behaviour of the miner.
5263
#[derive(Debug, PartialEq)]
5364
pub struct MinerOptions {
@@ -73,6 +84,8 @@ pub struct MinerOptions {
7384
pub work_queue_size: usize,
7485
/// Can we submit two different solutions for the same block and expect both to result in an import?
7586
pub enable_resubmission: bool,
87+
/// Global gas limit for all transaction in the queue except for local and retracted.
88+
pub tx_queue_gas_limit: GasLimit,
7689
}
7790

7891
impl Default for MinerOptions {
@@ -89,6 +102,7 @@ impl Default for MinerOptions {
89102
reseal_min_period: Duration::from_secs(2),
90103
work_queue_size: 20,
91104
enable_resubmission: true,
105+
tx_queue_gas_limit: GasLimit::Auto,
92106
}
93107
}
94108
}
@@ -210,8 +224,12 @@ impl Miner {
210224
/// Creates new instance of miner
211225
pub fn new(options: MinerOptions, gas_pricer: GasPricer, spec: &Spec, accounts: Option<Arc<AccountProvider>>) -> Arc<Miner> {
212226
let work_poster = if !options.new_work_notify.is_empty() { Some(WorkPoster::new(&options.new_work_notify)) } else { None };
227+
let gas_limit = match options.tx_queue_gas_limit {
228+
GasLimit::Fixed(ref limit) => *limit,
229+
_ => !U256::zero(),
230+
};
213231
let txq = Arc::new(Mutex::new(TransactionQueue::with_limits(
214-
options.tx_queue_strategy, options.tx_queue_size, !U256::zero(), options.tx_gas_limit
232+
options.tx_queue_strategy, options.tx_queue_size, gas_limit, options.tx_gas_limit
215233
)));
216234
Arc::new(Miner {
217235
transaction_queue: txq,
@@ -402,8 +420,10 @@ impl Miner {
402420
let gas_limit = HeaderView::new(&chain.best_block_header()).gas_limit();
403421
let mut queue = self.transaction_queue.lock();
404422
queue.set_gas_limit(gas_limit);
405-
// Set total qx queue gas limit to be 2x the block gas limit.
406-
queue.set_total_gas_limit(gas_limit << 1);
423+
if let GasLimit::Auto = self.options.tx_queue_gas_limit {
424+
// Set total tx queue gas limit to be 2x the block gas limit.
425+
queue.set_total_gas_limit(gas_limit << 1);
426+
}
407427
}
408428

409429
/// Returns true if we had to prepare new pending block
@@ -1023,6 +1043,7 @@ mod tests {
10231043
tx_gas_limit: !U256::zero(),
10241044
tx_queue_size: 1024,
10251045
tx_queue_strategy: PrioritizationStrategy::GasFactorAndGasPrice,
1046+
tx_queue_gas_limit: GasLimit::None,
10261047
pending_set: PendingSet::AlwaysSealing,
10271048
work_queue_size: 5,
10281049
enable_resubmission: true,

ethcore/src/miner/mod.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,7 @@ mod work_notify;
4848
mod price_info;
4949

5050
pub use self::transaction_queue::{TransactionQueue, PrioritizationStrategy, AccountDetails, TransactionOrigin};
51-
pub use self::miner::{Miner, MinerOptions, PendingSet, GasPricer, GasPriceCalibratorOptions};
51+
pub use self::miner::{Miner, MinerOptions, PendingSet, GasPricer, GasPriceCalibratorOptions, GasLimit};
5252
pub use self::external::{ExternalMiner, ExternalMinerService};
5353
pub use client::TransactionImportResult;
5454

ethcore/src/miner/transaction_queue.rs

+21-5
Original file line numberDiff line numberDiff line change
@@ -310,7 +310,9 @@ impl TransactionSet {
310310
let r = gas.overflowing_add(order.gas);
311311
if r.1 { return false }
312312
gas = r.0;
313-
count <= self.limit && gas <= self.gas_limit
313+
// Own and retracted transactions are allowed to go above the gas limit, bot not above the count limit.
314+
(gas <= self.gas_limit || order.origin == TransactionOrigin::Local || order.origin == TransactionOrigin::RetractedBlock) &&
315+
count <= self.limit
314316
})
315317
.map(|order| by_hash.get(&order.hash)
316318
.expect("All transactions in `self.by_priority` and `self.by_address` are kept in sync with `by_hash`."))
@@ -1757,13 +1759,27 @@ mod test {
17571759
#[test]
17581760
fn should_limit_by_gas() {
17591761
let mut txq = TransactionQueue::with_limits(PrioritizationStrategy::GasPriceOnly, 100, default_gas_val() * U256::from(2), !U256::zero());
1760-
let (tx1, _) = new_txs_with_gas_price_diff(U256::from(4), U256::from(1));
1761-
let (tx3, _) = new_txs_with_gas_price_diff(U256::from(4), U256::from(2));
1762-
txq.add(tx1.clone(), &default_nonce, TransactionOrigin::External).unwrap();
1763-
txq.add(tx3.clone(), &default_nonce, TransactionOrigin::External).unwrap();
1762+
let (tx1, tx2) = new_txs_with_gas_price_diff(U256::from(1), U256::from(1));
1763+
let (tx3, tx4) = new_txs_with_gas_price_diff(U256::from(1), U256::from(2));
1764+
txq.add(tx1.clone(), &default_nonce, TransactionOrigin::External).ok();
1765+
txq.add(tx2.clone(), &default_nonce, TransactionOrigin::External).ok();
1766+
txq.add(tx3.clone(), &default_nonce, TransactionOrigin::External).ok();
1767+
txq.add(tx4.clone(), &default_nonce, TransactionOrigin::External).ok();
17641768
assert_eq!(txq.status().pending, 2);
17651769
}
17661770

1771+
#[test]
1772+
fn should_keep_own_transactions_above_gas_limit() {
1773+
let mut txq = TransactionQueue::with_limits(PrioritizationStrategy::GasPriceOnly, 100, default_gas_val() * U256::from(2), !U256::zero());
1774+
let (tx1, tx2) = new_txs_with_gas_price_diff(U256::from(1), U256::from(1));
1775+
let (tx3, tx4) = new_txs_with_gas_price_diff(U256::from(1), U256::from(2));
1776+
txq.add(tx1.clone(), &default_nonce, TransactionOrigin::Local).unwrap();
1777+
txq.add(tx2.clone(), &default_nonce, TransactionOrigin::Local).unwrap();
1778+
txq.add(tx3.clone(), &default_nonce, TransactionOrigin::Local).unwrap();
1779+
txq.add(tx4.clone(), &default_nonce, TransactionOrigin::Local).unwrap();
1780+
assert_eq!(txq.status().pending, 4);
1781+
}
1782+
17671783
#[test]
17681784
fn should_drop_transactions_with_old_nonces() {
17691785
let mut txq = TransactionQueue::default();

parity/cli.rs

+5
Original file line numberDiff line numberDiff line change
@@ -200,6 +200,10 @@ Sealing/Mining Options:
200200
gas_price - Prioritize txs with high gas price;
201201
gas_factor - Prioritize txs using gas price
202202
and gas limit ratio [default: gas_factor].
203+
--tx-queue-gas LIMIT Maximum amount of total gas for external transactions in
204+
the queue. LIMIT can be either an amount of gas or
205+
'auto' or 'off'. 'auto' sets the limit to be 2x
206+
the current block gas limit. [default: auto].
203207
--remove-solved Move solved blocks from the work package queue
204208
instead of cloning them. This gives a slightly
205209
faster import speed, but means that extra solutions
@@ -379,6 +383,7 @@ pub struct Args {
379383
pub flag_extra_data: Option<String>,
380384
pub flag_tx_queue_size: usize,
381385
pub flag_tx_queue_strategy: String,
386+
pub flag_tx_queue_gas: String,
382387
pub flag_notify_work: Option<String>,
383388
pub flag_logging: Option<String>,
384389
pub flag_version: bool,

parity/configuration.rs

+2-1
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ use rpc::{IpcConfiguration, HttpConfiguration};
3131
use ethcore_rpc::NetworkSettings;
3232
use cache::CacheConfig;
3333
use helpers::{to_duration, to_mode, to_block_id, to_u256, to_pending_set, to_price, replace_home,
34-
geth_ipc_path, parity_ipc_path, to_bootnodes, to_addresses, to_address};
34+
geth_ipc_path, parity_ipc_path, to_bootnodes, to_addresses, to_address, to_gas_limit};
3535
use params::{ResealPolicy, AccountsConfig, GasPricerConfig, MinerExtras};
3636
use ethcore_logger::Config as LogConfig;
3737
use dir::Directories;
@@ -342,6 +342,7 @@ impl Configuration {
342342
},
343343
tx_queue_size: self.args.flag_tx_queue_size,
344344
tx_queue_strategy: try!(self.transaction_queue_strategy()),
345+
tx_queue_gas_limit: try!(to_gas_limit(&self.args.flag_tx_queue_gas)),
345346
pending_set: try!(to_pending_set(&self.args.flag_relay_set)),
346347
reseal_min_period: Duration::from_millis(self.args.flag_reseal_min_period),
347348
work_queue_size: self.args.flag_work_queue_size,

parity/helpers.rs

+9-1
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ use std::fs::File;
2222
use util::{clean_0x, U256, Uint, Address, path, H256, CompactionProfile};
2323
use util::journaldb::Algorithm;
2424
use ethcore::client::{Mode, BlockID, Switch, VMType, DatabaseCompactionProfile, ClientConfig};
25-
use ethcore::miner::PendingSet;
25+
use ethcore::miner::{PendingSet, GasLimit};
2626
use cache::CacheConfig;
2727
use dir::Directories;
2828
use params::Pruning;
@@ -94,6 +94,14 @@ pub fn to_pending_set(s: &str) -> Result<PendingSet, String> {
9494
}
9595
}
9696

97+
pub fn to_gas_limit(s: &str) -> Result<GasLimit, String> {
98+
match s {
99+
"auto" => Ok(GasLimit::Auto),
100+
"off" => Ok(GasLimit::None),
101+
other => Ok(GasLimit::Fixed(try!(to_u256(other)))),
102+
}
103+
}
104+
97105
pub fn to_address(s: Option<String>) -> Result<Address, String> {
98106
match s {
99107
Some(ref a) => clean_0x(a).parse().map_err(|_| format!("Invalid address: {:?}", a)),

rpc/src/v1/tests/eth.rs

+2-1
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ use ethcore::spec::{Genesis, Spec};
2525
use ethcore::block::Block;
2626
use ethcore::views::BlockView;
2727
use ethcore::ethereum;
28-
use ethcore::miner::{MinerOptions, GasPricer, MinerService, ExternalMiner, Miner, PendingSet, PrioritizationStrategy};
28+
use ethcore::miner::{MinerOptions, GasPricer, MinerService, ExternalMiner, Miner, PendingSet, PrioritizationStrategy, GasLimit};
2929
use ethcore::account_provider::AccountProvider;
3030
use devtools::RandomTempPath;
3131
use util::Hashable;
@@ -60,6 +60,7 @@ fn miner_service(spec: &Spec, accounts: Arc<AccountProvider>) -> Arc<Miner> {
6060
tx_queue_size: 1024,
6161
tx_gas_limit: !U256::zero(),
6262
tx_queue_strategy: PrioritizationStrategy::GasPriceOnly,
63+
tx_queue_gas_limit: GasLimit::None,
6364
pending_set: PendingSet::SealingOrElseQueue,
6465
reseal_min_period: Duration::from_secs(0),
6566
work_queue_size: 50,

0 commit comments

Comments
 (0)