Skip to content

Commit 901358a

Browse files
UdjinM6claude
authored andcommitted
refactor: review fixes for CInstantSendManager decoupling
- Rename IsKnownTx to HasTxForLock for clarity (returns true when the lock's transaction is known, not pending without a TX) - Fix unconditional LookupBlockIndex in CheckCanLock: only take cs_main on cache miss instead of every call - Fix log prefix typos: NetSigning -> NetInstantSend in ProcessInstantSendLock - Remove redundant LookupBlockIndex fallback in ProcessInstantSendLock that duplicated the static GetBlockHeight helper - Simplify AttachISLockToTx: use for-loop with early-continue, remove unnecessary variable - Remove double blank line Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
1 parent a335d77 commit 901358a

File tree

5 files changed

+33
-43
lines changed

5 files changed

+33
-43
lines changed

src/active/context.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -100,6 +100,7 @@ struct ActiveContext final : public CValidationInterface {
100100
public:
101101
const std::unique_ptr<instantsend::InstantSendSigner> is_signer;
102102

103+
public:
103104
/** Owned by PeerManager, use GetCJServer() */
104105
CCoinJoinServer* m_cj_server{nullptr};
105106
};

src/instantsend/instantsend.cpp

Lines changed: 12 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -145,22 +145,19 @@ void CInstantSendManager::RemoveBlockISLocks(const std::shared_ptr<const CBlock>
145145

146146
instantsend::InstantSendLockPtr CInstantSendManager::AttachISLockToTx(const CTransactionRef& tx)
147147
{
148-
instantsend::InstantSendLockPtr ret_islock{nullptr};
149148
LOCK(cs_pendingLocks);
150-
auto it = pendingNoTxInstantSendLocks.begin();
151-
while (it != pendingNoTxInstantSendLocks.end()) {
152-
if (it->second.islock->txid == tx->GetHash()) {
153-
// we received an islock earlier, let's put it back into pending and verify/lock
154-
LogPrint(BCLog::INSTANTSEND, "CInstantSendManager::%s -- txid=%s, islock=%s\n", __func__,
155-
tx->GetHash().ToString(), it->first.ToString());
156-
ret_islock = it->second.islock;
157-
pendingInstantSendLocks.try_emplace(it->first, it->second);
158-
pendingNoTxInstantSendLocks.erase(it);
159-
return ret_islock;
160-
}
161-
++it;
149+
for (auto it = pendingNoTxInstantSendLocks.begin(); it != pendingNoTxInstantSendLocks.end(); ++it) {
150+
if (it->second.islock->txid != tx->GetHash()) continue;
151+
152+
// we received an islock earlier, let's put it back into pending and verify/lock
153+
LogPrint(BCLog::INSTANTSEND, "CInstantSendManager::%s -- txid=%s, islock=%s\n", __func__,
154+
tx->GetHash().ToString(), it->first.ToString());
155+
auto islock = it->second.islock;
156+
pendingInstantSendLocks.try_emplace(it->first, it->second);
157+
pendingNoTxInstantSendLocks.erase(it);
158+
return islock;
162159
}
163-
return ret_islock; // not found, nullptr
160+
return nullptr;
164161
}
165162

166163
void CInstantSendManager::AddNonLockedTx(const CTransactionRef& tx, const CBlockIndex* pindexMined)
@@ -290,7 +287,7 @@ std::unordered_map<const CBlockIndex*, Uint256HashMap<CTransactionRef>> CInstant
290287
return conflicts;
291288
}
292289

293-
bool CInstantSendManager::IsKnownTx(const uint256& islockHash) const
290+
bool CInstantSendManager::HasTxForLock(const uint256& islockHash) const
294291
{
295292
LOCK(cs_pendingLocks);
296293
return pendingNoTxInstantSendLocks.find(islockHash) == pendingNoTxInstantSendLocks.end();

src/instantsend/instantsend.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -104,7 +104,7 @@ class CInstantSendManager
104104
std::unordered_map<const CBlockIndex*, Uint256HashMap<CTransactionRef>> RetrieveISConflicts(
105105
const uint256& islockHash, const instantsend::InstantSendLock& islock)
106106
EXCLUSIVE_LOCKS_REQUIRED(!cs_nonLocked, !cs_pendingLocks);
107-
bool IsKnownTx(const uint256& islockHash) const EXCLUSIVE_LOCKS_REQUIRED(!cs_pendingLocks);
107+
bool HasTxForLock(const uint256& islockHash) const EXCLUSIVE_LOCKS_REQUIRED(!cs_pendingLocks);
108108

109109
bool IsLocked(const uint256& txHash) const;
110110
bool IsWaitingForTx(const uint256& txHash) const EXCLUSIVE_LOCKS_REQUIRED(!cs_pendingLocks);

src/instantsend/net_instantsend.cpp

Lines changed: 7 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -352,7 +352,7 @@ void NetInstantSend::ProcessPendingISLocks(std::vector<instantsend::PendingISLoc
352352

353353
void NetInstantSend::ProcessInstantSendLock(NodeId from, const uint256& hash, const instantsend::InstantSendLockPtr& islock)
354354
{
355-
LogPrint(BCLog::INSTANTSEND, "NetSigning::%s -- txid=%s, islock=%s: processing islock, peer=%d\n", __func__,
355+
LogPrint(BCLog::INSTANTSEND, "NetInstantSend::%s -- txid=%s, islock=%s: processing islock, peer=%d\n", __func__,
356356
islock->txid.ToString(), hash.ToString(), from);
357357

358358
if (m_signer) {
@@ -364,21 +364,13 @@ void NetInstantSend::ProcessInstantSendLock(NodeId from, const uint256& hash, co
364364
auto tx = GetTransaction(nullptr, &m_mempool, islock->txid, Params().GetConsensus(), hashBlock);
365365
const bool found_transaction{tx != nullptr};
366366
// we ignore failure here as we must be able to propagate the lock even if we don't have the TX locally
367-
std::optional<int> minedHeight = GetBlockHeight(m_is_manager, m_chainstate, hashBlock);
367+
const auto minedHeight = GetBlockHeight(m_is_manager, m_chainstate, hashBlock);
368368
if (found_transaction) {
369-
if (!minedHeight.has_value()) {
370-
const CBlockIndex* pindexMined = WITH_LOCK(::cs_main,
371-
return m_chainstate.m_blockman.LookupBlockIndex(hashBlock));
372-
if (pindexMined != nullptr) {
373-
m_is_manager.CacheBlockHeight(pindexMined);
374-
minedHeight = pindexMined->nHeight;
375-
}
376-
}
377369
// Let's see if the TX that was locked by this islock is already mined in a ChainLocked block. If yes,
378370
// we can simply ignore the islock, as the ChainLock implies locking of all TXs in that chain
379371
if (minedHeight.has_value() && m_chainlocks.HasChainLock(*minedHeight, hashBlock)) {
380372
LogPrint(BCLog::INSTANTSEND, /* Continued */
381-
"NetSigning::%s -- txlock=%s, islock=%s: dropping islock as it already got a "
373+
"NetInstantSend::%s -- txlock=%s, islock=%s: dropping islock as it already got a "
382374
"ChainLock in block %s, peer=%d\n",
383375
__func__, islock->txid.ToString(), hash.ToString(), hashBlock.ToString(), from);
384376
return;
@@ -388,7 +380,6 @@ void NetInstantSend::ProcessInstantSendLock(NodeId from, const uint256& hash, co
388380
m_is_manager.AddPendingISLock(hash, islock, from);
389381
}
390382

391-
392383
// This will also add children TXs to pendingRetryTxs
393384
m_is_manager.RemoveNonLockedTx(islock->txid, true);
394385
// We don't need the recovered sigs for the inputs anymore. This prevents unnecessary propagation of these sigs.
@@ -398,8 +389,8 @@ void NetInstantSend::ProcessInstantSendLock(NodeId from, const uint256& hash, co
398389

399390
if (found_transaction) {
400391
RemoveMempoolConflictsForLock(hash, *islock);
401-
LogPrint(BCLog::INSTANTSEND, "NetSigning::%s -- notify about lock %s for tx %s\n", __func__, hash.ToString(),
402-
tx->GetHash().ToString());
392+
LogPrint(BCLog::INSTANTSEND, "NetInstantSend::%s -- notify about lock %s for tx %s\n", __func__,
393+
hash.ToString(), tx->GetHash().ToString());
403394
GetMainSignals().NotifyTransactionLock(tx, islock);
404395
// bump m_mempool counter to make sure newly locked txes are picked up by getblocktemplate
405396
m_mempool.AddTransactionsUpdated(1);
@@ -588,7 +579,7 @@ void NetInstantSend::ResolveBlockConflicts(const uint256& islockHash, const inst
588579
return;
589580
}
590581

591-
bool isLockedTxKnown = m_is_manager.IsKnownTx(islockHash);
582+
bool hasTxForLock = m_is_manager.HasTxForLock(islockHash);
592583

593584
bool activateBestChain = false;
594585
for (const auto& p : conflicts) {
@@ -605,7 +596,7 @@ void NetInstantSend::ResolveBlockConflicts(const uint256& islockHash, const inst
605596
// This should not have happened and we are in a state were it's not safe to continue anymore
606597
assert(false);
607598
}
608-
if (isLockedTxKnown) {
599+
if (hasTxForLock) {
609600
activateBestChain = true;
610601
} else {
611602
LogPrintf("NetInstantSend::%s -- resetting block %s\n", __func__, pindex2->GetBlockHash().ToString());

src/instantsend/signing.cpp

Lines changed: 12 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -206,19 +206,20 @@ bool InstantSendSigner::CheckCanLock(const COutPoint& outpoint, bool printDebug,
206206

207207
int blockHeight{0};
208208
if (!hashBlock.IsNull()) {
209-
auto ret = m_isman.GetCachedHeight(hashBlock);
210-
if (ret) blockHeight = *ret;
211-
212-
const CBlockIndex* pindex = WITH_LOCK(::cs_main, return m_chainstate.m_blockman.LookupBlockIndex(hashBlock));
213-
if (pindex == nullptr) {
214-
if (printDebug) {
215-
LogPrint(BCLog::INSTANTSEND, "%s -- txid=%s: failed to determine mined height for parent TX %s\n",
216-
__func__, txHash.ToString(), outpoint.hash.ToString());
209+
if (auto ret = m_isman.GetCachedHeight(hashBlock)) {
210+
blockHeight = *ret;
211+
} else {
212+
const CBlockIndex* pindex = WITH_LOCK(::cs_main, return m_chainstate.m_blockman.LookupBlockIndex(hashBlock));
213+
if (pindex == nullptr) {
214+
if (printDebug) {
215+
LogPrint(BCLog::INSTANTSEND, "%s -- txid=%s: failed to determine mined height for parent TX %s\n",
216+
__func__, txHash.ToString(), outpoint.hash.ToString());
217+
}
218+
return false;
217219
}
218-
return false;
220+
m_isman.CacheBlockHeight(pindex);
221+
blockHeight = pindex->nHeight;
219222
}
220-
m_isman.CacheBlockHeight(pindex);
221-
blockHeight = pindex->nHeight;
222223
}
223224

224225
const int tipHeight = m_isman.GetTipHeight();

0 commit comments

Comments
 (0)