Browse Source

Make 100KB transaction size limit a consensus rule, rather than a standard rule.

pull/4/head
Sean Bowe 8 years ago
parent
commit
74f15a73a1
  1. 2
      src/consensus/consensus.h
  2. 25
      src/gtest/test_checktransaction.cpp
  3. 13
      src/main.cpp
  4. 2
      src/main.h
  5. 2
      src/wallet/wallet.cpp
  6. 8
      src/zcbenchmarks.cpp

2
src/consensus/consensus.h

@ -10,6 +10,8 @@
static const unsigned int MAX_BLOCK_SIZE = 2000000;
/** The maximum allowed number of signature check operations in a block (network rule) */
static const unsigned int MAX_BLOCK_SIGOPS = 20000;
/** The maximum size of a transaction (network rule) */
static const unsigned int MAX_TX_SIZE = 100000;
/** Coinbase transaction outputs can only be spent after this number of new blocks (network rule) */
static const int COINBASE_MATURITY = 100;

25
src/gtest/test_checktransaction.cpp

@ -121,17 +121,30 @@ TEST(checktransaction_tests, bad_txns_oversize) {
CMutableTransaction mtx = GetValidTransaction();
mtx.vin[0].scriptSig = CScript();
// 18 * (520char + DROP) + OP_1 = 9433 bytes
std::vector<unsigned char> vchData(520);
for (unsigned int i = 0; i < 4000; ++i)
for (unsigned int i = 0; i < 190; ++i)
mtx.vin[0].scriptSig << vchData << OP_DROP;
mtx.vin[0].scriptSig << OP_1;
CTransaction tx(mtx);
{
// Transaction is just under the limit...
CTransaction tx(mtx);
CValidationState state;
ASSERT_TRUE(CheckTransactionWithoutProofVerification(tx, state));
}
MockCValidationState state;
EXPECT_CALL(state, DoS(100, false, REJECT_INVALID, "bad-txns-oversize", false)).Times(1);
CheckTransactionWithoutProofVerification(tx, state);
// Not anymore!
mtx.vin[1].scriptSig << vchData << OP_DROP;
mtx.vin[1].scriptSig << OP_1;
{
CTransaction tx(mtx);
ASSERT_EQ(::GetSerializeSize(tx, SER_NETWORK, PROTOCOL_VERSION), 100202);
MockCValidationState state;
EXPECT_CALL(state, DoS(100, false, REJECT_INVALID, "bad-txns-oversize", false)).Times(1);
CheckTransactionWithoutProofVerification(tx, state);
}
}
TEST(checktransaction_tests, bad_txns_vout_negative) {

13
src/main.cpp

@ -644,16 +644,6 @@ bool IsStandardTx(const CTransaction& tx, string& reason)
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 = tx.GetSerializeSize(SER_NETWORK, CTransaction::CURRENT_VERSION);
if (sz >= MAX_STANDARD_TX_SIZE) {
reason = "tx-size";
return false;
}
BOOST_FOREACH(const CTxIn& txin, tx.vin)
{
// Biggest 'standard' txin is a 15-of-15 P2SH multisig with compressed
@ -871,7 +861,8 @@ bool CheckTransactionWithoutProofVerification(const CTransaction& tx, CValidatio
REJECT_INVALID, "bad-txns-vout-empty");
// Size limits
if (::GetSerializeSize(tx, SER_NETWORK, PROTOCOL_VERSION) > MAX_BLOCK_SIZE)
BOOST_STATIC_ASSERT(MAX_BLOCK_SIZE > MAX_TX_SIZE); // sanity
if (::GetSerializeSize(tx, SER_NETWORK, PROTOCOL_VERSION) > MAX_TX_SIZE)
return state.DoS(100, error("CheckTransaction(): size limits failed"),
REJECT_INVALID, "bad-txns-oversize");

2
src/main.h

@ -56,8 +56,6 @@ static const unsigned int DEFAULT_BLOCK_PRIORITY_SIZE = 50000;
static const bool DEFAULT_ALERTS = true;
/** Minimum alert priority for enabling safe mode. */
static const int ALERT_PRIORITY_SAFE_MODE = 4000;
/** The maximum size for transactions we're willing to relay/mine */
static const unsigned int MAX_STANDARD_TX_SIZE = 100000;
/** Maximum number of signature check operations in an IsStandard() P2SH script */
static const unsigned int MAX_P2SH_SIGOPS = 15;
/** The maximum number of sigops we're willing to relay/mine in a single tx */

2
src/wallet/wallet.cpp

@ -2471,7 +2471,7 @@ bool CWallet::CreateTransaction(const vector<CRecipient>& vecSend,
// Limit size
unsigned int nBytes = ::GetSerializeSize(*(CTransaction*)&wtxNew, SER_NETWORK, PROTOCOL_VERSION);
if (nBytes >= MAX_STANDARD_TX_SIZE)
if (nBytes >= MAX_TX_SIZE)
{
strFailReason = _("Transaction too large");
return false;

8
src/zcbenchmarks.cpp

@ -164,7 +164,7 @@ double benchmark_verify_equihash()
double benchmark_large_tx()
{
// Number of inputs in the spending transaction that we will simulate
const size_t NUM_INPUTS = 11100;
const size_t NUM_INPUTS = 555;
// Create priv/pub key
CKey priv;
@ -201,9 +201,9 @@ double benchmark_large_tx()
ss << spending_tx;
//std::cout << "SIZE OF SPENDING TX: " << ss.size() << std::endl;
auto error = MAX_BLOCK_SIZE / 20; // 5% error
assert(ss.size() < MAX_BLOCK_SIZE + error);
assert(ss.size() > MAX_BLOCK_SIZE - error);
auto error = MAX_TX_SIZE / 20; // 5% error
assert(ss.size() < MAX_TX_SIZE + error);
assert(ss.size() > MAX_TX_SIZE - error);
}
// Spending tx has all its inputs signed and does not need to be mutated anymore

Loading…
Cancel
Save