Merge pull request #974 from ethcore/tx-limit-conf
Configurable limit for transaction queue (CLI & Ethcore-RPC)
This commit is contained in:
commit
46c8324c52
@ -100,6 +100,12 @@ pub trait MinerService : Send + Sync {
|
|||||||
/// Set the gas limit we wish to target when sealing a new block.
|
/// Set the gas limit we wish to target when sealing a new block.
|
||||||
fn set_gas_floor_target(&self, target: U256);
|
fn set_gas_floor_target(&self, target: U256);
|
||||||
|
|
||||||
|
/// Get current transactions limit in queue.
|
||||||
|
fn transactions_limit(&self) -> usize;
|
||||||
|
|
||||||
|
/// Set maximal number of transactions kept in the queue (both current and future).
|
||||||
|
fn set_transactions_limit(&self, limit: usize);
|
||||||
|
|
||||||
/// Imports transactions to transaction queue.
|
/// Imports transactions to transaction queue.
|
||||||
fn import_transactions<T>(&self, transactions: Vec<SignedTransaction>, fetch_account: T) ->
|
fn import_transactions<T>(&self, transactions: Vec<SignedTransaction>, fetch_account: T) ->
|
||||||
Vec<Result<TransactionImportResult, Error>>
|
Vec<Result<TransactionImportResult, Error>>
|
||||||
|
@ -205,6 +205,14 @@ impl MinerService for Miner {
|
|||||||
*self.gas_floor_target.read().unwrap() / x!(5)
|
*self.gas_floor_target.read().unwrap() / x!(5)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn transactions_limit(&self) -> usize {
|
||||||
|
self.transaction_queue.lock().unwrap().limit()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn set_transactions_limit(&self, limit: usize) {
|
||||||
|
self.transaction_queue.lock().unwrap().set_limit(limit)
|
||||||
|
}
|
||||||
|
|
||||||
/// Get the author that we will seal blocks as.
|
/// Get the author that we will seal blocks as.
|
||||||
fn author(&self) -> Address {
|
fn author(&self) -> Address {
|
||||||
*self.author.read().unwrap()
|
*self.author.read().unwrap()
|
||||||
|
@ -250,6 +250,12 @@ impl TransactionSet {
|
|||||||
self.by_priority.clear();
|
self.by_priority.clear();
|
||||||
self.by_address.clear();
|
self.by_address.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Sets new limit for number of transactions in this `TransactionSet`.
|
||||||
|
/// Note the limit is not applied (no transactions are removed) by calling this method.
|
||||||
|
fn set_limit(&mut self, limit: usize) {
|
||||||
|
self.limit = limit;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
@ -307,20 +313,21 @@ impl Default for TransactionQueue {
|
|||||||
impl TransactionQueue {
|
impl TransactionQueue {
|
||||||
/// Creates new instance of this Queue
|
/// Creates new instance of this Queue
|
||||||
pub fn new() -> Self {
|
pub fn new() -> Self {
|
||||||
Self::with_limits(1024, 1024)
|
Self::with_limit(1024)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Create new instance of this Queue with specified limits
|
/// Create new instance of this Queue with specified limits
|
||||||
pub fn with_limits(current_limit: usize, future_limit: usize) -> Self {
|
pub fn with_limit(limit: usize) -> Self {
|
||||||
let current = TransactionSet {
|
let current = TransactionSet {
|
||||||
by_priority: BTreeSet::new(),
|
by_priority: BTreeSet::new(),
|
||||||
by_address: Table::new(),
|
by_address: Table::new(),
|
||||||
limit: current_limit,
|
limit: limit,
|
||||||
};
|
};
|
||||||
|
|
||||||
let future = TransactionSet {
|
let future = TransactionSet {
|
||||||
by_priority: BTreeSet::new(),
|
by_priority: BTreeSet::new(),
|
||||||
by_address: Table::new(),
|
by_address: Table::new(),
|
||||||
limit: future_limit,
|
limit: limit,
|
||||||
};
|
};
|
||||||
|
|
||||||
TransactionQueue {
|
TransactionQueue {
|
||||||
@ -333,6 +340,20 @@ impl TransactionQueue {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Set the new limit for `current` and `future` queue.
|
||||||
|
pub fn set_limit(&mut self, limit: usize) {
|
||||||
|
self.current.set_limit(limit);
|
||||||
|
self.future.set_limit(limit);
|
||||||
|
// And ensure the limits
|
||||||
|
self.current.enforce_limit(&mut self.by_hash);
|
||||||
|
self.future.enforce_limit(&mut self.by_hash);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Returns current limit of transactions in the queue.
|
||||||
|
pub fn limit(&self) -> usize {
|
||||||
|
self.current.limit
|
||||||
|
}
|
||||||
|
|
||||||
/// Get the minimal gas price.
|
/// Get the minimal gas price.
|
||||||
pub fn minimal_gas_price(&self) -> &U256 {
|
pub fn minimal_gas_price(&self) -> &U256 {
|
||||||
&self.minimal_gas_price
|
&self.minimal_gas_price
|
||||||
@ -1177,7 +1198,7 @@ mod test {
|
|||||||
#[test]
|
#[test]
|
||||||
fn should_drop_old_transactions_when_hitting_the_limit() {
|
fn should_drop_old_transactions_when_hitting_the_limit() {
|
||||||
// given
|
// given
|
||||||
let mut txq = TransactionQueue::with_limits(1, 1);
|
let mut txq = TransactionQueue::with_limit(1);
|
||||||
let (tx, tx2) = new_txs(U256::one());
|
let (tx, tx2) = new_txs(U256::one());
|
||||||
let sender = tx.sender().unwrap();
|
let sender = tx.sender().unwrap();
|
||||||
let nonce = tx.nonce;
|
let nonce = tx.nonce;
|
||||||
@ -1220,7 +1241,8 @@ mod test {
|
|||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn should_limit_future_transactions() {
|
fn should_limit_future_transactions() {
|
||||||
let mut txq = TransactionQueue::with_limits(10, 1);
|
let mut txq = TransactionQueue::with_limit(1);
|
||||||
|
txq.current.set_limit(10);
|
||||||
let (tx1, tx2) = new_txs_with_gas_price_diff(U256::from(4), U256::from(1));
|
let (tx1, tx2) = new_txs_with_gas_price_diff(U256::from(4), U256::from(1));
|
||||||
let (tx3, tx4) = new_txs_with_gas_price_diff(U256::from(4), U256::from(2));
|
let (tx3, tx4) = new_txs_with_gas_price_diff(U256::from(4), U256::from(2));
|
||||||
txq.add(tx1.clone(), &default_nonce).unwrap();
|
txq.add(tx1.clone(), &default_nonce).unwrap();
|
||||||
|
@ -172,6 +172,8 @@ Sealing/Mining Options:
|
|||||||
[default: 0037a6b811ffeb6e072da21179d11b1406371c63].
|
[default: 0037a6b811ffeb6e072da21179d11b1406371c63].
|
||||||
--extra-data STRING Specify a custom extra-data for authored blocks, no
|
--extra-data STRING Specify a custom extra-data for authored blocks, no
|
||||||
more than 32 characters.
|
more than 32 characters.
|
||||||
|
--tx-limit LIMIT Limit of transactions kept in the queue (waiting to
|
||||||
|
be included in next block) [default: 1024].
|
||||||
|
|
||||||
Footprint Options:
|
Footprint Options:
|
||||||
--pruning METHOD Configure pruning of the state/storage trie. METHOD
|
--pruning METHOD Configure pruning of the state/storage trie. METHOD
|
||||||
@ -259,6 +261,7 @@ struct Args {
|
|||||||
flag_usd_per_eth: String,
|
flag_usd_per_eth: String,
|
||||||
flag_gas_floor_target: String,
|
flag_gas_floor_target: String,
|
||||||
flag_extra_data: Option<String>,
|
flag_extra_data: Option<String>,
|
||||||
|
flag_tx_limit: usize,
|
||||||
flag_logging: Option<String>,
|
flag_logging: Option<String>,
|
||||||
flag_version: bool,
|
flag_version: bool,
|
||||||
// geth-compatibility...
|
// geth-compatibility...
|
||||||
@ -713,6 +716,7 @@ impl Configuration {
|
|||||||
miner.set_gas_floor_target(self.gas_floor_target());
|
miner.set_gas_floor_target(self.gas_floor_target());
|
||||||
miner.set_extra_data(self.extra_data());
|
miner.set_extra_data(self.extra_data());
|
||||||
miner.set_minimal_gas_price(self.gas_price());
|
miner.set_minimal_gas_price(self.gas_price());
|
||||||
|
miner.set_transactions_limit(self.args.flag_tx_limit);
|
||||||
|
|
||||||
// Sync
|
// Sync
|
||||||
let sync = EthSync::register(service.network(), sync_config, client.clone(), miner.clone());
|
let sync = EthSync::register(service.network(), sync_config, client.clone(), miner.clone());
|
||||||
|
@ -67,6 +67,17 @@ impl<M> Ethcore for EthcoreClient<M> where M: MinerService + 'static {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn set_transactions_limit(&self, params: Params) -> Result<Value, Error> {
|
||||||
|
from_params::<(usize,)>(params).and_then(|(limit,)| {
|
||||||
|
take_weak!(self.miner).set_transactions_limit(limit);
|
||||||
|
to_value(&true)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
fn transactions_limit(&self, _: Params) -> Result<Value, Error> {
|
||||||
|
to_value(&take_weak!(self.miner).transactions_limit())
|
||||||
|
}
|
||||||
|
|
||||||
fn min_gas_price(&self, _: Params) -> Result<Value, Error> {
|
fn min_gas_price(&self, _: Params) -> Result<Value, Error> {
|
||||||
to_value(&take_weak!(self.miner).minimal_gas_price())
|
to_value(&take_weak!(self.miner).minimal_gas_price())
|
||||||
}
|
}
|
||||||
|
@ -123,3 +123,31 @@ fn rpc_ethcore_set_author() {
|
|||||||
assert_eq!(io.handle_request(request), Some(response.to_owned()));
|
assert_eq!(io.handle_request(request), Some(response.to_owned()));
|
||||||
assert_eq!(miner.author(), Address::from_str("cd1722f3947def4cf144679da39c4c32bdc35681").unwrap());
|
assert_eq!(miner.author(), Address::from_str("cd1722f3947def4cf144679da39c4c32bdc35681").unwrap());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn rpc_ethcore_set_transactions_limit() {
|
||||||
|
let miner = miner_service();
|
||||||
|
let ethcore = EthcoreClient::new(&miner).to_delegate();
|
||||||
|
let io = IoHandler::new();
|
||||||
|
io.add_delegate(ethcore);
|
||||||
|
|
||||||
|
let request = r#"{"jsonrpc": "2.0", "method": "ethcore_setTransactionsLimit", "params":[10240240], "id": 1}"#;
|
||||||
|
let response = r#"{"jsonrpc":"2.0","result":true,"id":1}"#;
|
||||||
|
|
||||||
|
assert_eq!(io.handle_request(request), Some(response.to_owned()));
|
||||||
|
assert_eq!(miner.transactions_limit(), 10_240_240);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn rpc_ethcore_transactions_limit() {
|
||||||
|
let miner = miner_service();
|
||||||
|
let ethcore = EthcoreClient::new(&miner).to_delegate();
|
||||||
|
let io = IoHandler::new();
|
||||||
|
io.add_delegate(ethcore);
|
||||||
|
|
||||||
|
let request = r#"{"jsonrpc": "2.0", "method": "ethcore_transactionsLimit", "params":[], "id": 1}"#;
|
||||||
|
let response = r#"{"jsonrpc":"2.0","result":1024,"id":1}"#;
|
||||||
|
|
||||||
|
assert_eq!(io.handle_request(request), Some(response.to_owned()));
|
||||||
|
}
|
||||||
|
@ -39,6 +39,7 @@ pub struct TestMinerService {
|
|||||||
gas_floor_target: RwLock<U256>,
|
gas_floor_target: RwLock<U256>,
|
||||||
author: RwLock<Address>,
|
author: RwLock<Address>,
|
||||||
extra_data: RwLock<Bytes>,
|
extra_data: RwLock<Bytes>,
|
||||||
|
limit: RwLock<usize>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Default for TestMinerService {
|
impl Default for TestMinerService {
|
||||||
@ -52,6 +53,7 @@ impl Default for TestMinerService {
|
|||||||
gas_floor_target: RwLock::new(U256::from(12345)),
|
gas_floor_target: RwLock::new(U256::from(12345)),
|
||||||
author: RwLock::new(Address::zero()),
|
author: RwLock::new(Address::zero()),
|
||||||
extra_data: RwLock::new(vec![1, 2, 3, 4]),
|
extra_data: RwLock::new(vec![1, 2, 3, 4]),
|
||||||
|
limit: RwLock::new(1024),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -84,6 +86,14 @@ impl MinerService for TestMinerService {
|
|||||||
*self.min_gas_price.write().unwrap() = min_gas_price;
|
*self.min_gas_price.write().unwrap() = min_gas_price;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn set_transactions_limit(&self, limit: usize) {
|
||||||
|
*self.limit.write().unwrap() = limit;
|
||||||
|
}
|
||||||
|
|
||||||
|
fn transactions_limit(&self) -> usize {
|
||||||
|
*self.limit.read().unwrap()
|
||||||
|
}
|
||||||
|
|
||||||
fn author(&self) -> Address {
|
fn author(&self) -> Address {
|
||||||
*self.author.read().unwrap()
|
*self.author.read().unwrap()
|
||||||
}
|
}
|
||||||
|
@ -33,6 +33,12 @@ pub trait Ethcore: Sized + Send + Sync + 'static {
|
|||||||
/// Sets new author for mined block.
|
/// Sets new author for mined block.
|
||||||
fn set_author(&self, _: Params) -> Result<Value, Error> { rpc_unimplemented!() }
|
fn set_author(&self, _: Params) -> Result<Value, Error> { rpc_unimplemented!() }
|
||||||
|
|
||||||
|
/// Sets the limits for transaction queue.
|
||||||
|
fn set_transactions_limit(&self, _: Params) -> Result<Value, Error> { rpc_unimplemented!() }
|
||||||
|
|
||||||
|
/// Returns current transactions limit.
|
||||||
|
fn transactions_limit(&self, _: Params) -> Result<Value, Error> { rpc_unimplemented!() }
|
||||||
|
|
||||||
/// Returns mining extra data.
|
/// Returns mining extra data.
|
||||||
fn extra_data(&self, _: Params) -> Result<Value, Error> { rpc_unimplemented!() }
|
fn extra_data(&self, _: Params) -> Result<Value, Error> { rpc_unimplemented!() }
|
||||||
|
|
||||||
@ -49,10 +55,12 @@ pub trait Ethcore: Sized + Send + Sync + 'static {
|
|||||||
delegate.add_method("ethcore_setGasFloorTarget", Ethcore::set_gas_floor_target);
|
delegate.add_method("ethcore_setGasFloorTarget", Ethcore::set_gas_floor_target);
|
||||||
delegate.add_method("ethcore_setExtraData", Ethcore::set_extra_data);
|
delegate.add_method("ethcore_setExtraData", Ethcore::set_extra_data);
|
||||||
delegate.add_method("ethcore_setAuthor", Ethcore::set_author);
|
delegate.add_method("ethcore_setAuthor", Ethcore::set_author);
|
||||||
|
delegate.add_method("ethcore_setTransactionsLimit", Ethcore::set_transactions_limit);
|
||||||
|
|
||||||
delegate.add_method("ethcore_extraData", Ethcore::extra_data);
|
delegate.add_method("ethcore_extraData", Ethcore::extra_data);
|
||||||
delegate.add_method("ethcore_gasFloorTarget", Ethcore::gas_floor_target);
|
delegate.add_method("ethcore_gasFloorTarget", Ethcore::gas_floor_target);
|
||||||
delegate.add_method("ethcore_minGasPrice", Ethcore::min_gas_price);
|
delegate.add_method("ethcore_minGasPrice", Ethcore::min_gas_price);
|
||||||
|
delegate.add_method("ethcore_transactionsLimit", Ethcore::transactions_limit);
|
||||||
delegate
|
delegate
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user