Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 4 additions & 3 deletions src/evo/core_write.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -275,9 +275,10 @@ UniValue CDeterministicMNState::ToJson(MnType nType) const
// CDeterministicMNStateDiff::ToJson() defined in evo/dmnstate.cpp
RPCResult CDeterministicMNStateDiff::GetJsonHelp(const std::string& key, bool optional)
{
// Every field is emitted only when the diff actually carries it, version included.
return {RPCResult::Type::OBJ, key, optional, key.empty() ? "" : "The masternode state diff",
{
{RPCResult::Type::NUM, "version", "Version of the masternode state diff"},
{RPCResult::Type::NUM, "version", /*optional=*/true, "Version of the masternode state diff"},
GetRpcResult("service", /*optional=*/true),
GetRpcResult("registeredHeight", /*optional=*/true),
GetRpcResult("lastPaidHeight", /*optional=*/true),
Expand Down Expand Up @@ -468,8 +469,8 @@ RPCResult CSimplifiedMNListDiff::GetJsonHelp(const std::string& key, bool option
GetRpcResult("merkleRootMNList", /*optional=*/true),
GetRpcResult("merkleRootQuorums", /*optional=*/true),
{RPCResult::Type::ARR, "quorumsCLSigs", "ChainLock signature details", {
{RPCResult::Type::OBJ, "", "", {
{RPCResult::Type::ARR, "<sig_hex>", "Array of quorum indices, keyed by BLS signature", {
{RPCResult::Type::OBJ_DYN, "", "json object with the BLS signature as key", {
{RPCResult::Type::ARR, "<sig_hex>", "Array of quorum indices signed by this BLS signature", {
{RPCResult::Type::NUM, "", "Quorum index"}
}}}}}},
}};
Expand Down
19 changes: 11 additions & 8 deletions src/governance/core_write.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -119,20 +119,23 @@ RPCResult Object::GetJsonHelp(const std::string& key, bool optional)
GetRpcResult("collateralHash"),
{RPCResult::Type::NUM, "createdAt", "Proposal creation timestamp"},
{RPCResult::Type::NUM, "revision", "Proposal revision number"},
// Everything but "hex" is the submitter's own JSON echoed back verbatim, so neither the
// set of keys nor their types is ours to promise: a proposal may carry extra fields and
// may encode the numeric ones as strings. Hence the type check is skipped here.
{RPCResult::Type::OBJ, "data", "", {
// Fields emitted through GetDataAsPlainString(), read by CProposalValidator
{RPCResult::Type::STR, "end_epoch", /*optional=*/true, "Proposal end timestamp"},
{RPCResult::Type::STR, "name", /*optional=*/true, "Proposal name"},
{RPCResult::Type::STR, "payment_address", /*optional=*/true, "Proposal payment address"},
{RPCResult::Type::STR, "payment_amount", /*optional=*/true, "Proposal payment amount"},
{RPCResult::Type::STR, "start_epoch", /*optional=*/true, "Proposal start timestamp"},
{RPCResult::Type::STR, "type", /*optional=*/true, "Object type"},
{RPCResult::Type::STR, "url", /*optional=*/true, "Proposal URL"},
{RPCResult::Type::ANY, "end_epoch", /*optional=*/true, "Proposal end timestamp"},
{RPCResult::Type::ANY, "name", /*optional=*/true, "Proposal name"},
{RPCResult::Type::ANY, "payment_address", /*optional=*/true, "Proposal payment address"},
{RPCResult::Type::ANY, "payment_amount", /*optional=*/true, "Proposal payment amount"},
{RPCResult::Type::ANY, "start_epoch", /*optional=*/true, "Proposal start timestamp"},
{RPCResult::Type::ANY, "type", /*optional=*/true, "Object type"},
{RPCResult::Type::ANY, "url", /*optional=*/true, "Proposal URL"},
// Failure case for GetDataAsPlainString()
{RPCResult::Type::STR, "plain", /*optional=*/true, "Governance object data as string"},
// Always emitted by ToJson()
{RPCResult::Type::STR_HEX, "hex", "Governance object data as hex"},
}},
}, /*skip_type_check=*/true},
Comment thread
coderabbitai[bot] marked this conversation as resolved.
}};
}

Expand Down
88 changes: 32 additions & 56 deletions src/llmq/core_write.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -19,61 +19,37 @@ 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",
// A member tally is a count for detail_level = 0, an array of member indexes for
// detail_level = 1, and an array of {memberIndex, proTxHash} objects for
// detail_level = 2. RPCResult can only express such a union as ANY: conditional
// variants are only resolved for top-level results, so listing one variant per
// detail level here would make every level fail the runtime doc check.
const auto member_tally{[](const std::string& name, const std::string& what) {
return RPCResult{RPCResult::Type::ANY, name,
strprintf("Number of %s (detail_level = 0), array of quorum member indexes "
"(detail_level = 1), or array of {memberIndex, proTxHash} objects "
"(detail_level = 2)",
what)};
Comment thread
knst marked this conversation as resolved.
}};
return {RPCResult::Type::OBJ, key, optional, key.empty() ? "" : "The state of a DKG session. Empty for an unknown LLMQ type or quorum hash",
{
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")}}},
GetRpcResult("llmqType", /*optional=*/true),
GetRpcResult("quorumHash", /*optional=*/true),
{RPCResult::Type::NUM, "quorumHeight", /*optional=*/true, "Block height of the quorum"},
{RPCResult::Type::NUM, "phase", /*optional=*/true, "Active DKG phase"},
{RPCResult::Type::BOOL, "sentContributions", /*optional=*/true, "Returns true if contributions sent"},
{RPCResult::Type::BOOL, "sentComplaint", /*optional=*/true, "Returns true if complaints sent"},
{RPCResult::Type::BOOL, "sentJustification", /*optional=*/true, "Returns true if justifications sent"},
{RPCResult::Type::BOOL, "sentPrematureCommitment", /*optional=*/true, "Returns true if premature commitments sent"},
{RPCResult::Type::BOOL, "aborted", /*optional=*/true, "Returns true if DKG session aborted"},
member_tally("badMembers", "bad members"),
member_tally("weComplain", "complaints sent"),
member_tally("receivedContributions", "contributions received"),
member_tally("receivedComplaints", "complaints received"),
member_tally("receivedJustifications", "justifications received"),
member_tally("receivedPrematureCommitments", "premature commitments received"),
{RPCResult::Type::ARR, "allMembers", /*optional=*/true, "Provider registration transaction hash for all quorum members. Only present for detail_level = 2", {
GetRpcResult("proTxHash")}},
}};
Comment thread
coderabbitai[bot] marked this conversation as resolved.
}

