MCPcopy Create free account
hub / github.com/ElementsProject/elements / addPackageTxs

Method addPackageTxs

src/node/miner.cpp:373–518  ·  view source on GitHub ↗

This transaction selection algorithm orders the mempool based on feerate of a transaction including all unconfirmed ancestors. Since we don't remove transactions from the mempool as we select them for block inclusion, we need an alternate method of updating the feerate of a transaction with its not-yet-selected ancestors as we go. This is accomplished by walking the in-mempool descendants of selec

Source from the content-addressed store, hash-verified

371// mapModifiedTxs with the next transaction in the mempool to decide what
372// transaction package to work on next.
373void BlockAssembler::addPackageTxs(int& nPackagesSelected, int& nDescendantsUpdated, std::chrono::seconds min_tx_age)
374{
375 AssertLockHeld(m_mempool.cs);
376
377 // mapModifiedTx will store sorted packages after they are modified
378 // because some of their txs are already in the block
379 indexed_modified_transaction_set mapModifiedTx;
380 // Keep track of entries that failed inclusion, to avoid duplicate work
381 CTxMemPool::setEntries failedTx;
382
383 // Start by adding all descendants of previously added txs to mapModifiedTx
384 // and modifying them for their already included ancestors
385 UpdatePackagesForAdded(inBlock, mapModifiedTx);
386
387 // ELEMENTS: we use confidential_score instead of ancestor_score
388 CTxMemPool::indexed_transaction_set::index<confidential_score>::type::iterator mi = m_mempool.mapTx.get<confidential_score>().begin();
389 CTxMemPool::txiter iter;
390
391 // Limit the number of attempts to add transactions to the block when it is
392 // close to full; this is just a simple heuristic to finish quickly if the
393 // mempool has a lot of entries.
394 const int64_t MAX_CONSECUTIVE_FAILURES = 1000;
395 constexpr int32_t BLOCK_FULL_ENOUGH_WEIGHT_DELTA = 4000;
396 int64_t nConsecutiveFailed = 0;
397
398 while (mi != m_mempool.mapTx.get<confidential_score>().end() || !mapModifiedTx.empty()) {
399 // First try to find a new transaction in mapTx to evaluate.
400 if (mi != m_mempool.mapTx.get<confidential_score>().end() &&
401 SkipMapTxEntry(m_mempool.mapTx.project<0>(mi), mapModifiedTx, failedTx)) {
402 ++mi;
403 continue;
404 }
405
406 // Now that mi is not stale, determine which transaction to evaluate:
407 // the next entry from mapTx, or the best from mapModifiedTx?
408 bool fUsingModified = false;
409
410 modconftxscoreiter modit = mapModifiedTx.get<confidential_score>().begin();
411 if (mi == m_mempool.mapTx.get<confidential_score>().end()) {
412 // We're out of entries in mapTx; use the entry from mapModifiedTx
413 iter = modit->iter;
414 fUsingModified = true;
415 } else {
416 // Try to compare the mapTx entry to the mapModifiedTx entry
417 iter = m_mempool.mapTx.project<0>(mi);
418 if (modit != mapModifiedTx.get<confidential_score>().end() &&
419 CompareTxMemPoolEntryByConfidentialFee()(*modit, CTxMemPoolModifiedEntry(iter))) {
420 // The best entry in mapModifiedTx has higher score
421 // than the one from mapTx.
422 // Switch which transaction (package) to consider
423 iter = modit->iter;
424 fUsingModified = true;
425 } else {
426 // Either no entry in mapModifiedTx, or it's worse than mapTx.
427 // Increment mi for the next loop iteration.
428 ++mi;
429 }
430 }

Callers

nothing calls this directly

Calls 15

GetTimeMethod · 0.80
countMethod · 0.80
GetFeeMethod · 0.80
GetAcceptDiscountCTMethod · 0.80
ParamsClass · 0.70
beginMethod · 0.45
endMethod · 0.45
emptyMethod · 0.45

Tested by

no test coverage detected