Merge bitcoin/bitcoin#35986: p2p: reconsider orphans when missing inputs are mined

9cc7dc50bd p2p: reconsider orphans when missing inputs are mined (Greg Sanders)

Pull request description:

  We reconsider for mempool entry of missing inputs, we should reconsider for mining of them too.

ACKs for top commit:
  yuvicc:
    ACK 9cc7dc50bd
  l0rinc:
    Lightly tested code review ACK 9cc7dc50bd
  marcofleon:
    ACK 9cc7dc50bd

Tree-SHA512: 9acfb6898e3b286ce23bc2ca3369ae951fadee5f175baad634a6bd23039108d97283814e47972fb857ae459505535f621866f2514b705e94cf841979c37a3933
This commit is contained in:
merge-script
2026-08-18 11:48:20 +01:00
3 changed files with 31 additions and 0 deletions

View File

@@ -100,6 +100,9 @@ void TxDownloadManagerImpl::BlockConnected(const std::shared_ptr<const CBlock>&
m_orphanage->EraseForBlock(*pblock);
for (const auto& ptx : pblock->vtx) {
// Reconsider potential child transactions.
m_orphanage->AddChildrenToWorkSet(*ptx, m_opts.m_rng);
RecentConfirmedTransactionsFilter().insert(ptx->GetHash().ToUint256());
if (ptx->HasWitness()) {
RecentConfirmedTransactionsFilter().insert(ptx->GetWitnessHash().ToUint256());

View File

@@ -531,6 +531,8 @@ void TxOrphanageImpl::LimitOrphans()
std::vector<std::pair<Wtxid, NodeId>> TxOrphanageImpl::AddChildrenToWorkSet(const CTransaction& tx, FastRandomContext& rng)
{
if (m_orphans.empty()) return {};
std::vector<std::pair<Wtxid, NodeId>> ret;
auto& index_by_wtxid = m_orphans.get<ByWtxid>();
for (unsigned int i = 0; i < tx.vout.size(); i++) {

View File

@@ -383,6 +383,31 @@ class OrphanHandlingTest(BitcoinTestFramework):
assert tx_in_orphanage(node, orphan["tx"])
peer.wait_for_parent_requests([int(missing_parent["txid"], 16)])
@cleanup
def test_orphan_parent_confirmed(self):
node = self.nodes[0]
peer = node.add_p2p_connection(PeerTxRelayer())
parent = self.wallet.create_self_transfer(fee_rate=0)
child = self.wallet.create_self_transfer(utxo_to_spend=parent["new_utxo"])
self.log.info("Test orphan reconsideration when its missing parent is confirmed")
self.relay_transaction(peer, child["tx"])
assert tx_in_orphanage(node, child["tx"])
# Withhold the requested parent so it can only become available through the block.
node.bumpmocktime(TXREQUEST_TIME_SKIP)
peer.wait_for_parent_requests([parent["tx"].txid_int])
assert_equal(node.getrawmempool(), [])
self.generateblock(
node,
output=self.wallet.get_address(),
transactions=[parent["hex"]],
)
self.wait_until(lambda: child["txid"] in node.getrawmempool())
assert not tx_in_orphanage(node, child["tx"])
@cleanup
def test_orphan_inherit_rejection(self):
node = self.nodes[0]
@@ -826,6 +851,7 @@ class OrphanHandlingTest(BitcoinTestFramework):
self.test_orphan_multiple_parents()
self.test_orphans_overlapping_parents()
self.test_orphan_of_orphan()
self.test_orphan_parent_confirmed()
self.test_orphan_inherit_rejection()
self.test_same_txid_orphan()
self.test_same_txid_orphan_of_orphan()