diff --git a/src/consensus/consensus.h b/src/consensus/consensus.h index 5a099cf53c5..2ab03bcf624 100644 --- a/src/consensus/consensus.h +++ b/src/consensus/consensus.h @@ -6,10 +6,12 @@ #ifndef BITCOIN_CONSENSUS_CONSENSUS_H #define BITCOIN_CONSENSUS_CONSENSUS_H -/** The maximum allowed size for a serialized block, in bytes (network rule) */ -static const unsigned int MAX_BLOCK_SIZE = 1000000; -/** The maximum allowed number of signature check operations in a block (network rule) */ -static const unsigned int MAX_BLOCK_SIGOPS = MAX_BLOCK_SIZE/50; +/** Block size limit, post-2MB fork */ +static const unsigned int MAX_BLOCK_SIZE = 2000000; +/** The old block size limit */ +static const unsigned int OLD_MAX_BLOCK_SIZE = 1000000; +/** pre-2MB-fork limit on signature operations in a block */ +static const unsigned int MAX_BLOCK_SIGOPS = OLD_MAX_BLOCK_SIZE/50; /** 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/main.cpp b/src/main.cpp index 5b27698d8b9..9514c7ef9fb 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -2954,15 +2954,17 @@ bool CheckBlock(const CBlock& block, CValidationState& state, bool fCheckPOW, bo REJECT_INVALID, "bad-txns-duplicate", true); } + // Size limits + unsigned int nSizeLimit = MaxBlockSize(block.nTime); + + if (block.vtx.empty() || block.vtx.size() > nSizeLimit || ::GetSerializeSize(block, SER_NETWORK, PROTOCOL_VERSION) > nSizeLimit) + return state.DoS(100, error("CheckBlock(): size limits failed"), + REJECT_INVALID, "bad-blk-length"); + // All potential-corruption validation must be done before we do any // transaction validation, as otherwise we may mark the header as invalid // because we receive the wrong transactions for it. - // Size limits - if (block.vtx.empty() || block.vtx.size() > MAX_BLOCK_SIZE || ::GetSerializeSize(block, SER_NETWORK, PROTOCOL_VERSION) > MAX_BLOCK_SIZE) - return state.DoS(100, error("CheckBlock(): size limits failed"), - REJECT_INVALID, "bad-blk-length"); - // First transaction must be coinbase, the rest must not be if (block.vtx.empty() || !block.vtx[0].IsCoinBase()) return state.DoS(100, error("CheckBlock(): first tx is not coinbase"), @@ -5665,6 +5667,14 @@ bool SendMessages(CNode* pto) return strprintf("CBlockFileInfo(blocks=%u, size=%u, heights=%u...%u, time=%s...%s)", nBlocks, nSize, nHeightFirst, nHeightLast, DateTimeStrFormat("%Y-%m-%d", nTimeFirst), DateTimeStrFormat("%Y-%m-%d", nTimeLast)); } +/** Maximum size of a block */ +unsigned int MaxBlockSize(uint32_t nBLockTime) +{ + if (true) // TODO: activation condition + return MAX_BLOCK_SIZE; + return OLD_MAX_BLOCK_SIZE; +} + class CMainCleanup diff --git a/src/main.h b/src/main.h index 9fd97d21268..825d1538fda 100644 --- a/src/main.h +++ b/src/main.h @@ -514,5 +514,7 @@ static const unsigned int REJECT_HIGHFEE = 0x100; static const unsigned int REJECT_ALREADY_KNOWN = 0x101; /** Transaction conflicts with a transaction already known */ static const unsigned int REJECT_CONFLICT = 0x102; +/** Maximum size of a block */ +unsigned int MaxBlockSize(uint32_t nBlockTime); #endif // BITCOIN_MAIN_H diff --git a/src/miner.cpp b/src/miner.cpp index c454c0279c2..af839fa671e 100644 --- a/src/miner.cpp +++ b/src/miner.cpp @@ -96,21 +96,6 @@ CBlockTemplate* CreateNewBlock(const CChainParams& chainparams, const CScript& s pblocktemplate->vTxFees.push_back(-1); // updated at end pblocktemplate->vTxSigOps.push_back(-1); // updated at end - // Largest block you're willing to create: - unsigned int nBlockMaxSize = GetArg("-blockmaxsize", DEFAULT_BLOCK_MAX_SIZE); - // Limit to between 1K and MAX_BLOCK_SIZE-1K for sanity: - nBlockMaxSize = std::max((unsigned int)1000, std::min((unsigned int)(MAX_BLOCK_SIZE-1000), nBlockMaxSize)); - - // How much of the block should be dedicated to high-priority transactions, - // included regardless of the fees they pay - unsigned int nBlockPrioritySize = GetArg("-blockprioritysize", DEFAULT_BLOCK_PRIORITY_SIZE); - nBlockPrioritySize = std::min(nBlockMaxSize, nBlockPrioritySize); - - // Minimum block size you want to create; block will be filled with free transactions - // until there are no more or the block reaches this size: - unsigned int nBlockMinSize = GetArg("-blockminsize", DEFAULT_BLOCK_MIN_SIZE); - nBlockMinSize = std::min(nBlockMaxSize, nBlockMinSize); - // Collect memory pool transactions into the block CTxMemPool::setEntries inBlock; CTxMemPool::setEntries waitSet; @@ -137,6 +122,23 @@ CBlockTemplate* CreateNewBlock(const CChainParams& chainparams, const CScript& s pblock->nTime = GetAdjustedTime(); const int64_t nMedianTimePast = pindexPrev->GetMedianTimePast(); + unsigned int nSizeLimit = MaxBlockSize(nMedianTimePast); + + // Largest block you're willing to create: + unsigned int nBlockMaxSize = GetArg("-blockmaxsize", DEFAULT_BLOCK_MAX_SIZE); + // Limit to between 1K and MAX_BLOCK_SIZE-1K for sanity: + nBlockMaxSize = std::max((unsigned int)1000, std::min((unsigned int)(MAX_BLOCK_SIZE-1000), nBlockMaxSize)); + + // How much of the block should be dedicated to high-priority transactions, + // included regardless of the fees they pay + unsigned int nBlockPrioritySize = GetArg("-blockprioritysize", DEFAULT_BLOCK_PRIORITY_SIZE); + nBlockPrioritySize = std::min(nBlockMaxSize, nBlockPrioritySize); + + // Minimum block size you want to create; block will be filled with free transactions + // until there are no more or the block reaches this size: + unsigned int nBlockMinSize = GetArg("-blockminsize", DEFAULT_BLOCK_MIN_SIZE); + nBlockMinSize = std::min(nBlockMaxSize, nBlockMinSize); + int64_t nLockTimeCutoff = (STANDARD_LOCKTIME_VERIFY_FLAGS & LOCKTIME_MEDIAN_TIME_PAST) ? nMedianTimePast : pblock->GetBlockTime();