From 56b95d4526fb109a440c37eb3a701f3d456251f6 Mon Sep 17 00:00:00 2001 From: Kittywhiskers Van Gogh <63189531+kwvg@users.noreply.github.com> Date: Fri, 12 Dec 2025 19:03:49 +0530 Subject: [PATCH 1/8] rpc: add `GetJsonHelp()` defs for `CDKGDebug{,Session}Status` --- src/evo/core_write.cpp | 1 + src/llmq/core_write.cpp | 79 +++++++++++++++++++++++++++++++++++++++++ src/llmq/debug.h | 11 +++--- 3 files changed, 87 insertions(+), 4 deletions(-) diff --git a/src/evo/core_write.cpp b/src/evo/core_write.cpp index 0779abe51893..05e50f0e9b9b 100644 --- a/src/evo/core_write.cpp +++ b/src/evo/core_write.cpp @@ -44,6 +44,7 @@ const std::map RPCRESULT_MAP{{ RESULT_MAP_ENTRY("inputsHash", RPCResult::Type::STR_HEX, "Hash of all the outpoints of the transaction inputs"), RESULT_MAP_ENTRY("lastPaidHeight", RPCResult::Type::NUM, "Height masternode was last paid"), RESULT_MAP_ENTRY("llmqType", RPCResult::Type::NUM, "Quorum type"), + RESULT_MAP_ENTRY("memberIndex", RPCResult::Type::NUM, "Quorum member index"), RESULT_MAP_ENTRY("merkleRootMNList", RPCResult::Type::STR_HEX, "Merkle root of the masternode list"), RESULT_MAP_ENTRY("merkleRootQuorums", RPCResult::Type::STR_HEX, "Merkle root of the quorum list"), RESULT_MAP_ENTRY("operatorPayoutAddress", RPCResult::Type::STR, "Dash address used for operator reward payments"), diff --git a/src/llmq/core_write.cpp b/src/llmq/core_write.cpp index 5ffe3c46f956..91375c7b644c 100644 --- a/src/llmq/core_write.cpp +++ b/src/llmq/core_write.cpp @@ -3,6 +3,7 @@ // file COPYING or http://www.opensource.org/licenses/mit-license.php. #include +#include #include #include @@ -15,6 +16,84 @@ #include namespace llmq { +// CDKGDebugSessionStatus::ToJson() defined in llmq/debug.cpp +RPCResult CDKGDebugSessionStatus::GetJsonHelp(const std::string& key, bool optional) +{ + return {RPCResult::Type::OBJ, key, optional, key.empty() ? "" : "The state of a DKG session", + { + GetRpcResult("llmqType"), + GetRpcResult("quorumHash"), + {RPCResult::Type::NUM, "quorumHeight", "Block height of the quorum"}, + {RPCResult::Type::NUM, "phase", "Active DKG phase"}, + {RPCResult::Type::BOOL, "sentContributions", "Returns true if contributions sent"}, + {RPCResult::Type::BOOL, "sentComplaint", "Returns true if complaints sent"}, + {RPCResult::Type::BOOL, "sentJustification", "Returns true if justifications sent"}, + {RPCResult::Type::BOOL, "sentPrematureCommitment", "Returns true if premature commitments sent"}, + {RPCResult::Type::BOOL, "aborted", "Returns true if DKG session aborted"}, + {RPCResult{"for detail_level = 0", RPCResult::Type::NUM, "badMembers", "Number of bad members"}}, + {RPCResult{"for detail_level = 0", RPCResult::Type::NUM, "weComplain", "Number of complaints sent"}}, + {RPCResult{"for detail_level = 0", RPCResult::Type::NUM, "receivedContributions", "Number of contributions received"}}, + {RPCResult{"for detail_level = 0", RPCResult::Type::NUM, "receivedComplaints", "Number of complaints received"}}, + {RPCResult{"for detail_level = 0", RPCResult::Type::NUM, "receivedJustifications", "Number of justifications received"}}, + {RPCResult{"for detail_level = 0", RPCResult::Type::NUM, "receivedPrematureCommitments", "Number of premature commitments received"}}, + {RPCResult{"for detail_level = 1", RPCResult::Type::ARR, "badMembers", "Array of indexes for each bad member", { + {RPCResult::Type::NUM, "", "Quorum member index"}}}}, + {RPCResult{"for detail_level = 1", RPCResult::Type::ARR, "weComplain", "Array of indexes for each complaint sent", { + {RPCResult::Type::NUM, "", "Quorum member index"}}}}, + {RPCResult{"for detail_level = 1", RPCResult::Type::ARR, "receivedContributions", "Array of indexes for each contribution received", { + {RPCResult::Type::NUM, "", "Quorum member index"}}}}, + {RPCResult{"for detail_level = 1", RPCResult::Type::ARR, "receivedComplaints", "Array of indexes for each complaint received", { + {RPCResult::Type::NUM, "", "Quorum member index"}}}}, + {RPCResult{"for detail_level = 1", RPCResult::Type::ARR, "receivedJustifications", "Array of indexes for each justification received", { + {RPCResult::Type::NUM, "", "Quorum member index"}}}}, + {RPCResult{"for detail_level = 1", RPCResult::Type::ARR, "receivedPrematureCommitments", "Array of indexes for each commitment received", { + {RPCResult::Type::NUM, "", "Quorum member index"}}}}, + {RPCResult{"for detail_level = 2", RPCResult::Type::ARR, "badMembers", "Array of objects for each bad member", { + {RPCResult::Type::OBJ, "", "", { + GetRpcResult("memberIndex"), + GetRpcResult("proTxHash", /*optional=*/true)}}}}}, + {RPCResult{"for detail_level = 2", RPCResult::Type::ARR, "weComplain", "Array of objects for each complaint sent", { + {RPCResult::Type::OBJ, "", "", { + GetRpcResult("memberIndex"), + GetRpcResult("proTxHash", /*optional=*/true)}}}}}, + {RPCResult{"for detail_level = 2", RPCResult::Type::ARR, "receivedContributions", "Array of objects for each contribution received", { + {RPCResult::Type::OBJ, "", "", { + GetRpcResult("memberIndex"), + GetRpcResult("proTxHash", /*optional=*/true)}}}}}, + {RPCResult{"for detail_level = 2", RPCResult::Type::ARR, "receivedComplaints", "Array of objects for each complaint received", { + {RPCResult::Type::OBJ, "", "", { + GetRpcResult("memberIndex"), + GetRpcResult("proTxHash", /*optional=*/true)}}}}}, + {RPCResult{"for detail_level = 2", RPCResult::Type::ARR, "receivedJustifications", "Array of objects for each justification received", { + {RPCResult::Type::OBJ, "", "", { + GetRpcResult("memberIndex"), + GetRpcResult("proTxHash", /*optional=*/true)}}}}}, + {RPCResult{"for detail_level = 2", RPCResult::Type::ARR, "receivedPrematureCommitments", "Array of objects for each commitment received", { + {RPCResult::Type::OBJ, "", "", { + GetRpcResult("memberIndex"), + GetRpcResult("proTxHash", /*optional=*/true)}}}}}, + {RPCResult{"for detail_level = 2", RPCResult::Type::ARR, "allMembers", "Array of provider registration transaction hash for all quorum members", { + GetRpcResult("proTxHash")}}}, + }}; +} + +// CDKGDebugStatus::ToJson() defined in llmq/debug.cpp +RPCResult CDKGDebugStatus::GetJsonHelp(const std::string& key, bool optional) +{ + return {RPCResult::Type::OBJ, key, optional, key.empty() ? "" : "The state of the node's DKG sessions", + { + {RPCResult::Type::NUM, "time", "Adjusted time for the last update, timestamp"}, + {RPCResult::Type::STR, "timeStr", "Adjusted time for the last update, human friendly"}, + {RPCResult::Type::ARR, "session", "", { + {RPCResult::Type::OBJ, "", "", { + {RPCResult::Type::NUM, "llmqType", "Name of quorum"}, + GetRpcResult("quorumIndex"), + CDKGDebugSessionStatus::GetJsonHelp(/*key=*/"status", /*optional=*/false) + }}, + }} + }}; +} + RPCResult CFinalCommitment::GetJsonHelp(const std::string& key, bool optional) { return {RPCResult::Type::OBJ, key, optional, key.empty() ? "" : "The quorum commitment payload", diff --git a/src/llmq/debug.h b/src/llmq/debug.h index 4ea8e597b022..cebaadbee93f 100644 --- a/src/llmq/debug.h +++ b/src/llmq/debug.h @@ -17,6 +17,7 @@ class CDeterministicMNManager; class ChainstateManager; class CInv; class CScheduler; +struct RPCResult; namespace llmq { @@ -77,8 +78,9 @@ class CDKGDebugSessionStatus public: CDKGDebugSessionStatus() : statusBitset(0) {} - UniValue ToJson(CDeterministicMNManager& dmnman, CQuorumSnapshotManager& qsnapman, - const ChainstateManager& chainman, int quorumIndex, int detailLevel) const; + [[nodiscard]] static RPCResult GetJsonHelp(const std::string& key, bool optional); + [[nodiscard]] UniValue ToJson(CDeterministicMNManager& dmnman, CQuorumSnapshotManager& qsnapman, + const ChainstateManager& chainman, int quorumIndex, int detailLevel) const; }; class CDKGDebugStatus @@ -90,8 +92,9 @@ class CDKGDebugStatus //std::map sessions; public: - UniValue ToJson(CDeterministicMNManager& dmnman, CQuorumSnapshotManager& qsnapman, - const ChainstateManager& chainman, int detailLevel) const; + [[nodiscard]] static RPCResult GetJsonHelp(const std::string& key, bool optional); + [[nodiscard]] UniValue ToJson(CDeterministicMNManager& dmnman, CQuorumSnapshotManager& qsnapman, + const ChainstateManager& chainman, int detailLevel) const; }; class CDKGDebugManager From 291b8f6f05086643a49e7fbcbd5b673b4efca02f Mon Sep 17 00:00:00 2001 From: Kittywhiskers Van Gogh <63189531+kwvg@users.noreply.github.com> Date: Fri, 12 Dec 2025 18:57:23 +0530 Subject: [PATCH 2/8] rpc: add help text for `quorum dkgstatus` --- src/rpc/quorums.cpp | 55 +++++++++++++++++++++------------------------ 1 file changed, 25 insertions(+), 30 deletions(-) diff --git a/src/rpc/quorums.cpp b/src/rpc/quorums.cpp index fbac23cd76dc..1371d8e8b5cf 100644 --- a/src/rpc/quorums.cpp +++ b/src/rpc/quorums.cpp @@ -294,6 +294,30 @@ static RPCHelpMan quorum_info() }; } +static RPCResult quorum_dkgstatus_help() +{ + auto ret = llmq::CDKGDebugStatus::GetJsonHelp(/*key=*/"", /*optional=*/false); + auto mod_inner = ret.m_inner; + mod_inner.push_back({RPCResult::Type::ARR, "quorumConnections", "Array of objects containing quorum connection information", { + {RPCResult::Type::OBJ, "", "", { + GetRpcResult("llmqType"), + GetRpcResult("quorumIndex"), + {RPCResult::Type::NUM, "pQuorumBaseBlockIndex", /*optional=*/true, "Height of the quorum’s base block"}, + GetRpcResult("quorumHash", /*optional=*/true), + {RPCResult::Type::NUM, "pindexTip", /*optional=*/true, "Height of the quorum index tip"}, + {RPCResult::Type::ARR, "quorumConnections", /*optional=*/true, "", { + {RPCResult::Type::OBJ, "", "", { + GetRpcResult("proTxHash"), + {RPCResult::Type::BOOL, "connected", "Returns true if connection is active"}, + {RPCResult::Type::STR, "address", /*optional=*/true, "IP address and port of the masternode"}, + {RPCResult::Type::BOOL, "outbound", /*optional=*/true, "Returns true if outbound connection"}, + }}}} + }}}}); + mod_inner.push_back({RPCResult::Type::ARR, "minableCommitments", "Array of objects containing minable commitments", { + llmq::CFinalCommitment::GetJsonHelp(/*key=*/"", /*optional=*/false)}}); + return RPCResult{ret.m_type, ret.m_key_name, ret.m_description, mod_inner}; +} + static RPCHelpMan quorum_dkgstatus() { return RPCHelpMan{"quorum dkgstatus", @@ -304,35 +328,7 @@ static RPCHelpMan quorum_dkgstatus() "Detail level of output.\n" "0=Only show counts. 1=Show member indexes. 2=Show member's ProTxHashes."}, }, - RPCResult{ - RPCResult::Type::OBJ, "", "", - { - {RPCResult::Type::NUM, "time", "Adjusted time for the last update, timestamp"}, - {RPCResult::Type::STR, "timeStr", "Adjusted time for the last update, human friendly"}, - {RPCResult::Type::ARR, "session", "", - { - {RPCResult::Type::OBJ, "", "", - { - {RPCResult::Type::NUM, "llmqType", "Name of quorum"}, - GetRpcResult("quorumIndex"), - {RPCResult::Type::OBJ, "status", "", - { - // TODO: list fields of output for RPC help instead ELISION - {RPCResult::Type::ELISION, "", ""}, - }}, - }}, - }, - }, - {RPCResult::Type::ARR, "quorumConnections", "", - // TODO: list fields of output for RPC help instead ELISION - {{RPCResult::Type::ELISION, "", ""}}, - }, - {RPCResult::Type::ARR, "minableCommitments", "", - // TODO: list fields of output for RPC help instead ELISION - {{RPCResult::Type::ELISION, "", ""}}, - }, - }, - }, + quorum_dkgstatus_help(), RPCExamples{""}, [&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue { @@ -417,7 +413,6 @@ static RPCHelpMan quorum_dkgstatus() std::optional> vfqc = llmq_ctx.quorum_block_processor->GetMineableCommitments(llmq_params, tipHeight); if (vfqc.has_value()) { for (const auto& fqc : vfqc.value()) { - // TODO: Use CFinalCommitment::GetJsonHelp() for fqc minableCommitments.push_back(fqc.ToJson()); } } From ae4057553827cc1814d08a9190942b754b64ed84 Mon Sep 17 00:00:00 2001 From: Kittywhiskers Van Gogh <63189531+kwvg@users.noreply.github.com> Date: Fri, 12 Dec 2025 03:11:18 +0530 Subject: [PATCH 3/8] rpc: add help text for `protx listdiff`, `masternode status` --- src/evo/core_write.cpp | 1 + src/rpc/coinjoin.cpp | 2 +- src/rpc/evo.cpp | 29 ++++------------------------- src/rpc/masternode.cpp | 12 +++++++++--- 4 files changed, 15 insertions(+), 29 deletions(-) diff --git a/src/evo/core_write.cpp b/src/evo/core_write.cpp index 05e50f0e9b9b..fad805299ff2 100644 --- a/src/evo/core_write.cpp +++ b/src/evo/core_write.cpp @@ -49,6 +49,7 @@ const std::map RPCRESULT_MAP{{ RESULT_MAP_ENTRY("merkleRootQuorums", RPCResult::Type::STR_HEX, "Merkle root of the quorum list"), RESULT_MAP_ENTRY("operatorPayoutAddress", RPCResult::Type::STR, "Dash address used for operator reward payments"), RESULT_MAP_ENTRY("operatorReward", RPCResult::Type::NUM, "Fraction in %% of reward shared with the operator between 0 and 10000"), + RESULT_MAP_ENTRY("outpoint", RPCResult::Type::STR_HEX,"The outpoint of the masternode"), RESULT_MAP_ENTRY("ownerAddress", RPCResult::Type::STR, "Dash address used for payee updates and proposal voting"), RESULT_MAP_ENTRY("payoutAddress", RPCResult::Type::STR, "Dash address used for masternode reward payments"), RESULT_MAP_ENTRY("platformHTTPPort", RPCResult::Type::NUM, "(DEPRECATED) TCP port of Platform HTTP API"), diff --git a/src/rpc/coinjoin.cpp b/src/rpc/coinjoin.cpp index d3dd399dd35d..7eead4884ad6 100644 --- a/src/rpc/coinjoin.cpp +++ b/src/rpc/coinjoin.cpp @@ -431,7 +431,7 @@ static RPCHelpMan getcoinjoininfo() {RPCResult::Type::OBJ, "", "", { {RPCResult::Type::STR_HEX, "protxhash", "The ProTxHash of the masternode"}, - {RPCResult::Type::STR_HEX, "outpoint", "The outpoint of the masternode"}, + GetRpcResult("outpoint"), {RPCResult::Type::STR, "service", "(DEPRECATED) The IP address and port of the masternode"}, {RPCResult::Type::ARR, "addrs_core_p2p", "Network addresses of the masternode used for protocol P2P", { diff --git a/src/rpc/evo.cpp b/src/rpc/evo.cpp index deee9ffe8a78..29790e1e1e2f 100644 --- a/src/rpc/evo.cpp +++ b/src/rpc/evo.cpp @@ -1657,31 +1657,12 @@ static RPCHelpMan protx_listdiff() {RPCResult::Type::NUM, "baseHeight", "Height of base (starting) block"}, {RPCResult::Type::NUM, "blockHeight", "Height of target (ending) block"}, {RPCResult::Type::ARR, "addedMNs", "Added masternodes", - { - {RPCResult::Type::OBJ, "", "", - { - // TODO: list fields of output for RPC help instead ELISION - {RPCResult::Type::ELISION, "", ""} - }}, - }, - }, + {CDeterministicMN::GetJsonHelp(/*key=*/"", /*optional=*/false)}}, {RPCResult::Type::ARR, "removedMns", "Removed masternodes", - { - {RPCResult::Type::STR_HEX, "protx", "ProTx of removed masternode"}, - }, - }, + {{RPCResult::Type::STR_HEX, "protx", "ProTx of removed masternode"}}}, {RPCResult::Type::ARR, "updatedMNs", "Updated masternodes", - { - {RPCResult::Type::OBJ, "", "", - { - {RPCResult::Type::OBJ, "protx", "ProTx of updated masternode", - { - // TODO: list fields of output for RPC help instead ELISION - {RPCResult::Type::ELISION, "", ""} - }}, - }}, - }, - }, + {{RPCResult::Type::OBJ, "", "", + {CDeterministicMNStateDiff::GetJsonHelp(/*key=*/"", /*optional=*/false)}}}}, }, }, RPCExamples{""}, @@ -1718,7 +1699,6 @@ static RPCHelpMan protx_listdiff() for(const auto& mn : mnDiff.addedMNs) { jaddedMNs.push_back(mn->ToJson()); } - // TODO: Use CDeterministicMN::GetJsonHelp() for mn ret.pushKV("addedMNs", jaddedMNs); UniValue jremovedMNs(UniValue::VARR); @@ -1741,7 +1721,6 @@ static RPCHelpMan protx_listdiff() obj.pushKV(dmn->proTxHash.ToString(), stateDiff.ToJson(dmn->nType)); jupdatedMNs.push_back(obj); } - // TODO: Use CDeterministicMNStateDiff::GetJsonHelp() for stateDiff ret.pushKV("updatedMNs", jupdatedMNs); return ret; diff --git a/src/rpc/masternode.cpp b/src/rpc/masternode.cpp index 7a8537da3356..cff1a6e44c3d 100644 --- a/src/rpc/masternode.cpp +++ b/src/rpc/masternode.cpp @@ -182,8 +182,15 @@ static RPCHelpMan masternode_status() RPCResult{ RPCResult::Type::OBJ, "", "", { - // TODO: implement proper type validator instead ELISION - {RPCResult::Type::ELISION, "", ""} + GetRpcResult("outpoint"), + GetRpcResult("service"), + GetRpcResult("proTxHash", /*optional=*/true), + {RPCResult::Type::STR, "type", /*optional=*/true, "Masternode type"}, + GetRpcResult("collateralHash", /*optional=*/true), + GetRpcResult("collateralIndex", /*optional=*/true), + CDeterministicMNState::GetJsonHelp(/*key=*/"dmnState", /*optional=*/true), + {RPCResult::Type::STR, "state", "Masternode state (human-readable string)"}, + {RPCResult::Type::STR, "status", "Masternode status (human-readable string, based on current state)"}, } }, RPCExamples{""}, @@ -205,7 +212,6 @@ static RPCHelpMan masternode_status() mnObj.pushKV("type", std::string(GetMnType(dmn->nType).description)); mnObj.pushKV("collateralHash", dmn->collateralOutpoint.hash.ToString()); mnObj.pushKV("collateralIndex", dmn->collateralOutpoint.n); - // TODO: Use CDeterministicMNState::GetJsonHelp() for dmnState mnObj.pushKV("dmnState", dmn->pdmnState->ToJson(dmn->nType)); } mnObj.pushKV("state", node.mn_activeman->GetStateString()); From 6063d79dee02caa7a9d7e4fb417a8b36504d7bc7 Mon Sep 17 00:00:00 2001 From: Kittywhiskers Van Gogh <63189531+kwvg@users.noreply.github.com> Date: Fri, 12 Dec 2025 18:48:21 +0530 Subject: [PATCH 4/8] rpc: add help text for `masternode list` --- src/core_io.h | 2 +- src/evo/core_write.cpp | 12 +++++++----- src/rpc/masternode.cpp | 36 +++++++++++++++++++++++++++++++----- 3 files changed, 39 insertions(+), 11 deletions(-) diff --git a/src/core_io.h b/src/core_io.h index 8dd365f95518..85deffd5c2fd 100644 --- a/src/core_io.h +++ b/src/core_io.h @@ -58,6 +58,6 @@ void ScriptToUniv(const CScript& script, UniValue& out, bool include_hex = true, void TxToUniv(const CTransaction& tx, const uint256& block_hash, UniValue& entry, bool include_hex = true, int serialize_flags = 0, const CTxUndo* txundo = nullptr, TxVerbosity verbosity = TxVerbosity::SHOW_DETAILS, const CSpentIndexTxInfo* ptxSpentInfo = nullptr); // evo/core_write.cpp -RPCResult GetRpcResult(const std::string& key, bool optional = false); +RPCResult GetRpcResult(const std::string& key, bool optional = false, const std::string& override_name = ""); #endif // BITCOIN_CORE_IO_H diff --git a/src/evo/core_write.cpp b/src/evo/core_write.cpp index fad805299ff2..b3e414d7c779 100644 --- a/src/evo/core_write.cpp +++ b/src/evo/core_write.cpp @@ -37,6 +37,7 @@ const std::map RPCRESULT_MAP{{ {RPCResult::Type::ARR, "platform_https", /*optional=*/true, "Addresses used for Platform HTTPS API", {{RPCResult::Type::STR, "address", ""}}}, }}}, + RESULT_MAP_ENTRY("collateralAddress", RPCResult::Type::STR, "Dash address used for collateral"), RESULT_MAP_ENTRY("collateralHash", RPCResult::Type::STR_HEX, "Collateral transaction hash"), RESULT_MAP_ENTRY("collateralIndex", RPCResult::Type::NUM, "Collateral transaction output index"), RESULT_MAP_ENTRY("consecutivePayments", RPCResult::Type::NUM, "Consecutive payments masternode has received in payment cycle"), @@ -67,17 +68,18 @@ const std::map RPCRESULT_MAP{{ RESULT_MAP_ENTRY("revocationReason", RPCResult::Type::NUM, "Reason for ProUpRegTx revocation"), RESULT_MAP_ENTRY("service", RPCResult::Type::STR, "(DEPRECATED) IP address and port of the masternode"), RESULT_MAP_ENTRY("type", RPCResult::Type::NUM, "Masternode type"), + RESULT_MAP_ENTRY("type_str", RPCResult::Type::STR, "Masternode type (human-readable string)"), RESULT_MAP_ENTRY("version", RPCResult::Type::NUM, "Special transaction version"), RESULT_MAP_ENTRY("votingAddress", RPCResult::Type::STR, "Dash address used for voting"), }}; #undef RESULT_MAP_ENTRY } // anonymous namespace -RPCResult GetRpcResult(const std::string& key, bool optional) +RPCResult GetRpcResult(const std::string& key, bool optional, const std::string& override_name) { if (const auto it = RPCRESULT_MAP.find(key); it != RPCRESULT_MAP.end()) { const auto& ret{it->second}; - return RPCResult{ret.m_type, ret.m_key_name, optional, ret.m_description, ret.m_inner}; + return RPCResult{ret.m_type, override_name.empty() ? ret.m_key_name : override_name, optional, ret.m_description, ret.m_inner}; } throw NonFatalCheckError(strprintf("Requested invalid RPCResult for nonexistent key \"%s\"", key).c_str(), __FILE__, __LINE__, __func__); @@ -180,11 +182,11 @@ RPCResult CDeterministicMN::GetJsonHelp(const std::string& key, bool optional) { return {RPCResult::Type::OBJ, key, optional, key.empty() ? "" : "The masternode's details", { - {RPCResult::Type::STR, "type", "Masternode type"}, + GetRpcResult("type_str", /*optional=*/false, /*override_name=*/"type"), GetRpcResult("proTxHash"), GetRpcResult("collateralHash"), GetRpcResult("collateralIndex"), - {RPCResult::Type::STR, "collateralAddress", /*optional=*/true, "Dash address used for collateral"}, + GetRpcResult("collateralAddress", /*optional=*/true), GetRpcResult("operatorReward"), CDeterministicMNState::GetJsonHelp(/*key=*/"state", /*optional=*/false), }}; @@ -503,7 +505,7 @@ RPCResult CSimplifiedMNListEntry::GetJsonHelp(const std::string& key, bool optio return {RPCResult::Type::OBJ, key, optional, key.empty() ? "" : "The simplified masternode list entry", { {RPCResult::Type::NUM, "nVersion", "Version of the entry"}, - {RPCResult::Type::NUM, "nType", "Masternode type"}, + GetRpcResult("type", /*optional=*/false, /*override_name=*/"nType"), {RPCResult::Type::STR_HEX, "proRegTxHash", "Hash of the ProRegTx identifying the masternode"}, {RPCResult::Type::STR_HEX, "confirmedHash", "Hash of the block where the masternode was confirmed"}, GetRpcResult("service"), diff --git a/src/rpc/masternode.cpp b/src/rpc/masternode.cpp index cff1a6e44c3d..f44228e23f38 100644 --- a/src/rpc/masternode.cpp +++ b/src/rpc/masternode.cpp @@ -185,7 +185,7 @@ static RPCHelpMan masternode_status() GetRpcResult("outpoint"), GetRpcResult("service"), GetRpcResult("proTxHash", /*optional=*/true), - {RPCResult::Type::STR, "type", /*optional=*/true, "Masternode type"}, + GetRpcResult("type_str", /*optional=*/true, /*override_name=*/"type"), GetRpcResult("collateralHash", /*optional=*/true), GetRpcResult("collateralIndex", /*optional=*/true), CDeterministicMNState::GetJsonHelp(/*key=*/"dmnState", /*optional=*/true), @@ -531,10 +531,36 @@ static RPCHelpMan masternodelist_helper(bool is_composite) {"filter", RPCArg::Type::STR, RPCArg::Default{""}, "Filter results. Partial match by outpoint by default in all modes, additional matches in some modes are also available"}, }, RPCResult{ - RPCResult::Type::OBJ, "", "", - { - // TODO: implement proper type validator instead ELISION - {RPCResult::Type::ELISION, "", ""} + RPCResult::Type::OBJ, "", "", { + RPCResult{"for mode = addr", RPCResult::Type::STR, "
", "Flattened list of all addresses registered to masternode"}, + RPCResult{"for mode = full", RPCResult::Type::STR, "", "Flattened list of a masternode's status, payee address, last paid block's timestamp, height and service addresses"}, + RPCResult{"for mode = info", RPCResult::Type::STR, "", "Flattened list of a masternode's status, payee address and service addresses"}, + RPCResult{"for mode = evo, json or recent", RPCResult::Type::OBJ, "", "", { + GetRpcResult("proTxHash"), + GetRpcResult("service", /*optional=*/false, /*override_name=*/"address"), + GetRpcResult("addresses"), + GetRpcResult("payoutAddress", /*optional=*/false, /*override_name=*/"payee"), + {RPCResult::Type::STR, "status", "Masternode status (human-readable string)"}, + GetRpcResult("type_str", /*optional=*/false, /*override_name=*/"type"), + GetRpcResult("platformNodeID", /*optional=*/true), + GetRpcResult("platformP2PPort", /*optional=*/true), + GetRpcResult("platformHTTPPort", /*optional=*/true), + GetRpcResult("PoSePenalty", /*optional=*/false, /*override_name=*/"pospenaltyscore"), + GetRpcResult("consecutivePayments"), + {RPCResult::Type::NUM, "lastpaidtime", "Timestamp of block the masternode was last paid"}, + GetRpcResult("lastPaidHeight", /*optional=*/false, /*override_name=*/"lastpaidblock"), + GetRpcResult("ownerAddress", /*optional=*/false, /*override_name=*/"owneraddress"), + GetRpcResult("votingAddress", /*optional=*/false, /*override_name=*/"votingaddress"), + GetRpcResult("collateralAddress", /*optional=*/false, /*override_name=*/"collateraladdress"), + GetRpcResult("pubKeyOperator", /*optional=*/false, /*override_name=*/"pubkeyoperator"), + }}, + RPCResult{"for mode = lastpaidblock", RPCResult::Type::NUM, "", "Height masternode was last paid"}, + RPCResult{"for mode = lastpaidtime", RPCResult::Type::NUM, "