diff --git a/src/blockencodings.cpp b/src/blockencodings.cpp index 4a311cbba2a6..65f0bf088f72 100644 --- a/src/blockencodings.cpp +++ b/src/blockencodings.cpp @@ -15,8 +15,6 @@ #include -#define MIN_TRANSACTION_BASE_SIZE (::GetSerializeSize(CTransaction(), SER_NETWORK, PROTOCOL_VERSION | SERIALIZE_TRANSACTION_NO_WITNESS)) - CBlockHeaderAndShortTxIDs::CBlockHeaderAndShortTxIDs(const CBlock& block, bool fUseWTXID) : nonce(GetRand(std::numeric_limits::max())), 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>& extra_txn) { if (cmpctblock.header.IsNull() || (cmpctblock.shorttxids.empty() && cmpctblock.prefilledtxn.empty())) 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_BASE_SIZE / MIN_TRANSACTION_SIZE) return READ_STATUS_INVALID; assert(header.IsNull() && txn_available.empty()); diff --git a/src/consensus/consensus.h b/src/consensus/consensus.h index 351911a3a47b..c7c0a65f7e17 100644 --- a/src/consensus/consensus.h +++ b/src/consensus/consensus.h @@ -16,6 +16,8 @@ static const unsigned int MAX_BLOCK_WEIGHT = 4000000; static const unsigned int MAX_BLOCK_BASE_SIZE = 1000000; /** The maximum allowed number of signature check operations in a block (network rule) */ static const int64_t MAX_BLOCK_SIGOPS_COST = 80000; +/** Smallest possible transaction size */ +static const unsigned int MIN_TRANSACTION_SIZE = 60; /** Coinbase transaction outputs can only be spent after this number of new blocks (network rule) */ static const int COINBASE_MATURITY = 100; diff --git a/src/init.cpp b/src/init.cpp index 5be011f944de..f0c1f2de6c84 100644 --- a/src/init.cpp +++ b/src/init.cpp @@ -693,6 +693,16 @@ bool InitSanityCheck(void) if (!glibc_sanity_test() || !glibcxx_sanity_test()) return false; + CMutableTransaction tx; + tx.vin.resize(1); + tx.vout.resize(1); + size_t nMinTxSize = ::GetSerializeSize(tx, SER_NETWORK, PROTOCOL_VERSION); + size_t nMinStrippedTxSize = ::GetSerializeSize(tx, SER_NETWORK, PROTOCOL_VERSION | SERIALIZE_TRANSACTION_NO_WITNESS); + if (MIN_TRANSACTION_SIZE != nMinTxSize || MIN_TRANSACTION_SIZE != nMinStrippedTxSize) { + InitError(strprintf("MIN_TRANSACTION_SIZE verification failure: const %u vs min=%u vs minstripped=%u", MIN_TRANSACTION_SIZE, nMinTxSize, nMinStrippedTxSize)); + return false; + } + return true; } diff --git a/src/merkleblock.cpp b/src/merkleblock.cpp index 86c8172a31df..662bac8a0399 100644 --- a/src/merkleblock.cpp +++ b/src/merkleblock.cpp @@ -155,7 +155,7 @@ uint256 CPartialMerkleTree::ExtractMatches(std::vector &vMatch, std::ve if (nTransactions == 0) return uint256(); // 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_BASE_SIZE / MIN_TRANSACTION_SIZE) return uint256(); // there can never be more hashes provided than one for every txid if (vHash.size() > nTransactions)