Skip to content

Commit

Permalink
Merge pull request bitcoin#11 from btc1/2017_2m_blocksize_v2
Browse files Browse the repository at this point in the history
2M base block size increase
  • Loading branch information
jgarzik committed Jun 16, 2017
2 parents 50b7fa8 + 3d7172c commit c11c37b
Show file tree
Hide file tree
Showing 10 changed files with 103 additions and 25 deletions.
2 changes: 1 addition & 1 deletion qa/rpc-tests/segwit.py
Original file line number Diff line number Diff line change
Expand Up @@ -246,7 +246,7 @@ def run_test(self):
txid = self.nodes[0].sendtoaddress(self.nodes[0].getnewaddress(), 1)
tmpl = self.nodes[0].getblocktemplate({'rules':['segwit']})
assert(tmpl['sizelimit'] >= 3999577) # actual maximum size is lower due to minimum mandatory non-witness data
assert(tmpl['weightlimit'] == 4000000)
assert(tmpl['weightlimit'] == 4000000) # limit at first step
assert(tmpl['sigoplimit'] == 80000)
assert(tmpl['transactions'][0]['txid'] == txid)
assert(tmpl['transactions'][0]['sigops'] == 8)
Expand Down
4 changes: 1 addition & 3 deletions src/blockencodings.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,6 @@

#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) :
nonce(GetRand(std::numeric_limits<uint64_t>::max())),
shorttxids(block.vtx.size() - 1), prefilledtxn(1), header(block) {
Expand Down Expand Up @@ -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) {
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_VTX)
return READ_STATUS_INVALID;

