Merge bitcoin/bitcoin#24155: doc: Fix rpc docs

fac8caaa62 doc: Fix rpc docs (MarcoFalke)

Pull request description:

  Broken in commit 39d9bbe4ac.

  The fix removes the "type" `OBJ_EMPTY` added in commit 8d1a3e6498, which isn't really a separate type and instead runs a check on `OBJ` whether it is empty or not.

ACKs for top commit:
  Sjors:
    tACK fac8caaa62

Tree-SHA512: dd978fe526a45095800249204afd26a239078e83b15124a5756ac078c473a677a3084b8f54e34d6dd5580abef7275c875a14bc9eb20d8feab066dfb0f0932967
This commit is contained in:
fanquake 2022-01-26 21:19:24 +08:00
commit e3699b71c4
No known key found for this signature in database
GPG key ID: 2EEB9F5CC09526C1
3 changed files with 22 additions and 13 deletions

View file

@ -790,7 +790,7 @@ static RPCHelpMan getblockfrompeer()
{ {
return RPCHelpMan{ return RPCHelpMan{
"getblockfrompeer", "getblockfrompeer",
"\nAttempt to fetch block from a given peer.\n" "Attempt to fetch block from a given peer.\n"
"\nWe must have the header for this block, e.g. using submitheader.\n" "\nWe must have the header for this block, e.g. using submitheader.\n"
"Subsequent calls for the same block and a new peer will cause the response from the previous peer to be ignored.\n" "Subsequent calls for the same block and a new peer will cause the response from the previous peer to be ignored.\n"
"\nReturns an empty JSON object if the request was successfully scheduled.", "\nReturns an empty JSON object if the request was successfully scheduled.",
@ -798,7 +798,7 @@ static RPCHelpMan getblockfrompeer()
{"block_hash", RPCArg::Type::STR_HEX, RPCArg::Optional::NO, "The block hash to try to fetch"}, {"block_hash", RPCArg::Type::STR_HEX, RPCArg::Optional::NO, "The block hash to try to fetch"},
{"peer_id", RPCArg::Type::NUM, RPCArg::Optional::NO, "The peer to fetch it from (see getpeerinfo for peer IDs)"}, {"peer_id", RPCArg::Type::NUM, RPCArg::Optional::NO, "The peer to fetch it from (see getpeerinfo for peer IDs)"},
}, },
RPCResult{RPCResult::Type::OBJ_EMPTY, "", /*optional=*/ false, "", {}}, RPCResult{RPCResult::Type::OBJ, "", /*optional=*/false, "", {}},
RPCExamples{ RPCExamples{
HelpExampleCli("getblockfrompeer", "\"00000000c937983704a73af28acdec37b049d214adbda81d7e2a3dd146f6ed09\" 0") HelpExampleCli("getblockfrompeer", "\"00000000c937983704a73af28acdec37b049d214adbda81d7e2a3dd146f6ed09\" 0")
+ HelpExampleRpc("getblockfrompeer", "\"00000000c937983704a73af28acdec37b049d214adbda81d7e2a3dd146f6ed09\" 0") + HelpExampleRpc("getblockfrompeer", "\"00000000c937983704a73af28acdec37b049d214adbda81d7e2a3dd146f6ed09\" 0")

View file

@ -830,16 +830,15 @@ void RPCResult::ToSections(Sections& sections, const OuterType outer_type, const
return; return;
} }
case Type::OBJ_DYN: case Type::OBJ_DYN:
case Type::OBJ_EMPTY: {
sections.PushSection({indent + maybe_key + "{}", Description("empty JSON object")});
return;
}
case Type::OBJ: { case Type::OBJ: {
if (m_inner.empty()) {
sections.PushSection({indent + maybe_key + "{}", Description("empty JSON object")});
return;
}
sections.PushSection({indent + maybe_key + "{", Description("json object")}); sections.PushSection({indent + maybe_key + "{", Description("json object")});
for (const auto& i : m_inner) { for (const auto& i : m_inner) {
i.ToSections(sections, OuterType::OBJ, current_indent + 2); i.ToSections(sections, OuterType::OBJ, current_indent + 2);
} }
CHECK_NONFATAL(!m_inner.empty());
if (m_type == Type::OBJ_DYN && m_inner.back().m_type != Type::ELISION) { if (m_type == Type::OBJ_DYN && m_inner.back().m_type != Type::ELISION) {
// If the dictionary keys are dynamic, use three dots for continuation // If the dictionary keys are dynamic, use three dots for continuation
sections.PushSection({indent_next + "...", ""}); sections.PushSection({indent_next + "...", ""});
@ -883,7 +882,6 @@ bool RPCResult::MatchesType(const UniValue& result) const
return UniValue::VARR == result.getType(); return UniValue::VARR == result.getType();
} }
case Type::OBJ_DYN: case Type::OBJ_DYN:
case Type::OBJ_EMPTY:
case Type::OBJ: { case Type::OBJ: {
return UniValue::VOBJ == result.getType(); return UniValue::VOBJ == result.getType();
} }
@ -891,6 +889,17 @@ bool RPCResult::MatchesType(const UniValue& result) const
CHECK_NONFATAL(false); CHECK_NONFATAL(false);
} }
void RPCResult::CheckInnerDoc() const
{
if (m_type == Type::OBJ) {
// May or may not be empty
return;
}
// Everything else must either be empty or not
const bool inner_needed{m_type == Type::ARR || m_type == Type::ARR_FIXED || m_type == Type::OBJ_DYN};
CHECK_NONFATAL(inner_needed != m_inner.empty());
}
std::string RPCArg::ToStringObj(const bool oneline) const std::string RPCArg::ToStringObj(const bool oneline) const
{ {
std::string res; std::string res;

View file

@ -240,7 +240,6 @@ struct RPCResult {
STR_AMOUNT, //!< Special string to represent a floating point amount STR_AMOUNT, //!< Special string to represent a floating point amount
STR_HEX, //!< Special string with only hex chars STR_HEX, //!< Special string with only hex chars
OBJ_DYN, //!< Special dictionary with keys that are not literals OBJ_DYN, //!< Special dictionary with keys that are not literals
OBJ_EMPTY, //!< Special type to allow empty OBJ
ARR_FIXED, //!< Special array that has a fixed number of entries ARR_FIXED, //!< Special array that has a fixed number of entries
NUM_TIME, //!< Special numeric to denote unix epoch time NUM_TIME, //!< Special numeric to denote unix epoch time
ELISION, //!< Special type to denote elision (...) ELISION, //!< Special type to denote elision (...)
@ -268,8 +267,7 @@ struct RPCResult {
m_cond{std::move(cond)} m_cond{std::move(cond)}
{ {
CHECK_NONFATAL(!m_cond.empty()); CHECK_NONFATAL(!m_cond.empty());
const bool inner_needed{type == Type::ARR || type == Type::ARR_FIXED || type == Type::OBJ || type == Type::OBJ_DYN}; CheckInnerDoc();
CHECK_NONFATAL(inner_needed != inner.empty());
} }
RPCResult( RPCResult(
@ -293,8 +291,7 @@ struct RPCResult {
m_description{std::move(description)}, m_description{std::move(description)},
m_cond{} m_cond{}
{ {
const bool inner_needed{type == Type::ARR || type == Type::ARR_FIXED || type == Type::OBJ || type == Type::OBJ_DYN}; CheckInnerDoc();
CHECK_NONFATAL(inner_needed != inner.empty());
} }
RPCResult( RPCResult(
@ -312,6 +309,9 @@ struct RPCResult {
std::string ToDescriptionString() const; std::string ToDescriptionString() const;
/** Check whether the result JSON type matches. */ /** Check whether the result JSON type matches. */
bool MatchesType(const UniValue& result) const; bool MatchesType(const UniValue& result) const;
private:
void CheckInnerDoc() const;
}; };
struct RPCResults { struct RPCResults {