refactor: use new approach for rpc quorums NNN

This commit is contained in:
Konstantin Akimov 2024-06-11 15:33:22 +07:00
parent 21af5af6c5
commit 2af9d86654
No known key found for this signature in database
GPG Key ID: 2176C4A5D01EA524

View File

@ -34,9 +34,9 @@ namespace llmq {
extern const std::string CLSIG_REQUESTID_PREFIX; extern const std::string CLSIG_REQUESTID_PREFIX;
} }
static void quorum_list_help(const JSONRPCRequest& request) static RPCHelpMan quorum_list()
{ {
RPCHelpMan{"quorum list", return RPCHelpMan{"quorum list",
"List of on-chain quorums\n", "List of on-chain quorums\n",
{ {
{"count", RPCArg::Type::NUM, /* default */ "", {"count", RPCArg::Type::NUM, /* default */ "",
@ -57,12 +57,11 @@ static void quorum_list_help(const JSONRPCRequest& request)
+ HelpExampleCli("quorum", "list 10") + HelpExampleCli("quorum", "list 10")
+ HelpExampleRpc("quorum", "list, 10") + HelpExampleRpc("quorum", "list, 10")
}, },
}.Check(request); [&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue
}
static UniValue quorum_list(const JSONRPCRequest& request, const ChainstateManager& chainman, const LLMQContext& llmq_ctx)
{ {
quorum_list_help(request); const NodeContext& node = EnsureAnyNodeContext(request.context);
const ChainstateManager& chainman = EnsureChainman(node);
const LLMQContext& llmq_ctx = EnsureLLMQContext(node);
int count = -1; int count = -1;
if (!request.params[0].isNull()) { if (!request.params[0].isNull()) {
@ -90,11 +89,13 @@ static UniValue quorum_list(const JSONRPCRequest& request, const ChainstateManag
} }
return ret; return ret;
},
};
} }
static void quorum_list_extended_help(const JSONRPCRequest& request) static RPCHelpMan quorum_list_extended()
{ {
RPCHelpMan{"quorum listextended", return RPCHelpMan{"quorum listextended",
"Extended list of on-chain quorums\n", "Extended list of on-chain quorums\n",
{ {
{"height", RPCArg::Type::NUM, /* default */ "", "The height index. Will list active quorums at tip if \"height\" is not specified."}, {"height", RPCArg::Type::NUM, /* default */ "", "The height index. Will list active quorums at tip if \"height\" is not specified."},
@ -122,12 +123,11 @@ static void quorum_list_extended_help(const JSONRPCRequest& request)
+ HelpExampleCli("quorum", "listextended 2500") + HelpExampleCli("quorum", "listextended 2500")
+ HelpExampleRpc("quorum", "listextended, 2500") + HelpExampleRpc("quorum", "listextended, 2500")
}, },
}.Check(request); [&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue
}
static UniValue quorum_list_extended(const JSONRPCRequest& request, const ChainstateManager& chainman, const LLMQContext& llmq_ctx)
{ {
quorum_list_extended_help(request); const NodeContext& node = EnsureAnyNodeContext(request.context);
const ChainstateManager& chainman = EnsureChainman(node);
const LLMQContext& llmq_ctx = EnsureLLMQContext(node);
int nHeight = -1; int nHeight = -1;
if (!request.params[0].isNull()) { if (!request.params[0].isNull()) {
@ -172,20 +172,8 @@ static UniValue quorum_list_extended(const JSONRPCRequest& request, const Chains
} }
return ret; return ret;
} },
};
static void quorum_info_help(const JSONRPCRequest& request)
{
RPCHelpMan{"quorum info",
"Return information about a quorum\n",
{
{"llmqType", RPCArg::Type::NUM, RPCArg::Optional::NO, "LLMQ type."},
{"quorumHash", RPCArg::Type::STR_HEX, RPCArg::Optional::NO, "Block hash of quorum."},
{"includeSkShare", RPCArg::Type::BOOL, /* default */ "", "Include secret key share in output."},
},
RPCResults{},
RPCExamples{""},
}.Check(request);
} }
static UniValue BuildQuorumInfo(const llmq::CQuorumBlockProcessor& quorum_block_processor, const llmq::CQuorumCPtr& quorum, bool includeMembers, bool includeSkShare) static UniValue BuildQuorumInfo(const llmq::CQuorumBlockProcessor& quorum_block_processor, const llmq::CQuorumCPtr& quorum, bool includeMembers, bool includeSkShare)
@ -237,9 +225,21 @@ static UniValue BuildQuorumInfo(const llmq::CQuorumBlockProcessor& quorum_block_
return ret; return ret;
} }
static UniValue quorum_info(const JSONRPCRequest& request, const LLMQContext& llmq_ctx) static RPCHelpMan quorum_info()
{ {
quorum_info_help(request); return RPCHelpMan{"quorum info",
"Return information about a quorum\n",
{
{"llmqType", RPCArg::Type::NUM, RPCArg::Optional::NO, "LLMQ type."},
{"quorumHash", RPCArg::Type::STR_HEX, RPCArg::Optional::NO, "Block hash of quorum."},
{"includeSkShare", RPCArg::Type::BOOL, /* default */ "", "Include secret key share in output."},
},
RPCResults{},
RPCExamples{""},
[&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue
{
const NodeContext& node = EnsureAnyNodeContext(request.context);
const LLMQContext& llmq_ctx = EnsureLLMQContext(node);
Consensus::LLMQType llmqType = (Consensus::LLMQType)ParseInt32V(request.params[0], "llmqType"); Consensus::LLMQType llmqType = (Consensus::LLMQType)ParseInt32V(request.params[0], "llmqType");
if (!Params().GetLLMQ(llmqType).has_value()) { if (!Params().GetLLMQ(llmqType).has_value()) {
@ -258,11 +258,13 @@ static UniValue quorum_info(const JSONRPCRequest& request, const LLMQContext& ll
} }
return BuildQuorumInfo(*llmq_ctx.quorum_block_processor, quorum, true, includeSkShare); return BuildQuorumInfo(*llmq_ctx.quorum_block_processor, quorum, true, includeSkShare);
},
};
} }
static void quorum_dkgstatus_help(const JSONRPCRequest& request) static RPCHelpMan quorum_dkgstatus()
{ {
RPCHelpMan{"quorum dkgstatus", return RPCHelpMan{"quorum dkgstatus",
"Return the status of the current DKG process.\n" "Return the status of the current DKG process.\n"
"Works only when SPORK_17_QUORUM_DKG_ENABLED spork is ON.\n", "Works only when SPORK_17_QUORUM_DKG_ENABLED spork is ON.\n",
{ {
@ -272,13 +274,11 @@ static void quorum_dkgstatus_help(const JSONRPCRequest& request)
}, },
RPCResults{}, RPCResults{},
RPCExamples{""}, RPCExamples{""},
}.Check(request); [&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue
}
static UniValue quorum_dkgstatus(const JSONRPCRequest& request, CDeterministicMNManager& dmnman, const CActiveMasternodeManager* const mn_activeman,
const ChainstateManager& chainman, const CSporkManager& sporkman, const LLMQContext& llmq_ctx)
{ {
quorum_dkgstatus_help(request); const NodeContext& node = EnsureAnyNodeContext(request.context);
const ChainstateManager& chainman = EnsureChainman(node);
const LLMQContext& llmq_ctx = EnsureLLMQContext(node);
int detailLevel = 0; int detailLevel = 0;
if (!request.params[0].isNull()) { if (!request.params[0].isNull()) {
@ -291,12 +291,11 @@ static UniValue quorum_dkgstatus(const JSONRPCRequest& request, CDeterministicMN
llmq::CDKGDebugStatus status; llmq::CDKGDebugStatus status;
llmq_ctx.dkg_debugman->GetLocalDebugStatus(status); llmq_ctx.dkg_debugman->GetLocalDebugStatus(status);
auto ret = status.ToJson(dmnman, chainman, detailLevel); auto ret = status.ToJson(*node.dmnman, chainman, detailLevel);
CBlockIndex* pindexTip = WITH_LOCK(cs_main, return chainman.ActiveChain().Tip()); CBlockIndex* pindexTip = WITH_LOCK(cs_main, return chainman.ActiveChain().Tip());
int tipHeight = pindexTip->nHeight; int tipHeight = pindexTip->nHeight;
const uint256 proTxHash = node.mn_activeman ? node.mn_activeman->GetProTxHash() : uint256();
const uint256 proTxHash = mn_activeman ? mn_activeman->GetProTxHash() : uint256();
UniValue minableCommitments(UniValue::VARR); UniValue minableCommitments(UniValue::VARR);
UniValue quorumArrConnections(UniValue::VARR); UniValue quorumArrConnections(UniValue::VARR);
@ -312,7 +311,7 @@ static UniValue quorum_dkgstatus(const JSONRPCRequest& request, CDeterministicMN
obj.pushKV("llmqType", std::string(llmq_params.name)); obj.pushKV("llmqType", std::string(llmq_params.name));
obj.pushKV("quorumIndex", quorumIndex); obj.pushKV("quorumIndex", quorumIndex);
if (mn_activeman) { if (node.mn_activeman) {
int quorumHeight = tipHeight - (tipHeight % llmq_params.dkgInterval) + quorumIndex; int quorumHeight = tipHeight - (tipHeight % llmq_params.dkgInterval) + quorumIndex;
if (quorumHeight <= tipHeight) { if (quorumHeight <= tipHeight) {
const CBlockIndex* pQuorumBaseBlockIndex = WITH_LOCK(cs_main, return chainman.ActiveChain()[quorumHeight]); const CBlockIndex* pQuorumBaseBlockIndex = WITH_LOCK(cs_main, return chainman.ActiveChain()[quorumHeight]);
@ -320,10 +319,9 @@ static UniValue quorum_dkgstatus(const JSONRPCRequest& request, CDeterministicMN
obj.pushKV("quorumHash", pQuorumBaseBlockIndex->GetBlockHash().ToString()); obj.pushKV("quorumHash", pQuorumBaseBlockIndex->GetBlockHash().ToString());
obj.pushKV("pindexTip", pindexTip->nHeight); obj.pushKV("pindexTip", pindexTip->nHeight);
auto allConnections = llmq::utils::GetQuorumConnections(llmq_params, dmnman, sporkman, pQuorumBaseBlockIndex, proTxHash, false); auto allConnections = llmq::utils::GetQuorumConnections(llmq_params, *node.dmnman, *node.sporkman, pQuorumBaseBlockIndex, proTxHash, false);
auto outboundConnections = llmq::utils::GetQuorumConnections(llmq_params, dmnman, sporkman, pQuorumBaseBlockIndex, proTxHash, true); auto outboundConnections = llmq::utils::GetQuorumConnections(llmq_params, *node.dmnman, *node.sporkman, pQuorumBaseBlockIndex, proTxHash, true);
std::map<uint256, CAddress> foundConnections; std::map<uint256, CAddress> foundConnections;
const NodeContext& node = EnsureAnyNodeContext(request.context);
node.connman->ForEachNode([&](const CNode* pnode) { node.connman->ForEachNode([&](const CNode* pnode) {
auto verifiedProRegTxHash = pnode->GetVerifiedProRegTxHash(); auto verifiedProRegTxHash = pnode->GetVerifiedProRegTxHash();
if (!verifiedProRegTxHash.IsNull() && allConnections.count(verifiedProRegTxHash)) { if (!verifiedProRegTxHash.IsNull() && allConnections.count(verifiedProRegTxHash)) {
@ -360,11 +358,13 @@ static UniValue quorum_dkgstatus(const JSONRPCRequest& request, CDeterministicMN
ret.pushKV("quorumConnections", quorumArrConnections); ret.pushKV("quorumConnections", quorumArrConnections);
ret.pushKV("minableCommitments", minableCommitments); ret.pushKV("minableCommitments", minableCommitments);
return ret; return ret;
},
};
} }
static void quorum_memberof_help(const JSONRPCRequest& request) static RPCHelpMan quorum_memberof()
{ {
RPCHelpMan{"quorum memberof", return RPCHelpMan{"quorum memberof",
"Checks which quorums the given masternode is a member of.\n", "Checks which quorums the given masternode is a member of.\n",
{ {
{"proTxHash", RPCArg::Type::STR_HEX, RPCArg::Optional::NO, "ProTxHash of the masternode."}, {"proTxHash", RPCArg::Type::STR_HEX, RPCArg::Optional::NO, "ProTxHash of the masternode."},
@ -376,12 +376,11 @@ static void quorum_memberof_help(const JSONRPCRequest& request)
}, },
RPCResults{}, RPCResults{},
RPCExamples{""}, RPCExamples{""},
}.Check(request); [&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue
}
static UniValue quorum_memberof(const JSONRPCRequest& request, const ChainstateManager& chainman, const NodeContext& node, const LLMQContext& llmq_ctx)
{ {
quorum_memberof_help(request); const NodeContext& node = EnsureAnyNodeContext(request.context);
const ChainstateManager& chainman = EnsureChainman(node);
const LLMQContext& llmq_ctx = EnsureLLMQContext(node);
uint256 protxHash(ParseHashV(request.params[0], "proTxHash")); uint256 protxHash(ParseHashV(request.params[0], "proTxHash"));
int scanQuorumsCount = -1; int scanQuorumsCount = -1;
@ -419,11 +418,13 @@ static UniValue quorum_memberof(const JSONRPCRequest& request, const ChainstateM
} }
return result; return result;
},
};
} }
static void quorum_sign_help(const JSONRPCRequest& request) static RPCHelpMan quorum_sign()
{ {
RPCHelpMan{"quorum sign", return RPCHelpMan{"quorum sign",
"Threshold-sign a message\n", "Threshold-sign a message\n",
{ {
{"llmqType", RPCArg::Type::NUM, RPCArg::Optional::NO, "LLMQ type."}, {"llmqType", RPCArg::Type::NUM, RPCArg::Optional::NO, "LLMQ type."},
@ -618,9 +619,9 @@ static UniValue quorum_sigs_cmd(const JSONRPCRequest& request, const LLMQContext
} }
} }
static void quorum_selectquorum_help(const JSONRPCRequest& request) static RPCHelpMan quorum_selectquorum()
{ {
RPCHelpMan{"quorum selectquorum", return RPCHelpMan{"quorum selectquorum",
"Returns the quorum that would/should sign a request\n", "Returns the quorum that would/should sign a request\n",
{ {
{"llmqType", RPCArg::Type::NUM, RPCArg::Optional::NO, "LLMQ type."}, {"llmqType", RPCArg::Type::NUM, RPCArg::Optional::NO, "LLMQ type."},
@ -628,12 +629,10 @@ static void quorum_selectquorum_help(const JSONRPCRequest& request)
}, },
RPCResults{}, RPCResults{},
RPCExamples{""}, RPCExamples{""},
}.Check(request); [&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue
}
static UniValue quorum_selectquorum(const JSONRPCRequest& request, const LLMQContext& llmq_ctx)
{ {
quorum_selectquorum_help(request); const NodeContext& node = EnsureAnyNodeContext(request.context);
const LLMQContext& llmq_ctx = EnsureLLMQContext(node);
Consensus::LLMQType llmqType = (Consensus::LLMQType)ParseInt32V(request.params[0], "llmqType"); Consensus::LLMQType llmqType = (Consensus::LLMQType)ParseInt32V(request.params[0], "llmqType");
const auto& llmq_params_opt = Params().GetLLMQ(llmqType); const auto& llmq_params_opt = Params().GetLLMQ(llmqType);
@ -659,11 +658,13 @@ static UniValue quorum_selectquorum(const JSONRPCRequest& request, const LLMQCon
ret.pushKV("recoveryMembers", recoveryMembers); ret.pushKV("recoveryMembers", recoveryMembers);
return ret; return ret;
},
};
} }
static void quorum_dkgsimerror_help(const JSONRPCRequest& request) static RPCHelpMan quorum_dkgsimerror()
{ {
RPCHelpMan{"quorum dkgsimerror", return RPCHelpMan{"quorum dkgsimerror",
"This enables simulation of errors and malicious behaviour in the DKG. Do NOT use this on mainnet\n" "This enables simulation of errors and malicious behaviour in the DKG. Do NOT use this on mainnet\n"
"as you will get yourself very likely PoSe banned for this.\n", "as you will get yourself very likely PoSe banned for this.\n",
{ {
@ -672,13 +673,8 @@ static void quorum_dkgsimerror_help(const JSONRPCRequest& request)
}, },
RPCResults{}, RPCResults{},
RPCExamples{""}, RPCExamples{""},
}.Check(request); [&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue
}
static UniValue quorum_dkgsimerror(const JSONRPCRequest& request)
{ {
quorum_dkgsimerror_help(request);
std::string type_str = request.params[0].get_str(); std::string type_str = request.params[0].get_str();
double rate = ParseDoubleV(request.params[1], "rate"); double rate = ParseDoubleV(request.params[1], "rate");
@ -693,11 +689,13 @@ static UniValue quorum_dkgsimerror(const JSONRPCRequest& request)
llmq::SetSimulatedDKGErrorRate(type, rate); llmq::SetSimulatedDKGErrorRate(type, rate);
return UniValue(); return UniValue();
} }
},
};
} }
static void quorum_getdata_help(const JSONRPCRequest& request) static RPCHelpMan quorum_getdata()
{ {
RPCHelpMan{"quorum getdata", return RPCHelpMan{"quorum getdata",
"Send a QGETDATA message to the specified peer.\n", "Send a QGETDATA message to the specified peer.\n",
{ {
{"nodeId", RPCArg::Type::NUM, RPCArg::Optional::NO, "The internal nodeId of the peer to request quorum data from."}, {"nodeId", RPCArg::Type::NUM, RPCArg::Optional::NO, "The internal nodeId of the peer to request quorum data from."},
@ -712,12 +710,11 @@ static void quorum_getdata_help(const JSONRPCRequest& request)
}, },
RPCResults{}, RPCResults{},
RPCExamples{""}, RPCExamples{""},
}.Check(request); [&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue
}
static UniValue quorum_getdata(const JSONRPCRequest& request, const LLMQContext& llmq_ctx, const ChainstateManager& chainman)
{ {
quorum_getdata_help(request); const NodeContext& node = EnsureAnyNodeContext(request.context);
const ChainstateManager& chainman = EnsureChainman(node);
const LLMQContext& llmq_ctx = EnsureLLMQContext(node);
NodeId nodeId = ParseInt64V(request.params[0], "nodeId"); NodeId nodeId = ParseInt64V(request.params[0], "nodeId");
Consensus::LLMQType llmqType = static_cast<Consensus::LLMQType>(ParseInt32V(request.params[1], "llmqType")); Consensus::LLMQType llmqType = static_cast<Consensus::LLMQType>(ParseInt32V(request.params[1], "llmqType"));
@ -739,15 +736,16 @@ static UniValue quorum_getdata(const JSONRPCRequest& request, const LLMQContext&
const CBlockIndex* pQuorumBaseBlockIndex = WITH_LOCK(cs_main, return chainman.m_blockman.LookupBlockIndex(quorumHash)); const CBlockIndex* pQuorumBaseBlockIndex = WITH_LOCK(cs_main, return chainman.m_blockman.LookupBlockIndex(quorumHash));
const NodeContext& node = EnsureAnyNodeContext(request.context);
return node.connman->ForNode(nodeId, [&](CNode* pNode) { return node.connman->ForNode(nodeId, [&](CNode* pNode) {
return llmq_ctx.qman->RequestQuorumData(pNode, llmqType, pQuorumBaseBlockIndex, nDataMask, proTxHash); return llmq_ctx.qman->RequestQuorumData(pNode, llmqType, pQuorumBaseBlockIndex, nDataMask, proTxHash);
}); });
},
};
} }
static void quorum_rotationinfo_help(const JSONRPCRequest& request) static RPCHelpMan quorum_rotationinfo()
{ {
RPCHelpMan{ return RPCHelpMan{
"quorum rotationinfo", "quorum rotationinfo",
"Get quorum rotation information\n", "Get quorum rotation information\n",
{ {
@ -757,12 +755,10 @@ static void quorum_rotationinfo_help(const JSONRPCRequest& request)
}, },
RPCResults{}, RPCResults{},
RPCExamples{""}, RPCExamples{""},
}.Check(request); [&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue
}
static UniValue quorum_rotationinfo(const JSONRPCRequest& request, CDeterministicMNManager& dmnman, const LLMQContext& llmq_ctx)
{ {
quorum_rotationinfo_help(request); const NodeContext& node = EnsureAnyNodeContext(request.context);
const LLMQContext& llmq_ctx = EnsureLLMQContext(node);
llmq::CGetQuorumRotationInfo cmd; llmq::CGetQuorumRotationInfo cmd;
llmq::CQuorumRotationInfo quorumRotationInfoRet; llmq::CQuorumRotationInfo quorumRotationInfoRet;
@ -779,16 +775,18 @@ static UniValue quorum_rotationinfo(const JSONRPCRequest& request, CDeterministi
LOCK(cs_main); LOCK(cs_main);
if (!BuildQuorumRotationInfo(cmd, quorumRotationInfoRet, dmnman, *llmq_ctx.qman, *llmq_ctx.quorum_block_processor, strError)) { if (!BuildQuorumRotationInfo(cmd, quorumRotationInfoRet, *node.dmnman, *llmq_ctx.qman, *llmq_ctx.quorum_block_processor, strError)) {
throw JSONRPCError(RPC_INVALID_REQUEST, strError); throw JSONRPCError(RPC_INVALID_REQUEST, strError);
} }
return quorumRotationInfoRet.ToJson(); return quorumRotationInfoRet.ToJson();
},
};
} }
static void quorum_dkginfo_help(const JSONRPCRequest& request) static RPCHelpMan quorum_dkginfo()
{ {
RPCHelpMan{ return RPCHelpMan{
"quorum dkginfo", "quorum dkginfo",
"Return information regarding DKGs.\n", "Return information regarding DKGs.\n",
{ {
@ -802,12 +800,11 @@ static void quorum_dkginfo_help(const JSONRPCRequest& request)
} }
}, },
RPCExamples{""}, RPCExamples{""},
}.Check(request); [&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue
}
static UniValue quorum_dkginfo(const JSONRPCRequest& request, const LLMQContext& llmq_ctx, const ChainstateManager& chainman)
{ {
quorum_dkginfo_help(request); const NodeContext& node = EnsureAnyNodeContext(request.context);
const ChainstateManager& chainman = EnsureChainman(node);
const LLMQContext& llmq_ctx = EnsureLLMQContext(node);
llmq::CDKGDebugStatus status; llmq::CDKGDebugStatus status;
llmq_ctx.dkg_debugman->GetLocalDebugStatus(status); llmq_ctx.dkg_debugman->GetLocalDebugStatus(status);
@ -828,12 +825,13 @@ static UniValue quorum_dkginfo(const JSONRPCRequest& request, const LLMQContext&
ret.pushKV("next_dkg", minNextDKG(Params().GetConsensus(), nTipHeight)); ret.pushKV("next_dkg", minNextDKG(Params().GetConsensus(), nTipHeight));
return ret; return ret;
},
};
} }
[[ noreturn ]] static void quorum_help() static RPCHelpMan quorum_help()
{ {
throw std::runtime_error( return RPCHelpMan{
RPCHelpMan{
"quorum", "quorum",
"Set of commands for quorums/LLMQs.\n" "Set of commands for quorums/LLMQs.\n"
"To get help on individual commands, use \"help quorum command\".\n" "To get help on individual commands, use \"help quorum command\".\n"
@ -858,49 +856,16 @@ static UniValue quorum_dkginfo(const JSONRPCRequest& request, const LLMQContext&
}, },
RPCResults{}, RPCResults{},
RPCExamples{""}, RPCExamples{""},
} [&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue
.ToString()); {
throw JSONRPCError(RPC_INVALID_PARAMETER, "Must be a valid command");
},
};
} }
static UniValue _quorum(const JSONRPCRequest& request) static RPCHelpMan verifychainlock()
{ {
const JSONRPCRequest new_request{request.strMethod == "quorum" ? request.squashed() : request}; return RPCHelpMan{"verifychainlock",
const std::string command{new_request.strMethod};
const NodeContext& node = EnsureAnyNodeContext(request.context);
const ChainstateManager& chainman = EnsureChainman(node);
const LLMQContext& llmq_ctx = EnsureLLMQContext(node);
if (command == "quorumlist") {
return quorum_list(new_request, chainman, llmq_ctx);
} else if (command == "quorumlistextended") {
return quorum_list_extended(new_request, chainman, llmq_ctx);
} else if (command == "quoruminfo") {
return quorum_info(new_request, llmq_ctx);
} else if (command == "quorumdkginfo") {
return quorum_dkginfo(new_request, llmq_ctx, chainman);
} else if (command == "quorumdkgstatus") {
return quorum_dkgstatus(new_request, *node.dmnman, node.mn_activeman.get(), chainman, *node.sporkman, llmq_ctx);
} else if (command == "quorummemberof") {
return quorum_memberof(new_request, chainman, node, llmq_ctx);
} else if (command == "quorumsign" || command == "quorumverify" || command == "quorumhasrecsig" || command == "quorumgetrecsig" || command == "quorumisconflicting") {
return quorum_sigs_cmd(new_request, llmq_ctx);
} else if (command == "quorumselectquorum") {
return quorum_selectquorum(new_request, llmq_ctx);
} else if (command == "quorumdkgsimerror") {
return quorum_dkgsimerror(new_request);
} else if (command == "quorumgetdata") {
return quorum_getdata(new_request, llmq_ctx, chainman);
} else if (command == "quorumrotationinfo") {
return quorum_rotationinfo(new_request, *node.dmnman, llmq_ctx);
} else {
quorum_help();
}
}
static void verifychainlock_help(const JSONRPCRequest& request)
{
RPCHelpMan{"verifychainlock",
"Test if a quorum signature is valid for a ChainLock.\n", "Test if a quorum signature is valid for a ChainLock.\n",
{ {
{"blockHash", RPCArg::Type::STR_HEX, RPCArg::Optional::NO, "The block hash of the ChainLock."}, {"blockHash", RPCArg::Type::STR_HEX, RPCArg::Optional::NO, "The block hash of the ChainLock."},
@ -909,13 +874,8 @@ static void verifychainlock_help(const JSONRPCRequest& request)
}, },
RPCResults{}, RPCResults{},
RPCExamples{""}, RPCExamples{""},
}.Check(request); [&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue
}
static UniValue verifychainlock(const JSONRPCRequest& request)
{ {
verifychainlock_help(request);
const uint256 nBlockHash(ParseHashV(request.params[0], "blockHash")); const uint256 nBlockHash(ParseHashV(request.params[0], "blockHash"));
const NodeContext& node = EnsureAnyNodeContext(request.context); const NodeContext& node = EnsureAnyNodeContext(request.context);
@ -956,11 +916,13 @@ static UniValue verifychainlock(const JSONRPCRequest& request)
const LLMQContext& llmq_ctx = EnsureLLMQContext(node); const LLMQContext& llmq_ctx = EnsureLLMQContext(node);
return llmq_ctx.clhandler->VerifyChainLock(llmq::CChainLockSig(nBlockHeight, nBlockHash, sig)); return llmq_ctx.clhandler->VerifyChainLock(llmq::CChainLockSig(nBlockHeight, nBlockHash, sig));
},
};
} }
static void verifyislock_help(const JSONRPCRequest& request) static RPCHelpMan verifyislock()
{ {
RPCHelpMan{"verifyislock", return RPCHelpMan{"verifyislock",
"Test if a quorum signature is valid for an InstantSend Lock\n", "Test if a quorum signature is valid for an InstantSend Lock\n",
{ {
{"id", RPCArg::Type::STR_HEX, RPCArg::Optional::NO, "Request id."}, {"id", RPCArg::Type::STR_HEX, RPCArg::Optional::NO, "Request id."},
@ -970,13 +932,8 @@ static void verifyislock_help(const JSONRPCRequest& request)
}, },
RPCResults{}, RPCResults{},
RPCExamples{""}, RPCExamples{""},
}.Check(request); [&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue
}
static UniValue verifyislock(const JSONRPCRequest& request)
{ {
verifyislock_help(request);
uint256 id(ParseHashV(request.params[0], "id")); uint256 id(ParseHashV(request.params[0], "id"));
uint256 txid(ParseHashV(request.params[1], "txid")); uint256 txid(ParseHashV(request.params[1], "txid"));
@ -1036,11 +993,13 @@ static UniValue verifyislock(const JSONRPCRequest& request)
int signOffset{llmq_params_opt->dkgInterval}; int signOffset{llmq_params_opt->dkgInterval};
return llmq::VerifyRecoveredSig(llmqType, *llmq_ctx.qman, signHeight, id, txid, sig, 0) || return llmq::VerifyRecoveredSig(llmqType, *llmq_ctx.qman, signHeight, id, txid, sig, 0) ||
llmq::VerifyRecoveredSig(llmqType, *llmq_ctx.qman, signHeight, id, txid, sig, signOffset); llmq::VerifyRecoveredSig(llmqType, *llmq_ctx.qman, signHeight, id, txid, sig, signOffset);
},
};
} }
static void submitchainlock_help(const JSONRPCRequest& request) static RPCHelpMan submitchainlock()
{ {
RPCHelpMan{"submitchainlock", return RPCHelpMan{"submitchainlock",
"Submit a ChainLock signature if needed\n", "Submit a ChainLock signature if needed\n",
{ {
{"blockHash", RPCArg::Type::STR_HEX, RPCArg::Optional::NO, "The block hash of the ChainLock."}, {"blockHash", RPCArg::Type::STR_HEX, RPCArg::Optional::NO, "The block hash of the ChainLock."},
@ -1050,13 +1009,8 @@ static void submitchainlock_help(const JSONRPCRequest& request)
RPCResult{ RPCResult{
RPCResult::Type::NUM, "", "The height of the current best ChainLock"}, RPCResult::Type::NUM, "", "The height of the current best ChainLock"},
RPCExamples{""}, RPCExamples{""},
}.Check(request); [&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue
}
static UniValue submitchainlock(const JSONRPCRequest& request)
{ {
submitchainlock_help(request);
const uint256 nBlockHash(ParseHashV(request.params[0], "blockHash")); const uint256 nBlockHash(ParseHashV(request.params[0], "blockHash"));
const int nBlockHeight = ParseInt32V(request.params[2], "blockHeight"); const int nBlockHeight = ParseInt32V(request.params[2], "blockHeight");
@ -1080,6 +1034,8 @@ static UniValue submitchainlock(const JSONRPCRequest& request)
llmq_ctx.clhandler->ProcessNewChainLock(-1, clsig, ::SerializeHash(clsig)); llmq_ctx.clhandler->ProcessNewChainLock(-1, clsig, ::SerializeHash(clsig));
return llmq_ctx.clhandler->GetBestChainLock().getHeight(); return llmq_ctx.clhandler->GetBestChainLock().getHeight();
},
};
} }
@ -1089,13 +1045,28 @@ void RegisterQuorumsRPCCommands(CRPCTable &tableRPC)
static const CRPCCommand commands[] = static const CRPCCommand commands[] =
{ // category name actor (function) { // category name actor (function)
// --------------------- ------------------------ ----------------------- // --------------------- ------------------------ -----------------------
{ "evo", "quorum", &_quorum, {} }, { "evo", "quorum", &quorum_help, {"command"} },
{ "evo", "quorum", "list", &quorum_list, {"count"} },
{ "evo", "quorum", "listextended", &quorum_list_extended, {"height"} },
{ "evo", "quorum", "info", &quorum_info, {"llmqType", "quorumHash", "includeSkShare"} },
{ "evo", "quorum", "dkginfo", &quorum_dkginfo, {} },
{ "evo", "quorum", "dkgstatus", &quorum_dkgstatus, {"detail_level"} },
{ "evo", "quorum", "memberof", &quorum_memberof, {"proTxHash", "scanQuorumsCount"} },
{ "evo", "quorum", "sign", &quorum_sign, {"llmqType", "id", "msgHash", "quorumHash", "submit"} },
{ "evo", "quorum", "verify", &quorum_verify, {"llmqType", "id", "msgHash", "signature", "quorumHash", "signHeight"} },
{ "evo", "quorum", "hasrecsig", &quorum_hasrecsig, {"llmqType", "id", "msgHash"} },
{ "evo", "quorum", "getrecsig", &quorum_getrecsig, {"llmqType", "id", "msgHash"} },
{ "evo", "quorum", "isconflicting",&quorum_isconflicting, {"llmqType", "id", "msgHash"} },
{ "evo", "quorum", "selectquorum", &quorum_selectquorum, {"llmqType", "id"} },
{ "evo", "quorum", "dkgsimerror", &quorum_dkgsimerror, {"type", "rate"} },
{ "evo", "quorum", "getdata", &quorum_getdata, {"nodeId", "llmqType", "quorumHash", "dataMask", "proTxHash"} },
{ "evo", "quorum", "rotationinfo", &quorum_rotationinfo, {"blockRequestHash", "extraShare", "baseBlockHash..."} },
{ "evo", "submitchainlock", &submitchainlock, {"blockHash", "signature", "blockHeight"} }, { "evo", "submitchainlock", &submitchainlock, {"blockHash", "signature", "blockHeight"} },
{ "evo", "verifychainlock", &verifychainlock, {"blockHash", "signature", "blockHeight"} }, { "evo", "verifychainlock", &verifychainlock, {"blockHash", "signature", "blockHeight"} },
{ "evo", "verifyislock", &verifyislock, {"id", "txid", "signature", "maxHeight"} }, { "evo", "verifyislock", &verifyislock, {"id", "txid", "signature", "maxHeight"} },
}; };
// clang-format on // clang-format on
for (const auto& command : commands) { for (const auto& command : commands) {
tableRPC.appendCommand(command.name, &command); tableRPC.appendCommand(command.name, command.subname, &command);
} }
} }