mirror of
https://github.com/dashpay/dash.git
synced 2024-12-26 04:22:55 +01:00
Merge #6055: refactor: use new type of composite commands for quorum NNN
b478406f9f
refactor: clean-up, missing const in rpc/quorums (Konstantin Akimov)50c99e84f8
fix: adopt platform restriction for new composite commands (Konstantin Akimov)e3c4d66ef3
refactor: quorum sign methods (Konstantin Akimov)2af9d86654
refactor: use new approach for rpc quorums NNN (Konstantin Akimov) Pull request description: ## Issue being fixed or feature implemented See #6051 ## What was done? Commands starting from 'quorum ...' uses new a new way to make composite commands. ## How Has This Been Tested? Run unit/functional tests. Please notice, there's required extra changes for platform restrictions, the subcommand is no more first argument, but part of command, space separated. ## Breaking Changes N/A ## Checklist: - [x] I have performed a self-review of my own code - [x] I have commented my code, particularly in hard-to-understand areas - [x] I have added or updated relevant unit/integration/functional/e2e tests - [x] I have made corresponding changes to the documentation - [x] I have assigned this pull request to a milestone ACKs for top commit: UdjinM6: utACKb478406f9f
PastaPastaPasta: utACKb478406f9f
Tree-SHA512: c53856a3f45fee44a8130876ed4545f6f2c0f59f74e4d4745e7354097fee3a74ed526cc8160de532dbb4aeb81b82638ee912a0961b910692e78889baa2c976c3
This commit is contained in:
commit
692a076aa3
@ -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()) {
|
||||||
@ -77,7 +76,7 @@ static UniValue quorum_list(const JSONRPCRequest& request, const ChainstateManag
|
|||||||
CBlockIndex* pindexTip = WITH_LOCK(cs_main, return chainman.ActiveChain().Tip());
|
CBlockIndex* pindexTip = WITH_LOCK(cs_main, return chainman.ActiveChain().Tip());
|
||||||
|
|
||||||
for (const auto& type : llmq::GetEnabledQuorumTypes(pindexTip)) {
|
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());
|
CHECK_NONFATAL(llmq_params_opt.has_value());
|
||||||
UniValue v(UniValue::VARR);
|
UniValue v(UniValue::VARR);
|
||||||
|
|
||||||
@ -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()) {
|
||||||
@ -142,7 +142,7 @@ static UniValue quorum_list_extended(const JSONRPCRequest& request, const Chains
|
|||||||
CBlockIndex* pblockindex = nHeight != -1 ? WITH_LOCK(cs_main, return chainman.ActiveChain()[nHeight]) : WITH_LOCK(cs_main, return chainman.ActiveChain().Tip());
|
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)) {
|
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());
|
CHECK_NONFATAL(llmq_params_opt.has_value());
|
||||||
const auto& llmq_params = llmq_params_opt.value();
|
const auto& llmq_params = llmq_params_opt.value();
|
||||||
UniValue v(UniValue::VARR);
|
UniValue v(UniValue::VARR);
|
||||||
@ -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,16 +225,28 @@ 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");
|
const Consensus::LLMQType llmqType{static_cast<Consensus::LLMQType>(ParseInt32V(request.params[0], "llmqType"))};
|
||||||
if (!Params().GetLLMQ(llmqType).has_value()) {
|
if (!Params().GetLLMQ(llmqType).has_value()) {
|
||||||
throw JSONRPCError(RPC_INVALID_PARAMETER, "invalid LLMQ type");
|
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;
|
bool includeSkShare = false;
|
||||||
if (!request.params[2].isNull()) {
|
if (!request.params[2].isNull()) {
|
||||||
includeSkShare = ParseBoolV(request.params[2], "includeSkShare");
|
includeSkShare = ParseBoolV(request.params[2], "includeSkShare");
|
||||||
@ -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,17 +291,16 @@ 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);
|
||||||
for (const auto& type : llmq::GetEnabledQuorumTypes(pindexTip)) {
|
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());
|
CHECK_NONFATAL(llmq_params_opt.has_value());
|
||||||
const auto& llmq_params = llmq_params_opt.value();
|
const auto& llmq_params = llmq_params_opt.value();
|
||||||
bool rotation_enabled = llmq::IsQuorumRotationEnabled(llmq_params, pindexTip);
|
bool rotation_enabled = llmq::IsQuorumRotationEnabled(llmq_params, pindexTip);
|
||||||
@ -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;
|
||||||
@ -401,7 +400,7 @@ static UniValue quorum_memberof(const JSONRPCRequest& request, const ChainstateM
|
|||||||
|
|
||||||
UniValue result(UniValue::VARR);
|
UniValue result(UniValue::VARR);
|
||||||
for (const auto& type : llmq::GetEnabledQuorumTypes(pindexTip)) {
|
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());
|
CHECK_NONFATAL(llmq_params_opt.has_value());
|
||||||
size_t count = llmq_params_opt->signingActiveQuorumCount;
|
size_t count = llmq_params_opt->signingActiveQuorumCount;
|
||||||
if (scanQuorumsCount != -1) {
|
if (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."},
|
||||||
@ -435,103 +436,20 @@ static void quorum_sign_help(const JSONRPCRequest& request)
|
|||||||
},
|
},
|
||||||
RPCResults{},
|
RPCResults{},
|
||||||
RPCExamples{""},
|
RPCExamples{""},
|
||||||
}.Check(request);
|
[&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue
|
||||||
}
|
|
||||||
|
|
||||||
static void quorum_verify_help(const JSONRPCRequest& request)
|
|
||||||
{
|
{
|
||||||
RPCHelpMan{"quorum verify",
|
const NodeContext& node = EnsureAnyNodeContext(request.context);
|
||||||
"Test if a quorum signature is valid for a request id and a message hash\n",
|
const LLMQContext& llmq_ctx = EnsureLLMQContext(node);
|
||||||
{
|
|
||||||
{"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."},
|
|
||||||
{"signature", RPCArg::Type::STR, RPCArg::Optional::NO, "Quorum signature to verify."},
|
|
||||||
{"quorumHash", RPCArg::Type::STR_HEX, /* default */ "",
|
|
||||||
"The quorum identifier.\n"
|
|
||||||
"Set to \"\" if you want to specify signHeight instead."},
|
|
||||||
{"signHeight", RPCArg::Type::NUM, /* default */ "",
|
|
||||||
"The height at which the message was signed.\n"
|
|
||||||
"Only works when quorumHash is \"\"."},
|
|
||||||
},
|
|
||||||
RPCResults{},
|
|
||||||
RPCExamples{""},
|
|
||||||
}.Check(request);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void quorum_hasrecsig_help(const JSONRPCRequest& request)
|
const Consensus::LLMQType llmqType{static_cast<Consensus::LLMQType>(ParseInt32V(request.params[0], "llmqType"))};
|
||||||
{
|
const auto llmq_params_opt = Params().GetLLMQ(llmqType);
|
||||||
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");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Consensus::LLMQType llmqType = (Consensus::LLMQType)ParseInt32V(request.params[0], "llmqType");
|
|
||||||
|
|
||||||
const auto& llmq_params_opt = Params().GetLLMQ(llmqType);
|
|
||||||
if (!llmq_params_opt.has_value()) {
|
if (!llmq_params_opt.has_value()) {
|
||||||
throw JSONRPCError(RPC_INVALID_PARAMETER, "invalid LLMQ type");
|
throw JSONRPCError(RPC_INVALID_PARAMETER, "invalid LLMQ type");
|
||||||
}
|
}
|
||||||
|
|
||||||
uint256 id(ParseHashV(request.params[1], "id"));
|
const uint256 id(ParseHashV(request.params[1], "id"));
|
||||||
uint256 msgHash(ParseHashV(request.params[2], "msgHash"));
|
const uint256 msgHash(ParseHashV(request.params[2], "msgHash"));
|
||||||
|
|
||||||
if (cmd == "quorumsign") {
|
|
||||||
uint256 quorumHash;
|
uint256 quorumHash;
|
||||||
if (!request.params[3].isNull() && !request.params[3].get_str().empty()) {
|
if (!request.params[3].isNull() && !request.params[3].get_str().empty()) {
|
||||||
quorumHash = ParseHashV(request.params[3], "quorumHash");
|
quorumHash = ParseHashV(request.params[3], "quorumHash");
|
||||||
@ -572,7 +490,43 @@ static UniValue quorum_sigs_cmd(const JSONRPCRequest& request, const LLMQContext
|
|||||||
|
|
||||||
return obj;
|
return obj;
|
||||||
}
|
}
|
||||||
} else if (cmd == "quorumverify") {
|
},
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
static 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."},
|
||||||
|
{"id", RPCArg::Type::STR_HEX, RPCArg::Optional::NO, "Request id."},
|
||||||
|
{"msgHash", RPCArg::Type::STR_HEX, RPCArg::Optional::NO, "Message hash."},
|
||||||
|
{"signature", RPCArg::Type::STR, RPCArg::Optional::NO, "Quorum signature to verify."},
|
||||||
|
{"quorumHash", RPCArg::Type::STR_HEX, /* default */ "",
|
||||||
|
"The quorum identifier.\n"
|
||||||
|
"Set to \"\" if you want to specify signHeight instead."},
|
||||||
|
{"signHeight", RPCArg::Type::NUM, /* default */ "",
|
||||||
|
"The height at which the message was signed.\n"
|
||||||
|
"Only works when quorumHash is \"\"."},
|
||||||
|
},
|
||||||
|
RPCResults{},
|
||||||
|
RPCExamples{""},
|
||||||
|
[&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue
|
||||||
|
{
|
||||||
|
const NodeContext& node = EnsureAnyNodeContext(request.context);
|
||||||
|
const LLMQContext& llmq_ctx = EnsureLLMQContext(node);
|
||||||
|
|
||||||
|
const Consensus::LLMQType llmqType{static_cast<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");
|
||||||
|
}
|
||||||
|
|
||||||
|
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();
|
const bool use_bls_legacy = bls::bls_legacy_scheme.load();
|
||||||
CBLSSignature sig;
|
CBLSSignature sig;
|
||||||
if (!sig.SetHexStr(request.params[3].get_str(), use_bls_legacy)) {
|
if (!sig.SetHexStr(request.params[3].get_str(), use_bls_legacy)) {
|
||||||
@ -588,7 +542,8 @@ static UniValue quorum_sigs_cmd(const JSONRPCRequest& request, const LLMQContext
|
|||||||
int signOffset{llmq_params_opt->dkgInterval};
|
int signOffset{llmq_params_opt->dkgInterval};
|
||||||
return llmq::VerifyRecoveredSig(llmqType, *llmq_ctx.qman, signHeight, id, msgHash, sig, 0) ||
|
return llmq::VerifyRecoveredSig(llmqType, *llmq_ctx.qman, signHeight, id, msgHash, sig, 0) ||
|
||||||
llmq::VerifyRecoveredSig(llmqType, *llmq_ctx.qman, signHeight, id, msgHash, sig, signOffset);
|
llmq::VerifyRecoveredSig(llmqType, *llmq_ctx.qman, signHeight, id, msgHash, sig, signOffset);
|
||||||
} else {
|
}
|
||||||
|
|
||||||
uint256 quorumHash(ParseHashV(request.params[4], "quorumHash"));
|
uint256 quorumHash(ParseHashV(request.params[4], "quorumHash"));
|
||||||
llmq::CQuorumCPtr quorum = llmq_ctx.qman->GetQuorum(llmqType, quorumHash);
|
llmq::CQuorumCPtr quorum = llmq_ctx.qman->GetQuorum(llmqType, quorumHash);
|
||||||
|
|
||||||
@ -598,10 +553,63 @@ static UniValue quorum_sigs_cmd(const JSONRPCRequest& request, const LLMQContext
|
|||||||
|
|
||||||
uint256 signHash = llmq::BuildSignHash(llmqType, quorum->qc->quorumHash, id, msgHash);
|
uint256 signHash = llmq::BuildSignHash(llmqType, quorum->qc->quorumHash, id, msgHash);
|
||||||
return sig.VerifyInsecure(quorum->qc->quorumPublicKey, signHash);
|
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);
|
||||||
|
|
||||||
|
const Consensus::LLMQType llmqType{static_cast<Consensus::LLMQType>(ParseInt32V(request.params[0], "llmqType"))};
|
||||||
|
if (!Params().GetLLMQ(llmqType).has_value()) {
|
||||||
|
throw JSONRPCError(RPC_INVALID_PARAMETER, "invalid LLMQ type");
|
||||||
}
|
}
|
||||||
} else if (cmd == "quorumhasrecsig") {
|
|
||||||
|
const uint256 id(ParseHashV(request.params[1], "id"));
|
||||||
|
const uint256 msgHash(ParseHashV(request.params[2], "msgHash"));
|
||||||
|
|
||||||
return llmq_ctx.sigman->HasRecoveredSig(llmqType, id, msgHash);
|
return llmq_ctx.sigman->HasRecoveredSig(llmqType, id, msgHash);
|
||||||
} else if (cmd == "quorumgetrecsig") {
|
},
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
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);
|
||||||
|
|
||||||
|
const Consensus::LLMQType llmqType{static_cast<Consensus::LLMQType>(ParseInt32V(request.params[0], "llmqType"))};
|
||||||
|
if (!Params().GetLLMQ(llmqType).has_value()) {
|
||||||
|
throw JSONRPCError(RPC_INVALID_PARAMETER, "invalid LLMQ type");
|
||||||
|
}
|
||||||
|
|
||||||
|
const uint256 id(ParseHashV(request.params[1], "id"));
|
||||||
|
const uint256 msgHash(ParseHashV(request.params[2], "msgHash"));
|
||||||
|
|
||||||
llmq::CRecoveredSig recSig;
|
llmq::CRecoveredSig recSig;
|
||||||
if (!llmq_ctx.sigman->GetRecoveredSigForId(llmqType, id, recSig)) {
|
if (!llmq_ctx.sigman->GetRecoveredSigForId(llmqType, id, recSig)) {
|
||||||
throw JSONRPCError(RPC_INVALID_PARAMETER, "recovered signature not found");
|
throw JSONRPCError(RPC_INVALID_PARAMETER, "recovered signature not found");
|
||||||
@ -610,17 +618,42 @@ static UniValue quorum_sigs_cmd(const JSONRPCRequest& request, const LLMQContext
|
|||||||
throw JSONRPCError(RPC_INVALID_PARAMETER, "recovered signature not found");
|
throw JSONRPCError(RPC_INVALID_PARAMETER, "recovered signature not found");
|
||||||
}
|
}
|
||||||
return recSig.ToJson();
|
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");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void quorum_selectquorum_help(const JSONRPCRequest& request)
|
static RPCHelpMan quorum_isconflicting()
|
||||||
{
|
{
|
||||||
RPCHelpMan{"quorum selectquorum",
|
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);
|
||||||
|
|
||||||
|
const Consensus::LLMQType llmqType{static_cast<Consensus::LLMQType>(ParseInt32V(request.params[0], "llmqType"))};
|
||||||
|
if (!Params().GetLLMQ(llmqType).has_value()) {
|
||||||
|
throw JSONRPCError(RPC_INVALID_PARAMETER, "invalid LLMQ type");
|
||||||
|
}
|
||||||
|
|
||||||
|
const uint256 id(ParseHashV(request.params[1], "id"));
|
||||||
|
const uint256 msgHash(ParseHashV(request.params[2], "msgHash"));
|
||||||
|
|
||||||
|
return llmq_ctx.sigman->IsConflicting(llmqType, id, msgHash);
|
||||||
|
},
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
static 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,24 +661,22 @@ 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");
|
const Consensus::LLMQType llmqType{static_cast<Consensus::LLMQType>(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()) {
|
if (!llmq_params_opt.has_value()) {
|
||||||
throw JSONRPCError(RPC_INVALID_PARAMETER, "invalid LLMQ type");
|
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);
|
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) {
|
if (!quorum) {
|
||||||
throw JSONRPCError(RPC_MISC_ERROR, "no quorums active");
|
throw JSONRPCError(RPC_MISC_ERROR, "no quorums active");
|
||||||
}
|
}
|
||||||
@ -659,11 +690,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 +705,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 +721,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 +742,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 +768,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 +787,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 +807,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 +832,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 +857,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 +888,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 +906,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 +948,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,15 +964,10 @@ 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);
|
const uint256 id(ParseHashV(request.params[0], "id"));
|
||||||
|
const uint256 txid(ParseHashV(request.params[1], "txid"));
|
||||||
uint256 id(ParseHashV(request.params[0], "id"));
|
|
||||||
uint256 txid(ParseHashV(request.params[1], "txid"));
|
|
||||||
|
|
||||||
const NodeContext& node = EnsureAnyNodeContext(request.context);
|
const NodeContext& node = EnsureAnyNodeContext(request.context);
|
||||||
const ChainstateManager& chainman = EnsureChainman(node);
|
const ChainstateManager& chainman = EnsureChainman(node);
|
||||||
@ -987,7 +976,7 @@ static UniValue verifyislock(const JSONRPCRequest& request)
|
|||||||
g_txindex->BlockUntilSyncedToCurrentChain();
|
g_txindex->BlockUntilSyncedToCurrentChain();
|
||||||
}
|
}
|
||||||
|
|
||||||
CBlockIndex* pindexMined{nullptr};
|
const CBlockIndex* pindexMined{nullptr};
|
||||||
{
|
{
|
||||||
LOCK(cs_main);
|
LOCK(cs_main);
|
||||||
uint256 hash_block;
|
uint256 hash_block;
|
||||||
@ -1031,16 +1020,18 @@ static UniValue verifyislock(const JSONRPCRequest& request)
|
|||||||
|
|
||||||
auto llmqType = Params().GetConsensus().llmqTypeDIP0024InstantSend;
|
auto llmqType = Params().GetConsensus().llmqTypeDIP0024InstantSend;
|
||||||
// First check against the current active set, if it fails check against the last active set
|
// 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());
|
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) ||
|
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 +1041,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 +1066,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 +1077,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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -153,8 +153,8 @@ void CRPCTable::InitPlatformRestrictions()
|
|||||||
{"getblockhash", {}},
|
{"getblockhash", {}},
|
||||||
{"getblockcount", {}},
|
{"getblockcount", {}},
|
||||||
{"getbestchainlock", {}},
|
{"getbestchainlock", {}},
|
||||||
{"quorum", {"sign", static_cast<uint8_t>(Params().GetConsensus().llmqTypePlatform)}},
|
{"quorum sign", {static_cast<uint8_t>(Params().GetConsensus().llmqTypePlatform)}},
|
||||||
{"quorum", {"verify"}},
|
{"quorum verify", {}},
|
||||||
{"submitchainlock", {}},
|
{"submitchainlock", {}},
|
||||||
{"verifyislock", {}},
|
{"verifyislock", {}},
|
||||||
};
|
};
|
||||||
@ -538,7 +538,9 @@ static bool ExecuteCommand(const CRPCCommand& command, const JSONRPCRequest& req
|
|||||||
// Before executing the RPC Command, filter commands from platform rpc user
|
// Before executing the RPC Command, filter commands from platform rpc user
|
||||||
if (node.mn_activeman && request.authUser == gArgs.GetArg("-platform-user", defaultPlatformUser)) {
|
if (node.mn_activeman && request.authUser == gArgs.GetArg("-platform-user", defaultPlatformUser)) {
|
||||||
// replace this with structured binding in c++20
|
// 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_begin = it.first;
|
||||||
const auto& allowed_end = it.second;
|
const auto& allowed_end = it.second;
|
||||||
/**
|
/**
|
||||||
@ -548,8 +550,8 @@ static bool ExecuteCommand(const CRPCCommand& command, const JSONRPCRequest& req
|
|||||||
*
|
*
|
||||||
* if request.strMethod == "quorum":
|
* if request.strMethod == "quorum":
|
||||||
* [
|
* [
|
||||||
* "quorum", ["sign", platformLlmqType],
|
* "quorum sign", [platformLlmqType],
|
||||||
* "quorum", ["verify"]
|
* "quorum verify", []
|
||||||
* ]
|
* ]
|
||||||
* if request.strMethod == "verifyislock"
|
* if request.strMethod == "verifyislock"
|
||||||
* [
|
* [
|
||||||
|
Loading…
Reference in New Issue
Block a user