diff --git a/core/src/consensus.rs b/core/src/consensus.rs index ee3e36b7..8fd1610a 100644 --- a/core/src/consensus.rs +++ b/core/src/consensus.rs @@ -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 diff --git a/core/src/core/transaction.rs b/core/src/core/transaction.rs index 44d57565..ee7db3d5 100644 --- a/core/src/core/transaction.rs +++ b/core/src/core/transaction.rs @@ -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 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()?; }