diff --git a/src/main.cpp b/src/main.cpp index 847b1ea8a61..874769c483b 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -362,6 +362,14 @@ bool CTransaction::IsStandard() const if (!IsFinal()) 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) { // Biggest 'standard' txin is a 3-signature 3-of-3 CHECKMULTISIG diff --git a/src/main.h b/src/main.h index 23a4d3ba318..d8e6a1bd33a 100644 --- a/src/main.h +++ b/src/main.h @@ -28,6 +28,8 @@ struct CBlockIndexWorkComparator; static const unsigned int MAX_BLOCK_SIZE = 1000000; /** The maximum size for mined blocks */ 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) */ static const unsigned int MAX_BLOCK_SIGOPS = MAX_BLOCK_SIZE/50; /** The maximum number of orphan transactions kept in memory */ diff --git a/src/wallet.cpp b/src/wallet.cpp index b8ef2a20bfc..2317ac31ac7 100644 --- a/src/wallet.cpp +++ b/src/wallet.cpp @@ -1208,7 +1208,7 @@ bool CWallet::CreateTransaction(const vector >& vecSend, CW // Limit size 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; dPriority /= nBytes;