@@ -808,12 +808,6 @@ class PeerManagerImpl final : public PeerManager
808
808
/* * Stalling timeout for blocks in IBD */
809
809
std::atomic<std::chrono::seconds> m_block_stalling_timeout{BLOCK_STALLING_TIMEOUT_DEFAULT};
810
810
811
- CRollingBloomFilter& RecentRejectsFilter () EXCLUSIVE_LOCKS_REQUIRED(m_tx_download_mutex)
812
- {
813
- AssertLockHeld (m_tx_download_mutex);
814
- return m_txdownloadman.RecentRejectsFilter ();
815
- }
816
-
817
811
CRollingBloomFilter& RecentRejectsReconsiderableFilter () EXCLUSIVE_LOCKS_REQUIRED(m_tx_download_mutex)
818
812
{
819
813
AssertLockHeld (m_tx_download_mutex);
@@ -1906,7 +1900,7 @@ PeerManagerImpl::PeerManagerImpl(CConnman& connman, AddrMan& addrman,
1906
1900
m_banman(banman),
1907
1901
m_chainman(chainman),
1908
1902
m_mempool(pool),
1909
- m_txdownloadman(node::TxDownloadOptions{pool, m_rng}),
1903
+ m_txdownloadman(node::TxDownloadOptions{pool, m_rng, opts. max_orphan_txs }),
1910
1904
m_warnings{warnings},
1911
1905
m_opts{opts}
1912
1906
{
@@ -2984,148 +2978,14 @@ std::optional<node::PackageToValidate> PeerManagerImpl::ProcessInvalidTx(NodeId
2984
2978
2985
2979
PeerRef peer{GetPeerRef (nodeid)};
2986
2980
2987
- auto & m_orphanage = m_txdownloadman.GetOrphanageRef ();
2988
- auto & m_txrequest = m_txdownloadman.GetTxRequestRef ();
2989
- const CTransaction& tx{*ptx};
2990
-
2991
2981
LogDebug (BCLog::MEMPOOLREJ, " %s (wtxid=%s) from peer=%d was not accepted: %s\n " ,
2992
2982
ptx->GetHash ().ToString (),
2993
2983
ptx->GetWitnessHash ().ToString (),
2994
2984
nodeid,
2995
2985
state.ToString ());
2996
2986
2997
- // Whether we should call AddToCompactExtraTransactions at the end
2998
- bool add_extra_compact_tx{first_time_failure};
2999
- // Hashes to pass to AddKnownTx later
3000
- std::vector<uint256> unique_parents;
3001
- // Populated if failure is reconsiderable and eligible package is found.
3002
- std::optional<node::PackageToValidate> package_to_validate;
3003
-
3004
- if (state.GetResult () == TxValidationResult::TX_MISSING_INPUTS) {
3005
- // Only process a new orphan if this is a first time failure, as otherwise it must be either
3006
- // already in orphanage or from 1p1c processing.
3007
- if (first_time_failure) {
3008
- bool fRejectedParents = false ; // It may be the case that the orphans parents have all been rejected
3009
-
3010
- // Deduplicate parent txids, so that we don't have to loop over
3011
- // the same parent txid more than once down below.
3012
- unique_parents.reserve (tx.vin .size ());
3013
- for (const CTxIn& txin : tx.vin ) {
3014
- // We start with all parents, and then remove duplicates below.
3015
- unique_parents.push_back (txin.prevout .hash );
3016
- }
3017
- std::sort (unique_parents.begin (), unique_parents.end ());
3018
- unique_parents.erase (std::unique (unique_parents.begin (), unique_parents.end ()), unique_parents.end ());
3019
-
3020
- // Distinguish between parents in m_lazy_recent_rejects and m_lazy_recent_rejects_reconsiderable.
3021
- // We can tolerate having up to 1 parent in m_lazy_recent_rejects_reconsiderable since we
3022
- // submit 1p1c packages. However, fail immediately if any are in m_lazy_recent_rejects.
3023
- std::optional<uint256> rejected_parent_reconsiderable;
3024
- for (const uint256& parent_txid : unique_parents) {
3025
- if (RecentRejectsFilter ().contains (parent_txid)) {
3026
- fRejectedParents = true ;
3027
- break ;
3028
- } else if (RecentRejectsReconsiderableFilter ().contains (parent_txid) && !m_mempool.exists (GenTxid::Txid (parent_txid))) {
3029
- // More than 1 parent in m_lazy_recent_rejects_reconsiderable: 1p1c will not be
3030
- // sufficient to accept this package, so just give up here.
3031
- if (rejected_parent_reconsiderable.has_value ()) {
3032
- fRejectedParents = true ;
3033
- break ;
3034
- }
3035
- rejected_parent_reconsiderable = parent_txid;
3036
- }
3037
- }
3038
- if (!fRejectedParents ) {
3039
- const auto current_time{GetTime<std::chrono::microseconds>()};
3040
-
3041
- for (const uint256& parent_txid : unique_parents) {
3042
- // Here, we only have the txid (and not wtxid) of the
3043
- // inputs, so we only request in txid mode, even for
3044
- // wtxidrelay peers.
3045
- // Eventually we should replace this with an improved
3046
- // protocol for getting all unconfirmed parents.
3047
- const auto gtxid{GenTxid::Txid (parent_txid)};
3048
- // Exclude m_lazy_recent_rejects_reconsiderable: the missing parent may have been
3049
- // previously rejected for being too low feerate. This orphan might CPFP it.
3050
- if (!m_txdownloadman.AlreadyHaveTx (gtxid, /* include_reconsiderable=*/ false )) {
3051
- m_txdownloadman.AddTxAnnouncement (nodeid, gtxid, current_time, /* p2p_inv=*/ false );
3052
- }
3053
- }
2987
+ const auto & [add_extra_compact_tx, unique_parents, package_to_validate] = m_txdownloadman.MempoolRejectedTx (ptx, state, nodeid, first_time_failure);
3054
2988
3055
- // Potentially flip add_extra_compact_tx to false if AddTx returns false because the tx was already there
3056
- add_extra_compact_tx &= m_orphanage.AddTx (ptx, nodeid);
3057
-
3058
- // Once added to the orphan pool, a tx is considered AlreadyHave, and we shouldn't request it anymore.
3059
- m_txrequest.ForgetTxHash (tx.GetHash ());
3060
- m_txrequest.ForgetTxHash (tx.GetWitnessHash ());
3061
-
3062
- // DoS prevention: do not allow m_orphanage to grow unbounded (see CVE-2012-3789)
3063
- m_orphanage.LimitOrphans (m_opts.max_orphan_txs , m_rng);
3064
- } else {
3065
- unique_parents.clear ();
3066
- LogDebug (BCLog::MEMPOOL, " not keeping orphan with rejected parents %s (wtxid=%s)\n " ,
3067
- tx.GetHash ().ToString (),
3068
- tx.GetWitnessHash ().ToString ());
3069
- // We will continue to reject this tx since it has rejected
3070
- // parents so avoid re-requesting it from other peers.
3071
- // Here we add both the txid and the wtxid, as we know that
3072
- // regardless of what witness is provided, we will not accept
3073
- // this, so we don't need to allow for redownload of this txid
3074
- // from any of our non-wtxidrelay peers.
3075
- RecentRejectsFilter ().insert (tx.GetHash ().ToUint256 ());
3076
- RecentRejectsFilter ().insert (tx.GetWitnessHash ().ToUint256 ());
3077
- m_txrequest.ForgetTxHash (tx.GetHash ());
3078
- m_txrequest.ForgetTxHash (tx.GetWitnessHash ());
3079
- }
3080
- }
3081
- } else if (state.GetResult () == TxValidationResult::TX_WITNESS_STRIPPED) {
3082
- add_extra_compact_tx = false ;
3083
- } else {
3084
- // We can add the wtxid of this transaction to our reject filter.
3085
- // Do not add txids of witness transactions or witness-stripped
3086
- // transactions to the filter, as they can have been malleated;
3087
- // adding such txids to the reject filter would potentially
3088
- // interfere with relay of valid transactions from peers that
3089
- // do not support wtxid-based relay. See
3090
- // https://github.com/bitcoin/bitcoin/issues/8279 for details.
3091
- // We can remove this restriction (and always add wtxids to
3092
- // the filter even for witness stripped transactions) once
3093
- // wtxid-based relay is broadly deployed.
3094
- // See also comments in https://github.com/bitcoin/bitcoin/pull/18044#discussion_r443419034
3095
- // for concerns around weakening security of unupgraded nodes
3096
- // if we start doing this too early.
3097
- if (state.GetResult () == TxValidationResult::TX_RECONSIDERABLE) {
3098
- // If the result is TX_RECONSIDERABLE, add it to m_lazy_recent_rejects_reconsiderable
3099
- // because we should not download or submit this transaction by itself again, but may
3100
- // submit it as part of a package later.
3101
- RecentRejectsReconsiderableFilter ().insert (ptx->GetWitnessHash ().ToUint256 ());
3102
-
3103
- if (first_time_failure) {
3104
- // When a transaction fails for TX_RECONSIDERABLE, look for a matching child in the
3105
- // orphanage, as it is possible that they succeed as a package.
3106
- LogDebug (BCLog::TXPACKAGES, " tx %s (wtxid=%s) failed but reconsiderable, looking for child in orphanage\n " ,
3107
- ptx->GetHash ().ToString (), ptx->GetWitnessHash ().ToString ());
3108
- package_to_validate = m_txdownloadman.Find1P1CPackage (ptx, nodeid);
3109
- }
3110
- } else {
3111
- RecentRejectsFilter ().insert (ptx->GetWitnessHash ().ToUint256 ());
3112
- }
3113
- m_txrequest.ForgetTxHash (ptx->GetWitnessHash ());
3114
- // If the transaction failed for TX_INPUTS_NOT_STANDARD,
3115
- // then we know that the witness was irrelevant to the policy
3116
- // failure, since this check depends only on the txid
3117
- // (the scriptPubKey being spent is covered by the txid).
3118
- // Add the txid to the reject filter to prevent repeated
3119
- // processing of this transaction in the event that child
3120
- // transactions are later received (resulting in
3121
- // parent-fetching by txid via the orphan-handling logic).
3122
- // We only add the txid if it differs from the wtxid, to avoid wasting entries in the
3123
- // rolling bloom filter.
3124
- if (state.GetResult () == TxValidationResult::TX_INPUTS_NOT_STANDARD && ptx->HasWitness ()) {
3125
- RecentRejectsFilter ().insert (ptx->GetHash ().ToUint256 ());
3126
- m_txrequest.ForgetTxHash (ptx->GetHash ());
3127
- }
3128
- }
3129
2989
if (add_extra_compact_tx && RecursiveDynamicUsage (*ptx) < 100000 ) {
3130
2990
AddToCompactExtraTransactions (ptx);
3131
2991
}
@@ -3135,12 +2995,6 @@ std::optional<node::PackageToValidate> PeerManagerImpl::ProcessInvalidTx(NodeId
3135
2995
3136
2996
MaybePunishNodeForTx (nodeid, state);
3137
2997
3138
- // If the tx failed in ProcessOrphanTx, it should be removed from the orphanage unless the
3139
- // tx was still missing inputs. If the tx was not in the orphanage, EraseTx does nothing and returns 0.
3140
- if (state.GetResult () != TxValidationResult::TX_MISSING_INPUTS && m_orphanage.EraseTx (ptx->GetWitnessHash ()) > 0 ) {
3141
- LogDebug (BCLog::TXPACKAGES, " removed orphan tx %s (wtxid=%s)\n " , ptx->GetHash ().ToString (), ptx->GetWitnessHash ().ToString ());
3142
- }
3143
-
3144
2998
return package_to_validate;
3145
2999
}
3146
3000
0 commit comments