mirror of
https://github.com/bitcoin/bitcoin.git
synced 2026-06-10 22:58:40 +02:00
mining: add cooldown argument to createNewBlock()
At startup, if the needs to catch up, connected mining clients will receive a flood of new templates as new blocks are connected. Fix this by adding a cooldown argument to createNewBlock(). When set to true, block template creation is briefly paused while the best header chain is ahead of the tip. This wait only happens when the best header extends the current tip, to ignore competing branches. Additionally, cooldown waits for isInitialBlockDownload() to latch to false, which happens when there is less than a day of blocks left to sync. When cooldown is false createNewBlock() returns immediately. The argument is optional, because many tests are negatively impacted by this mechanism, and single miner signets could end up stuck if no block was mined for a day. The getblocktemplate RPC also opts out, because it would add a delay to each call. Fixes #33994
This commit is contained in:
@@ -4,18 +4,22 @@
|
||||
# file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
||||
"""Test the IPC (multiprocess) Mining interface."""
|
||||
import asyncio
|
||||
import time
|
||||
from contextlib import AsyncExitStack
|
||||
from io import BytesIO
|
||||
import re
|
||||
from test_framework.blocktools import NULL_OUTPOINT
|
||||
from test_framework.messages import (
|
||||
MAX_BLOCK_WEIGHT,
|
||||
CBlockHeader,
|
||||
CTransaction,
|
||||
CTxIn,
|
||||
CTxOut,
|
||||
CTxInWitness,
|
||||
ser_uint256,
|
||||
COIN,
|
||||
from_hex,
|
||||
msg_headers,
|
||||
)
|
||||
from test_framework.script import (
|
||||
CScript,
|
||||
@@ -24,9 +28,11 @@ from test_framework.script import (
|
||||
from test_framework.test_framework import BitcoinTestFramework
|
||||
from test_framework.util import (
|
||||
assert_equal,
|
||||
assert_greater_than_or_equal,
|
||||
assert_not_equal
|
||||
)
|
||||
from test_framework.wallet import MiniWallet
|
||||
from test_framework.p2p import P2PInterface
|
||||
from test_framework.ipc_util import (
|
||||
destroying,
|
||||
mining_create_block_template,
|
||||
@@ -141,9 +147,26 @@ class IPCMiningTest(BitcoinTestFramework):
|
||||
|
||||
async def async_routine():
|
||||
ctx, mining = await self.make_mining_ctx()
|
||||
blockref = await mining.getTip(ctx)
|
||||
|
||||
async with AsyncExitStack() as stack:
|
||||
self.log.debug("createNewBlock() should wait if tip is still updating")
|
||||
self.disconnect_nodes(0, 1)
|
||||
node1_block_hash = self.generate(self.nodes[1], 1, sync_fun=self.no_op)[0]
|
||||
header = from_hex(CBlockHeader(), self.nodes[1].getblockheader(node1_block_hash, False))
|
||||
header_only_peer = self.nodes[0].add_p2p_connection(P2PInterface())
|
||||
header_only_peer.send_and_ping(msg_headers([header]))
|
||||
start = time.time()
|
||||
async with destroying((await mining.createNewBlock(ctx, self.default_block_create_options)).result, ctx):
|
||||
pass
|
||||
# Lower-bound only: a heavily loaded CI host might still exceed 0.9s
|
||||
# even without the cooldown, so this can miss regressions but avoids
|
||||
# spurious failures.
|
||||
assert_greater_than_or_equal(time.time() - start, 0.9)
|
||||
|
||||
header_only_peer.peer_disconnect()
|
||||
self.connect_nodes(0, 1)
|
||||
self.sync_all()
|
||||
|
||||
self.log.debug("Create a template")
|
||||
template = await mining_create_block_template(mining, stack, ctx, self.default_block_create_options)
|
||||
assert template is not None
|
||||
@@ -152,8 +175,9 @@ class IPCMiningTest(BitcoinTestFramework):
|
||||
header = (await template.getBlockHeader(ctx)).result
|
||||
assert_equal(len(header), block_header_size)
|
||||
block = await mining_get_block(template, ctx)
|
||||
assert_equal(ser_uint256(block.hashPrevBlock), blockref.result.hash)
|
||||
assert len(block.vtx) >= 1
|
||||
current_tip = self.nodes[0].getbestblockhash()
|
||||
assert_equal(ser_uint256(block.hashPrevBlock), ser_uint256(int(current_tip, 16)))
|
||||
assert_greater_than_or_equal(len(block.vtx), 1)
|
||||
txfees = await template.getTxFees(ctx)
|
||||
assert_equal(len(txfees.result), 0)
|
||||
txsigops = await template.getTxSigops(ctx)
|
||||
|
||||
Reference in New Issue
Block a user