@@ -43,6 +43,21 @@ using node::GetTransaction;
4343namespace llmq {
4444static const std::string_view INPUTLOCK_REQUESTID_PREFIX = " inlock" ;
4545
46+ namespace {
47+ template <typename T>
48+ requires std::same_as<T, CTxIn> || std::same_as<T, COutPoint>
49+ std::unordered_set<uint256, StaticSaltedHasher> GetIdsFromLockable (const std::vector<T>& vec)
50+ {
51+ std::unordered_set<uint256, StaticSaltedHasher> ret{};
52+ if (vec.empty ()) return ret;
53+ ret.reserve (vec.size ());
54+ for (const auto & in : vec) {
55+ ret.emplace (::SerializeHash (std::make_pair (INPUTLOCK_REQUESTID_PREFIX, in)));
56+ }
57+ return ret;
58+ }
59+ } // anonymous namespace
60+
4661CInstantSendManager::CInstantSendManager (CChainLocksHandler& _clhandler, CChainState& chainstate, CQuorumManager& _qman,
4762 CSigningManager& _sigman, CSigSharesManager& _shareman,
4863 CSporkManager& sporkman, CTxMemPool& _mempool, const CMasternodeSync& mn_sync,
@@ -74,14 +89,14 @@ void CInstantSendManager::Start(PeerManager& peerman)
7489 workThread = std::thread (&util::TraceThread, " isman" , [this , &peerman] { WorkThreadMain (peerman); });
7590
7691 if (m_signer) {
77- sigman. RegisterRecoveredSigsListener ( m_signer. get () );
92+ m_signer-> Start ( );
7893 }
7994}
8095
8196void CInstantSendManager::Stop ()
8297{
8398 if (m_signer) {
84- sigman. UnregisterRecoveredSigsListener ( m_signer. get () );
99+ m_signer-> Stop ( );
85100 }
86101
87102 // make sure to call InterruptWorkerThread() first
@@ -344,9 +359,7 @@ void CInstantSendManager::ProcessInstantSendLock(NodeId from, PeerManager& peerm
344359 LogPrint (BCLog::INSTANTSEND, " CInstantSendManager::%s -- txid=%s, islock=%s: processing islock, peer=%d\n " , __func__,
345360 islock->txid .ToString (), hash.ToString (), from);
346361 if (m_signer) {
347- LOCK (m_signer->cs_creating );
348- m_signer->creatingInstantSendLocks .erase (islock->GetRequestId ());
349- m_signer->txToCreatingInstantSendLocks .erase (islock->txid );
362+ m_signer->ClearLockFromQueue (islock);
350363 }
351364 if (db.KnownInstantSendLock (hash)) {
352365 return ;
@@ -592,23 +605,28 @@ void CInstantSendManager::RemoveNonLockedTx(const uint256& txid, bool retryChild
592605void CInstantSendManager::RemoveConflictedTx (const CTransaction& tx)
593606{
594607 RemoveNonLockedTx (tx.GetHash (), false );
595- if (!m_signer) return ;
596-
597- LOCK (m_signer->cs_inputReqests );
598- for (const auto & in : tx.vin ) {
599- auto inputRequestId = ::SerializeHash (std::make_pair (INPUTLOCK_REQUESTID_PREFIX, in));
600- m_signer->inputRequestIds .erase (inputRequestId);
608+ if (m_signer) {
609+ m_signer->ClearInputsFromQueue (GetIdsFromLockable (tx.vin ));
601610 }
602611}
603612
604613void CInstantSendManager::TruncateRecoveredSigsForInputs (const llmq::CInstantSendLock& islock)
605614{
606- if (!m_signer) return ;
615+ auto ids = GetIdsFromLockable (islock.inputs );
616+ if (m_signer) {
617+ m_signer->ClearInputsFromQueue (ids);
618+ }
619+ for (const auto & id : ids) {
620+ sigman.TruncateRecoveredSig (Params ().GetConsensus ().llmqTypeDIP0024InstantSend , id);
621+ }
622+ }
607623
608- for (const auto & in : islock.inputs ) {
609- auto inputRequestId = ::SerializeHash (std::make_pair (INPUTLOCK_REQUESTID_PREFIX, in));
610- WITH_LOCK (m_signer->cs_inputReqests , m_signer->inputRequestIds .erase (inputRequestId));
611- sigman.TruncateRecoveredSig (Params ().GetConsensus ().llmqTypeDIP0024InstantSend , inputRequestId);
624+ void CInstantSendManager::TryEmplacePendingLock (const uint256& hash, const NodeId id, const CInstantSendLockPtr& islock)
625+ {
626+ if (db.KnownInstantSendLock (hash)) return ;
627+ LOCK (cs_pendingLocks);
628+ if (!pendingInstantSendLocks.count (hash)) {
629+ pendingInstantSendLocks.emplace (hash, std::make_pair (id, islock));
612630 }
613631}
614632
@@ -910,10 +928,29 @@ size_t CInstantSendManager::GetInstantSendLockCount() const
910928void CInstantSendManager::WorkThreadMain (PeerManager& peerman)
911929{
912930 while (!workInterrupt) {
913- bool fMoreWork = ProcessPendingInstantSendLocks (peerman);
914- if (m_signer) {
915- m_signer->ProcessPendingRetryLockTxs ();
916- }
931+ bool fMoreWork = [&]() -> bool {
932+ if (!IsInstantSendEnabled ()) return false ;
933+ const bool more_work{ProcessPendingInstantSendLocks (peerman)};
934+ if (!m_signer) return more_work;
935+ // Construct set of non-locked transactions that are pending to retry
936+ std::vector<CTransactionRef> txns{};
937+ {
938+ LOCK2 (cs_nonLocked, cs_pendingRetry);
939+ if (pendingRetryTxs.empty ()) return more_work;
940+ txns.reserve (pendingRetryTxs.size ());
941+ for (const auto & txid : pendingRetryTxs) {
942+ if (auto it = nonLockedTxs.find (txid); it != nonLockedTxs.end ()) {
943+ const auto & [_, tx_info] = *it;
944+ if (tx_info.tx ) {
945+ txns.push_back (tx_info.tx );
946+ }
947+ }
948+ }
949+ }
950+ // Retry processing them
951+ m_signer->ProcessPendingRetryLockTxs (txns);
952+ return more_work;
953+ }();
917954
918955 if (!fMoreWork && !workInterrupt.sleep_for (std::chrono::milliseconds (100 ))) {
919956 return ;
0 commit comments