rpc: Remove mempool global from miner

This commit is contained in:
MarcoFalke
2019-12-17 07:11:44 +07:00
parent 6666ef13f1
commit faa92a2297
13 changed files with 92 additions and 53 deletions

View File

@@ -15,6 +15,8 @@
#include <numeric> #include <numeric>
#include <regex> #include <regex>
const RegTestingSetup* g_testing_setup = nullptr;
void benchmark::ConsolePrinter::header() void benchmark::ConsolePrinter::header()
{ {
std::cout << "# Benchmark, evals, iterations, total, min, max, median" << std::endl; std::cout << "# Benchmark, evals, iterations, total, min, max, median" << std::endl;
@@ -113,6 +115,8 @@ void benchmark::BenchRunner::RunAll(Printer& printer, uint64_t num_evals, double
for (const auto& p : benchmarks()) { for (const auto& p : benchmarks()) {
RegTestingSetup test{}; RegTestingSetup test{};
assert(g_testing_setup == nullptr);
g_testing_setup = &test;
{ {
LOCK(cs_main); LOCK(cs_main);
assert(::ChainActive().Height() == 0); assert(::ChainActive().Height() == 0);
@@ -133,6 +137,7 @@ void benchmark::BenchRunner::RunAll(Printer& printer, uint64_t num_evals, double
p.second.func(state); p.second.func(state);
} }
printer.result(state); printer.result(state);
g_testing_setup = nullptr;
} }
printer.footer(); printer.footer();

View File

@@ -14,6 +14,9 @@
#include <boost/preprocessor/cat.hpp> #include <boost/preprocessor/cat.hpp>
#include <boost/preprocessor/stringize.hpp> #include <boost/preprocessor/stringize.hpp>
struct RegTestingSetup;
extern const RegTestingSetup* g_testing_setup; //!< A pointer to the current testing setup
// Simple micro-benchmarking framework; API mostly matches a subset of the Google Benchmark // Simple micro-benchmarking framework; API mostly matches a subset of the Google Benchmark
// framework (see https://github.com/google/benchmark) // framework (see https://github.com/google/benchmark)
// Why not use the Google Benchmark framework? Because adding Yet Another Dependency // Why not use the Google Benchmark framework? Because adding Yet Another Dependency

View File

@@ -6,6 +6,7 @@
#include <consensus/validation.h> #include <consensus/validation.h>
#include <crypto/sha256.h> #include <crypto/sha256.h>
#include <test/util/mining.h> #include <test/util/mining.h>
#include <test/util/setup_common.h>
#include <test/util/wallet.h> #include <test/util/wallet.h>
#include <txmempool.h> #include <txmempool.h>
#include <validation.h> #include <validation.h>
@@ -29,7 +30,7 @@ static void AssembleBlock(benchmark::State& state)
std::array<CTransactionRef, NUM_BLOCKS - COINBASE_MATURITY + 1> txs; std::array<CTransactionRef, NUM_BLOCKS - COINBASE_MATURITY + 1> txs;
for (size_t b{0}; b < NUM_BLOCKS; ++b) { for (size_t b{0}; b < NUM_BLOCKS; ++b) {
CMutableTransaction tx; CMutableTransaction tx;
tx.vin.push_back(MineBlock(SCRIPT_PUB)); tx.vin.push_back(MineBlock(g_testing_setup->m_node, SCRIPT_PUB));
tx.vin.back().scriptWitness = witness; tx.vin.back().scriptWitness = witness;
tx.vout.emplace_back(1337, SCRIPT_PUB); tx.vout.emplace_back(1337, SCRIPT_PUB);
if (NUM_BLOCKS - b >= COINBASE_MATURITY) if (NUM_BLOCKS - b >= COINBASE_MATURITY)
@@ -46,7 +47,7 @@ static void AssembleBlock(benchmark::State& state)
} }
while (state.KeepRunning()) { while (state.KeepRunning()) {
PrepareBlock(SCRIPT_PUB); PrepareBlock(g_testing_setup->m_node, SCRIPT_PUB);
} }
} }

View File

@@ -7,6 +7,7 @@
#include <node/context.h> #include <node/context.h>
#include <optional.h> #include <optional.h>
#include <test/util/mining.h> #include <test/util/mining.h>
#include <test/util/setup_common.h>
#include <test/util/wallet.h> #include <test/util/wallet.h>
#include <validationinterface.h> #include <validationinterface.h>
#include <wallet/wallet.h> #include <wallet/wallet.h>
@@ -29,8 +30,8 @@ static void WalletBalance(benchmark::State& state, const bool set_dirty, const b
if (add_watchonly) importaddress(wallet, ADDRESS_WATCHONLY); if (add_watchonly) importaddress(wallet, ADDRESS_WATCHONLY);
for (int i = 0; i < 100; ++i) { for (int i = 0; i < 100; ++i) {
generatetoaddress(address_mine.get_value_or(ADDRESS_WATCHONLY)); generatetoaddress(g_testing_setup->m_node, address_mine.get_value_or(ADDRESS_WATCHONLY));
generatetoaddress(ADDRESS_WATCHONLY); generatetoaddress(g_testing_setup->m_node, ADDRESS_WATCHONLY);
} }
SyncWithValidationInterfaceQueue(); SyncWithValidationInterfaceQueue();

View File

@@ -45,7 +45,9 @@ BlockAssembler::Options::Options() {
nBlockMaxWeight = DEFAULT_BLOCK_MAX_WEIGHT; nBlockMaxWeight = DEFAULT_BLOCK_MAX_WEIGHT;
} }
BlockAssembler::BlockAssembler(const CChainParams& params, const Options& options) : chainparams(params) BlockAssembler::BlockAssembler(const CTxMemPool& mempool, const CChainParams& params, const Options& options)
: chainparams(params),
m_mempool(mempool)
{ {
blockMinFeeRate = options.blockMinFeeRate; blockMinFeeRate = options.blockMinFeeRate;
// Limit weight to between 4K and MAX_BLOCK_WEIGHT-4K for sanity: // Limit weight to between 4K and MAX_BLOCK_WEIGHT-4K for sanity:
@@ -67,7 +69,8 @@ static BlockAssembler::Options DefaultOptions()
return options; return options;
} }
BlockAssembler::BlockAssembler(const CChainParams& params) : BlockAssembler(params, DefaultOptions()) {} BlockAssembler::BlockAssembler(const CTxMemPool& mempool, const CChainParams& params)
: BlockAssembler(mempool, params, DefaultOptions()) {}
void BlockAssembler::resetBlock() void BlockAssembler::resetBlock()
{ {
@@ -103,7 +106,7 @@ std::unique_ptr<CBlockTemplate> BlockAssembler::CreateNewBlock(const CScript& sc
pblocktemplate->vTxFees.push_back(-1); // updated at end pblocktemplate->vTxFees.push_back(-1); // updated at end
pblocktemplate->vTxSigOpsCost.push_back(-1); // updated at end pblocktemplate->vTxSigOpsCost.push_back(-1); // updated at end
LOCK2(cs_main, mempool.cs); LOCK2(cs_main, m_mempool.cs);
CBlockIndex* pindexPrev = ::ChainActive().Tip(); CBlockIndex* pindexPrev = ::ChainActive().Tip();
assert(pindexPrev != nullptr); assert(pindexPrev != nullptr);
nHeight = pindexPrev->nHeight + 1; nHeight = pindexPrev->nHeight + 1;
@@ -236,7 +239,7 @@ int BlockAssembler::UpdatePackagesForAdded(const CTxMemPool::setEntries& already
int nDescendantsUpdated = 0; int nDescendantsUpdated = 0;
for (CTxMemPool::txiter it : alreadyAdded) { for (CTxMemPool::txiter it : alreadyAdded) {
CTxMemPool::setEntries descendants; CTxMemPool::setEntries descendants;
mempool.CalculateDescendants(it, descendants); m_mempool.CalculateDescendants(it, descendants);
// Insert all descendants (not yet in block) into the modified set // Insert all descendants (not yet in block) into the modified set
for (CTxMemPool::txiter desc : descendants) { for (CTxMemPool::txiter desc : descendants) {
if (alreadyAdded.count(desc)) if (alreadyAdded.count(desc))
@@ -268,7 +271,7 @@ int BlockAssembler::UpdatePackagesForAdded(const CTxMemPool::setEntries& already
// cached size/sigops/fee values that are not actually correct. // cached size/sigops/fee values that are not actually correct.
bool BlockAssembler::SkipMapTxEntry(CTxMemPool::txiter it, indexed_modified_transaction_set &mapModifiedTx, CTxMemPool::setEntries &failedTx) bool BlockAssembler::SkipMapTxEntry(CTxMemPool::txiter it, indexed_modified_transaction_set &mapModifiedTx, CTxMemPool::setEntries &failedTx)
{ {
assert (it != mempool.mapTx.end()); assert(it != m_mempool.mapTx.end());
return mapModifiedTx.count(it) || inBlock.count(it) || failedTx.count(it); return mapModifiedTx.count(it) || inBlock.count(it) || failedTx.count(it);
} }
@@ -305,7 +308,7 @@ void BlockAssembler::addPackageTxs(int &nPackagesSelected, int &nDescendantsUpda
// and modifying them for their already included ancestors // and modifying them for their already included ancestors
UpdatePackagesForAdded(inBlock, mapModifiedTx); UpdatePackagesForAdded(inBlock, mapModifiedTx);
CTxMemPool::indexed_transaction_set::index<ancestor_score>::type::iterator mi = mempool.mapTx.get<ancestor_score>().begin(); CTxMemPool::indexed_transaction_set::index<ancestor_score>::type::iterator mi = m_mempool.mapTx.get<ancestor_score>().begin();
CTxMemPool::txiter iter; CTxMemPool::txiter iter;
// Limit the number of attempts to add transactions to the block when it is // Limit the number of attempts to add transactions to the block when it is
@@ -314,11 +317,10 @@ void BlockAssembler::addPackageTxs(int &nPackagesSelected, int &nDescendantsUpda
const int64_t MAX_CONSECUTIVE_FAILURES = 1000; const int64_t MAX_CONSECUTIVE_FAILURES = 1000;
int64_t nConsecutiveFailed = 0; int64_t nConsecutiveFailed = 0;
while (mi != mempool.mapTx.get<ancestor_score>().end() || !mapModifiedTx.empty()) while (mi != m_mempool.mapTx.get<ancestor_score>().end() || !mapModifiedTx.empty()) {
{
// First try to find a new transaction in mapTx to evaluate. // First try to find a new transaction in mapTx to evaluate.
if (mi != mempool.mapTx.get<ancestor_score>().end() && if (mi != m_mempool.mapTx.get<ancestor_score>().end() &&
SkipMapTxEntry(mempool.mapTx.project<0>(mi), mapModifiedTx, failedTx)) { SkipMapTxEntry(m_mempool.mapTx.project<0>(mi), mapModifiedTx, failedTx)) {
++mi; ++mi;
continue; continue;
} }
@@ -328,13 +330,13 @@ void BlockAssembler::addPackageTxs(int &nPackagesSelected, int &nDescendantsUpda
bool fUsingModified = false; bool fUsingModified = false;
modtxscoreiter modit = mapModifiedTx.get<ancestor_score>().begin(); modtxscoreiter modit = mapModifiedTx.get<ancestor_score>().begin();
if (mi == mempool.mapTx.get<ancestor_score>().end()) { if (mi == m_mempool.mapTx.get<ancestor_score>().end()) {
// We're out of entries in mapTx; use the entry from mapModifiedTx // We're out of entries in mapTx; use the entry from mapModifiedTx
iter = modit->iter; iter = modit->iter;
fUsingModified = true; fUsingModified = true;
} else { } else {
// Try to compare the mapTx entry to the mapModifiedTx entry // Try to compare the mapTx entry to the mapModifiedTx entry
iter = mempool.mapTx.project<0>(mi); iter = m_mempool.mapTx.project<0>(mi);
if (modit != mapModifiedTx.get<ancestor_score>().end() && if (modit != mapModifiedTx.get<ancestor_score>().end() &&
CompareTxMemPoolEntryByAncestorFee()(*modit, CTxMemPoolModifiedEntry(iter))) { CompareTxMemPoolEntryByAncestorFee()(*modit, CTxMemPoolModifiedEntry(iter))) {
// The best entry in mapModifiedTx has higher score // The best entry in mapModifiedTx has higher score
@@ -389,7 +391,7 @@ void BlockAssembler::addPackageTxs(int &nPackagesSelected, int &nDescendantsUpda
CTxMemPool::setEntries ancestors; CTxMemPool::setEntries ancestors;
uint64_t nNoLimit = std::numeric_limits<uint64_t>::max(); uint64_t nNoLimit = std::numeric_limits<uint64_t>::max();
std::string dummy; std::string dummy;
mempool.CalculateMemPoolAncestors(*iter, ancestors, nNoLimit, nNoLimit, nNoLimit, nNoLimit, dummy, false); m_mempool.CalculateMemPoolAncestors(*iter, ancestors, nNoLimit, nNoLimit, nNoLimit, nNoLimit, dummy, false);
onlyUnconfirmed(ancestors); onlyUnconfirmed(ancestors);
ancestors.insert(iter); ancestors.insert(iter);

View File

@@ -147,6 +147,7 @@ private:
int nHeight; int nHeight;
int64_t nLockTimeCutoff; int64_t nLockTimeCutoff;
const CChainParams& chainparams; const CChainParams& chainparams;
const CTxMemPool& m_mempool;
public: public:
struct Options { struct Options {
@@ -155,8 +156,8 @@ public:
CFeeRate blockMinFeeRate; CFeeRate blockMinFeeRate;
}; };
explicit BlockAssembler(const CChainParams& params); explicit BlockAssembler(const CTxMemPool& mempool, const CChainParams& params);
BlockAssembler(const CChainParams& params, const Options& options); explicit BlockAssembler(const CTxMemPool& mempool, const CChainParams& params, const Options& options);
/** Construct a new block template with coinbase to scriptPubKeyIn */ /** Construct a new block template with coinbase to scriptPubKeyIn */
std::unique_ptr<CBlockTemplate> CreateNewBlock(const CScript& scriptPubKeyIn); std::unique_ptr<CBlockTemplate> CreateNewBlock(const CScript& scriptPubKeyIn);
@@ -175,7 +176,7 @@ private:
/** Add transactions based on feerate including unconfirmed ancestors /** Add transactions based on feerate including unconfirmed ancestors
* Increments nPackagesSelected / nDescendantsUpdated with corresponding * Increments nPackagesSelected / nDescendantsUpdated with corresponding
* statistics from the package selection (for logging statistics). */ * statistics from the package selection (for logging statistics). */
void addPackageTxs(int &nPackagesSelected, int &nDescendantsUpdated) EXCLUSIVE_LOCKS_REQUIRED(mempool.cs); void addPackageTxs(int& nPackagesSelected, int& nDescendantsUpdated) EXCLUSIVE_LOCKS_REQUIRED(m_mempool.cs);
// helper functions for addPackageTxs() // helper functions for addPackageTxs()
/** Remove confirmed (inBlock) entries from given set */ /** Remove confirmed (inBlock) entries from given set */
@@ -189,13 +190,13 @@ private:
bool TestPackageTransactions(const CTxMemPool::setEntries& package); bool TestPackageTransactions(const CTxMemPool::setEntries& package);
/** Return true if given transaction from mapTx has already been evaluated, /** Return true if given transaction from mapTx has already been evaluated,
* or if the transaction's cached data in mapTx is incorrect. */ * or if the transaction's cached data in mapTx is incorrect. */
bool SkipMapTxEntry(CTxMemPool::txiter it, indexed_modified_transaction_set &mapModifiedTx, CTxMemPool::setEntries &failedTx) EXCLUSIVE_LOCKS_REQUIRED(mempool.cs); bool SkipMapTxEntry(CTxMemPool::txiter it, indexed_modified_transaction_set& mapModifiedTx, CTxMemPool::setEntries& failedTx) EXCLUSIVE_LOCKS_REQUIRED(m_mempool.cs);
/** Sort the package in an order that is valid to appear in a block */ /** Sort the package in an order that is valid to appear in a block */
void SortForBlock(const CTxMemPool::setEntries& package, std::vector<CTxMemPool::txiter>& sortedEntries); void SortForBlock(const CTxMemPool::setEntries& package, std::vector<CTxMemPool::txiter>& sortedEntries);
/** Add descendants of given transactions to mapModifiedTx with ancestor /** Add descendants of given transactions to mapModifiedTx with ancestor
* state updated assuming given transactions are inBlock. Returns number * state updated assuming given transactions are inBlock. Returns number
* of updated descendants. */ * of updated descendants. */
int UpdatePackagesForAdded(const CTxMemPool::setEntries& alreadyAdded, indexed_modified_transaction_set &mapModifiedTx) EXCLUSIVE_LOCKS_REQUIRED(mempool.cs); int UpdatePackagesForAdded(const CTxMemPool::setEntries& alreadyAdded, indexed_modified_transaction_set& mapModifiedTx) EXCLUSIVE_LOCKS_REQUIRED(m_mempool.cs);
}; };
/** Modify the extranonce in a block */ /** Modify the extranonce in a block */

View File

@@ -102,7 +102,7 @@ static UniValue getnetworkhashps(const JSONRPCRequest& request)
return GetNetworkHashPS(!request.params[0].isNull() ? request.params[0].get_int() : 120, !request.params[1].isNull() ? request.params[1].get_int() : -1); return GetNetworkHashPS(!request.params[0].isNull() ? request.params[0].get_int() : 120, !request.params[1].isNull() ? request.params[1].get_int() : -1);
} }
static UniValue generateBlocks(const CScript& coinbase_script, int nGenerate, uint64_t nMaxTries) static UniValue generateBlocks(const CTxMemPool& mempool, const CScript& coinbase_script, int nGenerate, uint64_t nMaxTries)
{ {
int nHeightEnd = 0; int nHeightEnd = 0;
int nHeight = 0; int nHeight = 0;
@@ -116,7 +116,7 @@ static UniValue generateBlocks(const CScript& coinbase_script, int nGenerate, ui
UniValue blockHashes(UniValue::VARR); UniValue blockHashes(UniValue::VARR);
while (nHeight < nHeightEnd && !ShutdownRequested()) while (nHeight < nHeightEnd && !ShutdownRequested())
{ {
std::unique_ptr<CBlockTemplate> pblocktemplate(BlockAssembler(Params()).CreateNewBlock(coinbase_script)); std::unique_ptr<CBlockTemplate> pblocktemplate(BlockAssembler(mempool, Params()).CreateNewBlock(coinbase_script));
if (!pblocktemplate.get()) if (!pblocktemplate.get())
throw JSONRPCError(RPC_INTERNAL_ERROR, "Couldn't create new block"); throw JSONRPCError(RPC_INTERNAL_ERROR, "Couldn't create new block");
CBlock *pblock = &pblocktemplate->block; CBlock *pblock = &pblocktemplate->block;
@@ -179,9 +179,11 @@ static UniValue generatetodescriptor(const JSONRPCRequest& request)
throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, strprintf("Cannot derive script without private keys")); throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, strprintf("Cannot derive script without private keys"));
} }
const CTxMemPool& mempool = EnsureMemPool();
CHECK_NONFATAL(coinbase_script.size() == 1); CHECK_NONFATAL(coinbase_script.size() == 1);
return generateBlocks(coinbase_script.at(0), num_blocks, max_tries); return generateBlocks(mempool, coinbase_script.at(0), num_blocks, max_tries);
} }
static UniValue generatetoaddress(const JSONRPCRequest& request) static UniValue generatetoaddress(const JSONRPCRequest& request)
@@ -215,9 +217,11 @@ static UniValue generatetoaddress(const JSONRPCRequest& request)
throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Error: Invalid address"); throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Error: Invalid address");
} }
const CTxMemPool& mempool = EnsureMemPool();
CScript coinbase_script = GetScriptForDestination(destination); CScript coinbase_script = GetScriptForDestination(destination);
return generateBlocks(coinbase_script, nGenerate, nMaxTries); return generateBlocks(mempool, coinbase_script, nGenerate, nMaxTries);
} }
static UniValue getmininginfo(const JSONRPCRequest& request) static UniValue getmininginfo(const JSONRPCRequest& request)
@@ -548,7 +552,7 @@ static UniValue getblocktemplate(const JSONRPCRequest& request)
// Create new block // Create new block
CScript scriptDummy = CScript() << OP_TRUE; CScript scriptDummy = CScript() << OP_TRUE;
pblocktemplate = BlockAssembler(Params()).CreateNewBlock(scriptDummy); pblocktemplate = BlockAssembler(mempool, Params()).CreateNewBlock(scriptDummy);
if (!pblocktemplate) if (!pblocktemplate)
throw JSONRPCError(RPC_OUT_OF_MEMORY, "Out of memory"); throw JSONRPCError(RPC_OUT_OF_MEMORY, "Out of memory");

View File

@@ -18,6 +18,11 @@
BOOST_AUTO_TEST_SUITE(blockfilter_index_tests) BOOST_AUTO_TEST_SUITE(blockfilter_index_tests)
struct BuildChainTestingSetup : public TestChain100Setup {
CBlock CreateBlock(const CBlockIndex* prev, const std::vector<CMutableTransaction>& txns, const CScript& scriptPubKey);
bool BuildChain(const CBlockIndex* pindex, const CScript& coinbase_script_pub_key, size_t length, std::vector<std::shared_ptr<CBlock>>& chain);
};
static bool CheckFilterLookups(BlockFilterIndex& filter_index, const CBlockIndex* block_index, static bool CheckFilterLookups(BlockFilterIndex& filter_index, const CBlockIndex* block_index,
uint256& last_header) uint256& last_header)
{ {
@@ -52,12 +57,12 @@ static bool CheckFilterLookups(BlockFilterIndex& filter_index, const CBlockIndex
return true; return true;
} }
static CBlock CreateBlock(const CBlockIndex* prev, CBlock BuildChainTestingSetup::CreateBlock(const CBlockIndex* prev,
const std::vector<CMutableTransaction>& txns, const std::vector<CMutableTransaction>& txns,
const CScript& scriptPubKey) const CScript& scriptPubKey)
{ {
const CChainParams& chainparams = Params(); const CChainParams& chainparams = Params();
std::unique_ptr<CBlockTemplate> pblocktemplate = BlockAssembler(chainparams).CreateNewBlock(scriptPubKey); std::unique_ptr<CBlockTemplate> pblocktemplate = BlockAssembler(*m_node.mempool, chainparams).CreateNewBlock(scriptPubKey);
CBlock& block = pblocktemplate->block; CBlock& block = pblocktemplate->block;
block.hashPrevBlock = prev->GetBlockHash(); block.hashPrevBlock = prev->GetBlockHash();
block.nTime = prev->nTime + 1; block.nTime = prev->nTime + 1;
@@ -76,8 +81,10 @@ static CBlock CreateBlock(const CBlockIndex* prev,
return block; return block;
} }
static bool BuildChain(const CBlockIndex* pindex, const CScript& coinbase_script_pub_key, bool BuildChainTestingSetup::BuildChain(const CBlockIndex* pindex,
size_t length, std::vector<std::shared_ptr<CBlock>>& chain) const CScript& coinbase_script_pub_key,
size_t length,
std::vector<std::shared_ptr<CBlock>>& chain)
{ {
std::vector<CMutableTransaction> no_txns; std::vector<CMutableTransaction> no_txns;
@@ -95,7 +102,7 @@ static bool BuildChain(const CBlockIndex* pindex, const CScript& coinbase_script
return true; return true;
} }
BOOST_FIXTURE_TEST_CASE(blockfilter_index_initial_sync, TestChain100Setup) BOOST_FIXTURE_TEST_CASE(blockfilter_index_initial_sync, BuildChainTestingSetup)
{ {
BlockFilterIndex filter_index(BlockFilterType::BASIC, 1 << 20, true); BlockFilterIndex filter_index(BlockFilterType::BASIC, 1 << 20, true);

View File

@@ -30,6 +30,7 @@ struct MinerTestingSetup : public TestingSetup {
{ {
return CheckSequenceLocks(*m_node.mempool, tx, flags); return CheckSequenceLocks(*m_node.mempool, tx, flags);
} }
BlockAssembler AssemblerForTest(const CChainParams& params);
}; };
} // namespace miner_tests } // namespace miner_tests
@@ -48,12 +49,13 @@ private:
static CFeeRate blockMinFeeRate = CFeeRate(DEFAULT_BLOCK_MIN_TX_FEE); static CFeeRate blockMinFeeRate = CFeeRate(DEFAULT_BLOCK_MIN_TX_FEE);
static BlockAssembler AssemblerForTest(const CChainParams& params) { BlockAssembler MinerTestingSetup::AssemblerForTest(const CChainParams& params)
{
BlockAssembler::Options options; BlockAssembler::Options options;
options.nBlockMaxWeight = MAX_BLOCK_WEIGHT; options.nBlockMaxWeight = MAX_BLOCK_WEIGHT;
options.blockMinFeeRate = blockMinFeeRate; options.blockMinFeeRate = blockMinFeeRate;
return BlockAssembler(params, options); return BlockAssembler(*m_node.mempool, params, options);
} }
constexpr static struct { constexpr static struct {

View File

@@ -8,22 +8,23 @@
#include <consensus/merkle.h> #include <consensus/merkle.h>
#include <key_io.h> #include <key_io.h>
#include <miner.h> #include <miner.h>
#include <node/context.h>
#include <pow.h> #include <pow.h>
#include <script/standard.h> #include <script/standard.h>
#include <validation.h> #include <validation.h>
CTxIn generatetoaddress(const std::string& address) CTxIn generatetoaddress(const NodeContext& node, const std::string& address)
{ {
const auto dest = DecodeDestination(address); const auto dest = DecodeDestination(address);
assert(IsValidDestination(dest)); assert(IsValidDestination(dest));
const auto coinbase_script = GetScriptForDestination(dest); const auto coinbase_script = GetScriptForDestination(dest);
return MineBlock(coinbase_script); return MineBlock(node, coinbase_script);
} }
CTxIn MineBlock(const CScript& coinbase_scriptPubKey) CTxIn MineBlock(const NodeContext& node, const CScript& coinbase_scriptPubKey)
{ {
auto block = PrepareBlock(coinbase_scriptPubKey); auto block = PrepareBlock(node, coinbase_scriptPubKey);
while (!CheckProofOfWork(block->GetHash(), block->nBits, Params().GetConsensus())) { while (!CheckProofOfWork(block->GetHash(), block->nBits, Params().GetConsensus())) {
++block->nNonce; ++block->nNonce;
@@ -36,10 +37,11 @@ CTxIn MineBlock(const CScript& coinbase_scriptPubKey)
return CTxIn{block->vtx[0]->GetHash(), 0}; return CTxIn{block->vtx[0]->GetHash(), 0};
} }
std::shared_ptr<CBlock> PrepareBlock(const CScript& coinbase_scriptPubKey) std::shared_ptr<CBlock> PrepareBlock(const NodeContext& node, const CScript& coinbase_scriptPubKey)
{ {
assert(node.mempool);
auto block = std::make_shared<CBlock>( auto block = std::make_shared<CBlock>(
BlockAssembler{Params()} BlockAssembler{*node.mempool, Params()}
.CreateNewBlock(coinbase_scriptPubKey) .CreateNewBlock(coinbase_scriptPubKey)
->block); ->block);

View File

@@ -11,14 +11,15 @@
class CBlock; class CBlock;
class CScript; class CScript;
class CTxIn; class CTxIn;
struct NodeContext;
/** Returns the generated coin */ /** Returns the generated coin */
CTxIn MineBlock(const CScript& coinbase_scriptPubKey); CTxIn MineBlock(const NodeContext&, const CScript& coinbase_scriptPubKey);
/** Prepare a block to be mined */ /** Prepare a block to be mined */
std::shared_ptr<CBlock> PrepareBlock(const CScript& coinbase_scriptPubKey); std::shared_ptr<CBlock> PrepareBlock(const NodeContext&, const CScript& coinbase_scriptPubKey);
/** RPC-like helper function, returns the generated coin */ /** RPC-like helper function, returns the generated coin */
CTxIn generatetoaddress(const std::string& address); CTxIn generatetoaddress(const NodeContext&, const std::string& address);
#endif // BITCOIN_TEST_UTIL_MINING_H #endif // BITCOIN_TEST_UTIL_MINING_H

View File

@@ -175,7 +175,7 @@ TestChain100Setup::TestChain100Setup()
CBlock TestChain100Setup::CreateAndProcessBlock(const std::vector<CMutableTransaction>& txns, const CScript& scriptPubKey) CBlock TestChain100Setup::CreateAndProcessBlock(const std::vector<CMutableTransaction>& txns, const CScript& scriptPubKey)
{ {
const CChainParams& chainparams = Params(); const CChainParams& chainparams = Params();
std::unique_ptr<CBlockTemplate> pblocktemplate = BlockAssembler(chainparams).CreateNewBlock(scriptPubKey); std::unique_ptr<CBlockTemplate> pblocktemplate = BlockAssembler(*m_node.mempool, chainparams).CreateNewBlock(scriptPubKey);
CBlock& block = pblocktemplate->block; CBlock& block = pblocktemplate->block;
// Replace mempool-selected txns with just coinbase plus passed-in txns: // Replace mempool-selected txns with just coinbase plus passed-in txns:

View File

@@ -20,7 +20,17 @@
static const std::vector<unsigned char> V_OP_TRUE{OP_TRUE}; static const std::vector<unsigned char> V_OP_TRUE{OP_TRUE};
BOOST_FIXTURE_TEST_SUITE(validation_block_tests, RegTestingSetup) namespace validation_block_tests {
struct MinerTestingSetup : public RegTestingSetup {
std::shared_ptr<CBlock> Block(const uint256& prev_hash);
std::shared_ptr<const CBlock> GoodBlock(const uint256& prev_hash);
std::shared_ptr<const CBlock> BadBlock(const uint256& prev_hash);
std::shared_ptr<CBlock> FinalizeBlock(std::shared_ptr<CBlock> pblock);
void BuildChain(const uint256& root, int height, const unsigned int invalid_rate, const unsigned int branch_rate, const unsigned int max_size, std::vector<std::shared_ptr<const CBlock>>& blocks);
};
} // namespace validation_block_tests
BOOST_FIXTURE_TEST_SUITE(validation_block_tests, MinerTestingSetup)
struct TestSubscriber : public CValidationInterface { struct TestSubscriber : public CValidationInterface {
uint256 m_expected_tip; uint256 m_expected_tip;
@@ -49,7 +59,7 @@ struct TestSubscriber : public CValidationInterface {
} }
}; };
std::shared_ptr<CBlock> Block(const uint256& prev_hash) std::shared_ptr<CBlock> MinerTestingSetup::Block(const uint256& prev_hash)
{ {
static int i = 0; static int i = 0;
static uint64_t time = Params().GenesisBlock().nTime; static uint64_t time = Params().GenesisBlock().nTime;
@@ -57,7 +67,7 @@ std::shared_ptr<CBlock> Block(const uint256& prev_hash)
CScript pubKey; CScript pubKey;
pubKey << i++ << OP_TRUE; pubKey << i++ << OP_TRUE;
auto ptemplate = BlockAssembler(Params()).CreateNewBlock(pubKey); auto ptemplate = BlockAssembler(*m_node.mempool, Params()).CreateNewBlock(pubKey);
auto pblock = std::make_shared<CBlock>(ptemplate->block); auto pblock = std::make_shared<CBlock>(ptemplate->block);
pblock->hashPrevBlock = prev_hash; pblock->hashPrevBlock = prev_hash;
pblock->nTime = ++time; pblock->nTime = ++time;
@@ -83,7 +93,7 @@ std::shared_ptr<CBlock> Block(const uint256& prev_hash)
return pblock; return pblock;
} }
std::shared_ptr<CBlock> FinalizeBlock(std::shared_ptr<CBlock> pblock) std::shared_ptr<CBlock> MinerTestingSetup::FinalizeBlock(std::shared_ptr<CBlock> pblock)
{ {
LOCK(cs_main); // For LookupBlockIndex LOCK(cs_main); // For LookupBlockIndex
GenerateCoinbaseCommitment(*pblock, LookupBlockIndex(pblock->hashPrevBlock), Params().GetConsensus()); GenerateCoinbaseCommitment(*pblock, LookupBlockIndex(pblock->hashPrevBlock), Params().GetConsensus());
@@ -98,13 +108,13 @@ std::shared_ptr<CBlock> FinalizeBlock(std::shared_ptr<CBlock> pblock)
} }
// construct a valid block // construct a valid block
std::shared_ptr<const CBlock> GoodBlock(const uint256& prev_hash) std::shared_ptr<const CBlock> MinerTestingSetup::GoodBlock(const uint256& prev_hash)
{ {
return FinalizeBlock(Block(prev_hash)); return FinalizeBlock(Block(prev_hash));
} }
// construct an invalid block (but with a valid header) // construct an invalid block (but with a valid header)
std::shared_ptr<const CBlock> BadBlock(const uint256& prev_hash) std::shared_ptr<const CBlock> MinerTestingSetup::BadBlock(const uint256& prev_hash)
{ {
auto pblock = Block(prev_hash); auto pblock = Block(prev_hash);
@@ -119,7 +129,7 @@ std::shared_ptr<const CBlock> BadBlock(const uint256& prev_hash)
return ret; return ret;
} }
void BuildChain(const uint256& root, int height, const unsigned int invalid_rate, const unsigned int branch_rate, const unsigned int max_size, std::vector<std::shared_ptr<const CBlock>>& blocks) void MinerTestingSetup::BuildChain(const uint256& root, int height, const unsigned int invalid_rate, const unsigned int branch_rate, const unsigned int max_size, std::vector<std::shared_ptr<const CBlock>>& blocks)
{ {
if (height <= 0 || blocks.size() >= max_size) return; if (height <= 0 || blocks.size() >= max_size) return;