* Reconsider orphan transactions after a parent has been accepted to the mempool. * * @param[in,out] orphan_work_set The set of orphan transactions to reconsider. Generally only one * orphan will be reconsidered on each call of this function. This set * may be added to if accepting an orphan causes its children to be *
| 2328 | * reconsidered. |
| 2329 | */ |
| 2330 | void PeerManagerImpl::ProcessOrphanTx(std::set<uint256>& orphan_work_set) |
| 2331 | { |
| 2332 | AssertLockHeld(cs_main); |
| 2333 | AssertLockHeld(g_cs_orphans); |
| 2334 | |
| 2335 | while (!orphan_work_set.empty()) { |
| 2336 | const uint256 orphanHash = *orphan_work_set.begin(); |
| 2337 | orphan_work_set.erase(orphan_work_set.begin()); |
| 2338 | |
| 2339 | const auto [porphanTx, from_peer] = m_orphanage.GetTx(orphanHash); |
| 2340 | if (porphanTx == nullptr) continue; |
| 2341 | |
| 2342 | const MempoolAcceptResult result = m_chainman.ProcessTransaction(porphanTx); |
| 2343 | const TxValidationState& state = result.m_state; |
| 2344 | |
| 2345 | if (result.m_result_type == MempoolAcceptResult::ResultType::VALID) { |
| 2346 | LogPrint(BCLog::MEMPOOL, " accepted orphan tx %s\n", orphanHash.ToString()); |
| 2347 | _RelayTransaction(orphanHash, porphanTx->GetWitnessHash()); |
| 2348 | m_orphanage.AddChildrenToWorkSet(*porphanTx, orphan_work_set); |
| 2349 | m_orphanage.EraseTx(orphanHash); |
| 2350 | for (const CTransactionRef& removedTx : result.m_replaced_transactions.value()) { |
| 2351 | AddToCompactExtraTransactions(removedTx); |
| 2352 | } |
| 2353 | break; |
| 2354 | } else if (state.GetResult() != TxValidationResult::TX_MISSING_INPUTS) { |
| 2355 | if (state.IsInvalid()) { |
| 2356 | LogPrint(BCLog::MEMPOOL, " invalid orphan tx %s from peer=%d. %s\n", |
| 2357 | orphanHash.ToString(), |
| 2358 | from_peer, |
| 2359 | state.ToString()); |
| 2360 | } |
| 2361 | // Has inputs but not accepted to mempool |
| 2362 | // Probably non-standard or insufficient fee |
| 2363 | LogPrint(BCLog::MEMPOOL, " removed orphan tx %s\n", orphanHash.ToString()); |
| 2364 | if (state.GetResult() != TxValidationResult::TX_WITNESS_STRIPPED) { |
| 2365 | // We can add the wtxid of this transaction to our reject filter. |
| 2366 | // Do not add txids of witness transactions or witness-stripped |
| 2367 | // transactions to the filter, as they can have been malleated; |
| 2368 | // adding such txids to the reject filter would potentially |
| 2369 | // interfere with relay of valid transactions from peers that |
| 2370 | // do not support wtxid-based relay. See |
| 2371 | // https://github.com/bitcoin/bitcoin/issues/8279 for details. |
| 2372 | // We can remove this restriction (and always add wtxids to |
| 2373 | // the filter even for witness stripped transactions) once |
| 2374 | // wtxid-based relay is broadly deployed. |
| 2375 | // See also comments in https://github.com/bitcoin/bitcoin/pull/18044#discussion_r443419034 |
| 2376 | // for concerns around weakening security of unupgraded nodes |
| 2377 | // if we start doing this too early. |
| 2378 | m_recent_rejects.insert(porphanTx->GetWitnessHash()); |
| 2379 | // If the transaction failed for TX_INPUTS_NOT_STANDARD, |
| 2380 | // then we know that the witness was irrelevant to the policy |
| 2381 | // failure, since this check depends only on the txid |
| 2382 | // (the scriptPubKey being spent is covered by the txid). |
| 2383 | // Add the txid to the reject filter to prevent repeated |
| 2384 | // processing of this transaction in the event that child |
| 2385 | // transactions are later received (resulting in |
| 2386 | // parent-fetching by txid via the orphan-handling logic). |
| 2387 | if (state.GetResult() == TxValidationResult::TX_INPUTS_NOT_STANDARD && porphanTx->GetWitnessHash() != porphanTx->GetHash()) { |
nothing calls this directly
no test coverage detected