@@ -564,40 +564,6 @@ class PeerManagerImpl final : public PeerManager
564
564
*/
565
565
bool MaybeDiscourageAndDisconnect (CNode& pnode, Peer& peer);
566
566
567
- struct PackageToValidate {
568
- Package m_txns;
569
- std::vector<NodeId> m_senders;
570
- /* * Construct a 1-parent-1-child package. */
571
- explicit PackageToValidate (const CTransactionRef& parent,
572
- const CTransactionRef& child,
573
- NodeId parent_sender,
574
- NodeId child_sender) :
575
- m_txns{parent, child},
576
- m_senders{parent_sender, child_sender}
577
- {}
578
-
579
- // Move ctor
580
- PackageToValidate (PackageToValidate&& other) : m_txns{std::move (other.m_txns )}, m_senders{std::move (other.m_senders )} {}
581
-
582
- // Move assignment
583
- PackageToValidate& operator =(PackageToValidate&& other) {
584
- this ->m_txns = std::move (other.m_txns );
585
- this ->m_senders = std::move (other.m_senders );
586
- return *this ;
587
- }
588
-
589
- std::string ToString () const {
590
- Assume (m_txns.size () == 2 );
591
- return strprintf (" parent %s (wtxid=%s, sender=%d) + child %s (wtxid=%s, sender=%d)" ,
592
- m_txns.front ()->GetHash ().ToString (),
593
- m_txns.front ()->GetWitnessHash ().ToString (),
594
- m_senders.front (),
595
- m_txns.back ()->GetHash ().ToString (),
596
- m_txns.back ()->GetWitnessHash ().ToString (),
597
- m_senders.back ());
598
- }
599
- };
600
-
601
567
/* * Handle a transaction whose result was not MempoolAcceptResult::ResultType::VALID.
602
568
* @param[in] first_time_failure Whether we should consider inserting into vExtraTxnForCompact, adding
603
569
* a new orphan to resolve, or looking for a package to submit.
@@ -609,8 +575,8 @@ class PeerManagerImpl final : public PeerManager
609
575
* @returns a PackageToValidate if this transaction has a reconsiderable failure and an eligible package was found,
610
576
* or std::nullopt otherwise.
611
577
*/
612
- std::optional<PackageToValidate> ProcessInvalidTx (NodeId nodeid, const CTransactionRef& tx, const TxValidationState& result,
613
- bool first_time_failure)
578
+ std::optional<node:: PackageToValidate> ProcessInvalidTx (NodeId nodeid, const CTransactionRef& tx, const TxValidationState& result,
579
+ bool first_time_failure)
614
580
EXCLUSIVE_LOCKS_REQUIRED(!m_peer_mutex, g_msgproc_mutex, m_tx_download_mutex);
615
581
616
582
/* * Handle a transaction whose result was MempoolAcceptResult::ResultType::VALID.
@@ -621,13 +587,7 @@ class PeerManagerImpl final : public PeerManager
621
587
/* * Handle the results of package validation: calls ProcessValidTx and ProcessInvalidTx for
622
588
* individual transactions, and caches rejection for the package as a group.
623
589
*/
624
- void ProcessPackageResult (const PackageToValidate& package_to_validate, const PackageMempoolAcceptResult& package_result)
625
- EXCLUSIVE_LOCKS_REQUIRED(!m_peer_mutex, g_msgproc_mutex, m_tx_download_mutex);
626
-
627
- /* * Look for a child of this transaction in the orphanage to form a 1-parent-1-child package,
628
- * skipping any combinations that have already been tried. Return the resulting package along with
629
- * the senders of its respective transactions, or std::nullopt if no package is found. */
630
- std::optional<PackageToValidate> Find1P1CPackage (const CTransactionRef& ptx, NodeId nodeid)
590
+ void ProcessPackageResult (const node::PackageToValidate& package_to_validate, const PackageMempoolAcceptResult& package_result)
631
591
EXCLUSIVE_LOCKS_REQUIRED(!m_peer_mutex, g_msgproc_mutex, m_tx_download_mutex);
632
592
633
593
/* *
@@ -1946,7 +1906,7 @@ PeerManagerImpl::PeerManagerImpl(CConnman& connman, AddrMan& addrman,
1946
1906
m_banman(banman),
1947
1907
m_chainman(chainman),
1948
1908
m_mempool(pool),
1949
- m_txdownloadman(node::TxDownloadOptions{pool}),
1909
+ m_txdownloadman(node::TxDownloadOptions{pool, m_rng }),
1950
1910
m_warnings{warnings},
1951
1911
m_opts{opts}
1952
1912
{
@@ -3015,7 +2975,7 @@ void PeerManagerImpl::ProcessHeadersMessage(CNode& pfrom, Peer& peer,
3015
2975
return ;
3016
2976
}
3017
2977
3018
- std::optional<PeerManagerImpl ::PackageToValidate> PeerManagerImpl::ProcessInvalidTx (NodeId nodeid, const CTransactionRef& ptx, const TxValidationState& state,
2978
+ std::optional<node ::PackageToValidate> PeerManagerImpl::ProcessInvalidTx (NodeId nodeid, const CTransactionRef& ptx, const TxValidationState& state,
3019
2979
bool first_time_failure)
3020
2980
{
3021
2981
AssertLockNotHeld (m_peer_mutex);
@@ -3039,7 +2999,7 @@ std::optional<PeerManagerImpl::PackageToValidate> PeerManagerImpl::ProcessInvali
3039
2999
// Hashes to pass to AddKnownTx later
3040
3000
std::vector<uint256> unique_parents;
3041
3001
// Populated if failure is reconsiderable and eligible package is found.
3042
- std::optional<PackageToValidate> package_to_validate;
3002
+ std::optional<node:: PackageToValidate> package_to_validate;
3043
3003
3044
3004
if (state.GetResult () == TxValidationResult::TX_MISSING_INPUTS) {
3045
3005
// Only process a new orphan if this is a first time failure, as otherwise it must be either
@@ -3145,7 +3105,7 @@ std::optional<PeerManagerImpl::PackageToValidate> PeerManagerImpl::ProcessInvali
3145
3105
// orphanage, as it is possible that they succeed as a package.
3146
3106
LogDebug (BCLog::TXPACKAGES, " tx %s (wtxid=%s) failed but reconsiderable, looking for child in orphanage\n " ,
3147
3107
ptx->GetHash ().ToString (), ptx->GetWitnessHash ().ToString ());
3148
- package_to_validate = Find1P1CPackage (ptx, nodeid);
3108
+ package_to_validate = m_txdownloadman. Find1P1CPackage (ptx, nodeid);
3149
3109
}
3150
3110
} else {
3151
3111
RecentRejectsFilter ().insert (ptx->GetWitnessHash ().ToUint256 ());
@@ -3215,7 +3175,7 @@ void PeerManagerImpl::ProcessValidTx(NodeId nodeid, const CTransactionRef& tx, c
3215
3175
}
3216
3176
}
3217
3177
3218
- void PeerManagerImpl::ProcessPackageResult (const PackageToValidate& package_to_validate, const PackageMempoolAcceptResult& package_result)
3178
+ void PeerManagerImpl::ProcessPackageResult (const node:: PackageToValidate& package_to_validate, const PackageMempoolAcceptResult& package_result)
3219
3179
{
3220
3180
AssertLockNotHeld (m_peer_mutex);
3221
3181
AssertLockHeld (g_msgproc_mutex);
@@ -3271,61 +3231,6 @@ void PeerManagerImpl::ProcessPackageResult(const PackageToValidate& package_to_v
3271
3231
}
3272
3232
}
3273
3233
3274
- std::optional<PeerManagerImpl::PackageToValidate> PeerManagerImpl::Find1P1CPackage (const CTransactionRef& ptx, NodeId nodeid)
3275
- {
3276
- AssertLockNotHeld (m_peer_mutex);
3277
- AssertLockHeld (g_msgproc_mutex);
3278
- AssertLockHeld (m_tx_download_mutex);
3279
-
3280
- const auto & parent_wtxid{ptx->GetWitnessHash ()};
3281
- auto & m_orphanage = m_txdownloadman.GetOrphanageRef ();
3282
-
3283
- Assume (RecentRejectsReconsiderableFilter ().contains (parent_wtxid.ToUint256 ()));
3284
-
3285
- // Prefer children from this peer. This helps prevent censorship attempts in which an attacker
3286
- // sends lots of fake children for the parent, and we (unluckily) keep selecting the fake
3287
- // children instead of the real one provided by the honest peer.
3288
- const auto cpfp_candidates_same_peer{m_orphanage.GetChildrenFromSamePeer (ptx, nodeid)};
3289
-
3290
- // These children should be sorted from newest to oldest. In the (probably uncommon) case
3291
- // of children that replace each other, this helps us accept the highest feerate (probably the
3292
- // most recent) one efficiently.
3293
- for (const auto & child : cpfp_candidates_same_peer) {
3294
- Package maybe_cpfp_package{ptx, child};
3295
- if (!RecentRejectsReconsiderableFilter ().contains (GetPackageHash (maybe_cpfp_package))) {
3296
- return PeerManagerImpl::PackageToValidate{ptx, child, nodeid, nodeid};
3297
- }
3298
- }
3299
-
3300
- // If no suitable candidate from the same peer is found, also try children that were provided by
3301
- // a different peer. This is useful because sometimes multiple peers announce both transactions
3302
- // to us, and we happen to download them from different peers (we wouldn't have known that these
3303
- // 2 transactions are related). We still want to find 1p1c packages then.
3304
- //
3305
- // If we start tracking all announcers of orphans, we can restrict this logic to parent + child
3306
- // pairs in which both were provided by the same peer, i.e. delete this step.
3307
- const auto cpfp_candidates_different_peer{m_orphanage.GetChildrenFromDifferentPeer (ptx, nodeid)};
3308
-
3309
- // Find the first 1p1c that hasn't already been rejected. We randomize the order to not
3310
- // create a bias that attackers can use to delay package acceptance.
3311
- //
3312
- // Create a random permutation of the indices.
3313
- std::vector<size_t > tx_indices (cpfp_candidates_different_peer.size ());
3314
- std::iota (tx_indices.begin (), tx_indices.end (), 0 );
3315
- std::shuffle (tx_indices.begin (), tx_indices.end (), m_rng);
3316
-
3317
- for (const auto index : tx_indices) {
3318
- // If we already tried a package and failed for any reason, the combined hash was
3319
- // cached in m_lazy_recent_rejects_reconsiderable.
3320
- const auto [child_tx, child_sender] = cpfp_candidates_different_peer.at (index);
3321
- Package maybe_cpfp_package{ptx, child_tx};
3322
- if (!RecentRejectsReconsiderableFilter ().contains (GetPackageHash (maybe_cpfp_package))) {
3323
- return PeerManagerImpl::PackageToValidate{ptx, child_tx, nodeid, child_sender};
3324
- }
3325
- }
3326
- return std::nullopt;
3327
- }
3328
-
3329
3234
bool PeerManagerImpl::ProcessOrphanTx (Peer& peer)
3330
3235
{
3331
3236
AssertLockHeld (g_msgproc_mutex);
@@ -4528,7 +4433,7 @@ void PeerManagerImpl::ProcessMessage(CNode& pfrom, const std::string& msg_type,
4528
4433
// possible that they succeed as a package.
4529
4434
LogDebug (BCLog::TXPACKAGES, " found tx %s (wtxid=%s) in reconsiderable rejects, looking for child in orphanage\n " ,
4530
4435
txid.ToString (), wtxid.ToString ());
4531
- if (auto package_to_validate{Find1P1CPackage (ptx, pfrom.GetId ())}) {
4436
+ if (auto package_to_validate{m_txdownloadman. Find1P1CPackage (ptx, pfrom.GetId ())}) {
4532
4437
const auto package_result{ProcessNewPackage (m_chainman.ActiveChainstate (), m_mempool, package_to_validate->m_txns , /* test_accept=*/ false , /* client_maxfeerate=*/ std::nullopt)};
4533
4438
LogDebug (BCLog::TXPACKAGES, " package evaluation for %s: %s\n " , package_to_validate->ToString (),
4534
4439
package_result.m_state .IsValid () ? " package accepted" : " package rejected" );
0 commit comments