diff --git a/src/miner.h b/src/miner.h --- a/src/miner.h +++ b/src/miner.h @@ -154,6 +154,7 @@ const CChainParams &chainParams; const CTxMemPool &m_mempool; + CChainState &m_chainstate; public: struct Options { @@ -163,9 +164,10 @@ CFeeRate blockMinFeeRate; }; - BlockAssembler(const Config &config, const CTxMemPool &mempool); - BlockAssembler(const CChainParams ¶ms, const CTxMemPool &mempool, - const Options &options); + BlockAssembler(const Config &config, CChainState &chainstate, + const CTxMemPool &mempool); + BlockAssembler(CChainState &chainstate, const CChainParams ¶ms, + const CTxMemPool &mempool, const Options &options); /** Construct a new block template with coinbase to scriptPubKeyIn */ std::unique_ptr diff --git a/src/miner.cpp b/src/miner.cpp --- a/src/miner.cpp +++ b/src/miner.cpp @@ -57,10 +57,11 @@ nMaxGeneratedBlockSize(DEFAULT_MAX_GENERATED_BLOCK_SIZE), blockMinFeeRate(DEFAULT_BLOCK_MIN_TX_FEE_PER_KB) {} -BlockAssembler::BlockAssembler(const CChainParams ¶ms, +BlockAssembler::BlockAssembler(CChainState &chainstate, + const CChainParams ¶ms, const CTxMemPool &mempool, const Options &options) - : chainParams(params), m_mempool(mempool) { + : chainParams(params), m_mempool(mempool), m_chainstate(chainstate) { blockMinFeeRate = options.blockMinFeeRate; // Limit size to between 1K and options.nExcessiveBlockSize -1K for sanity: nMaxGeneratedBlockSize = std::max( @@ -98,9 +99,10 @@ return options; } -BlockAssembler::BlockAssembler(const Config &config, const CTxMemPool &mempool) - : BlockAssembler(config.GetChainParams(), mempool, DefaultOptions(config)) { -} +BlockAssembler::BlockAssembler(const Config &config, CChainState &chainstate, + const CTxMemPool &mempool) + : BlockAssembler(chainstate, config.GetChainParams(), mempool, + DefaultOptions(config)) {} void BlockAssembler::resetBlock() { inBlock.clear(); @@ -135,7 +137,9 @@ pblocktemplate->entries.emplace_back(CTransactionRef(), -SATOSHI, -1); LOCK2(cs_main, m_mempool.cs); - CBlockIndex *pindexPrev = ::ChainActive().Tip(); + assert(std::addressof(*::ChainActive().Tip()) == + std::addressof(*m_chainstate.m_chain.Tip())); + CBlockIndex *pindexPrev = m_chainstate.m_chain.Tip(); assert(pindexPrev != nullptr); nHeight = pindexPrev->nHeight + 1; @@ -222,7 +226,9 @@ pblocktemplate->entries[0].sigOpCount = 0; BlockValidationState state; - if (!TestBlockValidity(state, chainParams, ::ChainstateActive(), *pblock, + assert(std::addressof(::ChainstateActive()) == + std::addressof(m_chainstate)); + if (!TestBlockValidity(state, chainParams, m_chainstate, *pblock, pindexPrev, BlockValidationOptions(nMaxGeneratedBlockSize) .withCheckPoW(false) diff --git a/src/rpc/mining.cpp b/src/rpc/mining.cpp --- a/src/rpc/mining.cpp +++ b/src/rpc/mining.cpp @@ -177,7 +177,8 @@ UniValue blockHashes(UniValue::VARR); while (nHeight < nHeightEnd && !ShutdownRequested()) { std::unique_ptr pblocktemplate( - BlockAssembler(config, mempool).CreateNewBlock(coinbase_script)); + BlockAssembler(config, chainman.ActiveChainstate(), mempool) + .CreateNewBlock(coinbase_script)); if (!pblocktemplate.get()) { throw JSONRPCError(RPC_INTERNAL_ERROR, "Couldn't create new block"); @@ -423,7 +424,6 @@ } else if (DecodeHexTx(mtx, str)) { txs.push_back(MakeTransactionRef(std::move(mtx))); - } else { throw JSONRPCError( RPC_DESERIALIZATION_ERROR, @@ -438,7 +438,7 @@ CTxMemPool empty_mempool; std::unique_ptr blocktemplate( - BlockAssembler(config, empty_mempool) + BlockAssembler(config, ::ChainstateActive(), empty_mempool) .CreateNewBlock(coinbase_script)); if (!blocktemplate) { throw JSONRPCError(RPC_INTERNAL_ERROR, @@ -937,7 +937,8 @@ // Create new block CScript scriptDummy = CScript() << OP_TRUE; pblocktemplate = - BlockAssembler(config, mempool).CreateNewBlock(scriptDummy); + BlockAssembler(config, ::ChainstateActive(), mempool) + .CreateNewBlock(scriptDummy); if (!pblocktemplate) { throw JSONRPCError(RPC_OUT_OF_MEMORY, "Out of memory"); } diff --git a/src/test/blockfilter_index_tests.cpp b/src/test/blockfilter_index_tests.cpp --- a/src/test/blockfilter_index_tests.cpp +++ b/src/test/blockfilter_index_tests.cpp @@ -69,7 +69,8 @@ const CScript &scriptPubKey) { const Config &config = GetConfig(); std::unique_ptr pblocktemplate = - BlockAssembler(config, *m_node.mempool).CreateNewBlock(scriptPubKey); + BlockAssembler(config, ::ChainstateActive(), *m_node.mempool) + .CreateNewBlock(scriptPubKey); CBlock &block = pblocktemplate->block; block.hashPrevBlock = prev->GetBlockHash(); block.nTime = prev->nTime + 1; diff --git a/src/test/miner_tests.cpp b/src/test/miner_tests.cpp --- a/src/test/miner_tests.cpp +++ b/src/test/miner_tests.cpp @@ -51,7 +51,8 @@ BlockAssembler MinerTestingSetup::AssemblerForTest(const CChainParams ¶ms) { BlockAssembler::Options options; options.blockMinFeeRate = blockMinFeeRate; - return BlockAssembler(params, *m_node.mempool, options); + return BlockAssembler(::ChainstateActive(), params, *m_node.mempool, + options); } constexpr static struct { @@ -233,7 +234,8 @@ << OP_CHECKSIG; std::unique_ptr pblocktemplate = - BlockAssembler(config, mempool).CreateNewBlock(scriptPubKey); + BlockAssembler(config, ::ChainstateActive(), mempool) + .CreateNewBlock(scriptPubKey); CBlock *pblock = &pblocktemplate->block; @@ -679,7 +681,7 @@ uint64_t size, uint64_t expected) { gArgs.ForceSetArg("-blockmaxsize", ToString(size)); - BlockAssembler ba(config, mempool); + BlockAssembler ba(config, ::ChainstateActive(), mempool); BOOST_CHECK_EQUAL(ba.GetMaxGeneratedBlockSize(), expected); } @@ -722,7 +724,7 @@ // DEFAULT_MAX_GENERATED_BLOCK_SIZE { gArgs.ClearForcedArg("-blockmaxsize"); - BlockAssembler ba(config, *m_node.mempool); + BlockAssembler ba(config, ::ChainstateActive(), *m_node.mempool); BOOST_CHECK_EQUAL(ba.GetMaxGeneratedBlockSize(), DEFAULT_MAX_GENERATED_BLOCK_SIZE); } diff --git a/src/test/util/mining.cpp b/src/test/util/mining.cpp --- a/src/test/util/mining.cpp +++ b/src/test/util/mining.cpp @@ -44,10 +44,10 @@ std::shared_ptr PrepareBlock(const Config &config, const NodeContext &node, const CScript &coinbase_scriptPubKey) { - auto block = - std::make_shared(BlockAssembler{config, *Assert(node.mempool)} - .CreateNewBlock(coinbase_scriptPubKey) - ->block); + auto block = std::make_shared( + BlockAssembler{config, ::ChainstateActive(), *Assert(node.mempool)} + .CreateNewBlock(coinbase_scriptPubKey) + ->block); LOCK(cs_main); block->nTime = ::ChainActive().Tip()->GetMedianTimePast() + 1; diff --git a/src/test/util/setup_common.cpp b/src/test/util/setup_common.cpp --- a/src/test/util/setup_common.cpp +++ b/src/test/util/setup_common.cpp @@ -284,8 +284,9 @@ const std::vector &txns, const CScript &scriptPubKey) { const Config &config = GetConfig(); CTxMemPool empty_pool; - CBlock block = - BlockAssembler(config, empty_pool).CreateNewBlock(scriptPubKey)->block; + CBlock block = BlockAssembler(config, ::ChainstateActive(), empty_pool) + .CreateNewBlock(scriptPubKey) + ->block; Assert(block.vtx.size() == 1); for (const CMutableTransaction &tx : txns) { diff --git a/src/test/validation_block_tests.cpp b/src/test/validation_block_tests.cpp --- a/src/test/validation_block_tests.cpp +++ b/src/test/validation_block_tests.cpp @@ -75,8 +75,9 @@ CScript pubKey; pubKey << i++ << OP_TRUE; - auto ptemplate = - BlockAssembler(config, *m_node.mempool).CreateNewBlock(pubKey); + auto ptemplate = BlockAssembler(config, m_node.chainman->ActiveChainstate(), + *m_node.mempool) + .CreateNewBlock(pubKey); auto pblock = std::make_shared(ptemplate->block); pblock->hashPrevBlock = prev_hash; pblock->nTime = ++time;