Merge #10618: Remove confusing MAX_BLOCK_BASE_SIZE.

3babbcb48 Remove confusing MAX_BLOCK_BASE_SIZE. (Gregory Maxwell)

Tree-SHA512: 361293fc4e1e379cd5a0908ed0866a00e1c7a771bdf02fded158fca21b492a29c7a67fea0d13dc40b2a04204c89823bf1836fe5b63a17c9747751b9c845a3527
This commit is contained in:
Pieter Wuille 2017-07-14 17:37:54 -07:00
commit f90603ac6d
No known key found for this signature in database
GPG Key ID: A636E97631F767E0
17 changed files with 43 additions and 45 deletions

View File

@ -239,7 +239,7 @@ static void MutateTxAddInput(CMutableTransaction& tx, const std::string& strInpu
uint256 txid(uint256S(strTxid)); uint256 txid(uint256S(strTxid));
static const unsigned int minTxOutSz = 9; static const unsigned int minTxOutSz = 9;
static const unsigned int maxVout = MAX_BLOCK_BASE_SIZE / minTxOutSz; static const unsigned int maxVout = MAX_BLOCK_WEIGHT / (WITNESS_SCALE_FACTOR * minTxOutSz);
// extract and validate vout // extract and validate vout
std::string strVout = vStrInputParts[1]; std::string strVout = vStrInputParts[1];

View File

@ -15,8 +15,6 @@
#include <unordered_map> #include <unordered_map>
#define MIN_TRANSACTION_BASE_SIZE (::GetSerializeSize(CTransaction(), SER_NETWORK, PROTOCOL_VERSION | SERIALIZE_TRANSACTION_NO_WITNESS))
CBlockHeaderAndShortTxIDs::CBlockHeaderAndShortTxIDs(const CBlock& block, bool fUseWTXID) : CBlockHeaderAndShortTxIDs::CBlockHeaderAndShortTxIDs(const CBlock& block, bool fUseWTXID) :
nonce(GetRand(std::numeric_limits<uint64_t>::max())), nonce(GetRand(std::numeric_limits<uint64_t>::max())),
shorttxids(block.vtx.size() - 1), prefilledtxn(1), header(block) { shorttxids(block.vtx.size() - 1), prefilledtxn(1), header(block) {
@ -50,7 +48,7 @@ uint64_t CBlockHeaderAndShortTxIDs::GetShortID(const uint256& txhash) const {
ReadStatus PartiallyDownloadedBlock::InitData(const CBlockHeaderAndShortTxIDs& cmpctblock, const std::vector<std::pair<uint256, CTransactionRef>>& extra_txn) { ReadStatus PartiallyDownloadedBlock::InitData(const CBlockHeaderAndShortTxIDs& cmpctblock, const std::vector<std::pair<uint256, CTransactionRef>>& extra_txn) {
if (cmpctblock.header.IsNull() || (cmpctblock.shorttxids.empty() && cmpctblock.prefilledtxn.empty())) if (cmpctblock.header.IsNull() || (cmpctblock.shorttxids.empty() && cmpctblock.prefilledtxn.empty()))
return READ_STATUS_INVALID; return READ_STATUS_INVALID;
if (cmpctblock.shorttxids.size() + cmpctblock.prefilledtxn.size() > MAX_BLOCK_BASE_SIZE / MIN_TRANSACTION_BASE_SIZE) if (cmpctblock.shorttxids.size() + cmpctblock.prefilledtxn.size() > MAX_BLOCK_WEIGHT / MIN_SERIALIZEABLE_TRANSACTION_WEIGHT)
return READ_STATUS_INVALID; return READ_STATUS_INVALID;
assert(header.IsNull() && txn_available.empty()); assert(header.IsNull() && txn_available.empty());

View File

@ -245,7 +245,8 @@ bool CCoinsViewCache::HaveInputs(const CTransaction& tx) const
return true; return true;
} }
static const size_t MAX_OUTPUTS_PER_BLOCK = MAX_BLOCK_BASE_SIZE / ::GetSerializeSize(CTxOut(), SER_NETWORK, PROTOCOL_VERSION); // TODO: merge with similar definition in undo.h. static const size_t MIN_TRANSACTION_OUTPUT_WEIGHT = WITNESS_SCALE_FACTOR * ::GetSerializeSize(CTxOut(), SER_NETWORK, PROTOCOL_VERSION);
static const size_t MAX_OUTPUTS_PER_BLOCK = MAX_BLOCK_WEIGHT / MIN_TRANSACTION_OUTPUT_WEIGHT;
const Coin& AccessByTxid(const CCoinsViewCache& view, const uint256& txid) const Coin& AccessByTxid(const CCoinsViewCache& view, const uint256& txid)
{ {

View File

@ -6,25 +6,23 @@
#ifndef BITCOIN_CONSENSUS_CONSENSUS_H #ifndef BITCOIN_CONSENSUS_CONSENSUS_H
#define BITCOIN_CONSENSUS_CONSENSUS_H #define BITCOIN_CONSENSUS_CONSENSUS_H
#include <stdlib.h>
#include <stdint.h> #include <stdint.h>
/** The maximum allowed size for a serialized block, in bytes (only for buffer size limits) */ /** The maximum allowed size for a serialized block, in bytes (only for buffer size limits) */
static const unsigned int MAX_BLOCK_SERIALIZED_SIZE = 4000000; static const unsigned int MAX_BLOCK_SERIALIZED_SIZE = 4000000;
/** The maximum allowed weight for a block, see BIP 141 (network rule) */ /** The maximum allowed weight for a block, see BIP 141 (network rule) */
static const unsigned int MAX_BLOCK_WEIGHT = 4000000; static const unsigned int MAX_BLOCK_WEIGHT = 4000000;
/**
* The maximum allowed size for a block excluding witness data, in bytes (network rule).
* This parameter is largely superfluous because it is directly implied by the above block
* weight limit, even when BIP 141 is not active. It continues to exist for use in
* various early tests that run before the witness data has been checked.
* All tests related to it could be removed without breaking consensus compatibility.
*/
static const unsigned int MAX_BLOCK_BASE_SIZE = 1000000;
/** 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 int64_t MAX_BLOCK_SIGOPS_COST = 80000; static const int64_t MAX_BLOCK_SIGOPS_COST = 80000;
/** Coinbase transaction outputs can only be spent after this number of new blocks (network rule) */ /** Coinbase transaction outputs can only be spent after this number of new blocks (network rule) */
static const int COINBASE_MATURITY = 100; static const int COINBASE_MATURITY = 100;
static const int WITNESS_SCALE_FACTOR = 4;
static const size_t MIN_TRANSACTION_WEIGHT = WITNESS_SCALE_FACTOR * 60; // 60 is the lower bound for the size of a valid serialized CTransaction
static const size_t MIN_SERIALIZEABLE_TRANSACTION_WEIGHT = WITNESS_SCALE_FACTOR * 10; // 10 is the lower bound for the size of a serialized CTransaction
/** Flags for nSequence and nLockTime locks */ /** Flags for nSequence and nLockTime locks */
enum { enum {
/* Interpret sequence numbers as relative lock-time constraints. */ /* Interpret sequence numbers as relative lock-time constraints. */

View File

@ -164,7 +164,7 @@ bool CheckTransaction(const CTransaction& tx, CValidationState &state, bool fChe
if (tx.vout.empty()) if (tx.vout.empty())
return state.DoS(10, false, REJECT_INVALID, "bad-txns-vout-empty"); return state.DoS(10, false, REJECT_INVALID, "bad-txns-vout-empty");
// Size limits (this doesn't take the witness into account, as that hasn't been checked for malleability) // Size limits (this doesn't take the witness into account, as that hasn't been checked for malleability)
if (::GetSerializeSize(tx, SER_NETWORK, PROTOCOL_VERSION | SERIALIZE_TRANSACTION_NO_WITNESS) > MAX_BLOCK_BASE_SIZE) if (::GetSerializeSize(tx, SER_NETWORK, PROTOCOL_VERSION | SERIALIZE_TRANSACTION_NO_WITNESS) * WITNESS_SCALE_FACTOR > MAX_BLOCK_WEIGHT)
return state.DoS(100, false, REJECT_INVALID, "bad-txns-oversize"); return state.DoS(100, false, REJECT_INVALID, "bad-txns-oversize");
// Check for negative or overflow output values // Check for negative or overflow output values

View File

@ -7,6 +7,10 @@
#define BITCOIN_CONSENSUS_VALIDATION_H #define BITCOIN_CONSENSUS_VALIDATION_H
#include <string> #include <string>
#include "version.h"
#include "consensus/consensus.h"
#include "primitives/transaction.h"
#include "primitives/block.h"
/** "reject" message codes */ /** "reject" message codes */
static const unsigned char REJECT_MALFORMED = 0x01; static const unsigned char REJECT_MALFORMED = 0x01;
@ -85,4 +89,18 @@ public:
std::string GetDebugMessage() const { return strDebugMessage; } std::string GetDebugMessage() const { return strDebugMessage; }
}; };
static inline int64_t GetTransactionWeight(const CTransaction& tx)
{
return ::GetSerializeSize(tx, SER_NETWORK, PROTOCOL_VERSION | SERIALIZE_TRANSACTION_NO_WITNESS) * (WITNESS_SCALE_FACTOR -1) + ::GetSerializeSize(tx, SER_NETWORK, PROTOCOL_VERSION);
}
static inline int64_t GetBlockWeight(const CBlock& block)
{
// This implements the weight = (stripped_size * 4) + witness_size formula,
// using only serialization with and without witness data. As witness_size
// is equal to total_size - stripped_size, this formula is identical to:
// weight = (stripped_size * 3) + total_size.
return ::GetSerializeSize(block, SER_NETWORK, PROTOCOL_VERSION | SERIALIZE_TRANSACTION_NO_WITNESS) * (WITNESS_SCALE_FACTOR - 1) + ::GetSerializeSize(block, SER_NETWORK, PROTOCOL_VERSION);
}
#endif // BITCOIN_CONSENSUS_VALIDATION_H #endif // BITCOIN_CONSENSUS_VALIDATION_H

View File

@ -5,7 +5,8 @@
#include "core_io.h" #include "core_io.h"
#include "base58.h" #include "base58.h"
#include "primitives/transaction.h" #include "consensus/consensus.h"
#include "consensus/validation.h"
#include "script/script.h" #include "script/script.h"
#include "script/standard.h" #include "script/standard.h"
#include "serialize.h" #include "serialize.h"
@ -15,7 +16,6 @@
#include "utilmoneystr.h" #include "utilmoneystr.h"
#include "utilstrencodings.h" #include "utilstrencodings.h"
std::string FormatScript(const CScript& script) std::string FormatScript(const CScript& script)
{ {
std::string ret; std::string ret;

View File

@ -153,7 +153,7 @@ uint256 CPartialMerkleTree::ExtractMatches(std::vector<uint256> &vMatch, std::ve
if (nTransactions == 0) if (nTransactions == 0)
return uint256(); return uint256();
// check for excessively high numbers of transactions // check for excessively high numbers of transactions
if (nTransactions > MAX_BLOCK_BASE_SIZE / 60) // 60 is the lower bound for the size of a serialized CTransaction if (nTransactions > MAX_BLOCK_WEIGHT / MIN_TRANSACTION_WEIGHT)
return uint256(); return uint256();
// there can never be more hashes provided than one for every txid // there can never be more hashes provided than one for every txid
if (vHash.size() > nTransactions) if (vHash.size() > nTransactions)

View File

@ -7,6 +7,7 @@
#include "policy/policy.h" #include "policy/policy.h"
#include "consensus/validation.h"
#include "validation.h" #include "validation.h"
#include "coins.h" #include "coins.h"
#include "tinyformat.h" #include "tinyformat.h"

View File

@ -31,12 +31,3 @@ std::string CBlock::ToString() const
} }
return s.str(); return s.str();
} }
int64_t GetBlockWeight(const CBlock& block)
{
// This implements the weight = (stripped_size * 4) + witness_size formula,
// using only serialization with and without witness data. As witness_size
// is equal to total_size - stripped_size, this formula is identical to:
// weight = (stripped_size * 3) + total_size.
return ::GetSerializeSize(block, SER_NETWORK, PROTOCOL_VERSION | SERIALIZE_TRANSACTION_NO_WITNESS) * (WITNESS_SCALE_FACTOR - 1) + ::GetSerializeSize(block, SER_NETWORK, PROTOCOL_VERSION);
}

View File

@ -152,7 +152,4 @@ struct CBlockLocator
} }
}; };
/** Compute the consensus-critical block weight (see BIP 141). */
int64_t GetBlockWeight(const CBlock& tx);
#endif // BITCOIN_PRIMITIVES_BLOCK_H #endif // BITCOIN_PRIMITIVES_BLOCK_H

View File

@ -114,8 +114,3 @@ std::string CTransaction::ToString() const
str += " " + vout[i].ToString() + "\n"; str += " " + vout[i].ToString() + "\n";
return str; return str;
} }
int64_t GetTransactionWeight(const CTransaction& tx)
{
return ::GetSerializeSize(tx, SER_NETWORK, PROTOCOL_VERSION | SERIALIZE_TRANSACTION_NO_WITNESS) * (WITNESS_SCALE_FACTOR -1) + ::GetSerializeSize(tx, SER_NETWORK, PROTOCOL_VERSION);
}

