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,13 +164,14 @@ 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 - CreateNewBlock(CChainState &chainstate, const CScript &scriptPubKeyIn); + CreateNewBlock(const CScript &scriptPubKeyIn); uint64_t GetMaxGeneratedBlockSize() const { return nMaxGeneratedBlockSize; } 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(); @@ -118,8 +120,7 @@ std::optional BlockAssembler::m_last_block_size{std::nullopt}; std::unique_ptr -BlockAssembler::CreateNewBlock(CChainState &chainstate, - const CScript &scriptPubKeyIn) { +BlockAssembler::CreateNewBlock(const CScript &scriptPubKeyIn) { int64_t nTimeStart = GetTimeMicros(); resetBlock(); @@ -137,8 +138,8 @@ LOCK2(cs_main, m_mempool.cs); assert(std::addressof(*::ChainActive().Tip()) == - std::addressof(*chainstate.m_chain.Tip())); - CBlockIndex *pindexPrev = chainstate.m_chain.Tip(); + std::addressof(*m_chainstate.m_chain.Tip())); + CBlockIndex *pindexPrev = m_chainstate.m_chain.Tip(); assert(pindexPrev != nullptr); nHeight = pindexPrev->nHeight + 1; @@ -225,8 +226,10 @@ pblocktemplate->entries[0].sigOpCount = 0; BlockValidationState state; - assert(std::addressof(::ChainstateActive()) == std::addressof(chainstate)); - if (!TestBlockValidity(state, chainParams, chainstate, *pblock, pindexPrev, + assert(std::addressof(::ChainstateActive()) == + std::addressof(m_chainstate)); + if (!TestBlockValidity(state, chainParams, m_chainstate, *pblock, + pindexPrev, BlockValidationOptions(nMaxGeneratedBlockSize) .withCheckPoW(false) .withCheckMerkleRoot(false))) { diff --git a/src/rpc/mining.cpp b/src/rpc/mining.cpp --- a/src/rpc/mining.cpp +++ b/src/rpc/mining.cpp @@ -177,8 +177,8 @@ UniValue blockHashes(UniValue::VARR); while (nHeight < nHeightEnd && !ShutdownRequested()) { std::unique_ptr pblocktemplate( - BlockAssembler(config, mempool) - .CreateNewBlock(::ChainstateActive(), coinbase_script)); + BlockAssembler(config, chainman.ActiveChainstate(), mempool) + .CreateNewBlock(coinbase_script)); if (!pblocktemplate.get()) { throw JSONRPCError(RPC_INTERNAL_ERROR, "Couldn't create new block"); @@ -424,7 +424,6 @@ } else if (DecodeHexTx(mtx, str)) { txs.push_back(MakeTransactionRef(std::move(mtx))); - } else { throw JSONRPCError( RPC_DESERIALIZATION_ERROR, @@ -439,8 +438,8 @@ CTxMemPool empty_mempool; std::unique_ptr blocktemplate( - BlockAssembler(config, empty_mempool) - .CreateNewBlock(::ChainstateActive(), coinbase_script)); + BlockAssembler(config, ::ChainstateActive(), empty_mempool) + .CreateNewBlock(coinbase_script)); if (!blocktemplate) { throw JSONRPCError(RPC_INTERNAL_ERROR, "Couldn't create new block"); @@ -938,8 +937,8 @@ // Create new block CScript scriptDummy = CScript() << OP_TRUE; pblocktemplate = - BlockAssembler(config, mempool) - .CreateNewBlock(::ChainstateActive(), 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,8 +69,8 @@ const CScript &scriptPubKey) { const Config &config = GetConfig(); std::unique_ptr pblocktemplate = - BlockAssembler(config, *m_node.mempool) - .CreateNewBlock(::ChainstateActive(), 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 { @@ -141,8 +142,7 @@ .FromTx(tx)); std::unique_ptr pblocktemplate = - AssemblerForTest(chainparams) - .CreateNewBlock(::ChainstateActive(), scriptPubKey); + AssemblerForTest(chainparams).CreateNewBlock(scriptPubKey); BOOST_CHECK(pblocktemplate->block.vtx[1]->GetId() == parentTxId); BOOST_CHECK(pblocktemplate->block.vtx[2]->GetId() == highFeeTxId); BOOST_CHECK(pblocktemplate->block.vtx[3]->GetId() == mediumFeeTxId); @@ -164,8 +164,7 @@ int64_t(5000000000LL - 1000 - 50000) * SATOSHI - feeToUse; TxId lowFeeTxId = tx.GetId(); m_node.mempool->addUnchecked(entry.Fee(feeToUse).FromTx(tx)); - pblocktemplate = AssemblerForTest(chainparams) - .CreateNewBlock(::ChainstateActive(), scriptPubKey); + pblocktemplate = AssemblerForTest(chainparams).CreateNewBlock(scriptPubKey); // Verify that the free tx and the low fee tx didn't get selected. for (const auto &txn : pblocktemplate->block.vtx) { BOOST_CHECK(txn->GetId() != freeTxId); @@ -181,8 +180,7 @@ tx.vout[0].nValue -= 2 * SATOSHI; lowFeeTxId = tx.GetId(); m_node.mempool->addUnchecked(entry.Fee(feeToUse + 2 * SATOSHI).FromTx(tx)); - pblocktemplate = AssemblerForTest(chainparams) - .CreateNewBlock(::ChainstateActive(), scriptPubKey); + pblocktemplate = AssemblerForTest(chainparams).CreateNewBlock(scriptPubKey); BOOST_CHECK(pblocktemplate->block.vtx[4]->GetId() == freeTxId); BOOST_CHECK(pblocktemplate->block.vtx[5]->GetId() == lowFeeTxId); @@ -206,8 +204,7 @@ TxId lowFeeTxId2 = tx.GetId(); m_node.mempool->addUnchecked( entry.Fee(feeToUse).SpendsCoinbase(false).FromTx(tx)); - pblocktemplate = AssemblerForTest(chainparams) - .CreateNewBlock(::ChainstateActive(), scriptPubKey); + pblocktemplate = AssemblerForTest(chainparams).CreateNewBlock(scriptPubKey); // Verify that this tx isn't selected. for (const auto &txn : pblocktemplate->block.vtx) { @@ -221,8 +218,7 @@ // 10k satoshi fee. tx.vout[0].nValue = (100000000 - 10000) * SATOSHI; m_node.mempool->addUnchecked(entry.Fee(10000 * SATOSHI).FromTx(tx)); - pblocktemplate = AssemblerForTest(chainparams) - .CreateNewBlock(::ChainstateActive(), scriptPubKey); + pblocktemplate = AssemblerForTest(chainparams).CreateNewBlock(scriptPubKey); BOOST_CHECK(pblocktemplate->block.vtx[8]->GetId() == lowFeeTxId2); } @@ -238,8 +234,8 @@ << OP_CHECKSIG; std::unique_ptr pblocktemplate = - BlockAssembler(config, mempool) - .CreateNewBlock(::ChainstateActive(), scriptPubKey); + BlockAssembler(config, ::ChainstateActive(), mempool) + .CreateNewBlock(scriptPubKey); CBlock *pblock = &pblocktemplate->block; @@ -283,8 +279,7 @@ // Simple block creation, nothing special yet: BOOST_CHECK(pblocktemplate = - AssemblerForTest(chainparams) - .CreateNewBlock(::ChainstateActive(), scriptPubKey)); + AssemblerForTest(chainparams).CreateNewBlock(scriptPubKey)); // We can't make transactions until we have inputs. // Therefore, load 110 blocks :) @@ -329,8 +324,7 @@ // Just to make sure we can still make simple blocks. BOOST_CHECK(pblocktemplate = - AssemblerForTest(chainparams) - .CreateNewBlock(::ChainstateActive(), scriptPubKey)); + AssemblerForTest(chainparams).CreateNewBlock(scriptPubKey)); const Amount BLOCKSUBSIDY = 50 * COIN; const Amount LOWFEE = CENT; @@ -363,15 +357,13 @@ } BOOST_CHECK(pblocktemplate = - AssemblerForTest(chainparams) - .CreateNewBlock(::ChainstateActive(), scriptPubKey)); + AssemblerForTest(chainparams).CreateNewBlock(scriptPubKey)); m_node.mempool->clear(); // Orphan in mempool, template creation fails. m_node.mempool->addUnchecked(entry.Fee(LOWFEE).Time(GetTime()).FromTx(tx)); BOOST_CHECK_EXCEPTION( - AssemblerForTest(chainparams) - .CreateNewBlock(::ChainstateActive(), scriptPubKey), + AssemblerForTest(chainparams).CreateNewBlock(scriptPubKey), std::runtime_error, HasReason("bad-txns-inputs-missingorspent")); m_node.mempool->clear(); @@ -392,8 +384,7 @@ m_node.mempool->addUnchecked( entry.Fee(HIGHERFEE).Time(GetTime()).SpendsCoinbase(true).FromTx(tx)); BOOST_CHECK(pblocktemplate = - AssemblerForTest(chainparams) - .CreateNewBlock(::ChainstateActive(), scriptPubKey)); + AssemblerForTest(chainparams).CreateNewBlock(scriptPubKey)); m_node.mempool->clear(); // Coinbase in mempool, template creation fails. @@ -407,8 +398,7 @@ entry.Fee(LOWFEE).Time(GetTime()).SpendsCoinbase(false).FromTx(tx)); // Should throw bad-tx-coinbase BOOST_CHECK_EXCEPTION( - AssemblerForTest(chainparams) - .CreateNewBlock(::ChainstateActive(), scriptPubKey), + AssemblerForTest(chainparams).CreateNewBlock(scriptPubKey), std::runtime_error, HasReason("bad-tx-coinbase")); m_node.mempool->clear(); @@ -425,8 +415,7 @@ m_node.mempool->addUnchecked( entry.Fee(HIGHFEE).Time(GetTime()).SpendsCoinbase(true).FromTx(tx)); BOOST_CHECK_EXCEPTION( - AssemblerForTest(chainparams) - .CreateNewBlock(::ChainstateActive(), scriptPubKey), + AssemblerForTest(chainparams).CreateNewBlock(scriptPubKey), std::runtime_error, HasReason("bad-txns-inputs-missingorspent")); m_node.mempool->clear(); @@ -444,8 +433,7 @@ ::ChainActive().SetTip(next); } BOOST_CHECK(pblocktemplate = - AssemblerForTest(chainparams) - .CreateNewBlock(::ChainstateActive(), scriptPubKey)); + AssemblerForTest(chainparams).CreateNewBlock(scriptPubKey)); // Extend to a 210000-long block chain. while (::ChainActive().Tip()->nHeight < 210000) { CBlockIndex *prev = ::ChainActive().Tip(); @@ -459,8 +447,7 @@ } BOOST_CHECK(pblocktemplate = - AssemblerForTest(chainparams) - .CreateNewBlock(::ChainstateActive(), scriptPubKey)); + AssemblerForTest(chainparams).CreateNewBlock(scriptPubKey)); // Invalid p2sh txn in mempool, template creation fails tx.vin[0].prevout = COutPoint(txFirst[0]->GetId(), 0); @@ -480,8 +467,7 @@ entry.Fee(LOWFEE).Time(GetTime()).SpendsCoinbase(false).FromTx(tx)); // Should throw blk-bad-inputs BOOST_CHECK_EXCEPTION( - AssemblerForTest(chainparams) - .CreateNewBlock(::ChainstateActive(), scriptPubKey), + AssemblerForTest(chainparams).CreateNewBlock(scriptPubKey), std::runtime_error, HasReason("blk-bad-inputs")); m_node.mempool->clear(); @@ -658,8 +644,7 @@ // Sequence locks fail. BOOST_CHECK(!TestSequenceLocks(CTransaction(tx), flags)); - pblocktemplate = AssemblerForTest(chainparams) - .CreateNewBlock(::ChainstateActive(), scriptPubKey); + pblocktemplate = AssemblerForTest(chainparams).CreateNewBlock(scriptPubKey); BOOST_CHECK(pblocktemplate); // None of the of the absolute height/time locked tx should have made it @@ -680,8 +665,7 @@ SetMockTime(::ChainActive().Tip()->GetMedianTimePast() + 1); BOOST_CHECK(pblocktemplate = - AssemblerForTest(chainparams) - .CreateNewBlock(::ChainstateActive(), scriptPubKey)); + AssemblerForTest(chainparams).CreateNewBlock(scriptPubKey)); BOOST_CHECK_EQUAL(pblocktemplate->block.vtx.size(), 5UL); ::ChainActive().Tip()->nHeight--; @@ -697,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); } @@ -740,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 @@ -45,8 +45,8 @@ const NodeContext &node, const CScript &coinbase_scriptPubKey) { auto block = std::make_shared( - BlockAssembler{config, *Assert(node.mempool)} - .CreateNewBlock(::ChainstateActive(), coinbase_scriptPubKey) + BlockAssembler{config, ::ChainstateActive(), *Assert(node.mempool)} + .CreateNewBlock(coinbase_scriptPubKey) ->block); LOCK(cs_main); 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,8 @@ const std::vector &txns, const CScript &scriptPubKey) { const Config &config = GetConfig(); CTxMemPool empty_pool; - CBlock block = BlockAssembler(config, empty_pool) - .CreateNewBlock(::ChainstateActive(), scriptPubKey) + CBlock block = BlockAssembler(config, ::ChainstateActive(), empty_pool) + .CreateNewBlock(scriptPubKey) ->block; Assert(block.vtx.size() == 1); 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(::ChainstateActive(), 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;