Merge pull request #2273 from gavinandresen/txsize

Make transactions larger than 100K non-standard
This commit is contained in:
Gavin Andresen 2013-02-05 07:12:27 -08:00
commit 1d0851eca8
3 changed files with 11 additions and 1 deletions

View file

@ -362,6 +362,14 @@ bool CTransaction::IsStandard() const
if (!IsFinal()) if (!IsFinal())
return false; return false;
// Extremely large transactions with lots of inputs can cost the network
// almost as much to process as they cost the sender in fees, because
// computing signature hashes is O(ninputs*txsize). Limiting transactions
// to MAX_STANDARD_TX_SIZE mitigates CPU exhaustion attacks.
unsigned int sz = this->GetSerializeSize(SER_NETWORK, CTransaction::CURRENT_VERSION);
if (sz >= MAX_STANDARD_TX_SIZE)
return false;
BOOST_FOREACH(const CTxIn& txin, vin) BOOST_FOREACH(const CTxIn& txin, vin)
{ {
// Biggest 'standard' txin is a 3-signature 3-of-3 CHECKMULTISIG // Biggest 'standard' txin is a 3-signature 3-of-3 CHECKMULTISIG

View file

@ -28,6 +28,8 @@ struct CBlockIndexWorkComparator;
static const unsigned int MAX_BLOCK_SIZE = 1000000; static const unsigned int MAX_BLOCK_SIZE = 1000000;
/** The maximum size for mined blocks */ /** The maximum size for mined blocks */
static const unsigned int MAX_BLOCK_SIZE_GEN = MAX_BLOCK_SIZE/2; static const unsigned int MAX_BLOCK_SIZE_GEN = MAX_BLOCK_SIZE/2;
/** The maximum size for transactions we're willing to relay/mine **/
static const unsigned int MAX_STANDARD_TX_SIZE = MAX_BLOCK_SIZE_GEN/5;
/** The maximum allowed number of signature check operations in a block (network rule) */ /** The maximum allowed number of signature check operations in a block (network rule) */
static const unsigned int MAX_BLOCK_SIGOPS = MAX_BLOCK_SIZE/50; static const unsigned int MAX_BLOCK_SIGOPS = MAX_BLOCK_SIZE/50;
/** The maximum number of orphan transactions kept in memory */ /** The maximum number of orphan transactions kept in memory */

View file

@ -1208,7 +1208,7 @@ bool CWallet::CreateTransaction(const vector<pair<CScript, int64> >& vecSend, CW
// Limit size // Limit size
unsigned int nBytes = ::GetSerializeSize(*(CTransaction*)&wtxNew, SER_NETWORK, PROTOCOL_VERSION); unsigned int nBytes = ::GetSerializeSize(*(CTransaction*)&wtxNew, SER_NETWORK, PROTOCOL_VERSION);
if (nBytes >= MAX_BLOCK_SIZE_GEN/5) if (nBytes >= MAX_STANDARD_TX_SIZE)
return false; return false;
dPriority /= nBytes; dPriority /= nBytes;