View File

@ -6,6 +6,7 @@
#ifndef BITCOIN_PRIMITIVES_TRANSACTION_H #ifndef BITCOIN_PRIMITIVES_TRANSACTION_H
#define BITCOIN_PRIMITIVES_TRANSACTION_H #define BITCOIN_PRIMITIVES_TRANSACTION_H
#include <stdint.h>
#include "amount.h" #include "amount.h"
#include "script/script.h" #include "script/script.h"
#include "serialize.h" #include "serialize.h"
@ -13,8 +14,6 @@
static const int SERIALIZE_TRANSACTION_NO_WITNESS = 0x40000000; static const int SERIALIZE_TRANSACTION_NO_WITNESS = 0x40000000;
static const int WITNESS_SCALE_FACTOR = 4;
/** An outpoint - a combination of a transaction hash and an index n into its vout */ /** An outpoint - a combination of a transaction hash and an index n into its vout */
class COutPoint class COutPoint
{ {
@ -411,7 +410,4 @@ typedef std::shared_ptr<const CTransaction> CTransactionRef;
static inline CTransactionRef MakeTransactionRef() { return std::make_shared<const CTransaction>(); } static inline CTransactionRef MakeTransactionRef() { return std::make_shared<const CTransaction>(); }
template <typename Tx> static inline CTransactionRef MakeTransactionRef(Tx&& txIn) { return std::make_shared<const CTransaction>(std::forward<Tx>(txIn)); } template <typename Tx> static inline CTransactionRef MakeTransactionRef(Tx&& txIn) { return std::make_shared<const CTransaction>(std::forward<Tx>(txIn)); }
/** Compute the weight of a transaction, as defined by BIP 141 */
int64_t GetTransactionWeight(const CTransaction &tx);
#endif // BITCOIN_PRIMITIVES_TRANSACTION_H #endif // BITCOIN_PRIMITIVES_TRANSACTION_H

View File

@ -645,15 +645,16 @@ UniValue getblocktemplate(const JSONRPCRequest& request)
result.push_back(Pair("mutable", aMutable)); result.push_back(Pair("mutable", aMutable));
result.push_back(Pair("noncerange", "00000000ffffffff")); result.push_back(Pair("noncerange", "00000000ffffffff"));
int64_t nSigOpLimit = MAX_BLOCK_SIGOPS_COST; int64_t nSigOpLimit = MAX_BLOCK_SIGOPS_COST;
int64_t nSizeLimit = MAX_BLOCK_SERIALIZED_SIZE;
if (fPreSegWit) { if (fPreSegWit) {
assert(nSigOpLimit % WITNESS_SCALE_FACTOR == 0); assert(nSigOpLimit % WITNESS_SCALE_FACTOR == 0);
nSigOpLimit /= WITNESS_SCALE_FACTOR; nSigOpLimit /= WITNESS_SCALE_FACTOR;
assert(nSizeLimit % WITNESS_SCALE_FACTOR == 0);
nSizeLimit /= WITNESS_SCALE_FACTOR;
} }
result.push_back(Pair("sigoplimit", nSigOpLimit)); result.push_back(Pair("sigoplimit", nSigOpLimit));
if (fPreSegWit) { result.push_back(Pair("sizelimit", nSizeLimit));
result.push_back(Pair("sizelimit", (int64_t)MAX_BLOCK_BASE_SIZE)); if (!fPreSegWit) {
} else {
result.push_back(Pair("sizelimit", (int64_t)MAX_BLOCK_SERIALIZED_SIZE));
result.push_back(Pair("weightlimit", (int64_t)MAX_BLOCK_WEIGHT)); result.push_back(Pair("weightlimit", (int64_t)MAX_BLOCK_WEIGHT));
} }
result.push_back(Pair("curtime", pblock->GetBlockTime())); result.push_back(Pair("curtime", pblock->GetBlockTime()));

View File

@ -3,6 +3,7 @@
// file COPYING or http://www.opensource.org/licenses/mit-license.php. // file COPYING or http://www.opensource.org/licenses/mit-license.php.
#include "consensus/tx_verify.h" #include "consensus/tx_verify.h"
#include "consensus/validation.h"
#include "pubkey.h" #include "pubkey.h"
#include "key.h" #include "key.h"
#include "script/script.h" #include "script/script.h"

View File

@ -60,7 +60,8 @@ public:
TxInUndoDeserializer(Coin* coin) : txout(coin) {} TxInUndoDeserializer(Coin* coin) : txout(coin) {}
}; };
static const size_t MAX_INPUTS_PER_BLOCK = MAX_BLOCK_BASE_SIZE / ::GetSerializeSize(CTxIn(), SER_NETWORK, PROTOCOL_VERSION); static const size_t MIN_TRANSACTION_INPUT_WEIGHT = WITNESS_SCALE_FACTOR * ::GetSerializeSize(CTxIn(), SER_NETWORK, PROTOCOL_VERSION);
static const size_t MAX_INPUTS_PER_BLOCK = MAX_BLOCK_WEIGHT / MIN_TRANSACTION_INPUT_WEIGHT;
/** Undo information for a CTransaction */ /** Undo information for a CTransaction */
class CTxUndo class CTxUndo

View File

@ -2799,7 +2799,7 @@ bool CheckBlock(const CBlock& block, CValidationState& state, const Consensus::P
// checks that use witness data may be performed here. // checks that use witness data may be performed here.
// Size limits // Size limits
if (block.vtx.empty() || block.vtx.size() > MAX_BLOCK_BASE_SIZE || ::GetSerializeSize(block, SER_NETWORK, PROTOCOL_VERSION | SERIALIZE_TRANSACTION_NO_WITNESS) > MAX_BLOCK_BASE_SIZE) if (block.vtx.empty() || block.vtx.size() * WITNESS_SCALE_FACTOR > MAX_BLOCK_WEIGHT || ::GetSerializeSize(block, SER_NETWORK, PROTOCOL_VERSION | SERIALIZE_TRANSACTION_NO_WITNESS) * WITNESS_SCALE_FACTOR > MAX_BLOCK_WEIGHT)
return state.DoS(100, false, REJECT_INVALID, "bad-blk-length", false, "size limits failed"); return state.DoS(100, false, REJECT_INVALID, "bad-blk-length", false, "size limits failed");
// First transaction must be coinbase, the rest must not be // First transaction must be coinbase, the rest must not be