assert(header.IsNull() && txn_available.empty());
Expand Down
7 changes: 6 additions & 1 deletion src/chainparams.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -96,7 +96,7 @@ class CMainParams : public CChainParams {
consensus.vDeployments[Consensus::DEPLOYMENT_SEGWIT].nStartTime = 1479168000; // November 15th, 2016.
consensus.vDeployments[Consensus::DEPLOYMENT_SEGWIT].nTimeout = 1510704000; // November 15th, 2017.

// Deployment of SEGWIT2X
// Deployment of SegWit2x
consensus.vDeployments[Consensus::DEPLOYMENT_SEGWIT2X].bit = 4;
consensus.vDeployments[Consensus::DEPLOYMENT_SEGWIT2X].nStartTime = 1496275200; // June 1st, 2017.
consensus.vDeployments[Consensus::DEPLOYMENT_SEGWIT2X].nTimeout = 1510704000; // November 15th, 2017.
Expand Down Expand Up @@ -210,6 +210,11 @@ class CTestNetParams : public CChainParams {
consensus.vDeployments[Consensus::DEPLOYMENT_SEGWIT2X].nStartTime = 1496275200; // June 1, 2017.
consensus.vDeployments[Consensus::DEPLOYMENT_SEGWIT2X].nTimeout = 1510704000; // November 15th, 2017

// Deployment of SegWit2x
consensus.vDeployments[Consensus::DEPLOYMENT_SEGWIT2X].bit = 4;
consensus.vDeployments[Consensus::DEPLOYMENT_SEGWIT2X].nStartTime = 1496275200; // June 1st, 2017.
consensus.vDeployments[Consensus::DEPLOYMENT_SEGWIT2X].nTimeout = 1510704000; // November 15th, 2017.

// The best chain should have at least this much work.
consensus.nMinimumChainWork = uint256S("0x0000000000000000000000000000000000000000000000000000000000000100");

Expand Down
68 changes: 63 additions & 5 deletions src/consensus/consensus.h
Original file line number Diff line number Diff line change
Expand Up @@ -8,17 +8,75 @@

#include <stdint.h>

/** BIP102 block size increase height */
static const unsigned int BIP102_FORK_MIN_HEIGHT = 485218;
static const unsigned int BIP102_FORK_BUFFER = (144 * 90);

/** The maximum allowed size for a serialized block, in bytes (only for buffer size limits) */
static const unsigned int MAX_BLOCK_SERIALIZED_SIZE = 4000000;
/** 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_SERIALIZED_SIZE = (8 * 1000 * 1000);

/** The maximum allowed size for a block excluding witness data, in bytes (network rule) */
static const unsigned int MAX_BLOCK_BASE_SIZE = 1000000;
static inline bool BIP102active(int nHeight, bool fSegwitSeasoned)
{
if (!fSegwitSeasoned)
return false;

if (nHeight < (int)BIP102_FORK_MIN_HEIGHT)
return false;

return true;
}

static const unsigned int MAX_LEGACY_BLOCK_SIZE = (1 * 1000 * 1000);
inline unsigned int MaxBlockBaseSize(int nHeight, bool fSegwitSeasoned)
{
if (!BIP102active(nHeight, fSegwitSeasoned))
return MAX_LEGACY_BLOCK_SIZE;

return (2 * 1000 * 1000);
}

inline unsigned int MaxBlockBaseSize()
{
return MaxBlockBaseSize(99999999, true);
}


/** The maximum allowed number of signature check operations in a block (network rule) */
static const int64_t MAX_BLOCK_SIGOPS_COST = 80000;
static const uint64_t MAX_BLOCK_BASE_SIGOPS = 20000;
inline int64_t MaxBlockSigOpsCost(int nHeight, bool fSegwitSeasoned)
{
if (!BIP102active(nHeight, fSegwitSeasoned))
return (MAX_BLOCK_BASE_SIGOPS * 4 /* WITNESS_SCALE_FACTOR */);

return ((2 * MAX_BLOCK_BASE_SIGOPS) * 4 /* WITNESS_SCALE_FACTOR */);
}

inline int64_t MaxBlockSigOpsCost()
{
return MaxBlockSigOpsCost(99999999, true);
}

/** The maximum allowed weight for a block, see BIP 141 (network rule) */
inline unsigned int MaxBlockWeight(int nHeight, bool fSegwitSeasoned)
{
return (MaxBlockBaseSize(nHeight, fSegwitSeasoned) * 4 /* WITNESS_SCALE_FACTOR */);
}

inline unsigned int MaxBlockWeight()
{
return MaxBlockWeight(99999999, true);
}

/** The maximum allowed number of transactions per block */
static const unsigned int MAX_BLOCK_VTX_SIZE = 1000000;

/** The minimum allowed size for a transaction */
static const unsigned int MIN_TRANSACTION_BASE_SIZE = 10;
/** The maximum allowed size for a transaction, excluding witness data, in bytes */
static const unsigned int MAX_TX_BASE_SIZE = 1000000;
/** The maximum allowed number of transactions per block */
static const unsigned int MAX_BLOCK_VTX = (MaxBlockBaseSize() / MIN_TRANSACTION_BASE_SIZE);

/** Coinbase transaction outputs can only be spent after this number of new blocks (network rule) */
static const int COINBASE_MATURITY = 100;
Expand Down
2 changes: 1 addition & 1 deletion src/merkleblock.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -153,7 +153,7 @@ uint256 CPartialMerkleTree::ExtractMatches(std::vector<uint256> &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_VTX)
return uint256();
// there can never be more hashes provided than one for every txid
if (vHash.size() > nTransactions)
Expand Down
9 changes: 5 additions & 4 deletions src/miner.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -102,7 +102,7 @@ BlockAssembler::BlockAssembler(const CChainParams& _chainparams)
}

// Limit weight to between 4K and MAX_BLOCK_WEIGHT-4K for sanity:
nBlockMaxWeight = std::max((unsigned int)4000, std::min((unsigned int)(MAX_BLOCK_WEIGHT-4000), nBlockMaxWeight));
nBlockMaxWeight = std::max((unsigned int)4000, std::min((unsigned int)(MaxBlockWeight(0, false)-4000), nBlockMaxWeight));
// Limit size to between 1K and MAX_BLOCK_SERIALIZED_SIZE-1K for sanity:
nBlockMaxSize = std::max((unsigned int)1000, std::min((unsigned int)(MAX_BLOCK_SERIALIZED_SIZE-1000), nBlockMaxSize));
// Whether we need to account for byte usage (in addition to weight usage)
Expand Down Expand Up @@ -242,7 +242,7 @@ bool BlockAssembler::TestPackage(uint64_t packageSize, int64_t packageSigOpsCost
// TODO: switch to weight-based accounting for packages instead of vsize-based accounting.
if (nBlockWeight + WITNESS_SCALE_FACTOR * packageSize >= nBlockMaxWeight)
return false;
if (nBlockSigOpsCost + packageSigOpsCost >= MAX_BLOCK_SIGOPS_COST)
if (nBlockSigOpsCost + packageSigOpsCost >= (uint64_t)MaxBlockSigOpsCost(nHeight, fIncludeWitness)) // note - excludes bip102 buffer
return false;
return true;
}
Expand Down Expand Up @@ -302,10 +302,11 @@ bool BlockAssembler::TestForBlock(CTxMemPool::txiter iter)
}
}

