Merge #5987: refactor: reduce fMasternodeMode usage, remove fDisableGovernance global

b4477e409c trivial: don't print `fDisableGovernance` value anymore (Kittywhiskers Van Gogh)
a42370df93 refactor: remove fDisableGovernance global, define default in variable (Kittywhiskers Van Gogh)
b1527599e4 refactor: remove fMasternodeMode and fDisableGovernance from Qt code (Kittywhiskers Van Gogh)
9402ce7171 refactor: limit usage of fDisableGovernance, use `IsValid()` instead (Kittywhiskers Van Gogh)
106f6bdd4e refactor: reduce fMasternodeMode usage in governance and mnauth (Kittywhiskers Van Gogh)
3ba293fbcc refactor: remove fMasternodeMode checks in CActiveMasternodeManager (Kittywhiskers Van Gogh)
b0216ac8a6 refactor: remove fMasternodeMode usage in rpc logic (Kittywhiskers Van Gogh)
4d629a04fb refactor: limit fMasternodeMode usage in blockstorage, init, net_processing (Kittywhiskers Van Gogh)
a9cbdfcebc refactor: remove fMasternodeMode usage from llmq logic (Kittywhiskers Van Gogh)
c62a3d5778 refactor: remove fMasternodeMode usage from coinjoin logic (Kittywhiskers Van Gogh)

Pull request description:

  ## Motivation

  Since https://github.com/dashpay/dash/pull/5940, `CActiveMasternodeManager` ceased to be a global variable and became a conditional smart pointer initialized based on the value of `fMasternodeMode`.

  Likewise, since https://github.com/dashpay/dash/pull/5555, we can tell if any `CFlatDB`-based manager has successfully loaded its database. `CGovernanceManager` is one of them and conditionally loads its database based on the value of `fGovernanceDisabled`.

  `fMasternodeMode` and `fGovernanceDisabled` were (and the former to a certain degree still is) unavoidable globals due to the way the functionality they influenced was structured (i.e. decided in initialization code with no way to query from the manager itself). As we can directly ask the managers now, we can start reducing the usage of these globals and at least in this PR, get rid of one of them.

  This PR was the idea of PastaPastaPasta, special thanks for the suggestion!

  ## Additional Information

  * There are two conventions being used for checking `nullptr`-ity of a pointer, `if (mn_activeman)` and `if (mn_activeman != nullptr)`. The former is used in initialization and RPC code due to existing conventions there ([source](2dacfb08bd/src/init.cpp (L1659-L1677)), [source](2dacfb08bd/src/rpc/net.cpp (L942-L945)), [source](2dacfb08bd/src/rpc/misc.cpp (L215-L218))). The latter is used whenever the value has to be passed as a `bool` (you cannot pass the implicit conversion to a `bool` argument without explicitly casting it) and in Dash-specific code where it is the prevalent convention ([source](2dacfb08bd/src/governance/governance.cpp (L125)), [source](2dacfb08bd/src/coinjoin/client.cpp (L1064))).

    Unfortunately, that means this PR expresses the same thing sometimes in two different ways but this approach was taken so that reading is consistent within the same file. Codebase-wide harmonization is outside the scope of this PR.

  * Where `mn_activeman` isn't directly available, the result of the check is passed as an argument named `is_masternode` and/or set for the manager during its construction as `m_is_masternode` (`const bool`) as it is expected for the `CActiveMasternodeManager`'s presence or absence to remain as-is for the duration of the manager's lifetime.

    This does mean that some parts of the codebase check for `mn_activeman` while others check for {`m_`}`is_masternode`, which does reduce clarity while reading. Suggestions on improving this are welcomed.

  * One of the reasons this PR was made was to avoid having to deal the _possibility_ of `fMasternodeMode` or `fDisableGovernance` from desynchronizing from the behaviour of the managers it's suppose to influence. It's why additional assertions were placed in to make sure that `fMasternodeMode` and the existence of `mn_activeman` were always in sync ([source](2dacfb08bd/src/evo/mnauth.cpp (L137-L139)), [source](2dacfb08bd/src/rpc/governance.cpp (L319-L320))).

    But removing the tracking global and relying on a manager's state itself prevents a potential desync, which is what this PR is aiming to do.

  ## Breaking Changes

  None expected.

  ## Checklist:

  - [x] I have performed a self-review of my own code
  - [x] I have commented my code, particularly in hard-to-understand areas
  - [x] I have added or updated relevant unit/integration/functional/e2e tests
  - [x] I have made corresponding changes to the documentation **(note: N/A)**
  - [x] I have assigned this pull request to a milestone _(for repository code-owners and collaborators only)_

Top commit has no ACKs.

Tree-SHA512: 7861afd17c83b92af4c95b2841e9b0f676116eb3f234c4d0b1dcd3c20395452893e8ca3a17c7225389c8411dac80aeb5050f06a2ae35df5ec48998a571ef120c
This commit is contained in:
pasta 2024-04-26 11:02:29 -05:00
commit f9e123efd6
No known key found for this signature in database
GPG Key ID: 52527BEDABE87984
43 changed files with 206 additions and 191 deletions

View File

