txmempool.cpp
1 // Copyright (c) 2009-2010 Satoshi Nakamoto 2 // Copyright (c) 2009-2022 The Bitcoin Core developers 3 // Distributed under the MIT software license, see the accompanying 4 // file COPYING or http://www.opensource.org/licenses/mit-license.php. 5 6 #include <txmempool.h> 7 8 #include <chain.h> 9 #include <coins.h> 10 #include <common/system.h> 11 #include <consensus/consensus.h> 12 #include <consensus/tx_verify.h> 13 #include <consensus/validation.h> 14 #include <logging.h> 15 #include <policy/policy.h> 16 #include <policy/settings.h> 17 #include <random.h> 18 #include <tinyformat.h> 19 #include <util/check.h> 20 #include <util/feefrac.h> 21 #include <util/moneystr.h> 22 #include <util/overflow.h> 23 #include <util/result.h> 24 #include <util/time.h> 25 #include <util/trace.h> 26 #include <util/translation.h> 27 #include <validationinterface.h> 28 29 #include <algorithm> 30 #include <cmath> 31 #include <numeric> 32 #include <optional> 33 #include <ranges> 34 #include <string_view> 35 #include <utility> 36 37 TRACEPOINT_SEMAPHORE(mempool, added); 38 TRACEPOINT_SEMAPHORE(mempool, removed); 39 40 bool TestLockPointValidity(CChain& active_chain, const LockPoints& lp) 41 { 42 AssertLockHeld(cs_main); 43 // If there are relative lock times then the maxInputBlock will be set 44 // If there are no relative lock times, the LockPoints don't depend on the chain 45 if (lp.maxInputBlock) { 46 // Check whether active_chain is an extension of the block at which the LockPoints 47 // calculation was valid. If not LockPoints are no longer valid 48 if (!active_chain.Contains(lp.maxInputBlock)) { 49 return false; 50 } 51 } 52 53 // LockPoints still valid 54 return true; 55 } 56 57 std::vector<CTxMemPoolEntry::CTxMemPoolEntryRef> CTxMemPool::GetChildren(const CTxMemPoolEntry& entry) const 58 { 59 LOCK(cs); 60 std::vector<CTxMemPoolEntry::CTxMemPoolEntryRef> ret; 61 WITH_FRESH_EPOCH(m_epoch); 62 auto iter = mapNextTx.lower_bound(COutPoint(entry.GetTx().GetHash(), 0)); 63 for (; iter != mapNextTx.end() && iter->first->hash == entry.GetTx().GetHash(); ++iter) { 64 if (!visited(iter->second)) { 65 ret.emplace_back(*(iter->second)); 66 } 67 } 68 return ret; 69 } 70 71 std::vector<CTxMemPoolEntry::CTxMemPoolEntryRef> CTxMemPool::GetParents(const CTxMemPoolEntry& entry) const 72 { 73 LOCK(cs); 74 std::vector<CTxMemPoolEntry::CTxMemPoolEntryRef> ret; 75 std::set<Txid> inputs; 76 for (const auto& txin : entry.GetTx().vin) { 77 inputs.insert(txin.prevout.hash); 78 } 79 for (const auto& hash : inputs) { 80 std::optional<txiter> piter = GetIter(hash); 81 if (piter) { 82 ret.emplace_back(**piter); 83 } 84 } 85 return ret; 86 } 87 88 void CTxMemPool::UpdateTransactionsFromBlock(const std::vector<Txid>& vHashesToUpdate) 89 { 90 AssertLockHeld(cs); 91 92 // Iterate in reverse, so that whenever we are looking at a transaction 93 // we are sure that all in-mempool descendants have already been processed. 94 for (const Txid& hash : vHashesToUpdate | std::views::reverse) { 95 // calculate children from mapNextTx 96 txiter it = mapTx.find(hash); 97 if (it == mapTx.end()) { 98 continue; 99 } 100 auto iter = mapNextTx.lower_bound(COutPoint(hash, 0)); 101 { 102 for (; iter != mapNextTx.end() && iter->first->hash == hash; ++iter) { 103 txiter childIter = iter->second; 104 assert(childIter != mapTx.end()); 105 // Add dependencies that are discovered between transactions in the 106 // block and transactions that were in the mempool to txgraph. 107 m_txgraph->AddDependency(/*parent=*/*it, /*child=*/*childIter); 108 } 109 } 110 } 111 112 auto txs_to_remove = m_txgraph->Trim(); // Enforce cluster size limits. 113 for (auto txptr : txs_to_remove) { 114 const CTxMemPoolEntry& entry = *(static_cast<const CTxMemPoolEntry*>(txptr)); 115 removeUnchecked(mapTx.iterator_to(entry), MemPoolRemovalReason::SIZELIMIT); 116 } 117 } 118 119 bool CTxMemPool::HasDescendants(const Txid& txid) const 120 { 121 LOCK(cs); 122 auto entry = GetEntry(txid); 123 if (!entry) return false; 124 return m_txgraph->GetDescendants(*entry, TxGraph::Level::MAIN).size() > 1; 125 } 126 127 CTxMemPool::setEntries CTxMemPool::CalculateMemPoolAncestors(const CTxMemPoolEntry &entry) const 128 { 129 auto ancestors = m_txgraph->GetAncestors(entry, TxGraph::Level::MAIN); 130 setEntries ret; 131 if (ancestors.size() > 0) { 132 for (auto ancestor : ancestors) { 133 if (ancestor != &entry) { 134 ret.insert(mapTx.iterator_to(static_cast<const CTxMemPoolEntry&>(*ancestor))); 135 } 136 } 137 return ret; 138 } 139 140 // If we didn't get anything back, the transaction is not in the graph. 141 // Find each parent and call GetAncestors on each. 142 setEntries staged_parents; 143 const CTransaction &tx = entry.GetTx(); 144 145 // Get parents of this transaction that are in the mempool 146 for (unsigned int i = 0; i < tx.vin.size(); i++) { 147 std::optional<txiter> piter = GetIter(tx.vin[i].prevout.hash); 148 if (piter) { 149 staged_parents.insert(*piter); 150 } 151 } 152 153 for (const auto& parent : staged_parents) { 154 auto parent_ancestors = m_txgraph->GetAncestors(*parent, TxGraph::Level::MAIN); 155 for (auto ancestor : parent_ancestors) { 156 ret.insert(mapTx.iterator_to(static_cast<const CTxMemPoolEntry&>(*ancestor))); 157 } 158 } 159 160 return ret; 161 } 162 163 static CTxMemPool::Options&& Flatten(CTxMemPool::Options&& opts, bilingual_str& error) 164 { 165 opts.check_ratio = std::clamp<int>(opts.check_ratio, 0, 1'000'000); 166 int64_t cluster_limit_bytes = opts.limits.cluster_size_vbytes * 40; 167 if (opts.max_size_bytes < 0 || (opts.max_size_bytes > 0 && opts.max_size_bytes < cluster_limit_bytes)) { 168 error = strprintf(_("-maxmempool must be at least %d MB"), std::ceil(cluster_limit_bytes / 1'000'000.0)); 169 } 170 return std::move(opts); 171 } 172 173 CTxMemPool::CTxMemPool(Options opts, bilingual_str& error) 174 : m_opts{Flatten(std::move(opts), error)} 175 { 176 m_txgraph = MakeTxGraph(m_opts.limits.cluster_count, m_opts.limits.cluster_size_vbytes * WITNESS_SCALE_FACTOR, ACCEPTABLE_ITERS); 177 } 178 179 bool CTxMemPool::isSpent(const COutPoint& outpoint) const 180 { 181 LOCK(cs); 182 return mapNextTx.count(outpoint); 183 } 184 185 unsigned int CTxMemPool::GetTransactionsUpdated() const 186 { 187 return nTransactionsUpdated; 188 } 189 190 void CTxMemPool::AddTransactionsUpdated(unsigned int n) 191 { 192 nTransactionsUpdated += n; 193 } 194 195 void CTxMemPool::Apply(ChangeSet* changeset) 196 { 197 AssertLockHeld(cs); 198 m_txgraph->CommitStaging(); 199 200 RemoveStaged(changeset->m_to_remove, MemPoolRemovalReason::REPLACED); 201 202 for (size_t i=0; i<changeset->m_entry_vec.size(); ++i) { 203 auto tx_entry = changeset->m_entry_vec[i]; 204 // First splice this entry into mapTx. 205 auto node_handle = changeset->m_to_add.extract(tx_entry); 206 auto result = mapTx.insert(std::move(node_handle)); 207 208 Assume(result.inserted); 209 txiter it = result.position; 210 211 addNewTransaction(it); 212 } 213 m_txgraph->DoWork(POST_CHANGE_WORK); 214 } 215 216 void CTxMemPool::addNewTransaction(CTxMemPool::txiter newit) 217 { 218 const CTxMemPoolEntry& entry = *newit; 219 220 // Update cachedInnerUsage to include contained transaction's usage. 221 // (When we update the entry for in-mempool parents, memory usage will be 222 // further updated.) 223 cachedInnerUsage += entry.DynamicMemoryUsage(); 224 225 const CTransaction& tx = newit->GetTx(); 226 for (unsigned int i = 0; i < tx.vin.size(); i++) { 227 mapNextTx.insert(std::make_pair(&tx.vin[i].prevout, newit)); 228 } 229 // Don't bother worrying about child transactions of this one. 230 // Normal case of a new transaction arriving is that there can't be any 231 // children, because such children would be orphans. 232 // An exception to that is if a transaction enters that used to be in a block. 233 // In that case, our disconnect block logic will call UpdateTransactionsFromBlock 234 // to clean up the mess we're leaving here. 235 236 nTransactionsUpdated++; 237 totalTxSize += entry.GetTxSize(); 238 m_total_fee += entry.GetFee(); 239 240 txns_randomized.emplace_back(tx.GetWitnessHash(), newit); 241 newit->idx_randomized = txns_randomized.size() - 1; 242 243 TRACEPOINT(mempool, added, 244 entry.GetTx().GetHash().data(), 245 entry.GetTxSize(), 246 entry.GetFee() 247 ); 248 } 249 250 void CTxMemPool::removeUnchecked(txiter it, MemPoolRemovalReason reason) 251 { 252 // We increment mempool sequence value no matter removal reason 253 // even if not directly reported below. 254 uint64_t mempool_sequence = GetAndIncrementSequence(); 255 256 if (reason != MemPoolRemovalReason::BLOCK && m_opts.signals) { 257 // Notify clients that a transaction has been removed from the mempool 258 // for any reason except being included in a block. Clients interested 259 // in transactions included in blocks can subscribe to the BlockConnected 260 // notification. 261 m_opts.signals->TransactionRemovedFromMempool(it->GetSharedTx(), reason, mempool_sequence); 262 } 263 TRACEPOINT(mempool, removed, 264 it->GetTx().GetHash().data(), 265 RemovalReasonToString(reason).c_str(), 266 it->GetTxSize(), 267 it->GetFee(), 268 std::chrono::duration_cast<std::chrono::duration<std::uint64_t>>(it->GetTime()).count() 269 ); 270 271 for (const CTxIn& txin : it->GetTx().vin) 272 mapNextTx.erase(txin.prevout); 273 274 RemoveUnbroadcastTx(it->GetTx().GetHash(), true /* add logging because unchecked */); 275 276 if (txns_randomized.size() > 1) { 277 // Remove entry from txns_randomized by replacing it with the back and deleting the back. 278 txns_randomized[it->idx_randomized] = std::move(txns_randomized.back()); 279 txns_randomized[it->idx_randomized].second->idx_randomized = it->idx_randomized; 280 txns_randomized.pop_back(); 281 if (txns_randomized.size() * 2 < txns_randomized.capacity()) { 282 txns_randomized.shrink_to_fit(); 283 } 284 } else { 285 txns_randomized.clear(); 286 } 287 288 totalTxSize -= it->GetTxSize(); 289 m_total_fee -= it->GetFee(); 290 cachedInnerUsage -= it->DynamicMemoryUsage(); 291 mapTx.erase(it); 292 nTransactionsUpdated++; 293 } 294 295 // Calculates descendants of given entry and adds to setDescendants. 296 void CTxMemPool::CalculateDescendants(txiter entryit, setEntries& setDescendants) const 297 { 298 (void)CalculateDescendants(*entryit, setDescendants); 299 return; 300 } 301 302 CTxMemPool::txiter CTxMemPool::CalculateDescendants(const CTxMemPoolEntry& entry, setEntries& setDescendants) const 303 { 304 for (auto tx : m_txgraph->GetDescendants(entry, TxGraph::Level::MAIN)) { 305 setDescendants.insert(mapTx.iterator_to(static_cast<const CTxMemPoolEntry&>(*tx))); 306 } 307 return mapTx.iterator_to(entry); 308 } 309 310 void CTxMemPool::removeRecursive(CTxMemPool::txiter to_remove, MemPoolRemovalReason reason) 311 { 312 AssertLockHeld(cs); 313 Assume(!m_have_changeset); 314 auto descendants = m_txgraph->GetDescendants(*to_remove, TxGraph::Level::MAIN); 315 for (auto tx: descendants) { 316 removeUnchecked(mapTx.iterator_to(static_cast<const CTxMemPoolEntry&>(*tx)), reason); 317 } 318 } 319 320 void CTxMemPool::removeRecursive(const CTransaction &origTx, MemPoolRemovalReason reason) 321 { 322 // Remove transaction from memory pool 323 AssertLockHeld(cs); 324 Assume(!m_have_changeset); 325 txiter origit = mapTx.find(origTx.GetHash()); 326 if (origit != mapTx.end()) { 327 removeRecursive(origit, reason); 328 } else { 329 // When recursively removing but origTx isn't in the mempool 330 // be sure to remove any descendants that are in the pool. This can 331 // happen during chain re-orgs if origTx isn't re-accepted into 332 // the mempool for any reason. 333 auto iter = mapNextTx.lower_bound(COutPoint(origTx.GetHash(), 0)); 334 std::vector<const TxGraph::Ref*> to_remove; 335 while (iter != mapNextTx.end() && iter->first->hash == origTx.GetHash()) { 336 to_remove.emplace_back(&*(iter->second)); 337 ++iter; 338 } 339 auto all_removes = m_txgraph->GetDescendantsUnion(to_remove, TxGraph::Level::MAIN); 340 for (auto ref : all_removes) { 341 auto tx = mapTx.iterator_to(static_cast<const CTxMemPoolEntry&>(*ref)); 342 removeUnchecked(tx, reason); 343 } 344 } 345 } 346 347 void CTxMemPool::removeForReorg(CChain& chain, std::function<bool(txiter)> check_final_and_mature) 348 { 349 // Remove transactions spending a coinbase which are now immature and no-longer-final transactions 350 AssertLockHeld(cs); 351 AssertLockHeld(::cs_main); 352 Assume(!m_have_changeset); 353 354 std::vector<const TxGraph::Ref*> to_remove; 355 for (txiter it = mapTx.begin(); it != mapTx.end(); it++) { 356 if (check_final_and_mature(it)) { 357 to_remove.emplace_back(&*it); 358 } 359 } 360 361 auto all_to_remove = m_txgraph->GetDescendantsUnion(to_remove, TxGraph::Level::MAIN); 362 363 for (auto ref : all_to_remove) { 364 auto it = mapTx.iterator_to(static_cast<const CTxMemPoolEntry&>(*ref)); 365 removeUnchecked(it, MemPoolRemovalReason::REORG); 366 } 367 for (indexed_transaction_set::const_iterator it = mapTx.begin(); it != mapTx.end(); it++) { 368 assert(TestLockPointValidity(chain, it->GetLockPoints())); 369 } 370 m_txgraph->DoWork(POST_CHANGE_WORK); 371 } 372 373 void CTxMemPool::removeConflicts(const CTransaction &tx) 374 { 375 // Remove transactions which depend on inputs of tx, recursively 376 AssertLockHeld(cs); 377 for (const CTxIn &txin : tx.vin) { 378 auto it = mapNextTx.find(txin.prevout); 379 if (it != mapNextTx.end()) { 380 const CTransaction &txConflict = it->second->GetTx(); 381 if (Assume(txConflict.GetHash() != tx.GetHash())) 382 { 383 ClearPrioritisation(txConflict.GetHash()); 384 removeRecursive(it->second, MemPoolRemovalReason::CONFLICT); 385 } 386 } 387 } 388 } 389 390 void CTxMemPool::removeForBlock(const std::vector<CTransactionRef>& vtx, unsigned int nBlockHeight) 391 { 392 // Remove confirmed txs and conflicts when a new block is connected, updating the fee logic 393 AssertLockHeld(cs); 394 Assume(!m_have_changeset); 395 std::vector<RemovedMempoolTransactionInfo> txs_removed_for_block; 396 if (mapTx.size() || mapNextTx.size() || mapDeltas.size()) { 397 txs_removed_for_block.reserve(vtx.size()); 398 for (const auto& tx : vtx) { 399 txiter it = mapTx.find(tx->GetHash()); 400 if (it != mapTx.end()) { 401 txs_removed_for_block.emplace_back(*it); 402 removeUnchecked(it, MemPoolRemovalReason::BLOCK); 403 } 404 removeConflicts(*tx); 405 ClearPrioritisation(tx->GetHash()); 406 } 407 } 408 if (m_opts.signals) { 409 m_opts.signals->MempoolTransactionsRemovedForBlock(txs_removed_for_block, nBlockHeight); 410 } 411 lastRollingFeeUpdate = GetTime(); 412 blockSinceLastRollingFeeBump = true; 413 m_txgraph->DoWork(POST_CHANGE_WORK); 414 } 415 416 void CTxMemPool::check(const CCoinsViewCache& active_coins_tip, int64_t spendheight) const 417 { 418 if (m_opts.check_ratio == 0) return; 419 420 if (FastRandomContext().randrange(m_opts.check_ratio) >= 1) return; 421 422 AssertLockHeld(::cs_main); 423 LOCK(cs); 424 LogDebug(BCLog::MEMPOOL, "Checking mempool with %u transactions and %u inputs\n", (unsigned int)mapTx.size(), (unsigned int)mapNextTx.size()); 425 426 uint64_t checkTotal = 0; 427 CAmount check_total_fee{0}; 428 CAmount check_total_modified_fee{0}; 429 int64_t check_total_adjusted_weight{0}; 430 uint64_t innerUsage = 0; 431 432 assert(!m_txgraph->IsOversized(TxGraph::Level::MAIN)); 433 m_txgraph->SanityCheck(); 434 435 CCoinsViewCache mempoolDuplicate(const_cast<CCoinsViewCache*>(&active_coins_tip)); 436 437 const auto score_with_topo{GetSortedScoreWithTopology()}; 438 439 // Number of chunks is bounded by number of transactions. 440 const auto diagram{GetFeerateDiagram()}; 441 assert(diagram.size() <= score_with_topo.size() + 1); 442 assert(diagram.size() >= 1); 443 444 std::optional<Wtxid> last_wtxid = std::nullopt; 445 auto diagram_iter = diagram.cbegin(); 446 447 for (const auto& it : score_with_topo) { 448 // GetSortedScoreWithTopology() contains the same chunks as the feerate 449 // diagram. We do not know where the chunk boundaries are, but we can 450 // check that there are points at which they match the cumulative fee 451 // and weight. 452 // The feerate diagram should never get behind the current transaction 453 // size totals. 454 assert(diagram_iter->size >= check_total_adjusted_weight); 455 if (diagram_iter->fee == check_total_modified_fee && 456 diagram_iter->size == check_total_adjusted_weight) { 457 ++diagram_iter; 458 } 459 checkTotal += it->GetTxSize(); 460 check_total_adjusted_weight += it->GetAdjustedWeight(); 461 check_total_fee += it->GetFee(); 462 check_total_modified_fee += it->GetModifiedFee(); 463 innerUsage += it->DynamicMemoryUsage(); 464 const CTransaction& tx = it->GetTx(); 465 466 // CompareMiningScoreWithTopology should agree with GetSortedScoreWithTopology() 467 if (last_wtxid) { 468 assert(CompareMiningScoreWithTopology(*last_wtxid, tx.GetWitnessHash())); 469 } 470 last_wtxid = tx.GetWitnessHash(); 471 472 std::set<CTxMemPoolEntry::CTxMemPoolEntryRef, CompareIteratorByHash> setParentCheck; 473 std::set<CTxMemPoolEntry::CTxMemPoolEntryRef, CompareIteratorByHash> setParentsStored; 474 for (const CTxIn &txin : tx.vin) { 475 // Check that every mempool transaction's inputs refer to available coins, or other mempool tx's. 476 indexed_transaction_set::const_iterator it2 = mapTx.find(txin.prevout.hash); 477 if (it2 != mapTx.end()) { 478 const CTransaction& tx2 = it2->GetTx(); 479 assert(tx2.vout.size() > txin.prevout.n && !tx2.vout[txin.prevout.n].IsNull()); 480 setParentCheck.insert(*it2); 481 } 482 // We are iterating through the mempool entries sorted 483 // topologically and by mining score. All parents must have been 484 // checked before their children and their coins added to the 485 // mempoolDuplicate coins cache. 486 assert(mempoolDuplicate.HaveCoin(txin.prevout)); 487 // Check whether its inputs are marked in mapNextTx. 488 auto it3 = mapNextTx.find(txin.prevout); 489 assert(it3 != mapNextTx.end()); 490 assert(it3->first == &txin.prevout); 491 assert(&it3->second->GetTx() == &tx); 492 } 493 auto comp = [](const CTxMemPoolEntry& a, const CTxMemPoolEntry& b) -> bool { 494 return a.GetTx().GetHash() == b.GetTx().GetHash(); 495 }; 496 for (auto &txentry : GetParents(*it)) { 497 setParentsStored.insert(dynamic_cast<const CTxMemPoolEntry&>(txentry.get())); 498 } 499 assert(setParentCheck.size() == setParentsStored.size()); 500 assert(std::equal(setParentCheck.begin(), setParentCheck.end(), setParentsStored.begin(), comp)); 501 502 // Check children against mapNextTx 503 std::set<CTxMemPoolEntry::CTxMemPoolEntryRef, CompareIteratorByHash> setChildrenCheck; 504 std::set<CTxMemPoolEntry::CTxMemPoolEntryRef, CompareIteratorByHash> setChildrenStored; 505 auto iter = mapNextTx.lower_bound(COutPoint(it->GetTx().GetHash(), 0)); 506 for (; iter != mapNextTx.end() && iter->first->hash == it->GetTx().GetHash(); ++iter) { 507 txiter childit = iter->second; 508 assert(childit != mapTx.end()); // mapNextTx points to in-mempool transactions 509 setChildrenCheck.insert(*childit); 510 } 511 for (auto &txentry : GetChildren(*it)) { 512 setChildrenStored.insert(dynamic_cast<const CTxMemPoolEntry&>(txentry.get())); 513 } 514 assert(setChildrenCheck.size() == setChildrenStored.size()); 515 assert(std::equal(setChildrenCheck.begin(), setChildrenCheck.end(), setChildrenStored.begin(), comp)); 516 517 TxValidationState dummy_state; // Not used. CheckTxInputs() should always pass 518 CAmount txfee = 0; 519 assert(!tx.IsCoinBase()); 520 assert(Consensus::CheckTxInputs(tx, dummy_state, mempoolDuplicate, spendheight, txfee)); 521 for (const auto& input: tx.vin) mempoolDuplicate.SpendCoin(input.prevout); 522 AddCoins(mempoolDuplicate, tx, std::numeric_limits<int>::max()); 523 } 524 for (auto it = mapNextTx.cbegin(); it != mapNextTx.cend(); it++) { 525 indexed_transaction_set::const_iterator it2 = it->second; 526 assert(it2 != mapTx.end()); 527 } 528 529 ++diagram_iter; 530 assert(diagram_iter == diagram.cend()); 531 532 assert(totalTxSize == checkTotal); 533 assert(m_total_fee == check_total_fee); 534 assert(diagram.back().fee == check_total_modified_fee); 535 assert(diagram.back().size == check_total_adjusted_weight); 536 assert(innerUsage == cachedInnerUsage); 537 } 538 539 bool CTxMemPool::CompareMiningScoreWithTopology(const Wtxid& hasha, const Wtxid& hashb) const 540 { 541 /* Return `true` if hasha should be considered sooner than hashb, namely when: 542 * a is not in the mempool but b is, or 543 * both are in the mempool but a is sorted before b in the total mempool ordering 544 * (which takes dependencies and (chunk) feerates into account). 545 */ 546 LOCK(cs); 547 auto j{GetIter(hashb)}; 548 if (!j.has_value()) return false; 549 auto i{GetIter(hasha)}; 550 if (!i.has_value()) return true; 551 552 return m_txgraph->CompareMainOrder(*i.value(), *j.value()) < 0; 553 } 554 555 std::vector<CTxMemPool::indexed_transaction_set::const_iterator> CTxMemPool::GetSortedScoreWithTopology() const 556 { 557 std::vector<indexed_transaction_set::const_iterator> iters; 558 AssertLockHeld(cs); 559 560 iters.reserve(mapTx.size()); 561 562 for (indexed_transaction_set::iterator mi = mapTx.begin(); mi != mapTx.end(); ++mi) { 563 iters.push_back(mi); 564 } 565 std::sort(iters.begin(), iters.end(), [this](const auto& a, const auto& b) EXCLUSIVE_LOCKS_REQUIRED(cs) noexcept { 566 return m_txgraph->CompareMainOrder(*a, *b) < 0; 567 }); 568 return iters; 569 } 570 571 std::vector<CTxMemPoolEntryRef> CTxMemPool::entryAll() const 572 { 573 AssertLockHeld(cs); 574 575 std::vector<CTxMemPoolEntryRef> ret; 576 ret.reserve(mapTx.size()); 577 for (const auto& it : GetSortedScoreWithTopology()) { 578 ret.emplace_back(*it); 579 } 580 return ret; 581 } 582 583 std::vector<TxMempoolInfo> CTxMemPool::infoAll() const 584 { 585 LOCK(cs); 586 auto iters = GetSortedScoreWithTopology(); 587 588 std::vector<TxMempoolInfo> ret; 589 ret.reserve(mapTx.size()); 590 for (auto it : iters) { 591 ret.push_back(GetInfo(it)); 592 } 593 594 return ret; 595 } 596 597 const CTxMemPoolEntry* CTxMemPool::GetEntry(const Txid& txid) const 598 { 599 AssertLockHeld(cs); 600 const auto i = mapTx.find(txid); 601 return i == mapTx.end() ? nullptr : &(*i); 602 } 603 604 CTransactionRef CTxMemPool::get(const Txid& hash) const 605 { 606 LOCK(cs); 607 indexed_transaction_set::const_iterator i = mapTx.find(hash); 608 if (i == mapTx.end()) 609 return nullptr; 610 return i->GetSharedTx(); 611 } 612 613 void CTxMemPool::PrioritiseTransaction(const Txid& hash, const CAmount& nFeeDelta) 614 { 615 { 616 LOCK(cs); 617 CAmount &delta = mapDeltas[hash]; 618 delta = SaturatingAdd(delta, nFeeDelta); 619 txiter it = mapTx.find(hash); 620 if (it != mapTx.end()) { 621 // PrioritiseTransaction calls stack on previous ones. Set the new 622 // transaction fee to be current modified fee + feedelta. 623 it->UpdateModifiedFee(nFeeDelta); 624 m_txgraph->SetTransactionFee(*it, it->GetModifiedFee()); 625 ++nTransactionsUpdated; 626 } 627 if (delta == 0) { 628 mapDeltas.erase(hash); 629 LogPrintf("PrioritiseTransaction: %s (%sin mempool) delta cleared\n", hash.ToString(), it == mapTx.end() ? "not " : ""); 630 } else { 631 LogPrintf("PrioritiseTransaction: %s (%sin mempool) fee += %s, new delta=%s\n", 632 hash.ToString(), 633 it == mapTx.end() ? "not " : "", 634 FormatMoney(nFeeDelta), 635 FormatMoney(delta)); 636 } 637 } 638 } 639 640 void CTxMemPool::ApplyDelta(const Txid& hash, CAmount &nFeeDelta) const 641 { 642 AssertLockHeld(cs); 643 std::map<Txid, CAmount>::const_iterator pos = mapDeltas.find(hash); 644 if (pos == mapDeltas.end()) 645 return; 646 const CAmount &delta = pos->second; 647 nFeeDelta += delta; 648 } 649 650 void CTxMemPool::ClearPrioritisation(const Txid& hash) 651 { 652 AssertLockHeld(cs); 653 mapDeltas.erase(hash); 654 } 655 656 std::vector<CTxMemPool::delta_info> CTxMemPool::GetPrioritisedTransactions() const 657 { 658 AssertLockNotHeld(cs); 659 LOCK(cs); 660 std::vector<delta_info> result; 661 result.reserve(mapDeltas.size()); 662 for (const auto& [txid, delta] : mapDeltas) { 663 const auto iter{mapTx.find(txid)}; 664 const bool in_mempool{iter != mapTx.end()}; 665 std::optional<CAmount> modified_fee; 666 if (in_mempool) modified_fee = iter->GetModifiedFee(); 667 result.emplace_back(delta_info{in_mempool, delta, modified_fee, txid}); 668 } 669 return result; 670 } 671 672 const CTransaction* CTxMemPool::GetConflictTx(const COutPoint& prevout) const 673 { 674 const auto it = mapNextTx.find(prevout); 675 return it == mapNextTx.end() ? nullptr : &(it->second->GetTx()); 676 } 677 678 std::optional<CTxMemPool::txiter> CTxMemPool::GetIter(const Txid& txid) const 679 { 680 AssertLockHeld(cs); 681 auto it = mapTx.find(txid); 682 return it != mapTx.end() ? std::make_optional(it) : std::nullopt; 683 } 684 685 std::optional<CTxMemPool::txiter> CTxMemPool::GetIter(const Wtxid& wtxid) const 686 { 687 AssertLockHeld(cs); 688 auto it{mapTx.project<0>(mapTx.get<index_by_wtxid>().find(wtxid))}; 689 return it != mapTx.end() ? std::make_optional(it) : std::nullopt; 690 } 691 692 CTxMemPool::setEntries CTxMemPool::GetIterSet(const std::set<Txid>& hashes) const 693 { 694 CTxMemPool::setEntries ret; 695 for (const auto& h : hashes) { 696 const auto mi = GetIter(h); 697 if (mi) ret.insert(*mi); 698 } 699 return ret; 700 } 701 702 std::vector<CTxMemPool::txiter> CTxMemPool::GetIterVec(const std::vector<Txid>& txids) const 703 { 704 AssertLockHeld(cs); 705 std::vector<txiter> ret; 706 ret.reserve(txids.size()); 707 for (const auto& txid : txids) { 708 const auto it{GetIter(txid)}; 709 if (!it) return {}; 710 ret.push_back(*it); 711 } 712 return ret; 713 } 714 715 bool CTxMemPool::HasNoInputsOf(const CTransaction &tx) const 716 { 717 for (unsigned int i = 0; i < tx.vin.size(); i++) 718 if (exists(tx.vin[i].prevout.hash)) 719 return false; 720 return true; 721 } 722 723 CCoinsViewMemPool::CCoinsViewMemPool(CCoinsView* baseIn, const CTxMemPool& mempoolIn) : CCoinsViewBacked(baseIn), mempool(mempoolIn) { } 724 725 std::optional<Coin> CCoinsViewMemPool::GetCoin(const COutPoint& outpoint) const 726 { 727 // Check to see if the inputs are made available by another tx in the package. 728 // These Coins would not be available in the underlying CoinsView. 729 if (auto it = m_temp_added.find(outpoint); it != m_temp_added.end()) { 730 return it->second; 731 } 732 733 // If an entry in the mempool exists, always return that one, as it's guaranteed to never 734 // conflict with the underlying cache, and it cannot have pruned entries (as it contains full) 735 // transactions. First checking the underlying cache risks returning a pruned entry instead. 736 CTransactionRef ptx = mempool.get(outpoint.hash); 737 if (ptx) { 738 if (outpoint.n < ptx->vout.size()) { 739 Coin coin(ptx->vout[outpoint.n], MEMPOOL_HEIGHT, false); 740 m_non_base_coins.emplace(outpoint); 741 return coin; 742 } 743 return std::nullopt; 744 } 745 return base->GetCoin(outpoint); 746 } 747 748 void CCoinsViewMemPool::PackageAddTransaction(const CTransactionRef& tx) 749 { 750 for (unsigned int n = 0; n < tx->vout.size(); ++n) { 751 m_temp_added.emplace(COutPoint(tx->GetHash(), n), Coin(tx->vout[n], MEMPOOL_HEIGHT, false)); 752 m_non_base_coins.emplace(tx->GetHash(), n); 753 } 754 } 755 void CCoinsViewMemPool::Reset() 756 { 757 m_temp_added.clear(); 758 m_non_base_coins.clear(); 759 } 760 761 size_t CTxMemPool::DynamicMemoryUsage() const { 762 LOCK(cs); 763 // Estimate the overhead of mapTx to be 9 pointers (3 pointers per index) + an allocation, as no exact formula for boost::multi_index_contained is implemented. 764 return memusage::MallocUsage(sizeof(CTxMemPoolEntry) + 9 * sizeof(void*)) * mapTx.size() + memusage::DynamicUsage(mapNextTx) + memusage::DynamicUsage(mapDeltas) + memusage::DynamicUsage(txns_randomized) + m_txgraph->GetMainMemoryUsage() + cachedInnerUsage; 765 } 766 767 void CTxMemPool::RemoveUnbroadcastTx(const Txid& txid, const bool unchecked) { 768 LOCK(cs); 769 770 if (m_unbroadcast_txids.erase(txid)) 771 { 772 LogDebug(BCLog::MEMPOOL, "Removed %i from set of unbroadcast txns%s\n", txid.GetHex(), (unchecked ? " before confirmation that txn was sent out" : "")); 773 } 774 } 775 776 void CTxMemPool::RemoveStaged(setEntries &stage, MemPoolRemovalReason reason) { 777 AssertLockHeld(cs); 778 for (txiter it : stage) { 779 removeUnchecked(it, reason); 780 } 781 } 782 783 bool CTxMemPool::CheckPolicyLimits(const CTransactionRef& tx) 784 { 785 LOCK(cs); 786 // Use ChangeSet interface to check whether the cluster count 787 // limits would be violated. Note that the changeset will be destroyed 788 // when it goes out of scope. 789 auto changeset = GetChangeSet(); 790 (void) changeset->StageAddition(tx, /*fee=*/0, /*time=*/0, /*entry_height=*/0, /*entry_sequence=*/0, /*spends_coinbase=*/false, /*sigops_cost=*/0, LockPoints{}); 791 return changeset->CheckMemPoolPolicyLimits(); 792 } 793 794 int CTxMemPool::Expire(std::chrono::seconds time) 795 { 796 AssertLockHeld(cs); 797 Assume(!m_have_changeset); 798 indexed_transaction_set::index<entry_time>::type::iterator it = mapTx.get<entry_time>().begin(); 799 setEntries toremove; 800 while (it != mapTx.get<entry_time>().end() && it->GetTime() < time) { 801 toremove.insert(mapTx.project<0>(it)); 802 it++; 803 } 804 setEntries stage; 805 for (txiter removeit : toremove) { 806 CalculateDescendants(removeit, stage); 807 } 808 RemoveStaged(stage, MemPoolRemovalReason::EXPIRY); 809 return stage.size(); 810 } 811 812 CFeeRate CTxMemPool::GetMinFee(size_t sizelimit) const { 813 LOCK(cs); 814 if (!blockSinceLastRollingFeeBump || rollingMinimumFeeRate == 0) 815 return CFeeRate(llround(rollingMinimumFeeRate)); 816 817 int64_t time = GetTime(); 818 if (time > lastRollingFeeUpdate + 10) { 819 double halflife = ROLLING_FEE_HALFLIFE; 820 if (DynamicMemoryUsage() < sizelimit / 4) 821 halflife /= 4; 822 else if (DynamicMemoryUsage() < sizelimit / 2) 823 halflife /= 2; 824 825 rollingMinimumFeeRate = rollingMinimumFeeRate / pow(2.0, (time - lastRollingFeeUpdate) / halflife); 826 lastRollingFeeUpdate = time; 827 828 if (rollingMinimumFeeRate < (double)m_opts.incremental_relay_feerate.GetFeePerK() / 2) { 829 rollingMinimumFeeRate = 0; 830 return CFeeRate(0); 831 } 832 } 833 return std::max(CFeeRate(llround(rollingMinimumFeeRate)), m_opts.incremental_relay_feerate); 834 } 835 836 void CTxMemPool::trackPackageRemoved(const CFeeRate& rate) { 837 AssertLockHeld(cs); 838 if (rate.GetFeePerK() > rollingMinimumFeeRate) { 839 rollingMinimumFeeRate = rate.GetFeePerK(); 840 blockSinceLastRollingFeeBump = false; 841 } 842 } 843 844 void CTxMemPool::TrimToSize(size_t sizelimit, std::vector<COutPoint>* pvNoSpendsRemaining) { 845 AssertLockHeld(cs); 846 Assume(!m_have_changeset); 847 848 unsigned nTxnRemoved = 0; 849 CFeeRate maxFeeRateRemoved(0); 850 851 while (!mapTx.empty() && DynamicMemoryUsage() > sizelimit) { 852 const auto &[worst_chunk, feeperweight] = m_txgraph->GetWorstMainChunk(); 853 FeePerVSize feerate = ToFeePerVSize(feeperweight); 854 CFeeRate removed{feerate.fee, feerate.size}; 855 856 // We set the new mempool min fee to the feerate of the removed set, plus the 857 // "minimum reasonable fee rate" (ie some value under which we consider txn 858 // to have 0 fee). This way, we don't allow txn to enter mempool with feerate 859 // equal to txn which were removed with no block in between. 860 removed += m_opts.incremental_relay_feerate; 861 trackPackageRemoved(removed); 862 maxFeeRateRemoved = std::max(maxFeeRateRemoved, removed); 863 864 nTxnRemoved += worst_chunk.size(); 865 866 std::vector<CTransaction> txn; 867 if (pvNoSpendsRemaining) { 868 txn.reserve(worst_chunk.size()); 869 for (auto ref : worst_chunk) { 870 txn.emplace_back(static_cast<const CTxMemPoolEntry&>(*ref).GetTx()); 871 } 872 } 873 874 setEntries stage; 875 for (auto ref : worst_chunk) { 876 stage.insert(mapTx.iterator_to(static_cast<const CTxMemPoolEntry&>(*ref))); 877 } 878 for (auto e : stage) { 879 removeUnchecked(e, MemPoolRemovalReason::SIZELIMIT); 880 } 881 if (pvNoSpendsRemaining) { 882 for (const CTransaction& tx : txn) { 883 for (const CTxIn& txin : tx.vin) { 884 if (exists(txin.prevout.hash)) continue; 885 pvNoSpendsRemaining->push_back(txin.prevout); 886 } 887 } 888 } 889 } 890 891 if (maxFeeRateRemoved > CFeeRate(0)) { 892 LogDebug(BCLog::MEMPOOL, "Removed %u txn, rolling minimum fee bumped to %s\n", nTxnRemoved, maxFeeRateRemoved.ToString()); 893 } 894 } 895 896 std::tuple<size_t, size_t, CAmount> CTxMemPool::CalculateAncestorData(const CTxMemPoolEntry& entry) const 897 { 898 auto ancestors = m_txgraph->GetAncestors(entry, TxGraph::Level::MAIN); 899 900 size_t ancestor_count = ancestors.size(); 901 size_t ancestor_size = 0; 902 CAmount ancestor_fees = 0; 903 for (auto tx: ancestors) { 904 const CTxMemPoolEntry& anc = static_cast<const CTxMemPoolEntry&>(*tx); 905 ancestor_size += anc.GetTxSize(); 906 ancestor_fees += anc.GetModifiedFee(); 907 } 908 return {ancestor_count, ancestor_size, ancestor_fees}; 909 } 910 911 std::tuple<size_t, size_t, CAmount> CTxMemPool::CalculateDescendantData(const CTxMemPoolEntry& entry) const 912 { 913 auto descendants = m_txgraph->GetDescendants(entry, TxGraph::Level::MAIN); 914 size_t descendant_count = descendants.size(); 915 size_t descendant_size = 0; 916 CAmount descendant_fees = 0; 917 918 for (auto tx: descendants) { 919 const CTxMemPoolEntry &desc = static_cast<const CTxMemPoolEntry&>(*tx); 920 descendant_size += desc.GetTxSize(); 921 descendant_fees += desc.GetModifiedFee(); 922 } 923 return {descendant_count, descendant_size, descendant_fees}; 924 } 925 926 void CTxMemPool::GetTransactionAncestry(const Txid& txid, size_t& ancestors, size_t& cluster_count, size_t* const ancestorsize, CAmount* const ancestorfees) const { 927 LOCK(cs); 928 auto it = mapTx.find(txid); 929 ancestors = cluster_count = 0; 930 if (it != mapTx.end()) { 931 auto [ancestor_count, ancestor_size, ancestor_fees] = CalculateAncestorData(*it); 932 ancestors = ancestor_count; 933 if (ancestorsize) *ancestorsize = ancestor_size; 934 if (ancestorfees) *ancestorfees = ancestor_fees; 935 cluster_count = m_txgraph->GetCluster(*it, TxGraph::Level::MAIN).size(); 936 } 937 } 938 939 bool CTxMemPool::GetLoadTried() const 940 { 941 LOCK(cs); 942 return m_load_tried; 943 } 944 945 void CTxMemPool::SetLoadTried(bool load_tried) 946 { 947 LOCK(cs); 948 m_load_tried = load_tried; 949 } 950 951 std::vector<CTxMemPool::txiter> CTxMemPool::GatherClusters(const std::vector<Txid>& txids) const 952 { 953 AssertLockHeld(cs); 954 955 std::vector<CTxMemPool::txiter> ret; 956 std::set<const CTxMemPoolEntry*> unique_cluster_representatives; 957 for (auto txid : txids) { 958 auto it = mapTx.find(txid); 959 if (it != mapTx.end()) { 960 // Note that TxGraph::GetCluster will return results in graph 961 // order, which is deterministic (as long as we are not modifying 962 // the graph). 963 auto cluster = m_txgraph->GetCluster(*it, TxGraph::Level::MAIN); 964 if (unique_cluster_representatives.insert(static_cast<const CTxMemPoolEntry*>(&(**cluster.begin()))).second) { 965 for (auto tx : cluster) { 966 ret.emplace_back(mapTx.iterator_to(static_cast<const CTxMemPoolEntry&>(*tx))); 967 } 968 } 969 } 970 } 971 if (ret.size() > 500) { 972 return {}; 973 } 974 return ret; 975 } 976 977 util::Result<std::pair<std::vector<FeeFrac>, std::vector<FeeFrac>>> CTxMemPool::ChangeSet::CalculateChunksForRBF() 978 { 979 LOCK(m_pool->cs); 980 981 if (!CheckMemPoolPolicyLimits()) { 982 return util::Error{Untranslated("cluster size limit exceeded")}; 983 } 984 985 return m_pool->m_txgraph->GetMainStagingDiagrams(); 986 } 987 988 CTxMemPool::ChangeSet::TxHandle CTxMemPool::ChangeSet::StageAddition(const CTransactionRef& tx, const CAmount fee, int64_t time, unsigned int entry_height, uint64_t entry_sequence, bool spends_coinbase, int64_t sigops_cost, LockPoints lp) 989 { 990 LOCK(m_pool->cs); 991 Assume(m_to_add.find(tx->GetHash()) == m_to_add.end()); 992 Assume(!m_dependencies_processed); 993 994 // We need to process dependencies after adding a new transaction. 995 m_dependencies_processed = false; 996 997 CAmount delta{0}; 998 m_pool->ApplyDelta(tx->GetHash(), delta); 999 1000 TxGraph::Ref ref(m_pool->m_txgraph->AddTransaction(FeePerWeight(fee, GetSigOpsAdjustedWeight(GetTransactionWeight(*tx), sigops_cost, ::nBytesPerSigOp)))); 1001 auto newit = m_to_add.emplace(std::move(ref), tx, fee, time, entry_height, entry_sequence, spends_coinbase, sigops_cost, lp).first; 1002 if (delta) { 1003 newit->UpdateModifiedFee(delta); 1004 m_pool->m_txgraph->SetTransactionFee(*newit, newit->GetModifiedFee()); 1005 } 1006 1007 m_entry_vec.push_back(newit); 1008 1009 return newit; 1010 } 1011 1012 void CTxMemPool::ChangeSet::StageRemoval(CTxMemPool::txiter it) 1013 { 1014 LOCK(m_pool->cs); 1015 m_pool->m_txgraph->RemoveTransaction(*it); 1016 m_to_remove.insert(it); 1017 } 1018 1019 void CTxMemPool::ChangeSet::Apply() 1020 { 1021 LOCK(m_pool->cs); 1022 if (!m_dependencies_processed) { 1023 ProcessDependencies(); 1024 } 1025 m_pool->Apply(this); 1026 m_to_add.clear(); 1027 m_to_remove.clear(); 1028 m_entry_vec.clear(); 1029 m_ancestors.clear(); 1030 } 1031 1032 void CTxMemPool::ChangeSet::ProcessDependencies() 1033 { 1034 LOCK(m_pool->cs); 1035 Assume(!m_dependencies_processed); // should only call this once. 1036 for (const auto& entryptr : m_entry_vec) { 1037 for (const auto &txin : entryptr->GetSharedTx()->vin) { 1038 std::optional<txiter> piter = m_pool->GetIter(txin.prevout.hash); 1039 if (!piter) { 1040 auto it = m_to_add.find(txin.prevout.hash); 1041 if (it != m_to_add.end()) { 1042 piter = std::make_optional(it); 1043 } 1044 } 1045 if (piter) { 1046 m_pool->m_txgraph->AddDependency(/*parent=*/**piter, /*child=*/*entryptr); 1047 } 1048 } 1049 } 1050 m_dependencies_processed = true; 1051 return; 1052 } 1053 1054 bool CTxMemPool::ChangeSet::CheckMemPoolPolicyLimits() 1055 { 1056 LOCK(m_pool->cs); 1057 if (!m_dependencies_processed) { 1058 ProcessDependencies(); 1059 } 1060 1061 return !m_pool->m_txgraph->IsOversized(TxGraph::Level::TOP); 1062 } 1063 1064 std::vector<FeePerWeight> CTxMemPool::GetFeerateDiagram() const 1065 { 1066 FeePerWeight zero{}; 1067 std::vector<FeePerWeight> ret; 1068 1069 ret.emplace_back(zero); 1070 1071 StartBlockBuilding(); 1072 1073 std::vector<CTxMemPoolEntry::CTxMemPoolEntryRef> dummy; 1074 1075 FeePerWeight last_selection = GetBlockBuilderChunk(dummy); 1076 while (last_selection != FeePerWeight{}) { 1077 last_selection += ret.back(); 1078 ret.emplace_back(last_selection); 1079 IncludeBuilderChunk(); 1080 last_selection = GetBlockBuilderChunk(dummy); 1081 } 1082 StopBlockBuilding(); 1083 return ret; 1084 }