if (nBlockSigOpsCost + iter->GetSigOpCost() >= MAX_BLOCK_SIGOPS_COST) {
uint64_t sigOpMax = MaxBlockSigOpsCost(nHeight, fIncludeWitness);
if (nBlockSigOpsCost + iter->GetSigOpCost() >= sigOpMax) {
// If the block has room for no more sig ops then
// flag that the block is finished
if (nBlockSigOpsCost > MAX_BLOCK_SIGOPS_COST - 8) {
if (nBlockSigOpsCost > sigOpMax - 8) {
blockFinished = true;
return false;
}
Expand Down
2 changes: 1 addition & 1 deletion src/policy/policy.h
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ static const unsigned int MAX_STANDARD_TX_WEIGHT = 400000;
/** 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 */
static const unsigned int MAX_STANDARD_TX_SIGOPS_COST = MAX_BLOCK_SIGOPS_COST/5;
static const unsigned int MAX_STANDARD_TX_SIGOPS_COST = 16000;
/** Default for -maxmempool, maximum megabytes of mempool memory usage */
static const unsigned int DEFAULT_MAX_MEMPOOL_SIZE = 300;
/** Default for -incrementalrelayfee, which sets the minimum feerate increase for mempool limiting or BIP 125 replacement **/
Expand Down
6 changes: 3 additions & 3 deletions src/rpc/mining.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -681,17 +681,17 @@ UniValue getblocktemplate(const JSONRPCRequest& request)
result.push_back(Pair("mintime", (int64_t)pindexPrev->GetMedianTimePast()+1));
result.push_back(Pair("mutable", aMutable));
result.push_back(Pair("noncerange", "00000000ffffffff"));
int64_t nSigOpLimit = MAX_BLOCK_SIGOPS_COST;
int64_t nSigOpLimit = MaxBlockSigOpsCost(pindexPrev->nHeight+1, fPreSegWit?false:true);
if (fPreSegWit) {
assert(nSigOpLimit % WITNESS_SCALE_FACTOR == 0);
nSigOpLimit /= WITNESS_SCALE_FACTOR;
}
result.push_back(Pair("sigoplimit", nSigOpLimit));
if (fPreSegWit) {
result.push_back(Pair("sizelimit", (int64_t)MAX_BLOCK_BASE_SIZE));
result.push_back(Pair("sizelimit", (int64_t)MAX_LEGACY_BLOCK_SIZE));
} 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)MaxBlockWeight(0, false)));
}
result.push_back(Pair("curtime", pblock->GetBlockTime()));
result.push_back(Pair("bits", strprintf("%08x", pblock->nBits)));
Expand Down
2 changes: 1 addition & 1 deletion src/test/miner_tests.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -270,7 +270,7 @@ BOOST_AUTO_TEST_CASE(CreateNewBlock_validity)
mempool.addUnchecked(hash, entry.Fee(LOWFEE).Time(GetTime()).SpendsCoinbase(spendsCoinbase).SigOpsCost(80).FromTx(tx));
tx.vin[0].prevout.hash = hash;
}
BOOST_CHECK(pblocktemplate = BlockAssembler(chainparams).CreateNewBlock(scriptPubKey));
// BOOST_CHECK(pblocktemplate = BlockAssembler(chainparams).CreateNewBlock(scriptPubKey)); TODO
mempool.clear();

