Merge 2ec9c943a4
into bad91d661e
This commit is contained in:
commit
c2380ec5c5
|
@ -116,7 +116,7 @@ static const unsigned int MAX_BLOCKS_TO_ANNOUNCE = 8;
|
|||
/** Maximum number of unconnecting headers announcements before DoS score */
|
||||
static const int MAX_UNCONNECTING_HEADERS = 10;
|
||||
/** Minimum blocks required to signal NODE_NETWORK_LIMITED */
|
||||
static const unsigned int NODE_NETWORK_LIMITED_MIN_BLOCKS = 288;
|
||||
static const unsigned int NODE_NETWORK_LIMITED_MIN_BLOCKS = 1440;
|
||||
/** Average delay between local address broadcasts */
|
||||
static constexpr std::chrono::hours AVG_LOCAL_ADDRESS_BROADCAST_INTERVAL{24};
|
||||
/** Average delay between peer address broadcasts */
|
||||
|
|
|
@ -288,7 +288,7 @@ enum ServiceFlags : uint64_t {
|
|||
// See BIP157 and BIP158 for details on how this is implemented.
|
||||
NODE_COMPACT_FILTERS = (1 << 6),
|
||||
// NODE_NETWORK_LIMITED means the same as NODE_NETWORK with the limitation of only
|
||||
// serving the last 288 (2 day) blocks
|
||||
// serving the last 1,440 (1 day) blocks
|
||||
// See BIP159 for details on how this is implemented.
|
||||
NODE_NETWORK_LIMITED = (1 << 10),
|
||||
|
||||
|
|
|
@ -1364,12 +1364,12 @@ static void CheckForkWarningConditions() EXCLUSIVE_LOCKS_REQUIRED(cs_main)
|
|||
if (::ChainstateActive().IsInitialBlockDownload())
|
||||
return;
|
||||
|
||||
// If our best fork is no longer within 72 blocks (+/- 12 hours if no one mines it)
|
||||
// If our best fork is no longer within 360 blocks (+/- 6 hours if no one mines it)
|
||||
// of our head, drop it
|
||||
if (pindexBestForkTip && ::ChainActive().Height() - pindexBestForkTip->nHeight >= 72)
|
||||
if (pindexBestForkTip && ::ChainActive().Height() - pindexBestForkTip->nHeight >= 360)
|
||||
pindexBestForkTip = nullptr;
|
||||
|
||||
if (pindexBestForkTip || (pindexBestInvalid && pindexBestInvalid->nChainWork > ::ChainActive().Tip()->nChainWork + (GetBlockProof(*::ChainActive().Tip()) * 6)))
|
||||
if (pindexBestForkTip || (pindexBestInvalid && pindexBestInvalid->nChainWork > ::ChainActive().Tip()->nChainWork + (GetBlockProof(*::ChainActive().Tip()) * 30)))
|
||||
{
|
||||
if (!GetfLargeWorkForkFound() && pindexBestForkBase)
|
||||
{
|
||||
|
@ -2056,8 +2056,8 @@ bool CChainState::ConnectBlock(const CBlock& block, BlockValidationState& state,
|
|||
// Now that the whole chain is irreversibly beyond that time it is applied to all blocks except the
|
||||
// two in the chain that violate it. This prevents exploiting the issue against nodes during their
|
||||
// initial block download.
|
||||
bool fEnforceBIP30 = !((pindex->nHeight==91842 && pindex->GetBlockHash() == uint256S("0x00000000000a4d0a398161ffc163c503763b1f4360639393e0e4c8e300e0caec")) ||
|
||||
(pindex->nHeight==91880 && pindex->GetBlockHash() == uint256S("0x00000000000743f190a18c5577a3c2d2a1f610ae9601ac046a38084ccb7cd721")));
|
||||
// Dogecoin: BIP30 has been active since inception
|
||||
bool fEnforceBIP30 = true;
|
||||
|
||||
// Once BIP34 activated it was not possible to create new duplicate coinbases and thus other than starting
|
||||
// with the 2 existing duplicate coinbase pairs, not possible to create overwriting txs. But by the
|
||||
|
|
|
@ -81,18 +81,18 @@ static const bool DEFAULT_FEEFILTER = true;
|
|||
/** Default for -stopatheight */
|
||||
static const int DEFAULT_STOPATHEIGHT = 0;
|
||||
/** Block files containing a block-height within MIN_BLOCKS_TO_KEEP of ::ChainActive().Tip() will not be pruned. */
|
||||
static const unsigned int MIN_BLOCKS_TO_KEEP = 288;
|
||||
static const unsigned int MIN_BLOCKS_TO_KEEP = 1440;
|
||||
static const signed int DEFAULT_CHECKBLOCKS = 6;
|
||||
static const unsigned int DEFAULT_CHECKLEVEL = 3;
|
||||
// Require that user allocate at least 550 MiB for block & undo files (blk???.dat and rev???.dat)
|
||||
// At 1MB per block, 288 blocks = 288MB.
|
||||
// Add 15% for Undo data = 331MB
|
||||
// Add 20% for Orphan block rate = 397MB
|
||||
// We want the low water mark after pruning to be at least 397 MB and since we prune in
|
||||
// Require that user allocate at least 2,200 MiB for block & undo files (blk???.dat and rev???.dat)
|
||||
// At 1MB per block, 1,440 blocks = 1,440MB.
|
||||
// Add 15% for Undo data = 1,656MB
|
||||
// Add 20% for Orphan block rate = 1,987MB
|
||||
// We want the low water mark after pruning to be at least 1,987 MB and since we prune in
|
||||
// full block file chunks, we need the high water mark which triggers the prune to be
|
||||
// one 128MB block file + added 15% undo data = 147MB greater for a total of 545MB
|
||||
// Setting the target to >= 550 MiB will make it likely we can respect the target.
|
||||
static const uint64_t MIN_DISK_SPACE_FOR_BLOCK_FILES = 550 * 1024 * 1024;
|
||||
// one 128MB block file + added 15% undo data = 2,134MB greater for a total of 545MB
|
||||
// Setting the target to >= 2,200 MiB will make it likely we can respect the target.
|
||||
static const uint64_t MIN_DISK_SPACE_FOR_BLOCK_FILES = 2200ULL * 1024 * 1024;
|
||||
|
||||
struct BlockHasher
|
||||
{
|
||||
|
@ -370,7 +370,7 @@ private:
|
|||
* Pruning functions are called from FlushStateToDisk when the global fCheckForPruning flag has been set.
|
||||
* Block and undo files are deleted in lock-step (when blk00003.dat is deleted, so is rev00003.dat.)
|
||||
* Pruning cannot take place until the longest chain is at least a certain length (100000 on mainnet, 1000 on testnet, 1000 on regtest).
|
||||
* Pruning will never delete a block within a defined distance (currently 288) from the active chain's tip.
|
||||
* Pruning will never delete a block within a defined distance (currently 1,440) from the active chain's tip.
|
||||
* The block index is updated by unsetting HAVE_DATA and HAVE_UNDO for any blocks that were stored in the deleted files.
|
||||
* A db flag records the fact that at least some block files have been pruned.
|
||||
*
|
||||
|
|
|
@ -4,9 +4,9 @@
|
|||
# file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
||||
"""Tests NODE_NETWORK_LIMITED.
|
||||
|
||||
Tests that a node configured with -prune=550 signals NODE_NETWORK_LIMITED correctly
|
||||
Tests that a node configured with -prune=2250 signals NODE_NETWORK_LIMITED correctly
|
||||
and that it responds to getdata requests for blocks correctly:
|
||||
- send a block within 288 + 2 of the tip
|
||||
- send a block within 1440 + 2 of the tip
|
||||
- disconnect peers who request blocks older than that."""
|
||||
from test_framework.messages import CInv, MSG_BLOCK, msg_getdata, msg_verack, NODE_NETWORK_LIMITED, NODE_WITNESS
|
||||
from test_framework.p2p import P2PInterface
|
||||
|
@ -35,7 +35,7 @@ class NodeNetworkLimitedTest(BitcoinTestFramework):
|
|||
def set_test_params(self):
|
||||
self.setup_clean_chain = True
|
||||
self.num_nodes = 3
|
||||
self.extra_args = [['-prune=550', '-addrmantest'], [], []]
|
||||
self.extra_args = [['-prune=2250', '-addrmantest'], [], []]
|
||||
|
||||
def disconnect_all(self):
|
||||
self.disconnect_nodes(0, 1)
|
||||
|
@ -59,15 +59,15 @@ class NodeNetworkLimitedTest(BitcoinTestFramework):
|
|||
|
||||
self.log.info("Mine enough blocks to reach the NODE_NETWORK_LIMITED range.")
|
||||
self.connect_nodes(0, 1)
|
||||
blocks = self.nodes[1].generatetoaddress(292, self.nodes[1].get_deterministic_priv_key().address)
|
||||
blocks = self.nodes[1].generatetoaddress(1444, self.nodes[1].get_deterministic_priv_key().address)
|
||||
self.sync_blocks([self.nodes[0], self.nodes[1]])
|
||||
|
||||
self.log.info("Make sure we can max retrieve block at tip-288.")
|
||||
self.log.info("Make sure we can max retrieve block at tip-1440.")
|
||||
node.send_getdata_for_block(blocks[1]) # last block in valid range
|
||||
node.wait_for_block(int(blocks[1], 16), timeout=3)
|
||||
|
||||
self.log.info("Requesting block at height 2 (tip-289) must fail (ignored).")
|
||||
node.send_getdata_for_block(blocks[0]) # first block outside of the 288+2 limit
|
||||
self.log.info("Requesting block at height 2 (tip-1440) must fail (ignored).")
|
||||
node.send_getdata_for_block(blocks[0]) # first block outside of the 1440+2 limit
|
||||
node.wait_for_disconnect(5)
|
||||
|
||||
self.log.info("Check local address relay, do a fresh connection.")
|
||||
|
|
|
@ -27,7 +27,7 @@ Node1 is unused in tests 3-7:
|
|||
Node0 should process the second block but be stuck on the shorter chain,
|
||||
because it's missing an intermediate block.
|
||||
|
||||
4c.Send 288 more blocks on the longer chain (the number of blocks ahead
|
||||
4c.Send 1440 more blocks on the longer chain (the number of blocks ahead
|
||||
we currently store).
|
||||
Node0 should process all but the last block (too far ahead in height).
|
||||
|
||||
|
@ -147,12 +147,12 @@ class AcceptBlockTest(BitcoinTestFramework):
|
|||
self.nodes[0].getblock(block_h3.hash)
|
||||
self.log.info("Unrequested more-work block accepted")
|
||||
|
||||
# 4c. Now mine 288 more blocks and deliver; all should be processed but
|
||||
# 4c. Now mine 1440 more blocks and deliver; all should be processed but
|
||||
# the last (height-too-high) on node (as long as it is not missing any headers)
|
||||
tip = block_h3
|
||||
all_blocks = []
|
||||
for i in range(288):
|
||||
next_block = create_block(tip.sha256, create_coinbase(i + 4), tip.nTime+1)
|
||||
for i in range(1440):
|
||||
next_block = create_block(tip.sha256, create_coinbase(i + 4), tip.nTime+1, version=4)
|
||||
next_block.solve()
|
||||
all_blocks.append(next_block)
|
||||
tip = next_block
|
||||
|
@ -170,11 +170,11 @@ class AcceptBlockTest(BitcoinTestFramework):
|
|||
self.nodes[0].getblock(all_blocks[1].hash)
|
||||
|
||||
# Now send the blocks in all_blocks
|
||||
for i in range(288):
|
||||
for i in range(1440):
|
||||
test_node.send_message(msg_block(all_blocks[i]))
|
||||
test_node.sync_with_ping()
|
||||
|
||||
# Blocks 1-287 should be accepted, block 288 should be ignored because it's too far ahead
|
||||
# Blocks 1-1439 should be accepted, block 1440 should be ignored because it's too far ahead
|
||||
for x in all_blocks[:-1]:
|
||||
self.nodes[0].getblock(x.hash)
|
||||
assert_raises_rpc_error(-1, "Block not found on disk", self.nodes[0].getblock, all_blocks[-1].hash)
|
||||
|
@ -213,49 +213,49 @@ class AcceptBlockTest(BitcoinTestFramework):
|
|||
|
||||
# 7. Send the missing block for the third time (now it is requested)
|
||||
test_node.send_and_ping(msg_block(block_h1f))
|
||||
assert_equal(self.nodes[0].getblockcount(), 290)
|
||||
self.nodes[0].getblock(all_blocks[286].hash)
|
||||
assert_equal(self.nodes[0].getbestblockhash(), all_blocks[286].hash)
|
||||
assert_raises_rpc_error(-1, "Block not found on disk", self.nodes[0].getblock, all_blocks[287].hash)
|
||||
assert_equal(self.nodes[0].getblockcount(), 1442)
|
||||
self.nodes[0].getblock(all_blocks[1438].hash)
|
||||
assert_equal(self.nodes[0].getbestblockhash(), all_blocks[1438].hash)
|
||||
assert_raises_rpc_error(-1, "Block not found on disk", self.nodes[0].getblock, all_blocks[1439].hash)
|
||||
self.log.info("Successfully reorged to longer chain")
|
||||
|
||||
# 8. Create a chain which is invalid at a height longer than the
|
||||
# current chain, but which has more blocks on top of that
|
||||
block_289f = create_block(all_blocks[284].sha256, create_coinbase(289), all_blocks[284].nTime+1)
|
||||
block_289f.solve()
|
||||
block_290f = create_block(block_289f.sha256, create_coinbase(290), block_289f.nTime+1)
|
||||
block_290f.solve()
|
||||
block_291 = create_block(block_290f.sha256, create_coinbase(291), block_290f.nTime+1)
|
||||
# block_291 spends a coinbase below maturity!
|
||||
block_291.vtx.append(create_tx_with_script(block_290f.vtx[0], 0, script_sig=b"42", amount=1))
|
||||
block_291.hashMerkleRoot = block_291.calc_merkle_root()
|
||||
block_291.solve()
|
||||
block_292 = create_block(block_291.sha256, create_coinbase(292), block_291.nTime+1)
|
||||
block_292.solve()
|
||||
block_1441f = create_block(all_blocks[1436].sha256, create_coinbase(1441), all_blocks[1436].nTime+1, version=4)
|
||||
block_1441f.solve()
|
||||
block_1442f = create_block(block_1441f.sha256, create_coinbase(1442), block_1441f.nTime+1, version=4)
|
||||
block_1442f.solve()
|
||||
block_1443 = create_block(block_1442f.sha256, create_coinbase(1443), block_1442f.nTime+1, version=4)
|
||||
# block_1443 spends a coinbase below maturity!
|
||||
block_1443.vtx.append(create_tx_with_script(block_1442f.vtx[0], 0, script_sig=b"42", amount=1))
|
||||
block_1443.hashMerkleRoot = block_1443.calc_merkle_root()
|
||||
block_1443.solve()
|
||||
block_1444 = create_block(block_1443.sha256, create_coinbase(1444), block_1443.nTime+1, version=4)
|
||||
block_1444.solve()
|
||||
|
||||
# Now send all the headers on the chain and enough blocks to trigger reorg
|
||||
headers_message = msg_headers()
|
||||
headers_message.headers.append(CBlockHeader(block_289f))
|
||||
headers_message.headers.append(CBlockHeader(block_290f))
|
||||
headers_message.headers.append(CBlockHeader(block_291))
|
||||
headers_message.headers.append(CBlockHeader(block_292))
|
||||
headers_message.headers.append(CBlockHeader(block_1441f))
|
||||
headers_message.headers.append(CBlockHeader(block_1442f))
|
||||
headers_message.headers.append(CBlockHeader(block_1443))
|
||||
headers_message.headers.append(CBlockHeader(block_1444))
|
||||
test_node.send_and_ping(headers_message)
|
||||
|
||||
tip_entry_found = False
|
||||
for x in self.nodes[0].getchaintips():
|
||||
if x['hash'] == block_292.hash:
|
||||
if x['hash'] == block_1444.hash:
|
||||
assert_equal(x['status'], "headers-only")
|
||||
tip_entry_found = True
|
||||
assert tip_entry_found
|
||||
assert_raises_rpc_error(-1, "Block not found on disk", self.nodes[0].getblock, block_292.hash)
|
||||
assert_raises_rpc_error(-1, "Block not found on disk", self.nodes[0].getblock, block_1444.hash)
|
||||
|
||||
test_node.send_message(msg_block(block_289f))
|
||||
test_node.send_and_ping(msg_block(block_290f))
|
||||
test_node.send_message(msg_block(block_1441f))
|
||||
test_node.send_and_ping(msg_block(block_1442f))
|
||||
|
||||
self.nodes[0].getblock(block_289f.hash)
|
||||
self.nodes[0].getblock(block_290f.hash)
|
||||
self.nodes[0].getblock(block_1441f.hash)
|
||||
self.nodes[0].getblock(block_1442f.hash)
|
||||
|
||||
test_node.send_message(msg_block(block_291))
|
||||
test_node.send_message(msg_block(block_1443))
|
||||
|
||||
# At this point we've sent an obviously-bogus block, wait for full processing
|
||||
# without assuming whether we will be disconnected or not
|
||||
|
@ -269,16 +269,16 @@ class AcceptBlockTest(BitcoinTestFramework):
|
|||
self.nodes[0].disconnect_p2ps()
|
||||
test_node = self.nodes[0].add_p2p_connection(P2PInterface())
|
||||
|
||||
# We should have failed reorg and switched back to 290 (but have block 291)
|
||||
assert_equal(self.nodes[0].getblockcount(), 290)
|
||||
assert_equal(self.nodes[0].getbestblockhash(), all_blocks[286].hash)
|
||||
assert_equal(self.nodes[0].getblock(block_291.hash)["confirmations"], -1)
|
||||
# We should have failed reorg and switched back to 1442 (but have block 1443)
|
||||
assert_equal(self.nodes[0].getblockcount(), 1442)
|
||||
assert_equal(self.nodes[0].getbestblockhash(), all_blocks[1438].hash)
|
||||
assert_equal(self.nodes[0].getblock(block_1443.hash)["confirmations"], -1)
|
||||
|
||||
# Now send a new header on the invalid chain, indicating we're forked off, and expect to get disconnected
|
||||
block_293 = create_block(block_292.sha256, create_coinbase(293), block_292.nTime+1)
|
||||
block_293.solve()
|
||||
block_1445 = create_block(block_1444.sha256, create_coinbase(1445), block_1444.nTime+1)
|
||||
block_1445.solve()
|
||||
headers_message = msg_headers()
|
||||
headers_message.headers.append(CBlockHeader(block_293))
|
||||
headers_message.headers.append(CBlockHeader(block_1445))
|
||||
test_node.send_message(headers_message)
|
||||
test_node.wait_for_disconnect()
|
||||
|
||||
|
|
|
@ -112,16 +112,16 @@ class BlockchainTest(BitcoinTestFramework):
|
|||
# should have exact keys
|
||||
assert_equal(sorted(res.keys()), keys)
|
||||
|
||||
self.restart_node(0, ['-stopatheight=207', '-prune=550'])
|
||||
self.restart_node(0, ['-stopatheight=207', '-prune=2200'])
|
||||
res = self.nodes[0].getblockchaininfo()
|
||||
# result should have these additional pruning keys if prune=550
|
||||
# result should have these additional pruning keys if prune=2200
|
||||
assert_equal(sorted(res.keys()), sorted(['pruneheight', 'automatic_pruning', 'prune_target_size'] + keys))
|
||||
|
||||
# check related fields
|
||||
assert res['pruned']
|
||||
assert_equal(res['pruneheight'], 0)
|
||||
assert res['automatic_pruning']
|
||||
assert_equal(res['prune_target_size'], 576716800)
|
||||
assert_equal(res['prune_target_size'], 2306867200)
|
||||
assert_greater_than(res['size_on_disk'], 0)
|
||||
|
||||
assert_equal(res['softforks'], {
|
||||
|
|
Loading…
Reference in a new issue