@@ -851,6 +851,7 @@ class PeerManagerImpl final : public PeerManager
851
851
std::shared_ptr<const CBlock> m_most_recent_block GUARDED_BY (m_most_recent_block_mutex);
852
852
std::shared_ptr<const CBlockHeaderAndShortTxIDs> m_most_recent_compact_block GUARDED_BY (m_most_recent_block_mutex);
853
853
uint256 m_most_recent_block_hash GUARDED_BY (m_most_recent_block_mutex);
854
+ std::unique_ptr<const std::map<uint256, CTransactionRef>> m_most_recent_block_txs GUARDED_BY (m_most_recent_block_mutex);
854
855
855
856
// Data about the low-work headers synchronization, aggregated from all peers' HeadersSyncStates.
856
857
/* * Mutex guarding the other m_headers_presync_* variables. */
@@ -910,7 +911,7 @@ class PeerManagerImpl final : public PeerManager
910
911
911
912
/* * Determine whether or not a peer can request a transaction, and return it (or nullptr if not found or not allowed). */
912
913
CTransactionRef FindTxForGetData (const Peer::TxRelay& tx_relay, const GenTxid& gtxid, const std::chrono::seconds mempool_req, const std::chrono::seconds now)
913
- EXCLUSIVE_LOCKS_REQUIRED(NetEventsInterface::g_msgproc_mutex);
914
+ EXCLUSIVE_LOCKS_REQUIRED(!m_most_recent_block_mutex, NetEventsInterface::g_msgproc_mutex);
914
915
915
916
void ProcessGetData (CNode& pfrom, Peer& peer, const std::atomic<bool >& interruptMsgProc)
916
917
EXCLUSIVE_LOCKS_REQUIRED(!m_most_recent_block_mutex, peer.m_getdata_requests_mutex, NetEventsInterface::g_msgproc_mutex)
@@ -1927,10 +1928,17 @@ void PeerManagerImpl::NewPoWValidBlock(const CBlockIndex *pindex, const std::sha
1927
1928
std::async (std::launch::deferred, [&] { return msgMaker.Make (NetMsgType::CMPCTBLOCK, *pcmpctblock); })};
1928
1929
1929
1930
{
1931
+ auto most_recent_block_txs = std::make_unique<std::map<uint256, CTransactionRef>>();
1932
+ for (const auto & tx : pblock->vtx ) {
1933
+ most_recent_block_txs->emplace (tx->GetHash (), tx);
1934
+ most_recent_block_txs->emplace (tx->GetWitnessHash (), tx);
1935
+ }
1936
+
1930
1937
LOCK (m_most_recent_block_mutex);
1931
1938
m_most_recent_block_hash = hashBlock;
1932
1939
m_most_recent_block = pblock;
1933
1940
m_most_recent_compact_block = pcmpctblock;
1941
+ m_most_recent_block_txs = std::move (most_recent_block_txs);
1934
1942
}
1935
1943
1936
1944
m_connman.ForEachNode ([this , pindex, &lazy_ser, &hashBlock](CNode* pnode) EXCLUSIVE_LOCKS_REQUIRED (::cs_main) {
@@ -2301,11 +2309,21 @@ CTransactionRef PeerManagerImpl::FindTxForGetData(const Peer::TxRelay& tx_relay,
2301
2309
}
2302
2310
}
2303
2311
2304
- // Otherwise, the transaction must have been announced recently.
2305
- if (tx_relay.m_recently_announced_invs .contains (gtxid.GetHash ())) {
2306
- // If it was, it can be relayed from either the mempool...
2307
- if (txinfo.tx ) return std::move (txinfo.tx );
2308
- // ... or the relay pool.
2312
+ // Otherwise, the transaction might have been announced recently.
2313
+ bool recent = tx_relay.m_recently_announced_invs .contains (gtxid.GetHash ());
2314
+ if (recent && txinfo.tx ) return std::move (txinfo.tx );
2315
+
2316
+ // Or it might be from the most recent block
2317
+ {
2318
+ LOCK (m_most_recent_block_mutex);
2319
+ if (m_most_recent_block_txs != nullptr ) {
2320
+ auto it = m_most_recent_block_txs->find (gtxid.GetHash ());
2321
+ if (it != m_most_recent_block_txs->end ()) return it->second ;
2322
+ }
2323
+ }
2324
+
2325
+ // Or it might be recent and in the relay pool.
2326
+ if (recent) {
2309
2327
auto mi = mapRelay.find (gtxid.GetHash ());
2310
2328
if (mi != mapRelay.end ()) return mi->second ;
2311
2329
}
0 commit comments