Line data Source code
1 : // Copyright (c) 2009-2010 Satoshi Nakamoto
2 : // Copyright (c) 2009-2021 The Bitcoin Core developers
3 : // Copyright (c) 2014-2025 The Dash Core developers
4 : // Distributed under the MIT software license, see the accompanying
5 : // file COPYING or http://www.opensource.org/licenses/mit-license.php.
6 :
7 : #include <node/miner.h>
8 :
9 : #include <chain.h>
10 : #include <chainparams.h>
11 : #include <consensus/amount.h>
12 : #include <consensus/consensus.h>
13 : #include <consensus/merkle.h>
14 : #include <consensus/tx_verify.h>
15 : #include <consensus/validation.h>
16 : #include <deploymentstatus.h>
17 : #include <node/context.h>
18 : #include <policy/feerate.h>
19 : #include <policy/policy.h>
20 : #include <pow.h>
21 : #include <primitives/transaction.h>
22 : #include <timedata.h>
23 : #include <util/moneystr.h>
24 : #include <util/system.h>
25 : #include <validation.h>
26 :
27 : #include <chainlock/chainlock.h>
28 : #include <chainlock/handler.h>
29 : #include <evo/specialtx.h>
30 : #include <evo/cbtx.h>
31 : #include <evo/chainhelper.h>
32 : #include <evo/creditpool.h>
33 : #include <evo/mnhftx.h>
34 : #include <evo/deterministicmns.h>
35 : #include <evo/simplifiedmns.h>
36 : #include <evo/specialtxman.h>
37 : #include <governance/governance.h>
38 : #include <instantsend/instantsend.h>
39 : #include <llmq/blockprocessor.h>
40 : #include <llmq/context.h>
41 : #include <llmq/options.h>
42 : #include <llmq/snapshot.h>
43 : #include <masternode/payments.h>
44 :
45 : #include <algorithm>
46 : #include <utility>
47 :
48 : namespace node {
49 88152 : int64_t UpdateTime(CBlockHeader* pblock, const Consensus::Params& consensusParams, const CBlockIndex* pindexPrev)
50 : {
51 88152 : int64_t nOldTime = pblock->nTime;
52 88152 : int64_t nNewTime = std::max(pindexPrev->GetMedianTimePast() + 1, GetAdjustedTime());
53 :
54 88152 : if (nOldTime < nNewTime) {
55 65125 : pblock->nTime = nNewTime;
56 65125 : }
57 :
58 : // Updating time can change work required on testnet:
59 88152 : if (consensusParams.fPowAllowMinDifficultyBlocks) {
60 88134 : pblock->nBits = GetNextWorkRequired(pindexPrev, pblock, consensusParams);
61 88134 : }
62 :
63 88152 : return nNewTime - nOldTime;
64 : }
65 :
66 175202 : BlockAssembler::Options::Options()
67 87601 : {
68 87601 : blockMinFeeRate = CFeeRate(DEFAULT_BLOCK_MIN_TX_FEE);
69 87601 : nBlockMaxSize = DEFAULT_BLOCK_MAX_SIZE;
70 175202 : }
71 :
72 175202 : BlockAssembler::BlockAssembler(CChainState& chainstate, const NodeContext& node, const CTxMemPool* mempool, const CChainParams& params, const Options& options) :
73 87601 : m_blockman(chainstate.m_blockman),
74 87601 : m_chain_helper(chainstate.ChainHelper()),
75 87601 : m_chainstate(chainstate),
76 87601 : m_evoDb(*Assert(node.evodb)),
77 87601 : m_chainlocks(*Assert(node.chainlocks)),
78 87601 : m_clhandler(*Assert(node.clhandler)),
79 87601 : m_isman(*Assert(Assert(node.llmq_ctx)->isman)),
80 87601 : chainparams(params),
81 87601 : m_mempool(mempool),
82 87601 : m_quorum_block_processor(*Assert(Assert(node.llmq_ctx)->quorum_block_processor)),
83 87601 : m_qman(*Assert(Assert(node.llmq_ctx)->qman))
84 87601 : {
85 87601 : blockMinFeeRate = options.blockMinFeeRate;
86 87601 : nBlockMaxSize = options.nBlockMaxSize;
87 175202 : }
88 :
89 87583 : static BlockAssembler::Options DefaultOptions()
90 : {
91 : // Block resource limits
92 87583 : BlockAssembler::Options options;
93 87583 : options.nBlockMaxSize = DEFAULT_BLOCK_MAX_SIZE;
94 87583 : if (gArgs.IsArgSet("-blockmaxsize")) {
95 86 : options.nBlockMaxSize = gArgs.GetIntArg("-blockmaxsize", DEFAULT_BLOCK_MAX_SIZE);
96 86 : }
97 87583 : if (gArgs.IsArgSet("-blockmintxfee")) {
98 0 : std::optional<CAmount> parsed = ParseMoney(gArgs.GetArg("-blockmintxfee", ""));
99 0 : options.blockMinFeeRate = CFeeRate{parsed.value_or(DEFAULT_BLOCK_MIN_TX_FEE)};
100 0 : } else {
101 87583 : options.blockMinFeeRate = CFeeRate{DEFAULT_BLOCK_MIN_TX_FEE};
102 : }
103 87583 : return options;
104 0 : }
105 :
106 87583 : BlockAssembler::BlockAssembler(CChainState& chainstate, const NodeContext& node, const CTxMemPool* mempool, const CChainParams& params)
107 87583 : : BlockAssembler(chainstate, node, mempool, params, DefaultOptions()) {}
108 :
109 87601 : void BlockAssembler::resetBlock()
110 : {
111 87601 : inBlock.clear();
112 :
113 : // Reserve space for coinbase tx
114 87601 : nBlockSize = 1000;
115 87601 : nBlockSigOps = 100;
116 :
117 : // These counters do not include coinbase tx
118 87601 : nBlockTx = 0;
119 87601 : nFees = 0;
120 87601 : }
121 :
122 : // Helper to calculate best chainlock
123 23873 : static bool CalcCbTxBestChainlock(const chainlock::Chainlocks& chainlocks, const CBlockIndex* pindexPrev,
124 : uint32_t& bestCLHeightDiff, CBLSSignature& bestCLSignature)
125 : {
126 23873 : auto best_clsig = chainlocks.GetBestChainLock();
127 23873 : if (best_clsig.getHeight() < Params().GetConsensus().DeploymentHeight(Consensus::DEPLOYMENT_V19)) {
128 : // We don't want legacy BLS ChainLocks in CbTx (can happen on regtest/devenets)
129 19713 : best_clsig = chainlock::ChainLockSig{};
130 19713 : }
131 23873 : if (best_clsig.getHeight() == pindexPrev->nHeight) {
132 : // Our best CL is the newest one possible
133 1210 : bestCLHeightDiff = 0;
134 1210 : bestCLSignature = best_clsig.getSig();
135 1210 : return true;
136 : }
137 :
138 22663 : auto prevBlockCoinbaseChainlock = GetNonNullCoinbaseChainlock(pindexPrev);
139 22663 : if (prevBlockCoinbaseChainlock.has_value()) {
140 : // Previous block Coinbase contains a non-null CL: We must insert the same sig or a better (newest) one
141 2978 : if (best_clsig.IsNull()) {
142 : // We don't know any CL, therefore inserting the CL of the previous block
143 31 : bestCLHeightDiff = prevBlockCoinbaseChainlock->second + 1;
144 31 : bestCLSignature = prevBlockCoinbaseChainlock->first;
145 31 : return true;
146 : }
147 :
148 : // We check if our best CL is newer than the one from previous block Coinbase
149 2947 : int curCLHeight = best_clsig.getHeight();
150 2947 : int prevCLHeight = pindexPrev->nHeight - static_cast<int>(prevBlockCoinbaseChainlock->second) - 1;
151 2947 : if (curCLHeight < prevCLHeight) {
152 : // Our best CL isn't newer: inserting CL from previous block
153 0 : bestCLHeightDiff = prevBlockCoinbaseChainlock->second + 1;
154 0 : bestCLSignature = prevBlockCoinbaseChainlock->first;
155 0 : }
156 : else {
157 : // Our best CL is newer
158 2947 : bestCLHeightDiff = pindexPrev->nHeight - best_clsig.getHeight();
159 2947 : bestCLSignature = best_clsig.getSig();
160 : }
161 :
162 2947 : return true;
163 : }
164 : else {
165 : // Previous block Coinbase has no CL. We can either insert null or any valid CL
166 19685 : if (best_clsig.IsNull()) {
167 : // We don't know any CL, therefore inserting a null CL
168 19682 : bestCLHeightDiff = 0;
169 19682 : bestCLSignature.Reset();
170 19682 : return false;
171 : }
172 :
173 : // Inserting our best CL
174 3 : bestCLHeightDiff = pindexPrev->nHeight - best_clsig.getHeight();
175 3 : bestCLSignature = best_clsig.getSig();
176 :
177 3 : return true;
178 : }
179 23873 : }
180 :
181 :
182 87601 : std::unique_ptr<CBlockTemplate> BlockAssembler::CreateNewBlock(const CScript& scriptPubKeyIn)
183 : {
184 87601 : int64_t nTimeStart = GetTimeMicros();
185 :
186 87601 : resetBlock();
187 :
188 87606 : pblocktemplate.reset(new CBlockTemplate());
189 :
190 87601 : if (!pblocktemplate.get()) {
191 0 : return nullptr;
192 : }
193 87601 : CBlock* const pblock = &pblocktemplate->block; // pointer for convenience
194 :
195 : // Add dummy coinbase tx as first transaction
196 87601 : pblock->vtx.emplace_back();
197 87601 : pblocktemplate->vTxFees.push_back(-1); // updated at end
198 87601 : pblocktemplate->vTxSigOps.push_back(-1); // updated at end
199 :
200 87601 : LOCK(::cs_main);
201 87601 : CBlockIndex* pindexPrev = m_chainstate.m_chain.Tip();
202 87601 : assert(pindexPrev != nullptr);
203 87601 : nHeight = pindexPrev->nHeight + 1;
204 :
205 87601 : const bool fDIP0001Active_context{DeploymentActiveAfter(pindexPrev, chainparams.GetConsensus(), Consensus::DEPLOYMENT_DIP0001)};
206 87601 : const bool fDIP0003Active_context{DeploymentActiveAfter(pindexPrev, chainparams.GetConsensus(), Consensus::DEPLOYMENT_DIP0003)};
207 87601 : const bool fDIP0008Active_context{DeploymentActiveAfter(pindexPrev, chainparams.GetConsensus(), Consensus::DEPLOYMENT_DIP0008)};
208 87601 : const bool fV20Active_context{DeploymentActiveAfter(pindexPrev, chainparams.GetConsensus(), Consensus::DEPLOYMENT_V20)};
209 :
210 : // Limit size to between 1K and MaxBlockSize()-1K for sanity:
211 87601 : nBlockMaxSize = std::max<unsigned int>(1000, std::min<unsigned int>(MaxBlockSize(fDIP0001Active_context) - 1000, nBlockMaxSize));
212 87601 : nBlockMaxSigOps = MaxBlockSigOps(fDIP0001Active_context);
213 :
214 87601 : pblock->nVersion = m_chainstate.m_chainman.m_versionbitscache.ComputeBlockVersion(pindexPrev, chainparams.GetConsensus());
215 : // Non-mainnet only: allow overriding block.nVersion with
216 : // -blockversion=N to test forking scenarios
217 87601 : if (Params().NetworkIDString() != CBaseChainParams::MAIN) {
218 87583 : pblock->nVersion = gArgs.GetIntArg("-blockversion", pblock->nVersion);
219 87583 : }
220 :
221 87601 : pblock->nTime = GetAdjustedTime();
222 87601 : m_lock_time_cutoff = pindexPrev->GetMedianTimePast();
223 :
224 87601 : if (fDIP0003Active_context) {
225 163259 : for (const Consensus::LLMQParams& params : llmq::GetEnabledQuorumParams(m_chainstate.m_chainman, pindexPrev)) {
226 125388 : std::vector<CTransactionRef> vqcTx;
227 250776 : if (m_quorum_block_processor.GetMineableCommitmentsTx(params,
228 125388 : nHeight,
229 : vqcTx)) {
230 100157 : for (const auto& qcTx : vqcTx) {
231 56008 : pblock->vtx.emplace_back(qcTx);
232 56008 : pblocktemplate->vTxFees.emplace_back(0);
233 56008 : pblocktemplate->vTxSigOps.emplace_back(0);
234 56008 : nBlockSize += qcTx->GetTotalSize();
235 56008 : ++nBlockTx;
236 : }
237 44149 : }
238 125388 : }
239 37871 : }
240 :
241 87601 : int nPackagesSelected = 0;
242 87601 : int nDescendantsUpdated = 0;
243 87601 : if (m_mempool) {
244 87585 : LOCK(m_mempool->cs);
245 87585 : addPackageTxs(*m_mempool, nPackagesSelected, nDescendantsUpdated, pindexPrev);
246 87585 : }
247 :
248 87601 : int64_t nTime1 = GetTimeMicros();
249 :
250 87601 : m_last_block_num_txs = nBlockTx;
251 87601 : m_last_block_size = nBlockSize;
252 87601 : LogPrintf("CreateNewBlock(): total size %u txs: %u fees: %ld sigops %d\n", nBlockSize, nBlockTx, nFees, nBlockSigOps);
253 :
254 : // Create coinbase transaction.
255 87601 : CMutableTransaction coinbaseTx;
256 87601 : coinbaseTx.vin.resize(1);
257 87601 : coinbaseTx.vin[0].prevout.SetNull();
258 87601 : coinbaseTx.vout.resize(1);
259 87601 : coinbaseTx.vout[0].scriptPubKey = scriptPubKeyIn;
260 :
261 : // NOTE: unlike in bitcoin, we need to pass PREVIOUS block height here
262 87601 : CAmount blockSubsidy = GetBlockSubsidyInner(pindexPrev->nBits, pindexPrev->nHeight, Params().GetConsensus(), fV20Active_context);
263 87601 : CAmount blockReward = blockSubsidy + nFees;
264 :
265 : // Compute regular coinbase transaction.
266 87601 : coinbaseTx.vout[0].nValue = blockReward;
267 :
268 87601 : if (!fDIP0003Active_context) {
269 49730 : coinbaseTx.vin[0].scriptSig = CScript() << nHeight << OP_0;
270 49730 : } else {
271 37871 : coinbaseTx.vin[0].scriptSig = CScript() << OP_RETURN;
272 :
273 37871 : coinbaseTx.nVersion = 3;
274 37871 : coinbaseTx.nType = TRANSACTION_COINBASE;
275 :
276 37871 : CCbTx cbTx;
277 :
278 37871 : if (fV20Active_context) {
279 23873 : cbTx.nVersion = CCbTx::Version::CLSIG_AND_BALANCE;
280 37871 : } else if (fDIP0008Active_context) {
281 12526 : cbTx.nVersion = CCbTx::Version::MERKLE_ROOT_QUORUMS;
282 12526 : } else {
283 1472 : cbTx.nVersion = CCbTx::Version::MERKLE_ROOT_MNLIST;
284 : }
285 :
286 37871 : cbTx.nHeight = nHeight;
287 :
288 37871 : BlockValidationState state;
289 37871 : CDeterministicMNList mn_list;
290 37871 : if (!m_chain_helper.special_tx->BuildNewListFromBlock(*pblock, pindexPrev, m_chainstate.CoinsTip(), true, state, mn_list)) {
291 0 : throw std::runtime_error(strprintf("%s: BuildNewListFromBlock failed: %s", __func__, state.ToString()));
292 : }
293 37871 : if (!CalcCbTxMerkleRootMNList(cbTx.merkleRootMNList, mn_list.to_sml(), state)) {
294 0 : throw std::runtime_error(strprintf("%s: CalcCbTxMerkleRootMNList failed: %s", __func__, state.ToString()));
295 : }
296 37871 : if (fDIP0008Active_context) {
297 36399 : if (!CalcCbTxMerkleRootQuorums(*pblock, pindexPrev, m_quorum_block_processor, cbTx.merkleRootQuorums, state)) {
298 0 : throw std::runtime_error(strprintf("%s: CalcCbTxMerkleRootQuorums failed: %s", __func__, state.ToString()));
299 : }
300 36399 : if (fV20Active_context) {
301 23873 : if (CalcCbTxBestChainlock(m_chainlocks, pindexPrev, cbTx.bestCLHeightDiff, cbTx.bestCLSignature)) {
302 4191 : LogPrintf("CreateNewBlock() h[%d] CbTx bestCLHeightDiff[%d] CLSig[%s]\n", nHeight, cbTx.bestCLHeightDiff, cbTx.bestCLSignature.ToString());
303 4191 : } else {
304 : // not an error
305 19682 : LogPrintf("CreateNewBlock() h[%d] CbTx failed to find best CL. Inserting null CL\n", nHeight);
306 : }
307 23873 : BlockValidationState state;
308 23873 : const auto creditPoolDiff = GetCreditPoolDiffForBlock(*m_chain_helper.credit_pool_manager, *pblock, pindexPrev, chainparams.GetConsensus(), blockSubsidy, state);
309 23873 : if (creditPoolDiff == std::nullopt) {
310 0 : throw std::runtime_error(strprintf("%s: GetCreditPoolDiffForBlock failed: %s", __func__, state.ToString()));
311 : }
312 :
313 23873 : cbTx.creditPoolBalance = creditPoolDiff->GetTotalLocked();
314 23873 : }
315 36399 : }
316 :
317 37871 : SetTxPayload(coinbaseTx, cbTx);
318 37871 : }
319 :
320 : // Update coinbase transaction with additional info about masternode and governance payments,
321 : // get some info back to pass to getblocktemplate
322 87601 : m_chain_helper.mn_payments->FillBlockPayments(coinbaseTx, pindexPrev, blockSubsidy, nFees, pblocktemplate->voutMasternodePayments, pblocktemplate->voutSuperblockPayments);
323 :
324 87601 : pblock->vtx[0] = MakeTransactionRef(std::move(coinbaseTx));
325 87601 : pblocktemplate->vTxFees[0] = -nFees;
326 :
327 : // Fill in header
328 87601 : pblock->hashPrevBlock = pindexPrev->GetBlockHash();
329 87601 : UpdateTime(pblock, chainparams.GetConsensus(), pindexPrev);
330 87601 : pblock->nBits = GetNextWorkRequired(pindexPrev, pblock, chainparams.GetConsensus());
331 87601 : pblock->nNonce = 0;
332 87601 : pblocktemplate->nPrevBits = pindexPrev->nBits;
333 87601 : pblocktemplate->vTxSigOps[0] = GetLegacySigOpCount(*pblock->vtx[0]);
334 :
335 87601 : BlockValidationState state;
336 87601 : if (!TestBlockValidity(state, m_chainlocks, m_evoDb, chainparams, m_chainstate, *pblock, pindexPrev, false, false)) {
337 5 : throw std::runtime_error(strprintf("%s: TestBlockValidity failed: %s", __func__, state.ToString()));
338 : }
339 87596 : int64_t nTime2 = GetTimeMicros();
340 :
341 87596 : LogPrint(BCLog::BENCHMARK, "CreateNewBlock() packages: %.2fms (%d packages, %d updated descendants), validity: %.2fms (total %.2fms)\n", 0.001 * (nTime1 - nTimeStart), nPackagesSelected, nDescendantsUpdated, 0.001 * (nTime2 - nTime1), 0.001 * (nTime2 - nTimeStart));
342 :
343 87596 : return std::move(pblocktemplate);
344 87606 : }
345 :
346 14756 : void BlockAssembler::onlyUnconfirmed(CTxMemPool::setEntries& testSet)
347 : {
348 37301 : for (CTxMemPool::setEntries::iterator iit = testSet.begin(); iit != testSet.end(); ) {
349 : // Only test txs not already in the block
350 22545 : if (inBlock.count(*iit)) {
351 13716 : testSet.erase(iit++);
352 13716 : } else {
353 8829 : iit++;
354 : }
355 : }
356 14756 : }
357 :
358 39284 : bool BlockAssembler::TestPackage(uint64_t packageSize, unsigned int packageSigOps) const
359 : {
360 39284 : if (nBlockSize + packageSize >= nBlockMaxSize) {
361 24520 : return false;
362 : }
363 :
364 14764 : if (nBlockSigOps + packageSigOps >= nBlockMaxSigOps) {
365 8 : return false;
366 : }
367 14756 : return true;
368 39284 : }
369 :
370 : // Perform transaction-level checks before adding to block:
371 : // - transaction finality (locktime)
372 : // - safe TXs in regard to ChainLocks
373 14756 : bool BlockAssembler::TestPackageTransactions(const CTxMemPool::setEntries& package) const
374 : {
375 32474 : for (CTxMemPool::txiter it : package) {
376 18121 : if (!IsFinalTx(it->GetTx(), nHeight, m_lock_time_cutoff)) {
377 2 : return false;
378 : }
379 :
380 18119 : const auto& txid = it->GetTx().GetHash();
381 18119 : if (!m_isman.IsInstantSendEnabled() || m_isman.IsLocked(txid)) {
382 15436 : continue;
383 : }
384 :
385 2683 : if (!it->GetTx().vin.empty() && !m_clhandler.IsTxSafeForMining(txid)) {
386 401 : return false;
387 : }
388 : }
389 14353 : return true;
390 14756 : }
391 :
392 17718 : void BlockAssembler::AddToBlock(CTxMemPool::txiter iter)
393 : {
394 17718 : pblocktemplate->block.vtx.emplace_back(iter->GetSharedTx());
395 17718 : pblocktemplate->vTxFees.push_back(iter->GetFee());
396 17718 : pblocktemplate->vTxSigOps.push_back(iter->GetSigOpCount());
397 17718 : nBlockSize += iter->GetTxSize();
398 17718 : ++nBlockTx;
399 17718 : nBlockSigOps += iter->GetSigOpCount();
400 17718 : nFees += iter->GetFee();
401 17718 : inBlock.insert(iter);
402 :
403 17718 : bool fPrintPriority = gArgs.GetBoolArg("-printpriority", DEFAULT_PRINTPRIORITY);
404 17718 : if (fPrintPriority) {
405 294 : LogPrintf("fee rate %s txid %s\n",
406 : CFeeRate(iter->GetModifiedFee(), iter->GetTxSize()).ToString(),
407 : iter->GetTx().GetHash().ToString());
408 294 : }
409 17718 : }
410 :
411 : /** Add descendants of given transactions to mapModifiedTx with ancestor
412 : * state updated assuming given transactions are inBlock. Returns number
413 : * of updated descendants. */
414 14353 : static int UpdatePackagesForAdded(const CTxMemPool& mempool,
415 : const CTxMemPool::setEntries& alreadyAdded,
416 : indexed_modified_transaction_set& mapModifiedTx) EXCLUSIVE_LOCKS_REQUIRED(mempool.cs)
417 : {
418 14353 : AssertLockHeld(mempool.cs);
419 :
420 14353 : int nDescendantsUpdated = 0;
421 32071 : for (CTxMemPool::txiter it : alreadyAdded) {
422 17718 : CTxMemPool::setEntries descendants;
423 17718 : mempool.CalculateDescendants(it, descendants);
424 : // Insert all descendants (not yet in block) into the modified set
425 1045528 : for (CTxMemPool::txiter desc : descendants) {
426 1027810 : if (alreadyAdded.count(desc)) {
427 290918 : continue;
428 : }
429 736892 : ++nDescendantsUpdated;
430 736892 : modtxiter mit = mapModifiedTx.find(desc);
431 736892 : if (mit == mapModifiedTx.end()) {
432 2328 : CTxMemPoolModifiedEntry modEntry(desc);
433 2328 : mit = mapModifiedTx.insert(modEntry).first;
434 2328 : }
435 736892 : mapModifiedTx.modify(mit, update_for_parent_inclusion(it));
436 : }
437 17718 : }
438 14353 : return nDescendantsUpdated;
439 0 : }
440 :
441 14353 : void BlockAssembler::SortForBlock(const CTxMemPool::setEntries& package, std::vector<CTxMemPool::txiter>& sortedEntries)
442 : {
443 : // Sort package by ancestor count
444 : // If a transaction A depends on transaction B, then A's ancestor count
445 : // must be greater than B's. So this is sufficient to validly order the
446 : // transactions for block inclusion.
447 14353 : sortedEntries.clear();
448 14353 : sortedEntries.insert(sortedEntries.begin(), package.begin(), package.end());
449 14353 : std::sort(sortedEntries.begin(), sortedEntries.end(), CompareTxIterByAncestorCount());
450 14353 : }
451 :
452 : // This transaction selection algorithm orders the mempool based
453 : // on feerate of a transaction including all unconfirmed ancestors.
454 : // Since we don't remove transactions from the mempool as we select them
455 : // for block inclusion, we need an alternate method of updating the feerate
456 : // of a transaction with its not-yet-selected ancestors as we go.
457 : // This is accomplished by walking the in-mempool descendants of selected
458 : // transactions and storing a temporary modified state in mapModifiedTxs.
459 : // Each time through the loop, we compare the best transaction in
460 : // mapModifiedTxs with the next transaction in the mempool to decide what
461 : // transaction package to work on next.
462 87585 : void BlockAssembler::addPackageTxs(const CTxMemPool& mempool, int& nPackagesSelected, int& nDescendantsUpdated, const CBlockIndex* const pindexPrev)
463 : {
464 87585 : AssertLockHeld(mempool.cs);
465 :
466 : // This credit pool is used only to check withdrawal limits and to find
467 : // duplicates of indexes. There's used `BlockSubsidy` equaled to 0
468 87585 : std::optional<CCreditPoolDiff> creditPoolDiff;
469 87585 : if (DeploymentActiveAfter(pindexPrev, chainparams.GetConsensus(), Consensus::DEPLOYMENT_V20)) {
470 23873 : CCreditPool creditPool = m_chain_helper.GetCreditPool(pindexPrev);
471 23873 : creditPoolDiff.emplace(std::move(creditPool), pindexPrev, chainparams.GetConsensus(), 0);
472 23873 : }
473 :
474 : // This map with signals is used only to find duplicates
475 87585 : std::unordered_map<uint8_t, int> signals = m_chain_helper.ehf_manager->GetSignalsStage(pindexPrev);
476 :
477 : // mapModifiedTx will store sorted packages after they are modified
478 : // because some of their txs are already in the block
479 87585 : indexed_modified_transaction_set mapModifiedTx;
480 : // Keep track of entries that failed inclusion, to avoid duplicate work
481 87585 : CTxMemPool::setEntries failedTx;
482 :
483 87585 : CTxMemPool::indexed_transaction_set::index<ancestor_score>::type::iterator mi = mempool.mapTx.get<ancestor_score>().begin();
484 87585 : CTxMemPool::txiter iter;
485 :
486 : // Limit the number of attempts to add transactions to the block when it is
487 : // close to full; this is just a simple heuristic to finish quickly if the
488 : // mempool has a lot of entries.
489 87585 : const int64_t MAX_CONSECUTIVE_FAILURES = 1000;
490 87585 : int64_t nConsecutiveFailed = 0;
491 :
492 131781 : while (mi != mempool.mapTx.get<ancestor_score>().end() || !mapModifiedTx.empty()) {
493 : // First try to find a new transaction in mapTx to evaluate.
494 : //
495 : // Skip entries in mapTx that are already in a block or are present
496 : // in mapModifiedTx (which implies that the mapTx ancestor state is
497 : // stale due to ancestor inclusion in the block)
498 : // Also skip transactions that we've already failed to add. This can happen if
499 : // we consider a transaction in mapModifiedTx and it fails: we can then
500 : // potentially consider it again while walking mapTx. It's currently
501 : // guaranteed to fail again, but as a belt-and-suspenders check we put it in
502 : // failedTx and avoid re-evaluation, since the re-evaluation would be using
503 : // cached size/sigops/fee values that are not actually correct.
504 : /** Return true if given transaction from mapTx has already been evaluated,
505 : * or if the transaction's cached data in mapTx is incorrect. */
506 44231 : if (mi != mempool.mapTx.get<ancestor_score>().end()) {
507 43720 : auto it = mempool.mapTx.project<0>(mi);
508 43720 : assert(it != mempool.mapTx.end());
509 43720 : if (mapModifiedTx.count(it) || inBlock.count(it) || failedTx.count(it)) {
510 4290 : ++mi;
511 4290 : continue;
512 : }
513 39430 : }
514 :
515 : // Now that mi is not stale, determine which transaction to evaluate:
516 : // the next entry from mapTx, or the best from mapModifiedTx?
517 39941 : bool fUsingModified = false;
518 :
519 39941 : modtxscoreiter modit = mapModifiedTx.get<ancestor_score>().begin();
520 39941 : if (mi == mempool.mapTx.get<ancestor_score>().end()) {
521 : // We're out of entries in mapTx; use the entry from mapModifiedTx
522 511 : iter = modit->iter;
523 511 : fUsingModified = true;
524 511 : } else {
525 : // Try to compare the mapTx entry to the mapModifiedTx entry
526 39430 : iter = mempool.mapTx.project<0>(mi);
527 41099 : if (modit != mapModifiedTx.get<ancestor_score>().end() &&
528 1669 : CompareTxMemPoolEntryByAncestorFee()(*modit, CTxMemPoolModifiedEntry(iter))) {
529 : // The best entry in mapModifiedTx has higher score
530 : // than the one from mapTx.
531 : // Switch which transaction (package) to consider
532 415 : iter = modit->iter;
533 415 : fUsingModified = true;
534 415 : } else {
535 : // Either no entry in mapModifiedTx, or it's worse than mapTx.
536 : // Increment mi for the next loop iteration.
537 39015 : ++mi;
538 : }
539 : }
540 :
541 39941 : if (creditPoolDiff != std::nullopt) {
542 : // If one transaction is skipped due to limits, it is not a reason to interrupt
543 : // whole process of adding transactions.
544 : // `state` is local here because used only to log info about this specific tx
545 2252 : TxValidationState state;
546 :
547 2252 : if (iter->GetTx().IsSpecialTxVersion() && iter->GetTx().nType == TRANSACTION_ASSET_UNLOCK) {
548 : // ASSET_UNLOCK transactions may expire after being added to mempool
549 : // They should not be included to the block
550 654 : if (!CheckAssetUnlockTx(m_blockman, m_qman, iter->GetTx(), pindexPrev, creditPoolDiff->pool.indexes, state)) {
551 12 : if (fUsingModified) {
552 0 : mapModifiedTx.get<ancestor_score>().erase(modit);
553 0 : failedTx.insert(iter);
554 0 : }
555 12 : LogPrintf("%s: asset unlock tx %s is skipped due %s\n",
556 : __func__, iter->GetTx().GetHash().ToString(), state.ToString());
557 12 : continue;
558 : }
559 642 : }
560 2240 : if (!creditPoolDiff->ProcessLockUnlockTransaction(iter->GetTx(), state)) {
561 606 : if (fUsingModified) {
562 0 : mapModifiedTx.get<ancestor_score>().erase(modit);
563 0 : failedTx.insert(iter);
564 0 : }
565 606 : LogPrintf("%s: asset-locks tx %s skipped due %s\n",
566 : __func__, iter->GetTx().GetHash().ToString(), state.ToString());
567 606 : continue;
568 : }
569 2252 : }
570 39323 : if (std::optional<uint8_t> signal = extractEHFSignal(iter->GetTx()); signal != std::nullopt) {
571 56 : if (signals.find(*signal) != signals.end()) {
572 4 : if (fUsingModified) {
573 0 : mapModifiedTx.get<ancestor_score>().erase(modit);
574 0 : failedTx.insert(iter);
575 0 : }
576 4 : LogPrintf("%s: ehf signal tx %s skipped due to duplicate %d\n",
577 : __func__, iter->GetTx().GetHash().ToString(), *signal);
578 4 : continue;
579 : }
580 52 : signals.insert({*signal, 0});
581 52 : }
582 :
583 : // We skip mapTx entries that are inBlock, and mapModifiedTx shouldn't
584 : // contain anything that is inBlock.
585 39319 : assert(!inBlock.count(iter));
586 :
587 39319 : uint64_t packageSize = iter->GetSizeWithAncestors();
588 39319 : CAmount packageFees = iter->GetModFeesWithAncestors();
589 39319 : unsigned int packageSigOps = iter->GetSigOpCountWithAncestors();
590 39319 : if (fUsingModified) {
591 926 : packageSize = modit->nSizeWithAncestors;
592 926 : packageFees = modit->nModFeesWithAncestors;
593 926 : packageSigOps = modit->nSigOpCountWithAncestors;
594 926 : }
595 :
596 39319 : if (packageFees < blockMinFeeRate.GetFee(packageSize)) {
597 : // Everything else we might consider has a lower fee rate
598 35 : return;
599 : }
600 :
601 39284 : if (!TestPackage(packageSize, packageSigOps)) {
602 24528 : if (fUsingModified) {
603 : // Since we always look at the best entry in mapModifiedTx,
604 : // we must erase failed entries so that we can consider the
605 : // next best entry on the next loop iteration
606 8 : mapModifiedTx.get<ancestor_score>().erase(modit);
607 8 : failedTx.insert(iter);
608 8 : }
609 :
610 24528 : ++nConsecutiveFailed;
611 :
612 24528 : if (nConsecutiveFailed > MAX_CONSECUTIVE_FAILURES && nBlockSize > nBlockMaxSize - 1000) {
613 : // Give up if we're close to full and haven't succeeded in a while
614 0 : break;
615 : }
616 24528 : continue;
617 : }
618 :
619 14756 : CTxMemPool::setEntries ancestors;
620 14756 : uint64_t nNoLimit = std::numeric_limits<uint64_t>::max();
621 14756 : std::string dummy;
622 14756 : mempool.CalculateMemPoolAncestors(*iter, ancestors, nNoLimit, nNoLimit, nNoLimit, nNoLimit, dummy, false);
623 :
624 14756 : onlyUnconfirmed(ancestors);
625 14756 : ancestors.insert(iter);
626 :
627 : // Test if all tx's are Final and safe
628 14756 : if (!TestPackageTransactions(ancestors)) {
629 403 : if (fUsingModified) {
630 0 : mapModifiedTx.get<ancestor_score>().erase(modit);
631 0 : failedTx.insert(iter);
632 0 : }
633 403 : continue;
634 : }
635 :
636 : // This transaction will make it in; reset the failed counter.
637 14353 : nConsecutiveFailed = 0;
638 :
639 : // Package can be added. Sort the entries in a valid order.
640 14353 : std::vector<CTxMemPool::txiter> sortedEntries;
641 14353 : SortForBlock(ancestors, sortedEntries);
642 :
643 32071 : for (size_t i = 0; i < sortedEntries.size(); ++i) {
644 17718 : AddToBlock(sortedEntries[i]);
645 : // Erase from the modified set, if present
646 17718 : mapModifiedTx.erase(sortedEntries[i]);
647 17718 : }
648 :
649 14353 : ++nPackagesSelected;
650 :
651 : // Update transactions that depend on each of these
652 14353 : nDescendantsUpdated += UpdatePackagesForAdded(mempool, ancestors, mapModifiedTx);
653 14756 : }
654 87585 : }
655 : } // namespace node
|