mirror of
https://github.com/bitcoin/bitcoin.git
synced 2026-06-10 14:48:46 +02:00
mining: use interface for tests, bench and fuzzers
Have most tests, benchmarks and fuzzers go through the mining interface. This is a refactor: it does not change what blocks are created, just how the creation calls are made. This avoids most direct test, benchmark and fuzzer use of node::BlockAssembler::Options, making it easier to drop in a later commit. Two exceptions which use BlockAssembler directly: - one check in test/miner_tests.cpp needs m_package_feerates - fuzz/tx_pool.cpp Finish() doesn't have access to a NodeContext Move test_block_validity from BlockAssembler::Options to BlockCreateOptions so bench/block_assemble.cpp can continue to set it. Just like coinbase_output_script, this is not exposed to IPC clients. Inline options variable in places where it's only needed once. We also drop one unused PrepareBlock declaration and one unused implementation. TestChain100Setup::CreateBlock no longer needs a chainstate argument, which in turn means it can be dropped from CreateAndProcessBlock. Using the Mining interface here also requires marking the test KernelNotifications chainstate as loaded after LoadVerifyActivateChainstate().
This commit is contained in:
@@ -20,7 +20,7 @@
|
||||
#include <memory>
|
||||
#include <vector>
|
||||
|
||||
using node::BlockAssembler;
|
||||
using node::BlockCreateOptions;
|
||||
|
||||
static void AssembleBlock(benchmark::Bench& bench)
|
||||
{
|
||||
@@ -28,8 +28,9 @@ static void AssembleBlock(benchmark::Bench& bench)
|
||||
|
||||
CScriptWitness witness;
|
||||
witness.stack.push_back(WITNESS_STACK_ELEM_OP_TRUE);
|
||||
BlockAssembler::Options options;
|
||||
options.coinbase_output_script = P2WSH_OP_TRUE;
|
||||
BlockCreateOptions options{
|
||||
.coinbase_output_script = P2WSH_OP_TRUE,
|
||||
};
|
||||
|
||||
// Collect some loose transactions that spend the coinbases of our mined blocks
|
||||
constexpr size_t NUM_BLOCKS{200};
|
||||
@@ -60,12 +61,12 @@ static void BlockAssemblerAddPackageTxns(benchmark::Bench& bench)
|
||||
FastRandomContext det_rand{true};
|
||||
auto testing_setup{MakeNoLogFileContext<TestChain100Setup>()};
|
||||
testing_setup->PopulateMempool(det_rand, /*num_transactions=*/1000, /*submit=*/true);
|
||||
BlockAssembler::Options assembler_options;
|
||||
assembler_options.test_block_validity = false;
|
||||
assembler_options.coinbase_output_script = P2WSH_OP_TRUE;
|
||||
|
||||
bench.run([&] {
|
||||
PrepareBlock(testing_setup->m_node, assembler_options);
|
||||
PrepareBlock(testing_setup->m_node, {
|
||||
.coinbase_output_script = P2WSH_OP_TRUE,
|
||||
.test_block_validity = false
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@@ -39,7 +39,7 @@ CBlock CreateTestBlock(
|
||||
{COutPoint(coinbase_to_spend->GetHash(), 0)},
|
||||
chainstate.m_chain.Height() + 1, keys, outputs, {}, {})};
|
||||
const CScript coinbase_spk{GetScriptForDestination(coinbase_taproot)};
|
||||
test_setup.CreateAndProcessBlock({first_tx}, coinbase_spk, &chainstate);
|
||||
test_setup.CreateAndProcessBlock({first_tx}, coinbase_spk);
|
||||
|
||||
std::vector<CMutableTransaction> txs;
|
||||
txs.reserve(num_txs);
|
||||
@@ -59,7 +59,7 @@ CBlock CreateTestBlock(
|
||||
}
|
||||
|
||||
// Coinbase output can use any output type as it is not spent and will not change the benchmark
|
||||
return test_setup.CreateBlock(txs, coinbase_spk, chainstate);
|
||||
return test_setup.CreateBlock(txs, coinbase_spk);
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
@@ -83,8 +83,6 @@ public:
|
||||
// Configuration parameters for the block size
|
||||
size_t nBlockMaxWeight{DEFAULT_BLOCK_MAX_WEIGHT};
|
||||
CFeeRate blockMinFeeRate{DEFAULT_BLOCK_MIN_TX_FEE};
|
||||
// Whether to call TestBlockValidity() at the end of CreateNewBlock().
|
||||
bool test_block_validity{true};
|
||||
bool print_modified_fee{DEFAULT_PRINT_MODIFIED_FEE};
|
||||
};
|
||||
|
||||
|
||||
@@ -62,6 +62,11 @@ struct BlockCreateOptions {
|
||||
* coinbase_max_additional_weight and coinbase_output_max_additional_sigops.
|
||||
*/
|
||||
CScript coinbase_output_script{CScript() << OP_TRUE};
|
||||
/**
|
||||
* Whether to call TestBlockValidity() at the end of CreateNewBlock().
|
||||
* Should only be used for tests / benchmarks.
|
||||
*/
|
||||
bool test_block_validity{true};
|
||||
};
|
||||
|
||||
struct BlockWaitOptions {
|
||||
|
||||
@@ -8,6 +8,7 @@
|
||||
#include <consensus/merkle.h>
|
||||
#include <consensus/validation.h>
|
||||
#include <index/blockfilterindex.h>
|
||||
#include <interfaces/mining.h>
|
||||
#include <interfaces/chain.h>
|
||||
#include <node/miner.h>
|
||||
#include <pow.h>
|
||||
@@ -20,9 +21,7 @@
|
||||
#include <boost/test/unit_test.hpp>
|
||||
#include <future>
|
||||
|
||||
using node::BlockAssembler;
|
||||
using node::BlockManager;
|
||||
using node::CBlockTemplate;
|
||||
|
||||
BOOST_AUTO_TEST_SUITE(blockfilter_index_tests)
|
||||
|
||||
@@ -69,10 +68,12 @@ CBlock BuildChainTestingSetup::CreateBlock(const CBlockIndex* prev,
|
||||
const std::vector<CMutableTransaction>& txns,
|
||||
const CScript& scriptPubKey)
|
||||
{
|
||||
BlockAssembler::Options options;
|
||||
options.coinbase_output_script = scriptPubKey;
|
||||
std::unique_ptr<CBlockTemplate> pblocktemplate = BlockAssembler{m_node.chainman->ActiveChainstate(), m_node.mempool.get(), options}.CreateNewBlock();
|
||||
CBlock& block = pblocktemplate->block;
|
||||
auto mining{interfaces::MakeMining(m_node)};
|
||||
auto block_template{mining->createNewBlock({
|
||||
.coinbase_output_script = scriptPubKey,
|
||||
}, /*cooldown=*/false)};
|
||||
BOOST_REQUIRE(block_template);
|
||||
CBlock block{block_template->getBlock()};
|
||||
block.hashPrevBlock = prev->GetBlockHash();
|
||||
block.nTime = prev->nTime + 1;
|
||||
|
||||
|
||||
@@ -83,7 +83,7 @@ BOOST_FIXTURE_TEST_CASE(coinstatsindex_unclean_shutdown, TestChain100Setup)
|
||||
CBlockIndex* new_block_index = nullptr;
|
||||
{
|
||||
const CScript script_pub_key{CScript() << ToByteVector(coinbaseKey.GetPubKey()) << OP_CHECKSIG};
|
||||
const CBlock block = this->CreateBlock({}, script_pub_key, chainstate);
|
||||
const CBlock block = this->CreateBlock({}, script_pub_key);
|
||||
|
||||
new_block = std::make_shared<CBlock>(block);
|
||||
|
||||
|
||||
@@ -21,7 +21,6 @@
|
||||
#include <validation.h>
|
||||
#include <validationinterface.h>
|
||||
|
||||
using node::BlockAssembler;
|
||||
using node::NodeContext;
|
||||
|
||||
namespace {
|
||||
@@ -44,11 +43,10 @@ void initialize_tx_pool()
|
||||
g_setup = testing_setup.get();
|
||||
SetMockTime(WITH_LOCK(g_setup->m_node.chainman->GetMutex(), return g_setup->m_node.chainman->ActiveTip()->Time()));
|
||||
|
||||
BlockAssembler::Options options;
|
||||
options.coinbase_output_script = P2WSH_EMPTY;
|
||||
|
||||
for (int i = 0; i < 2 * COINBASE_MATURITY; ++i) {
|
||||
COutPoint prevout{MineBlock(g_setup->m_node, options)};
|
||||
COutPoint prevout{MineBlock(g_setup->m_node, {
|
||||
.coinbase_output_script = P2WSH_EMPTY,
|
||||
})};
|
||||
if (i < COINBASE_MATURITY) {
|
||||
// Remember the txids to avoid expensive disk access later on
|
||||
g_outpoints_coinbase_init_mature.push_back(prevout);
|
||||
|
||||
@@ -42,7 +42,7 @@ void ResetChainman(TestingSetup& setup)
|
||||
setup.m_make_chainman();
|
||||
setup.LoadVerifyActivateChainstate();
|
||||
for (int i = 0; i < 2 * COINBASE_MATURITY; i++) {
|
||||
node::BlockAssembler::Options options;
|
||||
node::BlockCreateOptions options;
|
||||
MineBlock(setup.m_node, options);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -36,7 +36,7 @@ void ResetChainman(TestingSetup& setup)
|
||||
setup.m_node.chainman.reset();
|
||||
setup.m_make_chainman();
|
||||
setup.LoadVerifyActivateChainstate();
|
||||
node::BlockAssembler::Options options;
|
||||
node::BlockCreateOptions options;
|
||||
for (int i = 0; i < 2 * COINBASE_MATURITY; i++) {
|
||||
MineBlock(setup.m_node, options);
|
||||
}
|
||||
|
||||
@@ -46,11 +46,10 @@ void initialize_tx_pool()
|
||||
g_setup = testing_setup.get();
|
||||
SetMockTime(WITH_LOCK(g_setup->m_node.chainman->GetMutex(), return g_setup->m_node.chainman->ActiveTip()->Time()));
|
||||
|
||||
BlockAssembler::Options options;
|
||||
options.coinbase_output_script = P2WSH_OP_TRUE;
|
||||
|
||||
for (int i = 0; i < 2 * COINBASE_MATURITY; ++i) {
|
||||
COutPoint prevout{MineBlock(g_setup->m_node, options)};
|
||||
COutPoint prevout{MineBlock(g_setup->m_node, {
|
||||
.coinbase_output_script = P2WSH_OP_TRUE,
|
||||
})};
|
||||
// Remember the txids to avoid expensive disk access later on
|
||||
auto& outpoints = i < COINBASE_MATURITY ?
|
||||
g_outpoints_coinbase_init_mature :
|
||||
|
||||
@@ -19,8 +19,6 @@
|
||||
#include <util/time.h>
|
||||
#include <validation.h>
|
||||
|
||||
using node::BlockAssembler;
|
||||
|
||||
FUZZ_TARGET(utxo_total_supply)
|
||||
{
|
||||
SeedRandomStateForTest(SeedRand::ZEROS);
|
||||
@@ -44,11 +42,11 @@ FUZZ_TARGET(utxo_total_supply)
|
||||
LOCK(chainman.GetMutex());
|
||||
return chainman.ActiveHeight();
|
||||
};
|
||||
BlockAssembler::Options options;
|
||||
options.coinbase_output_script = CScript() << OP_FALSE;
|
||||
const auto PrepareNextBlock = [&]() {
|
||||
// Use OP_FALSE to avoid BIP30 check from hitting early
|
||||
auto block = PrepareBlock(node, options);
|
||||
auto block = PrepareBlock(node, {
|
||||
.coinbase_output_script = CScript() << OP_FALSE,
|
||||
});
|
||||
// Replace OP_FALSE with OP_TRUE
|
||||
{
|
||||
CMutableTransaction tx{*block->vtx.back()};
|
||||
|
||||
@@ -37,6 +37,7 @@ using namespace util::hex_literals;
|
||||
using interfaces::BlockTemplate;
|
||||
using interfaces::Mining;
|
||||
using node::BlockAssembler;
|
||||
using node::BlockCreateOptions;
|
||||
|
||||
namespace miner_tests {
|
||||
struct MinerTestingSetup : public TestingSetup {
|
||||
@@ -115,8 +116,9 @@ void MinerTestingSetup::TestPackageSelection(const CScript& scriptPubKey, const
|
||||
{
|
||||
CTxMemPool& tx_mempool{MakeMempool()};
|
||||
auto mining{MakeMining()};
|
||||
BlockAssembler::Options options;
|
||||
options.coinbase_output_script = scriptPubKey;
|
||||
BlockCreateOptions options{
|
||||
.coinbase_output_script = scriptPubKey,
|
||||
};
|
||||
|
||||
LOCK(tx_mempool.cs);
|
||||
BOOST_CHECK(tx_mempool.size() == 0);
|
||||
@@ -175,7 +177,12 @@ void MinerTestingSetup::TestPackageSelection(const CScript& scriptPubKey, const
|
||||
BOOST_CHECK(block.vtx[3]->GetHash() == hashMediumFeeTx);
|
||||
|
||||
// Test the inclusion of package feerates in the block template and ensure they are sequential.
|
||||
const auto block_package_feerates = BlockAssembler{m_node.chainman->ActiveChainstate(), &tx_mempool, options}.CreateNewBlock()->m_package_feerates;
|
||||
// Can't use the Mining interface because it needs access to m_package_feerates.
|
||||
const auto block_package_feerates = BlockAssembler{
|
||||
m_node.chainman->ActiveChainstate(),
|
||||
&tx_mempool,
|
||||
{}
|
||||
}.CreateNewBlock()->m_package_feerates;
|
||||
BOOST_CHECK(block_package_feerates.size() == 2);
|
||||
|
||||
// parent_tx and high_fee_tx are added to the block as a package.
|
||||
@@ -333,8 +340,9 @@ void MinerTestingSetup::TestBasicMining(const CScript& scriptPubKey, const std::
|
||||
auto mining{MakeMining()};
|
||||
BOOST_REQUIRE(mining);
|
||||
|
||||
BlockAssembler::Options options;
|
||||
options.coinbase_output_script = scriptPubKey;
|
||||
BlockCreateOptions options{
|
||||
.coinbase_output_script = scriptPubKey,
|
||||
};
|
||||
|
||||
{
|
||||
CTxMemPool& tx_mempool{MakeMempool()};
|
||||
@@ -659,8 +667,9 @@ void MinerTestingSetup::TestPrioritisedMining(const CScript& scriptPubKey, const
|
||||
auto mining{MakeMining()};
|
||||
BOOST_REQUIRE(mining);
|
||||
|
||||
BlockAssembler::Options options;
|
||||
options.coinbase_output_script = scriptPubKey;
|
||||
BlockCreateOptions options{
|
||||
.coinbase_output_script = scriptPubKey,
|
||||
};
|
||||
|
||||
CTxMemPool& tx_mempool{MakeMempool()};
|
||||
LOCK(tx_mempool.cs);
|
||||
@@ -748,8 +757,9 @@ BOOST_AUTO_TEST_CASE(CreateNewBlock_validity)
|
||||
|
||||
// Note that by default, these tests run with size accounting enabled.
|
||||
CScript scriptPubKey = CScript() << "04678afdb0fe5548271967f1a67130b7105cd6a828e03909a67962e0ea1f61deb649f6bc3f4cef38c4f35504e51ec112de5c384df7ba0b8d578a4c702b6bf11d5f"_hex << OP_CHECKSIG;
|
||||
BlockAssembler::Options options;
|
||||
options.coinbase_output_script = scriptPubKey;
|
||||
BlockCreateOptions options{
|
||||
.coinbase_output_script = scriptPubKey,
|
||||
};
|
||||
|
||||
// Create and check a simple template
|
||||
std::unique_ptr<BlockTemplate> block_template = mining->createNewBlock(options, /*cooldown=*/false);
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
// file COPYING or https://www.opensource.org/licenses/mit-license.php.
|
||||
|
||||
#include <chainparams.h>
|
||||
#include <interfaces/mining.h>
|
||||
#include <node/miner.h>
|
||||
#include <net_processing.h>
|
||||
#include <pow.h>
|
||||
@@ -16,12 +17,14 @@ BOOST_FIXTURE_TEST_SUITE(peerman_tests, RegTestingSetup)
|
||||
/** Window, in blocks, for connecting to NODE_NETWORK_LIMITED peers */
|
||||
static constexpr int64_t NODE_NETWORK_LIMITED_ALLOW_CONN_BLOCKS = 144;
|
||||
|
||||
static void mineBlock(const node::NodeContext& node, std::chrono::seconds block_time)
|
||||
static void mineBlock(node::NodeContext& node, std::chrono::seconds block_time)
|
||||
{
|
||||
auto curr_time = GetTime<std::chrono::seconds>();
|
||||
node::BlockAssembler::Options options;
|
||||
SetMockTime(block_time); // update time so the block is created with it
|
||||
CBlock block = node::BlockAssembler{node.chainman->ActiveChainstate(), nullptr, options}.CreateNewBlock()->block;
|
||||
auto mining{interfaces::MakeMining(node)};
|
||||
auto block_template{mining->createNewBlock({}, /*cooldown=*/false)};
|
||||
BOOST_REQUIRE(block_template);
|
||||
CBlock block{block_template->getBlock()};
|
||||
while (!CheckProofOfWork(block.GetHash(), block.nBits, node.chainman->GetConsensus())) ++block.nNonce;
|
||||
block.fChecked = true; // little speedup
|
||||
SetMockTime(curr_time); // process block at current time
|
||||
|
||||
@@ -15,7 +15,6 @@
|
||||
|
||||
using interfaces::BlockTemplate;
|
||||
using interfaces::Mining;
|
||||
using node::BlockAssembler;
|
||||
using node::BlockWaitOptions;
|
||||
|
||||
namespace testnet4_miner_tests {
|
||||
@@ -35,18 +34,18 @@ 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 auto template_time{3min + WITH_LOCK(cs_main, return m_node.chainman->ActiveChain().Tip()->Time())};
|
||||
NodeClockContext clock_ctx{template_time};
|
||||
|
||||
block_template = mining->createNewBlock(options, /*cooldown=*/false);
|
||||
block_template = mining->createNewBlock({}, /*cooldown=*/false);
|
||||
BOOST_REQUIRE(block_template);
|
||||
|
||||
// The template should use the mocked system time
|
||||
BOOST_REQUIRE_EQUAL(block_template->getBlockHeader().Time(), template_time);
|
||||
BOOST_REQUIRE_EQUAL(TicksSinceEpoch<std::chrono::seconds>(block_template->getBlockHeader().Time()),
|
||||
TicksSinceEpoch<std::chrono::seconds>(template_time));
|
||||
|
||||
const BlockWaitOptions wait_options{.timeout = MillisecondsDouble{0}, .fee_threshold = 1};
|
||||
|
||||
|
||||
@@ -7,6 +7,7 @@
|
||||
#include <chainparams.h>
|
||||
#include <consensus/merkle.h>
|
||||
#include <consensus/validation.h>
|
||||
#include <interfaces/mining.h>
|
||||
#include <key_io.h>
|
||||
#include <node/context.h>
|
||||
#include <pow.h>
|
||||
@@ -20,17 +21,15 @@
|
||||
#include <algorithm>
|
||||
#include <memory>
|
||||
|
||||
using node::BlockAssembler;
|
||||
using node::NodeContext;
|
||||
|
||||
COutPoint generatetoaddress(const NodeContext& node, const std::string& address)
|
||||
{
|
||||
const auto dest = DecodeDestination(address);
|
||||
assert(IsValidDestination(dest));
|
||||
BlockAssembler::Options assembler_options;
|
||||
assembler_options.coinbase_output_script = GetScriptForDestination(dest);
|
||||
|
||||
return MineBlock(node, assembler_options);
|
||||
return MineBlock(node, {
|
||||
.coinbase_output_script = GetScriptForDestination(dest),
|
||||
});
|
||||
}
|
||||
|
||||
std::vector<std::shared_ptr<CBlock>> CreateBlockChain(size_t total_height, const CChainParams& params)
|
||||
@@ -68,7 +67,7 @@ std::vector<std::shared_ptr<CBlock>> CreateBlockChain(size_t total_height, const
|
||||
return ret;
|
||||
}
|
||||
|
||||
COutPoint MineBlock(const NodeContext& node, const node::BlockAssembler::Options& assembler_options)
|
||||
COutPoint MineBlock(const NodeContext& node, const node::BlockCreateOptions& assembler_options)
|
||||
{
|
||||
auto block = PrepareBlock(node, assembler_options);
|
||||
auto valid = MineBlock(node, block);
|
||||
@@ -122,12 +121,11 @@ COutPoint ProcessBlock(const NodeContext& node, const std::shared_ptr<CBlock>& b
|
||||
}
|
||||
|
||||
std::shared_ptr<CBlock> PrepareBlock(const NodeContext& node,
|
||||
const BlockAssembler::Options& assembler_options)
|
||||
const node::BlockCreateOptions& assembler_options)
|
||||
{
|
||||
auto block = std::make_shared<CBlock>(
|
||||
BlockAssembler{Assert(node.chainman)->ActiveChainstate(), Assert(node.mempool.get()), assembler_options}
|
||||
.CreateNewBlock()
|
||||
->block);
|
||||
auto mining = interfaces::MakeMining(node);
|
||||
auto block_template = mining->createNewBlock(assembler_options, /*cooldown=*/false);
|
||||
auto block = std::make_shared<CBlock>(Assert(block_template)->getBlock());
|
||||
|
||||
LOCK(cs_main);
|
||||
block->nTime = Assert(node.chainman)->ActiveChain().Tip()->GetMedianTimePast() + 1;
|
||||
@@ -135,10 +133,3 @@ std::shared_ptr<CBlock> PrepareBlock(const NodeContext& node,
|
||||
|
||||
return block;
|
||||
}
|
||||
std::shared_ptr<CBlock> PrepareBlock(const NodeContext& node, const CScript& coinbase_scriptPubKey)
|
||||
{
|
||||
BlockAssembler::Options assembler_options;
|
||||
assembler_options.coinbase_output_script = coinbase_scriptPubKey;
|
||||
ApplyArgsManOptions(*node.args, assembler_options);
|
||||
return PrepareBlock(node, assembler_options);
|
||||
}
|
||||
|
||||
@@ -24,7 +24,7 @@ std::vector<std::shared_ptr<CBlock>> CreateBlockChain(size_t total_height, const
|
||||
|
||||
/** Returns the generated coin */
|
||||
COutPoint MineBlock(const node::NodeContext&,
|
||||
const node::BlockAssembler::Options& assembler_options);
|
||||
const node::BlockCreateOptions& assembler_options);
|
||||
|
||||
/**
|
||||
* Returns the generated coin (or Null if the block was invalid).
|
||||
@@ -38,9 +38,8 @@ COutPoint MineBlock(const node::NodeContext&, std::shared_ptr<CBlock>& block);
|
||||
COutPoint ProcessBlock(const node::NodeContext&, const std::shared_ptr<CBlock>& block);
|
||||
|
||||
/** Prepare a block to be mined */
|
||||
std::shared_ptr<CBlock> PrepareBlock(const node::NodeContext&);
|
||||
std::shared_ptr<CBlock> PrepareBlock(const node::NodeContext& node,
|
||||
const node::BlockAssembler::Options& assembler_options);
|
||||
const node::BlockCreateOptions& assembler_options);
|
||||
|
||||
/** RPC-like helper function, returns the generated coin */
|
||||
COutPoint generatetoaddress(const node::NodeContext&, const std::string& address);
|
||||
|
||||
@@ -13,6 +13,7 @@
|
||||
#include <consensus/validation.h>
|
||||
#include <crypto/sha256.h>
|
||||
#include <init.h>
|
||||
#include <interfaces/mining.h>
|
||||
#include <init/common.h>
|
||||
#include <interfaces/chain.h>
|
||||
#include <kernel/mempool_entry.h>
|
||||
@@ -67,7 +68,6 @@
|
||||
|
||||
using namespace util::hex_literals;
|
||||
using node::ApplyArgsManOptions;
|
||||
using node::BlockAssembler;
|
||||
using node::BlockManager;
|
||||
using node::KernelNotifications;
|
||||
using node::LoadChainstate;
|
||||
@@ -335,6 +335,8 @@ void ChainTestingSetup::LoadVerifyActivateChainstate()
|
||||
std::tie(status, error) = VerifyLoadedChainstate(chainman, options);
|
||||
assert(status == node::ChainstateLoadStatus::SUCCESS);
|
||||
|
||||
m_node.notifications->setChainstateLoaded(true);
|
||||
|
||||
BlockValidationState state;
|
||||
if (!chainman.ActiveChainstate().ActivateBestChain(state)) {
|
||||
throw std::runtime_error(strprintf("ActivateBestChain failed. (%s)", state.ToString()));
|
||||
@@ -411,12 +413,15 @@ void TestChain100Setup::mineBlocks(int num_blocks)
|
||||
|
||||
CBlock TestChain100Setup::CreateBlock(
|
||||
const std::vector<CMutableTransaction>& txns,
|
||||
const CScript& scriptPubKey,
|
||||
Chainstate& chainstate)
|
||||
const CScript& scriptPubKey)
|
||||
{
|
||||
BlockAssembler::Options options;
|
||||
options.coinbase_output_script = scriptPubKey;
|
||||
CBlock block = BlockAssembler{chainstate, nullptr, options}.CreateNewBlock()->block;
|
||||
auto mining{interfaces::MakeMining(m_node)};
|
||||
auto block_template{mining->createNewBlock({
|
||||
.use_mempool = false,
|
||||
.coinbase_output_script = scriptPubKey,
|
||||
}, /*cooldown=*/false)};
|
||||
Assert(block_template);
|
||||
CBlock block{block_template->getBlock()};
|
||||
|
||||
Assert(block.vtx.size() == 1);
|
||||
for (const CMutableTransaction& tx : txns) {
|
||||
@@ -431,14 +436,9 @@ CBlock TestChain100Setup::CreateBlock(
|
||||
|
||||
CBlock TestChain100Setup::CreateAndProcessBlock(
|
||||
const std::vector<CMutableTransaction>& txns,
|
||||
const CScript& scriptPubKey,
|
||||
Chainstate* chainstate)
|
||||
const CScript& scriptPubKey)
|
||||
{
|
||||
if (!chainstate) {
|
||||
chainstate = &Assert(m_node.chainman)->ActiveChainstate();
|
||||
}
|
||||
|
||||
CBlock block = this->CreateBlock(txns, scriptPubKey, *chainstate);
|
||||
CBlock block = this->CreateBlock(txns, scriptPubKey);
|
||||
std::shared_ptr<const CBlock> shared_pblock = std::make_shared<const CBlock>(block);
|
||||
Assert(m_node.chainman)->ProcessNewBlock(shared_pblock, true, true, nullptr);
|
||||
|
||||
|
||||
@@ -28,12 +28,7 @@
|
||||
#include <type_traits>
|
||||
#include <vector>
|
||||
|
||||
class arith_uint256;
|
||||
class CFeeRate;
|
||||
class Chainstate;
|
||||
class FastRandomContext;
|
||||
class uint160;
|
||||
class uint256;
|
||||
|
||||
/** Retrieve the command line arguments. */
|
||||
extern const std::function<std::vector<const char*>()> G_TEST_COMMAND_LINE_ARGUMENTS;
|
||||
@@ -134,7 +129,6 @@ struct Testnet4Setup : public TestingSetup {
|
||||
};
|
||||
|
||||
class CBlock;
|
||||
struct CMutableTransaction;
|
||||
class CScript;
|
||||
|
||||
/**
|
||||
@@ -148,11 +142,9 @@ struct TestChain100Setup : public TestingSetup {
|
||||
/**
|
||||
* Create a new block with just given transactions, coinbase paying to
|
||||
* scriptPubKey, and try to add it to the current chain.
|
||||
* If no chainstate is specified, default to the active.
|
||||
*/
|
||||
CBlock CreateAndProcessBlock(const std::vector<CMutableTransaction>& txns,
|
||||
const CScript& scriptPubKey,
|
||||
Chainstate* chainstate = nullptr);
|
||||
const CScript& scriptPubKey);
|
||||
|
||||
/**
|
||||
* Create a new block with just given transactions, coinbase paying to
|
||||
@@ -160,8 +152,7 @@ struct TestChain100Setup : public TestingSetup {
|
||||
*/
|
||||
CBlock CreateBlock(
|
||||
const std::vector<CMutableTransaction>& txns,
|
||||
const CScript& scriptPubKey,
|
||||
Chainstate& chainstate);
|
||||
const CScript& scriptPubKey);
|
||||
|
||||
//! Mine a series of new blocks on the active chain.
|
||||
void mineBlocks(int num_blocks);
|
||||
|
||||
@@ -7,6 +7,7 @@
|
||||
#include <chainparams.h>
|
||||
#include <consensus/merkle.h>
|
||||
#include <consensus/validation.h>
|
||||
#include <interfaces/mining.h>
|
||||
#include <node/miner.h>
|
||||
#include <pow.h>
|
||||
#include <random.h>
|
||||
@@ -21,7 +22,6 @@
|
||||
#include <thread>
|
||||
|
||||
using kernel::ChainstateRole;
|
||||
using node::BlockAssembler;
|
||||
|
||||
namespace validation_block_tests {
|
||||
struct MinerTestingSetup : public RegTestingSetup {
|
||||
@@ -67,10 +67,12 @@ std::shared_ptr<CBlock> MinerTestingSetup::Block(const uint256& prev_hash)
|
||||
static int i = 0;
|
||||
static uint64_t time = Params().GenesisBlock().nTime;
|
||||
|
||||
BlockAssembler::Options options;
|
||||
options.coinbase_output_script = CScript{} << i++ << OP_TRUE;
|
||||
auto ptemplate = BlockAssembler{m_node.chainman->ActiveChainstate(), m_node.mempool.get(), options}.CreateNewBlock();
|
||||
auto pblock = std::make_shared<CBlock>(ptemplate->block);
|
||||
auto mining{interfaces::MakeMining(m_node)};
|
||||
auto block_template{mining->createNewBlock({
|
||||
.coinbase_output_script = CScript{} << i++ << OP_TRUE,
|
||||
}, /*cooldown=*/false)};
|
||||
BOOST_REQUIRE(block_template);
|
||||
auto pblock = std::make_shared<CBlock>(block_template->getBlock());
|
||||
pblock->hashPrevBlock = prev_hash;
|
||||
pblock->nTime = ++time;
|
||||
|
||||
@@ -335,10 +337,12 @@ BOOST_AUTO_TEST_CASE(witness_commitment_index)
|
||||
LOCK(Assert(m_node.chainman)->GetMutex());
|
||||
CScript pubKey;
|
||||
pubKey << 1 << OP_TRUE;
|
||||
BlockAssembler::Options options;
|
||||
options.coinbase_output_script = pubKey;
|
||||
auto ptemplate = BlockAssembler{m_node.chainman->ActiveChainstate(), m_node.mempool.get(), options}.CreateNewBlock();
|
||||
CBlock pblock = ptemplate->block;
|
||||
auto mining{interfaces::MakeMining(m_node)};
|
||||
auto block_template{mining->createNewBlock({
|
||||
.coinbase_output_script = pubKey,
|
||||
}, /*cooldown=*/false)};
|
||||
BOOST_REQUIRE(block_template);
|
||||
CBlock pblock{block_template->getBlock()};
|
||||
|
||||
CTxOut witness;
|
||||
witness.scriptPubKey.resize(MINIMUM_WITNESS_COMMITMENT);
|
||||
|
||||
@@ -24,6 +24,8 @@
|
||||
|
||||
#include <boost/test/unit_test.hpp>
|
||||
|
||||
class CTxMemPool;
|
||||
|
||||
BOOST_FIXTURE_TEST_SUITE(validation_chainstate_tests, ChainTestingSetup)
|
||||
|
||||
//! Test resizing coins-related Chainstate caches during runtime.
|
||||
@@ -83,7 +85,7 @@ BOOST_FIXTURE_TEST_CASE(connect_tip_does_not_cache_inputs_on_failed_connect, Tes
|
||||
tx.vout.emplace_back(MAX_MONEY, CScript{} << OP_TRUE);
|
||||
|
||||
const auto tip{WITH_LOCK(cs_main, return chainstate.m_chain.Tip()->GetBlockHash())};
|
||||
const CBlock block{CreateBlock({tx}, CScript{} << OP_TRUE, chainstate)};
|
||||
const CBlock block{CreateBlock({tx}, CScript{} << OP_TRUE)};
|
||||
BOOST_CHECK(Assert(m_node.chainman)->ProcessNewBlock(std::make_shared<CBlock>(block), true, true, nullptr));
|
||||
|
||||
LOCK(cs_main);
|
||||
|
||||
Reference in New Issue
Block a user