@ -31,7 +31,7 @@
PeerMsgRet CCoinJoinClientQueueManager::ProcessMessage(const CNode& peer, std::string_view msg_type, CDataStream& vRecv)
{
if (fMasternodeMode) return {};
if (m_is_masternode) return {};
if (!m_mn_sync.IsBlockchainSynced()) return {};
if (msg_type == NetMsgType::DSQUEUE) {
@ -133,7 +133,7 @@ PeerMsgRet CCoinJoinClientQueueManager::ProcessDSQueue(const CNode& peer, CDataS
void CCoinJoinClientManager::ProcessMessage(CNode& peer, CConnman& connman, const CTxMemPool& mempool, std::string_view msg_type, CDataStream& vRecv)
{
if (fMasternodeMode) return;
if (m_is_masternode) return;
if (!CCoinJoinClientOptions::IsEnabled()) return;
if (!m_mn_sync.IsBlockchainSynced()) return;
@ -156,19 +156,20 @@ void CCoinJoinClientManager::ProcessMessage(CNode& peer, CConnman& connman, cons
}
CCoinJoinClientSession::CCoinJoinClientSession(CWallet& wallet, CoinJoinWalletManager& walletman, CDeterministicMNManager& dmnman, CMasternodeMetaMan& mn_metaman,
const CMasternodeSync& mn_sync, const std::unique_ptr<CCoinJoinClientQueueManager>& queueman) :
const CMasternodeSync& mn_sync, const std::unique_ptr<CCoinJoinClientQueueManager>& queueman, bool is_masternode) :
m_wallet(wallet),
m_walletman(walletman),
m_manager(*Assert(walletman.Get(wallet.GetName()))),
m_dmnman(dmnman),
m_mn_metaman(mn_metaman),
m_mn_sync(mn_sync),
m_queueman(queueman)
m_queueman(queueman),
m_is_masternode{is_masternode}
{}
void CCoinJoinClientSession::ProcessMessage(CNode& peer, CConnman& connman, const CTxMemPool& mempool, std::string_view msg_type, CDataStream& vRecv)
{
if (fMasternodeMode) return;
if (m_is_masternode) return;
if (!CCoinJoinClientOptions::IsEnabled()) return;
if (!m_mn_sync.IsBlockchainSynced()) return;
@ -385,7 +386,7 @@ bool CCoinJoinClientManager::GetMixingMasternodesInfo(std::vector<CDeterministic
//
bool CCoinJoinClientSession::CheckTimeout()
{
if (fMasternodeMode) return false;
if (m_is_masternode) return false;
if (nState == POOL_STATE_IDLE) return false;
@ -422,7 +423,7 @@ bool CCoinJoinClientSession::CheckTimeout()
void CCoinJoinClientManager::CheckTimeout()
{
AssertLockNotHeld(cs_deqsessions);
if (fMasternodeMode) return;
if (m_is_masternode) return;
if (!CCoinJoinClientOptions::IsEnabled() || !IsMixing()) return;
@ -440,7 +441,7 @@ void CCoinJoinClientManager::CheckTimeout()
//
bool CCoinJoinClientSession::SendDenominate(const std::vector<std::pair<CTxDSIn, CTxOut> >& vecPSInOutPairsIn, CConnman& connman)
{
if (fMasternodeMode) {
if (m_is_masternode) {
WalletCJLogPrint(m_wallet, "CCoinJoinClientSession::SendDenominate -- CoinJoin from a Masternode is not supported currently.\n");
return false;
}
@ -497,7 +498,7 @@ bool CCoinJoinClientSession::SendDenominate(const std::vector<std::pair<CTxDSIn,
// Process incoming messages from Masternode updating the progress of mixing
void CCoinJoinClientSession::ProcessPoolStateUpdate(CCoinJoinStatusUpdate psssup)
{
if (fMasternodeMode) return;
if (m_is_masternode) return;
// do not update state when mixing client state is one of these
if (nState == POOL_STATE_IDLE || nState == POOL_STATE_ERROR) return;
@ -551,7 +552,7 @@ bool CCoinJoinClientSession::SignFinalTransaction(const CTxMemPool& mempool, con
{
if (!CCoinJoinClientOptions::IsEnabled()) return false;
if (fMasternodeMode) return false;
if (m_is_masternode) return false;
if (!mixingMasternode) return false;
LOCK(m_wallet.cs_wallet);
@ -680,7 +681,7 @@ bool CCoinJoinClientSession::SignFinalTransaction(const CTxMemPool& mempool, con
// mixing transaction was completed (failed or successful)
void CCoinJoinClientSession::CompletedTransaction(PoolMessage nMessageID)
{
if (fMasternodeMode) return;
if (m_is_masternode) return;
if (nMessageID == MSG_SUCCESS) {
m_manager.UpdatedSuccessBlock();
@ -697,7 +698,7 @@ void CCoinJoinClientSession::CompletedTransaction(PoolMessage nMessageID)
void CCoinJoinClientManager::UpdatedSuccessBlock()
{
if (fMasternodeMode) return;
if (m_is_masternode) return;
nCachedLastSuccessBlock = nCachedBlockHeight;
}
@ -782,7 +783,7 @@ bool CCoinJoinClientManager::CheckAutomaticBackup()
//
bool CCoinJoinClientSession::DoAutomaticDenominating(CConnman& connman, CTxMemPool& mempool, bool fDryRun)
{
if (fMasternodeMode) return false; // no client-side mixing on masternodes
if (m_is_masternode) return false; // no client-side mixing on masternodes
if (nState != POOL_STATE_IDLE) return false;
if (!m_mn_sync.IsBlockchainSynced()) {
@ -962,7 +963,7 @@ bool CCoinJoinClientSession::DoAutomaticDenominating(CConnman& connman, CTxMemPo
bool CCoinJoinClientManager::DoAutomaticDenominating(CConnman& connman, CTxMemPool& mempool, bool fDryRun)
{
if (fMasternodeMode) return false; // no client-side mixing on masternodes
if (m_is_masternode) return false; // no client-side mixing on masternodes
if (!CCoinJoinClientOptions::IsEnabled() || !IsMixing()) return false;
if (!m_mn_sync.IsBlockchainSynced()) {
@ -991,7 +992,7 @@ bool CCoinJoinClientManager::DoAutomaticDenominating(CConnman& connman, CTxMemPo
AssertLockNotHeld(cs_deqsessions);
LOCK(cs_deqsessions);
if (int(deqSessions.size()) < CCoinJoinClientOptions::GetSessions()) {
deqSessions.emplace_back(m_wallet, m_walletman, m_dmnman, m_mn_metaman, m_mn_sync, m_queueman);
deqSessions.emplace_back(m_wallet, m_walletman, m_dmnman, m_mn_metaman, m_mn_sync, m_queueman, m_is_masternode);
}
for (auto& session : deqSessions) {
if (!CheckAutomaticBackup()) return false;
@ -1832,7 +1833,7 @@ void CCoinJoinClientManager::UpdatedBlockTip(const CBlockIndex* pindex)
void CCoinJoinClientQueueManager::DoMaintenance()
{
if (fMasternodeMode) return; // no client-side mixing on masternodes
if (m_is_masternode) return; // no client-side mixing on masternodes
if (!m_mn_sync.IsBlockchainSynced() || ShutdownRequested()) return;
@ -1842,7 +1843,7 @@ void CCoinJoinClientQueueManager::DoMaintenance()
void CCoinJoinClientManager::DoMaintenance(CConnman& connman, CTxMemPool& mempool)
{
if (!CCoinJoinClientOptions::IsEnabled()) return;
if (fMasternodeMode) return; // no client-side mixing on masternodes
if (m_is_masternode) return; // no client-side mixing on masternodes
if (!m_mn_sync.IsBlockchainSynced() || ShutdownRequested()) return;
@ -1893,7 +1894,7 @@ void CCoinJoinClientManager::GetJsonInfo(UniValue& obj) const
void CoinJoinWalletManager::Add(CWallet& wallet) {
m_wallet_manager_map.try_emplace(
wallet.GetName(),
std::make_unique<CCoinJoinClientManager>(wallet, *this, m_dmnman, m_mn_metaman, m_mn_sync, m_queueman)
std::make_unique<CCoinJoinClientManager>(wallet, *this, m_dmnman, m_mn_metaman, m_mn_sync, m_queueman, m_is_masternode)
);
g_wallet_init_interface.InitCoinJoinSettings(*this);
}

View File

@ -74,8 +74,10 @@ public:
public:
CoinJoinWalletManager(CConnman& connman, CDeterministicMNManager& dmnman, CMasternodeMetaMan& mn_metaman, CTxMemPool& mempool,
const CMasternodeSync& mn_sync, const std::unique_ptr<CCoinJoinClientQueueManager>& queueman)
: m_connman(connman), m_dmnman(dmnman), m_mn_metaman(mn_metaman), m_mempool(mempool), m_mn_sync(mn_sync), m_queueman(queueman) {}
const CMasternodeSync& mn_sync, const std::unique_ptr<CCoinJoinClientQueueManager>& queueman, bool is_masternode)
: m_connman(connman), m_dmnman(dmnman), m_mn_metaman(mn_metaman), m_mempool(mempool), m_mn_sync(mn_sync), m_queueman(queueman),
m_is_masternode{is_masternode}
{}
~CoinJoinWalletManager() {
for (auto& [wallet_name, cj_man] : m_wallet_manager_map) {
@ -101,6 +103,7 @@ private:
const CMasternodeSync& m_mn_sync;
const std::unique_ptr<CCoinJoinClientQueueManager>& m_queueman;
const bool m_is_masternode;
wallet_name_cjman_map m_wallet_manager_map;
};
@ -115,6 +118,9 @@ private:
const CMasternodeSync& m_mn_sync;
const std::unique_ptr<CCoinJoinClientQueueManager>& m_queueman;
// Track node type
const bool m_is_masternode;
std::vector<COutPoint> vecOutPointLocked;
bilingual_str strLastMessage;
@ -162,7 +168,7 @@ private:
public:
explicit CCoinJoinClientSession(CWallet& wallet, CoinJoinWalletManager& walletman, CDeterministicMNManager& dmnman, CMasternodeMetaMan& mn_metaman,
const CMasternodeSync& mn_sync, const std::unique_ptr<CCoinJoinClientQueueManager>& queueman);
const CMasternodeSync& mn_sync, const std::unique_ptr<CCoinJoinClientQueueManager>& queueman, bool is_masternode);
void ProcessMessage(CNode& peer, CConnman& connman, const CTxMemPool& mempool, std::string_view msg_type, CDataStream& vRecv);
@ -197,12 +203,14 @@ private:
CDeterministicMNManager& m_dmnman;
CMasternodeMetaMan& m_mn_metaman;
const CMasternodeSync& m_mn_sync;
mutable Mutex cs_ProcessDSQueue;
const bool m_is_masternode;
public:
explicit CCoinJoinClientQueueManager(CConnman& _connman, CoinJoinWalletManager& walletman, CDeterministicMNManager& dmnman,
CMasternodeMetaMan& mn_metaman, const CMasternodeSync& mn_sync) :
connman(_connman), m_walletman(walletman), m_dmnman(dmnman), m_mn_metaman(mn_metaman), m_mn_sync(mn_sync) {};
CMasternodeMetaMan& mn_metaman, const CMasternodeSync& mn_sync, bool is_masternode) :
connman(_connman), m_walletman(walletman), m_dmnman(dmnman), m_mn_metaman(mn_metaman), m_mn_sync(mn_sync), m_is_masternode{is_masternode} {};
PeerMsgRet ProcessMessage(const CNode& peer, std::string_view msg_type, CDataStream& vRecv) LOCKS_EXCLUDED(cs_vecqueue);
PeerMsgRet ProcessDSQueue(const CNode& peer, CDataStream& vRecv);
@ -221,6 +229,9 @@ private:
const CMasternodeSync& m_mn_sync;
const std::unique_ptr<CCoinJoinClientQueueManager>& m_queueman;
// Track node type
const bool m_is_masternode;
// Keep track of the used Masternodes
std::vector<COutPoint> vecMasternodesUsed;
@ -252,8 +263,9 @@ public:
explicit CCoinJoinClientManager(CWallet& wallet, CoinJoinWalletManager& walletman, CDeterministicMNManager& dmnman,
CMasternodeMetaMan& mn_metaman, const CMasternodeSync& mn_sync,
const std::unique_ptr<CCoinJoinClientQueueManager>& queueman) :
m_wallet(wallet), m_walletman(walletman), m_dmnman(dmnman), m_mn_metaman(mn_metaman), m_mn_sync(mn_sync), m_queueman(queueman) {}
const std::unique_ptr<CCoinJoinClientQueueManager>& queueman, bool is_masternode) :
m_wallet(wallet), m_walletman(walletman), m_dmnman(dmnman), m_mn_metaman(mn_metaman), m_mn_sync(mn_sync), m_queueman(queueman),
m_is_masternode{is_masternode} {}
void ProcessMessage(CNode& peer, CConnman& connman, const CTxMemPool& mempool, std::string_view msg_type, CDataStream& vRecv) LOCKS_EXCLUDED(cs_deqsessions);

View File

@ -14,8 +14,8 @@ CJContext::CJContext(CChainState& chainstate, CConnman& connman, CDeterministicM
const std::unique_ptr<PeerManager>& peerman, bool relay_txes) :
dstxman{std::make_unique<CDSTXManager>()},
#ifdef ENABLE_WALLET
walletman{std::make_unique<CoinJoinWalletManager>(connman, dmnman, mn_metaman, mempool, mn_sync, queueman)},
queueman {relay_txes ? std::make_unique<CCoinJoinClientQueueManager>(connman, *walletman, dmnman, mn_metaman, mn_sync) : nullptr},
walletman{std::make_unique<CoinJoinWalletManager>(connman, dmnman, mn_metaman, mempool, mn_sync, queueman, /* is_masternode = */ mn_activeman != nullptr)},
queueman {relay_txes ? std::make_unique<CCoinJoinClientQueueManager>(connman, *walletman, dmnman, mn_metaman, mn_sync, /* is_masternode = */ mn_activeman != nullptr) : nullptr},
#endif // ENABLE_WALLET
server{std::make_unique<CCoinJoinServer>(chainstate, connman, dmnman, *dstxman, mn_metaman, mempool, mn_activeman, mn_sync, peerman)}
{}

View File

@ -27,7 +27,7 @@
PeerMsgRet CCoinJoinServer::ProcessMessage(CNode& peer, std::string_view msg_type, CDataStream& vRecv)
{
if (!fMasternodeMode) return {};
if (!m_mn_activeman) return {};
if (!m_mn_sync.IsBlockchainSynced()) return {};
if (msg_type == NetMsgType::DSACCEPT) {
@ -249,7 +249,7 @@ void CCoinJoinServer::SetNull()
//
void CCoinJoinServer::CheckPool()
{
if (!fMasternodeMode) return;
if (!m_mn_activeman) return;
if (int entries = GetEntriesCount(); entries != 0) LogPrint(BCLog::COINJOIN, "CCoinJoinServer::CheckPool -- entries count %lu\n", entries);
@ -312,9 +312,7 @@ void CCoinJoinServer::CreateFinalTransaction()
void CCoinJoinServer::CommitFinalTransaction()
{
AssertLockNotHeld(cs_coinjoin);
if (!fMasternodeMode) return; // check and relay final tx only on masternode
assert(m_mn_activeman);
if (!m_mn_activeman) return; // check and relay final tx only on masternode
CTransactionRef finalTransaction = WITH_LOCK(cs_coinjoin, return MakeTransactionRef(finalMutableTransaction));
uint256 hashTx = finalTransaction->GetHash();
@ -377,7 +375,7 @@ void CCoinJoinServer::CommitFinalTransaction()
void CCoinJoinServer::ChargeFees() const
{
AssertLockNotHeld(cs_coinjoin);
if (!fMasternodeMode) return;
if (!m_mn_activeman) return;
//we don't need to charge collateral for every offence.
if (GetRandInt(100) > 33) return;
@ -445,7 +443,7 @@ void CCoinJoinServer::ChargeFees() const
*/
void CCoinJoinServer::ChargeRandomFees() const
{
if (!fMasternodeMode) return;
if (!m_mn_activeman) return;
for (const auto& txCollateral : vecSessionCollaterals) {
if (GetRandInt(100) > 10) return;
@ -467,7 +465,7 @@ void CCoinJoinServer::ConsumeCollateral(const CTransactionRef& txref) const
bool CCoinJoinServer::HasTimedOut() const
{
if (!fMasternodeMode) return false;
if (!m_mn_activeman) return false;
if (nState == POOL_STATE_IDLE) return false;
@ -481,7 +479,7 @@ bool CCoinJoinServer::HasTimedOut() const
//
void CCoinJoinServer::CheckTimeout()
{
if (!fMasternodeMode) return;
if (!m_mn_activeman) return;
CheckQueue();
@ -501,9 +499,7 @@ void CCoinJoinServer::CheckTimeout()
*/
void CCoinJoinServer::CheckForCompleteQueue()
{
if (!fMasternodeMode) return;
assert(m_mn_activeman);
if (!m_mn_activeman) return;
if (nState == POOL_STATE_QUEUE && IsSessionReady()) {
SetState(POOL_STATE_ACCEPTING_ENTRIES);
@ -570,7 +566,7 @@ bool CCoinJoinServer::IsInputScriptSigValid(const CTxIn& txin) const
bool CCoinJoinServer::AddEntry(const CCoinJoinEntry& entry, PoolMessage& nMessageIDRet)
{
AssertLockNotHeld(cs_coinjoin);
if (!fMasternodeMode) return false;
if (!m_mn_activeman) return false;
if (size_t(GetEntriesCount()) >= vecSessionCollaterals.size()) {
LogPrint(BCLog::COINJOIN, "CCoinJoinServer::%s -- ERROR: entries is full!\n", __func__);
@ -679,7 +675,7 @@ bool CCoinJoinServer::IsSignaturesComplete() const
bool CCoinJoinServer::IsAcceptableDSA(const CCoinJoinAccept& dsa, PoolMessage& nMessageIDRet) const
{
if (!fMasternodeMode) return false;
if (!m_mn_activeman) return false;
// is denom even something legit?
if (!CoinJoin::IsValidDenomination(dsa.nDenom)) {
@ -700,9 +696,7 @@ bool CCoinJoinServer::IsAcceptableDSA(const CCoinJoinAccept& dsa, PoolMessage& n
bool CCoinJoinServer::CreateNewSession(const CCoinJoinAccept& dsa, PoolMessage& nMessageIDRet)
{
if (!fMasternodeMode || nSessionID != 0) return false;
assert(m_mn_activeman);
if (!m_mn_activeman || nSessionID != 0) return false;
// new session can only be started in idle mode
if (nState != POOL_STATE_IDLE) {
@ -744,7 +738,7 @@ bool CCoinJoinServer::CreateNewSession(const CCoinJoinAccept& dsa, PoolMessage&
bool CCoinJoinServer::AddUserToExistingSession(const CCoinJoinAccept& dsa, PoolMessage& nMessageIDRet)
{
if (!fMasternodeMode || nSessionID == 0 || IsSessionReady()) return false;
if (!m_mn_activeman || nSessionID == 0 || IsSessionReady()) return false;
if (!IsAcceptableDSA(dsa, nMessageIDRet)) {
return false;
@ -880,7 +874,7 @@ void CCoinJoinServer::RelayCompletedTransaction(PoolMessage nMessageID)
void CCoinJoinServer::SetState(PoolState nStateNew)
{
if (!fMasternodeMode) return;
if (!m_mn_activeman) return;
if (nStateNew == POOL_STATE_ERROR) {
LogPrint(BCLog::COINJOIN, "CCoinJoinServer::SetState -- Can't set state to ERROR as a Masternode. \n");
@ -894,7 +888,7 @@ void CCoinJoinServer::SetState(PoolState nStateNew)
void CCoinJoinServer::DoMaintenance()
{
if (!fMasternodeMode) return; // only run on masternodes
if (!m_mn_activeman) return; // only run on masternodes
if (!m_mn_sync.IsBlockchainSynced()) return;
if (ShutdownRequested()) return;

View File

@ -97,9 +97,11 @@ void CDSNotificationInterface::UpdatedBlockTip(const CBlockIndex *pindexNew, con
m_llmq_ctx->qman->UpdatedBlockTip(pindexNew, fInitialDownload);
m_llmq_ctx->qdkgsman->UpdatedBlockTip(pindexNew, fInitialDownload);
m_llmq_ctx->ehfSignalsHandler->UpdatedBlockTip(pindexNew);
m_llmq_ctx->ehfSignalsHandler->UpdatedBlockTip(pindexNew, /* is_masternode = */ m_mn_activeman != nullptr);
if (!fDisableGovernance) m_govman.UpdatedBlockTip(pindexNew, m_connman, m_peerman, m_mn_activeman);
if (m_govman.IsValid()) {
m_govman.UpdatedBlockTip(pindexNew, m_connman, m_peerman, m_mn_activeman);
}
}
void CDSNotificationInterface::TransactionAddedToMempool(const CTransactionRef& ptx, int64_t nAcceptTime)

View File

@ -22,8 +22,6 @@
void CMNAuth::PushMNAUTH(CNode& peer, CConnman& connman, const CActiveMasternodeManager& mn_activeman,
const CBlockIndex* tip)
{
assert(fMasternodeMode);
CMNAuth mnauth;
if (mn_activeman.GetProTxHash().IsNull()) {
return;
@ -134,9 +132,7 @@ PeerMsgRet CMNAuth::ProcessMessage(CNode& peer, CConnman& connman, CMasternodeMe
}
}
const uint256 myProTxHash = fMasternodeMode ?
Assert(mn_activeman)->GetProTxHash() :
uint256();
const uint256 myProTxHash = mn_activeman != nullptr ? mn_activeman->GetProTxHash() : uint256();
connman.ForEachNode([&](CNode* pnode2) {
if (peer.fDisconnect) {
@ -145,7 +141,7 @@ PeerMsgRet CMNAuth::ProcessMessage(CNode& peer, CConnman& connman, CMasternodeMe
}
if (pnode2->GetVerifiedProRegTxHash() == mnauth.proRegTxHash) {
if (fMasternodeMode && !myProTxHash.IsNull()) {
if (mn_activeman != nullptr && !myProTxHash.IsNull()) {
const auto deterministicOutbound = llmq::utils::DeterministicOutboundConnection(myProTxHash, mnauth.proRegTxHash);
LogPrint(BCLog::NET_NETCONN, "CMNAuth::ProcessMessage -- Masternode %s has already verified as peer %d, deterministicOutbound=%s. peer=%d\n",
mnauth.proRegTxHash.ToString(), pnode2->GetId(), deterministicOutbound.ToString(), peer.GetId());

View File

@ -121,7 +121,7 @@ bool CGovernanceManager::SerializeVoteForHash(const uint256& nHash, CDataStream&
PeerMsgRet CGovernanceManager::ProcessMessage(CNode& peer, CConnman& connman, PeerManager& peerman, std::string_view msg_type, CDataStream& vRecv)
{
if (fDisableGovernance) return {};
if (!IsValid()) return {};
if (m_mn_sync == nullptr || !m_mn_sync->IsBlockchainSynced()) return {};
const auto tip_mn_list = Assert(m_dmnman)->GetListAtChainTip();
@ -565,7 +565,7 @@ struct sortProposalsByVotes {
std::optional<const CSuperblock> CGovernanceManager::CreateSuperblockCandidate(int nHeight) const
{
if (!fMasternodeMode || fDisableGovernance) return std::nullopt;
if (!IsValid()) return std::nullopt;
if (m_mn_sync == nullptr || !m_mn_sync->IsSynced()) return std::nullopt;
if (nHeight % Params().GetConsensus().nSuperblockCycle < Params().GetConsensus().nSuperblockCycle - Params().GetConsensus().nSuperblockMaturityWindow) return std::nullopt;
if (HasAlreadyVotedFundingTrigger()) return std::nullopt;
@ -673,10 +673,8 @@ std::optional<const CSuperblock> CGovernanceManager::CreateSuperblockCandidate(i
}
std::optional<const CGovernanceObject> CGovernanceManager::CreateGovernanceTrigger(const std::optional<const CSuperblock>& sb_opt, PeerManager& peerman,
const CActiveMasternodeManager* const mn_activeman)
const CActiveMasternodeManager& mn_activeman)
{
if (!fMasternodeMode) return std::nullopt;
// no sb_opt, no trigger
if (!sb_opt.has_value()) return std::nullopt;
@ -700,12 +698,12 @@ std::optional<const CGovernanceObject> CGovernanceManager::CreateGovernanceTrigg
return std::nullopt;
}
if (mn_payees.front()->proTxHash != Assert(mn_activeman)->GetProTxHash()) {
if (mn_payees.front()->proTxHash != mn_activeman.GetProTxHash()) {
LogPrint(BCLog::GOBJECT, "CGovernanceManager::%s we are not the payee, skipping\n", __func__);
return std::nullopt;
}
gov_sb.SetMasternodeOutpoint(mn_activeman->GetOutPoint());
gov_sb.Sign(*mn_activeman);
gov_sb.SetMasternodeOutpoint(mn_activeman.GetOutPoint());
gov_sb.Sign(mn_activeman);
if (std::string strError; !gov_sb.IsValidLocally(m_dmnman->GetListAtChainTip(), strError, true)) {
LogPrint(BCLog::GOBJECT, "CGovernanceManager::%s Created trigger is invalid:%s\n", __func__, strError);
@ -723,11 +721,10 @@ std::optional<const CGovernanceObject> CGovernanceManager::CreateGovernanceTrigg
}
void CGovernanceManager::VoteGovernanceTriggers(const std::optional<const CGovernanceObject>& trigger_opt, CConnman& connman, PeerManager& peerman,
const CActiveMasternodeManager* const mn_activeman)
const CActiveMasternodeManager& mn_activeman)
{
// only active masternodes can vote on triggers
if (!fMasternodeMode) return;
if (Assert(mn_activeman)->GetProTxHash().IsNull()) return;
if (mn_activeman.GetProTxHash().IsNull()) return;
LOCK2(cs_main, cs);
@ -769,13 +766,11 @@ void CGovernanceManager::VoteGovernanceTriggers(const std::optional<const CGover
}
bool CGovernanceManager::VoteFundingTrigger(const uint256& nHash, const vote_outcome_enum_t outcome, CConnman& connman, PeerManager& peerman,
const CActiveMasternodeManager* const mn_activeman)
const CActiveMasternodeManager& mn_activeman)
{
if (!fMasternodeMode) return false;
CGovernanceVote vote(Assert(mn_activeman)->GetOutPoint(), nHash, VOTE_SIGNAL_FUNDING, outcome);
CGovernanceVote vote(mn_activeman.GetOutPoint(), nHash, VOTE_SIGNAL_FUNDING, outcome);
vote.SetTime(GetAdjustedTime());
vote.Sign(*mn_activeman);
vote.Sign(mn_activeman);
CGovernanceException exception;
if (!ProcessVoteAndRelay(vote, exception, connman, peerman)) {
@ -798,7 +793,7 @@ void CGovernanceManager::ResetVotedFundingTrigger()
void CGovernanceManager::DoMaintenance(CConnman& connman)
{
if (fDisableGovernance) return;
if (!IsValid()) return;
if (m_mn_sync == nullptr || !m_mn_sync->IsSynced()) return;
if (ShutdownRequested()) return;
@ -1485,9 +1480,11 @@ void CGovernanceManager::UpdatedBlockTip(const CBlockIndex* pindex, CConnman& co
return;
}
const auto sb_opt = CreateSuperblockCandidate(pindex->nHeight);
const auto trigger_opt = CreateGovernanceTrigger(sb_opt, peerman, mn_activeman);
VoteGovernanceTriggers(trigger_opt, connman, peerman, mn_activeman);
if (mn_activeman) {
const auto sb_opt = CreateSuperblockCandidate(pindex->nHeight);
const auto trigger_opt = CreateGovernanceTrigger(sb_opt, peerman, *mn_activeman);
VoteGovernanceTriggers(trigger_opt, connman, peerman, *mn_activeman);
}
nCachedBlockHeight = pindex->nHeight;
LogPrint(BCLog::GOBJECT, "CGovernanceManager::UpdatedBlockTip -- nCachedBlockHeight: %d\n", nCachedBlockHeight);

View File

@ -33,6 +33,7 @@ class CNetFulfilledRequestManager;
class CSporkManager;
static constexpr int RATE_BUFFER_SIZE = 5;
static constexpr bool DEFAULT_GOVERNANCE_ENABLE{true};
class CDeterministicMNList;
using CDeterministicMNListPtr = std::shared_ptr<CDeterministicMNList>;
@ -371,11 +372,11 @@ public:
private:
std::optional<const CSuperblock> CreateSuperblockCandidate(int nHeight) const;
std::optional<const CGovernanceObject> CreateGovernanceTrigger(const std::optional<const CSuperblock>& sb_opt, PeerManager& peerman,
const CActiveMasternodeManager* const mn_activeman);
const CActiveMasternodeManager& mn_activeman);
void VoteGovernanceTriggers(const std::optional<const CGovernanceObject>& trigger_opt, CConnman& connman, PeerManager& peerman,
const CActiveMasternodeManager* const mn_activeman);
const CActiveMasternodeManager& mn_activeman);
bool VoteFundingTrigger(const uint256& nHash, const vote_outcome_enum_t outcome, CConnman& connman, PeerManager& peerman,
const CActiveMasternodeManager* const mn_activeman);
const CActiveMasternodeManager& mn_activeman);
bool HasAlreadyVotedFundingTrigger() const;
void RequestGovernanceObject(CNode* pfrom, const uint256& nHash, CConnman& connman, bool fUseFilter = false) const;

View File

@ -366,7 +366,7 @@ void PrepareShutdown(NodeContext& node)
delete pdsNotificationInterface;
pdsNotificationInterface = nullptr;
}
if (fMasternodeMode) {
if (node.mn_activeman) {
UnregisterValidationInterface(node.mn_activeman.get());
node.mn_activeman.reset();
}
@ -1230,7 +1230,7 @@ bool AppInitParameterInteraction(const ArgsManager& args)
return InitError(_("Prune mode is incompatible with -txindex."));
if (args.GetBoolArg("-coinstatsindex", DEFAULT_COINSTATSINDEX))
return InitError(_("Prune mode is incompatible with -coinstatsindex."));
if (!args.GetBoolArg("-disablegovernance", false)) {
if (!args.GetBoolArg("-disablegovernance", !DEFAULT_GOVERNANCE_ENABLE)) {
return InitError(_("Prune mode is incompatible with -disablegovernance=false."));
}
}
@ -1454,15 +1454,12 @@ bool AppInitParameterInteraction(const ArgsManager& args)
if (args.GetArg("-maxconnections", DEFAULT_MAX_PEER_CONNECTIONS) < DEFAULT_MAX_PEER_CONNECTIONS) {
return InitError(strprintf(Untranslated("Masternode must be able to handle at least %d connections, set -maxconnections=%d"), DEFAULT_MAX_PEER_CONNECTIONS, DEFAULT_MAX_PEER_CONNECTIONS));
}
if (args.GetBoolArg("-disablegovernance", false)) {
if (args.GetBoolArg("-disablegovernance", !DEFAULT_GOVERNANCE_ENABLE)) {
return InitError(_("You can not disable governance validation on a masternode."));
}
}
fDisableGovernance = args.GetBoolArg("-disablegovernance", false);
LogPrintf("fDisableGovernance %d\n", fDisableGovernance);
if (fDisableGovernance) {
if (args.GetBoolArg("-disablegovernance", !DEFAULT_GOVERNANCE_ENABLE)) {
InitWarning(_("You are starting with governance validation disabled.") +
(fPruneMode ?
Untranslated(" ") + _("This is expected because you are running a pruned node.") :
@ -1684,6 +1681,15 @@ bool AppInitMain(const CoreContext& context, NodeContext& node, interfaces::Bloc
assert(!node.netfulfilledman);
node.netfulfilledman = std::make_unique<CNetFulfilledRequestManager>();
/**
* The manager needs to be constructed regardless of whether governance
* validation is needed or not.
*
* Instead, we decide whether to initialize its database based on whether we
* need it or not further down and then query if the database is initialized
* to check if validation is enabled.
*/
const bool is_governance_enabled{!args.GetBoolArg("-disablegovernance", !DEFAULT_GOVERNANCE_ENABLE)};
assert(!node.govman);
node.govman = std::make_unique<CGovernanceManager>(*node.mn_metaman, *node.netfulfilledman, node.dmnman, node.mn_sync);
@ -1988,7 +1994,7 @@ bool AppInitMain(const CoreContext& context, NodeContext& node, interfaces::Bloc
break;
}
if (!fDisableGovernance && !args.GetBoolArg("-txindex", DEFAULT_TXINDEX) && chainparams.NetworkIDString() != CBaseChainParams::REGTEST) { // TODO remove this when pruning is fixed. See https://github.com/dashpay/dash/pull/1817 and https://github.com/dashpay/dash/pull/1743
if (is_governance_enabled && !args.GetBoolArg("-txindex", DEFAULT_TXINDEX) && chainparams.NetworkIDString() != CBaseChainParams::REGTEST) { // TODO remove this when pruning is fixed. See https://github.com/dashpay/dash/pull/1817 and https://github.com/dashpay/dash/pull/1743
return InitError(_("Transaction index can't be disabled with governance validation enabled. Either start with -disablegovernance command line switch or enable transaction index."));
}
@ -2234,10 +2240,10 @@ bool AppInitMain(const CoreContext& context, NodeContext& node, interfaces::Bloc
return InitError(strprintf(_("Failed to clear masternode cache at %s"), file_path));
}
if (!fDisableGovernance) {
if (is_governance_enabled) {
if (!node.govman->LoadCache(fLoadCacheFiles)) {
auto file_path = (GetDataDir() / "governance.dat").string();
if (fLoadCacheFiles && !fDisableGovernance) {
if (fLoadCacheFiles) {
return InitError(strprintf(_("Failed to load governance cache from %s"), file_path));
}
return InitError(strprintf(_("Failed to clear governance cache at %s"), file_path));
@ -2312,11 +2318,11 @@ bool AppInitMain(const CoreContext& context, NodeContext& node, interfaces::Bloc
node.scheduler->scheduleEvery(std::bind(&CMasternodeUtils::DoMaintenance, std::ref(*node.connman), std::ref(*node.dmnman), std::ref(*node.mn_sync), std::ref(*node.cj_ctx)), std::chrono::minutes{1});
node.scheduler->scheduleEvery(std::bind(&CDeterministicMNManager::DoMaintenance, std::ref(*node.dmnman)), std::chrono::seconds{10});
if (!fDisableGovernance) {
if (node.govman->IsValid()) {
node.scheduler->scheduleEvery(std::bind(&CGovernanceManager::DoMaintenance, std::ref(*node.govman), std::ref(*node.connman)), std::chrono::minutes{5});
}
if (fMasternodeMode) {
if (node.mn_activeman) {
node.scheduler->scheduleEvery(std::bind(&CCoinJoinServer::DoMaintenance, std::ref(*node.cj_ctx->server)), std::chrono::seconds{1});
node.scheduler->scheduleEvery(std::bind(&llmq::CDKGSessionManager::CleanupOldContributions, std::ref(*node.llmq_ctx->qdkgsman)), std::chrono::hours{1});
#ifdef ENABLE_WALLET

View File

@ -65,6 +65,7 @@ public:
virtual void getAllNewerThan(std::vector<CGovernanceObject> &objs, int64_t nMoreThanTime) = 0;
virtual int32_t getObjAbsYesCount(const CGovernanceObject& obj, vote_signal_enum_t vote_signal) = 0;
virtual bool getObjLocalValidity(const CGovernanceObject& obj, std::string& error, bool check_collateral) = 0;
virtual bool isEnabled() = 0;
virtual void setContext(NodeContext* context) {}
};
@ -230,6 +231,9 @@ public:
//! Is initial block download.
virtual bool isInitialBlockDownload() = 0;
//! Is masternode.
virtual bool isMasternode() = 0;
//! Get reindex.
virtual bool getReindex() = 0;

View File

@ -28,7 +28,8 @@ std::unique_ptr<CChainLocksHandler> chainLocksHandler;
CChainLocksHandler::CChainLocksHandler(CChainState& chainstate, CQuorumManager& _qman, CSigningManager& _sigman,
CSigSharesManager& _shareman, CSporkManager& sporkman, CTxMemPool& _mempool,
const CMasternodeSync& mn_sync, const std::unique_ptr<PeerManager>& peerman) :
const CMasternodeSync& mn_sync, const std::unique_ptr<PeerManager>& peerman,
bool is_masternode) :
m_chainstate(chainstate),
qman(_qman),
sigman(_sigman),
@ -37,6 +38,7 @@ CChainLocksHandler::CChainLocksHandler(CChainState& chainstate, CQuorumManager&
mempool(_mempool),
m_mn_sync(mn_sync),
m_peerman(peerman),
m_is_masternode{is_masternode},
scheduler(std::make_unique<CScheduler>()),
scheduler_thread(std::make_unique<std::thread>(std::thread(util::TraceThread, "cl-schdlr", [&] { scheduler->serviceQueue(); })))
{
@ -238,7 +240,7 @@ void CChainLocksHandler::TrySignChainTip()
{
Cleanup();
if (!fMasternodeMode) {
if (!m_is_masternode) {
return;
}

View File

@ -54,6 +54,7 @@ private:
const CMasternodeSync& m_mn_sync;
const std::unique_ptr<PeerManager>& m_peerman;
const bool m_is_masternode;
std::unique_ptr<CScheduler> scheduler;
std::unique_ptr<std::thread> scheduler_thread;
mutable Mutex cs;
@ -87,7 +88,8 @@ private:
public:
explicit CChainLocksHandler(CChainState& chainstate, CQuorumManager& _qman, CSigningManager& _sigman,
CSigSharesManager& _shareman, CSporkManager& sporkman, CTxMemPool& _mempool,
const CMasternodeSync& mn_sync, const std::unique_ptr<PeerManager>& peerman);
const CMasternodeSync& mn_sync, const std::unique_ptr<PeerManager>& peerman,
bool is_masternode);
~CChainLocksHandler();
void Start();

View File

@ -21,6 +21,7 @@ LLMQContext::LLMQContext(CChainState& chainstate, CConnman& connman, CDeterminis
CMasternodeMetaMan& mn_metaman, CMNHFManager& mnhfman, CSporkManager& sporkman, CTxMemPool& mempool,
const CActiveMasternodeManager* const mn_activeman, const CMasternodeSync& mn_sync,
const std::unique_ptr<PeerManager>& peerman, bool unit_tests, bool wipe) :
is_masternode{mn_activeman != nullptr},
bls_worker{std::make_shared<CBLSWorker>()},
dkg_debugman{std::make_unique<llmq::CDKGDebugManager>()},
quorum_block_processor{[&]() -> llmq::CQuorumBlockProcessor* const {
@ -38,12 +39,12 @@ LLMQContext::LLMQContext(CChainState& chainstate, CConnman& connman, CDeterminis
shareman{std::make_unique<llmq::CSigSharesManager>(connman, *sigman, mn_activeman, *llmq::quorumManager, sporkman, peerman)},
clhandler{[&]() -> llmq::CChainLocksHandler* const {
assert(llmq::chainLocksHandler == nullptr);
llmq::chainLocksHandler = std::make_unique<llmq::CChainLocksHandler>(chainstate, *llmq::quorumManager, *sigman, *shareman, sporkman, mempool, mn_sync, peerman);
llmq::chainLocksHandler = std::make_unique<llmq::CChainLocksHandler>(chainstate, *llmq::quorumManager, *sigman, *shareman, sporkman, mempool, mn_sync, peerman, is_masternode);
return llmq::chainLocksHandler.get();
}()},
isman{[&]() -> llmq::CInstantSendManager* const {
assert(llmq::quorumInstantSendManager == nullptr);
llmq::quorumInstantSendManager = std::make_unique<llmq::CInstantSendManager>(*llmq::chainLocksHandler, chainstate, connman, *llmq::quorumManager, *sigman, *shareman, sporkman, mempool, mn_sync, peerman, unit_tests, wipe);
llmq::quorumInstantSendManager = std::make_unique<llmq::CInstantSendManager>(*llmq::chainLocksHandler, chainstate, connman, *llmq::quorumManager, *sigman, *shareman, sporkman, mempool, mn_sync, peerman, is_masternode, unit_tests, wipe);
return llmq::quorumInstantSendManager.get();
}()},
ehfSignalsHandler{std::make_unique<llmq::CEHFSignalsHandler>(chainstate, mnhfman, *sigman, *shareman, mempool, *llmq::quorumManager, sporkman, peerman)}
@ -76,7 +77,7 @@ void LLMQContext::Start() {
assert(isman == llmq::quorumInstantSendManager.get());
bls_worker->Start();
if (fMasternodeMode) {
if (is_masternode) {
qdkgsman->StartThreads();
}
qman->Start();
@ -101,7 +102,7 @@ void LLMQContext::Stop() {
shareman->UnregisterAsRecoveredSigsListener();
sigman->StopWorkerThread();
qman->Stop();
if (fMasternodeMode) {
if (is_masternode) {
qdkgsman->StopThreads();
}
bls_worker->Stop();

View File

@ -34,6 +34,10 @@ class CSigningManager;
}
struct LLMQContext {
private:
const bool is_masternode;
public:
LLMQContext() = delete;
LLMQContext(const LLMQContext&) = delete;
LLMQContext(CChainState& chainstate, CConnman& connman, CDeterministicMNManager& dmnman, CEvoDB& evo_db,

View File

@ -532,7 +532,7 @@ void CDKGSessionHandler::HandleDKGRound()
});
const auto tip_mn_list = m_dmnman.GetListAtChainTip();
utils::EnsureQuorumConnections(params, connman, m_dmnman, m_sporkman, tip_mn_list, pQuorumBaseBlockIndex, curSession->myProTxHash);
utils::EnsureQuorumConnections(params, connman, m_dmnman, m_sporkman, tip_mn_list, pQuorumBaseBlockIndex, curSession->myProTxHash, /* is_masternode = */ m_mn_activeman != nullptr);
if (curSession->AreWeMember()) {
utils::AddQuorumProbeConnections(params, connman, m_dmnman, m_mn_metaman, m_sporkman, tip_mn_list, pQuorumBaseBlockIndex, curSession->myProTxHash);
}

View File

@ -36,7 +36,7 @@ CDKGSessionManager::CDKGSessionManager(CBLSWorker& _blsWorker, CChainState& chai
quorumBlockProcessor(_quorumBlockProcessor),
spork_manager(sporkman)
{
if (!fMasternodeMode && !IsWatchQuorumsEnabled()) {
if (mn_activeman == nullptr && !IsWatchQuorumsEnabled()) {
// Regular nodes do not care about any DKG internals, bail out
return;
}
@ -173,7 +173,7 @@ void CDKGSessionManager::UpdatedBlockTip(const CBlockIndex* pindexNew, bool fIni
}
}
PeerMsgRet CDKGSessionManager::ProcessMessage(CNode& pfrom, PeerManager* peerman, const std::string& msg_type, CDataStream& vRecv)
PeerMsgRet CDKGSessionManager::ProcessMessage(CNode& pfrom, PeerManager* peerman, bool is_masternode, const std::string& msg_type, CDataStream& vRecv)
{
static Mutex cs_indexedQuorumsCache;
static std::map<Consensus::LLMQType, unordered_lru_cache<uint256, int, StaticSaltedHasher>> indexedQuorumsCache GUARDED_BY(cs_indexedQuorumsCache);
@ -190,7 +190,7 @@ PeerMsgRet CDKGSessionManager::ProcessMessage(CNode& pfrom, PeerManager* peerman
}
if (msg_type == NetMsgType::QWATCH) {
if (!fMasternodeMode) {
if (!is_masternode) {
// non-masternodes should never receive this
return tl::unexpected{10};
}
@ -198,7 +198,7 @@ PeerMsgRet CDKGSessionManager::ProcessMessage(CNode& pfrom, PeerManager* peerman
return {};
}
if ((!fMasternodeMode && !IsWatchQuorumsEnabled())) {
if ((!is_masternode && !IsWatchQuorumsEnabled())) {
// regular non-watching nodes should never receive any of these
return tl::unexpected{10};
}

View File

@ -77,7 +77,7 @@ public:
void UpdatedBlockTip(const CBlockIndex *pindexNew, bool fInitialDownload);
PeerMsgRet ProcessMessage(CNode& pfrom, PeerManager* peerman, const std::string& msg_type, CDataStream& vRecv);
PeerMsgRet ProcessMessage(CNode& pfrom, PeerManager* peerman, bool is_masternode, const std::string& msg_type, CDataStream& vRecv);
bool AlreadyHave(const CInv& inv) const;
bool GetContribution(const uint256& hash, CDKGContribution& ret) const;
bool GetComplaint(const uint256& hash, CDKGComplaint& ret) const;

View File

@ -44,11 +44,11 @@ CEHFSignalsHandler::~CEHFSignalsHandler()
sigman.UnregisterRecoveredSigsListener(this);
}
void CEHFSignalsHandler::UpdatedBlockTip(const CBlockIndex* const pindexNew)
void CEHFSignalsHandler::UpdatedBlockTip(const CBlockIndex* const pindexNew, bool is_masternode)
{
if (!DeploymentActiveAfter(pindexNew, Params().GetConsensus(), Consensus::DEPLOYMENT_V20)) return;
if (!fMasternodeMode || (Params().IsTestChain() && !sporkman.IsSporkActive(SPORK_24_TEST_EHF))) {
if (!is_masternode || (Params().IsTestChain() && !sporkman.IsSporkActive(SPORK_24_TEST_EHF))) {
return;
}

View File

@ -49,7 +49,7 @@ public:
/**
* Since Tip is updated it could be a time to generate EHF Signal
*/
void UpdatedBlockTip(const CBlockIndex* const pindexNew);
void UpdatedBlockTip(const CBlockIndex* const pindexNew, bool is_masternode);
void HandleNewRecoveredSig(const CRecoveredSig& recoveredSig) override LOCKS_EXCLUDED(cs);

View File

@ -474,7 +474,7 @@ void CInstantSendManager::Stop()
void CInstantSendManager::ProcessTx(const CTransaction& tx, bool fRetroactive, const Consensus::Params& params)
{
if (!fMasternodeMode || !IsInstantSendEnabled() || !m_mn_sync.IsBlockchainSynced()) {
if (!m_is_masternode || !IsInstantSendEnabled() || !m_mn_sync.IsBlockchainSynced()) {
return;
}
@ -1062,7 +1062,7 @@ void CInstantSendManager::ProcessInstantSendLock(NodeId from, const uint256& has
// bump mempool counter to make sure newly locked txes are picked up by getblocktemplate
mempool.AddTransactionsUpdated(1);
} else {
AskNodesForLockedTx(islock->txid, connman, *m_peerman);
AskNodesForLockedTx(islock->txid, connman, *m_peerman, m_is_masternode);
}
}
@ -1338,7 +1338,7 @@ void CInstantSendManager::RemoveMempoolConflictsForLock(const uint256& hash, con
for (const auto& p : toDelete) {
RemoveConflictedTx(*p.second);
}
AskNodesForLockedTx(islock.txid, connman, *m_peerman);
AskNodesForLockedTx(islock.txid, connman, *m_peerman, m_is_masternode);
}
}
@ -1443,7 +1443,7 @@ void CInstantSendManager::RemoveConflictingLock(const uint256& islockHash, const
}
}
void CInstantSendManager::AskNodesForLockedTx(const uint256& txid, const CConnman& connman, const PeerManager& peerman)
void CInstantSendManager::AskNodesForLockedTx(const uint256& txid, const CConnman& connman, const PeerManager& peerman, bool is_masternode)
{
std::vector<CNode*> nodesToAskFor;
nodesToAskFor.reserve(4);
@ -1476,7 +1476,7 @@ void CInstantSendManager::AskNodesForLockedTx(const uint256& txid, const CConnma
txid.ToString(), pnode->GetId());
CInv inv(MSG_TX, txid);
RequestObject(pnode->GetId(), inv, GetTime<std::chrono::microseconds>(), true);
RequestObject(pnode->GetId(), inv, GetTime<std::chrono::microseconds>(), is_masternode, /* fForce = */ true);
}
}
for (CNode* pnode : nodesToAskFor) {

View File

@ -208,6 +208,7 @@ private:
const CMasternodeSync& m_mn_sync;
const std::unique_ptr<PeerManager>& m_peerman;
const bool m_is_masternode;
std::atomic<bool> fUpgradedDB{false};
std::thread workThread;
@ -257,10 +258,11 @@ public:
explicit CInstantSendManager(CChainLocksHandler& _clhandler, CChainState& chainstate, CConnman& _connman,
CQuorumManager& _qman, CSigningManager& _sigman, CSigSharesManager& _shareman,
CSporkManager& sporkman, CTxMemPool& _mempool, const CMasternodeSync& mn_sync,
const std::unique_ptr<PeerManager>& peerman, bool unitTests, bool fWipe) :
const std::unique_ptr<PeerManager>& peerman, bool is_masternode, bool unitTests, bool fWipe) :
db(unitTests, fWipe),
clhandler(_clhandler), m_chainstate(chainstate), connman(_connman), qman(_qman), sigman(_sigman),
shareman(_shareman), spork_manager(sporkman), mempool(_mempool), m_mn_sync(mn_sync), m_peerman(peerman)
shareman(_shareman), spork_manager(sporkman), mempool(_mempool), m_mn_sync(mn_sync), m_peerman(peerman),
m_is_masternode{is_masternode}
{
workInterrupt.reset();
}
@ -299,7 +301,7 @@ private:
void RemoveMempoolConflictsForLock(const uint256& hash, const CInstantSendLock& islock);
void ResolveBlockConflicts(const uint256& islockHash, const CInstantSendLock& islock) LOCKS_EXCLUDED(cs_pendingLocks, cs_nonLocked);
static void AskNodesForLockedTx(const uint256& txid, const CConnman& connman, const PeerManager& peerman);
static void AskNodesForLockedTx(const uint256& txid, const CConnman& connman, const PeerManager& peerman, bool is_masternode);
void ProcessPendingRetryLockTxs() LOCKS_EXCLUDED(cs_creating, cs_nonLocked, cs_pendingRetry);
void WorkThreadMain();

View File

@ -240,7 +240,7 @@ void CQuorumManager::Stop()
void CQuorumManager::TriggerQuorumDataRecoveryThreads(const CBlockIndex* pIndex) const
{
if ((!fMasternodeMode && !IsWatchQuorumsEnabled()) || !QuorumDataRecoveryEnabled() || pIndex == nullptr) {
if ((m_mn_activeman == nullptr && !IsWatchQuorumsEnabled()) || !QuorumDataRecoveryEnabled() || pIndex == nullptr) {
return;
}
@ -252,11 +252,7 @@ void CQuorumManager::TriggerQuorumDataRecoveryThreads(const CBlockIndex* pIndex)
const auto vecQuorums = ScanQuorums(params.type, pIndex, params.keepOldConnections);
// First check if we are member of any quorum of this type
const uint256 proTxHash = [this]() {
if (!fMasternodeMode) return uint256();
assert(m_mn_activeman);
return m_mn_activeman->GetProTxHash();
}();
const uint256 proTxHash = m_mn_activeman != nullptr ? m_mn_activeman->GetProTxHash() : uint256();
bool fWeAreQuorumTypeMember = ranges::any_of(vecQuorums, [&proTxHash](const auto& pQuorum) {
return pQuorum->IsValidMember(proTxHash);
@ -302,7 +298,7 @@ void CQuorumManager::UpdatedBlockTip(const CBlockIndex* pindexNew, bool fInitial
CheckQuorumConnections(params, pindexNew);
}
if (fMasternodeMode || IsWatchQuorumsEnabled()) {
if (m_mn_activeman != nullptr || IsWatchQuorumsEnabled()) {
// Cleanup expired data requests
LOCK(cs_data_requests);
auto it = mapQuorumDataRequests.begin();
@ -321,7 +317,7 @@ void CQuorumManager::UpdatedBlockTip(const CBlockIndex* pindexNew, bool fInitial
void CQuorumManager::CheckQuorumConnections(const Consensus::LLMQParams& llmqParams, const CBlockIndex* pindexNew) const
{
if (!fMasternodeMode && !IsWatchQuorumsEnabled()) return;
if (m_mn_activeman == nullptr && !IsWatchQuorumsEnabled()) return;
auto lastQuorums = ScanQuorums(llmqParams.type, pindexNew, (size_t)llmqParams.keepOldConnections);
@ -348,11 +344,7 @@ void CQuorumManager::CheckQuorumConnections(const Consensus::LLMQParams& llmqPar
LogPrint(BCLog::LLMQ, "CQuorumManager::%s -- llmqType[%d] h[%d] keeping mn quorum connections for quorum: [%d:%s]\n", __func__, ToUnderlying(llmqParams.type), pindexNew->nHeight, curDkgHeight, curDkgBlock.ToString());
}
const uint256 myProTxHash = [this]() {
if (!fMasternodeMode) return uint256();
assert(m_mn_activeman);
return m_mn_activeman->GetProTxHash();
}();
const uint256 myProTxHash = m_mn_activeman != nullptr ? m_mn_activeman->GetProTxHash() : uint256();
bool isISType = llmqParams.type == Params().GetConsensus().llmqTypeDIP0024InstantSend;
@ -362,7 +354,7 @@ void CQuorumManager::CheckQuorumConnections(const Consensus::LLMQParams& llmqPar
});
for (const auto& quorum : lastQuorums) {
if (utils::EnsureQuorumConnections(llmqParams, connman, m_dmnman, m_sporkman, m_dmnman.GetListAtChainTip(), quorum->m_quorum_base_block_index, myProTxHash)) {
if (utils::EnsureQuorumConnections(llmqParams, connman, m_dmnman, m_sporkman, m_dmnman.GetListAtChainTip(), quorum->m_quorum_base_block_index, myProTxHash, /* is_masternode = */ m_mn_activeman != nullptr)) {
if (connmanQuorumsToDelete.erase(quorum->qc->quorumHash) > 0) {
LogPrint(BCLog::LLMQ, "CQuorumManager::%s -- llmqType[%d] h[%d] keeping mn quorum connections for quorum: [%d:%s]\n", __func__, ToUnderlying(llmqParams.type), pindexNew->nHeight, quorum->m_quorum_base_block_index->nHeight, quorum->m_quorum_base_block_index->GetBlockHash().ToString());
}
@ -688,7 +680,7 @@ PeerMsgRet CQuorumManager::ProcessMessage(CNode& pfrom, const std::string& msg_t
if (msg_type == NetMsgType::QGETDATA) {
if (!fMasternodeMode || (pfrom.GetVerifiedProRegTxHash().IsNull() && !pfrom.qwatch)) {
if (m_mn_activeman == nullptr || (pfrom.GetVerifiedProRegTxHash().IsNull() && !pfrom.qwatch)) {
return errorHandler("Not a verified masternode or a qwatch connection");
}
@ -778,7 +770,7 @@ PeerMsgRet CQuorumManager::ProcessMessage(CNode& pfrom, const std::string& msg_t
}
if (msg_type == NetMsgType::QDATA) {
if ((!fMasternodeMode && !IsWatchQuorumsEnabled()) || pfrom.GetVerifiedProRegTxHash().IsNull()) {
if ((m_mn_activeman == nullptr && !IsWatchQuorumsEnabled()) || pfrom.GetVerifiedProRegTxHash().IsNull()) {
return errorHandler("Not a verified masternode and -watchquorums is not enabled");
}
@ -827,7 +819,7 @@ PeerMsgRet CQuorumManager::ProcessMessage(CNode& pfrom, const std::string& msg_t
// Check if request has ENCRYPTED_CONTRIBUTIONS data
if (request.GetDataMask() & CQuorumDataRequest::ENCRYPTED_CONTRIBUTIONS) {
assert(fMasternodeMode);
assert(m_mn_activeman);
if (WITH_LOCK(pQuorum->cs, return pQuorum->quorumVvec->size() != size_t(pQuorum->params.threshold))) {
return errorHandler("No valid quorum verification vector available", 0); // Don't bump score because we asked for it
@ -844,7 +836,7 @@ PeerMsgRet CQuorumManager::ProcessMessage(CNode& pfrom, const std::string& msg_t
std::vector<CBLSSecretKey> vecSecretKeys;
vecSecretKeys.resize(vecEncrypted.size());
for (const auto i : irange::range(vecEncrypted.size())) {
if (!Assert(m_mn_activeman)->Decrypt(vecEncrypted[i], memberIdx, vecSecretKeys[i], PROTOCOL_VERSION)) {
if (!m_mn_activeman->Decrypt(vecEncrypted[i], memberIdx, vecSecretKeys[i], PROTOCOL_VERSION)) {
return errorHandler("Failed to decrypt");
}
}
@ -1069,7 +1061,7 @@ void CQuorumManager::StartCleanupOldQuorumDataThread(const CBlockIndex* pIndex)
// window and it's better to have more room so we pick next cycle.
// dkgMiningWindowStart for small quorums is 10 i.e. a safe block to start
// these calculations is at height 576 + 24 * 2 + 10 = 576 + 58.
if ((!fMasternodeMode && !IsWatchQuorumsEnabled()) || pIndex == nullptr || (pIndex->nHeight % 576 != 58)) {
if ((m_mn_activeman == nullptr && !IsWatchQuorumsEnabled()) || pIndex == nullptr || (pIndex->nHeight % 576 != 58)) {
return;
}

View File

@ -838,7 +838,7 @@ void CSigningManager::ProcessRecoveredSig(const std::shared_ptr<const CRecovered
pendingReconstructedRecoveredSigs.erase(recoveredSig->GetHash());
}
if (fMasternodeMode) {
if (m_mn_activeman != nullptr) {
CInv inv(MSG_QUORUM_RECOVERED_SIG, recoveredSig->GetHash());
connman.ForEachNode([&](CNode* pnode) {
if (pnode->fSendRecSigs) {
@ -895,9 +895,7 @@ void CSigningManager::UnregisterRecoveredSigsListener(CRecoveredSigsListener* l)
bool CSigningManager::AsyncSignIfMember(Consensus::LLMQType llmqType, CSigSharesManager& shareman, const uint256& id, const uint256& msgHash, const uint256& quorumHash, bool allowReSign)
{
if (!fMasternodeMode) return false;
assert(m_mn_activeman);
if (m_mn_activeman == nullptr) return false;
if (m_mn_activeman->GetProTxHash().IsNull()) return false;
const CQuorumCPtr quorum = [&]() {

View File

@ -218,9 +218,7 @@ void CSigSharesManager::InterruptWorkerThread()
void CSigSharesManager::ProcessMessage(const CNode& pfrom, const CSporkManager& sporkman, const std::string& msg_type, CDataStream& vRecv)
{
// non-masternodes are not interested in sigshares
if (!fMasternodeMode) return;
assert(m_mn_activeman);
if (m_mn_activeman == nullptr) return;
if (m_mn_activeman->GetProTxHash().IsNull()) return;
if (sporkman.IsSporkActive(SPORK_21_QUORUM_ALL_CONNECTED) && msg_type == NetMsgType::QSIGSHARE) {

View File

@ -755,9 +755,9 @@ std::set<size_t> CalcDeterministicWatchConnections(Consensus::LLMQType llmqType,
bool EnsureQuorumConnections(const Consensus::LLMQParams& llmqParams, CConnman& connman, CDeterministicMNManager& dmnman, const CSporkManager& sporkman,
const CDeterministicMNList& tip_mn_list, gsl::not_null<const CBlockIndex*> pQuorumBaseBlockIndex,
const uint256& myProTxHash)
const uint256& myProTxHash, bool is_masternode)
{
if (!fMasternodeMode && !IsWatchQuorumsEnabled()) {
if (!is_masternode && !IsWatchQuorumsEnabled()) {
return false;
}

View File

@ -40,7 +40,7 @@ std::set<size_t> CalcDeterministicWatchConnections(Consensus::LLMQType llmqType,
bool EnsureQuorumConnections(const Consensus::LLMQParams& llmqParams, CConnman& connman, CDeterministicMNManager& dmnman, const CSporkManager& sporkman,
const CDeterministicMNList& tip_mn_list, gsl::not_null<const CBlockIndex*> pQuorumBaseBlockIndex,
const uint256& myProTxHash);
const uint256& myProTxHash, bool is_masternode);
void AddQuorumProbeConnections(const Consensus::LLMQParams& llmqParams, CConnman& connman, CDeterministicMNManager& dmnman,
CMasternodeMetaMan& mn_metaman, const CSporkManager& sporkman, const CDeterministicMNList& tip_mn_list,
gsl::not_null<const CBlockIndex*> pQuorumBaseBlockIndex, const uint256& myProTxHash);

View File

@ -75,8 +75,6 @@ void CActiveMasternodeManager::InitInternal(const CBlockIndex* pindex)
{
AssertLockHeld(cs);
if (!fMasternodeMode) return;
if (!DeploymentDIP0003Enforced(pindex->nHeight, Params().GetConsensus())) return;
// Check that our local network configuration is correct
@ -146,8 +144,6 @@ void CActiveMasternodeManager::InitInternal(const CBlockIndex* pindex)
void CActiveMasternodeManager::UpdatedBlockTip(const CBlockIndex* pindexNew, const CBlockIndex* pindexFork, bool fInitialDownload)
{
if (!fMasternodeMode) return;
if (!DeploymentDIP0003Enforced(pindexNew->nHeight, Params().GetConsensus())) return;
const auto [cur_state, cur_protx_hash] = WITH_READ_LOCK(cs, return std::make_pair(m_state, m_info.proTxHash));

View File

@ -18,7 +18,6 @@
#include <script/standard.h>
#include <tinyformat.h>
#include <util/ranges.h>
#include <util/system.h>
#include <validation.h>
#include <cassert>
@ -223,7 +222,7 @@ bool CMNPaymentsProcessor::IsBlockValueValid(const CBlock& block, const int nBlo
return false;
}
if(!m_mn_sync.IsSynced() || fDisableGovernance) {
if (!m_mn_sync.IsSynced() || !m_govman.IsValid()) {
LogPrint(BCLog::MNPAYMENTS, "CMNPaymentsProcessor::%s -- WARNING! Not enough data, checked superblock max bounds only\n", __func__);
// not enough data for full checks but at least we know that the superblock limits were honored.
// We rely on the network to have followed the correct chain in this case
@ -280,7 +279,7 @@ bool CMNPaymentsProcessor::IsBlockPayeeValid(const CTransaction& txNew, const CB
return false;
}
if (!m_mn_sync.IsSynced() || fDisableGovernance) {
if (!m_mn_sync.IsSynced() || !m_govman.IsValid()) {
// governance data is either incomplete or non-existent
LogPrint(BCLog::MNPAYMENTS, "CMNPaymentsProcessor::%s -- WARNING! Not enough data, skipping superblock payee checks\n", __func__);
return true; // not an error

View File

@ -220,7 +220,7 @@ void CMasternodeSync::ProcessTick()
// GOVOBJ : SYNC GOVERNANCE ITEMS FROM OUR PEERS
if(nCurrentAsset == MASTERNODE_SYNC_GOVERNANCE) {
if (fDisableGovernance) {
if (!m_govman.IsValid()) {
SwitchToNextAsset();
connman.ReleaseNodeVector(vNodesCopy);
return;

View File

@ -1564,7 +1564,7 @@ public:
extern RecursiveMutex cs_main;
void EraseObjectRequest(NodeId nodeId, const CInv& inv) EXCLUSIVE_LOCKS_REQUIRED(cs_main);
void RequestObject(NodeId nodeId, const CInv& inv, std::chrono::microseconds current_time, bool fForce=false) EXCLUSIVE_LOCKS_REQUIRED(cs_main);
void RequestObject(NodeId nodeId, const CInv& inv, std::chrono::microseconds current_time, bool is_masternode, bool fForce=false) EXCLUSIVE_LOCKS_REQUIRED(cs_main);
size_t GetRequestedObjectCount(NodeId nodeId) EXCLUSIVE_LOCKS_REQUIRED(cs_main);
/** Protect desirable or disadvantaged inbound peers from eviction by ratio.

View File

@ -1259,7 +1259,7 @@ std::chrono::microseconds GetObjectRandomDelay(int invType)
return {};
}
std::chrono::microseconds CalculateObjectGetDataTime(const CInv& inv, std::chrono::microseconds current_time, bool use_inbound_delay) EXCLUSIVE_LOCKS_REQUIRED(cs_main)
std::chrono::microseconds CalculateObjectGetDataTime(const CInv& inv, std::chrono::microseconds current_time, bool is_masternode, bool use_inbound_delay) EXCLUSIVE_LOCKS_REQUIRED(cs_main)
{
AssertLockHeld(cs_main);
std::chrono::microseconds process_time;
@ -1274,12 +1274,12 @@ std::chrono::microseconds CalculateObjectGetDataTime(const CInv& inv, std::chron
}
// We delay processing announcements from inbound peers
if (inv.IsMsgTx() && !fMasternodeMode && use_inbound_delay) process_time += INBOUND_PEER_TX_DELAY;
if (inv.IsMsgTx() && !is_masternode && use_inbound_delay) process_time += INBOUND_PEER_TX_DELAY;
return process_time;
}
void RequestObject(CNodeState* state, const CInv& inv, std::chrono::microseconds current_time, bool fForce = false) EXCLUSIVE_LOCKS_REQUIRED(cs_main)
void RequestObject(CNodeState* state, const CInv& inv, std::chrono::microseconds current_time, bool is_masternode, bool fForce = false) EXCLUSIVE_LOCKS_REQUIRED(cs_main)
{
AssertLockHeld(cs_main);
CNodeState::ObjectDownloadState& peer_download_state = state->m_object_download;
@ -1294,7 +1294,7 @@ void RequestObject(CNodeState* state, const CInv& inv, std::chrono::microseconds
// Calculate the time to try requesting this transaction. Use
// fPreferredDownload as a proxy for outbound peers.
std::chrono::microseconds process_time = CalculateObjectGetDataTime(inv, current_time, !state->fPreferredDownload);
std::chrono::microseconds process_time = CalculateObjectGetDataTime(inv, current_time, is_masternode, !state->fPreferredDownload);
peer_download_state.m_object_process_time.emplace(process_time, inv);
@ -1307,14 +1307,14 @@ void RequestObject(CNodeState* state, const CInv& inv, std::chrono::microseconds
LogPrint(BCLog::NET, "%s -- inv=(%s), current_time=%d, process_time=%d, delta=%d\n", __func__, inv.ToString(), current_time.count(), process_time.count(), (process_time - current_time).count());
}
void RequestObject(NodeId nodeId, const CInv& inv, std::chrono::microseconds current_time, bool fForce) EXCLUSIVE_LOCKS_REQUIRED(cs_main)
void RequestObject(NodeId nodeId, const CInv& inv, std::chrono::microseconds current_time, bool is_masternode, bool fForce) EXCLUSIVE_LOCKS_REQUIRED(cs_main)
{
AssertLockHeld(cs_main);
auto* state = State(nodeId);
if (!state) {
return;
}
RequestObject(state, inv, current_time, fForce);
RequestObject(state, inv, current_time, is_masternode, fForce);
}
size_t GetRequestedObjectCount(NodeId nodeId)
@ -3127,6 +3127,7 @@ void PeerManagerImpl::ProcessMessage(
LogPrint(BCLog::NET, "received: %s (%u bytes) peer=%d\n", SanitizeString(msg_type), vRecv.size(), pfrom.GetId());
statsClient.inc("message.received." + SanitizeString(msg_type), 1.0f);
const bool is_masternode = m_mn_activeman != nullptr;
PeerRef peer = GetPeerRef(pfrom.GetId());
if (peer == nullptr) return;
@ -3197,7 +3198,7 @@ void PeerManagerImpl::ProcessMessage(
pfrom.m_masternode_connection = fOtherMasternode;
if (fOtherMasternode) {
LogPrint(BCLog::NET_NETCONN, "peer=%d is an inbound masternode connection, not relaying anything to it\n", pfrom.GetId());
if (!fMasternodeMode) {
if (!is_masternode) {
LogPrint(BCLog::NET_NETCONN, "but we're not a masternode, disconnecting\n");
pfrom.fDisconnect = true;
return;
@ -3374,8 +3375,8 @@ void PeerManagerImpl::ProcessMessage(
pfrom.ConnectionTypeAsString());
}
if (fMasternodeMode && !pfrom.m_masternode_probe_connection) {
CMNAuth::PushMNAUTH(pfrom, m_connman, *Assert(m_mn_activeman), m_chainman.ActiveChain().Tip());
if (is_masternode && !pfrom.m_masternode_probe_connection) {
CMNAuth::PushMNAUTH(pfrom, m_connman, *m_mn_activeman, m_chainman.ActiveChain().Tip());
}
// Tell our peer we prefer to receive headers rather than inv's
@ -3674,7 +3675,7 @@ void PeerManagerImpl::ProcessMessage(
}
bool allowWhileInIBD = allowWhileInIBDObjs.count(inv.type);
if (allowWhileInIBD || !m_chainman.ActiveChainstate().IsInitialBlockDownload()) {
RequestObject(State(pfrom.GetId()), inv, current_time);
RequestObject(State(pfrom.GetId()), inv, current_time, is_masternode);
}
}
}
@ -4026,11 +4027,11 @@ void PeerManagerImpl::ProcessMessage(
for (const uint256& parent_txid : unique_parents) {
CInv _inv(MSG_TX, parent_txid);
pfrom.AddKnownInventory(_inv.hash);
if (!AlreadyHave(_inv)) RequestObject(State(pfrom.GetId()), _inv, current_time);
if (!AlreadyHave(_inv)) RequestObject(State(pfrom.GetId()), _inv, current_time, is_masternode);
// We don't know if the previous tx was a regular or a mixing one, try both
CInv _inv2(MSG_DSTX, parent_txid);
pfrom.AddKnownInventory(_inv2.hash);
if (!AlreadyHave(_inv2)) RequestObject(State(pfrom.GetId()), _inv2, current_time);
if (!AlreadyHave(_inv2)) RequestObject(State(pfrom.GetId()), _inv2, current_time, is_masternode);
}
AddOrphanTx(ptx, pfrom.GetId());
@ -4743,7 +4744,7 @@ void PeerManagerImpl::ProcessMessage(
ProcessPeerMsgRet(m_govman.ProcessMessage(pfrom, m_connman, *this, msg_type, vRecv), pfrom);
ProcessPeerMsgRet(CMNAuth::ProcessMessage(pfrom, m_connman, m_mn_metaman, m_mn_activeman, m_mn_sync, m_dmnman->GetListAtChainTip(), msg_type, vRecv), pfrom);
ProcessPeerMsgRet(m_llmq_ctx->quorum_block_processor->ProcessMessage(pfrom, msg_type, vRecv), pfrom);
ProcessPeerMsgRet(m_llmq_ctx->qdkgsman->ProcessMessage(pfrom, this, msg_type, vRecv), pfrom);
ProcessPeerMsgRet(m_llmq_ctx->qdkgsman->ProcessMessage(pfrom, this, is_masternode, msg_type, vRecv), pfrom);
ProcessPeerMsgRet(m_llmq_ctx->qman->ProcessMessage(pfrom, msg_type, vRecv), pfrom);
m_llmq_ctx->shareman->ProcessMessage(pfrom, m_sporkman, msg_type, vRecv);
ProcessPeerMsgRet(m_llmq_ctx->sigman->ProcessMessage(pfrom, this, msg_type, vRecv), pfrom);
@ -5203,6 +5204,8 @@ bool PeerManagerImpl::SendMessages(CNode* pto)
{
assert(m_llmq_ctx);
const bool is_masternode = m_mn_activeman != nullptr;
PeerRef peer = GetPeerRef(pto->GetId());
if (!peer) return false;
const Consensus::Params& consensusParams = m_chainparams.GetConsensus();
@ -5463,7 +5466,7 @@ bool PeerManagerImpl::SendMessages(CNode* pto)
// Check whether periodic sends should happen
// Note: If this node is running in a Masternode mode, it makes no sense to delay outgoing txes
// because we never produce any txes ourselves i.e. no privacy is lost in this case.
bool fSendTrickle = pto->HasPermission(NetPermissionFlags::NoBan) || fMasternodeMode;
bool fSendTrickle = pto->HasPermission(NetPermissionFlags::NoBan) || is_masternode;
if (pto->m_tx_relay->nNextInvSend < current_time) {
fSendTrickle = true;
if (pto->IsInboundConn()) {
@ -5731,7 +5734,7 @@ bool PeerManagerImpl::SendMessages(CNode* pto)
// up processing to happen after the download times out
// (with a slight delay for inbound peers, to prefer
// requests to outbound peers).
const auto next_process_time = CalculateObjectGetDataTime(inv, current_time, !state.fPreferredDownload);
const auto next_process_time = CalculateObjectGetDataTime(inv, current_time, is_masternode, !state.fPreferredDownload);
object_process_time.emplace(next_process_time, inv);
LogPrint(BCLog::NET, "%s -- GETDATA re-queue inv=(%s), next_process_time=%d, delta=%d, peer=%d\n", __func__, inv.ToString(), next_process_time.count(), (next_process_time - current_time).count(), pto->GetId());
}

View File

@ -209,8 +209,8 @@ void ThreadImport(ChainstateManager& chainman, CDeterministicMNManager& dmnman,
LogPrintf("Filling coin cache with masternode UTXOs: done in %dms\n", GetTimeMillis() - nStart);
}
if (fMasternodeMode) {
Assert(mn_activeman)->Init(::ChainActive().Tip());
if (mn_activeman != nullptr) {
mn_activeman->Init(::ChainActive().Tip());
}
g_wallet_init_interface.AutoLockMasternodeCollaterals();

View File

@ -133,6 +133,13 @@ public:
}
return false;
}
bool isEnabled() override
{
if (context().govman != nullptr) {
return context().govman->IsValid();
}
return false;
}
void setContext(NodeContext* context) override
{
m_context = context;
@ -477,6 +484,10 @@ public:
}
return active_chainstate->IsInitialBlockDownload();
}
bool isMasternode() override
{
return m_context->mn_activeman != nullptr;
}
bool getReindex() override { return ::fReindex; }
bool getImporting() override { return ::fImporting; }
void setNetworkActive(bool active) override

View File

@ -1483,7 +1483,7 @@ void BitcoinGUI::setNumBlocks(int count, const QDateTime& blockDate, const QStri
tooltip += tr("Last received block was generated %1 ago.").arg(timeBehindText);
tooltip += QString("<br>");
tooltip += tr("Transactions after this will not yet be visible.");
} else if (fDisableGovernance) {
} else if (!m_node.gov().isEnabled()) {
setAdditionalDataSyncProgress(1);
}

View File

@ -474,7 +474,7 @@ void OverviewPage::coinJoinStatus(bool fForce)
if (!fForce && (clientModel->node().shutdownRequested() || !clientModel->masternodeSync().isBlockchainSynced())) return;
// Disable any PS UI for masternode or when autobackup is disabled or failed for whatever reason
if (fMasternodeMode || nWalletBackups <= 0) {
if (clientModel->node().isMasternode() || nWalletBackups <= 0) {
DisableCoinJoinCompletely();
if (nWalletBackups <= 0) {
ui->labelCoinJoinEnabled->setToolTip(tr("Automatic backups are disabled, no mixing available!"));

View File

@ -38,7 +38,8 @@ static RPCHelpMan coinjoin()
std::shared_ptr<CWallet> const wallet = GetWalletForJSONRPCRequest(request);
if (!wallet) return NullUniValue;
if (fMasternodeMode) {
const NodeContext& node = EnsureAnyNodeContext(request.context);
if (node.mn_activeman) {
throw JSONRPCError(RPC_INTERNAL_ERROR, "Client-side mixing is not supported on masternodes");
}
@ -53,7 +54,6 @@ static RPCHelpMan coinjoin()
}
}
const NodeContext& node = EnsureAnyNodeContext(request.context);
auto cj_clientman = node.coinjoin_loader->walletman().Get(wallet->GetName());
CHECK_NONFATAL(cj_clientman != nullptr);
@ -152,9 +152,9 @@ static RPCHelpMan getcoinjoininfo()
[&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue
{
UniValue obj(UniValue::VOBJ);
const NodeContext& node = EnsureAnyNodeContext(request.context);
if (fMasternodeMode) {
const NodeContext& node = EnsureAnyNodeContext(request.context);
if (node.mn_activeman) {
node.cj_ctx->server->GetJsonInfo(obj);
return obj;
}

View File

@ -316,9 +316,7 @@ static UniValue gobject_submit(const JSONRPCRequest& request)
auto mnList = node.dmnman->GetListAtChainTip();
if (fMasternodeMode) {
CHECK_NONFATAL(node.mn_activeman);
if (node.mn_activeman) {
const bool fMnFound = mnList.HasValidMNByCollateral(node.mn_activeman->GetOutPoint());
LogPrint(BCLog::GOBJECT, "gobject_submit -- pubKeyOperator = %s, outpoint = %s, params.size() = %lld, fMnFound = %d\n",

View File

@ -257,13 +257,11 @@ static UniValue masternode_status(const JSONRPCRequest& request)
{
masternode_status_help(request);
if (!fMasternodeMode) {
const NodeContext& node = EnsureAnyNodeContext(request.context);
if (!node.mn_activeman) {
throw JSONRPCError(RPC_INTERNAL_ERROR, "This node does not run an active masternode.");
}
const NodeContext& node = EnsureAnyNodeContext(request.context);
CHECK_NONFATAL(node.mn_activeman);
UniValue mnObj(UniValue::VOBJ);
// keep compatibility with legacy status for now (might get deprecated/removed later)
mnObj.pushKV("outpoint", node.mn_activeman->GetOutPoint().ToStringShort());

View File

@ -296,11 +296,7 @@ static UniValue quorum_dkgstatus(const JSONRPCRequest& request, CDeterministicMN
CBlockIndex* pindexTip = WITH_LOCK(cs_main, return chainman.ActiveChain().Tip());
int tipHeight = pindexTip->nHeight;
const uint256 proTxHash = [&mn_activeman]() {
if (!fMasternodeMode) return uint256();
CHECK_NONFATAL(mn_activeman);
return mn_activeman->GetProTxHash();
}();
const uint256 proTxHash = mn_activeman ? mn_activeman->GetProTxHash() : uint256();
UniValue minableCommitments(UniValue::VARR);
UniValue quorumArrConnections(UniValue::VARR);
@ -316,7 +312,7 @@ static UniValue quorum_dkgstatus(const JSONRPCRequest& request, CDeterministicMN
obj.pushKV("llmqType", std::string(llmq_params.name));
obj.pushKV("quorumIndex", quorumIndex);
if (fMasternodeMode) {
if (mn_activeman) {
int quorumHeight = tipHeight - (tipHeight % llmq_params.dkgInterval) + quorumIndex;
if (quorumHeight <= tipHeight) {
const CBlockIndex* pQuorumBaseBlockIndex = WITH_LOCK(cs_main, return chainman.ActiveChain()[quorumHeight]);

View File

@ -7,6 +7,8 @@
#include <rpc/server.h>
#include <chainparams.h>
#include <node/context.h>
#include <rpc/blockchain.h>
#include <rpc/util.h>
#include <shutdown.h>
#include <sync.h>
@ -511,8 +513,9 @@ UniValue CRPCTable::execute(const JSONRPCRequest &request) const
static bool ExecuteCommand(const CRPCCommand& command, const JSONRPCRequest& request, UniValue& result, bool last_handler, const std::multimap<std::string, std::vector<UniValue>>& mapPlatformRestrictions)
{
const NodeContext& node = EnsureAnyNodeContext(request.context);
// Before executing the RPC Command, filter commands from platform rpc user
if (fMasternodeMode && request.authUser == gArgs.GetArg("-platform-user", defaultPlatformUser)) {
if (node.mn_activeman && request.authUser == gArgs.GetArg("-platform-user", defaultPlatformUser)) {
// replace this with structured binding in c++20
const auto& it = mapPlatformRestrictions.equal_range(request.strMethod);
const auto& allowed_begin = it.first;

View File

@ -80,7 +80,6 @@ const int64_t nStartupTime = GetTime();
//Dash only features
bool fMasternodeMode = false;
bool fDisableGovernance = false;
const std::string gCoinJoinName = "CoinJoin";
/**

View File

@ -37,7 +37,6 @@
//Dash only features
extern bool fMasternodeMode;
extern bool fDisableGovernance;
extern int nWalletBackups;
extern const std::string gCoinJoinName;

View File

@ -105,6 +105,7 @@ EXPECTED_CIRCULAR_DEPENDENCIES=(
"llmq/blockprocessor -> net_processing -> llmq/quorums -> llmq/blockprocessor"
"llmq/chainlocks -> net_processing -> llmq/context -> llmq/chainlocks"
"coinjoin/client -> coinjoin/coinjoin -> llmq/chainlocks -> net_processing -> coinjoin/client"
"rpc/blockchain -> rpc/server -> rpc/blockchain"
)
EXIT_CODE=0