[CONSENSUS] Limit number of inputs in a block #261 (#328)

* Limit number of inputs in a block, fix #261
* MAX_BLOCK_INPUTS = 300_000 // IO-time bound DoS protection. 5MB/s disk random reads gives ~150k UTXO lookups/s, so set limit at 300k UTXO inputs
This commit is contained in:
Simon B 2017-11-20 01:59:07 +01:00 committed by Ignotus Peverell
parent 4b3a374d98
commit fed0bd3ed3
2 changed files with 11 additions and 0 deletions

View file

@ -85,10 +85,15 @@ pub const BLOCK_KERNEL_WEIGHT: usize = 2;
/// Total maximum block weight
pub const MAX_BLOCK_WEIGHT: usize = 80_000;
/// Maximum inputs for a block (issue#261)
/// Hundreds of inputs + 1 output might be slow to validate (issue#258)
pub const MAX_BLOCK_INPUTS: usize = 300_000; // soft fork down when too_high
/// Whether a block exceeds the maximum acceptable weight
pub fn exceeds_weight(input_len: usize, output_len: usize, kernel_len: usize) -> bool {
input_len * BLOCK_INPUT_WEIGHT + output_len * BLOCK_OUTPUT_WEIGHT
+ kernel_len * BLOCK_KERNEL_WEIGHT > MAX_BLOCK_WEIGHT
|| input_len > MAX_BLOCK_INPUTS
}
/// Fork every 250,000 blocks for first 2 years, simple number and just a

View file

@ -22,6 +22,7 @@ use util::secp::pedersen::{Commitment, RangeProof};
use std::cmp::Ordering;
use std::ops;
use consensus;
use core::Committed;
use core::hash::Hashed;
use core::pmmr::Summable;
@ -72,6 +73,8 @@ pub enum Error {
/// Underlying Secp256k1 error (signature validation or invalid public
/// key typically)
Secp(secp::Error),
/// Restrict number of incoming inputs
TooManyInputs,
}
impl From<secp::Error> for Error {
@ -347,6 +350,9 @@ impl Transaction {
if self.fee & 1 != 0 {
return Err(Error::OddFee);
}
if self.inputs.len() > consensus::MAX_BLOCK_INPUTS {
return Err(Error::TooManyInputs);
}
for out in &self.outputs {
out.verify_proof()?;
}