| 530 | } |
| 531 | |
| 532 | std::vector<std::pair<Wtxid, NodeId>> TxOrphanageImpl::AddChildrenToWorkSet(const CTransaction& tx, FastRandomContext& rng) |
| 533 | { |
| 534 | std::vector<std::pair<Wtxid, NodeId>> ret; |
| 535 | auto& index_by_wtxid = m_orphans.get<ByWtxid>(); |
| 536 | for (unsigned int i = 0; i < tx.vout.size(); i++) { |
| 537 | const auto it_by_prev = m_outpoint_to_orphan_wtxids.find(COutPoint(tx.GetHash(), i)); |
| 538 | if (it_by_prev != m_outpoint_to_orphan_wtxids.end()) { |
| 539 | for (const auto& wtxid : it_by_prev->second) { |
| 540 | // If a reconsiderable announcement for this wtxid already exists, skip it. |
| 541 | if (m_reconsiderable_wtxids.contains(wtxid)) continue; |
| 542 | |
| 543 | // Belt and suspenders, each entry in m_outpoint_to_orphan_wtxids should always have at least 1 announcement. |
| 544 | auto it = index_by_wtxid.lower_bound(ByWtxidView{wtxid, MIN_PEER}); |
| 545 | if (!Assume(it != index_by_wtxid.end() && it->m_tx->GetWitnessHash() == wtxid)) continue; |
| 546 | |
| 547 | // Select a random peer to assign orphan processing, reducing wasted work if the orphan is still missing |
| 548 | // inputs. However, we don't want to create an issue in which the assigned peer can purposefully stop us |
| 549 | // from processing the orphan by disconnecting. |
| 550 | auto it_end = index_by_wtxid.upper_bound(ByWtxidView{wtxid, MAX_PEER}); |
| 551 | const auto num_announcers{std::distance(it, it_end)}; |
| 552 | if (!Assume(num_announcers > 0)) continue; |
| 553 | std::advance(it, rng.randrange(num_announcers)); |
| 554 | |
| 555 | if (!Assume(it->m_tx->GetWitnessHash() == wtxid)) break; |
| 556 | |
| 557 | // Mark this orphan as ready to be reconsidered. |
| 558 | static constexpr auto mark_reconsidered_modifier = [](auto& ann) { ann.m_reconsider = true; }; |
| 559 | Assume(!it->m_reconsider); |
| 560 | index_by_wtxid.modify(it, mark_reconsidered_modifier); |
| 561 | ret.emplace_back(wtxid, it->m_announcer); |
| 562 | m_reconsiderable_wtxids.insert(wtxid); |
| 563 | |
| 564 | LogDebug(BCLog::TXPACKAGES, "added %s (wtxid=%s) to peer %d workset\n", |
| 565 | it->m_tx->GetHash().ToString(), it->m_tx->GetWitnessHash().ToString(), it->m_announcer); |
| 566 | } |
| 567 | } |
| 568 | } |
| 569 | return ret; |
| 570 | } |
| 571 | |
| 572 | bool TxOrphanageImpl::HaveTx(const Wtxid& wtxid) const |
| 573 | { |