Validating minimal required gas for a transaction (#2937)
* Validating minimal required gas for a transaction * Adding RPC case and note * Fixing whitespace [ci skip]
This commit is contained in:
parent
2806f1d4c9
commit
0f0334275e
ethcore/src
rpc/src/v1/helpers
@ -60,7 +60,7 @@ use receipt::LocalizedReceipt;
|
|||||||
use trace::{TraceDB, ImportRequest as TraceImportRequest, LocalizedTrace, Database as TraceDatabase};
|
use trace::{TraceDB, ImportRequest as TraceImportRequest, LocalizedTrace, Database as TraceDatabase};
|
||||||
use trace;
|
use trace;
|
||||||
use trace::FlatTransactionTraces;
|
use trace::FlatTransactionTraces;
|
||||||
use evm::Factory as EvmFactory;
|
use evm::{Factory as EvmFactory, Schedule};
|
||||||
use miner::{Miner, MinerService};
|
use miner::{Miner, MinerService};
|
||||||
use snapshot::{self, io as snapshot_io};
|
use snapshot::{self, io as snapshot_io};
|
||||||
use factory::Factories;
|
use factory::Factories;
|
||||||
@ -1156,6 +1156,23 @@ impl BlockChainClient for Client {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl MiningBlockChainClient for Client {
|
impl MiningBlockChainClient for Client {
|
||||||
|
|
||||||
|
fn latest_schedule(&self) -> Schedule {
|
||||||
|
let header_data = self.best_block_header();
|
||||||
|
let view = HeaderView::new(&header_data);
|
||||||
|
|
||||||
|
let env_info = EnvInfo {
|
||||||
|
number: view.number(),
|
||||||
|
author: view.author(),
|
||||||
|
timestamp: view.timestamp(),
|
||||||
|
difficulty: view.difficulty(),
|
||||||
|
last_hashes: self.build_last_hashes(view.hash()),
|
||||||
|
gas_used: U256::default(),
|
||||||
|
gas_limit: view.gas_limit(),
|
||||||
|
};
|
||||||
|
self.engine.schedule(&env_info)
|
||||||
|
}
|
||||||
|
|
||||||
fn prepare_open_block(&self, author: Address, gas_range_target: (U256, U256), extra_data: Bytes) -> OpenBlock {
|
fn prepare_open_block(&self, author: Address, gas_range_target: (U256, U256), extra_data: Bytes) -> OpenBlock {
|
||||||
let engine = &*self.engine;
|
let engine = &*self.engine;
|
||||||
let chain = self.chain.read();
|
let chain = self.chain.read();
|
||||||
|
@ -34,7 +34,7 @@ use log_entry::LocalizedLogEntry;
|
|||||||
use receipt::{Receipt, LocalizedReceipt};
|
use receipt::{Receipt, LocalizedReceipt};
|
||||||
use blockchain::extras::BlockReceipts;
|
use blockchain::extras::BlockReceipts;
|
||||||
use error::{ImportResult};
|
use error::{ImportResult};
|
||||||
use evm::{Factory as EvmFactory, VMType};
|
use evm::{Factory as EvmFactory, VMType, Schedule};
|
||||||
use miner::{Miner, MinerService, TransactionImportResult};
|
use miner::{Miner, MinerService, TransactionImportResult};
|
||||||
use spec::Spec;
|
use spec::Spec;
|
||||||
|
|
||||||
@ -306,6 +306,10 @@ pub fn get_temp_state_db() -> GuardedTempResult<StateDB> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl MiningBlockChainClient for TestBlockChainClient {
|
impl MiningBlockChainClient for TestBlockChainClient {
|
||||||
|
fn latest_schedule(&self) -> Schedule {
|
||||||
|
Schedule::new_homestead_gas_fix()
|
||||||
|
}
|
||||||
|
|
||||||
fn prepare_open_block(&self, author: Address, gas_range_target: (U256, U256), extra_data: Bytes) -> OpenBlock {
|
fn prepare_open_block(&self, author: Address, gas_range_target: (U256, U256), extra_data: Bytes) -> OpenBlock {
|
||||||
let engine = &*self.spec.engine;
|
let engine = &*self.spec.engine;
|
||||||
let genesis_header = self.spec.genesis_header();
|
let genesis_header = self.spec.genesis_header();
|
||||||
|
@ -27,7 +27,7 @@ use views::{BlockView};
|
|||||||
use error::{ImportResult, CallError};
|
use error::{ImportResult, CallError};
|
||||||
use receipt::LocalizedReceipt;
|
use receipt::LocalizedReceipt;
|
||||||
use trace::LocalizedTrace;
|
use trace::LocalizedTrace;
|
||||||
use evm::Factory as EvmFactory;
|
use evm::{Factory as EvmFactory, Schedule};
|
||||||
use types::ids::*;
|
use types::ids::*;
|
||||||
use types::trace_filter::Filter as TraceFilter;
|
use types::trace_filter::Filter as TraceFilter;
|
||||||
use executive::Executed;
|
use executive::Executed;
|
||||||
@ -236,6 +236,9 @@ pub trait MiningBlockChainClient : BlockChainClient {
|
|||||||
|
|
||||||
/// Import sealed block. Skips all verifications.
|
/// Import sealed block. Skips all verifications.
|
||||||
fn import_sealed_block(&self, block: SealedBlock) -> ImportResult;
|
fn import_sealed_block(&self, block: SealedBlock) -> ImportResult;
|
||||||
|
|
||||||
|
/// Returns latest schedule.
|
||||||
|
fn latest_schedule(&self) -> Schedule;
|
||||||
}
|
}
|
||||||
|
|
||||||
impl IpcConfig for BlockChainClient { }
|
impl IpcConfig for BlockChainClient { }
|
||||||
|
@ -47,6 +47,13 @@ pub enum TransactionError {
|
|||||||
/// Transaction gas price
|
/// Transaction gas price
|
||||||
got: U256,
|
got: U256,
|
||||||
},
|
},
|
||||||
|
/// Transaction's gas is below currently set minimal gas requirement.
|
||||||
|
InsufficientGas {
|
||||||
|
/// Minimal expected gas
|
||||||
|
minimal: U256,
|
||||||
|
/// Transaction gas
|
||||||
|
got: U256,
|
||||||
|
},
|
||||||
/// Sender doesn't have enough funds to pay for this transaction
|
/// Sender doesn't have enough funds to pay for this transaction
|
||||||
InsufficientBalance {
|
InsufficientBalance {
|
||||||
/// Senders balance
|
/// Senders balance
|
||||||
@ -81,6 +88,8 @@ impl fmt::Display for TransactionError {
|
|||||||
LimitReached => "Transaction limit reached".into(),
|
LimitReached => "Transaction limit reached".into(),
|
||||||
InsufficientGasPrice { minimal, got } =>
|
InsufficientGasPrice { minimal, got } =>
|
||||||
format!("Insufficient gas price. Min={}, Given={}", minimal, got),
|
format!("Insufficient gas price. Min={}, Given={}", minimal, got),
|
||||||
|
InsufficientGas { minimal, got } =>
|
||||||
|
format!("Insufficient gas. Min={}, Given={}", minimal, got),
|
||||||
InsufficientBalance { balance, cost } =>
|
InsufficientBalance { balance, cost } =>
|
||||||
format!("Insufficient balance for transaction. Balance={}, Cost={}",
|
format!("Insufficient balance for transaction. Balance={}, Cost={}",
|
||||||
balance, cost),
|
balance, cost),
|
||||||
|
@ -75,11 +75,15 @@ impl BanningTransactionQueue {
|
|||||||
|
|
||||||
/// Add to the queue taking bans into consideration.
|
/// Add to the queue taking bans into consideration.
|
||||||
/// May reject transaction because of the banlist.
|
/// May reject transaction because of the banlist.
|
||||||
pub fn add_with_banlist<F>(
|
pub fn add_with_banlist<F, G>(
|
||||||
&mut self,
|
&mut self,
|
||||||
transaction: SignedTransaction,
|
transaction: SignedTransaction,
|
||||||
account_details: &F,
|
account_details: &F,
|
||||||
) -> Result<TransactionImportResult, Error> where F: Fn(&Address) -> AccountDetails {
|
gas_estimator: &G,
|
||||||
|
) -> Result<TransactionImportResult, Error> where
|
||||||
|
F: Fn(&Address) -> AccountDetails,
|
||||||
|
G: Fn(&SignedTransaction) -> U256,
|
||||||
|
{
|
||||||
if let Threshold::BanAfter(threshold) = self.ban_threshold {
|
if let Threshold::BanAfter(threshold) = self.ban_threshold {
|
||||||
// NOTE In all checks use direct query to avoid increasing ban timeout.
|
// NOTE In all checks use direct query to avoid increasing ban timeout.
|
||||||
|
|
||||||
@ -111,7 +115,7 @@ impl BanningTransactionQueue {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
self.queue.add(transaction, account_details, TransactionOrigin::External)
|
self.queue.add(transaction, TransactionOrigin::External, account_details, gas_estimator)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Ban transaction with given hash.
|
/// Ban transaction with given hash.
|
||||||
@ -228,6 +232,10 @@ mod tests {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn gas_required(_tx: &SignedTransaction) -> U256 {
|
||||||
|
0.into()
|
||||||
|
}
|
||||||
|
|
||||||
fn transaction(action: Action) -> SignedTransaction {
|
fn transaction(action: Action) -> SignedTransaction {
|
||||||
let keypair = Random.generate().unwrap();
|
let keypair = Random.generate().unwrap();
|
||||||
Transaction {
|
Transaction {
|
||||||
@ -255,7 +263,7 @@ mod tests {
|
|||||||
let mut txq = queue();
|
let mut txq = queue();
|
||||||
|
|
||||||
// when
|
// when
|
||||||
txq.queue().add(tx, &default_account_details, TransactionOrigin::External).unwrap();
|
txq.queue().add(tx, TransactionOrigin::External, &default_account_details, &gas_required).unwrap();
|
||||||
|
|
||||||
// then
|
// then
|
||||||
// should also deref to queue
|
// should also deref to queue
|
||||||
@ -271,12 +279,12 @@ mod tests {
|
|||||||
let banlist1 = txq.ban_sender(tx.sender().unwrap());
|
let banlist1 = txq.ban_sender(tx.sender().unwrap());
|
||||||
assert!(!banlist1, "Threshold not reached yet.");
|
assert!(!banlist1, "Threshold not reached yet.");
|
||||||
// Insert once
|
// Insert once
|
||||||
let import1 = txq.add_with_banlist(tx.clone(), &default_account_details).unwrap();
|
let import1 = txq.add_with_banlist(tx.clone(), &default_account_details, &gas_required).unwrap();
|
||||||
assert_eq!(import1, TransactionImportResult::Current);
|
assert_eq!(import1, TransactionImportResult::Current);
|
||||||
|
|
||||||
// when
|
// when
|
||||||
let banlist2 = txq.ban_sender(tx.sender().unwrap());
|
let banlist2 = txq.ban_sender(tx.sender().unwrap());
|
||||||
let import2 = txq.add_with_banlist(tx.clone(), &default_account_details);
|
let import2 = txq.add_with_banlist(tx.clone(), &default_account_details, &gas_required);
|
||||||
|
|
||||||
// then
|
// then
|
||||||
assert!(banlist2, "Threshold should be reached - banned.");
|
assert!(banlist2, "Threshold should be reached - banned.");
|
||||||
@ -295,12 +303,12 @@ mod tests {
|
|||||||
let banlist1 = txq.ban_recipient(recipient);
|
let banlist1 = txq.ban_recipient(recipient);
|
||||||
assert!(!banlist1, "Threshold not reached yet.");
|
assert!(!banlist1, "Threshold not reached yet.");
|
||||||
// Insert once
|
// Insert once
|
||||||
let import1 = txq.add_with_banlist(tx.clone(), &default_account_details).unwrap();
|
let import1 = txq.add_with_banlist(tx.clone(), &default_account_details, &gas_required).unwrap();
|
||||||
assert_eq!(import1, TransactionImportResult::Current);
|
assert_eq!(import1, TransactionImportResult::Current);
|
||||||
|
|
||||||
// when
|
// when
|
||||||
let banlist2 = txq.ban_recipient(recipient);
|
let banlist2 = txq.ban_recipient(recipient);
|
||||||
let import2 = txq.add_with_banlist(tx.clone(), &default_account_details);
|
let import2 = txq.add_with_banlist(tx.clone(), &default_account_details, &gas_required);
|
||||||
|
|
||||||
// then
|
// then
|
||||||
assert!(banlist2, "Threshold should be reached - banned.");
|
assert!(banlist2, "Threshold should be reached - banned.");
|
||||||
@ -317,12 +325,12 @@ mod tests {
|
|||||||
let banlist1 = txq.ban_codehash(codehash);
|
let banlist1 = txq.ban_codehash(codehash);
|
||||||
assert!(!banlist1, "Threshold not reached yet.");
|
assert!(!banlist1, "Threshold not reached yet.");
|
||||||
// Insert once
|
// Insert once
|
||||||
let import1 = txq.add_with_banlist(tx.clone(), &default_account_details).unwrap();
|
let import1 = txq.add_with_banlist(tx.clone(), &default_account_details, &gas_required).unwrap();
|
||||||
assert_eq!(import1, TransactionImportResult::Current);
|
assert_eq!(import1, TransactionImportResult::Current);
|
||||||
|
|
||||||
// when
|
// when
|
||||||
let banlist2 = txq.ban_codehash(codehash);
|
let banlist2 = txq.ban_codehash(codehash);
|
||||||
let import2 = txq.add_with_banlist(tx.clone(), &default_account_details);
|
let import2 = txq.add_with_banlist(tx.clone(), &default_account_details, &gas_required);
|
||||||
|
|
||||||
// then
|
// then
|
||||||
assert!(banlist2, "Threshold should be reached - banned.");
|
assert!(banlist2, "Threshold should be reached - banned.");
|
||||||
|
@ -562,13 +562,15 @@ impl Miner {
|
|||||||
balance: chain.latest_balance(a),
|
balance: chain.latest_balance(a),
|
||||||
};
|
};
|
||||||
|
|
||||||
|
let schedule = chain.latest_schedule();
|
||||||
|
let gas_required = |tx: &SignedTransaction| tx.gas_required(&schedule).into();
|
||||||
transactions.into_iter()
|
transactions.into_iter()
|
||||||
.map(|tx| match origin {
|
.map(|tx| match origin {
|
||||||
TransactionOrigin::Local | TransactionOrigin::RetractedBlock => {
|
TransactionOrigin::Local | TransactionOrigin::RetractedBlock => {
|
||||||
transaction_queue.add(tx, &fetch_account, origin)
|
transaction_queue.add(tx, origin, &fetch_account, &gas_required)
|
||||||
},
|
},
|
||||||
TransactionOrigin::External => {
|
TransactionOrigin::External => {
|
||||||
transaction_queue.add_with_banlist(tx, &fetch_account)
|
transaction_queue.add_with_banlist(tx, &fetch_account, &gas_required)
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
.collect()
|
.collect()
|
||||||
|
@ -48,10 +48,11 @@
|
|||||||
//! nonce: U256::from(10),
|
//! nonce: U256::from(10),
|
||||||
//! balance: U256::from(1_000_000),
|
//! balance: U256::from(1_000_000),
|
||||||
//! };
|
//! };
|
||||||
|
//! let gas_estimator = |_tx: &SignedTransaction| 2.into();
|
||||||
//!
|
//!
|
||||||
//! let mut txq = TransactionQueue::default();
|
//! let mut txq = TransactionQueue::default();
|
||||||
//! txq.add(st2.clone(), &default_account_details, TransactionOrigin::External).unwrap();
|
//! txq.add(st2.clone(), TransactionOrigin::External, &default_account_details, &gas_estimator).unwrap();
|
||||||
//! txq.add(st1.clone(), &default_account_details, TransactionOrigin::External).unwrap();
|
//! txq.add(st1.clone(), TransactionOrigin::External, &default_account_details, &gas_estimator).unwrap();
|
||||||
//!
|
//!
|
||||||
//! // Check status
|
//! // Check status
|
||||||
//! assert_eq!(txq.status().pending, 2);
|
//! assert_eq!(txq.status().pending, 2);
|
||||||
@ -593,9 +594,20 @@ impl TransactionQueue {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Add signed transaction to queue to be verified and imported
|
/// Add signed transaction to queue to be verified and imported.
|
||||||
pub fn add<T>(&mut self, tx: SignedTransaction, fetch_account: &T, origin: TransactionOrigin) -> Result<TransactionImportResult, Error>
|
///
|
||||||
where T: Fn(&Address) -> AccountDetails {
|
/// NOTE fetch_account and gas_estimator should be cheap to compute
|
||||||
|
/// otherwise it might open up an attack vector.
|
||||||
|
pub fn add<F, G>(
|
||||||
|
&mut self,
|
||||||
|
tx: SignedTransaction,
|
||||||
|
origin: TransactionOrigin,
|
||||||
|
fetch_account: &F,
|
||||||
|
gas_estimator: &G,
|
||||||
|
) -> Result<TransactionImportResult, Error> where
|
||||||
|
F: Fn(&Address) -> AccountDetails,
|
||||||
|
G: Fn(&SignedTransaction) -> U256,
|
||||||
|
{
|
||||||
|
|
||||||
if tx.gas_price < self.minimal_gas_price && origin != TransactionOrigin::Local {
|
if tx.gas_price < self.minimal_gas_price && origin != TransactionOrigin::Local {
|
||||||
trace!(target: "txqueue",
|
trace!(target: "txqueue",
|
||||||
@ -626,8 +638,6 @@ impl TransactionQueue {
|
|||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
|
|
||||||
try!(tx.check_low_s());
|
|
||||||
|
|
||||||
if tx.gas > self.gas_limit || tx.gas > self.tx_gas_limit {
|
if tx.gas > self.gas_limit || tx.gas > self.tx_gas_limit {
|
||||||
trace!(target: "txqueue",
|
trace!(target: "txqueue",
|
||||||
"Dropping transaction above gas limit: {:?} ({} > min({}, {}))",
|
"Dropping transaction above gas limit: {:?} ({} > min({}, {}))",
|
||||||
@ -643,6 +653,24 @@ impl TransactionQueue {
|
|||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let minimal_gas = gas_estimator(&tx);
|
||||||
|
if tx.gas < minimal_gas {
|
||||||
|
trace!(target: "txqueue",
|
||||||
|
"Dropping transaction with insufficient gas: {:?} ({} > {})",
|
||||||
|
tx.hash(),
|
||||||
|
tx.gas,
|
||||||
|
minimal_gas,
|
||||||
|
);
|
||||||
|
|
||||||
|
return Err(Error::Transaction(TransactionError::InsufficientGas {
|
||||||
|
minimal: minimal_gas,
|
||||||
|
got: tx.gas,
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Verify signature
|
||||||
|
try!(tx.check_low_s());
|
||||||
|
|
||||||
let vtx = try!(VerifiedTransaction::new(tx, origin));
|
let vtx = try!(VerifiedTransaction::new(tx, origin));
|
||||||
let client_account = fetch_account(&vtx.sender());
|
let client_account = fetch_account(&vtx.sender());
|
||||||
|
|
||||||
@ -905,16 +933,6 @@ impl TransactionQueue {
|
|||||||
let nonce = tx.nonce();
|
let nonce = tx.nonce();
|
||||||
let hash = tx.hash();
|
let hash = tx.hash();
|
||||||
|
|
||||||
{
|
|
||||||
// Rough size sanity check
|
|
||||||
let gas = &tx.transaction.gas;
|
|
||||||
if U256::from(tx.transaction.data.len()) > *gas {
|
|
||||||
// Droping transaction
|
|
||||||
trace!(target: "txqueue", "Dropping oversized transaction: {:?} (gas: {} < size {})", hash, gas, tx.transaction.data.len());
|
|
||||||
return Err(TransactionError::LimitReached);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// The transaction might be old, let's check that.
|
// The transaction might be old, let's check that.
|
||||||
// This has to be the first test, otherwise calculating
|
// This has to be the first test, otherwise calculating
|
||||||
// nonce height would result in overflow.
|
// nonce height would result in overflow.
|
||||||
@ -1104,6 +1122,10 @@ mod test {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn gas_estimator(_tx: &SignedTransaction) -> U256 {
|
||||||
|
U256::zero()
|
||||||
|
}
|
||||||
|
|
||||||
fn new_tx_pair(nonce: U256, gas_price: U256, nonce_increment: U256, gas_price_increment: U256) -> (SignedTransaction, SignedTransaction) {
|
fn new_tx_pair(nonce: U256, gas_price: U256, nonce_increment: U256, gas_price_increment: U256) -> (SignedTransaction, SignedTransaction) {
|
||||||
let tx1 = new_unsigned_tx(nonce, default_gas_val(), gas_price);
|
let tx1 = new_unsigned_tx(nonce, default_gas_val(), gas_price);
|
||||||
let tx2 = new_unsigned_tx(nonce + nonce_increment, default_gas_val(), gas_price + gas_price_increment);
|
let tx2 = new_unsigned_tx(nonce + nonce_increment, default_gas_val(), gas_price + gas_price_increment);
|
||||||
@ -1155,14 +1177,14 @@ mod test {
|
|||||||
let (tx1, tx2) = new_tx_pair(123.into(), 1.into(), 1.into(), 0.into());
|
let (tx1, tx2) = new_tx_pair(123.into(), 1.into(), 1.into(), 0.into());
|
||||||
let sender = tx1.sender().unwrap();
|
let sender = tx1.sender().unwrap();
|
||||||
let nonce = tx1.nonce;
|
let nonce = tx1.nonce;
|
||||||
txq.add(tx1.clone(), &default_account_details, TransactionOrigin::External).unwrap();
|
txq.add(tx1.clone(), TransactionOrigin::External, &default_account_details, &gas_estimator).unwrap();
|
||||||
txq.add(tx2.clone(), &default_account_details, TransactionOrigin::External).unwrap();
|
txq.add(tx2.clone(), TransactionOrigin::External, &default_account_details, &gas_estimator).unwrap();
|
||||||
assert_eq!(txq.status().pending, 2);
|
assert_eq!(txq.status().pending, 2);
|
||||||
assert_eq!(txq.last_nonce(&sender), Some(nonce + 1.into()));
|
assert_eq!(txq.last_nonce(&sender), Some(nonce + 1.into()));
|
||||||
|
|
||||||
// when
|
// when
|
||||||
let tx = new_tx(123.into(), 1.into());
|
let tx = new_tx(123.into(), 1.into());
|
||||||
let res = txq.add(tx.clone(), &default_account_details, TransactionOrigin::External);
|
let res = txq.add(tx.clone(), TransactionOrigin::External, &default_account_details, &gas_estimator);
|
||||||
|
|
||||||
// then
|
// then
|
||||||
// No longer the case as we don't even consider a transaction that isn't above a full
|
// No longer the case as we don't even consider a transaction that isn't above a full
|
||||||
@ -1318,12 +1340,12 @@ mod test {
|
|||||||
!U256::zero() };
|
!U256::zero() };
|
||||||
|
|
||||||
// First insert one transaction to future
|
// First insert one transaction to future
|
||||||
let res = txq.add(tx, &prev_nonce, TransactionOrigin::External);
|
let res = txq.add(tx, TransactionOrigin::External, &prev_nonce, &gas_estimator);
|
||||||
assert_eq!(res.unwrap(), TransactionImportResult::Future);
|
assert_eq!(res.unwrap(), TransactionImportResult::Future);
|
||||||
assert_eq!(txq.status().future, 1);
|
assert_eq!(txq.status().future, 1);
|
||||||
|
|
||||||
// now import second transaction to current
|
// now import second transaction to current
|
||||||
let res = txq.add(tx2.clone(), &default_account_details, TransactionOrigin::External);
|
let res = txq.add(tx2.clone(), TransactionOrigin::External, &default_account_details, &gas_estimator);
|
||||||
|
|
||||||
// and then there should be only one transaction in current (the one with higher gas_price)
|
// and then there should be only one transaction in current (the one with higher gas_price)
|
||||||
assert_eq!(res.unwrap(), TransactionImportResult::Current);
|
assert_eq!(res.unwrap(), TransactionImportResult::Current);
|
||||||
@ -1343,12 +1365,12 @@ mod test {
|
|||||||
!U256::zero() };
|
!U256::zero() };
|
||||||
|
|
||||||
// First insert one transaction to future
|
// First insert one transaction to future
|
||||||
let res = txq.add(tx.clone(), &prev_nonce, TransactionOrigin::External);
|
let res = txq.add(tx.clone(), TransactionOrigin::External, &prev_nonce, &gas_estimator);
|
||||||
assert_eq!(res.unwrap(), TransactionImportResult::Future);
|
assert_eq!(res.unwrap(), TransactionImportResult::Future);
|
||||||
assert_eq!(txq.status().future, 1);
|
assert_eq!(txq.status().future, 1);
|
||||||
|
|
||||||
// now import second transaction to current
|
// now import second transaction to current
|
||||||
let res = txq.add(tx2.clone(), &default_account_details, TransactionOrigin::External);
|
let res = txq.add(tx2.clone(), TransactionOrigin::External, &default_account_details, &gas_estimator);
|
||||||
|
|
||||||
// then
|
// then
|
||||||
assert_eq!(res.unwrap(), TransactionImportResult::Current);
|
assert_eq!(res.unwrap(), TransactionImportResult::Current);
|
||||||
@ -1367,7 +1389,7 @@ mod test {
|
|||||||
let tx = new_tx_default();
|
let tx = new_tx_default();
|
||||||
|
|
||||||
// when
|
// when
|
||||||
let res = txq.add(tx, &default_account_details, TransactionOrigin::External);
|
let res = txq.add(tx, TransactionOrigin::External, &default_account_details, &gas_estimator);
|
||||||
|
|
||||||
// then
|
// then
|
||||||
assert_eq!(res.unwrap(), TransactionImportResult::Current);
|
assert_eq!(res.unwrap(), TransactionImportResult::Current);
|
||||||
@ -1386,10 +1408,10 @@ mod test {
|
|||||||
txq.set_minimal_gas_price(15.into());
|
txq.set_minimal_gas_price(15.into());
|
||||||
|
|
||||||
// when
|
// when
|
||||||
let res1 = txq.add(tx1, &default_account_details, TransactionOrigin::External);
|
let res1 = txq.add(tx1, TransactionOrigin::External, &default_account_details, &gas_estimator);
|
||||||
let res2 = txq.add(tx2, &default_account_details, TransactionOrigin::External);
|
let res2 = txq.add(tx2, TransactionOrigin::External, &default_account_details, &gas_estimator);
|
||||||
let res3 = txq.add(tx3, &default_account_details, TransactionOrigin::External);
|
let res3 = txq.add(tx3, TransactionOrigin::External, &default_account_details, &gas_estimator);
|
||||||
let res4 = txq.add(tx4, &default_account_details, TransactionOrigin::External);
|
let res4 = txq.add(tx4, TransactionOrigin::External, &default_account_details, &gas_estimator);
|
||||||
|
|
||||||
// then
|
// then
|
||||||
assert_eq!(res1.unwrap(), TransactionImportResult::Current);
|
assert_eq!(res1.unwrap(), TransactionImportResult::Current);
|
||||||
@ -1420,10 +1442,10 @@ mod test {
|
|||||||
txq.set_minimal_gas_price(15.into());
|
txq.set_minimal_gas_price(15.into());
|
||||||
|
|
||||||
// when
|
// when
|
||||||
let res1 = txq.add(tx1, &default_account_details, TransactionOrigin::External);
|
let res1 = txq.add(tx1, TransactionOrigin::External, &default_account_details, &gas_estimator);
|
||||||
let res2 = txq.add(tx2, &default_account_details, TransactionOrigin::External);
|
let res2 = txq.add(tx2, TransactionOrigin::External, &default_account_details, &gas_estimator);
|
||||||
let res3 = txq.add(tx3, &default_account_details, TransactionOrigin::External);
|
let res3 = txq.add(tx3, TransactionOrigin::External, &default_account_details, &gas_estimator);
|
||||||
let res4 = txq.add(tx4, &default_account_details, TransactionOrigin::External);
|
let res4 = txq.add(tx4, TransactionOrigin::External, &default_account_details, &gas_estimator);
|
||||||
|
|
||||||
// then
|
// then
|
||||||
assert_eq!(res1.unwrap(), TransactionImportResult::Current);
|
assert_eq!(res1.unwrap(), TransactionImportResult::Current);
|
||||||
@ -1466,7 +1488,7 @@ mod test {
|
|||||||
txq.set_gas_limit(limit);
|
txq.set_gas_limit(limit);
|
||||||
|
|
||||||
// when
|
// when
|
||||||
let res = txq.add(tx, &default_account_details, TransactionOrigin::External);
|
let res = txq.add(tx, TransactionOrigin::External, &default_account_details, &gas_estimator);
|
||||||
|
|
||||||
// then
|
// then
|
||||||
assert_eq!(unwrap_tx_err(res), TransactionError::GasLimitExceeded {
|
assert_eq!(unwrap_tx_err(res), TransactionError::GasLimitExceeded {
|
||||||
@ -1490,7 +1512,7 @@ mod test {
|
|||||||
};
|
};
|
||||||
|
|
||||||
// when
|
// when
|
||||||
let res = txq.add(tx, &account, TransactionOrigin::External);
|
let res = txq.add(tx, TransactionOrigin::External, &account, &gas_estimator);
|
||||||
|
|
||||||
// then
|
// then
|
||||||
assert_eq!(unwrap_tx_err(res), TransactionError::InsufficientBalance {
|
assert_eq!(unwrap_tx_err(res), TransactionError::InsufficientBalance {
|
||||||
@ -1510,7 +1532,7 @@ mod test {
|
|||||||
txq.set_minimal_gas_price(tx.gas_price + U256::one());
|
txq.set_minimal_gas_price(tx.gas_price + U256::one());
|
||||||
|
|
||||||
// when
|
// when
|
||||||
let res = txq.add(tx, &default_account_details, TransactionOrigin::External);
|
let res = txq.add(tx, TransactionOrigin::External, &default_account_details, &gas_estimator);
|
||||||
|
|
||||||
// then
|
// then
|
||||||
assert_eq!(unwrap_tx_err(res), TransactionError::InsufficientGasPrice {
|
assert_eq!(unwrap_tx_err(res), TransactionError::InsufficientGasPrice {
|
||||||
@ -1530,7 +1552,7 @@ mod test {
|
|||||||
txq.set_minimal_gas_price(tx.gas_price + U256::one());
|
txq.set_minimal_gas_price(tx.gas_price + U256::one());
|
||||||
|
|
||||||
// when
|
// when
|
||||||
let res = txq.add(tx, &default_account_details, TransactionOrigin::Local);
|
let res = txq.add(tx, TransactionOrigin::Local, &default_account_details, &gas_estimator);
|
||||||
|
|
||||||
// then
|
// then
|
||||||
assert_eq!(res.unwrap(), TransactionImportResult::Current);
|
assert_eq!(res.unwrap(), TransactionImportResult::Current);
|
||||||
@ -1560,7 +1582,7 @@ mod test {
|
|||||||
rlp::decode(s.as_raw())
|
rlp::decode(s.as_raw())
|
||||||
};
|
};
|
||||||
// when
|
// when
|
||||||
let res = txq.add(stx, &default_account_details, TransactionOrigin::External);
|
let res = txq.add(stx, TransactionOrigin::External, &default_account_details, &gas_estimator);
|
||||||
|
|
||||||
// then
|
// then
|
||||||
assert!(res.is_err());
|
assert!(res.is_err());
|
||||||
@ -1574,8 +1596,8 @@ mod test {
|
|||||||
let (tx, tx2) = new_tx_pair_default(1.into(), 0.into());
|
let (tx, tx2) = new_tx_pair_default(1.into(), 0.into());
|
||||||
|
|
||||||
// when
|
// when
|
||||||
txq.add(tx.clone(), &default_account_details, TransactionOrigin::External).unwrap();
|
txq.add(tx.clone(), TransactionOrigin::External, &default_account_details, &gas_estimator).unwrap();
|
||||||
txq.add(tx2.clone(), &default_account_details, TransactionOrigin::External).unwrap();
|
txq.add(tx2.clone(), TransactionOrigin::External, &default_account_details, &gas_estimator).unwrap();
|
||||||
|
|
||||||
// then
|
// then
|
||||||
let top = txq.top_transactions();
|
let top = txq.top_transactions();
|
||||||
@ -1594,9 +1616,9 @@ mod test {
|
|||||||
|
|
||||||
// when
|
// when
|
||||||
// first insert the one with higher gas price
|
// first insert the one with higher gas price
|
||||||
txq.add(tx2.clone(), &default_account_details, TransactionOrigin::External).unwrap();
|
txq.add(tx2.clone(), TransactionOrigin::External, &default_account_details, &gas_estimator).unwrap();
|
||||||
// then the one with lower gas price, but local
|
// then the one with lower gas price, but local
|
||||||
txq.add(tx.clone(), &default_account_details, TransactionOrigin::Local).unwrap();
|
txq.add(tx.clone(), TransactionOrigin::Local, &default_account_details, &gas_estimator).unwrap();
|
||||||
|
|
||||||
// then
|
// then
|
||||||
let top = txq.top_transactions();
|
let top = txq.top_transactions();
|
||||||
@ -1615,9 +1637,9 @@ mod test {
|
|||||||
|
|
||||||
// when
|
// when
|
||||||
// first insert local one with higher gas price
|
// first insert local one with higher gas price
|
||||||
txq.add(tx2.clone(), &default_account_details, TransactionOrigin::Local).unwrap();
|
txq.add(tx2.clone(), TransactionOrigin::Local, &default_account_details, &gas_estimator).unwrap();
|
||||||
// then the one with lower gas price, but from retracted block
|
// then the one with lower gas price, but from retracted block
|
||||||
txq.add(tx.clone(), &default_account_details, TransactionOrigin::RetractedBlock).unwrap();
|
txq.add(tx.clone(), TransactionOrigin::RetractedBlock, &default_account_details, &gas_estimator).unwrap();
|
||||||
|
|
||||||
// then
|
// then
|
||||||
let top = txq.top_transactions();
|
let top = txq.top_transactions();
|
||||||
@ -1633,8 +1655,8 @@ mod test {
|
|||||||
let (tx, tx2) = new_tx_pair_default(1.into(), 0.into());
|
let (tx, tx2) = new_tx_pair_default(1.into(), 0.into());
|
||||||
|
|
||||||
// when
|
// when
|
||||||
txq.add(tx.clone(), &default_account_details, TransactionOrigin::External).unwrap();
|
txq.add(tx.clone(), TransactionOrigin::External, &default_account_details, &gas_estimator).unwrap();
|
||||||
txq.add(tx2.clone(), &default_account_details, TransactionOrigin::Local).unwrap();
|
txq.add(tx2.clone(), TransactionOrigin::Local, &default_account_details, &gas_estimator).unwrap();
|
||||||
|
|
||||||
// then
|
// then
|
||||||
let top = txq.top_transactions();
|
let top = txq.top_transactions();
|
||||||
@ -1653,10 +1675,10 @@ mod test {
|
|||||||
let (tx1, tx2) = new_tx_pair_with_gas_price_increment(3.into());
|
let (tx1, tx2) = new_tx_pair_with_gas_price_increment(3.into());
|
||||||
|
|
||||||
// insert everything
|
// insert everything
|
||||||
txq.add(txa.clone(), &prev_nonce, TransactionOrigin::External).unwrap();
|
txq.add(txa.clone(), TransactionOrigin::External, &prev_nonce, &gas_estimator).unwrap();
|
||||||
txq.add(txb.clone(), &prev_nonce, TransactionOrigin::External).unwrap();
|
txq.add(txb.clone(), TransactionOrigin::External, &prev_nonce, &gas_estimator).unwrap();
|
||||||
txq.add(tx1.clone(), &prev_nonce, TransactionOrigin::External).unwrap();
|
txq.add(tx1.clone(), TransactionOrigin::External, &prev_nonce, &gas_estimator).unwrap();
|
||||||
txq.add(tx2.clone(), &prev_nonce, TransactionOrigin::External).unwrap();
|
txq.add(tx2.clone(), TransactionOrigin::External, &prev_nonce, &gas_estimator).unwrap();
|
||||||
|
|
||||||
assert_eq!(txq.status().future, 4);
|
assert_eq!(txq.status().future, 4);
|
||||||
|
|
||||||
@ -1682,10 +1704,10 @@ mod test {
|
|||||||
let (tx1, tx2) = new_tx_pair_with_gas_price_increment(3.into());
|
let (tx1, tx2) = new_tx_pair_with_gas_price_increment(3.into());
|
||||||
|
|
||||||
// insert everything
|
// insert everything
|
||||||
txq.add(txa.clone(), &default_account_details, TransactionOrigin::External).unwrap();
|
txq.add(txa.clone(), TransactionOrigin::External, &default_account_details, &gas_estimator).unwrap();
|
||||||
txq.add(txb.clone(), &default_account_details, TransactionOrigin::External).unwrap();
|
txq.add(txb.clone(), TransactionOrigin::External, &default_account_details, &gas_estimator).unwrap();
|
||||||
txq.add(tx1.clone(), &default_account_details, TransactionOrigin::External).unwrap();
|
txq.add(tx1.clone(), TransactionOrigin::External, &default_account_details, &gas_estimator).unwrap();
|
||||||
txq.add(tx2.clone(), &default_account_details, TransactionOrigin::External).unwrap();
|
txq.add(tx2.clone(), TransactionOrigin::External, &default_account_details, &gas_estimator).unwrap();
|
||||||
|
|
||||||
let top = txq.top_transactions();
|
let top = txq.top_transactions();
|
||||||
assert_eq!(top[0], tx1);
|
assert_eq!(top[0], tx1);
|
||||||
@ -1714,8 +1736,8 @@ mod test {
|
|||||||
let (tx, tx2) = new_tx_pair_default(1.into(), 0.into());
|
let (tx, tx2) = new_tx_pair_default(1.into(), 0.into());
|
||||||
|
|
||||||
// when
|
// when
|
||||||
txq.add(tx.clone(), &default_account_details, TransactionOrigin::External).unwrap();
|
txq.add(tx.clone(), TransactionOrigin::External, &default_account_details, &gas_estimator).unwrap();
|
||||||
txq.add(tx2.clone(), &default_account_details, TransactionOrigin::External).unwrap();
|
txq.add(tx2.clone(), TransactionOrigin::External, &default_account_details, &gas_estimator).unwrap();
|
||||||
|
|
||||||
// then
|
// then
|
||||||
let top = txq.pending_hashes();
|
let top = txq.pending_hashes();
|
||||||
@ -1732,8 +1754,8 @@ mod test {
|
|||||||
let (tx, tx2) = new_tx_pair_default(2.into(), 0.into());
|
let (tx, tx2) = new_tx_pair_default(2.into(), 0.into());
|
||||||
|
|
||||||
// when
|
// when
|
||||||
let res1 = txq.add(tx.clone(), &default_account_details, TransactionOrigin::External).unwrap();
|
let res1 = txq.add(tx.clone(), TransactionOrigin::External, &default_account_details, &gas_estimator).unwrap();
|
||||||
let res2 = txq.add(tx2.clone(), &default_account_details, TransactionOrigin::External).unwrap();
|
let res2 = txq.add(tx2.clone(), TransactionOrigin::External, &default_account_details, &gas_estimator).unwrap();
|
||||||
|
|
||||||
// then
|
// then
|
||||||
assert_eq!(res1, TransactionImportResult::Current);
|
assert_eq!(res1, TransactionImportResult::Current);
|
||||||
@ -1756,8 +1778,8 @@ mod test {
|
|||||||
let mut txq = TransactionQueue::default();
|
let mut txq = TransactionQueue::default();
|
||||||
|
|
||||||
let (tx, tx2) = new_tx_pair_default(1.into(), 0.into());
|
let (tx, tx2) = new_tx_pair_default(1.into(), 0.into());
|
||||||
txq.add(tx.clone(), &prev_nonce, TransactionOrigin::External).unwrap();
|
txq.add(tx.clone(), TransactionOrigin::External, &prev_nonce, &gas_estimator).unwrap();
|
||||||
txq.add(tx2.clone(), &prev_nonce, TransactionOrigin::External).unwrap();
|
txq.add(tx2.clone(), TransactionOrigin::External, &prev_nonce, &gas_estimator).unwrap();
|
||||||
assert_eq!(txq.status().future, 2);
|
assert_eq!(txq.status().future, 2);
|
||||||
|
|
||||||
// when
|
// when
|
||||||
@ -1779,13 +1801,13 @@ mod test {
|
|||||||
let tx1 = new_unsigned_tx(124.into(), default_gas_val(), 1.into()).sign(secret);
|
let tx1 = new_unsigned_tx(124.into(), default_gas_val(), 1.into()).sign(secret);
|
||||||
let tx2 = new_unsigned_tx(125.into(), default_gas_val(), 1.into()).sign(secret);
|
let tx2 = new_unsigned_tx(125.into(), default_gas_val(), 1.into()).sign(secret);
|
||||||
|
|
||||||
txq.add(tx, &default_account_details, TransactionOrigin::External).unwrap();
|
txq.add(tx, TransactionOrigin::External, &default_account_details, &gas_estimator).unwrap();
|
||||||
assert_eq!(txq.status().pending, 1);
|
assert_eq!(txq.status().pending, 1);
|
||||||
txq.add(tx2, &default_account_details, TransactionOrigin::External).unwrap();
|
txq.add(tx2, TransactionOrigin::External, &default_account_details, &gas_estimator).unwrap();
|
||||||
assert_eq!(txq.status().future, 1);
|
assert_eq!(txq.status().future, 1);
|
||||||
|
|
||||||
// when
|
// when
|
||||||
txq.add(tx1, &default_account_details, TransactionOrigin::External).unwrap();
|
txq.add(tx1, TransactionOrigin::External, &default_account_details, &gas_estimator).unwrap();
|
||||||
|
|
||||||
// then
|
// then
|
||||||
let stats = txq.status();
|
let stats = txq.status();
|
||||||
@ -1801,8 +1823,8 @@ mod test {
|
|||||||
// given
|
// given
|
||||||
let mut txq2 = TransactionQueue::default();
|
let mut txq2 = TransactionQueue::default();
|
||||||
let (tx, tx2) = new_tx_pair_default(3.into(), 0.into());
|
let (tx, tx2) = new_tx_pair_default(3.into(), 0.into());
|
||||||
txq2.add(tx.clone(), &default_account_details, TransactionOrigin::External).unwrap();
|
txq2.add(tx.clone(), TransactionOrigin::External, &default_account_details, &gas_estimator).unwrap();
|
||||||
txq2.add(tx2.clone(), &default_account_details, TransactionOrigin::External).unwrap();
|
txq2.add(tx2.clone(), TransactionOrigin::External, &default_account_details, &gas_estimator).unwrap();
|
||||||
assert_eq!(txq2.status().pending, 1);
|
assert_eq!(txq2.status().pending, 1);
|
||||||
assert_eq!(txq2.status().future, 1);
|
assert_eq!(txq2.status().future, 1);
|
||||||
|
|
||||||
@ -1823,10 +1845,10 @@ mod test {
|
|||||||
let mut txq = TransactionQueue::default();
|
let mut txq = TransactionQueue::default();
|
||||||
let (tx, tx2) = new_tx_pair_default(1.into(), 0.into());
|
let (tx, tx2) = new_tx_pair_default(1.into(), 0.into());
|
||||||
let tx3 = new_tx_default();
|
let tx3 = new_tx_default();
|
||||||
txq.add(tx2.clone(), &default_account_details, TransactionOrigin::External).unwrap();
|
txq.add(tx2.clone(), TransactionOrigin::External, &default_account_details, &gas_estimator).unwrap();
|
||||||
assert_eq!(txq.status().future, 1);
|
assert_eq!(txq.status().future, 1);
|
||||||
txq.add(tx3.clone(), &default_account_details, TransactionOrigin::External).unwrap();
|
txq.add(tx3.clone(), TransactionOrigin::External, &default_account_details, &gas_estimator).unwrap();
|
||||||
txq.add(tx.clone(), &default_account_details, TransactionOrigin::External).unwrap();
|
txq.add(tx.clone(), TransactionOrigin::External, &default_account_details, &gas_estimator).unwrap();
|
||||||
assert_eq!(txq.status().pending, 3);
|
assert_eq!(txq.status().pending, 3);
|
||||||
|
|
||||||
// when
|
// when
|
||||||
@ -1845,8 +1867,8 @@ mod test {
|
|||||||
let (tx, tx2) = new_tx_pair_default(1.into(), 0.into());
|
let (tx, tx2) = new_tx_pair_default(1.into(), 0.into());
|
||||||
|
|
||||||
// add
|
// add
|
||||||
txq.add(tx2.clone(), &default_account_details, TransactionOrigin::External).unwrap();
|
txq.add(tx2.clone(), TransactionOrigin::External, &default_account_details, &gas_estimator).unwrap();
|
||||||
txq.add(tx.clone(), &default_account_details, TransactionOrigin::External).unwrap();
|
txq.add(tx.clone(), TransactionOrigin::External, &default_account_details, &gas_estimator).unwrap();
|
||||||
let stats = txq.status();
|
let stats = txq.status();
|
||||||
assert_eq!(stats.pending, 2);
|
assert_eq!(stats.pending, 2);
|
||||||
|
|
||||||
@ -1865,11 +1887,11 @@ mod test {
|
|||||||
let (tx, tx2) = new_tx_pair_default(1.into(), 0.into());
|
let (tx, tx2) = new_tx_pair_default(1.into(), 0.into());
|
||||||
let sender = tx.sender().unwrap();
|
let sender = tx.sender().unwrap();
|
||||||
let nonce = tx.nonce;
|
let nonce = tx.nonce;
|
||||||
txq.add(tx.clone(), &default_account_details, TransactionOrigin::External).unwrap();
|
txq.add(tx.clone(), TransactionOrigin::External, &default_account_details, &gas_estimator).unwrap();
|
||||||
assert_eq!(txq.status().pending, 1);
|
assert_eq!(txq.status().pending, 1);
|
||||||
|
|
||||||
// when
|
// when
|
||||||
let res = txq.add(tx2.clone(), &default_account_details, TransactionOrigin::External);
|
let res = txq.add(tx2.clone(), TransactionOrigin::External, &default_account_details, &gas_estimator);
|
||||||
|
|
||||||
// then
|
// then
|
||||||
let t = txq.top_transactions();
|
let t = txq.top_transactions();
|
||||||
@ -1886,14 +1908,14 @@ mod test {
|
|||||||
txq.current.set_limit(10);
|
txq.current.set_limit(10);
|
||||||
let (tx1, tx2) = new_tx_pair_default(4.into(), 1.into());
|
let (tx1, tx2) = new_tx_pair_default(4.into(), 1.into());
|
||||||
let (tx3, tx4) = new_tx_pair_default(4.into(), 2.into());
|
let (tx3, tx4) = new_tx_pair_default(4.into(), 2.into());
|
||||||
txq.add(tx1.clone(), &default_account_details, TransactionOrigin::External).unwrap();
|
txq.add(tx1.clone(), TransactionOrigin::External, &default_account_details, &gas_estimator).unwrap();
|
||||||
txq.add(tx3.clone(), &default_account_details, TransactionOrigin::External).unwrap();
|
txq.add(tx3.clone(), TransactionOrigin::External, &default_account_details, &gas_estimator).unwrap();
|
||||||
assert_eq!(txq.status().pending, 2);
|
assert_eq!(txq.status().pending, 2);
|
||||||
|
|
||||||
// when
|
// when
|
||||||
txq.add(tx2.clone(), &default_account_details, TransactionOrigin::External).unwrap();
|
txq.add(tx2.clone(), TransactionOrigin::External, &default_account_details, &gas_estimator).unwrap();
|
||||||
assert_eq!(txq.status().future, 1);
|
assert_eq!(txq.status().future, 1);
|
||||||
txq.add(tx4.clone(), &default_account_details, TransactionOrigin::External).unwrap();
|
txq.add(tx4.clone(), TransactionOrigin::External, &default_account_details, &gas_estimator).unwrap();
|
||||||
|
|
||||||
// then
|
// then
|
||||||
assert_eq!(txq.status().future, 1);
|
assert_eq!(txq.status().future, 1);
|
||||||
@ -1904,11 +1926,11 @@ mod test {
|
|||||||
let mut txq = TransactionQueue::with_limits(PrioritizationStrategy::GasPriceOnly, 100, default_gas_val() * U256::from(2), !U256::zero());
|
let mut txq = TransactionQueue::with_limits(PrioritizationStrategy::GasPriceOnly, 100, default_gas_val() * U256::from(2), !U256::zero());
|
||||||
let (tx1, tx2) = new_tx_pair_default(U256::from(1), U256::from(1));
|
let (tx1, tx2) = new_tx_pair_default(U256::from(1), U256::from(1));
|
||||||
let (tx3, tx4) = new_tx_pair_default(U256::from(1), U256::from(2));
|
let (tx3, tx4) = new_tx_pair_default(U256::from(1), U256::from(2));
|
||||||
txq.add(tx1.clone(), &default_account_details, TransactionOrigin::External).unwrap();
|
txq.add(tx1.clone(), TransactionOrigin::External, &default_account_details, &gas_estimator).unwrap();
|
||||||
txq.add(tx2.clone(), &default_account_details, TransactionOrigin::External).unwrap();
|
txq.add(tx2.clone(), TransactionOrigin::External, &default_account_details, &gas_estimator).unwrap();
|
||||||
txq.add(tx3.clone(), &default_account_details, TransactionOrigin::External).unwrap();
|
txq.add(tx3.clone(), TransactionOrigin::External, &default_account_details, &gas_estimator).unwrap();
|
||||||
// limited by gas
|
// limited by gas
|
||||||
txq.add(tx4.clone(), &default_account_details, TransactionOrigin::External).unwrap_err();
|
txq.add(tx4.clone(), TransactionOrigin::External, &default_account_details, &gas_estimator).unwrap_err();
|
||||||
assert_eq!(txq.status().pending, 2);
|
assert_eq!(txq.status().pending, 2);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1918,13 +1940,13 @@ mod test {
|
|||||||
let (tx1, tx2) = new_tx_pair_default(U256::from(1), U256::from(1));
|
let (tx1, tx2) = new_tx_pair_default(U256::from(1), U256::from(1));
|
||||||
let (tx3, tx4) = new_tx_pair_default(U256::from(1), U256::from(2));
|
let (tx3, tx4) = new_tx_pair_default(U256::from(1), U256::from(2));
|
||||||
let (tx5, tx6) = new_tx_pair_default(U256::from(1), U256::from(2));
|
let (tx5, tx6) = new_tx_pair_default(U256::from(1), U256::from(2));
|
||||||
txq.add(tx1.clone(), &default_account_details, TransactionOrigin::Local).unwrap();
|
txq.add(tx1.clone(), TransactionOrigin::Local, &default_account_details, &gas_estimator).unwrap();
|
||||||
txq.add(tx2.clone(), &default_account_details, TransactionOrigin::Local).unwrap();
|
txq.add(tx2.clone(), TransactionOrigin::Local, &default_account_details, &gas_estimator).unwrap();
|
||||||
txq.add(tx5.clone(), &default_account_details, TransactionOrigin::External).unwrap();
|
txq.add(tx5.clone(), TransactionOrigin::External, &default_account_details, &gas_estimator).unwrap();
|
||||||
// Not accepted because of limit
|
// Not accepted because of limit
|
||||||
txq.add(tx6.clone(), &default_account_details, TransactionOrigin::External).unwrap_err();
|
txq.add(tx6.clone(), TransactionOrigin::External, &default_account_details, &gas_estimator).unwrap_err();
|
||||||
txq.add(tx3.clone(), &default_account_details, TransactionOrigin::Local).unwrap();
|
txq.add(tx3.clone(), TransactionOrigin::Local, &default_account_details, &gas_estimator).unwrap();
|
||||||
txq.add(tx4.clone(), &default_account_details, TransactionOrigin::Local).unwrap();
|
txq.add(tx4.clone(), TransactionOrigin::Local, &default_account_details, &gas_estimator).unwrap();
|
||||||
assert_eq!(txq.status().pending, 4);
|
assert_eq!(txq.status().pending, 4);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1936,7 +1958,7 @@ mod test {
|
|||||||
let fetch_last_nonce = |_a: &Address| AccountDetails { nonce: last_nonce, balance: !U256::zero() };
|
let fetch_last_nonce = |_a: &Address| AccountDetails { nonce: last_nonce, balance: !U256::zero() };
|
||||||
|
|
||||||
// when
|
// when
|
||||||
let res = txq.add(tx, &fetch_last_nonce, TransactionOrigin::External);
|
let res = txq.add(tx, TransactionOrigin::External, &fetch_last_nonce, &gas_estimator);
|
||||||
|
|
||||||
// then
|
// then
|
||||||
assert_eq!(unwrap_tx_err(res), TransactionError::Old);
|
assert_eq!(unwrap_tx_err(res), TransactionError::Old);
|
||||||
@ -1952,12 +1974,12 @@ mod test {
|
|||||||
balance: !U256::zero() };
|
balance: !U256::zero() };
|
||||||
let mut txq = TransactionQueue::default();
|
let mut txq = TransactionQueue::default();
|
||||||
let (_tx1, tx2) = new_tx_pair_default(1.into(), 0.into());
|
let (_tx1, tx2) = new_tx_pair_default(1.into(), 0.into());
|
||||||
txq.add(tx2.clone(), &default_account_details, TransactionOrigin::External).unwrap();
|
txq.add(tx2.clone(), TransactionOrigin::External, &default_account_details, &gas_estimator).unwrap();
|
||||||
assert_eq!(txq.status().future, 1);
|
assert_eq!(txq.status().future, 1);
|
||||||
assert_eq!(txq.status().pending, 0);
|
assert_eq!(txq.status().pending, 0);
|
||||||
|
|
||||||
// when
|
// when
|
||||||
let res = txq.add(tx2.clone(), &nonce, TransactionOrigin::External);
|
let res = txq.add(tx2.clone(), TransactionOrigin::External, &nonce, &gas_estimator);
|
||||||
|
|
||||||
// then
|
// then
|
||||||
assert_eq!(unwrap_tx_err(res), TransactionError::AlreadyImported);
|
assert_eq!(unwrap_tx_err(res), TransactionError::AlreadyImported);
|
||||||
@ -1971,15 +1993,15 @@ mod test {
|
|||||||
// given
|
// given
|
||||||
let mut txq = TransactionQueue::default();
|
let mut txq = TransactionQueue::default();
|
||||||
let (tx1, tx2) = new_tx_pair_default(1.into(), 0.into());
|
let (tx1, tx2) = new_tx_pair_default(1.into(), 0.into());
|
||||||
txq.add(tx1.clone(), &default_account_details, TransactionOrigin::External).unwrap();
|
txq.add(tx1.clone(), TransactionOrigin::External, &default_account_details, &gas_estimator).unwrap();
|
||||||
txq.add(tx2.clone(), &default_account_details, TransactionOrigin::External).unwrap();
|
txq.add(tx2.clone(), TransactionOrigin::External, &default_account_details, &gas_estimator).unwrap();
|
||||||
assert_eq!(txq.status().pending, 2);
|
assert_eq!(txq.status().pending, 2);
|
||||||
|
|
||||||
// when
|
// when
|
||||||
txq.remove_invalid(&tx1.hash(), &default_account_details);
|
txq.remove_invalid(&tx1.hash(), &default_account_details);
|
||||||
assert_eq!(txq.status().pending, 0);
|
assert_eq!(txq.status().pending, 0);
|
||||||
assert_eq!(txq.status().future, 1);
|
assert_eq!(txq.status().future, 1);
|
||||||
txq.add(tx1.clone(), &default_account_details, TransactionOrigin::External).unwrap();
|
txq.add(tx1.clone(), TransactionOrigin::External, &default_account_details, &gas_estimator).unwrap();
|
||||||
|
|
||||||
// then
|
// then
|
||||||
let stats = txq.status();
|
let stats = txq.status();
|
||||||
@ -1993,10 +2015,10 @@ mod test {
|
|||||||
let mut txq = TransactionQueue::default();
|
let mut txq = TransactionQueue::default();
|
||||||
let (tx, tx2) = new_tx_pair_default(1.into(), 0.into());
|
let (tx, tx2) = new_tx_pair_default(1.into(), 0.into());
|
||||||
let tx3 = new_tx_default();
|
let tx3 = new_tx_default();
|
||||||
txq.add(tx2.clone(), &default_account_details, TransactionOrigin::External).unwrap();
|
txq.add(tx2.clone(), TransactionOrigin::External, &default_account_details, &gas_estimator).unwrap();
|
||||||
assert_eq!(txq.status().future, 1);
|
assert_eq!(txq.status().future, 1);
|
||||||
txq.add(tx3.clone(), &default_account_details, TransactionOrigin::External).unwrap();
|
txq.add(tx3.clone(), TransactionOrigin::External, &default_account_details, &gas_estimator).unwrap();
|
||||||
txq.add(tx.clone(), &default_account_details, TransactionOrigin::External).unwrap();
|
txq.add(tx.clone(), TransactionOrigin::External, &default_account_details, &gas_estimator).unwrap();
|
||||||
assert_eq!(txq.status().pending, 3);
|
assert_eq!(txq.status().pending, 3);
|
||||||
|
|
||||||
// when
|
// when
|
||||||
@ -2023,8 +2045,8 @@ mod test {
|
|||||||
};
|
};
|
||||||
|
|
||||||
// when
|
// when
|
||||||
txq.add(tx, &default_account_details, TransactionOrigin::External).unwrap();
|
txq.add(tx, TransactionOrigin::External, &default_account_details, &gas_estimator).unwrap();
|
||||||
txq.add(tx2, &default_account_details, TransactionOrigin::External).unwrap();
|
txq.add(tx2, TransactionOrigin::External, &default_account_details, &gas_estimator).unwrap();
|
||||||
|
|
||||||
// then
|
// then
|
||||||
let stats = txq.status();
|
let stats = txq.status();
|
||||||
@ -2051,10 +2073,10 @@ mod test {
|
|||||||
};
|
};
|
||||||
|
|
||||||
// when
|
// when
|
||||||
txq.add(tx1, &default_account_details, TransactionOrigin::External).unwrap();
|
txq.add(tx1, TransactionOrigin::External, &default_account_details, &gas_estimator).unwrap();
|
||||||
txq.add(tx2, &default_account_details, TransactionOrigin::External).unwrap();
|
txq.add(tx2, TransactionOrigin::External, &default_account_details, &gas_estimator).unwrap();
|
||||||
assert_eq!(txq.status().future, 1);
|
assert_eq!(txq.status().future, 1);
|
||||||
txq.add(tx0, &default_account_details, TransactionOrigin::External).unwrap();
|
txq.add(tx0, TransactionOrigin::External, &default_account_details, &gas_estimator).unwrap();
|
||||||
|
|
||||||
// then
|
// then
|
||||||
let stats = txq.status();
|
let stats = txq.status();
|
||||||
@ -2072,8 +2094,8 @@ mod test {
|
|||||||
!U256::zero() };
|
!U256::zero() };
|
||||||
let mut txq = TransactionQueue::default();
|
let mut txq = TransactionQueue::default();
|
||||||
let (tx1, tx2) = new_tx_pair_default(1.into(), 0.into());
|
let (tx1, tx2) = new_tx_pair_default(1.into(), 0.into());
|
||||||
txq.add(tx1.clone(), &previous_nonce, TransactionOrigin::External).unwrap();
|
txq.add(tx1.clone(), TransactionOrigin::External, &previous_nonce, &gas_estimator).unwrap();
|
||||||
txq.add(tx2, &previous_nonce, TransactionOrigin::External).unwrap();
|
txq.add(tx2, TransactionOrigin::External, &previous_nonce, &gas_estimator).unwrap();
|
||||||
assert_eq!(txq.status().future, 2);
|
assert_eq!(txq.status().future, 2);
|
||||||
|
|
||||||
// when
|
// when
|
||||||
@ -2104,7 +2126,7 @@ mod test {
|
|||||||
let details = |_a: &Address| AccountDetails { nonce: nonce, balance: !U256::zero() };
|
let details = |_a: &Address| AccountDetails { nonce: nonce, balance: !U256::zero() };
|
||||||
|
|
||||||
// when
|
// when
|
||||||
txq.add(tx, &details, TransactionOrigin::External).unwrap();
|
txq.add(tx, TransactionOrigin::External, &details, &gas_estimator).unwrap();
|
||||||
|
|
||||||
// then
|
// then
|
||||||
assert_eq!(txq.last_nonce(&from), Some(nonce));
|
assert_eq!(txq.last_nonce(&from), Some(nonce));
|
||||||
@ -2119,7 +2141,7 @@ mod test {
|
|||||||
let details1 = |_a: &Address| AccountDetails { nonce: nonce1, balance: !U256::zero() };
|
let details1 = |_a: &Address| AccountDetails { nonce: nonce1, balance: !U256::zero() };
|
||||||
|
|
||||||
// Insert first transaction
|
// Insert first transaction
|
||||||
txq.add(tx1, &details1, TransactionOrigin::External).unwrap();
|
txq.add(tx1, TransactionOrigin::External, &details1, &gas_estimator).unwrap();
|
||||||
|
|
||||||
// when
|
// when
|
||||||
txq.remove_all(tx2.sender().unwrap(), nonce2 + U256::one());
|
txq.remove_all(tx2.sender().unwrap(), nonce2 + U256::one());
|
||||||
@ -2139,9 +2161,9 @@ mod test {
|
|||||||
|
|
||||||
// when
|
// when
|
||||||
// Insert first transaction
|
// Insert first transaction
|
||||||
assert_eq!(txq.add(tx1, &details1, TransactionOrigin::External).unwrap(), TransactionImportResult::Current);
|
assert_eq!(txq.add(tx1, TransactionOrigin::External, &details1, &gas_estimator).unwrap(), TransactionImportResult::Current);
|
||||||
// Second should go to future
|
// Second should go to future
|
||||||
assert_eq!(txq.add(tx2, &details1, TransactionOrigin::External).unwrap(), TransactionImportResult::Future);
|
assert_eq!(txq.add(tx2, TransactionOrigin::External, &details1, &gas_estimator).unwrap(), TransactionImportResult::Future);
|
||||||
// Now block is imported
|
// Now block is imported
|
||||||
txq.remove_all(sender, nonce2 - U256::from(1));
|
txq.remove_all(sender, nonce2 - U256::from(1));
|
||||||
// tx2 should be not be promoted to current
|
// tx2 should be not be promoted to current
|
||||||
@ -2160,9 +2182,9 @@ mod test {
|
|||||||
assert_eq!(txq.has_local_pending_transactions(), false);
|
assert_eq!(txq.has_local_pending_transactions(), false);
|
||||||
|
|
||||||
// when
|
// when
|
||||||
assert_eq!(txq.add(tx1, &default_account_details, TransactionOrigin::External).unwrap(), TransactionImportResult::Current);
|
assert_eq!(txq.add(tx1, TransactionOrigin::External, &default_account_details, &gas_estimator).unwrap(), TransactionImportResult::Current);
|
||||||
assert_eq!(txq.has_local_pending_transactions(), false);
|
assert_eq!(txq.has_local_pending_transactions(), false);
|
||||||
assert_eq!(txq.add(tx2, &default_account_details, TransactionOrigin::Local).unwrap(), TransactionImportResult::Current);
|
assert_eq!(txq.add(tx2, TransactionOrigin::Local, &default_account_details, &gas_estimator).unwrap(), TransactionImportResult::Current);
|
||||||
|
|
||||||
// then
|
// then
|
||||||
assert_eq!(txq.has_local_pending_transactions(), true);
|
assert_eq!(txq.has_local_pending_transactions(), true);
|
||||||
@ -2177,8 +2199,8 @@ mod test {
|
|||||||
default_account_details(a).balance };
|
default_account_details(a).balance };
|
||||||
|
|
||||||
// when
|
// when
|
||||||
assert_eq!(txq.add(tx2, &prev_nonce, TransactionOrigin::External).unwrap(), TransactionImportResult::Future);
|
assert_eq!(txq.add(tx2, TransactionOrigin::External, &prev_nonce, &gas_estimator).unwrap(), TransactionImportResult::Future);
|
||||||
assert_eq!(txq.add(tx1.clone(), &prev_nonce, TransactionOrigin::External).unwrap(), TransactionImportResult::Future);
|
assert_eq!(txq.add(tx1.clone(), TransactionOrigin::External, &prev_nonce, &gas_estimator).unwrap(), TransactionImportResult::Future);
|
||||||
|
|
||||||
// then
|
// then
|
||||||
assert_eq!(txq.future.by_priority.len(), 1);
|
assert_eq!(txq.future.by_priority.len(), 1);
|
||||||
@ -2203,14 +2225,14 @@ mod test {
|
|||||||
(tx.sign(secret), tx2.sign(secret), tx2_2.sign(secret), tx3.sign(secret))
|
(tx.sign(secret), tx2.sign(secret), tx2_2.sign(secret), tx3.sign(secret))
|
||||||
};
|
};
|
||||||
let sender = tx1.sender().unwrap();
|
let sender = tx1.sender().unwrap();
|
||||||
txq.add(tx1, &default_account_details, TransactionOrigin::Local).unwrap();
|
txq.add(tx1, TransactionOrigin::Local, &default_account_details, &gas_estimator).unwrap();
|
||||||
txq.add(tx2, &default_account_details, TransactionOrigin::Local).unwrap();
|
txq.add(tx2, TransactionOrigin::Local, &default_account_details, &gas_estimator).unwrap();
|
||||||
txq.add(tx3, &default_account_details, TransactionOrigin::Local).unwrap();
|
txq.add(tx3, TransactionOrigin::Local, &default_account_details, &gas_estimator).unwrap();
|
||||||
assert_eq!(txq.future.by_priority.len(), 0);
|
assert_eq!(txq.future.by_priority.len(), 0);
|
||||||
assert_eq!(txq.current.by_priority.len(), 3);
|
assert_eq!(txq.current.by_priority.len(), 3);
|
||||||
|
|
||||||
// when
|
// when
|
||||||
let res = txq.add(tx2_2, &default_account_details, TransactionOrigin::Local);
|
let res = txq.add(tx2_2, TransactionOrigin::Local, &default_account_details, &gas_estimator);
|
||||||
|
|
||||||
// then
|
// then
|
||||||
assert_eq!(txq.last_nonce(&sender).unwrap(), 125.into());
|
assert_eq!(txq.last_nonce(&sender).unwrap(), 125.into());
|
||||||
@ -2218,4 +2240,24 @@ mod test {
|
|||||||
assert_eq!(txq.current.by_priority.len(), 3);
|
assert_eq!(txq.current.by_priority.len(), 3);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn should_reject_transactions_below_bas_gas() {
|
||||||
|
// given
|
||||||
|
let mut txq = TransactionQueue::default();
|
||||||
|
let (tx1, tx2) = new_tx_pair_default(1.into(), 0.into());
|
||||||
|
let high_gas = |_: &SignedTransaction| 100_001.into();
|
||||||
|
|
||||||
|
// when
|
||||||
|
let res1 = txq.add(tx1, TransactionOrigin::Local, &default_account_details, &gas_estimator);
|
||||||
|
let res2 = txq.add(tx2, TransactionOrigin::Local, &default_account_details, &high_gas);
|
||||||
|
|
||||||
|
// then
|
||||||
|
assert_eq!(res1.unwrap(), TransactionImportResult::Current);
|
||||||
|
assert_eq!(unwrap_tx_err(res2), TransactionError::InsufficientGas {
|
||||||
|
minimal: 100_001.into(),
|
||||||
|
got: 100_000.into(),
|
||||||
|
});
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -221,6 +221,9 @@ pub fn from_transaction_error(error: EthcoreError) -> Error {
|
|||||||
LimitReached => {
|
LimitReached => {
|
||||||
"There are too many transactions in the queue. Your transaction was dropped due to limit. Try increasing the fee.".into()
|
"There are too many transactions in the queue. Your transaction was dropped due to limit. Try increasing the fee.".into()
|
||||||
},
|
},
|
||||||
|
InsufficientGas { minimal, got } => {
|
||||||
|
format!("Transaction gas is too low. There is not enough gas to cover minimal cost of the transaction (minimal: {}, got: {}). Try increasing supplied gas.", minimal, got)
|
||||||
|
},
|
||||||
InsufficientGasPrice { minimal, got } => {
|
InsufficientGasPrice { minimal, got } => {
|
||||||
format!("Transaction gas price is too low. It does not satisfy your node's minimal gas price (minimal: {}, got: {}). Try increasing the gas price.", minimal, got)
|
format!("Transaction gas price is too low. It does not satisfy your node's minimal gas price (minimal: {}, got: {}). Try increasing the gas price.", minimal, got)
|
||||||
},
|
},
|
||||||
|
Loading…
Reference in New Issue
Block a user