@@ -573,7 +573,7 @@ class PeerManagerImpl final : public PeerManager
573
573
NodeId parent_sender,
574
574
NodeId child_sender) :
575
575
m_txns{parent, child},
576
- m_senders {parent_sender, child_sender}
576
+ m_senders{parent_sender, child_sender}
577
577
{}
578
578
579
579
// Move ctor
@@ -3033,6 +3033,11 @@ std::optional<PeerManagerImpl::PackageToValidate> PeerManagerImpl::ProcessInvali
3033
3033
ptx->GetWitnessHash ().ToString (),
3034
3034
nodeid,
3035
3035
state.ToString ());
3036
+
3037
+ // Whether we should call AddToCompactExtraTransactions at the end
3038
+ bool add_extra_compact_tx{first_time_failure};
3039
+ // Hashes to pass to AddKnownTx later
3040
+ std::vector<uint256> unique_parents;
3036
3041
// Populated if failure is reconsiderable and eligible package is found.
3037
3042
std::optional<PackageToValidate> package_to_validate;
3038
3043
@@ -3044,7 +3049,6 @@ std::optional<PeerManagerImpl::PackageToValidate> PeerManagerImpl::ProcessInvali
3044
3049
3045
3050
// Deduplicate parent txids, so that we don't have to loop over
3046
3051
// the same parent txid more than once down below.
3047
- std::vector<uint256> unique_parents;
3048
3052
unique_parents.reserve (tx.vin .size ());
3049
3053
for (const CTxIn& txin : tx.vin ) {
3050
3054
// We start with all parents, and then remove duplicates below.
@@ -3081,17 +3085,15 @@ std::optional<PeerManagerImpl::PackageToValidate> PeerManagerImpl::ProcessInvali
3081
3085
// Eventually we should replace this with an improved
3082
3086
// protocol for getting all unconfirmed parents.
3083
3087
const auto gtxid{GenTxid::Txid (parent_txid)};
3084
- if (peer) AddKnownTx (*peer, parent_txid);
3085
3088
// Exclude m_lazy_recent_rejects_reconsiderable: the missing parent may have been
3086
3089
// previously rejected for being too low feerate. This orphan might CPFP it.
3087
3090
if (!m_txdownloadman.AlreadyHaveTx (gtxid, /* include_reconsiderable=*/ false )) {
3088
3091
m_txdownloadman.AddTxAnnouncement (nodeid, gtxid, current_time, /* p2p_inv=*/ false );
3089
3092
}
3090
3093
}
3091
3094
3092
- if (m_orphanage.AddTx (ptx, nodeid) && RecursiveDynamicUsage (*ptx) < 100000 ) {
3093
- AddToCompactExtraTransactions (ptx);
3094
- }
3095
+ // Potentially flip add_extra_compact_tx to false if AddTx returns false because the tx was already there
3096
+ add_extra_compact_tx &= m_orphanage.AddTx (ptx, nodeid);
3095
3097
3096
3098
// Once added to the orphan pool, a tx is considered AlreadyHave, and we shouldn't request it anymore.
3097
3099
m_txrequest.ForgetTxHash (tx.GetHash ());
@@ -3100,6 +3102,7 @@ std::optional<PeerManagerImpl::PackageToValidate> PeerManagerImpl::ProcessInvali
3100
3102
// DoS prevention: do not allow m_orphanage to grow unbounded (see CVE-2012-3789)
3101
3103
m_orphanage.LimitOrphans (m_opts.max_orphan_txs , m_rng);
3102
3104
} else {
3105
+ unique_parents.clear ();
3103
3106
LogDebug (BCLog::MEMPOOL, " not keeping orphan with rejected parents %s (wtxid=%s)\n " ,
3104
3107
tx.GetHash ().ToString (),
3105
3108
tx.GetWitnessHash ().ToString ());
@@ -3115,8 +3118,9 @@ std::optional<PeerManagerImpl::PackageToValidate> PeerManagerImpl::ProcessInvali
3115
3118
m_txrequest.ForgetTxHash (tx.GetWitnessHash ());
3116
3119
}
3117
3120
}
3118
- return std::nullopt;
3119
- } else if (state.GetResult () != TxValidationResult::TX_WITNESS_STRIPPED) {
3121
+ } else if (state.GetResult () == TxValidationResult::TX_WITNESS_STRIPPED) {
3122
+ add_extra_compact_tx = false ;
3123
+ } else {
3120
3124
// We can add the wtxid of this transaction to our reject filter.
3121
3125
// Do not add txids of witness transactions or witness-stripped
3122
3126
// transactions to the filter, as they can have been malleated;
@@ -3161,16 +3165,19 @@ std::optional<PeerManagerImpl::PackageToValidate> PeerManagerImpl::ProcessInvali
3161
3165
RecentRejectsFilter ().insert (ptx->GetHash ().ToUint256 ());
3162
3166
m_txrequest.ForgetTxHash (ptx->GetHash ());
3163
3167
}
3164
- if (first_time_failure && RecursiveDynamicUsage (*ptx) < 100000 ) {
3165
- AddToCompactExtraTransactions (ptx);
3166
- }
3168
+ }
3169
+ if (add_extra_compact_tx && RecursiveDynamicUsage (*ptx) < 100000 ) {
3170
+ AddToCompactExtraTransactions (ptx);
3171
+ }
3172
+ for (const uint256& parent_txid : unique_parents) {
3173
+ if (peer) AddKnownTx (*peer, parent_txid);
3167
3174
}
3168
3175
3169
3176
MaybePunishNodeForTx (nodeid, state);
3170
3177
3171
3178
// If the tx failed in ProcessOrphanTx, it should be removed from the orphanage unless the
3172
3179
// tx was still missing inputs. If the tx was not in the orphanage, EraseTx does nothing and returns 0.
3173
- if (Assume ( state.GetResult () != TxValidationResult::TX_MISSING_INPUTS) && m_orphanage.EraseTx (ptx->GetWitnessHash ()) > 0 ) {
3180
+ if (state.GetResult () != TxValidationResult::TX_MISSING_INPUTS && m_orphanage.EraseTx (ptx->GetWitnessHash ()) > 0 ) {
3174
3181
LogDebug (BCLog::TXPACKAGES, " removed orphan tx %s (wtxid=%s)\n " , ptx->GetHash ().ToString (), ptx->GetWitnessHash ().ToString ());
3175
3182
}
3176
3183
0 commit comments