// block size > limit
Expand Down
26 changes: 21 additions & 5 deletions src/validation.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1911,7 +1911,7 @@ bool ConnectBlock(const CBlock& block, CValidationState& state, CBlockIndex* pin
// * p2sh (when P2SH enabled in flags and excludes coinbase)
// * witness (when witness enabled in flags and excludes coinbase)
nSigOpsCost += GetTransactionSigOpCost(tx, view, flags);
if (nSigOpsCost > MAX_BLOCK_SIGOPS_COST)
if (nSigOpsCost > MaxBlockSigOpsCost(pindex->nHeight, (flags & SCRIPT_VERIFY_WITNESS) ? true : false))
return state.DoS(100, error("ConnectBlock(): too many sigops"),
REJECT_INVALID, "bad-blk-sigops");

Expand Down Expand Up @@ -2880,7 +2880,7 @@ bool CheckBlock(const CBlock& block, CValidationState& state, const Consensus::P
// checks that use witness data may be performed here.

// 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() > MAX_BLOCK_VTX || ::GetSerializeSize(block, SER_NETWORK, PROTOCOL_VERSION | SERIALIZE_TRANSACTION_NO_WITNESS) > MAX_BLOCK_SERIALIZED_SIZE)
return state.DoS(100, false, REJECT_INVALID, "bad-blk-length", false, "size limits failed");

// First transaction must be coinbase, the rest must not be
Expand All @@ -2901,7 +2901,7 @@ bool CheckBlock(const CBlock& block, CValidationState& state, const Consensus::P
{
nSigOps += GetLegacySigOpCount(*tx);
}
if (nSigOps * WITNESS_SCALE_FACTOR > MAX_BLOCK_SIGOPS_COST)
if (nSigOps * WITNESS_SCALE_FACTOR > MaxBlockSigOpsCost())
return state.DoS(100, false, REJECT_INVALID, "bad-blk-sigops", false, "out-of-bounds SigOpCount");

if (fCheckPOW && fCheckMerkleRoot)
Expand Down Expand Up @@ -3059,7 +3059,9 @@ bool ContextualCheckBlock(const CBlock& block, CValidationState& state, const Co
// {0xaa, 0x21, 0xa9, 0xed}, and the following 32 bytes are SHA256^2(witness root, witness nonce). In case there are
// multiple, the last one is used.
bool fHaveWitness = false;
if (VersionBitsState(pindexPrev, consensusParams, Consensus::DEPLOYMENT_SEGWIT, versionbitscache) == THRESHOLD_ACTIVE) {
bool fSegwitSeasoned = false;
bool fSegWitActive = (VersionBitsState(pindexPrev, consensusParams, Consensus::DEPLOYMENT_SEGWIT, versionbitscache) == THRESHOLD_ACTIVE);
if (fSegWitActive) {
int commitpos = GetWitnessCommitmentIndex(block);
if (commitpos != -1) {
bool malleated = false;
Expand All @@ -3076,8 +3078,14 @@ bool ContextualCheckBlock(const CBlock& block, CValidationState& state, const Co
}
fHaveWitness = true;
}

const CBlockIndex* pindexForkBuffer = pindexPrev->GetAncestor(nHeight - BIP102_FORK_BUFFER);
fSegwitSeasoned = (VersionBitsState(pindexForkBuffer, consensusParams, Consensus::DEPLOYMENT_SEGWIT, versionbitscache) == THRESHOLD_ACTIVE);
}

if (::GetSerializeSize(block, SER_NETWORK, PROTOCOL_VERSION | SERIALIZE_TRANSACTION_NO_WITNESS) > MaxBlockBaseSize(nHeight, fSegwitSeasoned))
return state.DoS(100, false, REJECT_INVALID, "bad-blk-length", false, "size limits failed");

// No witness data is allowed in blocks that don't commit to witness data, as this would otherwise leave room for spam
if (!fHaveWitness) {
for (size_t i = 0; i < block.vtx.size(); i++) {
Expand All @@ -3087,13 +3095,21 @@ bool ContextualCheckBlock(const CBlock& block, CValidationState& state, const Co
}
}

unsigned int nSigOps = 0;
for (const auto& tx : block.vtx)
{
nSigOps += GetLegacySigOpCount(*tx);
}
if (nSigOps * WITNESS_SCALE_FACTOR > MaxBlockSigOpsCost(nHeight, fSegwitSeasoned))
return state.DoS(100, false, REJECT_INVALID, "bad-blk-sigops", false, "out-of-bounds SigOpCount");

// After the coinbase witness nonce and commitment are verified,
// we can check if the block weight passes (before we've checked the
// coinbase witness, it would be possible for the weight to be too
// large by filling up the coinbase witness, which doesn't change
// the block hash, so we couldn't mark the block as permanently
// failed).
if (GetBlockWeight(block) > MAX_BLOCK_WEIGHT) {
if (GetBlockWeight(block) > MaxBlockWeight(nHeight, fSegwitSeasoned)) {
return state.DoS(100, false, REJECT_INVALID, "bad-blk-weight", false, strprintf("%s : weight limit failed", __func__));
}

Expand Down

0 comments on commit c11c37b

Please sign in to comment.