From 2af9d866542b846daa60ab44987442cd24c71763 Mon Sep 17 00:00:00 2001 From: Konstantin Akimov Date: Tue, 11 Jun 2024 15:33:22 +0700 Subject: [PATCH 1/4] refactor: use new approach for rpc quorums NNN --- src/rpc/quorums.cpp | 289 ++++++++++++++++++++------------------------ 1 file changed, 130 insertions(+), 159 deletions(-) diff --git a/src/rpc/quorums.cpp b/src/rpc/quorums.cpp index 020e16bb78..0df442ce86 100644 --- a/src/rpc/quorums.cpp +++ b/src/rpc/quorums.cpp @@ -34,9 +34,9 @@ namespace llmq { 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", { {"count", RPCArg::Type::NUM, /* default */ "", @@ -57,12 +57,11 @@ static void quorum_list_help(const JSONRPCRequest& request) + HelpExampleCli("quorum", "list 10") + HelpExampleRpc("quorum", "list, 10") }, - }.Check(request); -} - -static UniValue quorum_list(const JSONRPCRequest& request, const ChainstateManager& chainman, const LLMQContext& llmq_ctx) + [&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue { - quorum_list_help(request); + const NodeContext& node = EnsureAnyNodeContext(request.context); + const ChainstateManager& chainman = EnsureChainman(node); + const LLMQContext& llmq_ctx = EnsureLLMQContext(node); int count = -1; if (!request.params[0].isNull()) { @@ -90,11 +89,13 @@ static UniValue quorum_list(const JSONRPCRequest& request, const ChainstateManag } 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", { {"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") + HelpExampleRpc("quorum", "listextended, 2500") }, - }.Check(request); -} - -static UniValue quorum_list_extended(const JSONRPCRequest& request, const ChainstateManager& chainman, const LLMQContext& llmq_ctx) + [&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue { - 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; if (!request.params[0].isNull()) { @@ -172,20 +172,8 @@ static UniValue quorum_list_extended(const JSONRPCRequest& request, const Chains } 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) @@ -237,9 +225,21 @@ static UniValue BuildQuorumInfo(const llmq::CQuorumBlockProcessor& quorum_block_ 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"); 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); +}, + }; } -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" "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{}, RPCExamples{""}, - }.Check(request); -} - -static UniValue quorum_dkgstatus(const JSONRPCRequest& request, CDeterministicMNManager& dmnman, const CActiveMasternodeManager* const mn_activeman, - const ChainstateManager& chainman, const CSporkManager& sporkman, const LLMQContext& llmq_ctx) + [&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue { - quorum_dkgstatus_help(request); + const NodeContext& node = EnsureAnyNodeContext(request.context); + const ChainstateManager& chainman = EnsureChainman(node); + const LLMQContext& llmq_ctx = EnsureLLMQContext(node); int detailLevel = 0; if (!request.params[0].isNull()) { @@ -291,12 +291,11 @@ static UniValue quorum_dkgstatus(const JSONRPCRequest& request, CDeterministicMN llmq::CDKGDebugStatus 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()); int tipHeight = pindexTip->nHeight; - - const uint256 proTxHash = mn_activeman ? mn_activeman->GetProTxHash() : uint256(); + const uint256 proTxHash = node.mn_activeman ? node.mn_activeman->GetProTxHash() : uint256(); UniValue minableCommitments(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("quorumIndex", quorumIndex); - if (mn_activeman) { + if (node.mn_activeman) { int quorumHeight = tipHeight - (tipHeight % llmq_params.dkgInterval) + quorumIndex; if (quorumHeight <= tipHeight) { 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("pindexTip", pindexTip->nHeight); - auto allConnections = llmq::utils::GetQuorumConnections(llmq_params, dmnman, sporkman, pQuorumBaseBlockIndex, proTxHash, false); - auto outboundConnections = llmq::utils::GetQuorumConnections(llmq_params, dmnman, sporkman, pQuorumBaseBlockIndex, proTxHash, true); + auto allConnections = llmq::utils::GetQuorumConnections(llmq_params, *node.dmnman, *node.sporkman, pQuorumBaseBlockIndex, proTxHash, false); + auto outboundConnections = llmq::utils::GetQuorumConnections(llmq_params, *node.dmnman, *node.sporkman, pQuorumBaseBlockIndex, proTxHash, true); std::map foundConnections; - const NodeContext& node = EnsureAnyNodeContext(request.context); node.connman->ForEachNode([&](const CNode* pnode) { auto verifiedProRegTxHash = pnode->GetVerifiedProRegTxHash(); if (!verifiedProRegTxHash.IsNull() && allConnections.count(verifiedProRegTxHash)) { @@ -360,11 +358,13 @@ static UniValue quorum_dkgstatus(const JSONRPCRequest& request, CDeterministicMN ret.pushKV("quorumConnections", quorumArrConnections); ret.pushKV("minableCommitments", minableCommitments); 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", { {"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{}, RPCExamples{""}, - }.Check(request); -} - -static UniValue quorum_memberof(const JSONRPCRequest& request, const ChainstateManager& chainman, const NodeContext& node, const LLMQContext& llmq_ctx) + [&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue { - 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")); int scanQuorumsCount = -1; @@ -419,11 +418,13 @@ static UniValue quorum_memberof(const JSONRPCRequest& request, const ChainstateM } 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", { {"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", { {"llmqType", RPCArg::Type::NUM, RPCArg::Optional::NO, "LLMQ type."}, @@ -628,12 +629,10 @@ static void quorum_selectquorum_help(const JSONRPCRequest& request) }, RPCResults{}, RPCExamples{""}, - }.Check(request); -} - -static UniValue quorum_selectquorum(const JSONRPCRequest& request, const LLMQContext& llmq_ctx) + [&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue { - 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"); 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); 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" "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{}, RPCExamples{""}, - }.Check(request); -} - -static UniValue quorum_dkgsimerror(const JSONRPCRequest& request) + [&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue { - quorum_dkgsimerror_help(request); - std::string type_str = request.params[0].get_str(); double rate = ParseDoubleV(request.params[1], "rate"); @@ -693,11 +689,13 @@ static UniValue quorum_dkgsimerror(const JSONRPCRequest& request) llmq::SetSimulatedDKGErrorRate(type, rate); 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", { {"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{}, RPCExamples{""}, - }.Check(request); -} - -static UniValue quorum_getdata(const JSONRPCRequest& request, const LLMQContext& llmq_ctx, const ChainstateManager& chainman) + [&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue { - 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"); Consensus::LLMQType llmqType = static_cast(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 NodeContext& node = EnsureAnyNodeContext(request.context); return node.connman->ForNode(nodeId, [&](CNode* pNode) { 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", "Get quorum rotation information\n", { @@ -757,12 +755,10 @@ static void quorum_rotationinfo_help(const JSONRPCRequest& request) }, RPCResults{}, RPCExamples{""}, - }.Check(request); -} - -static UniValue quorum_rotationinfo(const JSONRPCRequest& request, CDeterministicMNManager& dmnman, const LLMQContext& llmq_ctx) + [&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue { - quorum_rotationinfo_help(request); + const NodeContext& node = EnsureAnyNodeContext(request.context); + const LLMQContext& llmq_ctx = EnsureLLMQContext(node); llmq::CGetQuorumRotationInfo cmd; llmq::CQuorumRotationInfo quorumRotationInfoRet; @@ -779,16 +775,18 @@ static UniValue quorum_rotationinfo(const JSONRPCRequest& request, CDeterministi 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); } return quorumRotationInfoRet.ToJson(); +}, + }; } -static void quorum_dkginfo_help(const JSONRPCRequest& request) +static RPCHelpMan quorum_dkginfo() { - RPCHelpMan{ + return RPCHelpMan{ "quorum dkginfo", "Return information regarding DKGs.\n", { @@ -802,12 +800,11 @@ static void quorum_dkginfo_help(const JSONRPCRequest& request) } }, RPCExamples{""}, - }.Check(request); -} - -static UniValue quorum_dkginfo(const JSONRPCRequest& request, const LLMQContext& llmq_ctx, const ChainstateManager& chainman) + [&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue { - 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_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)); return ret; +}, + }; } -[[ noreturn ]] static void quorum_help() +static RPCHelpMan quorum_help() { - throw std::runtime_error( - RPCHelpMan{ + return RPCHelpMan{ "quorum", "Set of commands for quorums/LLMQs.\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{}, RPCExamples{""}, - } - .ToString()); + [&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue +{ + 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}; - 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", + return RPCHelpMan{"verifychainlock", "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."}, @@ -909,13 +874,8 @@ static void verifychainlock_help(const JSONRPCRequest& request) }, RPCResults{}, RPCExamples{""}, - }.Check(request); -} - -static UniValue verifychainlock(const JSONRPCRequest& request) + [&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue { - verifychainlock_help(request); - const uint256 nBlockHash(ParseHashV(request.params[0], "blockHash")); const NodeContext& node = EnsureAnyNodeContext(request.context); @@ -956,11 +916,13 @@ static UniValue verifychainlock(const JSONRPCRequest& request) const LLMQContext& llmq_ctx = EnsureLLMQContext(node); 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", { {"id", RPCArg::Type::STR_HEX, RPCArg::Optional::NO, "Request id."}, @@ -970,13 +932,8 @@ static void verifyislock_help(const JSONRPCRequest& request) }, RPCResults{}, RPCExamples{""}, - }.Check(request); -} - -static UniValue verifyislock(const JSONRPCRequest& request) + [&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue { - verifyislock_help(request); - uint256 id(ParseHashV(request.params[0], "id")); uint256 txid(ParseHashV(request.params[1], "txid")); @@ -1036,11 +993,13 @@ static UniValue verifyislock(const JSONRPCRequest& request) int signOffset{llmq_params_opt->dkgInterval}; return llmq::VerifyRecoveredSig(llmqType, *llmq_ctx.qman, signHeight, id, txid, sig, 0) || 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", { {"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::Type::NUM, "", "The height of the current best ChainLock"}, RPCExamples{""}, - }.Check(request); -} - -static UniValue submitchainlock(const JSONRPCRequest& request) + [&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue { - submitchainlock_help(request); - const uint256 nBlockHash(ParseHashV(request.params[0], "blockHash")); 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)); return llmq_ctx.clhandler->GetBestChainLock().getHeight(); +}, + }; } @@ -1089,13 +1045,28 @@ void RegisterQuorumsRPCCommands(CRPCTable &tableRPC) static const CRPCCommand commands[] = { // 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", "verifychainlock", &verifychainlock, {"blockHash", "signature", "blockHeight"} }, { "evo", "verifyislock", &verifyislock, {"id", "txid", "signature", "maxHeight"} }, }; // clang-format on for (const auto& command : commands) { - tableRPC.appendCommand(command.name, &command); + tableRPC.appendCommand(command.name, command.subname, &command); } } From e3c4d66ef355a7c8352e0e38c330067da7da974f Mon Sep 17 00:00:00 2001 From: Konstantin Akimov Date: Tue, 11 Jun 2024 20:26:08 +0700 Subject: [PATCH 2/4] refactor: quorum sign methods They are separated to own commit because the code move is not trivial to review --- src/rpc/quorums.cpp | 339 ++++++++++++++++++++++++-------------------- 1 file changed, 189 insertions(+), 150 deletions(-) diff --git a/src/rpc/quorums.cpp b/src/rpc/quorums.cpp index 0df442ce86..6a7a8dae8b 100644 --- a/src/rpc/quorums.cpp +++ b/src/rpc/quorums.cpp @@ -436,12 +436,68 @@ static RPCHelpMan quorum_sign() }, RPCResults{}, RPCExamples{""}, - }.Check(request); + [&](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"); + + const auto& llmq_params_opt = Params().GetLLMQ(llmqType); + if (!llmq_params_opt.has_value()) { + throw JSONRPCError(RPC_INVALID_PARAMETER, "invalid LLMQ type"); + } + + uint256 id(ParseHashV(request.params[1], "id")); + uint256 msgHash(ParseHashV(request.params[2], "msgHash")); + + uint256 quorumHash; + if (!request.params[3].isNull() && !request.params[3].get_str().empty()) { + quorumHash = ParseHashV(request.params[3], "quorumHash"); + } + bool fSubmit{true}; + if (!request.params[4].isNull()) { + fSubmit = ParseBoolV(request.params[4], "submit"); + } + if (fSubmit) { + return llmq_ctx.sigman->AsyncSignIfMember(llmqType, *llmq_ctx.shareman, id, msgHash, quorumHash); + } else { + llmq::CQuorumCPtr pQuorum; + + if (quorumHash.IsNull()) { + pQuorum = llmq::SelectQuorumForSigning(llmq_params_opt.value(), *llmq_ctx.qman, id); + } else { + pQuorum = llmq_ctx.qman->GetQuorum(llmqType, quorumHash); + } + + if (pQuorum == nullptr) { + throw JSONRPCError(RPC_INVALID_PARAMETER, "quorum not found"); + } + + auto sigShare = llmq_ctx.shareman->CreateSigShare(pQuorum, id, msgHash); + + if (!sigShare.has_value() || !sigShare->sigShare.Get().IsValid()) { + throw JSONRPCError(RPC_INVALID_PARAMETER, "failed to create sigShare"); + } + + UniValue obj(UniValue::VOBJ); + obj.pushKV("llmqType", static_cast(llmqType)); + obj.pushKV("quorumHash", sigShare->getQuorumHash().ToString()); + obj.pushKV("quorumMember", sigShare->getQuorumMember()); + obj.pushKV("id", id.ToString()); + obj.pushKV("msgHash", msgHash.ToString()); + obj.pushKV("signHash", sigShare->GetSignHash().ToString()); + obj.pushKV("signature", sigShare->sigShare.Get().ToString()); + + return obj; + } +}, + }; } -static void quorum_verify_help(const JSONRPCRequest& request) +static RPCHelpMan quorum_verify() { - RPCHelpMan{"quorum verify", + return RPCHelpMan{"quorum verify", "Test if a quorum signature is valid for a request id and a message hash\n", { {"llmqType", RPCArg::Type::NUM, RPCArg::Optional::NO, "LLMQ type."}, @@ -457,70 +513,10 @@ static void quorum_verify_help(const JSONRPCRequest& request) }, RPCResults{}, RPCExamples{""}, - }.Check(request); -} - -static void quorum_hasrecsig_help(const JSONRPCRequest& request) + [&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue { - RPCHelpMan{"quorum hasrecsig", - "Test if a valid recovered signature is present\n", - { - {"llmqType", RPCArg::Type::NUM, RPCArg::Optional::NO, "LLMQ type."}, - {"id", RPCArg::Type::STR_HEX, RPCArg::Optional::NO, "Request id."}, - {"msgHash", RPCArg::Type::STR_HEX, RPCArg::Optional::NO, "Message hash."}, - }, - RPCResults{}, - RPCExamples{""}, - }.Check(request); -} - -static void quorum_getrecsig_help(const JSONRPCRequest& request) -{ - RPCHelpMan{"quorum getrecsig", - "Get a recovered signature\n", - { - {"llmqType", RPCArg::Type::NUM, RPCArg::Optional::NO, "LLMQ type."}, - {"id", RPCArg::Type::STR_HEX, RPCArg::Optional::NO, "Request id."}, - {"msgHash", RPCArg::Type::STR_HEX, RPCArg::Optional::NO, "Message hash."}, - }, - RPCResults{}, - RPCExamples{""}, - }.Check(request); -} - -static void quorum_isconflicting_help(const JSONRPCRequest& request) -{ - RPCHelpMan{"quorum isconflicting", - "Test if a conflict exists\n", - { - {"llmqType", RPCArg::Type::NUM, RPCArg::Optional::NO, "LLMQ type."}, - {"id", RPCArg::Type::STR_HEX, RPCArg::Optional::NO, "Request id."}, - {"msgHash", RPCArg::Type::STR_HEX, RPCArg::Optional::NO, "Message hash."}, - }, - RPCResults{}, - RPCExamples{""}, - }.Check(request); -} - -static UniValue quorum_sigs_cmd(const JSONRPCRequest& request, const LLMQContext& llmq_ctx) -{ - auto cmd = request.strMethod; - if (request.fHelp || (request.params.size() != 3)) { - if (cmd == "quorumsign") { - quorum_sign_help(request); - } else if (cmd == "quorumverify") { - quorum_verify_help(request); - } else if (cmd == "quorumhasrecsig") { - quorum_hasrecsig_help(request); - } else if (cmd == "quorumgetrecsig") { - quorum_getrecsig_help(request); - } else if (cmd == "quorumisconflicting") { - quorum_isconflicting_help(request); - } else { - // shouldn't happen as it's already handled by the caller - throw JSONRPCError(RPC_INVALID_PARAMETER, "invalid cmd"); - } - } + const NodeContext& node = EnsureAnyNodeContext(request.context); + const LLMQContext& llmq_ctx = EnsureLLMQContext(node); Consensus::LLMQType llmqType = (Consensus::LLMQType)ParseInt32V(request.params[0], "llmqType"); @@ -532,91 +528,134 @@ static UniValue quorum_sigs_cmd(const JSONRPCRequest& request, const LLMQContext uint256 id(ParseHashV(request.params[1], "id")); uint256 msgHash(ParseHashV(request.params[2], "msgHash")); - if (cmd == "quorumsign") { - uint256 quorumHash; - if (!request.params[3].isNull() && !request.params[3].get_str().empty()) { - quorumHash = ParseHashV(request.params[3], "quorumHash"); - } - bool fSubmit{true}; - if (!request.params[4].isNull()) { - fSubmit = ParseBoolV(request.params[4], "submit"); - } - if (fSubmit) { - return llmq_ctx.sigman->AsyncSignIfMember(llmqType, *llmq_ctx.shareman, id, msgHash, quorumHash); - } else { - llmq::CQuorumCPtr pQuorum; - - if (quorumHash.IsNull()) { - pQuorum = llmq::SelectQuorumForSigning(llmq_params_opt.value(), *llmq_ctx.qman, id); - } else { - pQuorum = llmq_ctx.qman->GetQuorum(llmqType, quorumHash); - } - - if (pQuorum == nullptr) { - throw JSONRPCError(RPC_INVALID_PARAMETER, "quorum not found"); - } - - auto sigShare = llmq_ctx.shareman->CreateSigShare(pQuorum, id, msgHash); - - if (!sigShare.has_value() || !sigShare->sigShare.Get().IsValid()) { - throw JSONRPCError(RPC_INVALID_PARAMETER, "failed to create sigShare"); - } - - UniValue obj(UniValue::VOBJ); - obj.pushKV("llmqType", static_cast(llmqType)); - obj.pushKV("quorumHash", sigShare->getQuorumHash().ToString()); - obj.pushKV("quorumMember", sigShare->getQuorumMember()); - obj.pushKV("id", id.ToString()); - obj.pushKV("msgHash", msgHash.ToString()); - obj.pushKV("signHash", sigShare->GetSignHash().ToString()); - obj.pushKV("signature", sigShare->sigShare.Get().ToString()); - - return obj; - } - } else if (cmd == "quorumverify") { - const bool use_bls_legacy = bls::bls_legacy_scheme.load(); - CBLSSignature sig; - if (!sig.SetHexStr(request.params[3].get_str(), use_bls_legacy)) { - throw JSONRPCError(RPC_INVALID_PARAMETER, "invalid signature format"); - } - - if (request.params[4].isNull() || (request.params[4].get_str().empty() && !request.params[5].isNull())) { - int signHeight{-1}; - if (!request.params[5].isNull()) { - signHeight = ParseInt32V(request.params[5], "signHeight"); - } - // First check against the current active set, if it fails check against the last active set - int signOffset{llmq_params_opt->dkgInterval}; - return llmq::VerifyRecoveredSig(llmqType, *llmq_ctx.qman, signHeight, id, msgHash, sig, 0) || - llmq::VerifyRecoveredSig(llmqType, *llmq_ctx.qman, signHeight, id, msgHash, sig, signOffset); - } else { - uint256 quorumHash(ParseHashV(request.params[4], "quorumHash")); - llmq::CQuorumCPtr quorum = llmq_ctx.qman->GetQuorum(llmqType, quorumHash); - - if (!quorum) { - throw JSONRPCError(RPC_INVALID_PARAMETER, "quorum not found"); - } - - uint256 signHash = llmq::BuildSignHash(llmqType, quorum->qc->quorumHash, id, msgHash); - return sig.VerifyInsecure(quorum->qc->quorumPublicKey, signHash); - } - } else if (cmd == "quorumhasrecsig") { - return llmq_ctx.sigman->HasRecoveredSig(llmqType, id, msgHash); - } else if (cmd == "quorumgetrecsig") { - llmq::CRecoveredSig recSig; - if (!llmq_ctx.sigman->GetRecoveredSigForId(llmqType, id, recSig)) { - throw JSONRPCError(RPC_INVALID_PARAMETER, "recovered signature not found"); - } - if (recSig.getMsgHash() != msgHash) { - throw JSONRPCError(RPC_INVALID_PARAMETER, "recovered signature not found"); - } - return recSig.ToJson(); - } else if (cmd == "quorumisconflicting") { - return llmq_ctx.sigman->IsConflicting(llmqType, id, msgHash); - } else { - // shouldn't happen as it's already handled by the caller - throw JSONRPCError(RPC_INVALID_PARAMETER, "invalid cmd"); + const bool use_bls_legacy = bls::bls_legacy_scheme.load(); + CBLSSignature sig; + if (!sig.SetHexStr(request.params[3].get_str(), use_bls_legacy)) { + throw JSONRPCError(RPC_INVALID_PARAMETER, "invalid signature format"); } + + if (request.params[4].isNull() || (request.params[4].get_str().empty() && !request.params[5].isNull())) { + int signHeight{-1}; + if (!request.params[5].isNull()) { + signHeight = ParseInt32V(request.params[5], "signHeight"); + } + // First check against the current active set, if it fails check against the last active set + int signOffset{llmq_params_opt->dkgInterval}; + return llmq::VerifyRecoveredSig(llmqType, *llmq_ctx.qman, signHeight, id, msgHash, sig, 0) || + llmq::VerifyRecoveredSig(llmqType, *llmq_ctx.qman, signHeight, id, msgHash, sig, signOffset); + } + + uint256 quorumHash(ParseHashV(request.params[4], "quorumHash")); + llmq::CQuorumCPtr quorum = llmq_ctx.qman->GetQuorum(llmqType, quorumHash); + + if (!quorum) { + throw JSONRPCError(RPC_INVALID_PARAMETER, "quorum not found"); + } + + uint256 signHash = llmq::BuildSignHash(llmqType, quorum->qc->quorumHash, id, msgHash); + return sig.VerifyInsecure(quorum->qc->quorumPublicKey, signHash); +}, + }; +} + +static RPCHelpMan quorum_hasrecsig() +{ + return RPCHelpMan{"quorum hasrecsig", + "Test if a valid recovered signature is present\n", + { + {"llmqType", RPCArg::Type::NUM, RPCArg::Optional::NO, "LLMQ type."}, + {"id", RPCArg::Type::STR_HEX, RPCArg::Optional::NO, "Request id."}, + {"msgHash", RPCArg::Type::STR_HEX, RPCArg::Optional::NO, "Message hash."}, + }, + 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"); + + const auto& llmq_params_opt = Params().GetLLMQ(llmqType); + if (!llmq_params_opt.has_value()) { + throw JSONRPCError(RPC_INVALID_PARAMETER, "invalid LLMQ type"); + } + + uint256 id(ParseHashV(request.params[1], "id")); + uint256 msgHash(ParseHashV(request.params[2], "msgHash")); + + return llmq_ctx.sigman->HasRecoveredSig(llmqType, id, msgHash); +}, + }; +} + +static RPCHelpMan quorum_getrecsig() +{ + return RPCHelpMan{"quorum getrecsig", + "Get a recovered signature\n", + { + {"llmqType", RPCArg::Type::NUM, RPCArg::Optional::NO, "LLMQ type."}, + {"id", RPCArg::Type::STR_HEX, RPCArg::Optional::NO, "Request id."}, + {"msgHash", RPCArg::Type::STR_HEX, RPCArg::Optional::NO, "Message hash."}, + }, + 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"); + + const auto& llmq_params_opt = Params().GetLLMQ(llmqType); + if (!llmq_params_opt.has_value()) { + throw JSONRPCError(RPC_INVALID_PARAMETER, "invalid LLMQ type"); + } + + uint256 id(ParseHashV(request.params[1], "id")); + uint256 msgHash(ParseHashV(request.params[2], "msgHash")); + + llmq::CRecoveredSig recSig; + if (!llmq_ctx.sigman->GetRecoveredSigForId(llmqType, id, recSig)) { + throw JSONRPCError(RPC_INVALID_PARAMETER, "recovered signature not found"); + } + if (recSig.getMsgHash() != msgHash) { + throw JSONRPCError(RPC_INVALID_PARAMETER, "recovered signature not found"); + } + return recSig.ToJson(); +}, + }; +} + +static RPCHelpMan quorum_isconflicting() +{ + return RPCHelpMan{"quorum isconflicting", + "Test if a conflict exists\n", + { + {"llmqType", RPCArg::Type::NUM, RPCArg::Optional::NO, "LLMQ type."}, + {"id", RPCArg::Type::STR_HEX, RPCArg::Optional::NO, "Request id."}, + {"msgHash", RPCArg::Type::STR_HEX, RPCArg::Optional::NO, "Message hash."}, + }, + 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"); + + const auto& llmq_params_opt = Params().GetLLMQ(llmqType); + if (!llmq_params_opt.has_value()) { + throw JSONRPCError(RPC_INVALID_PARAMETER, "invalid LLMQ type"); + } + + uint256 id(ParseHashV(request.params[1], "id")); + uint256 msgHash(ParseHashV(request.params[2], "msgHash")); + + return llmq_ctx.sigman->IsConflicting(llmqType, id, msgHash); +}, + }; } static RPCHelpMan quorum_selectquorum() From 50c99e84f84e1a6101537b12f71b485edb4c6a1c Mon Sep 17 00:00:00 2001 From: Konstantin Akimov Date: Wed, 12 Jun 2024 01:42:59 +0700 Subject: [PATCH 3/4] fix: adopt platform restriction for new composite commands --- src/rpc/server.cpp | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/src/rpc/server.cpp b/src/rpc/server.cpp index 5fa3c72002..a0984b00cf 100644 --- a/src/rpc/server.cpp +++ b/src/rpc/server.cpp @@ -153,8 +153,8 @@ void CRPCTable::InitPlatformRestrictions() {"getblockhash", {}}, {"getblockcount", {}}, {"getbestchainlock", {}}, - {"quorum", {"sign", static_cast(Params().GetConsensus().llmqTypePlatform)}}, - {"quorum", {"verify"}}, + {"quorum sign", {static_cast(Params().GetConsensus().llmqTypePlatform)}}, + {"quorum verify", {}}, {"submitchainlock", {}}, {"verifyislock", {}}, }; @@ -535,7 +535,9 @@ static bool ExecuteCommand(const CRPCCommand& command, const JSONRPCRequest& req // Before executing the RPC Command, filter commands from platform rpc user 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); + std::string command_name = command.name; + if (!command.subname.empty()) command_name += " " + command.subname; + const auto& it = mapPlatformRestrictions.equal_range(command_name); const auto& allowed_begin = it.first; const auto& allowed_end = it.second; /** @@ -545,8 +547,8 @@ static bool ExecuteCommand(const CRPCCommand& command, const JSONRPCRequest& req * * if request.strMethod == "quorum": * [ - * "quorum", ["sign", platformLlmqType], - * "quorum", ["verify"] + * "quorum sign", [platformLlmqType], + * "quorum verify", [] * ] * if request.strMethod == "verifyislock" * [ From b478406f9f4b7e78771ed9bb1e4c932249dd5de4 Mon Sep 17 00:00:00 2001 From: Konstantin Akimov Date: Wed, 12 Jun 2024 14:49:37 +0700 Subject: [PATCH 4/4] refactor: clean-up, missing const in rpc/quorums --- src/rpc/quorums.cpp | 77 +++++++++++++++++++++------------------------ 1 file changed, 35 insertions(+), 42 deletions(-) diff --git a/src/rpc/quorums.cpp b/src/rpc/quorums.cpp index 6a7a8dae8b..ea2ad2bac3 100644 --- a/src/rpc/quorums.cpp +++ b/src/rpc/quorums.cpp @@ -76,7 +76,7 @@ static RPCHelpMan quorum_list() CBlockIndex* pindexTip = WITH_LOCK(cs_main, return chainman.ActiveChain().Tip()); for (const auto& type : llmq::GetEnabledQuorumTypes(pindexTip)) { - const auto& llmq_params_opt = Params().GetLLMQ(type); + const auto llmq_params_opt = Params().GetLLMQ(type); CHECK_NONFATAL(llmq_params_opt.has_value()); UniValue v(UniValue::VARR); @@ -142,7 +142,7 @@ static RPCHelpMan quorum_list_extended() CBlockIndex* pblockindex = nHeight != -1 ? WITH_LOCK(cs_main, return chainman.ActiveChain()[nHeight]) : WITH_LOCK(cs_main, return chainman.ActiveChain().Tip()); for (const auto& type : llmq::GetEnabledQuorumTypes(pblockindex)) { - const auto& llmq_params_opt = Params().GetLLMQ(type); + const auto llmq_params_opt = Params().GetLLMQ(type); CHECK_NONFATAL(llmq_params_opt.has_value()); const auto& llmq_params = llmq_params_opt.value(); UniValue v(UniValue::VARR); @@ -241,12 +241,12 @@ static RPCHelpMan quorum_info() const NodeContext& node = EnsureAnyNodeContext(request.context); const LLMQContext& llmq_ctx = EnsureLLMQContext(node); - Consensus::LLMQType llmqType = (Consensus::LLMQType)ParseInt32V(request.params[0], "llmqType"); + const Consensus::LLMQType llmqType{static_cast(ParseInt32V(request.params[0], "llmqType"))}; if (!Params().GetLLMQ(llmqType).has_value()) { throw JSONRPCError(RPC_INVALID_PARAMETER, "invalid LLMQ type"); } - uint256 quorumHash(ParseHashV(request.params[1], "quorumHash")); + const uint256 quorumHash(ParseHashV(request.params[1], "quorumHash")); bool includeSkShare = false; if (!request.params[2].isNull()) { includeSkShare = ParseBoolV(request.params[2], "includeSkShare"); @@ -300,7 +300,7 @@ static RPCHelpMan quorum_dkgstatus() UniValue minableCommitments(UniValue::VARR); UniValue quorumArrConnections(UniValue::VARR); for (const auto& type : llmq::GetEnabledQuorumTypes(pindexTip)) { - const auto& llmq_params_opt = Params().GetLLMQ(type); + const auto llmq_params_opt = Params().GetLLMQ(type); CHECK_NONFATAL(llmq_params_opt.has_value()); const auto& llmq_params = llmq_params_opt.value(); bool rotation_enabled = llmq::IsQuorumRotationEnabled(llmq_params, pindexTip); @@ -400,7 +400,7 @@ static RPCHelpMan quorum_memberof() UniValue result(UniValue::VARR); for (const auto& type : llmq::GetEnabledQuorumTypes(pindexTip)) { - const auto& llmq_params_opt = Params().GetLLMQ(type); + const auto llmq_params_opt = Params().GetLLMQ(type); CHECK_NONFATAL(llmq_params_opt.has_value()); size_t count = llmq_params_opt->signingActiveQuorumCount; if (scanQuorumsCount != -1) { @@ -441,15 +441,14 @@ static RPCHelpMan quorum_sign() const NodeContext& node = EnsureAnyNodeContext(request.context); const LLMQContext& llmq_ctx = EnsureLLMQContext(node); - Consensus::LLMQType llmqType = (Consensus::LLMQType)ParseInt32V(request.params[0], "llmqType"); - - const auto& llmq_params_opt = Params().GetLLMQ(llmqType); + const Consensus::LLMQType llmqType{static_cast(ParseInt32V(request.params[0], "llmqType"))}; + const auto llmq_params_opt = Params().GetLLMQ(llmqType); if (!llmq_params_opt.has_value()) { throw JSONRPCError(RPC_INVALID_PARAMETER, "invalid LLMQ type"); } - uint256 id(ParseHashV(request.params[1], "id")); - uint256 msgHash(ParseHashV(request.params[2], "msgHash")); + const uint256 id(ParseHashV(request.params[1], "id")); + const uint256 msgHash(ParseHashV(request.params[2], "msgHash")); uint256 quorumHash; if (!request.params[3].isNull() && !request.params[3].get_str().empty()) { @@ -518,15 +517,15 @@ static RPCHelpMan quorum_verify() const NodeContext& node = EnsureAnyNodeContext(request.context); const LLMQContext& llmq_ctx = EnsureLLMQContext(node); - Consensus::LLMQType llmqType = (Consensus::LLMQType)ParseInt32V(request.params[0], "llmqType"); + const Consensus::LLMQType llmqType{static_cast(ParseInt32V(request.params[0], "llmqType"))}; - const auto& llmq_params_opt = Params().GetLLMQ(llmqType); + const auto llmq_params_opt = Params().GetLLMQ(llmqType); if (!llmq_params_opt.has_value()) { throw JSONRPCError(RPC_INVALID_PARAMETER, "invalid LLMQ type"); } - uint256 id(ParseHashV(request.params[1], "id")); - uint256 msgHash(ParseHashV(request.params[2], "msgHash")); + const uint256 id(ParseHashV(request.params[1], "id")); + const uint256 msgHash(ParseHashV(request.params[2], "msgHash")); const bool use_bls_legacy = bls::bls_legacy_scheme.load(); CBLSSignature sig; @@ -574,15 +573,13 @@ static RPCHelpMan quorum_hasrecsig() const NodeContext& node = EnsureAnyNodeContext(request.context); const LLMQContext& llmq_ctx = EnsureLLMQContext(node); - Consensus::LLMQType llmqType = (Consensus::LLMQType)ParseInt32V(request.params[0], "llmqType"); - - const auto& llmq_params_opt = Params().GetLLMQ(llmqType); - if (!llmq_params_opt.has_value()) { + const Consensus::LLMQType llmqType{static_cast(ParseInt32V(request.params[0], "llmqType"))}; + if (!Params().GetLLMQ(llmqType).has_value()) { throw JSONRPCError(RPC_INVALID_PARAMETER, "invalid LLMQ type"); } - uint256 id(ParseHashV(request.params[1], "id")); - uint256 msgHash(ParseHashV(request.params[2], "msgHash")); + const uint256 id(ParseHashV(request.params[1], "id")); + const uint256 msgHash(ParseHashV(request.params[2], "msgHash")); return llmq_ctx.sigman->HasRecoveredSig(llmqType, id, msgHash); }, @@ -605,15 +602,13 @@ static RPCHelpMan quorum_getrecsig() const NodeContext& node = EnsureAnyNodeContext(request.context); const LLMQContext& llmq_ctx = EnsureLLMQContext(node); - Consensus::LLMQType llmqType = (Consensus::LLMQType)ParseInt32V(request.params[0], "llmqType"); - - const auto& llmq_params_opt = Params().GetLLMQ(llmqType); - if (!llmq_params_opt.has_value()) { + const Consensus::LLMQType llmqType{static_cast(ParseInt32V(request.params[0], "llmqType"))}; + if (!Params().GetLLMQ(llmqType).has_value()) { throw JSONRPCError(RPC_INVALID_PARAMETER, "invalid LLMQ type"); } - uint256 id(ParseHashV(request.params[1], "id")); - uint256 msgHash(ParseHashV(request.params[2], "msgHash")); + const uint256 id(ParseHashV(request.params[1], "id")); + const uint256 msgHash(ParseHashV(request.params[2], "msgHash")); llmq::CRecoveredSig recSig; if (!llmq_ctx.sigman->GetRecoveredSigForId(llmqType, id, recSig)) { @@ -643,15 +638,13 @@ static RPCHelpMan quorum_isconflicting() const NodeContext& node = EnsureAnyNodeContext(request.context); const LLMQContext& llmq_ctx = EnsureLLMQContext(node); - Consensus::LLMQType llmqType = (Consensus::LLMQType)ParseInt32V(request.params[0], "llmqType"); - - const auto& llmq_params_opt = Params().GetLLMQ(llmqType); - if (!llmq_params_opt.has_value()) { + const Consensus::LLMQType llmqType{static_cast(ParseInt32V(request.params[0], "llmqType"))}; + if (!Params().GetLLMQ(llmqType).has_value()) { throw JSONRPCError(RPC_INVALID_PARAMETER, "invalid LLMQ type"); } - uint256 id(ParseHashV(request.params[1], "id")); - uint256 msgHash(ParseHashV(request.params[2], "msgHash")); + const uint256 id(ParseHashV(request.params[1], "id")); + const uint256 msgHash(ParseHashV(request.params[2], "msgHash")); return llmq_ctx.sigman->IsConflicting(llmqType, id, msgHash); }, @@ -673,17 +666,17 @@ static RPCHelpMan quorum_selectquorum() const NodeContext& node = EnsureAnyNodeContext(request.context); const LLMQContext& llmq_ctx = EnsureLLMQContext(node); - Consensus::LLMQType llmqType = (Consensus::LLMQType)ParseInt32V(request.params[0], "llmqType"); - const auto& llmq_params_opt = Params().GetLLMQ(llmqType); + const Consensus::LLMQType llmqType{static_cast(ParseInt32V(request.params[0], "llmqType"))}; + const auto llmq_params_opt = Params().GetLLMQ(llmqType); if (!llmq_params_opt.has_value()) { throw JSONRPCError(RPC_INVALID_PARAMETER, "invalid LLMQ type"); } - uint256 id(ParseHashV(request.params[1], "id")); + const uint256 id(ParseHashV(request.params[1], "id")); UniValue ret(UniValue::VOBJ); - auto quorum = llmq::SelectQuorumForSigning(llmq_params_opt.value(), *llmq_ctx.qman, id); + const auto quorum = llmq::SelectQuorumForSigning(llmq_params_opt.value(), *llmq_ctx.qman, id); if (!quorum) { throw JSONRPCError(RPC_MISC_ERROR, "no quorums active"); } @@ -973,8 +966,8 @@ static RPCHelpMan verifyislock() RPCExamples{""}, [&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue { - uint256 id(ParseHashV(request.params[0], "id")); - uint256 txid(ParseHashV(request.params[1], "txid")); + const uint256 id(ParseHashV(request.params[0], "id")); + const uint256 txid(ParseHashV(request.params[1], "txid")); const NodeContext& node = EnsureAnyNodeContext(request.context); const ChainstateManager& chainman = EnsureChainman(node); @@ -983,7 +976,7 @@ static RPCHelpMan verifyislock() g_txindex->BlockUntilSyncedToCurrentChain(); } - CBlockIndex* pindexMined{nullptr}; + const CBlockIndex* pindexMined{nullptr}; { LOCK(cs_main); uint256 hash_block; @@ -1027,9 +1020,9 @@ static RPCHelpMan verifyislock() auto llmqType = Params().GetConsensus().llmqTypeDIP0024InstantSend; // First check against the current active set, if it fails check against the last active set - const auto& llmq_params_opt = Params().GetLLMQ(llmqType); + const auto llmq_params_opt = Params().GetLLMQ(llmqType); CHECK_NONFATAL(llmq_params_opt.has_value()); - int signOffset{llmq_params_opt->dkgInterval}; + const int signOffset{llmq_params_opt->dkgInterval}; return llmq::VerifyRecoveredSig(llmqType, *llmq_ctx.qman, signHeight, id, txid, sig, 0) || llmq::VerifyRecoveredSig(llmqType, *llmq_ctx.qman, signHeight, id, txid, sig, signOffset); },