|
| 1 | +// Copyright (c) 2025 The Bitcoin Core developers |
| 2 | +// Distributed under the MIT software license, see the accompanying |
| 3 | +// file COPYING or http://www.opensource.org/licenses/mit-license.php. |
| 4 | + |
| 5 | +#include <common/system.h> |
| 6 | +#include <interfaces/mining.h> |
| 7 | +#include <node/miner.h> |
| 8 | +#include <util/time.h> |
| 9 | +#include <validation.h> |
| 10 | + |
| 11 | +#include <test/util/setup_common.h> |
| 12 | + |
| 13 | +#include <boost/test/unit_test.hpp> |
| 14 | + |
| 15 | +using interfaces::BlockTemplate; |
| 16 | +using interfaces::Mining; |
| 17 | +using node::BlockAssembler; |
| 18 | +using node::BlockWaitOptions; |
| 19 | + |
| 20 | +namespace testnet4_miner_tests { |
| 21 | + |
| 22 | +struct Testnet4MinerTestingSetup : public Testnet4Setup { |
| 23 | + std::unique_ptr<Mining> MakeMining() |
| 24 | + { |
| 25 | + return interfaces::MakeMining(m_node); |
| 26 | + } |
| 27 | +}; |
| 28 | +} // namespace testnet4_miner_tests |
| 29 | + |
| 30 | +BOOST_FIXTURE_TEST_SUITE(testnet4_miner_tests, Testnet4MinerTestingSetup) |
| 31 | + |
| 32 | +BOOST_AUTO_TEST_CASE(MiningInterface) |
| 33 | +{ |
| 34 | + auto mining{MakeMining()}; |
| 35 | + BOOST_REQUIRE(mining); |
| 36 | + |
| 37 | + BlockAssembler::Options options; |
| 38 | + std::unique_ptr<BlockTemplate> block_template; |
| 39 | + |
| 40 | + // Set node time a few minutes past the testnet4 genesis block |
| 41 | + const int64_t genesis_time{WITH_LOCK(cs_main, return m_node.chainman->ActiveChain().Tip()->GetBlockTime())}; |
| 42 | + SetMockTime(genesis_time + 3 * 60); |
| 43 | + |
| 44 | + block_template = mining->createNewBlock(options); |
| 45 | + BOOST_REQUIRE(block_template); |
| 46 | + |
| 47 | + // The template should use the mocked system time |
| 48 | + BOOST_REQUIRE_EQUAL(block_template->getBlockHeader().nTime, genesis_time + 3 * 60); |
| 49 | + |
| 50 | + const BlockWaitOptions wait_options{.timeout = MillisecondsDouble{0}, .fee_threshold = 1}; |
| 51 | + |
| 52 | + // waitNext() should return nullptr because there is no better template |
| 53 | + auto should_be_nullptr = block_template->waitNext(wait_options); |
| 54 | + BOOST_REQUIRE(should_be_nullptr == nullptr); |
| 55 | + |
| 56 | + // This remains the case when exactly 20 minutes have gone by |
| 57 | + { |
| 58 | + LOCK(cs_main); |
| 59 | + SetMockTime(m_node.chainman->ActiveChain().Tip()->GetBlockTime() + 20 * 60); |
| 60 | + } |
| 61 | + should_be_nullptr = block_template->waitNext(wait_options); |
| 62 | + BOOST_REQUIRE(should_be_nullptr == nullptr); |
| 63 | + |
| 64 | + // One second later the difficulty drops and it returns a new template |
| 65 | + // Note that we can't test the actual difficulty change, because the |
| 66 | + // difficulty is already at 1. |
| 67 | + { |
| 68 | + LOCK(cs_main); |
| 69 | + SetMockTime(m_node.chainman->ActiveChain().Tip()->GetBlockTime() + 20 * 60 + 1); |
| 70 | + } |
| 71 | + block_template = block_template->waitNext(wait_options); |
| 72 | + BOOST_REQUIRE(block_template); |
| 73 | +} |
| 74 | + |
| 75 | +BOOST_AUTO_TEST_SUITE_END() |
0 commit comments