@@ -152,23 +152,29 @@ void TxOrphanage::LimitOrphans(unsigned int max_orphans, FastRandomContext& rng)
152
152
if (nEvicted > 0 ) LogDebug (BCLog::TXPACKAGES, " orphanage overflow, removed %u tx\n " , nEvicted);
153
153
}
154
154
155
- void TxOrphanage::AddChildrenToWorkSet (const CTransaction& tx)
155
+ void TxOrphanage::AddChildrenToWorkSet (const CTransaction& tx, FastRandomContext& rng )
156
156
{
157
157
for (unsigned int i = 0 ; i < tx.vout .size (); i++) {
158
158
const auto it_by_prev = m_outpoint_to_orphan_it.find (COutPoint (tx.GetHash (), i));
159
159
if (it_by_prev != m_outpoint_to_orphan_it.end ()) {
160
160
for (const auto & elem : it_by_prev->second ) {
161
161
// Belt and suspenders, each orphan should always have at least 1 announcer.
162
162
if (!Assume (!elem->second .announcers .empty ())) continue ;
163
- for (const auto announcer: elem->second .announcers ) {
164
- // Get this source peer's work set, emplacing an empty set if it didn't exist
165
- // (note: if this peer wasn't still connected, we would have removed the orphan tx already)
166
- std::set<Wtxid>& orphan_work_set = m_peer_work_set.try_emplace (announcer).first ->second ;
167
- // Add this tx to the work set
168
- orphan_work_set.insert (elem->first );
169
- LogDebug (BCLog::TXPACKAGES, " added %s (wtxid=%s) to peer %d workset\n " ,
170
- tx.GetHash ().ToString (), tx.GetWitnessHash ().ToString (), announcer);
171
- }
163
+
164
+ // Select a random peer to assign orphan processing, reducing wasted work if the orphan is still missing
165
+ // inputs. However, we don't want to create an issue in which the assigned peer can purposefully stop us
166
+ // from processing the orphan by disconnecting.
167
+ auto announcer_iter = std::begin (elem->second .announcers );
168
+ std::advance (announcer_iter, rng.randrange (elem->second .announcers .size ()));
169
+ auto announcer = *(announcer_iter);
170
+
171
+ // Get this source peer's work set, emplacing an empty set if it didn't exist
172
+ // (note: if this peer wasn't still connected, we would have removed the orphan tx already)
173
+ std::set<Wtxid>& orphan_work_set = m_peer_work_set.try_emplace (announcer).first ->second ;
174
+ // Add this tx to the work set
175
+ orphan_work_set.insert (elem->first );
176
+ LogDebug (BCLog::TXPACKAGES, " added %s (wtxid=%s) to peer %d workset\n " ,
177
+ tx.GetHash ().ToString (), tx.GetWitnessHash ().ToString (), announcer);
172
178
}
173
179
}
174
180
}
0 commit comments