Inside Bitcoin
Opening the selected file…
Inside Bitcoin
Opening the selected file…
The code behind the network, with room to understand it.
Release published 2026-10-28 · Snapshot fetched 2026-11-01. Latest stable release at fetch time; development branches and Git history are excluded. Only the selected code window and visible folders load here.
251std::string description,252std::vector<RPCArg> inner,253RPCArgOptions opts = {})254: m_names{std::move(name)},255m_type{type},256m_inner{std::move(inner)},257m_fallback{std::move(fallback)},258m_description{std::move(description)},259m_opts{std::move(opts)}260{261CHECK_NONFATAL(type == Type::ARR || type == Type::OBJ || type == Type::OBJ_NAMED_PARAMS || type == Type::OBJ_USER_KEYS);262}264bool IsOptional() const;266/**267* Check whether the request JSON type matches.268* Returns true if type matches, or object describing error(s) if not.269*/270UniValue MatchesType(const UniValue& request) const;272/** Return the first of all aliases */273std::string GetFirstName() const;275/** Return the name, throws when there are aliases */276std::string GetName() const;278/**279* Return the type string of the argument.280* Set oneline to allow it to be overridden by a custom oneline type string (m_opts.oneline_description).281*/282std::string ToString(bool oneline) const;283/**284* Return the type string of the argument when it is in an object (dict).285* Set oneline to get the oneline representation (less whitespace)286*/287std::string ToStringObj(bool oneline) const;288/**289* Return the description string, including the argument type and whether290* the argument is required.291*/292std::string ToDescriptionString(bool is_named_arg) const;293};295/// Controls how an RPCResult is rendered in human-readable help text.296/// The std::string alternative carries the summary text rendered as "...".297struct HelpElisionNone {}; //!< field printed normally298struct HelpElisionSkip {}; //!< field hidden from help299using HelpElision = std::variant<HelpElisionNone, HelpElisionSkip, std::string>;301struct RPCResultOptions {302bool skip_type_check{false};303HelpElision print_elision{HelpElisionNone{}};304};306// NOLINTNEXTLINE(misc-no-recursion)307struct RPCResult {308enum class Type {309OBJ,310ARR,311STR,312NUM,313BOOL,314NONE,315ANY, //!< Special type to disable type checks316STR_AMOUNT, //!< Special string to represent a floating point amount317STR_HEX, //!< Special string with only hex chars318OBJ_DYN, //!< Special dictionary with keys that are not literals319ARR_FIXED, //!< Special array that has a fixed number of entries320NUM_TIME, //!< Special numeric to denote unix epoch time321};323const Type m_type;324const std::string m_key_name; //!< Only used for dicts325const std::vector<RPCResult> m_inner; //!< Only used for arrays or dicts326const bool m_optional;327const RPCResultOptions m_opts;328const std::string m_description;329const std::string m_cond;331RPCResult(332std::string cond,333Type type,334std::string m_key_name,335bool optional,336std::string description,337std::vector<RPCResult> inner = {},338RPCResultOptions opts = {})339: m_type{type},340m_key_name{std::move(m_key_name)},341m_inner{std::move(inner)},342m_optional{optional},343m_opts{std::move(opts)},344m_description{std::move(description)},345m_cond{std::move(cond)}346{347CHECK_NONFATAL(!m_cond.empty());348CheckInnerDoc();349}351RPCResult(352std::string cond,353Type type,354std::string m_key_name,355std::string description,356std::vector<RPCResult> inner = {},357RPCResultOptions opts = {})358: RPCResult{std::move(cond), type, std::move(m_key_name), /*optional=*/false, std::move(description), std::move(inner), std::move(opts)} {}360RPCResult(361Type type,362std::string m_key_name,363bool optional,364std::string description,365std::vector<RPCResult> inner = {},366RPCResultOptions opts = {})367: m_type{type},368m_key_name{std::move(m_key_name)},369m_inner{std::move(inner)},370m_optional{optional},371m_opts{std::move(opts)},372m_description{std::move(description)},373m_cond{}374{375CheckInnerDoc();376}378RPCResult(379Type type,380std::string m_key_name,381std::string description,382std::vector<RPCResult> inner = {},383RPCResultOptions opts = {})384: RPCResult{type, std::move(m_key_name), /*optional=*/false, std::move(description), std::move(inner), std::move(opts)} {}386/// Copy with replacement options, for stamping new opts onto an existing result.387RPCResult(const RPCResult& other, RPCResultOptions opts)388: m_type{other.m_type},389m_key_name{other.m_key_name},390m_inner{other.m_inner},391m_optional{other.m_optional},392m_opts{std::move(opts)},393m_description{other.m_description},394m_cond{other.m_cond} {}396/** Append the sections of the result. */397void ToSections(Sections& sections, OuterType outer_type = OuterType::NONE, int current_indent = 0) const;398/** Return the type string of the result when it is in an object (dict). */399std::string ToStringObj() const;400/** Return the description string, including the result type. */401std::string ToDescriptionString() const;402/** Check whether the result JSON type matches.403* Returns true if type matches, or object describing error(s) if not.404*/405UniValue MatchesType(const UniValue& result) const;407private:408void CheckInnerDoc() const;409};411/// Stamp elision onto an entire vector of RPCResult fields at once.412/// Merges into existing m_opts so that flags like skip_type_check are preserved.413std::vector<RPCResult> ElideGroup(std::vector<RPCResult> fields, std::string summary = "");415struct RPCResults {416const std::vector<RPCResult> m_results;418RPCResults(RPCResult result)419: m_results{{result}}420{421}423RPCResults(std::initializer_list<RPCResult> results)424: m_results{results}425{426}428/**429* Return the description string.430*/431std::string ToDescriptionString() const;432};434struct RPCExamples {435const std::string m_examples;436explicit RPCExamples(437std::string examples)438: m_examples(std::move(examples))439{440}441std::string ToDescriptionString() const;442};444class RPCMethod445{446public:447RPCMethod(std::string name, std::string description, std::vector<RPCArg> args, RPCResults results, RPCExamples examples);448using RPCMethodImpl = std::function<UniValue(const RPCMethod&, const JSONRPCRequest&)>;449RPCMethod(std::string name, std::string description, std::vector<RPCArg> args, RPCResults results, RPCExamples examples, RPCMethodImpl fun);451UniValue HandleRequest(const JSONRPCRequest& request) const;452/**453* @brief Helper to get a required or default-valued request argument.454*455* Use this function when the argument is required or when it has a default value. If the456* argument is optional and may not be provided, use MaybeArg instead.457*458* This function only works during m_fun(), i.e., it should only be used in459* RPC method implementations. It internally checks whether the user-passed460* argument isNull() and parses (from JSON) and returns the user-passed argument,461* or the default value derived from the RPCArg documentation.462*463* The instantiation of this helper for type R must match the corresponding RPCArg::Type.464*465* @return The value of the RPC argument (or the default value) cast to type R.466*467* @see MaybeArg for handling optional arguments without default values.468*/469template <typename R>470auto Arg(std::string_view key) const471{472auto i{GetParamIndex(key)};473// Return argument (required or with default value).474if constexpr (std::is_trivially_copyable_v<R>) {475// Return trivially copyable types by value.476return ArgValue<R>(i);477} else {478// Return everything else by reference.479return ArgValue<const R&>(i);480}481}482/**483* @brief Helper to get an optional request argument.484*485* Use this function when the argument is optional and does not have a default value. If the486* argument is required or has a default value, use Arg instead.487*488* This function only works during m_fun(), i.e., it should only be used in489* RPC method implementations. It internally checks whether the user-passed490* argument isNull() and parses (from JSON) and returns the user-passed argument,491* or a falsy value if no argument was passed.492*493* The instantiation of this helper for type R must match the corresponding RPCArg::Type.494*495* @return For trivially copyable types, a std::optional<R> is returned.496* For other types, a R* pointer to the argument is returned. If the497* argument is not provided, std::nullopt or a null pointer is returned.498*499* @see Arg for handling arguments that are required or have a default value.500*/