@@ -353,18 +353,32 @@ void CInstantSendManager::ProcessInstantSendLock(NodeId from, PeerManager& peerm
353353{
354354 LogPrint (BCLog::INSTANTSEND, " CInstantSendManager::%s -- txid=%s, islock=%s: processing islock, peer=%d\n " ,
355355 __func__, islock->txid .ToString (), hash.ToString (), from);
356+
356357 if (m_signer) {
357358 m_signer->ClearLockFromQueue (islock);
358359 }
359360 if (db.KnownInstantSendLock (hash)) {
360361 return ;
361362 }
362363
364+ if (const auto sameTxIsLock = db.GetInstantSendLockByTxid (islock->txid )) {
365+ // can happen, nothing to do
366+ return ;
367+ }
368+ for (const auto & in : islock->inputs ) {
369+ const auto sameOutpointIsLock = db.GetInstantSendLockByInput (in);
370+ if (sameOutpointIsLock != nullptr ) {
371+ LogPrintf (" CInstantSendManager::%s -- txid=%s, islock=%s: conflicting outpoint in islock. input=%s, other islock=%s, peer=%d\n " , __func__,
372+ islock->txid .ToString (), hash.ToString (), in.ToStringShort (), ::SerializeHash (*sameOutpointIsLock).ToString (), from);
373+ }
374+ }
375+
363376 uint256 hashBlock{};
364377 const auto tx = GetTransaction (nullptr , &mempool, islock->txid , Params ().GetConsensus (), hashBlock);
365378 const CBlockIndex* pindexMined{nullptr };
379+ const bool found_transaction{tx != nullptr };
366380 // we ignore failure here as we must be able to propagate the lock even if we don't have the TX locally
367- if (tx && !hashBlock.IsNull ()) {
381+ if (found_transaction && !hashBlock.IsNull ()) {
368382 pindexMined = WITH_LOCK (::cs_main, return m_chainstate.m_blockman .LookupBlockIndex (hashBlock));
369383
370384 // Let's see if the TX that was locked by this islock is already mined in a ChainLocked block. If yes,
@@ -376,55 +390,40 @@ void CInstantSendManager::ProcessInstantSendLock(NodeId from, PeerManager& peerm
376390 }
377391 }
378392
379- const auto sameTxIsLock = db.GetInstantSendLockByTxid (islock->txid );
380- if (sameTxIsLock != nullptr ) {
381- // can happen, nothing to do
382- return ;
383- }
384- for (const auto & in : islock->inputs ) {
385- const auto sameOutpointIsLock = db.GetInstantSendLockByInput (in);
386- if (sameOutpointIsLock != nullptr ) {
387- LogPrintf (" CInstantSendManager::%s -- txid=%s, islock=%s: conflicting outpoint in islock. input=%s, other islock=%s, peer=%d\n " , __func__,
388- islock->txid .ToString (), hash.ToString (), in.ToStringShort (), ::SerializeHash (*sameOutpointIsLock).ToString (), from);
389- }
390- }
391-
392- if (tx == nullptr ) {
393- // put it in a separate pending map and try again later
394- LOCK (cs_pendingLocks);
395- pendingNoTxInstantSendLocks.try_emplace (hash, std::make_pair (from, islock));
396- } else {
393+ if (found_transaction) {
397394 db.WriteNewInstantSendLock (hash, islock);
398395 if (pindexMined) {
399396 db.WriteInstantSendLockMined (hash, pindexMined->nHeight );
400397 }
398+ } else {
399+ // put it in a separate pending map and try again later
400+ LOCK (cs_pendingLocks);
401+ pendingNoTxInstantSendLocks.try_emplace (hash, std::make_pair (from, islock));
401402 }
402403
403404 // This will also add children TXs to pendingRetryTxs
404405 RemoveNonLockedTx (islock->txid , true );
405406 // We don't need the recovered sigs for the inputs anymore. This prevents unnecessary propagation of these sigs.
406407 // We only need the ISLOCK from now on to detect conflicts
407408 TruncateRecoveredSigsForInputs (*islock);
408-
409- CInv inv (MSG_ISDLOCK, hash);
410- if (tx != nullptr ) {
411- peerman.RelayInvFiltered (inv, *tx, ISDLOCK_PROTO_VERSION);
412- } else {
413- // we don't have the TX yet, so we only filter based on txid. Later when that TX arrives, we will re-announce
414- // with the TX taken into account.
415- peerman.RelayInvFiltered (inv, islock->txid , ISDLOCK_PROTO_VERSION);
416- }
417-
418409 ResolveBlockConflicts (hash, *islock);
419410
420- if (tx != nullptr ) {
411+ if (found_transaction ) {
421412 RemoveMempoolConflictsForLock (peerman, hash, *islock);
422413 LogPrint (BCLog::INSTANTSEND, " CInstantSendManager::%s -- notify about lock %s for tx %s\n " , __func__,
423414 hash.ToString (), tx->GetHash ().ToString ());
424415 GetMainSignals ().NotifyTransactionLock (tx, islock);
425416 // bump mempool counter to make sure newly locked txes are picked up by getblocktemplate
426417 mempool.AddTransactionsUpdated (1 );
418+ }
419+
420+ CInv inv (MSG_ISDLOCK, hash);
421+ if (found_transaction) {
422+ peerman.RelayInvFiltered (inv, *tx, ISDLOCK_PROTO_VERSION);
427423 } else {
424+ // we don't have the TX yet, so we only filter based on txid. Later when that TX arrives, we will re-announce
425+ // with the TX taken into account.
426+ peerman.RelayInvFiltered (inv, islock->txid , ISDLOCK_PROTO_VERSION);
428427 peerman.AskPeersForTransaction (islock->txid , /* is_masternode=*/ m_signer != nullptr );
429428 }
430429}
0 commit comments