@@ -440,10 +440,16 @@ CTxMemPool::CTxMemPool(CBlockPolicyEstimator* estimator, int check_ratio)
440
440
void CTxMemPool::ConnectManagers (gsl::not_null<CDeterministicMNManager*> dmnman, gsl::not_null<llmq::CInstantSendManager*> isman)
441
441
{
442
442
// 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);
447
453
}
448
454
449
455
bool CTxMemPool::isSpent (const COutPoint& outpoint) const
@@ -516,8 +522,8 @@ void CTxMemPool::addUnchecked(const CTxMemPoolEntry &entry, setEntries &setAnces
516
522
// Invalid ProTxes should never get this far because transactions should be
517
523
// fully checked by AcceptToMemoryPool() at this point, so we just assume that
518
524
// 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);
521
527
}
522
528
}
523
529
@@ -641,10 +647,9 @@ void CTxMemPool::removeSpentIndex(const uint256 txhash)
641
647
}
642
648
}
643
649
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)
645
652
{
646
- assert (m_dmnman);
647
-
648
653
const uint256 tx_hash{tx.GetHash ()};
649
654
if (tx.nType == TRANSACTION_PROVIDER_REGISTER) {
650
655
auto proTx = *Assert (GetTxPayload<CProRegTx>(tx));
@@ -671,15 +676,15 @@ void CTxMemPool::addUncheckedProTx(indexed_transaction_set::iterator& newit, con
671
676
auto proTx = *Assert (GetTxPayload<CProUpRegTx>(tx));
672
677
mapProTxRefs.emplace (proTx.proTxHash , tx_hash);
673
678
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 ));
675
680
newit->validForProTxKey = ::SerializeHash (dmn->pdmnState ->pubKeyOperator );
676
681
if (dmn->pdmnState ->pubKeyOperator != proTx.pubKeyOperator ) {
677
682
newit->isKeyChangeProTx = true ;
678
683
}
679
684
} else if (tx.nType == TRANSACTION_PROVIDER_UPDATE_REVOKE) {
680
685
auto proTx = *Assert (GetTxPayload<CProUpRevTx>(tx));
681
686
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 ));
683
688
newit->validForProTxKey = ::SerializeHash (dmn->pdmnState ->pubKeyOperator );
684
689
if (dmn->pdmnState ->pubKeyOperator .Get () != CBLSPublicKey ()) {
685
690
newit->isKeyChangeProTx = true ;
@@ -721,7 +726,7 @@ void CTxMemPool::removeUnchecked(txiter it, MemPoolRemovalReason reason)
721
726
} else
722
727
vTxHashes.clear ();
723
728
724
- if (m_dmnman) {
729
+ if (m_dmnman. load (std::memory_order_acquire) ) {
725
730
removeUncheckedProTx (it->GetTx ());
726
731
}
727
732
@@ -926,7 +931,7 @@ void CTxMemPool::removeProTxCollateralConflicts(const CTransaction &tx, const CO
926
931
927
932
void CTxMemPool::removeProTxSpentCollateralConflicts (const CTransaction &tx)
928
933
{
929
- assert (m_dmnman);
934
+ auto dmnman = Assert (m_dmnman. load (std::memory_order_acquire) );
930
935
931
936
// Remove TXs that refer to a MN for which the collateral was spent
932
937
auto removeSpentCollateralConflict = [&](const uint256& proTxHash) EXCLUSIVE_LOCKS_REQUIRED (cs) {
@@ -948,7 +953,7 @@ void CTxMemPool::removeProTxSpentCollateralConflicts(const CTransaction &tx)
948
953
}
949
954
}
950
955
};
951
- auto mnList = m_dmnman ->GetListAtChainTip ();
956
+ auto mnList = dmnman ->GetListAtChainTip ();
952
957
for (const auto & in : tx.vin ) {
953
958
auto collateralIt = mapProTxCollaterals.find (in.prevout );
954
959
if (collateralIt != mapProTxCollaterals.end ()) {
@@ -1070,7 +1075,7 @@ void CTxMemPool::removeForBlock(const std::vector<CTransactionRef>& vtx, unsigne
1070
1075
RemoveStaged (stage, true , MemPoolRemovalReason::BLOCK);
1071
1076
}
1072
1077
removeConflicts (*tx);
1073
- if (m_dmnman) {
1078
+ if (m_dmnman. load (std::memory_order_acquire) ) {
1074
1079
removeProTxConflicts (*tx);
1075
1080
}
1076
1081
ClearPrioritisation (tx->GetHash ());
@@ -1328,7 +1333,7 @@ TxMempoolInfo CTxMemPool::info(const uint256& hash) const
1328
1333
}
1329
1334
1330
1335
bool CTxMemPool::existsProviderTxConflict (const CTransaction &tx) const {
1331
- assert (m_dmnman);
1336
+ auto dmnman = Assert (m_dmnman. load (std::memory_order_acquire) );
1332
1337
1333
1338
LOCK (cs);
1334
1339
@@ -1394,7 +1399,7 @@ bool CTxMemPool::existsProviderTxConflict(const CTransaction &tx) const {
1394
1399
auto & proTx = *opt_proTx;
1395
1400
1396
1401
// 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 );
1398
1403
if (!dmn) {
1399
1404
LogPrint (BCLog::MEMPOOL, " %s: ERROR: Masternode is not in the list, proTxHash: %s\n " , __func__, proTx.proTxHash .ToString ());
1400
1405
return true ; // i.e. failed to find validated ProTx == conflict
@@ -1416,7 +1421,7 @@ bool CTxMemPool::existsProviderTxConflict(const CTransaction &tx) const {
1416
1421
}
1417
1422
auto & proTx = *opt_proTx;
1418
1423
// 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 );
1420
1425
if (!dmn) {
1421
1426
LogPrint (BCLog::MEMPOOL, " %s: ERROR: Masternode is not in the list, proTxHash: %s\n " , __func__, proTx.proTxHash .ToString ());
1422
1427
return true ; // i.e. failed to find validated ProTx == conflict
@@ -1566,12 +1571,12 @@ void CTxMemPool::RemoveStaged(setEntries &stage, bool updateDescendants, MemPool
1566
1571
int CTxMemPool::Expire (std::chrono::seconds time)
1567
1572
{
1568
1573
AssertLockHeld (cs);
1569
- assert (m_isman);
1574
+ auto isman = Assert (m_isman. load (std::memory_order_acquire) );
1570
1575
indexed_transaction_set::index<entry_time>::type::iterator it = mapTx.get <entry_time>().begin ();
1571
1576
setEntries toremove;
1572
1577
while (it != mapTx.get <entry_time>().end () && it->GetTime () < time) {
1573
1578
// 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 ())) {
1575
1580
it++;
1576
1581
continue ;
1577
1582
}
0 commit comments