mirror of
https://github.com/dashpay/dash.git
synced 2024-12-27 13:03:17 +01:00
Implement debugging messages and RPC for LLMQ DKGs
This commit is contained in:
parent
098b094959
commit
324406bfed
@ -143,6 +143,7 @@ BITCOIN_CORE_H = \
|
|||||||
limitedmap.h \
|
limitedmap.h \
|
||||||
llmq/quorums_blockprocessor.h \
|
llmq/quorums_blockprocessor.h \
|
||||||
llmq/quorums_commitment.h \
|
llmq/quorums_commitment.h \
|
||||||
|
llmq/quorums_debug.h \
|
||||||
llmq/quorums_dkgsessionhandler.h \
|
llmq/quorums_dkgsessionhandler.h \
|
||||||
llmq/quorums_dkgsessionmgr.h \
|
llmq/quorums_dkgsessionmgr.h \
|
||||||
llmq/quorums_dkgsession.h \
|
llmq/quorums_dkgsession.h \
|
||||||
@ -254,6 +255,7 @@ libdash_server_a_SOURCES = \
|
|||||||
governance-votedb.cpp \
|
governance-votedb.cpp \
|
||||||
llmq/quorums_blockprocessor.cpp \
|
llmq/quorums_blockprocessor.cpp \
|
||||||
llmq/quorums_commitment.cpp \
|
llmq/quorums_commitment.cpp \
|
||||||
|
llmq/quorums_debug.cpp \
|
||||||
llmq/quorums_dkgsessionhandler.cpp \
|
llmq/quorums_dkgsessionhandler.cpp \
|
||||||
llmq/quorums_dkgsessionmgr.cpp \
|
llmq/quorums_dkgsessionmgr.cpp \
|
||||||
llmq/quorums_dkgsession.cpp \
|
llmq/quorums_dkgsession.cpp \
|
||||||
@ -284,6 +286,7 @@ libdash_server_a_SOURCES = \
|
|||||||
rpc/net.cpp \
|
rpc/net.cpp \
|
||||||
rpc/rawtransaction.cpp \
|
rpc/rawtransaction.cpp \
|
||||||
rpc/rpcevo.cpp \
|
rpc/rpcevo.cpp \
|
||||||
|
rpc/rpcquorums.cpp \
|
||||||
rpc/server.cpp \
|
rpc/server.cpp \
|
||||||
script/sigcache.cpp \
|
script/sigcache.cpp \
|
||||||
script/ismine.cpp \
|
script/ismine.cpp \
|
||||||
|
347
src/llmq/quorums_debug.cpp
Normal file
347
src/llmq/quorums_debug.cpp
Normal file
@ -0,0 +1,347 @@
|
|||||||
|
// Copyright (c) 2018 The Dash Core developers
|
||||||
|
// Distributed under the MIT/X11 software license, see the accompanying
|
||||||
|
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
||||||
|
|
||||||
|
#include "quorums_debug.h"
|
||||||
|
|
||||||
|
#include "activemasternode.h"
|
||||||
|
#include "chainparams.h"
|
||||||
|
#include "net.h"
|
||||||
|
#include "net_processing.h"
|
||||||
|
#include "scheduler.h"
|
||||||
|
#include "validation.h"
|
||||||
|
|
||||||
|
#include "evo/deterministicmns.h"
|
||||||
|
#include "quorums_utils.h"
|
||||||
|
|
||||||
|
namespace llmq
|
||||||
|
{
|
||||||
|
CDKGDebugManager* quorumDKGDebugManager;
|
||||||
|
|
||||||
|
UniValue CDKGDebugSessionStatus::ToJson(int detailLevel) const
|
||||||
|
{
|
||||||
|
UniValue ret(UniValue::VOBJ);
|
||||||
|
|
||||||
|
if (!Params().GetConsensus().llmqs.count((Consensus::LLMQType)llmqType) || quorumHash.IsNull()) {
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::vector<CDeterministicMNCPtr> dmnMembers;
|
||||||
|
if (detailLevel == 2) {
|
||||||
|
dmnMembers = CLLMQUtils::GetAllQuorumMembers((Consensus::LLMQType) llmqType, quorumHash);
|
||||||
|
}
|
||||||
|
|
||||||
|
ret.push_back(Pair("llmqType", llmqType));
|
||||||
|
ret.push_back(Pair("quorumHash", quorumHash.ToString()));
|
||||||
|
ret.push_back(Pair("quorumHeight", (int)quorumHeight));
|
||||||
|
ret.push_back(Pair("phase", (int)phase));
|
||||||
|
|
||||||
|
ret.push_back(Pair("sentContributions", sentContributions));
|
||||||
|
ret.push_back(Pair("sentComplaint", sentComplaint));
|
||||||
|
ret.push_back(Pair("sentJustification", sentJustification));
|
||||||
|
ret.push_back(Pair("sentPrematureCommitment", sentPrematureCommitment));
|
||||||
|
ret.push_back(Pair("aborted", aborted));
|
||||||
|
|
||||||
|
struct ArrOrCount {
|
||||||
|
int count{0};
|
||||||
|
UniValue arr{UniValue::VARR};
|
||||||
|
};
|
||||||
|
|
||||||
|
ArrOrCount badMembers;
|
||||||
|
ArrOrCount weComplain;
|
||||||
|
ArrOrCount receivedContributions;
|
||||||
|
ArrOrCount receivedComplaints;
|
||||||
|
ArrOrCount receivedJustifications;
|
||||||
|
ArrOrCount receivedPrematureCommitments;
|
||||||
|
ArrOrCount complaintsFromMembers;
|
||||||
|
|
||||||
|
auto add = [&](ArrOrCount& v, size_t idx, bool flag) {
|
||||||
|
if (flag) {
|
||||||
|
if (detailLevel == 0) {
|
||||||
|
v.count++;
|
||||||
|
} else if (detailLevel == 1) {
|
||||||
|
v.arr.push_back((int)idx);
|
||||||
|
} else if (detailLevel == 2) {
|
||||||
|
UniValue a(UniValue::VOBJ);
|
||||||
|
a.push_back(Pair("memberIndex", idx));
|
||||||
|
if (idx < dmnMembers.size()) {
|
||||||
|
a.push_back(Pair("proTxHash", dmnMembers[idx]->proTxHash.ToString()));
|
||||||
|
}
|
||||||
|
v.arr.push_back(a);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
auto push = [&](ArrOrCount& v, const std::string& name) {
|
||||||
|
if (detailLevel == 0) {
|
||||||
|
ret.push_back(Pair(name, v.count));
|
||||||
|
} else {
|
||||||
|
ret.push_back(Pair(name, v.arr));
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
for (size_t i = 0; i < members.size(); i++) {
|
||||||
|
const auto& m = members[i];
|
||||||
|
add(badMembers, i, m.bad);
|
||||||
|
add(weComplain, i, m.weComplain);
|
||||||
|
add(receivedContributions, i, m.receivedContribution);
|
||||||
|
add(receivedComplaints, i, m.receivedComplaint);
|
||||||
|
add(receivedJustifications, i, m.receivedJustification);
|
||||||
|
add(receivedPrematureCommitments, i, m.receivedPrematureCommitment);
|
||||||
|
}
|
||||||
|
push(badMembers, "badMembers");
|
||||||
|
push(weComplain, "weComplain");
|
||||||
|
push(receivedContributions, "receivedContributions");
|
||||||
|
push(receivedComplaints, "receivedComplaints");
|
||||||
|
push(receivedJustifications, "receivedJustifications");
|
||||||
|
push(receivedPrematureCommitments, "receivedPrematureCommitments");
|
||||||
|
|
||||||
|
if (detailLevel == 2) {
|
||||||
|
UniValue arr(UniValue::VARR);
|
||||||
|
for (const auto& dmn : dmnMembers) {
|
||||||
|
arr.push_back(dmn->proTxHash.ToString());
|
||||||
|
}
|
||||||
|
ret.push_back(Pair("allMembers", arr));
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
CDKGDebugManager::CDKGDebugManager(CScheduler* scheduler)
|
||||||
|
{
|
||||||
|
for (const auto& p : Params().GetConsensus().llmqs) {
|
||||||
|
ResetLocalSessionStatus(p.first, uint256(), 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (scheduler) {
|
||||||
|
scheduler->scheduleEvery([&]() {
|
||||||
|
SendLocalStatus();
|
||||||
|
}, 10);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void CDKGDebugManager::ProcessMessage(CNode* pfrom, const std::string& strCommand, CDataStream& vRecv, CConnman& connman)
|
||||||
|
{
|
||||||
|
if (strCommand == NetMsgType::QDEBUGSTATUS) {
|
||||||
|
CDKGDebugStatus status;
|
||||||
|
vRecv >> status;
|
||||||
|
|
||||||
|
{
|
||||||
|
LOCK(cs_main);
|
||||||
|
connman.RemoveAskFor(::SerializeHash(status));
|
||||||
|
}
|
||||||
|
|
||||||
|
ProcessDebugStatusMessage(pfrom->id, status);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void CDKGDebugManager::ProcessDebugStatusMessage(NodeId nodeId, llmq::CDKGDebugStatus& status)
|
||||||
|
{
|
||||||
|
auto dmn = deterministicMNManager->GetListAtChainTip().GetMN(status.proTxHash);
|
||||||
|
if (!dmn) {
|
||||||
|
if (nodeId != -1) {
|
||||||
|
LOCK(cs_main);
|
||||||
|
Misbehaving(nodeId, 10);
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
LOCK(cs);
|
||||||
|
auto it = statusesForMasternodes.find(status.proTxHash);
|
||||||
|
if (it != statusesForMasternodes.end()) {
|
||||||
|
if (statuses[it->second].nTime >= status.nTime) {
|
||||||
|
// we know a more recent status already
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// check if all expected LLMQ types are present and valid
|
||||||
|
std::set<Consensus::LLMQType> llmqTypes;
|
||||||
|
for (const auto& p : status.sessions) {
|
||||||
|
if (!Params().GetConsensus().llmqs.count((Consensus::LLMQType)p.first)) {
|
||||||
|
if (nodeId != -1) {
|
||||||
|
LOCK(cs_main);
|
||||||
|
Misbehaving(nodeId, 10);
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
const auto& params = Params().GetConsensus().llmqs.at((Consensus::LLMQType)p.first);
|
||||||
|
if (p.second.llmqType != p.first || p.second.members.size() != (size_t)params.size) {
|
||||||
|
if (nodeId != -1) {
|
||||||
|
LOCK(cs_main);
|
||||||
|
Misbehaving(nodeId, 10);
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
llmqTypes.emplace((Consensus::LLMQType)p.first);
|
||||||
|
}
|
||||||
|
for (const auto& p : Params().GetConsensus().llmqs) {
|
||||||
|
if (!llmqTypes.count(p.first)) {
|
||||||
|
if (nodeId != -1) {
|
||||||
|
LOCK(cs_main);
|
||||||
|
Misbehaving(nodeId, 10);
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO batch verification/processing
|
||||||
|
if (!status.sig.VerifyInsecure(dmn->pdmnState->pubKeyOperator, status.GetSignHash())) {
|
||||||
|
if (nodeId != -1) {
|
||||||
|
LOCK(cs_main);
|
||||||
|
Misbehaving(nodeId, 10);
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
LOCK(cs);
|
||||||
|
auto it = statusesForMasternodes.find(status.proTxHash);
|
||||||
|
if (it != statusesForMasternodes.end()) {
|
||||||
|
statuses.erase(it->second);
|
||||||
|
statusesForMasternodes.erase(it);
|
||||||
|
}
|
||||||
|
|
||||||
|
auto hash = ::SerializeHash(status);
|
||||||
|
|
||||||
|
statuses[hash] = status;
|
||||||
|
statusesForMasternodes[status.proTxHash] = hash;
|
||||||
|
|
||||||
|
CInv inv(MSG_QUORUM_DEBUG_STATUS, hash);
|
||||||
|
g_connman->RelayInv(inv, DMN_PROTO_VERSION);
|
||||||
|
}
|
||||||
|
|
||||||
|
UniValue CDKGDebugStatus::ToJson(int detailLevel) const
|
||||||
|
{
|
||||||
|
UniValue ret(UniValue::VOBJ);
|
||||||
|
|
||||||
|
ret.push_back(Pair("proTxHash", proTxHash.ToString()));
|
||||||
|
ret.push_back(Pair("height", (int)nHeight));
|
||||||
|
ret.push_back(Pair("time", nTime));
|
||||||
|
ret.push_back(Pair("timeStr", DateTimeStrFormat("%Y-%m-%d %H:%M:%S", nTime)));
|
||||||
|
|
||||||
|
UniValue sessionsJson(UniValue::VOBJ);
|
||||||
|
for (const auto& p : sessions) {
|
||||||
|
if (!Params().GetConsensus().llmqs.count((Consensus::LLMQType)p.first)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
const auto& params = Params().GetConsensus().llmqs.at((Consensus::LLMQType)p.first);
|
||||||
|
sessionsJson.push_back(Pair(params.name, p.second.ToJson(detailLevel)));
|
||||||
|
}
|
||||||
|
|
||||||
|
ret.push_back(Pair("session", sessionsJson));
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool CDKGDebugManager::AlreadyHave(const CInv& inv)
|
||||||
|
{
|
||||||
|
LOCK(cs);
|
||||||
|
return statuses.count(inv.hash) != 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool CDKGDebugManager::GetDebugStatus(const uint256& hash, llmq::CDKGDebugStatus& ret)
|
||||||
|
{
|
||||||
|
LOCK(cs);
|
||||||
|
auto it = statuses.find(hash);
|
||||||
|
if (it == statuses.end()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
ret = it->second;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool CDKGDebugManager::GetDebugStatusForMasternode(const uint256& proTxHash, llmq::CDKGDebugStatus& ret)
|
||||||
|
{
|
||||||
|
LOCK(cs);
|
||||||
|
auto it = statusesForMasternodes.find(proTxHash);
|
||||||
|
if (it == statusesForMasternodes.end()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
ret = statuses.at(it->second);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void CDKGDebugManager::GetLocalDebugStatus(llmq::CDKGDebugStatus& ret)
|
||||||
|
{
|
||||||
|
LOCK(cs);
|
||||||
|
ret = localStatus;
|
||||||
|
ret.proTxHash = activeMasternodeInfo.proTxHash;
|
||||||
|
}
|
||||||
|
|
||||||
|
void CDKGDebugManager::ResetLocalSessionStatus(Consensus::LLMQType llmqType, const uint256& quorumHash, int quorumHeight)
|
||||||
|
{
|
||||||
|
LOCK(cs);
|
||||||
|
|
||||||
|
auto& params = Params().GetConsensus().llmqs.at(llmqType);
|
||||||
|
|
||||||
|
localStatus.nTime = GetAdjustedTime();
|
||||||
|
|
||||||
|
auto& session = localStatus.sessions[llmqType];
|
||||||
|
|
||||||
|
session.llmqType = llmqType;
|
||||||
|
session.quorumHash = quorumHash;
|
||||||
|
session.quorumHeight = (uint32_t)quorumHeight;
|
||||||
|
session.phase = 0;
|
||||||
|
session.statusBitset = 0;
|
||||||
|
session.members.clear();
|
||||||
|
session.members.resize((size_t)params.size);
|
||||||
|
}
|
||||||
|
|
||||||
|
void CDKGDebugManager::UpdateLocalStatus(std::function<bool(CDKGDebugStatus& status)>&& func)
|
||||||
|
{
|
||||||
|
LOCK(cs);
|
||||||
|
if (func(localStatus)) {
|
||||||
|
localStatus.nTime = GetAdjustedTime();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void CDKGDebugManager::UpdateLocalSessionStatus(Consensus::LLMQType llmqType, std::function<bool(CDKGDebugSessionStatus& status)>&& func)
|
||||||
|
{
|
||||||
|
LOCK(cs);
|
||||||
|
if (func(localStatus.sessions.at(llmqType))) {
|
||||||
|
localStatus.nTime = GetAdjustedTime();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void CDKGDebugManager::UpdateLocalMemberStatus(Consensus::LLMQType llmqType, size_t memberIdx, std::function<bool(CDKGDebugMemberStatus& status)>&& func)
|
||||||
|
{
|
||||||
|
LOCK(cs);
|
||||||
|
if (func(localStatus.sessions.at(llmqType).members.at(memberIdx))) {
|
||||||
|
localStatus.nTime = GetAdjustedTime();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void CDKGDebugManager::SendLocalStatus()
|
||||||
|
{
|
||||||
|
if (!fMasternodeMode) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (activeMasternodeInfo.proTxHash.IsNull()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
CDKGDebugStatus status;
|
||||||
|
{
|
||||||
|
LOCK(cs);
|
||||||
|
status = localStatus;
|
||||||
|
}
|
||||||
|
|
||||||
|
int64_t nTime = status.nTime;
|
||||||
|
status.proTxHash = activeMasternodeInfo.proTxHash;
|
||||||
|
status.nTime = 0;
|
||||||
|
status.sig = CBLSSignature();
|
||||||
|
|
||||||
|
uint256 newHash = ::SerializeHash(status);
|
||||||
|
if (newHash == lastStatusHash) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
lastStatusHash = newHash;
|
||||||
|
|
||||||
|
status.nTime = nTime;
|
||||||
|
status.sig = activeMasternodeInfo.blsKeyOperator->Sign(status.GetSignHash());
|
||||||
|
|
||||||
|
ProcessDebugStatusMessage(-1, status);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
178
src/llmq/quorums_debug.h
Normal file
178
src/llmq/quorums_debug.h
Normal file
@ -0,0 +1,178 @@
|
|||||||
|
// Copyright (c) 2018 The Dash Core developers
|
||||||
|
// Distributed under the MIT/X11 software license, see the accompanying
|
||||||
|
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
||||||
|
|
||||||
|
#ifndef DASH_QUORUMS_DEBUG_H
|
||||||
|
#define DASH_QUORUMS_DEBUG_H
|
||||||
|
|
||||||
|
#include "consensus/params.h"
|
||||||
|
#include "serialize.h"
|
||||||
|
#include "bls/bls.h"
|
||||||
|
#include "sync.h"
|
||||||
|
#include "univalue.h"
|
||||||
|
#include "net.h"
|
||||||
|
|
||||||
|
class CDataStream;
|
||||||
|
class CInv;
|
||||||
|
class CScheduler;
|
||||||
|
|
||||||
|
namespace llmq
|
||||||
|
{
|
||||||
|
|
||||||
|
class CDKGDebugMemberStatus
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
union {
|
||||||
|
struct
|
||||||
|
{
|
||||||
|
// is it locally considered as bad (and thus removed from the validMembers set)
|
||||||
|
bool bad : 1;
|
||||||
|
// did we complain about this member
|
||||||
|
bool weComplain : 1;
|
||||||
|
|
||||||
|
// received message for DKG phases
|
||||||
|
bool receivedContribution : 1;
|
||||||
|
bool receivedComplaint : 1;
|
||||||
|
bool receivedJustification : 1;
|
||||||
|
bool receivedPrematureCommitment : 1;
|
||||||
|
};
|
||||||
|
uint16_t statusBitset;
|
||||||
|
};
|
||||||
|
|
||||||
|
std::set<size_t> complaintsFromMembers;
|
||||||
|
|
||||||
|
public:
|
||||||
|
CDKGDebugMemberStatus() : statusBitset(0) {}
|
||||||
|
|
||||||
|
public:
|
||||||
|
ADD_SERIALIZE_METHODS
|
||||||
|
|
||||||
|
template<typename Stream, typename Operation>
|
||||||
|
inline void SerializationOp(Stream& s, Operation ser_action)
|
||||||
|
{
|
||||||
|
READWRITE(statusBitset);
|
||||||
|
READWRITE(complaintsFromMembers);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
class CDKGDebugSessionStatus
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
uint8_t llmqType{Consensus::LLMQ_NONE};
|
||||||
|
uint256 quorumHash;
|
||||||
|
uint32_t quorumHeight{0};
|
||||||
|
uint8_t phase{0};
|
||||||
|
|
||||||
|
union {
|
||||||
|
struct
|
||||||
|
{
|
||||||
|
// sent messages for DKG phases
|
||||||
|
bool sentContributions : 1;
|
||||||
|
bool sentComplaint : 1;
|
||||||
|
bool sentJustification : 1;
|
||||||
|
bool sentPrematureCommitment : 1;
|
||||||
|
|
||||||
|
bool aborted : 1;
|
||||||
|
};
|
||||||
|
uint16_t statusBitset;
|
||||||
|
};
|
||||||
|
|
||||||
|
std::vector<CDKGDebugMemberStatus> members;
|
||||||
|
|
||||||
|
public:
|
||||||
|
CDKGDebugSessionStatus() : statusBitset(0) {}
|
||||||
|
|
||||||
|
public:
|
||||||
|
ADD_SERIALIZE_METHODS
|
||||||
|
|
||||||
|
template<typename Stream, typename Operation>
|
||||||
|
inline void SerializationOp(Stream& s, Operation ser_action)
|
||||||
|
{
|
||||||
|
READWRITE(llmqType);
|
||||||
|
READWRITE(quorumHash);
|
||||||
|
READWRITE(quorumHeight);
|
||||||
|
READWRITE(phase);
|
||||||
|
READWRITE(statusBitset);
|
||||||
|
READWRITE(members);
|
||||||
|
}
|
||||||
|
|
||||||
|
UniValue ToJson(int detailLevel) const;
|
||||||
|
};
|
||||||
|
|
||||||
|
class CDKGDebugStatus
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
uint256 proTxHash;
|
||||||
|
int64_t nTime{0};
|
||||||
|
uint32_t nHeight{0};
|
||||||
|
|
||||||
|
std::map<uint8_t, CDKGDebugSessionStatus> sessions;
|
||||||
|
|
||||||
|
CBLSSignature sig;
|
||||||
|
|
||||||
|
public:
|
||||||
|
ADD_SERIALIZE_METHODS
|
||||||
|
|
||||||
|
template<typename Stream, typename Operation>
|
||||||
|
inline void SerializationOpWithoutSig(Stream& s, Operation ser_action)
|
||||||
|
{
|
||||||
|
READWRITE(proTxHash);
|
||||||
|
READWRITE(nTime);
|
||||||
|
READWRITE(nHeight);
|
||||||
|
READWRITE(sessions);
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename Stream, typename Operation>
|
||||||
|
inline void SerializationOp(Stream& s, Operation ser_action)
|
||||||
|
{
|
||||||
|
SerializationOpWithoutSig(s, ser_action);
|
||||||
|
READWRITE(sig);
|
||||||
|
}
|
||||||
|
|
||||||
|
uint256 GetSignHash() const
|
||||||
|
{
|
||||||
|
CHashWriter hw(SER_GETHASH, 0);
|
||||||
|
NCONST_PTR(this)->SerializationOpWithoutSig(hw, CSerActionSerialize());
|
||||||
|
hw << CBLSSignature();
|
||||||
|
return hw.GetHash();
|
||||||
|
}
|
||||||
|
|
||||||
|
UniValue ToJson(int detailLevel) const;
|
||||||
|
};
|
||||||
|
|
||||||
|
class CDKGDebugManager
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
CCriticalSection cs;
|
||||||
|
|
||||||
|
std::map<uint256, CDKGDebugStatus> statuses;
|
||||||
|
std::map<uint256, uint256> statusesForMasternodes;
|
||||||
|
|
||||||
|
CDKGDebugStatus localStatus;
|
||||||
|
uint256 lastStatusHash;
|
||||||
|
|
||||||
|
public:
|
||||||
|
CDKGDebugManager(CScheduler* scheduler);
|
||||||
|
|
||||||
|
void ProcessMessage(CNode* pfrom, const std::string& strCommand, CDataStream& vRecv, CConnman& connman);
|
||||||
|
void ProcessDebugStatusMessage(NodeId nodeId, CDKGDebugStatus& status);
|
||||||
|
|
||||||
|
bool AlreadyHave(const CInv& inv);
|
||||||
|
bool GetDebugStatus(const uint256& hash, CDKGDebugStatus& ret);
|
||||||
|
bool GetDebugStatusForMasternode(const uint256& proTxHash, CDKGDebugStatus& ret);
|
||||||
|
void GetLocalDebugStatus(CDKGDebugStatus& ret);
|
||||||
|
|
||||||
|
void ResetLocalSessionStatus(Consensus::LLMQType llmqType, const uint256& quorumHash, int quorumHeight);
|
||||||
|
|
||||||
|
void UpdateLocalStatus(std::function<bool(CDKGDebugStatus& status)>&& func);
|
||||||
|
void UpdateLocalSessionStatus(Consensus::LLMQType llmqType, std::function<bool(CDKGDebugSessionStatus& status)>&& func);
|
||||||
|
void UpdateLocalMemberStatus(Consensus::LLMQType llmqType, size_t memberIdx, std::function<bool(CDKGDebugMemberStatus& status)>&& func);
|
||||||
|
|
||||||
|
void SendLocalStatus();
|
||||||
|
};
|
||||||
|
|
||||||
|
extern CDKGDebugManager* quorumDKGDebugManager;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif //DASH_QUORUMS_DEBUG_H
|
@ -5,6 +5,7 @@
|
|||||||
#include "quorums_dkgsession.h"
|
#include "quorums_dkgsession.h"
|
||||||
|
|
||||||
#include "quorums_commitment.h"
|
#include "quorums_commitment.h"
|
||||||
|
#include "quorums_debug.h"
|
||||||
#include "quorums_dkgsessionmgr.h"
|
#include "quorums_dkgsessionmgr.h"
|
||||||
#include "quorums_utils.h"
|
#include "quorums_utils.h"
|
||||||
|
|
||||||
@ -177,6 +178,11 @@ void CDKGSession::SendContributions()
|
|||||||
|
|
||||||
logger.Flush();
|
logger.Flush();
|
||||||
|
|
||||||
|
quorumDKGDebugManager->UpdateLocalSessionStatus(params.type, [&](CDKGDebugSessionStatus& status) {
|
||||||
|
status.sentContributions = true;
|
||||||
|
return true;
|
||||||
|
});
|
||||||
|
|
||||||
uint256 hash = ::SerializeHash(qc);
|
uint256 hash = ::SerializeHash(qc);
|
||||||
bool ban = false;
|
bool ban = false;
|
||||||
if (PreVerifyMessage(hash, qc, ban)) {
|
if (PreVerifyMessage(hash, qc, ban)) {
|
||||||
@ -265,6 +271,11 @@ void CDKGSession::ReceiveMessage(const uint256& hash, const CDKGContribution& qc
|
|||||||
invSet.emplace(inv);
|
invSet.emplace(inv);
|
||||||
RelayInvToParticipants(inv);
|
RelayInvToParticipants(inv);
|
||||||
|
|
||||||
|
quorumDKGDebugManager->UpdateLocalMemberStatus(params.type, member->idx, [&](CDKGDebugMemberStatus& status) {
|
||||||
|
status.receivedContribution = true;
|
||||||
|
return true;
|
||||||
|
});
|
||||||
|
|
||||||
if (member->contributions.size() > 1) {
|
if (member->contributions.size() > 1) {
|
||||||
// don't do any further processing if we got more than 1 contribution. we already relayed it,
|
// don't do any further processing if we got more than 1 contribution. we already relayed it,
|
||||||
// so others know about his bad behavior
|
// so others know about his bad behavior
|
||||||
@ -306,6 +317,10 @@ void CDKGSession::ReceiveMessage(const uint256& hash, const CDKGContribution& qc
|
|||||||
|
|
||||||
if (complain) {
|
if (complain) {
|
||||||
member->weComplain = true;
|
member->weComplain = true;
|
||||||
|
quorumDKGDebugManager->UpdateLocalMemberStatus(params.type, member->idx, [&](CDKGDebugMemberStatus& status) {
|
||||||
|
status.weComplain = true;
|
||||||
|
return true;
|
||||||
|
});
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -364,6 +379,10 @@ void CDKGSession::VerifyPendingContributions()
|
|||||||
auto& m = members[memberIndexes[i]];
|
auto& m = members[memberIndexes[i]];
|
||||||
logger.Printf("invalid contribution from %s. will complain later\n", m->dmn->proTxHash.ToString());
|
logger.Printf("invalid contribution from %s. will complain later\n", m->dmn->proTxHash.ToString());
|
||||||
m->weComplain = true;
|
m->weComplain = true;
|
||||||
|
quorumDKGDebugManager->UpdateLocalMemberStatus(params.type, m->idx, [&](CDKGDebugMemberStatus& status) {
|
||||||
|
status.weComplain = true;
|
||||||
|
return true;
|
||||||
|
});
|
||||||
} else {
|
} else {
|
||||||
size_t memberIdx = memberIndexes[i];
|
size_t memberIdx = memberIndexes[i];
|
||||||
dkgManager.WriteVerifiedSkContribution(params.type, quorumHash, members[memberIdx]->dmn->proTxHash, skContributions[i]);
|
dkgManager.WriteVerifiedSkContribution(params.type, quorumHash, members[memberIdx]->dmn->proTxHash, skContributions[i]);
|
||||||
@ -443,6 +462,11 @@ void CDKGSession::SendComplaint()
|
|||||||
|
|
||||||
logger.Flush();
|
logger.Flush();
|
||||||
|
|
||||||
|
quorumDKGDebugManager->UpdateLocalSessionStatus(params.type, [&](CDKGDebugSessionStatus& status) {
|
||||||
|
status.sentComplaint = true;
|
||||||
|
return true;
|
||||||
|
});
|
||||||
|
|
||||||
uint256 hash = ::SerializeHash(qc);
|
uint256 hash = ::SerializeHash(qc);
|
||||||
bool ban = false;
|
bool ban = false;
|
||||||
if (PreVerifyMessage(hash, qc, ban)) {
|
if (PreVerifyMessage(hash, qc, ban)) {
|
||||||
@ -522,6 +546,11 @@ void CDKGSession::ReceiveMessage(const uint256& hash, const CDKGComplaint& qc, b
|
|||||||
invSet.emplace(inv);
|
invSet.emplace(inv);
|
||||||
RelayInvToParticipants(inv);
|
RelayInvToParticipants(inv);
|
||||||
|
|
||||||
|
quorumDKGDebugManager->UpdateLocalMemberStatus(params.type, member->idx, [&](CDKGDebugMemberStatus& status) {
|
||||||
|
status.receivedComplaint = true;
|
||||||
|
return true;
|
||||||
|
});
|
||||||
|
|
||||||
if (member->complaints.size() > 1) {
|
if (member->complaints.size() > 1) {
|
||||||
// don't do any further processing if we got more than 1 complaint. we already relayed it,
|
// don't do any further processing if we got more than 1 complaint. we already relayed it,
|
||||||
// so others know about his bad behavior
|
// so others know about his bad behavior
|
||||||
@ -544,6 +573,9 @@ void CDKGSession::ReceiveMessage(const uint256& hash, const CDKGComplaint& qc, b
|
|||||||
if (qc.complainForMembers[i]) {
|
if (qc.complainForMembers[i]) {
|
||||||
m->complaintsFromOthers.emplace(qc.proTxHash);
|
m->complaintsFromOthers.emplace(qc.proTxHash);
|
||||||
m->someoneComplain = true;
|
m->someoneComplain = true;
|
||||||
|
quorumDKGDebugManager->UpdateLocalMemberStatus(params.type, m->idx, [&](CDKGDebugMemberStatus& status) {
|
||||||
|
return status.complaintsFromMembers.emplace(member->idx).second;
|
||||||
|
});
|
||||||
if (AreWeMember() && i == myIdx) {
|
if (AreWeMember() && i == myIdx) {
|
||||||
logger.Printf("%s complained about us\n", member->dmn->proTxHash.ToString());
|
logger.Printf("%s complained about us\n", member->dmn->proTxHash.ToString());
|
||||||
}
|
}
|
||||||
@ -636,6 +668,11 @@ void CDKGSession::SendJustification(const std::set<uint256>& forMembers)
|
|||||||
|
|
||||||
logger.Flush();
|
logger.Flush();
|
||||||
|
|
||||||
|
quorumDKGDebugManager->UpdateLocalSessionStatus(params.type, [&](CDKGDebugSessionStatus& status) {
|
||||||
|
status.sentJustification = true;
|
||||||
|
return true;
|
||||||
|
});
|
||||||
|
|
||||||
uint256 hash = ::SerializeHash(qj);
|
uint256 hash = ::SerializeHash(qj);
|
||||||
bool ban = false;
|
bool ban = false;
|
||||||
if (PreVerifyMessage(hash, qj, ban)) {
|
if (PreVerifyMessage(hash, qj, ban)) {
|
||||||
@ -732,6 +769,11 @@ void CDKGSession::ReceiveMessage(const uint256& hash, const CDKGJustification& q
|
|||||||
invSet.emplace(inv);
|
invSet.emplace(inv);
|
||||||
RelayInvToParticipants(inv);
|
RelayInvToParticipants(inv);
|
||||||
|
|
||||||
|
quorumDKGDebugManager->UpdateLocalMemberStatus(params.type, member->idx, [&](CDKGDebugMemberStatus& status) {
|
||||||
|
status.receivedJustification = true;
|
||||||
|
return true;
|
||||||
|
});
|
||||||
|
|
||||||
if (member->justifications.size() > 1) {
|
if (member->justifications.size() > 1) {
|
||||||
// don't do any further processing if we got more than 1 justification. we already relayed it,
|
// don't do any further processing if we got more than 1 justification. we already relayed it,
|
||||||
// so others know about his bad behavior
|
// so others know about his bad behavior
|
||||||
@ -956,6 +998,11 @@ void CDKGSession::SendCommitment()
|
|||||||
|
|
||||||
logger.Flush();
|
logger.Flush();
|
||||||
|
|
||||||
|
quorumDKGDebugManager->UpdateLocalSessionStatus(params.type, [&](CDKGDebugSessionStatus& status) {
|
||||||
|
status.sentPrematureCommitment = true;
|
||||||
|
return true;
|
||||||
|
});
|
||||||
|
|
||||||
uint256 hash = ::SerializeHash(qc);
|
uint256 hash = ::SerializeHash(qc);
|
||||||
bool ban = false;
|
bool ban = false;
|
||||||
if (PreVerifyMessage(hash, qc, ban)) {
|
if (PreVerifyMessage(hash, qc, ban)) {
|
||||||
@ -1099,6 +1146,11 @@ void CDKGSession::ReceiveMessage(const uint256& hash, const CDKGPrematureCommitm
|
|||||||
invSet.emplace(inv);
|
invSet.emplace(inv);
|
||||||
RelayInvToParticipants(inv);
|
RelayInvToParticipants(inv);
|
||||||
|
|
||||||
|
quorumDKGDebugManager->UpdateLocalMemberStatus(params.type, member->idx, [&](CDKGDebugMemberStatus& status) {
|
||||||
|
status.receivedPrematureCommitment = true;
|
||||||
|
return true;
|
||||||
|
});
|
||||||
|
|
||||||
int receivedCount = 0;
|
int receivedCount = 0;
|
||||||
for (auto& m : members) {
|
for (auto& m : members) {
|
||||||
if (!m->prematureCommitments.empty()) {
|
if (!m->prematureCommitments.empty()) {
|
||||||
@ -1223,6 +1275,10 @@ void CDKGSession::MarkBadMember(size_t idx)
|
|||||||
if (member->bad) {
|
if (member->bad) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
quorumDKGDebugManager->UpdateLocalMemberStatus(params.type, idx, [&](CDKGDebugMemberStatus& status) {
|
||||||
|
status.bad = true;
|
||||||
|
return true;
|
||||||
|
});
|
||||||
member->bad = true;
|
member->bad = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -123,6 +123,7 @@ void CDKGSessionHandler::UpdatedBlockTip(const CBlockIndex* pindexNew, const CBl
|
|||||||
QuorumPhase newPhase = phase;
|
QuorumPhase newPhase = phase;
|
||||||
if (quorumStageInt == 0) {
|
if (quorumStageInt == 0) {
|
||||||
newPhase = QuorumPhase_Initialized;
|
newPhase = QuorumPhase_Initialized;
|
||||||
|
quorumDKGDebugManager->ResetLocalSessionStatus(params.type, quorumHash, quorumHeight);
|
||||||
} else if (quorumStageInt == params.dkgPhaseBlocks * 1) {
|
} else if (quorumStageInt == params.dkgPhaseBlocks * 1) {
|
||||||
newPhase = QuorumPhase_Contribute;
|
newPhase = QuorumPhase_Contribute;
|
||||||
} else if (quorumStageInt == params.dkgPhaseBlocks * 2) {
|
} else if (quorumStageInt == params.dkgPhaseBlocks * 2) {
|
||||||
@ -137,6 +138,17 @@ void CDKGSessionHandler::UpdatedBlockTip(const CBlockIndex* pindexNew, const CBl
|
|||||||
newPhase = QuorumPhase_Idle;
|
newPhase = QuorumPhase_Idle;
|
||||||
}
|
}
|
||||||
phase = newPhase;
|
phase = newPhase;
|
||||||
|
|
||||||
|
quorumDKGDebugManager->UpdateLocalStatus([&](CDKGDebugStatus& status) {
|
||||||
|
bool changed = status.nHeight != pindexNew->nHeight;
|
||||||
|
status.nHeight = (uint32_t)pindexNew->nHeight;
|
||||||
|
return changed;
|
||||||
|
});
|
||||||
|
quorumDKGDebugManager->UpdateLocalSessionStatus(params.type, [&](CDKGDebugSessionStatus& status) {
|
||||||
|
bool changed = status.phase != (uint8_t)phase;
|
||||||
|
status.phase = (uint8_t)phase;
|
||||||
|
return changed;
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
void CDKGSessionHandler::ProcessMessage(CNode* pfrom, const std::string& strCommand, CDataStream& vRecv, CConnman& connman)
|
void CDKGSessionHandler::ProcessMessage(CNode* pfrom, const std::string& strCommand, CDataStream& vRecv, CConnman& connman)
|
||||||
@ -530,6 +542,10 @@ void CDKGSessionHandler::PhaseHandlerThread()
|
|||||||
try {
|
try {
|
||||||
HandleDKGRound();
|
HandleDKGRound();
|
||||||
} catch (AbortPhaseException& e) {
|
} catch (AbortPhaseException& e) {
|
||||||
|
quorumDKGDebugManager->UpdateLocalSessionStatus(params.type, [&](CDKGDebugSessionStatus& status) {
|
||||||
|
status.aborted = true;
|
||||||
|
return true;
|
||||||
|
});
|
||||||
LogPrintf("CDKGSessionHandler::%s -- aborted current DKG session\n", __func__);
|
LogPrintf("CDKGSessionHandler::%s -- aborted current DKG session\n", __func__);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -4,6 +4,7 @@
|
|||||||
|
|
||||||
#include "quorums_dkgsessionmgr.h"
|
#include "quorums_dkgsessionmgr.h"
|
||||||
#include "quorums_blockprocessor.h"
|
#include "quorums_blockprocessor.h"
|
||||||
|
#include "quorums_debug.h"
|
||||||
#include "quorums_init.h"
|
#include "quorums_init.h"
|
||||||
#include "quorums_utils.h"
|
#include "quorums_utils.h"
|
||||||
|
|
||||||
|
@ -6,6 +6,7 @@
|
|||||||
|
|
||||||
#include "quorums_blockprocessor.h"
|
#include "quorums_blockprocessor.h"
|
||||||
#include "quorums_commitment.h"
|
#include "quorums_commitment.h"
|
||||||
|
#include "quorums_debug.h"
|
||||||
#include "quorums_dkgsessionmgr.h"
|
#include "quorums_dkgsessionmgr.h"
|
||||||
|
|
||||||
#include "scheduler.h"
|
#include "scheduler.h"
|
||||||
@ -17,6 +18,7 @@ static CBLSWorker blsWorker;
|
|||||||
|
|
||||||
void InitLLMQSystem(CEvoDB& evoDb, CScheduler* scheduler)
|
void InitLLMQSystem(CEvoDB& evoDb, CScheduler* scheduler)
|
||||||
{
|
{
|
||||||
|
quorumDKGDebugManager = new CDKGDebugManager(scheduler);
|
||||||
quorumBlockProcessor = new CQuorumBlockProcessor(evoDb);
|
quorumBlockProcessor = new CQuorumBlockProcessor(evoDb);
|
||||||
quorumDKGSessionManager = new CDKGSessionManager(evoDb, blsWorker);
|
quorumDKGSessionManager = new CDKGSessionManager(evoDb, blsWorker);
|
||||||
}
|
}
|
||||||
@ -27,6 +29,8 @@ void DestroyLLMQSystem()
|
|||||||
quorumDKGSessionManager = NULL;
|
quorumDKGSessionManager = NULL;
|
||||||
delete quorumBlockProcessor;
|
delete quorumBlockProcessor;
|
||||||
quorumBlockProcessor = nullptr;
|
quorumBlockProcessor = nullptr;
|
||||||
|
delete quorumDKGDebugManager;
|
||||||
|
quorumDKGDebugManager = nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -46,6 +46,7 @@
|
|||||||
#include "evo/simplifiedmns.h"
|
#include "evo/simplifiedmns.h"
|
||||||
#include "llmq/quorums_blockprocessor.h"
|
#include "llmq/quorums_blockprocessor.h"
|
||||||
#include "llmq/quorums_commitment.h"
|
#include "llmq/quorums_commitment.h"
|
||||||
|
#include "llmq/quorums_debug.h"
|
||||||
#include "llmq/quorums_dkgsessionmgr.h"
|
#include "llmq/quorums_dkgsessionmgr.h"
|
||||||
#include "llmq/quorums_init.h"
|
#include "llmq/quorums_init.h"
|
||||||
|
|
||||||
@ -956,6 +957,8 @@ bool static AlreadyHave(const CInv& inv) EXCLUSIVE_LOCKS_REQUIRED(cs_main)
|
|||||||
case MSG_QUORUM_JUSTIFICATION:
|
case MSG_QUORUM_JUSTIFICATION:
|
||||||
case MSG_QUORUM_PREMATURE_COMMITMENT:
|
case MSG_QUORUM_PREMATURE_COMMITMENT:
|
||||||
return llmq::quorumDKGSessionManager->AlreadyHave(inv);
|
return llmq::quorumDKGSessionManager->AlreadyHave(inv);
|
||||||
|
case MSG_QUORUM_DEBUG_STATUS:
|
||||||
|
return llmq::quorumDKGDebugManager->AlreadyHave(inv);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Don't know what it is, just say we already got one
|
// Don't know what it is, just say we already got one
|
||||||
@ -1253,6 +1256,13 @@ void static ProcessGetData(CNode* pfrom, const Consensus::Params& consensusParam
|
|||||||
push = true;
|
push = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (!push && (inv.type == MSG_QUORUM_DEBUG_STATUS)) {
|
||||||
|
llmq::CDKGDebugStatus o;
|
||||||
|
if (llmq::quorumDKGDebugManager->GetDebugStatus(inv.hash, o)) {
|
||||||
|
connman.PushMessage(pfrom, msgMaker.Make(NetMsgType::QDEBUGSTATUS, o));
|
||||||
|
push = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (!push)
|
if (!push)
|
||||||
vNotFound.push_back(inv);
|
vNotFound.push_back(inv);
|
||||||
@ -2911,6 +2921,7 @@ bool static ProcessMessage(CNode* pfrom, const std::string& strCommand, CDataStr
|
|||||||
governance.ProcessMessage(pfrom, strCommand, vRecv, connman);
|
governance.ProcessMessage(pfrom, strCommand, vRecv, connman);
|
||||||
llmq::quorumBlockProcessor->ProcessMessage(pfrom, strCommand, vRecv, connman);
|
llmq::quorumBlockProcessor->ProcessMessage(pfrom, strCommand, vRecv, connman);
|
||||||
llmq::quorumDKGSessionManager->ProcessMessage(pfrom, strCommand, vRecv, connman);
|
llmq::quorumDKGSessionManager->ProcessMessage(pfrom, strCommand, vRecv, connman);
|
||||||
|
llmq::quorumDKGDebugManager->ProcessMessage(pfrom, strCommand, vRecv, connman);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -64,6 +64,7 @@ const char *QCOMPLAINT="qcomplaint";
|
|||||||
const char *QJUSTIFICATION="qjustify";
|
const char *QJUSTIFICATION="qjustify";
|
||||||
const char *QPCOMMITMENT="qpcommit";
|
const char *QPCOMMITMENT="qpcommit";
|
||||||
const char *QWATCH="qwatch";
|
const char *QWATCH="qwatch";
|
||||||
|
const char *QDEBUGSTATUS="qdebugstatus";
|
||||||
};
|
};
|
||||||
|
|
||||||
static const char* ppszTypeName[] =
|
static const char* ppszTypeName[] =
|
||||||
@ -97,6 +98,7 @@ static const char* ppszTypeName[] =
|
|||||||
NetMsgType::QCOMPLAINT,
|
NetMsgType::QCOMPLAINT,
|
||||||
NetMsgType::QJUSTIFICATION,
|
NetMsgType::QJUSTIFICATION,
|
||||||
NetMsgType::QPCOMMITMENT,
|
NetMsgType::QPCOMMITMENT,
|
||||||
|
NetMsgType::QDEBUGSTATUS,
|
||||||
};
|
};
|
||||||
|
|
||||||
/** All known message types. Keep this in the same order as the list of
|
/** All known message types. Keep this in the same order as the list of
|
||||||
@ -155,6 +157,7 @@ const static std::string allNetMessageTypes[] = {
|
|||||||
NetMsgType::QJUSTIFICATION,
|
NetMsgType::QJUSTIFICATION,
|
||||||
NetMsgType::QPCOMMITMENT,
|
NetMsgType::QPCOMMITMENT,
|
||||||
NetMsgType::QWATCH,
|
NetMsgType::QWATCH,
|
||||||
|
NetMsgType::QDEBUGSTATUS,
|
||||||
};
|
};
|
||||||
const static std::vector<std::string> allNetMessageTypesVec(allNetMessageTypes, allNetMessageTypes+ARRAYLEN(allNetMessageTypes));
|
const static std::vector<std::string> allNetMessageTypesVec(allNetMessageTypes, allNetMessageTypes+ARRAYLEN(allNetMessageTypes));
|
||||||
|
|
||||||
|
@ -270,6 +270,7 @@ extern const char *QCOMPLAINT;
|
|||||||
extern const char *QJUSTIFICATION;
|
extern const char *QJUSTIFICATION;
|
||||||
extern const char *QPCOMMITMENT;
|
extern const char *QPCOMMITMENT;
|
||||||
extern const char *QWATCH;
|
extern const char *QWATCH;
|
||||||
|
extern const char *QDEBUGSTATUS;
|
||||||
};
|
};
|
||||||
|
|
||||||
/* Get a vector of all valid message types (see above) */
|
/* Get a vector of all valid message types (see above) */
|
||||||
@ -369,6 +370,7 @@ enum GetDataMsg {
|
|||||||
MSG_QUORUM_COMPLAINT = 24,
|
MSG_QUORUM_COMPLAINT = 24,
|
||||||
MSG_QUORUM_JUSTIFICATION = 25,
|
MSG_QUORUM_JUSTIFICATION = 25,
|
||||||
MSG_QUORUM_PREMATURE_COMMITMENT = 26,
|
MSG_QUORUM_PREMATURE_COMMITMENT = 26,
|
||||||
|
MSG_QUORUM_DEBUG_STATUS = 27,
|
||||||
};
|
};
|
||||||
|
|
||||||
/** inv message data */
|
/** inv message data */
|
||||||
|
@ -25,6 +25,8 @@ void RegisterMasternodeRPCCommands(CRPCTable &tableRPC);
|
|||||||
void RegisterGovernanceRPCCommands(CRPCTable &tableRPC);
|
void RegisterGovernanceRPCCommands(CRPCTable &tableRPC);
|
||||||
/** Register Evo RPC commands */
|
/** Register Evo RPC commands */
|
||||||
void RegisterEvoRPCCommands(CRPCTable &tableRPC);
|
void RegisterEvoRPCCommands(CRPCTable &tableRPC);
|
||||||
|
/** Register Quorums RPC commands */
|
||||||
|
void RegisterQuorumsRPCCommands(CRPCTable &tableRPC);
|
||||||
|
|
||||||
static inline void RegisterAllCoreRPCCommands(CRPCTable &t)
|
static inline void RegisterAllCoreRPCCommands(CRPCTable &t)
|
||||||
{
|
{
|
||||||
@ -36,6 +38,7 @@ static inline void RegisterAllCoreRPCCommands(CRPCTable &t)
|
|||||||
RegisterMasternodeRPCCommands(t);
|
RegisterMasternodeRPCCommands(t);
|
||||||
RegisterGovernanceRPCCommands(t);
|
RegisterGovernanceRPCCommands(t);
|
||||||
RegisterEvoRPCCommands(t);
|
RegisterEvoRPCCommands(t);
|
||||||
|
RegisterQuorumsRPCCommands(t);
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
81
src/rpc/rpcquorums.cpp
Normal file
81
src/rpc/rpcquorums.cpp
Normal file
@ -0,0 +1,81 @@
|
|||||||
|
// Copyright (c) 2017 The Dash Core developers
|
||||||
|
// Distributed under the MIT software license, see the accompanying
|
||||||
|
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
||||||
|
|
||||||
|
#include "server.h"
|
||||||
|
#include "validation.h"
|
||||||
|
|
||||||
|
#include "llmq/quorums_debug.h"
|
||||||
|
#include "llmq/quorums_dkgsession.h"
|
||||||
|
|
||||||
|
void quorum_dkgstatus_help()
|
||||||
|
{
|
||||||
|
throw std::runtime_error(
|
||||||
|
"quorum dkgstatus (detailed)\n"
|
||||||
|
"\nArguments:\n"
|
||||||
|
"1. \"proTxHash\" (string, optional, default=0) ProTxHash of masternode to show status for.\n"
|
||||||
|
" If set to an empty string or 0, the local status is shown.\n"
|
||||||
|
"2. \"detailLevel\" (number, optional, default=0) Detail level of output.\n"
|
||||||
|
" 0=Only show counts. 1=Show member indexes. 2=Show member's ProTxHashes.\n"
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
UniValue quorum_dkgstatus(const JSONRPCRequest& request)
|
||||||
|
{
|
||||||
|
if (request.fHelp || (request.params.size() != 1 && request.params.size() != 2 && request.params.size() != 3)) {
|
||||||
|
quorum_dkgstatus_help();
|
||||||
|
}
|
||||||
|
|
||||||
|
uint256 proTxHash;
|
||||||
|
if (request.params.size() > 1 && request.params[1].get_str() != "" && request.params[1].get_str() != "0") {
|
||||||
|
proTxHash = ParseHashV(request.params[1], "proTxHash");
|
||||||
|
}
|
||||||
|
|
||||||
|
int detailLevel = 0;
|
||||||
|
if (request.params.size() > 2) {
|
||||||
|
detailLevel = ParseInt32V(request.params[2], "detailLevel");
|
||||||
|
if (detailLevel < 0 || detailLevel > 2) {
|
||||||
|
throw JSONRPCError(RPC_INVALID_PARAMETER, "invalid detailLevel");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
llmq::CDKGDebugStatus status;
|
||||||
|
if (proTxHash.IsNull()) {
|
||||||
|
llmq::quorumDKGDebugManager->GetLocalDebugStatus(status);
|
||||||
|
} else {
|
||||||
|
if (!llmq::quorumDKGDebugManager->GetDebugStatusForMasternode(proTxHash, status)) {
|
||||||
|
throw JSONRPCError(RPC_INVALID_PARAMETER, strprintf("no status for %s found", proTxHash.ToString()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return status.ToJson(detailLevel);
|
||||||
|
}
|
||||||
|
|
||||||
|
UniValue quorum(const JSONRPCRequest& request)
|
||||||
|
{
|
||||||
|
if (request.params.empty()) {
|
||||||
|
throw std::runtime_error(
|
||||||
|
"quorum \"command\" ...\n"
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string command = request.params[0].get_str();
|
||||||
|
|
||||||
|
if (command == "dkgstatus") {
|
||||||
|
return quorum_dkgstatus(request);
|
||||||
|
} else {
|
||||||
|
throw std::runtime_error("invalid command: " + command);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static const CRPCCommand commands[] =
|
||||||
|
{ // category name actor (function) okSafeMode
|
||||||
|
// --------------------- ------------------------ ----------------------- ----------
|
||||||
|
{ "evo", "quorum", &quorum, false, {} },
|
||||||
|
};
|
||||||
|
|
||||||
|
void RegisterQuorumsRPCCommands(CRPCTable &tableRPC)
|
||||||
|
{
|
||||||
|
for (unsigned int vcidx = 0; vcidx < ARRAYLEN(commands); vcidx++)
|
||||||
|
tableRPC.appendCommand(commands[vcidx].name, &commands[vcidx]);
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user