mirror of
https://github.com/bitcoin/bitcoin.git
synced 2026-03-02 17:56:16 +00:00
Previously the coinbase transaction generated by our miner code was not used downstream, because the getblocktemplate RPC excludes it. Since the Mining IPC interface was introduced in #30200 we do expose this dummy coinbase transaction. In Stratum v2 several parts of it are communicated downstream, including the scriptSig. This commit removes the dummy extraNonce from the coinbase scriptSig in block templates requested via IPC. This limits the scriptSig to what is essential for consensus (BIP34) and removes the need for external mining software to remove the dummy, or even ignore the scriptSig we provide and generate it some other way. This could cause problems if a future soft fork requires additional data to be committed here. A test is added to verify the new IPC behavior. It achieves this by introducing an include_dummy_extranonce option which defaults to false with all test code updated to set it to true. Because this option is not exposed via IPC, callers will no longer see it. The caller needs to ensure that for blocks 1 through 16 they pad the scriptSig in order to avoid bad-cb-length. Co-authored-by: Anthony Towns <aj@erisian.com.au>
77 lines
2.5 KiB
C++
77 lines
2.5 KiB
C++
// Copyright (c) 2025-present 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;
|
|
options.include_dummy_extranonce = true;
|
|
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()
|