mirror of
https://github.com/bitcoin/bitcoin.git
synced 2025-03-17 21:32:00 +01:00
miner: have waitNext return after 20 min on testnet
On testnet we need to create a min diff template after 20 min.
This commit is contained in:
parent
d4020f502a
commit
cadbd4137d
@ -64,6 +64,9 @@ public:
|
||||
* for the next block should rise (default infinite).
|
||||
*
|
||||
* @returns a new BlockTemplate or nothing if the timeout occurs.
|
||||
*
|
||||
* On testnet this will additionally return a template with difficulty 1 if
|
||||
* the tip is more than 20 minutes old.
|
||||
*/
|
||||
virtual std::unique_ptr<BlockTemplate> waitNext(const node::BlockWaitOptions options = {}) = 0;
|
||||
};
|
||||
|
@ -958,6 +958,7 @@ public:
|
||||
auto now{NodeClock::now()};
|
||||
const auto deadline = now + options.timeout;
|
||||
const MillisecondsDouble tick{1000};
|
||||
const bool allow_min_difficulty{chainman().GetParams().GetConsensus().fPowAllowMinDifficultyBlocks};
|
||||
|
||||
do {
|
||||
bool tip_changed{false};
|
||||
@ -982,6 +983,14 @@ public:
|
||||
// Must release m_tip_block_mutex before locking cs_main, to avoid deadlocks.
|
||||
LOCK(::cs_main);
|
||||
|
||||
// On test networks return a minimum difficulty block after 20 minutes
|
||||
if (!tip_changed && allow_min_difficulty) {
|
||||
const NodeClock::time_point tip_time{std::chrono::seconds{chainman().ActiveChain().Tip()->GetBlockTime()}};
|
||||
if (now > tip_time + 20min) {
|
||||
tip_changed = true;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* We determine if fees increased compared to the previous template by generating
|
||||
* a fresh template. There may be more efficient ways to determine how much
|
||||
|
@ -121,6 +121,7 @@ add_executable(test_bitcoin
|
||||
streams_tests.cpp
|
||||
sync_tests.cpp
|
||||
system_tests.cpp
|
||||
testnet4_miner_tests.cpp
|
||||
timeoffsets_tests.cpp
|
||||
torcontrol_tests.cpp
|
||||
transaction_tests.cpp
|
||||
|
75
src/test/testnet4_miner_tests.cpp
Normal file
75
src/test/testnet4_miner_tests.cpp
Normal file
@ -0,0 +1,75 @@
|
||||
// Copyright (c) 2025 The Bitcoin Core developers
|
||||
// Distributed under the MIT software license, see the accompanying
|
||||
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
||||
|
||||
#include <common/system.h>
|
||||
#include <interfaces/mining.h>
|
||||
#include <node/miner.h>
|
||||
#include <util/time.h>
|
||||
#include <validation.h>
|
||||
|
||||
#include <test/util/setup_common.h>
|
||||
|
||||
#include <boost/test/unit_test.hpp>
|
||||
|
||||
using interfaces::BlockTemplate;
|
||||
using interfaces::Mining;
|
||||
using node::BlockAssembler;
|
||||
using node::BlockWaitOptions;
|
||||
|
||||
namespace testnet4_miner_tests {
|
||||
|
||||
struct Testnet4MinerTestingSetup : public Testnet4Setup {
|
||||
std::unique_ptr<Mining> MakeMining()
|
||||
{
|
||||
return interfaces::MakeMining(m_node);
|
||||
}
|
||||
};
|
||||
} // namespace testnet4_miner_tests
|
||||
|
||||
BOOST_FIXTURE_TEST_SUITE(testnet4_miner_tests, Testnet4MinerTestingSetup)
|
||||
|
||||
BOOST_AUTO_TEST_CASE(MiningInterface)
|
||||
{
|
||||
auto mining{MakeMining()};
|
||||
BOOST_REQUIRE(mining);
|
||||
|
||||
BlockAssembler::Options options;
|
||||
std::unique_ptr<BlockTemplate> block_template;
|
||||
|
||||
// Set node time a few minutes past the testnet4 genesis block
|
||||
const int64_t genesis_time{WITH_LOCK(cs_main, return m_node.chainman->ActiveChain().Tip()->GetBlockTime())};
|
||||
SetMockTime(genesis_time + 3 * 60);
|
||||
|
||||
block_template = mining->createNewBlock(options);
|
||||
BOOST_REQUIRE(block_template);
|
||||
|
||||
// The template should use the mocked system time
|
||||
BOOST_REQUIRE_EQUAL(block_template->getBlockHeader().nTime, genesis_time + 3 * 60);
|
||||
|
||||
const BlockWaitOptions wait_options{.timeout = MillisecondsDouble{0}, .fee_threshold = 1};
|
||||
|
||||
// waitNext() should return nullptr because there is no better template
|
||||
auto should_be_nullptr = block_template->waitNext(wait_options);
|
||||
BOOST_REQUIRE(should_be_nullptr == nullptr);
|
||||
|
||||
// This remains the case when exactly 20 minutes have gone by
|
||||
{
|
||||
LOCK(cs_main);
|
||||
SetMockTime(m_node.chainman->ActiveChain().Tip()->GetBlockTime() + 20 * 60);
|
||||
}
|
||||
should_be_nullptr = block_template->waitNext(wait_options);
|
||||
BOOST_REQUIRE(should_be_nullptr == nullptr);
|
||||
|
||||
// One second later the difficulty drops and it returns a new template
|
||||
// Note that we can't test the actual difficulty change, because the
|
||||
// difficulty is already at 1.
|
||||
{
|
||||
LOCK(cs_main);
|
||||
SetMockTime(m_node.chainman->ActiveChain().Tip()->GetBlockTime() + 20 * 60 + 1);
|
||||
}
|
||||
block_template = block_template->waitNext(wait_options);
|
||||
BOOST_REQUIRE(block_template);
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_SUITE_END()
|
@ -130,6 +130,12 @@ struct RegTestingSetup : public TestingSetup {
|
||||
: TestingSetup{ChainType::REGTEST} {}
|
||||
};
|
||||
|
||||
/** Identical to TestingSetup, but chain set to testnet4 */
|
||||
struct Testnet4Setup : public TestingSetup {
|
||||
Testnet4Setup()
|
||||
: TestingSetup{ChainType::TESTNET4} {}
|
||||
};
|
||||
|
||||
class CBlock;
|
||||
struct CMutableTransaction;
|
||||
class CScript;
|
||||
|
Loading…
x
Reference in New Issue
Block a user