refactor: avoid accessing active masternode info if not in masternode mode

A later commit will be moving activeMasternodeInfo into activeMasternodeManager
and that is only conditionally initialized if the node is in masternode
mode, which will render access attempts outside of masternode mode invalid.
We need to adjust behaviour to account for that.
This commit is contained in:
Kittywhiskers Van Gogh 2024-03-24 07:20:41 +00:00
parent 9a3c5a3c48
commit b8c1f010e7
No known key found for this signature in database
GPG Key ID: 30CD0C065E5C4AAD
11 changed files with 72 additions and 58 deletions

View File

@ -21,10 +21,10 @@
void CMNAuth::PushMNAUTH(CNode& peer, CConnman& connman, const CBlockIndex* tip)
{
if (!fMasternodeMode) return;
LOCK(activeMasternodeInfoCs);
if (!fMasternodeMode || activeMasternodeInfo.proTxHash.IsNull()) {
return;
}
if (activeMasternodeInfo.proTxHash.IsNull()) return;
uint256 signHash;
const auto receivedMNAuthChallenge = peer.GetReceivedMNAuthChallenge();
@ -127,7 +127,9 @@ PeerMsgRet CMNAuth::ProcessMessage(CNode& peer, CConnman& connman, const CDeterm
}
}
const uint256 myProTxHash = WITH_LOCK(activeMasternodeInfoCs, return activeMasternodeInfo.proTxHash);
const uint256 myProTxHash = fMasternodeMode ?
WITH_LOCK(activeMasternodeInfoCs, return activeMasternodeInfo.proTxHash) :
uint256();
connman.ForEachNode([&](CNode* pnode2) {
if (peer.fDisconnect) {

View File

@ -719,7 +719,8 @@ std::optional<const CGovernanceObject> CGovernanceManager::CreateGovernanceTrigg
void CGovernanceManager::VoteGovernanceTriggers(const std::optional<const CGovernanceObject>& trigger_opt, CConnman& connman)
{
// only active masternodes can vote on triggers
if (!fMasternodeMode || WITH_LOCK(activeMasternodeInfoCs, return activeMasternodeInfo.proTxHash.IsNull())) return;
if (!fMasternodeMode) return;
if (WITH_LOCK(activeMasternodeInfoCs, return activeMasternodeInfo.proTxHash.IsNull())) return;
LOCK2(cs_main, cs);

View File

@ -370,14 +370,13 @@ void PrepareShutdown(NodeContext& node)
}
if (fMasternodeMode) {
UnregisterValidationInterface(activeMasternodeManager.get());
activeMasternodeManager.reset();
}
{
LOCK(activeMasternodeInfoCs);
// make sure to clean up BLS keys before global destructors are called (they have allocated from the secure memory pool)
activeMasternodeInfo.blsKeyOperator.reset();
activeMasternodeInfo.blsPubKeyOperator.reset();
activeMasternodeManager.reset();
}
node.chain_clients.clear();
@ -1606,34 +1605,6 @@ bool AppInitMain(const CoreContext& context, NodeContext& node, interfaces::Bloc
StartScriptCheckWorkerThreads(script_threads);
}
{
LOCK(activeMasternodeInfoCs);
assert(activeMasternodeInfo.blsKeyOperator == nullptr);
assert(activeMasternodeInfo.blsPubKeyOperator == nullptr);
}
fMasternodeMode = false;
std::string strMasterNodeBLSPrivKey = args.GetArg("-masternodeblsprivkey", "");
if (!strMasterNodeBLSPrivKey.empty()) {
CBLSSecretKey keyOperator(ParseHex(strMasterNodeBLSPrivKey));
if (!keyOperator.IsValid()) {
return InitError(_("Invalid masternodeblsprivkey. Please see documentation."));
}
fMasternodeMode = true;
{
LOCK(activeMasternodeInfoCs);
activeMasternodeInfo.blsKeyOperator = std::make_unique<CBLSSecretKey>(keyOperator);
activeMasternodeInfo.blsPubKeyOperator = std::make_unique<CBLSPublicKey>(keyOperator.GetPublicKey());
// We don't know the actual scheme at this point, print both
LogPrintf("MASTERNODE:\n blsPubKeyOperator legacy: %s\n blsPubKeyOperator basic: %s\n",
activeMasternodeInfo.blsPubKeyOperator->ToString(true),
activeMasternodeInfo.blsPubKeyOperator->ToString(false));
}
} else {
LOCK(activeMasternodeInfoCs);
activeMasternodeInfo.blsKeyOperator = std::make_unique<CBLSSecretKey>();
activeMasternodeInfo.blsPubKeyOperator = std::make_unique<CBLSPublicKey>();
}
assert(!node.scheduler);
node.scheduler = std::make_unique<CScheduler>();
@ -1878,10 +1849,30 @@ bool AppInitMain(const CoreContext& context, NodeContext& node, interfaces::Bloc
);
RegisterValidationInterface(pdsNotificationInterface);
if (fMasternodeMode) {
// Create and register activeMasternodeManager, will init later in ThreadImport
activeMasternodeManager = std::make_unique<CActiveMasternodeManager>(*node.connman, ::deterministicMNManager);
RegisterValidationInterface(activeMasternodeManager.get());
fMasternodeMode = false;
std::string strMasterNodeBLSPrivKey = args.GetArg("-masternodeblsprivkey", "");
if (!strMasterNodeBLSPrivKey.empty()) {
CBLSSecretKey keyOperator(ParseHex(strMasterNodeBLSPrivKey));
if (!keyOperator.IsValid()) {
return InitError(_("Invalid masternodeblsprivkey. Please see documentation."));
}
fMasternodeMode = true;
{
// Create and register activeMasternodeManager, will init later in ThreadImport
activeMasternodeManager = std::make_unique<CActiveMasternodeManager>(*node.connman, ::deterministicMNManager);
LOCK(activeMasternodeInfoCs);
assert(activeMasternodeInfo.blsKeyOperator == nullptr);
assert(activeMasternodeInfo.blsPubKeyOperator == nullptr);
activeMasternodeInfo.blsKeyOperator = std::make_unique<CBLSSecretKey>(keyOperator);
activeMasternodeInfo.blsPubKeyOperator = std::make_unique<CBLSPublicKey>(keyOperator.GetPublicKey());
// We don't know the actual scheme at this point, print both
LogPrintf("MASTERNODE:\n blsPubKeyOperator legacy: %s\n blsPubKeyOperator basic: %s\n",
activeMasternodeInfo.blsPubKeyOperator->ToString(true),
activeMasternodeInfo.blsPubKeyOperator->ToString(false));
RegisterValidationInterface(activeMasternodeManager.get());
}
}
// ********************************************************* Step 7a: Load sporks

View File

@ -77,7 +77,9 @@ void LLMQContext::Start() {
assert(isman == llmq::quorumInstantSendManager.get());
bls_worker->Start();
qdkgsman->StartThreads();
if (fMasternodeMode) {
qdkgsman->StartThreads();
}
qman->Start();
shareman->RegisterAsRecoveredSigsListener();
shareman->StartWorkerThread();
@ -100,6 +102,8 @@ void LLMQContext::Stop() {
shareman->UnregisterAsRecoveredSigsListener();
sigman->StopWorkerThread();
qman->Stop();
qdkgsman->StopThreads();
if (fMasternodeMode) {
qdkgsman->StopThreads();
}
bls_worker->Stop();
}

View File

@ -250,7 +250,10 @@ 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
auto proTxHash = WITH_LOCK(activeMasternodeInfoCs, return activeMasternodeInfo.proTxHash);
const uint256 proTxHash = fMasternodeMode ?
WITH_LOCK(activeMasternodeInfoCs, return activeMasternodeInfo.proTxHash) :
uint256();
bool fWeAreQuorumTypeMember = ranges::any_of(vecQuorums, [&proTxHash](const auto& pQuorum) {
return pQuorum->IsValidMember(proTxHash);
});
@ -341,7 +344,10 @@ 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 auto myProTxHash = WITH_LOCK(activeMasternodeInfoCs, return activeMasternodeInfo.proTxHash);
const uint256 myProTxHash = fMasternodeMode ?
WITH_LOCK(activeMasternodeInfoCs, return activeMasternodeInfo.proTxHash) :
uint256();
bool isISType = llmqParams.type == Params().GetConsensus().llmqTypeDIP0024InstantSend;
bool watchOtherISQuorums = isISType && !myProTxHash.IsNull() &&

View File

@ -895,9 +895,8 @@ 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 || WITH_LOCK(activeMasternodeInfoCs, return activeMasternodeInfo.proTxHash.IsNull())) {
return false;
}
if (!fMasternodeMode) return false;
if (WITH_LOCK(activeMasternodeInfoCs, return activeMasternodeInfo.proTxHash.IsNull())) return false;
const CQuorumCPtr quorum = [&]() {
if (quorumHash.IsNull()) {

View File

@ -218,9 +218,8 @@ 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 || WITH_LOCK(activeMasternodeInfoCs, return activeMasternodeInfo.proTxHash.IsNull())) {
return;
}
if (!fMasternodeMode) return;
if (WITH_LOCK(activeMasternodeInfoCs, return activeMasternodeInfo.proTxHash.IsNull())) return;
if (sporkman.IsSporkActive(SPORK_21_QUORUM_ALL_CONNECTED) && msg_type == NetMsgType::QSIGSHARE) {
std::vector<CSigShare> receivedSigShares;

View File

@ -38,8 +38,9 @@ static RPCHelpMan coinjoin()
std::shared_ptr<CWallet> const wallet = GetWalletForJSONRPCRequest(request);
if (!wallet) return NullUniValue;
if (fMasternodeMode)
if (fMasternodeMode) {
throw JSONRPCError(RPC_INTERNAL_ERROR, "Client-side mixing is not supported on masternodes");
}
if (!CCoinJoinClientOptions::IsEnabled()) {
if (!gArgs.GetBoolArg("-enablecoinjoin", true)) {

View File

@ -315,11 +315,19 @@ static UniValue gobject_submit(const JSONRPCRequest& request)
}
auto mnList = node.dmnman->GetListAtChainTip();
bool fMnFound = WITH_LOCK(activeMasternodeInfoCs, return mnList.HasValidMNByCollateral(activeMasternodeInfo.outpoint));
LogPrint(BCLog::GOBJECT, "gobject_submit -- pubKeyOperator = %s, outpoint = %s, params.size() = %lld, fMnFound = %d\n",
(WITH_LOCK(activeMasternodeInfoCs, return activeMasternodeInfo.blsPubKeyOperator ? activeMasternodeInfo.blsPubKeyOperator->ToString(activeMasternodeInfo.legacy) : "N/A")),
WITH_LOCK(activeMasternodeInfoCs, return activeMasternodeInfo.outpoint.ToStringShort()), request.params.size(), fMnFound);
bool fMnFound{false};
if (fMasternodeMode) {
LOCK(activeMasternodeInfoCs);
fMnFound = mnList.HasValidMNByCollateral(activeMasternodeInfo.outpoint);
LogPrint(BCLog::GOBJECT, "gobject_submit -- pubKeyOperator = %s, outpoint = %s, params.size() = %lld, fMnFound = %d\n",
(activeMasternodeInfo.blsPubKeyOperator ? activeMasternodeInfo.blsPubKeyOperator->ToString(activeMasternodeInfo.legacy) : "N/A"),
activeMasternodeInfo.outpoint.ToStringShort(), request.params.size(), fMnFound);
} else {
LogPrint(BCLog::GOBJECT, "gobject_submit -- pubKeyOperator = N/A, outpoint = N/A, params.size() = %lld, fMnFound = %d\n",
request.params.size(), fMnFound);
}
// ASSEMBLE NEW GOVERNANCE OBJECT FROM USER PARAMETERS

View File

@ -257,8 +257,9 @@ static UniValue masternode_status(const JSONRPCRequest& request)
{
masternode_status_help(request);
if (!fMasternodeMode)
throw JSONRPCError(RPC_INTERNAL_ERROR, "This is not a masternode");
if (!fMasternodeMode) {
throw JSONRPCError(RPC_INTERNAL_ERROR, "This node does not run an active masternode.");
}
const NodeContext& node = EnsureAnyNodeContext(request.context);

View File

@ -295,7 +295,9 @@ static UniValue quorum_dkgstatus(const JSONRPCRequest& request, CDeterministicMN
CBlockIndex* pindexTip = WITH_LOCK(cs_main, return chainman.ActiveChain().Tip());
int tipHeight = pindexTip->nHeight;
auto proTxHash = WITH_LOCK(activeMasternodeInfoCs, return activeMasternodeInfo.proTxHash);
const uint256 proTxHash = fMasternodeMode ?
WITH_LOCK(activeMasternodeInfoCs, return activeMasternodeInfo.proTxHash) :
uint256();
UniValue minableCommitments(UniValue::VARR);
UniValue quorumArrConnections(UniValue::VARR);