aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorGavin Andresen <gavinandresen@gmail.com>2013-02-04 16:56:26 -0500
committerGavin Andresen <gavinandresen@gmail.com>2013-02-05 10:08:35 -0500
commit41e1a0d7663d479f437c779df90775fc2bbc4087 (patch)
tree9dee872551006a837eb0b3cc46b87ac74addd033 /src
parent353b7f4a9c280ae02577b35cadb61783943493bc (diff)
Make transactions larger than 100K non-standard
Extremely large transactions with lots of inputs can cost the network almost as much to process as they cost the sender in fees. We would never create transactions larger than 100K big; this change makes transactions larger than 100K non-standard, so they are not relayed/mined by default. This is most important for miners that might create blocks larger than 250K big, who could be vulnerable to a make-your-blocks-so-expensive-to-verify-they-get-orphaned attack.
Diffstat (limited to 'src')
-rw-r--r--src/main.cpp8
-rw-r--r--src/main.h2
-rw-r--r--src/wallet.cpp2
3 files changed, 11 insertions, 1 deletions
diff --git a/src/main.cpp b/src/main.cpp
index 847b1ea8a6..874769c483 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 23a4d3ba31..d8e6a1bd33 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 b8ef2a20bf..2317ac31ac 100644
--- a/src/wallet.cpp
+++ b/src/wallet.cpp
@@ -1208,7 +1208,7 @@ bool CWallet::CreateTransaction(const vector<pair<CScript, int64> >& 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;