Expand All @@ -86,7 +62,7 @@ RPCResult CDKGDebugManager::GetJsonHelp(const std::string& key, bool optional, b
{RPCResult::Type::STR, "timeStr", inner_optional, "Adjusted time for the last update, human friendly"},
{RPCResult::Type::ARR, "session", inner_optional, "", {
{RPCResult::Type::OBJ, "", "", {
{RPCResult::Type::NUM, "llmqType", "Name of quorum"},
{RPCResult::Type::STR, "llmqType", "Name of quorum"},
GetRpcResult("quorumIndex"),
CDKGDebugSessionStatus::GetJsonHelp(/*key=*/"status", /*optional=*/false)
}},
Expand Down Expand Up @@ -258,7 +234,7 @@ RPCResult CRecoveredSig::GetJsonHelp(const std::string& key, bool optional)
{
GetRpcResult("llmqType"),
GetRpcResult("quorumHash"),
{RPCResult::Type::NUM, "id", "Signing session ID"},
{RPCResult::Type::STR_HEX, "id", "Signing session ID"},
{RPCResult::Type::STR_HEX, "msgHash", "Hash of message"},
{RPCResult::Type::STR_HEX, "sig", "BLS signature recovered"},
{RPCResult::Type::STR_HEX, "hash", "Hash of the BLS signature recovered"},
Expand Down
2 changes: 1 addition & 1 deletion src/rpc/blockchain.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -255,7 +255,7 @@ static RPCHelpMan getbestchainlock()
RPCResult{
RPCResult::Type::OBJ, "", "",
{
{RPCResult::Type::STR_HEX, "hash", "The block hash hex-encoded"},
{RPCResult::Type::STR_HEX, "blockhash", "The block hash hex-encoded"},
{RPCResult::Type::NUM, "height", "The block height or index"},
{RPCResult::Type::STR_HEX, "signature", "The ChainLock's BLS signature"},
{RPCResult::Type::BOOL, "known_block", "True if the block is known by our node"},
Expand Down
16 changes: 8 additions & 8 deletions src/rpc/coinjoin.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -427,17 +427,17 @@ static RPCHelpMan getcoinjoininfo()
{RPCResult::Type::NUM, "max_amount", "Target CoinJoin balance in " + CURRENCY_UNIT + ""},
{RPCResult::Type::NUM, "denoms_goal", "How many inputs of each denominated amount to target"},
{RPCResult::Type::NUM, "denoms_hardcap", "Maximum limit of how many inputs of each denominated amount to create"},
{RPCResult::Type::NUM, "queue_size", "How many queues there are currently on the network"},
{RPCResult::Type::BOOL, "running", "Whether mixing is currently running"},
{RPCResult::Type::NUM, "queue_size", /*optional=*/true, "How many queues there are currently on the network"},
{RPCResult::Type::BOOL, "running", /*optional=*/true, "Whether mixing is currently running (not returned when no wallet is loaded)"},
{RPCResult::Type::NUM, "pending_inputs", "The number of successfully mixed inputs kept locked until the transaction spending them is observed"},
Comment on lines +431 to 432

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Mark pending_inputs optional for no-wallet CoinJoin info

When getcoinjoininfo runs on a regular node without a selected/loaded wallet, the handler returns at src/rpc/coinjoin.cpp:485-487 before CCoinJoinClientManager::getJsonInfo() adds pending_inputs, but this result entry is still required while the neighboring wallet-only fields were made optional. With -rpcdoccheck, that no-wallet/reduced-functionality path still fails the new result matcher instead of returning the CoinJoin options object; make pending_inputs optional or document a separate no-wallet result shape.

Useful? React with 👍 / 👎.

{RPCResult::Type::ARR, "sessions", "",
{RPCResult::Type::ARR, "sessions", /*optional=*/true, "Not returned when no wallet is loaded",
{
{RPCResult::Type::OBJ, "", "",
{
{RPCResult::Type::STR_HEX, "protxhash", "The ProTxHash of the masternode"},
GetRpcResult("outpoint"),
{RPCResult::Type::STR, "service", "The IP address and port of the masternode (DEPRECATED, returned only if config option -deprecatedrpc=service is passed)"},
{RPCResult::Type::ARR, "addrs_core_p2p", "Network addresses of the masternode used for protocol P2P",
{RPCResult::Type::STR_HEX, "protxhash", /*optional=*/true, "The ProTxHash of the masternode (only while connected to one)"},
GetRpcResult("outpoint", /*optional=*/true),
{RPCResult::Type::STR, "service", /*optional=*/true, "The IP address and port of the masternode (DEPRECATED, returned only if config option -deprecatedrpc=service is passed)"},
{RPCResult::Type::ARR, "addrs_core_p2p", /*optional=*/true, "Network addresses of the masternode used for protocol P2P",
{
{RPCResult::Type::STR, "address", ""},
}
Expand All @@ -448,7 +448,7 @@ static RPCHelpMan getcoinjoininfo()
}},
}},
{RPCResult::Type::NUM, "keys_left", /*optional=*/true, "How many new keys are left since last automatic backup (if applicable)"},
{RPCResult::Type::STR, "warnings", "Warnings if any"},
{RPCResult::Type::STR, "warnings", /*optional=*/true, "Warnings if any (not returned when no wallet is loaded)"},
}},
RPCResult{"for masternodes",
RPCResult::Type::OBJ, "", "",
Expand Down
17 changes: 8 additions & 9 deletions src/rpc/evo.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1513,12 +1513,11 @@ static RPCHelpMan protx_list()
RPCResult{
RPCResult::Type::ARR, "", "List of masternodes",
{
RPCResult{"when detailed=false", RPCResult::Type::STR, "", "ProTx hash"},
RPCResult{"when detailed=true", RPCResult::Type::OBJ, "", "",
{
// TODO: document fields of the detailed entry
{RPCResult::Type::ELISION, "", ""}
}},
// Array elements are matched against this doc by index, so the two shapes
// cannot be listed as alternatives here - the first entry would be applied
// to element 0 only and the second to every element after it.
// TODO: document fields of the detailed entry
{RPCResult::Type::ANY, "", "The ProTx hash when detailed=false, otherwise an object describing the masternode"},

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Render nested ANY results before using them in help

When users request help for protx list, this nested RPCResult::Type::ANY is still rendered by RPCResult::ToSections(), whose ANY case calls NONFATAL_UNREACHABLE(); RPCResults::ToDescriptionString() only skips top-level ANY results. This pattern is repeated by the other new nested ANY entries, so those command help paths return an internal-bug error instead of help text. Teach ToSections() how to print ANY, or avoid using it in public nested result docs.

Useful? React with 👍 / 👎.

}},
Comment thread
coderabbitai[bot] marked this conversation as resolved.
RPCExamples{""},
[&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue
Expand Down Expand Up @@ -1772,11 +1771,11 @@ static RPCHelpMan protx_listdiff()
{RPCResult::Type::NUM, "blockHeight", "Height of target (ending) block"},
{RPCResult::Type::ARR, "addedMNs", "Added masternodes",
{CDeterministicMN::GetJsonHelp(/*key=*/"", /*optional=*/false)}},
{RPCResult::Type::ARR, "removedMns", "Removed masternodes",
{RPCResult::Type::ARR, "removedMNs", "Removed masternodes",
{{RPCResult::Type::STR_HEX, "protx", "ProTx of removed masternode"}}},
{RPCResult::Type::ARR, "updatedMNs", "Updated masternodes",
{{RPCResult::Type::OBJ, "<protx_hash>", "",
{CDeterministicMNStateDiff::GetJsonHelp(/*key=*/"", /*optional=*/false)}}}},
{{RPCResult::Type::OBJ_DYN, "", "json object with ProTx hash as keys",
{CDeterministicMNStateDiff::GetJsonHelp(/*key=*/"<protx_hash>", /*optional=*/false)}}}},
},
},
RPCExamples{""},
Expand Down
Loading
Loading