Permalink
Browse files

Activate 32MB blocks after May 15, 2018

Summary: This ensure that no block bigger than 8MB will be accepted or mined before the fork point and will start accepting blocks up to 32MB after the fork point by default.

Test Plan:
Added code to ensure the miner react properly to the fork activation.
Updated the compact block tests to ensure we activate the fork before send very large blocks
Updated fullblocktest to check for proper activation.

Reviewers: #bitcoin_abc, schancel

Reviewed By: #bitcoin_abc, schancel

Subscribers: teamcity

Differential Revision: https://reviews.bitcoinabc.org/D1149
  • Loading branch information...
deadalnix committed Mar 2, 2018
1 parent 3ea13c3 commit 699f4b867318486b915bd2d3b2102fb49ec652f1
@@ -152,6 +152,9 @@ class CMainParams : public CChainParams {
// November 13, 2017 hard fork
consensus.daaHeight = 504031;

// May 15, 2018 hard fork
consensus.monolithActivationTime = 1526400000;

/**
* The message start string is designed to be unlikely to occur in
* normal data. The characters are rarely used upper ASCII, not valid as
@@ -325,6 +328,9 @@ class CTestNetParams : public CChainParams {
// November 13, 2017 hard fork
consensus.daaHeight = 1188697;

// May 15, 2018 hard fork
consensus.monolithActivationTime = 1526400000;

diskMagic[0] = 0x0b;
diskMagic[1] = 0x11;
diskMagic[2] = 0x09;
@@ -449,6 +455,9 @@ class CRegTestParams : public CChainParams {
// November 13, 2017 hard fork is always on on regtest.
consensus.daaHeight = 0;

// May 15, 2018 hard fork.
consensus.monolithActivationTime = 1526400000;

diskMagic[0] = 0xfa;
diskMagic[1] = 0xbf;
diskMagic[2] = 0xb5;
@@ -15,7 +15,7 @@ static const uint64_t MAX_TX_SIZE = ONE_MEGABYTE;
/** The maximum allowed size for a block, before the UAHF */
static const uint64_t LEGACY_MAX_BLOCK_SIZE = ONE_MEGABYTE;
/** Default setting for maximum allowed size for a block, in bytes */
static const uint64_t DEFAULT_MAX_BLOCK_SIZE = 8 * ONE_MEGABYTE;
static const uint64_t DEFAULT_MAX_BLOCK_SIZE = 32 * ONE_MEGABYTE;
/** The maximum allowed number of signature check operations per MB in a block
* (network rule) */
static const int64_t MAX_BLOCK_SIGOPS_PER_MB = 20000;
@@ -52,6 +52,8 @@ struct Params {
int uahfHeight;
/** Block height at which the new DAA becomes active */
int daaHeight;
/** Unix time used for MTP activation of May 15 2018, hardfork */
int monolithActivationTime;
/** Block height at which OP_RETURN replay protection stops */
int antiReplayOpReturnSunsetHeight;
/** Committed OP_RETURN value for replay protection */
@@ -87,6 +87,13 @@ static uint64_t ComputeMaxGeneratedBlockSize(const Config &config,
std::max(uint64_t(1000), std::min(config.GetMaxBlockSize() - 1000,
nMaxGeneratedBlockSize));

// If May 15, 2018 HF is not activated yet, we also want to limit the max
// generated block size to 8MB - 1000
if (!IsMonolithEnabled(config, pindexPrev)) {
nMaxGeneratedBlockSize =
std::min(8 * ONE_MEGABYTE - 1000, nMaxGeneratedBlockSize);
}

return nMaxGeneratedBlockSize;
}

@@ -31,7 +31,7 @@ static CFeeRate blockMinFeeRate = CFeeRate(DEFAULT_BLOCK_MIN_TX_FEE);

static struct {
uint8_t extranonce;
unsigned int nonce;
uint32_t nonce;
} blockinfo[] = {
{4, 0xa4a3e223}, {2, 0x15c32f9e}, {1, 0x0375b547}, {1, 0x7004a8a5},
{2, 0xce440296}, {2, 0x52cfe198}, {1, 0x77a72cd0}, {2, 0xbb5d6f84},
@@ -723,19 +723,37 @@ BOOST_AUTO_TEST_CASE(BlockAssembler_construction) {
CheckBlockMaxSize(chainparams, ONE_MEGABYTE - 999, ONE_MEGABYTE - 999);
CheckBlockMaxSize(chainparams, ONE_MEGABYTE, ONE_MEGABYTE - 999);

// Test around higher limit such as 8MB
// The maximum block size to be generated before the May 15, 2018 HF
static const auto EIGHT_MEGABYTES = 8 * ONE_MEGABYTE;
config.SetMaxBlockSize(EIGHT_MEGABYTES);
static const auto LEGACY_CAP = EIGHT_MEGABYTES - 1000;

// Test around historical 8MB cap.
config.SetMaxBlockSize(EIGHT_MEGABYTES + 1);
CheckBlockMaxSize(chainparams, EIGHT_MEGABYTES - 1001,
EIGHT_MEGABYTES - 1001);
CheckBlockMaxSize(chainparams, EIGHT_MEGABYTES - 1000,
EIGHT_MEGABYTES - 1000);
CheckBlockMaxSize(chainparams, EIGHT_MEGABYTES - 999,
EIGHT_MEGABYTES - 1000);
CheckBlockMaxSize(chainparams, EIGHT_MEGABYTES - 1000, LEGACY_CAP);
CheckBlockMaxSize(chainparams, EIGHT_MEGABYTES - 999, LEGACY_CAP);
CheckBlockMaxSize(chainparams, EIGHT_MEGABYTES, EIGHT_MEGABYTES - 1000);

// Test around default cap
config.SetMaxBlockSize(DEFAULT_MAX_BLOCK_SIZE);

// We are stuck at the legacy cap before activation.
CheckBlockMaxSize(chainparams, DEFAULT_MAX_BLOCK_SIZE, LEGACY_CAP);

// Activate May 15, 2018 HF the dirty way
const int64_t monolithTime =
config.GetChainParams().GetConsensus().monolithActivationTime;
auto pindex = chainActive.Tip();
for (size_t i = 0; pindex && i < 5; i++) {
BOOST_CHECK(!IsMonolithEnabled(config, chainActive.Tip()));
pindex->nTime = monolithTime;
pindex = pindex->pprev;
}

BOOST_CHECK(IsMonolithEnabled(config, chainActive.Tip()));

// Now we can use the default max block size.
CheckBlockMaxSize(chainparams, DEFAULT_MAX_BLOCK_SIZE - 1001,
DEFAULT_MAX_BLOCK_SIZE - 1001);
CheckBlockMaxSize(chainparams, DEFAULT_MAX_BLOCK_SIZE - 1000,
@@ -599,6 +599,19 @@ bool IsDAAEnabled(const Config &config, const CBlockIndex *pindexPrev) {
return IsDAAEnabled(config, pindexPrev->nHeight);
}

static bool IsMonolithEnabled(const Config &config, int64_t nMedianTimePast) {
return nMedianTimePast >=
config.GetChainParams().GetConsensus().monolithActivationTime;
}

bool IsMonolithEnabled(const Config &config, const CBlockIndex *pindexPrev) {
if (pindexPrev == nullptr) {
return false;
}

return IsMonolithEnabled(config, pindexPrev->GetMedianTimePast());
}

/**
* Make mempool consistent after a reorg, by re-adding or recursively erasing
* disconnected block transactions from the mempool, and also removing any other
@@ -3562,6 +3575,17 @@ static bool ContextualCheckBlock(const Config &config, const CBlock &block,
nLockTimeFlags |= LOCKTIME_MEDIAN_TIME_PAST;
}

if (!IsMonolithEnabled(config, pindexPrev)) {
// When the May 15, 2018 HF is not enabled, block cannot be bigger
// than 8MB .
const uint64_t currentBlockSize =
::GetSerializeSize(block, SER_NETWORK, PROTOCOL_VERSION);
if (currentBlockSize > 8 * ONE_MEGABYTE) {
return state.DoS(100, false, REJECT_INVALID, "bad-blk-length",
false, "size limits failed");
}
}

const int64_t nMedianTimePast =
pindexPrev == nullptr ? 0 : pindexPrev->GetMedianTimePast();

@@ -360,6 +360,9 @@ bool IsUAHFenabled(const Config &config, const CBlockIndex *pindexPrev);
/** Check if DAA HF has activated. */
bool IsDAAEnabled(const Config &config, const CBlockIndex *pindexPrev);

/** Check if May 15, 2018 HF has activated. */
bool IsMonolithEnabled(const Config &config, const CBlockIndex *pindexPrev);

/**
* (try to) add transaction to memory pool
* plTxnReplaced will be appended to with all transactions replaced from
@@ -21,6 +21,9 @@
MAX_BLOCK_SIGOPS_PER_MB, MAX_TX_SIGOPS_COUNT)
from collections import deque

# far into the future
MONOLITH_START_TIME = 2000000000


class PreviousSpendableOutput():

@@ -95,6 +98,7 @@ def run_test(self):
NetworkThread().start()
# Set the blocksize to 2MB as initial condition
self.nodes[0].setexcessiveblock(self.excessive_block_size)
self.nodes[0].setmocktime(MONOLITH_START_TIME)
self.test.run()

def add_transactions_to_block(self, block, tx_list):
@@ -268,6 +272,19 @@ def update_block(block_number, new_transactions):
block(5000 + i)
test.blocks_and_transactions.append([self.tip, True])
save_spendable_output()

# Fork block
bfork = block(5555)
bfork.nTime = MONOLITH_START_TIME
update_block(5555, [])
test.blocks_and_transactions.append([self.tip, True])

# Get to one block of the May 15, 2018 HF activation
for i in range(5):
block(5100 + i)
test.blocks_and_transactions.append([self.tip, True])

# Send it all to the node at once.
yield test

# collect spendable outputs now to avoid cluttering the code later on
@@ -22,6 +22,9 @@
MAX_BLOCK_SIGOPS_PER_MB, MAX_TX_SIGOPS_COUNT)
from collections import deque

# far into the future
MONOLITH_START_TIME = 2000000000


class PreviousSpendableOutput():

@@ -59,6 +62,7 @@ def run_test(self):
NetworkThread().start()
# Set the blocksize to 2MB as initial condition
self.nodes[0].setexcessiveblock(self.excessive_block_size)
self.nodes[0].setmocktime(MONOLITH_START_TIME)
self.test.run()

def add_transactions_to_block(self, block, tx_list):
@@ -241,11 +245,34 @@ def update_block(block_number, new_transactions):
out.append(get_spendable_output())

# Let's build some blocks and test them.
for i in range(16):
for i in range(15):
n = i + 1
block(n, spend=out[i], block_size=n * ONE_MEGABYTE)
block(n, spend=out[i], block_size=n * ONE_MEGABYTE // 2)
yield accepted()

# Fork block
bfork = block(5555, out[15], block_size=8 * ONE_MEGABYTE)
bfork.nTime = MONOLITH_START_TIME
update_block(5555, [])
yield accepted()

# Get to one block of the May 15, 2018 HF activation
for i in range(4):
block(5100 + i)
test.blocks_and_transactions.append([self.tip, True])
yield test

# Before we acivate the May 15, 2018 HF, 8MB is the limit.
block(4444, spend=out[16], block_size=8 * ONE_MEGABYTE + 1)
yield rejected(RejectResult(16, b'bad-blk-length'))

# Rewind bad block.
tip(5103)

# Actiavte the May 15, 2018 HF
block(5104)
yield accepted()

# block of maximal size
block(17, spend=out[16], block_size=self.excessive_block_size)
yield accepted()

0 comments on commit 699f4b8

Please sign in to comment.