Return error if RLP size of transaction exceeds the limit (#8473)
* Return error if RLP size of transaction exceeds the limit * Review comments fixed * RLP check moved to verifier, corresponding pool test added
This commit is contained in:
committed by
Afri Schoedon
parent
9376796bdb
commit
01d399ad66
@@ -15,17 +15,21 @@
|
||||
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
use ethereum_types::{U256, H256, Address};
|
||||
use rlp::Rlp;
|
||||
use transaction::{self, Transaction, SignedTransaction, UnverifiedTransaction};
|
||||
|
||||
use pool;
|
||||
use pool::client::AccountDetails;
|
||||
|
||||
const MAX_TRANSACTION_SIZE: usize = 15 * 1024;
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct TestClient {
|
||||
account_details: AccountDetails,
|
||||
gas_required: U256,
|
||||
is_service_transaction: bool,
|
||||
local_address: Address,
|
||||
max_transaction_size: usize,
|
||||
}
|
||||
|
||||
impl Default for TestClient {
|
||||
@@ -39,6 +43,7 @@ impl Default for TestClient {
|
||||
gas_required: 21_000.into(),
|
||||
is_service_transaction: false,
|
||||
local_address: Default::default(),
|
||||
max_transaction_size: MAX_TRANSACTION_SIZE,
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -116,6 +121,15 @@ impl pool::client::Client for TestClient {
|
||||
pool::client::TransactionType::Regular
|
||||
}
|
||||
}
|
||||
|
||||
fn decode_transaction(&self, transaction: &[u8]) -> Result<UnverifiedTransaction, transaction::Error> {
|
||||
let rlp = Rlp::new(&transaction);
|
||||
if rlp.as_raw().len() > self.max_transaction_size {
|
||||
return Err(transaction::Error::TooBig)
|
||||
}
|
||||
rlp.as_val().map_err(|e| transaction::Error::InvalidRlp(e.to_string()))
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
impl pool::client::NonceClient for TestClient {
|
||||
|
||||
@@ -755,3 +755,13 @@ fn should_clear_cache_after_timeout_for_local() {
|
||||
// then
|
||||
assert_eq!(txq.pending(TestClient::new(), 0, 1002, None).len(), 2);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn should_reject_big_transaction() {
|
||||
let txq = new_queue();
|
||||
let big_tx = Tx::default().big_one();
|
||||
let res = txq.import(TestClient::new(), vec![
|
||||
verifier::Transaction::Local(PendingTransaction::new(big_tx, transaction::Condition::Timestamp(1000).into()))
|
||||
]);
|
||||
assert_eq!(res, vec![Err(transaction::Error::TooBig)]);
|
||||
}
|
||||
@@ -87,6 +87,19 @@ impl Tx {
|
||||
nonce: self.nonce.into()
|
||||
}
|
||||
}
|
||||
|
||||
pub fn big_one(self) -> SignedTransaction {
|
||||
let keypair = Random.generate().unwrap();
|
||||
let tx = Transaction {
|
||||
action: transaction::Action::Create,
|
||||
value: U256::from(100),
|
||||
data: include_str!("../res/big_transaction.data").from_hex().unwrap(),
|
||||
gas: self.gas.into(),
|
||||
gas_price: self.gas_price.into(),
|
||||
nonce: self.nonce.into()
|
||||
};
|
||||
tx.sign(keypair.secret(), None)
|
||||
}
|
||||
}
|
||||
pub trait TxExt: Sized {
|
||||
type Out;
|
||||
|
||||
Reference in New Issue
Block a user