Skip to content

Commit a39960b

Browse files
Merge #6956: refactor: use a vector; introduce instantsend::PendingISLockFromPeer
1b2bab4 chore: whitespace fix (pasta) 2980e60 perf: use vector instead of hash map for ProcessPendingInstantSendLocks (pasta) 5c6e98e refactor: replace pair with structured PendingISLockFromPeer in CInstantSendManager (pasta) Pull request description: ## Issue being fixed or feature implemented We don't use the hash map properties, so use a vector, since we are copying everything anyway. Also add instantsend::PendingISLockFromPeer for improved readability ## What was done? ## How Has This Been Tested? Builds ## Breaking Changes ## Checklist: _Go over all the following points, and put an `x` in all the boxes that apply._ - [ ] I have performed a self-review of my own code - [ ] I have commented my code, particularly in hard-to-understand areas - [ ] I have added or updated relevant unit/integration/functional/e2e tests - [ ] I have made corresponding changes to the documentation - [x] I have assigned this pull request to a milestone _(for repository code-owners and collaborators only)_ ACKs for top commit: kwvg: utACK 1b2bab4 UdjinM6: utACK 1b2bab4 Tree-SHA512: 369bdfc1d91e104402927a126477ab71a27331b56cfadef1f88279acc6f86a5a2eb592d43df1a2c33f0199072ecbf162010908088af9d4fdd6acb2398e60fd84
2 parents b440b16 + 1b2bab4 commit a39960b

File tree

2 files changed

+34
-26
lines changed

2 files changed

+34
-26
lines changed

src/instantsend/instantsend.cpp

Lines changed: 25 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -168,13 +168,13 @@ MessageProcessingResult CInstantSendManager::ProcessMessage(NodeId from, std::st
168168
}
169169

170170
LOCK(cs_pendingLocks);
171-
pendingInstantSendLocks.emplace(hash, std::make_pair(from, islock));
171+
pendingInstantSendLocks.emplace(hash, instantsend::PendingISLockFromPeer{from, islock});
172172
return ret;
173173
}
174174

