@@ -440,10 +440,16 @@ CTxMemPool::CTxMemPool(CBlockPolicyEstimator* estimator, int check_ratio)
440440void CTxMemPool::ConnectManagers (gsl::not_null<CDeterministicMNManager*> dmnman, gsl::not_null<llmq::CInstantSendManager*> isman)
441441{
442442 // Do not allow double-initialization
443- assert (m_dmnman == nullptr );
444- m_dmnman = dmnman;
445- assert (m_isman == nullptr );
446- m_isman = isman;
443+ assert (m_dmnman.load (std::memory_order_acquire) == nullptr );
444+ m_dmnman.store (dmnman, std::memory_order_release);
445+ assert (m_isman.load (std::memory_order_acquire) == nullptr );
446+ m_isman.store (isman, std::memory_order_release);
447+ }
448+
449+ void CTxMemPool::DisconnectManagers ()
450+ {
451+ m_dmnman.store (nullptr , std::memory_order_release);
452+ m_isman.store (nullptr , std::memory_order_release);
447453}
448454
449455bool CTxMemPool::isSpent (const COutPoint& outpoint) const
@@ -516,8 +522,8 @@ void CTxMemPool::addUnchecked(const CTxMemPoolEntry &entry, setEntries &setAnces
516522 // Invalid ProTxes should never get this far because transactions should be
517523 // fully checked by AcceptToMemoryPool() at this point, so we just assume that
518524 // everything is fine here.
519- if (m_dmnman) {
520- addUncheckedProTx (newit, tx);
525+ if (auto dmnman = m_dmnman. load (std::memory_order_acquire); dmnman ) {
526+ addUncheckedProTx (*dmnman, newit, tx);
521527 }
522528}
523529
@@ -641,10 +647,9 @@ void CTxMemPool::removeSpentIndex(const uint256 txhash)
641647 }
642648}
643649
644- void CTxMemPool::addUncheckedProTx (indexed_transaction_set::iterator& newit, const CTransaction& tx)
650+ void CTxMemPool::addUncheckedProTx (CDeterministicMNManager& dmnman, indexed_transaction_set::iterator& newit,
651+ const CTransaction& tx)
645652{
646- assert (m_dmnman);
647-
648653 const uint256 tx_hash{tx.GetHash ()};
649654 if (tx.nType == TRANSACTION_PROVIDER_REGISTER) {
650655 auto proTx = *Assert (GetTxPayload<CProRegTx>(tx));
@@ -671,15 +676,15 @@ void CTxMemPool::addUncheckedProTx(indexed_transaction_set::iterator& newit, con
671676 auto proTx = *Assert (GetTxPayload<CProUpRegTx>(tx));
672677 mapProTxRefs.emplace (proTx.proTxHash , tx_hash);
673678 mapProTxBlsPubKeyHashes.emplace (proTx.pubKeyOperator .GetHash (), tx_hash);
674- auto dmn = Assert (m_dmnman-> GetListAtChainTip ().GetMN (proTx.proTxHash ));
679+ auto dmn = Assert (dmnman. GetListAtChainTip ().GetMN (proTx.proTxHash ));
675680 newit->validForProTxKey = ::SerializeHash (dmn->pdmnState ->pubKeyOperator );
676681 if (dmn->pdmnState ->pubKeyOperator != proTx.pubKeyOperator ) {
677682 newit->isKeyChangeProTx = true ;
678683 }
679684 } else if (tx.nType == TRANSACTION_PROVIDER_UPDATE_REVOKE) {
680685 auto proTx = *Assert (GetTxPayload<CProUpRevTx>(tx));
681686 mapProTxRefs.emplace (proTx.proTxHash , tx_hash);
682- auto dmn = Assert (m_dmnman-> GetListAtChainTip ().GetMN (proTx.proTxHash ));
687+ auto dmn = Assert (dmnman. GetListAtChainTip ().GetMN (proTx.proTxHash ));
683688 newit->validForProTxKey = ::SerializeHash (dmn->pdmnState ->pubKeyOperator );
684689 if (dmn->pdmnState ->pubKeyOperator .Get () != CBLSPublicKey ()) {
685690 newit->isKeyChangeProTx = true ;
@@ -721,7 +726,7 @@ void CTxMemPool::removeUnchecked(txiter it, MemPoolRemovalReason reason)
721726 } else
722727 vTxHashes.clear ();
723728
724- if (m_dmnman) {
729+ if (m_dmnman. load (std::memory_order_acquire) ) {
725730 removeUncheckedProTx (it->GetTx ());
726731 }
727732
@@ -926,7 +931,7 @@ void CTxMemPool::removeProTxCollateralConflicts(const CTransaction &tx, const CO
926931
927932void CTxMemPool::removeProTxSpentCollateralConflicts (const CTransaction &tx)
928933{
929- assert (m_dmnman);
934+ auto dmnman = Assert (m_dmnman. load (std::memory_order_acquire) );
930935
931936 // Remove TXs that refer to a MN for which the collateral was spent
932937 auto removeSpentCollateralConflict = [&](const uint256& proTxHash) EXCLUSIVE_LOCKS_REQUIRED (cs) {
@@ -948,7 +953,7 @@ void CTxMemPool::removeProTxSpentCollateralConflicts(const CTransaction &tx)
948953 }
949954 }
950955 };
951- auto mnList = m_dmnman ->GetListAtChainTip ();
956+ auto mnList = dmnman ->GetListAtChainTip ();
952957 for (const auto & in : tx.vin ) {
953958 auto collateralIt = mapProTxCollaterals.find (in.prevout );
954959 if (collateralIt != mapProTxCollaterals.end ()) {
@@ -1070,7 +1075,7 @@ void CTxMemPool::removeForBlock(const std::vector<CTransactionRef>& vtx, unsigne
10701075 RemoveStaged (stage, true , MemPoolRemovalReason::BLOCK);
10711076 }
10721077 removeConflicts (*tx);
1073- if (m_dmnman) {
1078+ if (m_dmnman. load (std::memory_order_acquire) ) {
10741079 removeProTxConflicts (*tx);
10751080 }
10761081 ClearPrioritisation (tx->GetHash ());
@@ -1328,7 +1333,7 @@ TxMempoolInfo CTxMemPool::info(const uint256& hash) const
13281333}
13291334
13301335bool CTxMemPool::existsProviderTxConflict (const CTransaction &tx) const {
1331- assert (m_dmnman);
1336+ auto dmnman = Assert (m_dmnman. load (std::memory_order_acquire) );
13321337
13331338 LOCK (cs);
13341339
@@ -1394,7 +1399,7 @@ bool CTxMemPool::existsProviderTxConflict(const CTransaction &tx) const {
13941399 auto & proTx = *opt_proTx;
13951400
13961401 // this method should only be called with validated ProTxs
1397- auto dmn = m_dmnman ->GetListAtChainTip ().GetMN (proTx.proTxHash );
1402+ auto dmn = dmnman ->GetListAtChainTip ().GetMN (proTx.proTxHash );
13981403 if (!dmn) {
13991404 LogPrint (BCLog::MEMPOOL, " %s: ERROR: Masternode is not in the list, proTxHash: %s\n " , __func__, proTx.proTxHash .ToString ());
14001405 return true ; // i.e. failed to find validated ProTx == conflict
@@ -1416,7 +1421,7 @@ bool CTxMemPool::existsProviderTxConflict(const CTransaction &tx) const {
14161421 }
14171422 auto & proTx = *opt_proTx;
14181423 // this method should only be called with validated ProTxs
1419- auto dmn = m_dmnman ->GetListAtChainTip ().GetMN (proTx.proTxHash );
1424+ auto dmn = dmnman ->GetListAtChainTip ().GetMN (proTx.proTxHash );
14201425 if (!dmn) {
14211426 LogPrint (BCLog::MEMPOOL, " %s: ERROR: Masternode is not in the list, proTxHash: %s\n " , __func__, proTx.proTxHash .ToString ());
14221427 return true ; // i.e. failed to find validated ProTx == conflict
@@ -1566,12 +1571,12 @@ void CTxMemPool::RemoveStaged(setEntries &stage, bool updateDescendants, MemPool
15661571int CTxMemPool::Expire (std::chrono::seconds time)
15671572{
15681573 AssertLockHeld (cs);
1569- assert (m_isman);
1574+ auto isman = Assert (m_isman. load (std::memory_order_acquire) );
15701575 indexed_transaction_set::index<entry_time>::type::iterator it = mapTx.get <entry_time>().begin ();
15711576 setEntries toremove;
15721577 while (it != mapTx.get <entry_time>().end () && it->GetTime () < time) {
15731578 // locked txes do not expire until mined and have sufficient confirmations
1574- if (m_isman ->IsLocked (it->GetTx ().GetHash ())) {
1579+ if (isman ->IsLocked (it->GetTx ().GetHash ())) {
15751580 it++;
15761581 continue ;
15771582 }
0 commit comments