Skip to content

Commit dbfb426

Browse files
committed
Optimize the relay map to use shared_ptr's
* Switch mapRelay to use shared_ptr<CTransaction> * Switch the relay code to copy mempool shared_ptr's, rather than copying the transaction itself. * Change vRelayExpiration to store mapRelay iterators rather than hashes (smaller and faster).
1 parent 8d39d7a commit dbfb426

File tree

1 file changed

+16
-21
lines changed

1 file changed

+16
-21
lines changed

src/main.cpp

Lines changed: 16 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -80,9 +80,6 @@ uint64_t nPruneTarget = 0;
8080
int64_t nMaxTipAge = DEFAULT_MAX_TIP_AGE;
8181
bool fEnableReplacement = DEFAULT_ENABLE_REPLACEMENT;
8282

83-
std::map<uint256, CTransaction> mapRelay;
84-
std::deque<std::pair<int64_t, uint256> > vRelayExpiration;
85-
CCriticalSection cs_mapRelay;
8683

8784
CFeeRate minRelayTxFee = CFeeRate(DEFAULT_MIN_RELAY_TX_FEE);
8885
CAmount maxTxFee = DEFAULT_TRANSACTION_MAXFEE;
@@ -215,6 +212,12 @@ namespace {
215212

216213
/** Number of peers from which we're downloading blocks. */
217214
int nPeersWithValidatedDownloads = 0;
215+
216+
/** Relay map, protected by cs_main. */
217+
typedef std::map<uint256, std::shared_ptr<const CTransaction>> MapRelay;
218+
MapRelay mapRelay;
219+
/** Expiration-time ordered list of (expire time, relay map entry) pairs, protected by cs_main). */
220+
std::deque<std::pair<int64_t, MapRelay::iterator>> vRelayExpiration;
218221
} // anon namespace
219222

220223
//////////////////////////////////////////////////////////////////////////////
@@ -4505,31 +4508,24 @@ void static ProcessGetData(CNode* pfrom, const Consensus::Params& consensusParam
45054508
}
45064509
}
45074510
}
4508-
else if (inv.IsKnownType())
4511+
else if (inv.type == MSG_TX)
45094512
{
4510-
CTransaction tx;
45114513
// Send stream from relay memory
45124514
bool push = false;
4513-
{
4514-
LOCK(cs_mapRelay);
4515-
map<uint256, CTransaction>::iterator mi = mapRelay.find(inv.hash);
4516-
if (mi != mapRelay.end()) {
4517-
tx = (*mi).second;
4518-
push = true;
4519-
}
4520-
}
4521-
if (!push && inv.type == MSG_TX) {
4515+
auto mi = mapRelay.find(inv.hash);
4516+
if (mi != mapRelay.end()) {
4517+
pfrom->PushMessage(NetMsgType::TX, *mi->second);
4518+
push = true;
4519+
} else {
45224520
auto txinfo = mempool.info(inv.hash);
45234521
// To protect privacy, do not answer getdata using the mempool when
45244522
// that TX couldn't have been INVed in reply to a MEMPOOL request.
45254523
if (txinfo.tx && txinfo.nTime <= pfrom->timeLastMempoolReq) {
4526-
tx = *txinfo.tx;
4524+
pfrom->PushMessage(NetMsgType::TX, *txinfo.tx);
45274525
push = true;
45284526
}
45294527
}
4530-
if (push) {
4531-
pfrom->PushMessage(inv.GetCommand(), tx);
4532-
} else {
4528+
if (!push) {
45334529
vNotFound.push_back(inv);
45344530
}
45354531
}
@@ -5978,17 +5974,16 @@ bool SendMessages(CNode* pto)
59785974
vInv.push_back(CInv(MSG_TX, hash));
59795975
nRelayedTransactions++;
59805976
{
5981-
LOCK(cs_mapRelay);
59825977
// Expire old relay messages
59835978
while (!vRelayExpiration.empty() && vRelayExpiration.front().first < GetTime())
59845979
{
59855980
mapRelay.erase(vRelayExpiration.front().second);
59865981
vRelayExpiration.pop_front();
59875982
}
59885983

5989-
auto ret = mapRelay.insert(std::make_pair(hash, *txinfo.tx));
5984+
auto ret = mapRelay.insert(std::make_pair(hash, std::move(txinfo.tx)));
59905985
if (ret.second) {
5991-
vRelayExpiration.push_back(std::make_pair(GetTime() + 15 * 60, hash));
5986+
vRelayExpiration.push_back(std::make_pair(GetTime() + 15 * 60, ret.first));
59925987
}
59935988
}
59945989
if (vInv.size() == MAX_INV_SZ) {

0 commit comments

Comments
 (0)