175175
instantsend::PendingState CInstantSendManager::ProcessPendingInstantSendLocks()
176176
{
177-
decltype(pendingInstantSendLocks) pend;
177+
std::vector<std::pair<uint256, instantsend::PendingISLockFromPeer>> pend;
178178
instantsend::PendingState ret;
179179

180180
if (!IsInstantSendEnabled()) {
@@ -189,14 +189,15 @@ instantsend::PendingState CInstantSendManager::ProcessPendingInstantSendLocks()
189189
// The keys of the removed values are temporaily stored here to avoid invalidating an iterator
190190
std::vector<uint256> removed;
191191
removed.reserve(maxCount);
192+
pend.reserve(maxCount);
192193

193194
for (const auto& [islockHash, nodeid_islptr_pair] : pendingInstantSendLocks) {
194195
// Check if we've reached max count
195196
if (pend.size() >= maxCount) {
196197
ret.m_pending_work = true;
197198
break;
198199
}
199-
pend.emplace(islockHash, std::move(nodeid_islptr_pair));
200+
pend.emplace_back(islockHash, std::move(nodeid_islptr_pair));
200201
removed.emplace_back(islockHash);
201202
}
202203

@@ -222,24 +223,25 @@ instantsend::PendingState CInstantSendManager::ProcessPendingInstantSendLocks()
222223
if (!badISLocks.empty()) {
223224
LogPrint(BCLog::INSTANTSEND, "CInstantSendManager::%s -- doing verification on old active set\n", __func__);
224225

225-
// filter out valid IS locks from "pend"
226-
for (auto it = pend.begin(); it != pend.end();) {
227-
if (!badISLocks.count(it->first)) {
228-
it = pend.erase(it);
229-
} else {
230-
++it;
226+
// filter out valid IS locks from "pend" - keep only bad ones
227+
std::vector<std::pair<uint256, instantsend::PendingISLockFromPeer>> filteredPend;
228+
filteredPend.reserve(badISLocks.size());
229+
for (auto& p : pend) {
230+
if (badISLocks.contains(p.first)) {
231+
filteredPend.push_back(std::move(p));
231232
}
232233
}
234+
233235
// Now check against the previous active set and perform banning if this fails
234-
ProcessPendingInstantSendLocks(llmq_params, dkgInterval, /*ban=*/true, pend, ret.m_peer_activity);
236+
ProcessPendingInstantSendLocks(llmq_params, dkgInterval, /*ban=*/true, filteredPend, ret.m_peer_activity);
235237
}
236238

237239
return ret;
238240
}
239241

240242
Uint256HashSet CInstantSendManager::ProcessPendingInstantSendLocks(
241243
const Consensus::LLMQParams& llmq_params, int signOffset, bool ban,
242-
const Uint256HashMap<std::pair<NodeId, instantsend::InstantSendLockPtr>>& pend,
244+
const std::vector<std::pair<uint256, instantsend::PendingISLockFromPeer>>& pend,
243245
std::vector<std::pair<NodeId, MessageProcessingResult>>& peer_activity)
244246
{
245247
CBLSBatchVerifier<NodeId, uint256> batchVerifier(false, true, 8);
@@ -249,8 +251,8 @@ Uint256HashSet CInstantSendManager::ProcessPendingInstantSendLocks(
249251
size_t alreadyVerified = 0;
250252
for (const auto& p : pend) {
251253
const auto& hash = p.first;
252-
auto nodeId = p.second.first;
253-
const auto& islock = p.second.second;
254+
auto nodeId = p.second.node_id;
255+
const auto& islock = p.second.islock;
254256

255257
if (batchVerifier.badSources.count(nodeId)) {
256258
continue;
@@ -321,8 +323,8 @@ Uint256HashSet CInstantSendManager::ProcessPendingInstantSendLocks(
321323
}
322324
for (const auto& p : pend) {
323325
const auto& hash = p.first;
324-
auto nodeId = p.second.first;
325-
const auto& islock = p.second.second;
326+
auto nodeId = p.second.node_id;
327+
const auto& islock = p.second.islock;
326328

327329
if (batchVerifier.badMessages.count(hash)) {
328330
LogPrint(BCLog::INSTANTSEND, "CInstantSendManager::%s -- txid=%s, islock=%s: invalid sig in islock, peer=%d\n",
@@ -399,7 +401,7 @@ MessageProcessingResult CInstantSendManager::ProcessInstantSendLock(NodeId from,
399401
} else {
400402
// put it in a separate pending map and try again later
401403
LOCK(cs_pendingLocks);
402-
pendingNoTxInstantSendLocks.try_emplace(hash, std::make_pair(from, islock));
404+
pendingNoTxInstantSendLocks.try_emplace(hash, instantsend::PendingISLockFromPeer{from, islock});
403405
}
404406

405407
// This will also add children TXs to pendingRetryTxs
@@ -442,11 +444,11 @@ void CInstantSendManager::TransactionAddedToMempool(const CTransactionRef& tx)
442444
LOCK(cs_pendingLocks);
443445
auto it = pendingNoTxInstantSendLocks.begin();
444446
while (it != pendingNoTxInstantSendLocks.end()) {
445-
if (it->second.second->txid == tx->GetHash()) {
447+
if (it->second.islock->txid == tx->GetHash()) {
446448
// we received an islock earlier
447449
LogPrint(BCLog::INSTANTSEND, "CInstantSendManager::%s -- txid=%s, islock=%s\n", __func__,
448450
tx->GetHash().ToString(), it->first.ToString());
449-
islock = it->second.second;
451+
islock = it->second.islock;
450452
pendingInstantSendLocks.try_emplace(it->first, it->second);
451453
pendingNoTxInstantSendLocks.erase(it);
452454
break;
@@ -539,7 +541,7 @@ void CInstantSendManager::AddNonLockedTx(const CTransactionRef& tx, const CBlock
539541
LOCK(cs_pendingLocks);
540542
auto it = pendingNoTxInstantSendLocks.begin();
541543
while (it != pendingNoTxInstantSendLocks.end()) {
542-
if (it->second.second->txid == tx->GetHash()) {
544+
if (it->second.islock->txid == tx->GetHash()) {
543545
// we received an islock earlier, let's put it back into pending and verify/lock
544546
LogPrint(BCLog::INSTANTSEND, "CInstantSendManager::%s -- txid=%s, islock=%s\n", __func__,
545547
tx->GetHash().ToString(), it->first.ToString());
@@ -626,7 +628,7 @@ void CInstantSendManager::TryEmplacePendingLock(const uint256& hash, const NodeI
626628
if (db.KnownInstantSendLock(hash)) return;
627629
LOCK(cs_pendingLocks);
628630
if (!pendingInstantSendLocks.count(hash)) {
629-
pendingInstantSendLocks.emplace(hash, std::make_pair(id, islock));
631+
pendingInstantSendLocks.emplace(hash, instantsend::PendingISLockFromPeer{id, islock});
630632
}
631633
}
632634

@@ -848,11 +850,11 @@ bool CInstantSendManager::GetInstantSendLockByHash(const uint256& hash, instants
848850
LOCK(cs_pendingLocks);
849851
auto it = pendingInstantSendLocks.find(hash);
850852
if (it != pendingInstantSendLocks.end()) {
851-
islock = it->second.second;
853+
islock = it->second.islock;
852854
} else {
853855
auto itNoTx = pendingNoTxInstantSendLocks.find(hash);
854856
if (itNoTx != pendingNoTxInstantSendLocks.end()) {
855-
islock = itNoTx->second.second;
857+
islock = itNoTx->second.islock;
856858
} else {
857859
return false;
858860
}
@@ -889,7 +891,7 @@ bool CInstantSendManager::IsWaitingForTx(const uint256& txHash) const
889891
LOCK(cs_pendingLocks);
890892
auto it = pendingNoTxInstantSendLocks.begin();
891893
while (it != pendingNoTxInstantSendLocks.end()) {
892-
if (it->second.second->txid == txHash) {
894+
if (it->second.islock->txid == txHash) {
893895
LogPrint(BCLog::INSTANTSEND, "CInstantSendManager::%s -- txid=%s, islock=%s\n", __func__, txHash.ToString(),
894896
it->first.ToString());
895897
return true;

src/instantsend/instantsend.h

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
#include <atomic>
2121
#include <unordered_map>
2222
#include <unordered_set>
23+
#include <vector>
2324

2425
class CBlockIndex;
2526
class CChainState;
@@ -38,6 +39,11 @@ struct DbWrapperParams;
3839
namespace instantsend {
3940
class InstantSendSigner;
4041

42+
struct PendingISLockFromPeer {
43+
NodeId node_id;
44+
InstantSendLockPtr islock;
45+
};
46+
4147
struct PendingState {
4248
bool m_pending_work{false};
4349
std::vector<std::pair<NodeId, MessageProcessingResult>> m_peer_activity{};
@@ -69,9 +75,9 @@ class CInstantSendManager final : public instantsend::InstantSendSignerParent
6975

7076
mutable Mutex cs_pendingLocks;
7177
// Incoming and not verified yet
72-
Uint256HashMap<std::pair<NodeId, instantsend::InstantSendLockPtr>> pendingInstantSendLocks GUARDED_BY(cs_pendingLocks);
78+
Uint256HashMap<instantsend::PendingISLockFromPeer> pendingInstantSendLocks GUARDED_BY(cs_pendingLocks);
7379
// Tried to verify but there is no tx yet
74-
Uint256HashMap<std::pair<NodeId, instantsend::InstantSendLockPtr>> pendingNoTxInstantSendLocks GUARDED_BY(cs_pendingLocks);
80+
Uint256HashMap<instantsend::PendingISLockFromPeer> pendingNoTxInstantSendLocks GUARDED_BY(cs_pendingLocks);
7581

7682
// TXs which are neither IS locked nor ChainLocked. We use this to determine for which TXs we need to retry IS
7783
// locking of child TXs
@@ -117,7 +123,7 @@ class CInstantSendManager final : public instantsend::InstantSendSignerParent
117123
EXCLUSIVE_LOCKS_REQUIRED(!cs_nonLocked, !cs_pendingLocks, !cs_pendingRetry);
118124

119125
Uint256HashSet ProcessPendingInstantSendLocks(const Consensus::LLMQParams& llmq_params, int signOffset, bool ban,
120-
const Uint256HashMap<std::pair<NodeId, instantsend::InstantSendLockPtr>>& pend,
126+
const std::vector<std::pair<uint256, instantsend::PendingISLockFromPeer>>& pend,
121127
std::vector<std::pair<NodeId, MessageProcessingResult>>& peer_activity)
122128
EXCLUSIVE_LOCKS_REQUIRED(!cs_nonLocked, !cs_pendingLocks, !cs_pendingRetry);
123129
MessageProcessingResult ProcessInstantSendLock(NodeId from, const uint256& hash,

0 commit comments

Comments
 (0)