diff --git a/docs/daemon-rpc/core_rpc_server_commands_defs.h b/docs/daemon-rpc/core_rpc_server_commands_defs.h new file mode 120000 index 000000000..7d9b000d2 --- /dev/null +++ b/docs/daemon-rpc/core_rpc_server_commands_defs.h @@ -0,0 +1 @@ +../../src/rpc/core_rpc_server_commands_defs.h \ No newline at end of file diff --git a/docs/daemon-rpc/make-docs.sh b/docs/daemon-rpc/make-docs.sh new file mode 100755 index 000000000..a02402a36 --- /dev/null +++ b/docs/daemon-rpc/make-docs.sh @@ -0,0 +1,58 @@ +#!/bin/bash + +set -e + +if [ "$(basename $(pwd))" != "daemon-rpc" ]; then + echo "Error: you must run this from the docs/daemon-rpc directory" >&2 + exit 1 +fi + +rm -rf api + +docsify init --local api + +rm -f api/README.md + +if [ -n "$NPM_PACKAGES" ]; then + npm_dir="$NPM_PACKAGES/lib/node_modules" +elif [ -n "$NODE_PATH" ]; then + npm_dir="$NODE_PATH" +elif [ -d "$HOME/node_modules" ]; then + npm_dir="$HOME/node_modules" +elif [ -d "/usr/local/lib/node_modules" ]; then + npm_dir="/usr/local/lib/node_modules" +else + echo "Can't determine your node_modules path; set NPM_PACKAGES or NODE_PATH appropriately" >&2 + exit 1 +fi + +cp $npm_dir/docsify/node_modules/prismjs/components/prism-{json,python}.min.js api/vendor + +./rpc-to-markdown.py core_rpc_server_commands_defs.h "$@" + +perl -ni.bak -e ' +BEGIN { $first = 0; } +if (m{^\s*\s*$}) { + if (not $first) { + $first = false; + print qq{ + \n}; + } +} else { + s{.*}{Oxen Daemon RPC}; + s{(name="description" content=)"[^"]*"}{$1"Oxen Daemon RPC endpoint documentation"}; + if (m{^\s*}) { + print qq{ + + \n}; + } + print; +}' api/index.html diff --git a/docs/daemon-rpc/rpc-to-markdown.py b/docs/daemon-rpc/rpc-to-markdown.py new file mode 100755 index 000000000..c397d4a34 --- /dev/null +++ b/docs/daemon-rpc/rpc-to-markdown.py @@ -0,0 +1,376 @@ +#!/usr/bin/env python3 + +import sys +import os +import shutil +import re +import fileinput +from enum import Enum, auto +import json +import requests +import argparse + +parser = argparse.ArgumentParser() +parser.add_argument( + "-L", + "--markdown-level", + type=int, + choices=[1, 2, 3, 4], + default=2, + help="Specify a heading level for the top-level endpoints; the default is 2, which means " + "endpoints start in a `## name` section. For example, 3 would start endpoints with `### name` " + "instead.", +) +parser.add_argument("--out", "-o", metavar='DIR', default="api", help="Output directory for generated endpoints") +parser.add_argument("--disable-public", action='store_true', help="disable PUBLIC endpoint detection (and disable marking endpoints as requiring admin)") +parser.add_argument("--disable-no-args", action='store_true', help="disable NO_ARGS enforcement of `Inputs: none`") +parser.add_argument("--dev", action='store_true', help="generate dev mode docs, which include endpoints marked 'Dev-RPC'") +parser.add_argument("--no-sort", "-S", action='store_true', help="disable sorting endpoints by name (use file order)") +parser.add_argument("--no-group", "-G", action='store_true', help="disable grouping endpoints by category") +parser.add_argument("--no-emdash", "-M", action='store_true', help="disable converting ' -- ' to ' — ' (em-dashes)") +parser.add_argument("--rpc", metavar='URL', default="http://public-na.optf.ngo:22023", help="URL to a running oxend RPC node for live example fetching") +parser.add_argument("filename", nargs="+") +args = parser.parse_args() + +for f in args.filename: + if not os.path.exists(f): + parser.error(f"{f} does not exist!") + + +# We parse the file looking for `///` comment blocks beginning with "RPC: /". +# +# is the RPC endpoint name to use in the documentation (alternative names can be specified +# using "Old names:"; see below). +# +# is the category for grouping endpoints together. +# +# Following comment lines are then a Markdown long description, until we find one or more of: +# +# "Inputs: none." +# "Outputs: none." +# "Inputs:" followed by markdown (typically an unordered list) until the next match from this list. +# "Outputs:" followed by markdown +# "Example input:" followed by a code block (i.e. containing json) +# "Example output:" followed by a code block (i.e. json output) +# "Example-JSON-Fetch" goes and fetches the endpoint (live) with the previous example input as the +# "params" value (or no params if "Inputs: none"). +# "Old names: a, b, c" +# +# subject to the following rules: +# - each section must have exactly one Input; if the type inherits NO_ARGS then it *must* be an +# "Inputs: none". +# - each section must have exactly one Output +# - "Example input:" section must be immediately followed by an "Example output" +# - "Example output:" sections are permitted without a preceding example input only if the endpoint +# takes no inputs. +# - 0 or more example pairs are permitted. +# - Old names is permitted only once, if it occurs at all; the given names will be indicated as +# deprecated, old names for the endpoint. +# +# Immediately following the command we expect to find a not-only-comment line (e.g. `struct +# `) and apply some checks to this: +# - if the line does *not* contain the word `PUBLIC` then we mark the endpoint as requiring admin +# access in its description. +# - if the line contains the word `NO_ARGS` then we double-check that "Inputs: none" was also given +# and error if a more complex Inputs: section was written. + + +hdr = '#' * args.markdown_level +MD_INPUT_HEADER = f"{hdr}# Parameters" +MD_OUTPUT_HEADER = f"{hdr}# Returns" + +MD_EXAMPLES_HEADER = f"{hdr}# Examples" +MD_EXAMPLE_IN_HDR = f"{hdr}## Input" +MD_EXAMPLE_OUT_HDR = f"{hdr}## Output" + +MD_EX_SINGLE_IN_HDR = f"{hdr}# Example Input" +MD_EX_SINGLE_OUT_HDR = f"{hdr}# Example Output" + +MD_NO_INPUT = "This endpoint takes no inputs. _(An optional empty dict/object may be provided, but is not required.)_" +MD_ADMIN = "\n\n> _This endpoint requires admin RPC access; it is not available on public RPC servers._" + +RPC_COMMENT = re.compile(r"^\s*/// ?") +RPC_START = re.compile(r"^RPC:\s*([\w/]+)(.*)$") +DEV_RPC_START = re.compile(r"^Dev-RPC:\s*([\w/]+)(.*)$") +IN_NONE = re.compile(r"^Inputs?: *[nN]one\.?$") +IN_SOME = re.compile(r"^Inputs?:\s*$") +OUT_SOME = re.compile(r"^Outputs?:\s*$") +EXAMPLE_IN = re.compile(r"^Example [iI]nputs?:\s*$") +EXAMPLE_OUT = re.compile(r"^Example [oO]utputs?:\s*$") +EXAMPLE_JSON_FETCH = re.compile(r"^Example-JSON-Fetch\s*$") +OLD_NAMES = re.compile(r"[Oo]ld [nN]ames?:") +PLAIN_NAME = re.compile(r"\w+") +PUBLIC = re.compile(r"\bPUBLIC\b") +NO_ARGS = re.compile(r"\bNO_ARGS\b") + +input = fileinput.input(args.filename) +rpc_name = None + + +def error(msg): + print( + f"\x1b[31;1mERROR\x1b[0m[{input.filename()}:{input.filelineno()}] " + f"while parsing endpoint {rpc_name}:", + file=sys.stderr, + ) + if msg and isinstance(msg, list): + for m in msg: + print(f" - {m}", file=sys.stderr) + else: + print(f" {msg}", file=sys.stderr) + sys.exit(1) + + +class Parsing(Enum): + DESC = auto() + INPUTS = auto() + OUTPUTS = auto() + EX_IN = auto() + EX_OUT = auto() + NONE = auto() + + +cur_file = None +found_some = True + +endpoints = {} + +while True: + line = input.readline() + if not line: + break + + if cur_file is None or cur_file != input.filename(): + if not found_some: + error(f"Found no parseable endpoint descriptions in {cur_file}") + cur_file = input.filename() + found_some = False + + line, removed_comment = re.subn(RPC_COMMENT, "", line, count=1) + if not removed_comment: + continue + + m = re.search(RPC_START, line) + if not m and args.dev: + m = re.search(DEV_RPC_START, line) + if not m: + continue + if m and m[2]: + error(f"found trailing garbage after 'RPC: m[1]': {m[2]}") + if m[1].count('/') != 1: + error(f"Found invalid RPC name: expected 'cat/name', not '{m[1]}'") + + cat, rpc_name = m[1].split('/') + if args.no_group: + cat = '' + description, inputs, outputs = "", "", "" + done_desc = False + no_inputs = False + examples = [] + cur_ex_in = None + old_names = [] + + mode = Parsing.DESC + + while True: + line = input.readline() + line, removed_comment = re.subn(RPC_COMMENT, "", line, count=1) + if not removed_comment: + break + + if re.search(IN_NONE, line): + if inputs: + error("found multiple Inputs:") + inputs, no_inputs, mode = MD_NO_INPUT, True, Parsing.NONE + + elif re.search(IN_SOME, line): + if inputs: + error("found multiple Inputs:") + mode = Parsing.INPUTS + + elif re.search(OUT_SOME, line): + if outputs: + error("found multiple Outputs:") + mode = Parsing.OUTPUTS + + elif re.search(EXAMPLE_IN, line): + if cur_ex_in is not None: + error("found multiple input examples without paired output examples") + cur_ex_in = "" + mode = Parsing.EX_IN + + elif re.search(EXAMPLE_OUT, line): + if not cur_ex_in and not no_inputs: + error( + "found output example without preceding input example (or 'Inputs: none.')" + ) + examples.append([cur_ex_in, ""]) + cur_ex_in = None + mode = Parsing.EX_OUT + + elif re.search(EXAMPLE_JSON_FETCH, line): + if not cur_ex_in and not no_inputs: + error( + "found output example fetch instruction without preceding input (or 'Inputs: none.')" + ) + params = None + if cur_ex_in: + params = cur_ex_in.strip() + if not params.startswith("```json\n"): + error("current example input is not tagged as json for Example-JSON-Fetch") + params = params[8:] + if not params.endswith("\n```"): + error("current example input doesn't look right (expected trailing ```)") + params = params[:-4] + try: + params = json.loads(params) + except Exception as e: + error("failed to parse json example input as json") + + result = requests.post(args.rpc + "/json_rpc", json={"jsonrpc": "2.0", "id": "0", "method": rpc_name, "params": params}).json() + if 'error' in result: + error(f"JSON fetched example returned an error: {result['error']}") + elif 'result' not in result: + error(f"JSON fetched example doesn't contain a \"result\" key: {result}") + ex_out = json.dumps(result["result"], indent=2, sort_keys=True) + + examples.append([cur_ex_in, f"\n```json\n{ex_out}\n```\n"]) + cur_ex_in = None + mode = Parsing.NONE + + elif re.search(OLD_NAMES, line): + old_names = [x.strip() for x in line.split(':', 1)[1].split(',')] + if not old_names or not all(re.fullmatch(PLAIN_NAME, n) for n in old_names): + error(f"found unparseable old names line: {line}") + + elif mode == Parsing.NONE: + if line and not line.isspace(): + error(f"Found unexpected content while looking for a tag: '{line}'") + + elif mode == Parsing.DESC: + description += line + + elif mode == Parsing.INPUTS: + inputs += line + + elif mode == Parsing.OUTPUTS: + outputs += line + + elif mode == Parsing.EX_IN: + cur_ex_in += line + + elif mode == Parsing.EX_OUT: + examples[-1][1] += line + + problems = [] + # We hit the end of the commented section + if not description or inputs.isspace(): + problems.append("endpoint has no description") + if not inputs or inputs.isspace(): + problems.append( + "endpoint has no inputs description; perhaps you need to add 'Inputs: none.'?" + ) + if not outputs or outputs.isspace(): + problems.append("endpoint has no outputs description") + if cur_ex_in is not None: + problems.append( + "endpoint has a trailing example input without a following example output" + ) + if not no_inputs and any(not x[0] or x[0].isspace() for x in examples): + problems.append("found one or more blank input examples") + if any(not x[1] or x[1].isspace() for x in examples): + problems.append("found one or more blank output examples") + + public = args.disable_public or re.search(PUBLIC, line) + if not public: + description += MD_ADMIN + + if old_names: + s = 's' if len(old_names) > 1 else '' + description += f"\n\n> _For backwards compatibility this endpoint is also accessible via the following deprecated endpoint name{s}:_" + for n in old_names: + description += f"\n> - _`{n}`_" + + if not args.disable_no_args: + if re.search(NO_ARGS, line) and not no_inputs: + problems.append("found NO_ARGS, but 'Inputs: none' was specified in description") + + if problems: + error(problems) + + md = f""" +{hdr} `{rpc_name}` + +{description} + +{MD_INPUT_HEADER} + +{inputs} + +{MD_OUTPUT_HEADER} + +{outputs} +""" + + if examples: + if len(examples) > 1: + md += f"\n\n{MD_EXAMPLES_HEADER}\n\n" + for ex in examples: + if ex[0] is not None: + md += f""" +{MD_EXAMPLE_IN_HDR} + +{ex[0]} +""" + md += f""" +{MD_EXAMPLE_OUT_HDR} + +{ex[1]} +""" + + else: + if examples[0][0] is not None: + md += f"\n\n{MD_EX_SINGLE_IN_HDR}\n\n{examples[0][0]}" + md += f"\n\n{MD_EX_SINGLE_OUT_HDR}\n\n{examples[0][1]}" + + if not args.no_emdash: + md = md.replace(" -- ", " — ") + + if cat in endpoints: + endpoints[cat].append((rpc_name, md)) + else: + endpoints[cat] = [(rpc_name, md)] + +if not endpoints: + error(f"Found no parseable endpoint descriptions in {cur_file}") + +if not args.no_sort: + for v in endpoints.values(): + v.sort(key=lambda x: x[0]) + +os.makedirs(args.out, exist_ok=True) + +static_path = os.path.dirname(os.path.realpath(__file__)) + '/static' + +for f in ('index.md', 'sidebar.md'): + shutil.copy(f"{static_path}/{f}", f"{args.out}/{f}") + print(f"Copied static/{f} => {args.out}/{f}") + +preamble_prefix = static_path + '/preamble-' + +for cat, eps in endpoints.items(): + out = f"{args.out}/{cat}.md" + with open(out, "w") as f: + preamble = f"{preamble_prefix}{cat}.md" + if os.path.isfile(preamble): + with open(preamble, "r") as fp: + for line in fp: + f.write(line) + f.write("\n\n") + else: + print(f"Warning: {preamble} doesn't exist, writing generic preamble for {cat}", file=sys.stderr) + f.write(f"# {cat} endpoints\n\n") + + for _, md in eps: + f.write(md) + print(f"Wrote {out}") diff --git a/docs/daemon-rpc/static/index.md b/docs/daemon-rpc/static/index.md new file mode 100644 index 000000000..f36f05e80 --- /dev/null +++ b/docs/daemon-rpc/static/index.md @@ -0,0 +1,62 @@ +# Oxen Daemon RPC Endpoints + +These pages describe the available RPC endpoints available from a running `oxend` node. These +endpoints are used for querying blockchain data, submitting transactions, obtaining service node +information, and controlling the running oxend. + +Many of the endpoints described here are publicly accessible; those that are not are marked +accordingly and can only be used by a local administrator. + +## HTTP JSON access + +Accessing an endpoint using HTTP and JSON can be done by making a JSON RPC request. For example, to +call the `get_info` endpoint on a service node with an HTTP RPC listener on `localhost:22023` (the +default) using JSON RPC you would make a POST request to `http://localhost:22023/json_rpc` with a +JSON body: + +```json +{ + "jsonrpc": "2.0", + "id": "0", + "method": "get_info", + "params": { "foo": 123 } +} +``` + +The pages here describe only the values of the inner "params" value; the outer boilerplate is the +same for all requests. For methods that do not require any input parameters the `"params"` field +may be omitted entirely. + +### Command-line usage + +For example, to make a request using `curl` to the public RPC node `public-na.optf.ngo`, using the +command-line with `jq` to "prettify" the json response: + +``` +curl -sSX POST http://public-na.optf.ngo:22023/json_rpc \ + -d '{"jsonrpc":"2.0","id":"0","method":"get_info"}' | jq . +``` + +## OxenMQ RPC access + +All oxend endpoints are also available via OxenMQ at either the `rpc.ENDPOINT` or `admin.ENDPOINT` +name (the latter if the endpoint is marked admin-only), with an optional additional data part +containing a JSON or bencoded request. + +### Command-line usage: + +The oxen-core source code contains a script (`utils/lmq-rpc.py`) that can invoke such a request: + +``` +./utils/lmq-rpc.py ipc://$HOME/.oxen/oxend.sock rpc.get_info | jq . +``` +to query a local oxend, or: +``` +./utils/lmq-rpc.py tcp://public-na.optf.ngo:22027 02ae9aa1bdface3ce32488874d16671b04d44f611d1076033c92f3379f221161 rpc.get_info | jq . +``` +or +``` +./utils/lmq-rpc.py tcp://public-na.optf.ngo:22029 rpc.get_info '{}' | jq . +``` +to query a public node. (The first version uses an encrypted public connection given the remote +oxend's X25519 pubkey; the second version uses an unencrypted public connection). diff --git a/docs/daemon-rpc/static/preamble-blockchain.md b/docs/daemon-rpc/static/preamble-blockchain.md new file mode 100644 index 000000000..da8ab277b --- /dev/null +++ b/docs/daemon-rpc/static/preamble-blockchain.md @@ -0,0 +1,4 @@ +# Blockchain Endpoints + +These endpoints are used for querying various data from the blockchain; unless otherwise indicated, +these are accessible using a public RPC node. diff --git a/docs/daemon-rpc/static/preamble-daemon.md b/docs/daemon-rpc/static/preamble-daemon.md new file mode 100644 index 000000000..c37ecf59b --- /dev/null +++ b/docs/daemon-rpc/static/preamble-daemon.md @@ -0,0 +1,4 @@ +# Daemon Administration Endpoints + +These endpoints allow for controlling and querying privileged information about the running oxend. +They require administrator access. diff --git a/docs/daemon-rpc/static/preamble-network.md b/docs/daemon-rpc/static/preamble-network.md new file mode 100644 index 000000000..e6ba7505f --- /dev/null +++ b/docs/daemon-rpc/static/preamble-network.md @@ -0,0 +1,4 @@ +# Network Information Endpoints + +These endpoints are used for querying various general information about the network that are not +(directly) blockchain data. diff --git a/docs/daemon-rpc/static/preamble-ons.md b/docs/daemon-rpc/static/preamble-ons.md new file mode 100644 index 000000000..821dcfcc4 --- /dev/null +++ b/docs/daemon-rpc/static/preamble-ons.md @@ -0,0 +1,3 @@ +# Oxen Name System Query Endpoints + +This endpoints allow querying Oxen Name System records. diff --git a/docs/daemon-rpc/static/preamble-service_node.md b/docs/daemon-rpc/static/preamble-service_node.md new file mode 100644 index 000000000..6d1f77d95 --- /dev/null +++ b/docs/daemon-rpc/static/preamble-service_node.md @@ -0,0 +1,4 @@ +# Service Node Administration Endpoints + +These endpoints allow administering and controlling an active service node. They generally require +the queried oxend is running as a service node, and require administrator access. diff --git a/docs/daemon-rpc/static/sidebar.md b/docs/daemon-rpc/static/sidebar.md new file mode 100644 index 000000000..19fe0a9bc --- /dev/null +++ b/docs/daemon-rpc/static/sidebar.md @@ -0,0 +1,5 @@ +- [Network information](network.md) +- [Blockchain data](blockchain.md) +- [Oxen Name System](ons.md) +- [Daemon administration](daemon.md) +- [Service Node administration](service_node.md) diff --git a/src/rpc/core_rpc_server.cpp b/src/rpc/core_rpc_server.cpp index 480de6f71..5c6a680a1 100644 --- a/src/rpc/core_rpc_server.cpp +++ b/src/rpc/core_rpc_server.cpp @@ -1345,6 +1345,7 @@ namespace cryptonote::rpc { h, curr_height - 1)}; get.response_hex["{}"_format(h)] = m_core.get_block_id_by_height(h); } + get.response["height"] = curr_height; get.response["status"] = STATUS_OK; } //------------------------------------------------------------------------------------------------------------------------------ @@ -1625,10 +1626,6 @@ namespace cryptonote::rpc { if (i->second > now) { ban b; b.host = i->first; - b.ip = 0; - uint32_t ip; - if (epee::string_tools::get_ip_int32_from_string(ip, b.host)) - b.ip = ip; b.seconds = i->second - now; get_bans.response["bans"].push_back(b); } @@ -1639,7 +1636,6 @@ namespace cryptonote::rpc { if (i->second > now) { ban b; b.host = i->first.host_str(); - b.ip = 0; b.seconds = i->second - now; get_bans.response["bans"].push_back(b); } @@ -1675,32 +1671,22 @@ namespace cryptonote::rpc { { epee::net_utils::network_address na; // try subnet first - if (!set_bans.request.host.empty()) + auto ns_parsed = net::get_ipv4_subnet_address(set_bans.request.host); + if (ns_parsed) { - auto ns_parsed = net::get_ipv4_subnet_address(set_bans.request.host); - if (ns_parsed) - { - if (set_bans.request.ban) - m_p2p.block_subnet(*ns_parsed, set_bans.request.seconds); - else - m_p2p.unblock_subnet(*ns_parsed); - set_bans.response["status"] = STATUS_OK; - return; - } + if (set_bans.request.ban) + m_p2p.block_subnet(*ns_parsed, set_bans.request.seconds); + else + m_p2p.unblock_subnet(*ns_parsed); + set_bans.response["status"] = STATUS_OK; + return; } // then host - if (!set_bans.request.host.empty()) - { - auto na_parsed = net::get_network_address(set_bans.request.host, 0); - if (!na_parsed) - throw rpc_error{ERROR_WRONG_PARAM, "Unsupported host/subnet type"}; - na = std::move(*na_parsed); - } - else - { - na = epee::net_utils::ipv4_network_address{set_bans.request.ip, 0}; - } + auto na_parsed = net::get_network_address(set_bans.request.host, 0); + if (!na_parsed) + throw rpc_error{ERROR_WRONG_PARAM, "Unsupported host/subnet type"}; + na = std::move(*na_parsed); if (set_bans.request.ban) m_p2p.block_host(na, set_bans.request.seconds); else diff --git a/src/rpc/core_rpc_server_binary_commands.cpp b/src/rpc/core_rpc_server_binary_commands.cpp index 708486af2..367e7e989 100644 --- a/src/rpc/core_rpc_server_binary_commands.cpp +++ b/src/rpc/core_rpc_server_binary_commands.cpp @@ -2,6 +2,10 @@ namespace cryptonote::rpc { +KV_SERIALIZE_MAP_CODE_BEGIN(EMPTY) +KV_SERIALIZE_MAP_CODE_END() + + void to_json(nlohmann::json& j, const GET_BLOCKS_BIN::tx_output_indices& toi) { j = nlohmann::json{{"indices", toi.indices}}; diff --git a/src/rpc/core_rpc_server_binary_commands.h b/src/rpc/core_rpc_server_binary_commands.h index 0b02db26a..57eda68ab 100644 --- a/src/rpc/core_rpc_server_binary_commands.h +++ b/src/rpc/core_rpc_server_binary_commands.h @@ -35,6 +35,8 @@ namespace cryptonote::rpc { + struct EMPTY { KV_MAP_SERIALIZABLE }; + /// Specifies that the RPC call is legacy, deprecated Monero custom binary input/ouput. If not /// given then the command is JSON/bt-encoded values. For HTTP RPC this also means the command is /// *not* available via the HTTP JSON RPC. diff --git a/src/rpc/core_rpc_server_command_parser.cpp b/src/rpc/core_rpc_server_command_parser.cpp index 3bb932101..9d3a417ed 100644 --- a/src/rpc/core_rpc_server_command_parser.cpp +++ b/src/rpc/core_rpc_server_command_parser.cpp @@ -211,17 +211,17 @@ namespace cryptonote::rpc { void parse_request(SET_LOG_LEVEL& set_log_level, rpc_input in) { get_values(in, - "level", set_log_level.request.level); + "level", required{set_log_level.request.level}); } void parse_request(SET_LOG_CATEGORIES& set_log_categories, rpc_input in) { get_values(in, - "categories", set_log_categories.request.categories); + "categories", required{set_log_categories.request.categories}); } void parse_request(BANNED& banned, rpc_input in) { get_values(in, - "address", banned.request.address); + "address", required{banned.request.address}); } void parse_request(FLUSH_TRANSACTION_POOL& flush_transaction_pool, rpc_input in) { @@ -254,23 +254,23 @@ namespace cryptonote::rpc { void parse_request(POP_BLOCKS& pop_blocks, rpc_input in){ get_values(in, - "nblocks", pop_blocks.request.nblocks); + "nblocks", required{pop_blocks.request.nblocks}); } void parse_request(LOKINET_PING& lokinet_ping, rpc_input in){ get_values(in, "ed25519_pubkey", lokinet_ping.request.ed25519_pubkey, "error", lokinet_ping.request.error, - "version", lokinet_ping.request.version); + "version", required{lokinet_ping.request.version}); } void parse_request(STORAGE_SERVER_PING& storage_server_ping, rpc_input in){ get_values(in, - "ed25519_pubkey", storage_server_ping.request.ed25519_pubkey, + "ed25519_pubkey", required{storage_server_ping.request.ed25519_pubkey}, "error", storage_server_ping.request.error, - "https_port", storage_server_ping.request.https_port, - "omq_port", storage_server_ping.request.omq_port, - "version", storage_server_ping.request.version); + "https_port", required{storage_server_ping.request.https_port}, + "omq_port", required{storage_server_ping.request.omq_port}, + "version", required{storage_server_ping.request.version}); } void parse_request(PRUNE_BLOCKCHAIN& prune_blockchain, rpc_input in){ @@ -313,10 +313,9 @@ namespace cryptonote::rpc { void parse_request(SET_BANS& set_bans, rpc_input in) { get_values(in, - "ban", set_bans.request.ban, - "host", set_bans.request.host, - "ip", set_bans.request.ip, - "seconds", set_bans.request.seconds); + "ban", required{set_bans.request.ban}, + "host", required{set_bans.request.host}, + "seconds", required{set_bans.request.seconds}); } void parse_request(GET_STAKING_REQUIREMENT& get_staking_requirement, rpc_input in) { @@ -362,7 +361,7 @@ namespace cryptonote::rpc { void parse_request(ONS_OWNERS_TO_NAMES& ons_owners_to_names, rpc_input in) { get_values(in, - "entries", ons_owners_to_names.request.entries, + "entries", required{ons_owners_to_names.request.entries}, "include_expired", ons_owners_to_names.request.include_expired); } @@ -391,8 +390,8 @@ namespace cryptonote::rpc { void parse_request(GET_SERVICE_NODE_REGISTRATION_CMD_RAW& cmd, rpc_input in) { get_values(in, - "args", cmd.request.args, + "args", required{cmd.request.args}, "make_friendly", cmd.request.make_friendly, - "staking_requirement", cmd.request.staking_requirement); + "staking_requirement", required{cmd.request.staking_requirement}); } } diff --git a/src/rpc/core_rpc_server_commands_defs.cpp b/src/rpc/core_rpc_server_commands_defs.cpp index ec5a2a45f..45d6db509 100644 --- a/src/rpc/core_rpc_server_commands_defs.cpp +++ b/src/rpc/core_rpc_server_commands_defs.cpp @@ -182,34 +182,6 @@ void to_json(nlohmann::json& j, const ONS_OWNERS_TO_NAMES::response_entry& r) }; } -KV_SERIALIZE_MAP_CODE_BEGIN(EMPTY) -KV_SERIALIZE_MAP_CODE_END() - - -KV_SERIALIZE_MAP_CODE_BEGIN(block_header_response) - KV_SERIALIZE(major_version) - KV_SERIALIZE(minor_version) - KV_SERIALIZE(timestamp) - KV_SERIALIZE(prev_hash) - KV_SERIALIZE(nonce) - KV_SERIALIZE(orphan_status) - KV_SERIALIZE(height) - KV_SERIALIZE(depth) - KV_SERIALIZE(hash) - KV_SERIALIZE(difficulty) - KV_SERIALIZE(cumulative_difficulty) - KV_SERIALIZE(reward) - KV_SERIALIZE(coinbase_payouts) - KV_SERIALIZE(block_size) - KV_SERIALIZE_OPT(block_weight, (uint64_t)0) - KV_SERIALIZE(num_txes) - KV_SERIALIZE(pow_hash) - KV_SERIALIZE_OPT(long_term_weight, (uint64_t)0) - KV_SERIALIZE(miner_tx_hash) - KV_SERIALIZE(tx_hashes) - KV_SERIALIZE(service_node_winner) -KV_SERIALIZE_MAP_CODE_END() - KV_SERIALIZE_MAP_CODE_BEGIN(GET_OUTPUT_DISTRIBUTION::request) KV_SERIALIZE(amounts) diff --git a/src/rpc/core_rpc_server_commands_defs.h b/src/rpc/core_rpc_server_commands_defs.h index 605ac4d4d..7485c3230 100644 --- a/src/rpc/core_rpc_server_commands_defs.h +++ b/src/rpc/core_rpc_server_commands_defs.h @@ -103,167 +103,186 @@ namespace cryptonote::rpc { STATUS_TX_LONG_POLL_TIMED_OUT = "Long polling client timed out before txpool had an update"; - /// Generic, serializable, no-argument request or response type, use as - /// `struct request : EMPTY {};` or `using response = EMPTY;` - struct EMPTY { KV_MAP_SERIALIZABLE }; - + /// RPC: blockchain/get_height + /// /// Get the node's current height. /// /// Inputs: none. /// /// Outputs: /// - /// - \p height -- The current blockchain height according to the queried daemon. - /// - \p status -- Generic RPC error code. "OK" is the success value. - /// - \p hash -- Hash of the block at the current height - /// - \p immutable_height -- The latest height in the blockchain that cannot be reorganized + /// - `height` -- The current blockchain height according to the queried daemon. + /// - `status` -- Generic RPC error code. "OK" is the success value. + /// - `hash` -- Hash of the block at the current height + /// - `immutable_height` -- The latest height in the blockchain that cannot be reorganized /// because of a hardcoded checkpoint or 2 SN checkpoints. Omitted if not available. - /// - \p immutable_hash -- Hash of the highest block in the chain that cannot be reorganized. + /// - `immutable_hash` -- Hash of the highest block in the chain that cannot be reorganized. + /// + /// Example-JSON-Fetch struct GET_HEIGHT : PUBLIC, LEGACY, NO_ARGS { static constexpr auto names() { return NAMES("get_height", "getheight"); } }; + /// RPC: blockchain/get_transactions + /// /// Look up one or more transactions by hash. /// + /// Inputs: + /// + /// - `tx_hashes` -- List of transaction hashes to look up. (Will also be accepted as json input + /// key `"txs_hashes"` for backwards compatibility). Exclusive of `memory_pool`. + /// - `memory_pool` -- If true then return all transactions and spent key images currently in the + /// memory pool. This field is exclusive of `tx_hashes`. + /// - `tx_extra` -- If set to true then parse and return tx-extra information + /// - `tx_extra_raw` -- If set to true then include the raw tx-extra information in the + /// `tx_extra_raw` field. This will be hex-encoded for json, raw bytes for bt-encoded requests. + /// - `data` -- Controls whether the `data` (or `pruned`, if pruned) field containing raw tx data + /// is included. By default it is not included; you typically want `details` rather than this + /// field. + /// - `split` -- If set to true then always split transactions into non-prunable and prunable + /// parts in the response. + /// - `prune` -- Like `split`, but also omits the prunable part of transactions from the response + /// details. + /// /// Outputs: /// - /// - \p status -- Generic RPC error code. "OK" is the success value. - /// - \p missed_tx -- set of transaction hashes that were not found. If all were found then this + /// - `status` -- Generic RPC error code. "OK" is the success value. + /// - `missed_tx` -- set of transaction hashes that were not found. If all were found then this /// field is omitted. There is no particular ordering of hashes in this list. - /// - \p txs -- list of transaction details; each element is a dict containing: - /// - \p tx_hash -- Transaction hash. - /// - \p size -- Size of the transaction, in bytes. Note that if the transaction has been pruned + /// - `txs` -- list of transaction details; each element is a dict containing: + /// - `tx_hash` -- Transaction hash. + /// - `size` -- Size of the transaction, in bytes. Note that if the transaction has been pruned /// this is the post-pruning size, not the original size. - /// - \p in_pool -- Will be set to true if the transaction is in the transaction pool (`true`) + /// - `in_pool` -- Will be set to true if the transaction is in the transaction pool (`true`) /// and omitted if mined into a block. - /// - \p blink -- True if this is an approved, blink transaction; this information is generally + /// - `blink` -- True if this is an approved, blink transaction; this information is generally /// only available for approved in-pool transactions and txes in very recent blocks. - /// - \p fee -- the transaction fee (in atomic OXEN) incurred in this transaction (not including + /// - `fee` -- the transaction fee (in atomic OXEN) incurred in this transaction (not including /// any burned amount). - /// - \p burned -- the amount of OXEN (in atomic units) burned by this transaction. - /// - \p block_height -- Block height including the transaction. Omitted for tx pool + /// - `burned` -- the amount of OXEN (in atomic units) burned by this transaction. + /// - `block_height` -- Block height including the transaction. Omitted for tx pool /// transactions. - /// - \p block_timestamp -- Unix time at which the block has been added to the blockchain. + /// - `block_timestamp` -- Unix time at which the block has been added to the blockchain. /// Omitted for tx pool transactions. - /// - \p output_indices -- List of transaction indexes. Omitted for tx pool transactions. - /// - \p relayed -- For `in_pool` transactions this field will be set to indicate whether the + /// - `output_indices` -- List of transaction indexes. Omitted for tx pool transactions. + /// - `relayed` -- For `in_pool` transactions this field will be set to indicate whether the /// transaction has been relayed to the network. - /// - \p double_spend_seen -- Will be set to true for tx pool transactions that are + /// - `double_spend_seen` -- Will be set to true for tx pool transactions that are /// double-spends (and thus cannot be added to the blockchain). Omitted for mined /// transactions. - /// - \p received_timestamp -- Timestamp transaction was received in the pool. Omitted for + /// - `received_timestamp` -- Timestamp transaction was received in the pool. Omitted for /// mined blocks. - /// - \p max_used_block -- the hash of the highest block referenced by this transaction; only + /// - `max_used_block` -- the hash of the highest block referenced by this transaction; only /// for mempool transactions. - /// - \p max_used_height -- the height of the highest block referenced by this transaction; only + /// - `max_used_height` -- the height of the highest block referenced by this transaction; only /// for mempool transactions. - /// - \p last_failed_block -- the hash of the last block where this transaction was attempted to + /// - `last_failed_block` -- the hash of the last block where this transaction was attempted to /// be mined (but failed). - /// - \p max_used_height -- the height of the last block where this transaction failed to be + /// - `max_used_height` -- the height of the last block where this transaction failed to be /// acceptable for a block. - /// - \p weight -- the transaction "weight" which is the size of the transaction with padding + /// - `weight` -- the transaction "weight" which is the size of the transaction with padding /// removed. Only included for mempool transactions (for mined transactions the size and /// weight at the same and so only `size` is included). - /// - \p kept_by_block will be present and true if this is a mempool transaction that was added + /// - `kept_by_block` will be present and true if this is a mempool transaction that was added /// to the mempool after being popped off a block (e.g. because of a blockchain /// reorganization). - /// - \p last_relayed_time indicates the last time this block was relayed to the network; only + /// - `last_relayed_time` indicates the last time this block was relayed to the network; only /// for mempool transactions. - /// - \p do_not_relay -- set to true for mempool blocks that are marked "do not relay" - /// - \p double_spend_seen -- set to true if one or more outputs in this mempool transaction + /// - `do_not_relay` -- set to true for mempool blocks that are marked "do not relay" + /// - `double_spend_seen` -- set to true if one or more outputs in this mempool transaction /// have already been spent (and thus the tx cannot currently be added to the blockchain). - /// - \p data -- Full, unpruned transaction data. For a json request this is hex-encoded; for a + /// - `data` -- Full, unpruned transaction data. For a json request this is hex-encoded; for a /// bt-encoded request this is raw bytes. This field is omitted if any of `tx_extra`, /// `split`, or `prune` is requested; or if the transaction has been pruned in the database. - /// - \p pruned -- The non-prunable part of the transaction, encoded as hex (for json requests). + /// - `pruned` -- The non-prunable part of the transaction, encoded as hex (for json requests). /// Always included if `split` or `prune` are specified; without those options it will be /// included instead of `data` if the transaction has been pruned. - /// - \p prunable -- The prunable part of the transaction. Only included when `split` is + /// - `prunable` -- The prunable part of the transaction. Only included when `split` is /// specified, the transaction is prunable, and the tx has not been pruned from the database. - /// - \p prunable_hash -- The hash of the prunable part of the transaction. Will be provided if + /// - `prunable_hash` -- The hash of the prunable part of the transaction. Will be provided if /// either: the tx has been pruned; or the tx is prunable and either of `prune` or `split` are /// specified. - /// - \p extra -- Parsed "extra" transaction information; omitted unless specifically requested + /// - `extra` -- Parsed "extra" transaction information; omitted unless specifically requested /// (via the `tx_extra` request parameter). This is a dict containing one or more of the /// following keys. - /// - \p pubkey -- The tx extra public key - /// - \p burn_amount -- The amount of OXEN that this transaction burns, if any. - /// - \p extra_nonce -- Optional extra nonce value (in hex); will be empty if nonce is + /// - `pubkey` -- The tx extra public key + /// - `burn_amount` -- The amount of OXEN that this transaction burns, if any. + /// - `extra_nonce` -- Optional extra nonce value (in hex); will be empty if nonce is /// recognized as a payment id - /// - \p payment_id -- The payment ID, if present. This is either a 16 hex character (8-byte) + /// - `payment_id` -- The payment ID, if present. This is either a 16 hex character (8-byte) /// encrypted payment id, or a 64 hex character (32-byte) deprecated, unencrypted payment ID - /// - \p mm_depth -- (Merge-mining) the merge-mined depth - /// - \p mm_root -- (Merge-mining) the merge mining merkle root hash - /// - \p additional_pubkeys -- Additional public keys - /// - \p sn_winner -- Service node block reward winner public key - /// - \p sn_pubkey -- Service node public key (e.g. for registrations, stakes, unlocks) - /// - \p sn_contributor -- Service node contributor wallet address (for stakes) - /// - \p tx_secret_key -- The transaction secret key, included in registrations/stakes to + /// - `mm_depth` -- (Merge-mining) the merge-mined depth + /// - `mm_root` -- (Merge-mining) the merge mining merkle root hash + /// - `additional_pubkeys` -- Additional public keys + /// - `sn_winner` -- Service node block reward winner public key + /// - `sn_pubkey` -- Service node public key (e.g. for registrations, stakes, unlocks) + /// - `sn_contributor` -- Service node contributor wallet address (for stakes) + /// - `tx_secret_key` -- The transaction secret key, included in registrations/stakes to /// decrypt transaction amounts and recipients - /// - \p locked_key_images -- Key image(s) locked by the transaction (for registrations, + /// - `locked_key_images` -- Key image(s) locked by the transaction (for registrations, /// stakes) - /// - \p key_image_unlock -- A key image being unlocked in a stake unlock request (an unlock + /// - `key_image_unlock` -- A key image being unlocked in a stake unlock request (an unlock /// will be started for *all* key images locked in the same SN contributions). - /// - \p sn_registration -- Service node registration details; this is a dict containing: - /// - \p fee the operator fee expressed in millionths (i.e. 234567 == 23.4567%) - /// - \p expiry the unix timestamp at which the registration signature expires - /// - \p contributors: dict of (wallet => portion) pairs indicating the staking portions + /// - `sn_registration` -- Service node registration details; this is a dict containing: + /// - `fee` the operator fee expressed in millionths (i.e. 234567 == 23.4567%) + /// - `expiry` the unix timestamp at which the registration signature expires + /// - `contributors`: dict of (wallet => portion) pairs indicating the staking portions /// reserved for the operator and any reserved contribution spots in the registration. /// Portion is expressed in millionths (i.e. 250000 = 25% staking portion). - /// - \p sn_state_change -- Information for a "state change" transaction such as a + /// - `sn_state_change` -- Information for a "state change" transaction such as a /// deregistration, decommission, recommission, or ip change reset transaction. This is a /// dict containing: - /// - \p old_dereg will be set to true if this is an "old" deregistration transaction + /// - `old_dereg` will be set to true if this is an "old" deregistration transaction /// (before the Loki 4 hardfork), omitted for more modern state change txes. - /// - \p type string indicating the state change type: "dereg", "decomm", "recomm", or "ip" + /// - `type` string indicating the state change type: "dereg", "decomm", "recomm", or "ip" /// for a deregistration, decommission, recommission, or ip change penalty transaction. - /// - \p height the voting block height for the changing service node and voting service + /// - `height` the voting block height for the changing service node and voting service /// nodes that produced this state change transaction. - /// - \p index the position of the affected node in the random list of tested nodes for this + /// - `index` the position of the affected node in the random list of tested nodes for this /// `height`. - /// - \p voters the positions of validators in the testing quorum for this `height` who + /// - `voters` the positions of validators in the testing quorum for this `height` who /// tested and voted for this state change. This typically contains the first 7 voters /// who voted for the state change (out of a possible set of 10). - /// - \p reasons list of reported reasons for a decommission or deregistration as reported + /// - `reasons` list of reported reasons for a decommission or deregistration as reported /// by the voting quorum. This contains any reasons that all 7+ voters agreed on, and /// contains one or more of: - /// - \p "uptime" -- the service node was missing uptime proofs - /// - \p "checkpoints" -- the service node missed too many recent checkpoint votes - /// - \p "pulse" -- the service node missed too many recent pulse votes - /// - \p "storage" -- the service node's storage server was unreachable for too long - /// - \p "lokinet" -- the service node's lokinet router was unreachable for too long - /// - \p "timecheck" -- the service node's oxend was not reachable for too many recent + /// - `"uptime"` -- the service node was missing uptime proofs + /// - `"checkpoints"` -- the service node missed too many recent checkpoint votes + /// - `"pulse"` -- the service node missed too many recent pulse votes + /// - `"storage"` -- the service node's storage server was unreachable for too long + /// - `"lokinet"` -- the service node's lokinet router was unreachable for too long + /// - `"timecheck"` -- the service node's oxend was not reachable for too many recent /// time synchronization checks. (This generally means oxend's quorumnet port is not /// reachable). - /// - \p "timesync" -- the service node's clock was too far out of sync + /// - `"timesync"` -- the service node's clock was too far out of sync /// The list is omitted entirely if there are no reasons at all or if there are no reasons /// that were agreed upon by all voting service nodes. - /// - \p reasons_maybe list of reported reasons that some but not all service nodes provided + /// - `reasons_maybe` list of reported reasons that some but not all service nodes provided /// for the deregistration/decommission. Possible values are identical to the above. /// This list is omitted entirely if it would be empty (i.e. there are no reasons at all, /// or all voting service nodes agreed on all given reasons). - /// - \p ons -- ONS registration or update transaction details. This contains keys: - /// - \p buy -- set to true if this is an ONS buy record; omitted otherwise. - /// - \p update -- set to true if this is an ONS record update; omitted otherwise. - /// - \p renew -- set to true if this is an ONS renewal; omitted otherwise. - /// - \p type -- the ONS request type string. For registrations: "lokinet", "session", + /// - `ons` -- ONS registration or update transaction details. This contains keys: + /// - `buy` -- set to true if this is an ONS buy record; omitted otherwise. + /// - `update` -- set to true if this is an ONS record update; omitted otherwise. + /// - `renew` -- set to true if this is an ONS renewal; omitted otherwise. + /// - `type` -- the ONS request type string. For registrations: "lokinet", "session", /// "wallet"; for a record update: "update". - /// - \p blocks -- The registration length in blocks; omitted for registrations (such as + /// - `blocks` -- The registration length in blocks; omitted for registrations (such as /// Session/Wallets) that do not expire. - /// - \p name_hash -- The hashed name of the record being purchased/updated. Encoded in hex + /// - `name_hash` -- The hashed name of the record being purchased/updated. Encoded in hex /// for json requests. Note that the actual name is not provided on the blockchain. - /// - \p prev_txid -- For an update this field is set to the txid of the previous ONS update + /// - `prev_txid` -- For an update this field is set to the txid of the previous ONS update /// or registration (i.e. the most recent transaction that this record is updating). - /// - \p value -- The encrypted value of the record (in hex for json requests) being - /// set/updated. \see ONS_RESOLVE for details on encryption/decryption. - /// - \p owner -- the owner of this record being set in a registration or update; this can + /// - `value` -- The encrypted value of the record (in hex for json requests) being + /// set/updated. See [`ons_resolve`](#ons_resolve) for details on encryption/decryption. + /// - `owner` -- the owner of this record being set in a registration or update; this can /// be a primary wallet address, wallet subaddress, or a plain public key. - /// - \p backup_owner -- an optional backup owner who also has permission to edit the + /// - `backup_owner` -- an optional backup owner who also has permission to edit the /// record. - /// - \p stake_amount -- Set to the calculated transaction stake amount (only applicable if the + /// - `stake_amount` -- Set to the calculated transaction stake amount (only applicable if the /// transaction is a service node registration or stake). - /// - \p mempool_key_images -- dict of spent key images of mempool transactions. Only included + /// - `mempool_key_images` -- dict of spent key images of mempool transactions. Only included /// when `memory_pool` is set to true. Each key is the key image (in hex, for json requests) /// and each value is a list of transaction hashes that spend that key image (typically just /// one, but in the case of conflicting transactions there can be multiple). @@ -273,29 +292,18 @@ namespace cryptonote::rpc { struct request_parameters { - /// List of transaction hashes to look up. (Will also be accepted as json input key - /// "txs_hashes" for backwards compatibility). Exclusive of `memory_pool`. std::vector tx_hashes; - /// If true then return all transactions and spent key images currently in the memory pool. - /// This field is exclusive of `tx_hashes`. bool memory_pool = false; - /// If set to true then parse and return tx-extra information bool tx_extra = false; - /// If set to true then include the raw tx-extra information in the tx_extra_raw field. This - /// will be hex-encoded for json, raw bytes for bt-encoded requests. bool tx_extra_raw = false; - /// Controls whether the `data` (or `pruned`, if pruned) field containing raw tx data is - /// included. By default it is not included; you typically want `details` rather than this - /// field. bool data = false; - /// If set to true then always split transactions into non-prunable and prunable parts in the - /// response. bool split = false; - /// Like `split`, but also omits the prunable part of transactions from the response details. bool prune = false; } request; }; + /// RPC: daemon/get_transaction_pool + /// /// DEPRECATED. This endpoint is for backwards compatibility for old clients obtaining /// transactions in the transaction pool. The replacement is to use `get_transactions` with /// `"memory_pool": true`. @@ -312,21 +320,24 @@ namespace cryptonote::rpc { static constexpr auto names() { return NAMES("get_transaction_pool"); } }; + + /// RPC: blockchain/is_key_image_spent + /// /// Queries whether outputs have been spent using the key image associated with the output. /// /// Inputs: /// - /// - \p key_images list of key images to check. For json requests these must be hex or + /// - `key_images` -- list of key images to check. For json requests these must be hex or /// base64-encoded; for bt-requests they can be hex/base64 or raw bytes. /// - /// Outputs + /// Outputs: /// - /// - \p status General RPC status string. `"OK"` means everything looks good. - /// - \p spent_status array of status codes returned in the same order as the `key_images` input. + /// - `status` -- General RPC status string. `"OK"` means everything looks good. + /// - `spent_status` -- array of status codes returned in the same order as the `key_images` input. /// Each value is one of: - /// - \p 0 the key image is unspent - /// - \p 1 the key image is spent in a mined block - /// - \p 2 the key image is spent in a transaction currently in the mempool + /// - `0` -- the key image is unspent + /// - `1` -- the key image is spent in a mined block + /// - `2` -- the key image is spent in a transaction currently in the mempool struct IS_KEY_IMAGE_SPENT : PUBLIC, LEGACY { static constexpr auto names() { return NAMES("is_key_image_spent"); } @@ -343,26 +354,27 @@ namespace cryptonote::rpc { }; - //----------------------------------------------- + /// RPC: blockchain/get_outs + /// /// Retrieve transaction outputs /// /// Inputs: /// - /// - \p outputs Array of output indices. For backwards compatibility these may also be passed as + /// - `outputs` -- Array of output indices. For backwards compatibility these may also be passed as /// an array of {"amount":0,"index":n} dicts. - /// - \p get_txid Request the TXID (i.e. hash) of the transaction as well. - /// - \p as_tuple Requests the returned outs variable as a tuple of values rather than a dict. + /// - `get_txid` -- Request the TXID (i.e. hash) of the transaction as well. + /// - `as_tuple` -- Requests the returned outs variable as a tuple of values rather than a dict. /// - /// Output values available from a public RPC endpoint: + /// Outputs: /// - /// - \p status General RPC status string. `"OK"` means everything looks good. - /// - \p outs List of outkey information; if `as_tuple` is not set then these are dicts containing + /// - `status` -- General RPC status string. `"OK"` means everything looks good. + /// - `outs` -- List of outkey information; if `as_tuple` is not set then these are dicts containing /// keys: - /// - \p key The public key of the output. - /// - \p mask - /// - \p unlocked States if output is locked (`false`) or not (`true`). - /// - \p height Block height of the output. - /// - \p txid Transaction id; only present if requested via the `get_txid` parameter. + /// - `key` -- The public key of the output. + /// - `mask` + /// - `unlocked` -- States if output is locked (`false`) or not (`true`). + /// - `height` -- Block height of the output. + /// - `txid` -- Transaction id; only present if requested via the `get_txid` parameter. /// Otherwise, when `as_tuple` is set, these are 4- or 5-element arrays (depending on whether /// `get_txid` is desired) containing the values in the order listed above. struct GET_OUTPUTS : PUBLIC, LEGACY @@ -380,48 +392,50 @@ namespace cryptonote::rpc { } request; }; + /// RPC: blockchain/submit_transaction + /// /// Submit a transaction to be broadcast to the network. /// /// Inputs: /// - /// - \p tx the full transaction data itself. Can be hex- or base64-encoded for json requests; + /// - `tx` -- the full transaction data itself. Can be hex- or base64-encoded for json requests; /// can also be those or raw bytes for bt-encoded requests. For backwards compatibility, - /// hex-encoded data can also be passed in a json request via the parameter \p tx_as_hex but + /// hex-encoded data can also be passed in a json request via the parameter `tx_as_hex` but /// that is deprecated and will eventually be removed. - /// - \p blink Should be set to true if this transaction is a blink transaction that should be + /// - `blink` -- Should be set to true if this transaction is a blink transaction that should be /// submitted to a blink quorum rather than distributed through the mempool. /// - /// Output values available from a public RPC endpoint: + /// Output: /// - /// - \p status General RPC status string. `"OK"` means everything looks good. - /// - \p reason String containing additional information on why a transaction failed. - /// - \p blink_status Set to the result of submitting this transaction to the Blink quorum. 1 + /// - `status` -- General RPC status string. `"OK"` means everything looks good. + /// - `reason` -- String containing additional information on why a transaction failed. + /// - `blink_status` -- Set to the result of submitting this transaction to the Blink quorum. 1 /// means the quorum rejected the transaction; 2 means the quorum accepted it; 3 means there was /// a timeout connecting to or waiting for a response from the blink quorum. Note that a /// timeout response does *not* necessarily mean the transaction has not made it to the network. - /// - \p not_relayed will be set to true if some problem with the transactions prevents it from + /// - `not_relayed` -- will be set to true if some problem with the transactions prevents it from /// being relayed to the network, omitted otherwise. - /// - \p reason_codes If the transaction was rejected this will be set to a set of reason string + /// - `reason_codes` -- If the transaction was rejected this will be set to a set of reason string /// codes indicating why the transaction failed: - /// - \c "failed" -- general "bad transaction" code - /// - \c "altchain" -- the transaction is spending outputs that exist on an altchain. - /// - \c "mixin" -- the transaction has the wrong number of decoys - /// - \c "double_spend" -- the transaction is spending outputs that are already spent - /// - \c "invalid_input" -- one or more inputs in the transaction are invalid - /// - \c "invalid_output" -- out or more outputs in the transaction are invalid - /// - \c "too_few_outputs" -- the transaction does not create enough outputs (at least two are + /// - `"failed"` -- general "bad transaction" code + /// - `"altchain"` -- the transaction is spending outputs that exist on an altchain. + /// - `"mixin"` -- the transaction has the wrong number of decoys + /// - `"double_spend"` -- the transaction is spending outputs that are already spent + /// - `"invalid_input"` -- one or more inputs in the transaction are invalid + /// - `"invalid_output"` -- out or more outputs in the transaction are invalid + /// - `"too_few_outputs"` -- the transaction does not create enough outputs (at least two are /// required, currently). - /// - \c "too_big" -- the transaction is too large - /// - \c "overspend" -- the transaction spends (via outputs + fees) more than the inputs - /// - \c "fee_too_low" -- the transaction fee is insufficient - /// - \c "invalid_version" -- the transaction version is invalid (the wallet likely needs an + /// - `"too_big"` -- the transaction is too large + /// - `"overspend"` -- the transaction spends (via outputs + fees) more than the inputs + /// - `"fee_too_low"` -- the transaction fee is insufficient + /// - `"invalid_version"` -- the transaction version is invalid (the wallet likely needs an /// update). - /// - \c "invalid_type" -- the transaction type is invalid - /// - \c "snode_locked" -- one or more outputs are currently staked to a registred service node + /// - `"invalid_type"` -- the transaction type is invalid + /// - `"snode_locked"` -- one or more outputs are currently staked to a registred service node /// and thus are not currently spendable on the blockchain. - /// - \c "blacklisted" -- the outputs are currently blacklisted (from being in the 30-day - /// penalty period following a service node deregistration). - /// - \c "blink" -- the blink transaction failed (see `blink_status`) + /// - `"blacklisted"` -- the outputs are currently blacklisted (from being in the 30-day penalty + /// period following a service node deregistration). + /// - `"blink"` -- the blink transaction failed (see `blink_status`) struct SUBMIT_TRANSACTION : PUBLIC, LEGACY { static constexpr auto names() { return NAMES("submit_transaction", "send_raw_transaction", "sendrawtransaction"); } @@ -433,21 +447,22 @@ namespace cryptonote::rpc { } request; }; - //----------------------------------------------- + /// RPC: daemon/start_mining + /// /// Start mining on the daemon /// /// Inputs: /// - /// - \p miner_address Account address to mine to. - /// - \p threads_count Number of mining threads to run. Defaults to 1 thread if omitted or 0. - /// - \p num_blocks Mine until the blockchain has this many new blocks, then stop (no limit if 0, + /// - `miner_address` -- Account address to mine to. + /// - `threads_count` -- Number of mining threads to run. Defaults to 1 thread if omitted or 0. + /// - `num_blocks` -- Mine until the blockchain has this many new blocks, then stop (no limit if 0, /// the default). - /// - \p slow_mining Do slow mining (i.e. don't allocate RandomX cache); primarily intended for + /// - `slow_mining` -- Do slow mining (i.e. don't allocate RandomX cache); primarily intended for /// testing. /// - /// Output values available from a restricted/admin RPC endpoint: + /// Outputs: /// - /// \p status General RPC status string. `"OK"` means everything looks good. + /// `status` -- General RPC status string. `"OK"` means everything looks good. struct START_MINING : LEGACY { static constexpr auto names() { return NAMES("start_mining"); } @@ -460,122 +475,129 @@ namespace cryptonote::rpc { } request; }; - //----------------------------------------------- + /// RPC: daemon/stop_mining + /// /// Stop mining on the daemon. /// /// Inputs: none /// - /// Output values available from a restricted/admin RPC endpoint: + /// Outputs: /// - /// \p status General RPC status string. `"OK"` means everything looks good. + /// `status` -- General RPC status string. `"OK"` means everything looks good. struct STOP_MINING : LEGACY, NO_ARGS { static constexpr auto names() { return NAMES("stop_mining"); } }; - //----------------------------------------------- + /// RPC: daemon/mining_status + /// /// Get the mining status of the daemon. /// /// Inputs: none /// - /// Output values available from a restricted/admin RPC endpoint: + /// Outputs: /// - /// - \p status General RPC status string. `"OK"` means everything looks good. - /// - \p active States if mining is enabled (`true`) or disabled (`false`). - /// - \p speed Mining power in hashes per seconds. - /// - \p threads_count Number of running mining threads. - /// - \p address Account address daemon is mining to. Empty if not mining. - /// - \p pow_algorithm Current hashing algorithm name - /// - \p block_target The expected time to solve per block, i.e. TARGET_BLOCK_TIME - /// - \p block_reward Block reward for the current block being mined. - /// - \p difficulty The difficulty for the current block being mined. + /// - `status` -- General RPC status string. `"OK"` means everything looks good. + /// - `active` -- States if mining is enabled (`true`) or disabled (`false`). + /// - `speed` -- Mining power in hashes per seconds. + /// - `threads_count` -- Number of running mining threads. + /// - `address` -- Account address daemon is mining to. Empty if not mining. + /// - `pow_algorithm` -- Current hashing algorithm name + /// - `block_target` -- The expected time to solve per block, i.e. TARGET_BLOCK_TIME + /// - `block_reward` -- Block reward for the current block being mined. + /// - `difficulty` -- The difficulty for the current block being mined. struct MINING_STATUS : LEGACY, NO_ARGS { static constexpr auto names() { return NAMES("mining_status"); } }; + /// RPC: network/get_info + /// /// Retrieve general information about the state of the node and the network. /// /// Inputs: none. /// - /// Output values available from a public RPC endpoint: + /// Outputs: /// - /// - \p status General RPC status string. `"OK"` means everything looks good. - /// - \p height Current length of longest chain known to daemon. - /// - \p target_height The height of the next block in the chain. - /// - \p immutable_height The latest height in the blockchain that can not be reorganized (i.e. + /// - `status` -- General RPC status string. `"OK"` means everything looks good. + /// - `height` -- Current length of longest chain known to daemon. + /// - `target_height` -- The height of the next block in the chain. + /// - `immutable_height` -- The latest height in the blockchain that can not be reorganized (i.e. /// is backed by at least 2 Service Node, or 1 hardcoded checkpoint, 0 if N/A). Omitted if it /// cannot be determined (typically because the node is still syncing). - /// - \p pulse will be true if the next expected block is a pulse block, false otherwise. - /// - \p pulse_ideal_timestamp For pulse blocks this is the ideal timestamp of the next block, + /// - `pulse` -- will be true if the next expected block is a pulse block, false otherwise. + /// - `pulse_ideal_timestamp` -- For pulse blocks this is the ideal timestamp of the next block, /// that is, the timestamp if the network was operating with perfect 2-minute blocks since the /// pulse hard fork. - /// - \p pulse_target_timestamp For pulse blocks this is the target timestamp of the next block, + /// - `pulse_target_timestamp` -- For pulse blocks this is the target timestamp of the next block, /// which targets 2 minutes after the previous block but will be slightly faster/slower if the /// previous block is behind/ahead of the ideal timestamp. - /// - \p difficulty Network mining difficulty; omitted when the network is expecting a pulse + /// - `difficulty` -- Network mining difficulty; omitted when the network is expecting a pulse /// block. - /// - \p target Current target for next proof of work. - /// - \p tx_count Total number of non-coinbase transaction in the chain. - /// - \p tx_pool_size Number of transactions that have been broadcast but not included in a block. - /// - \p mainnet Indicates whether the node is on the main network (`true`) or not (`false`). - /// - \p testnet Indicates that the node is on the test network (`true`). Will be omitted for + /// - `target` -- Current target for next proof of work. + /// - `tx_count` -- Total number of non-coinbase transaction in the chain. + /// - `tx_pool_size` -- Number of transactions that have been broadcast but not included in a block. + /// - `mainnet` -- Indicates whether the node is on the main network (`true`) or not (`false`). + /// - `testnet` -- Indicates that the node is on the test network (`true`). Will be omitted for /// non-testnet. - /// - \p devnet Indicates that the node is on the dev network (`true`). Will be omitted for + /// - `devnet` -- Indicates that the node is on the dev network (`true`). Will be omitted for /// non-devnet. - /// - \p fakechain States that the node is running in "fakechain" mode (`true`). Omitted + /// - `fakechain` -- States that the node is running in "fakechain" mode (`true`). Omitted /// otherwise. - /// - \p nettype String value of the network type (mainnet, testnet, devnet, or fakechain). - /// - \p top_block_hash Hash of the highest block in the chain. Will be hex for JSON requests, + /// - `nettype` -- String value of the network type (mainnet, testnet, devnet, or fakechain). + /// - `top_block_hash` -- Hash of the highest block in the chain. Will be hex for JSON requests, /// 32-byte binary value for bt requests. - /// - \p immutable_block_hash Hash of the highest block in the chain that can not be reorganized. + /// - `immutable_block_hash` -- Hash of the highest block in the chain that can not be reorganized. /// Hex string for json, bytes for bt. - /// - \p cumulative_difficulty Cumulative difficulty of all blocks in the blockchain. - /// - \p block_size_limit Maximum allowed block size. - /// - \p block_size_median Median block size of latest 100 blocks. - /// - \p ons_counts ONS registration counts, as a three-element list: [session, wallet, lokinet] - /// - \p offline Indicates that the node is offline, if true. Omitted for online nodes. - /// - \p database_size Current size of Blockchain data. Over public RPC this is rounded up to the + /// - `cumulative_difficulty` -- Cumulative difficulty of all blocks in the blockchain. + /// - `block_size_limit` -- Maximum allowed block size. + /// - `block_size_median` -- Median block size of latest 100 blocks. + /// - `ons_counts` -- ONS registration counts, as a three-element list: [session, wallet, lokinet] + /// - `offline` -- Indicates that the node is offline, if true. Omitted for online nodes. + /// - `database_size` -- Current size of Blockchain data. Over public RPC this is rounded up to the /// next-largest GB value. - /// - \p version Current version of this daemon, as a string. For a public node this will just be + /// - `version` -- Current version of this daemon, as a string. For a public node this will just be /// the major and minor version (e.g. "9"); for an admin rpc endpoint this will return the full /// version (e.g. "9.2.1"). - /// - \p status_line A short one-line summary string of the node (requires an admin/unrestricted + /// - `status_line` -- A short one-line summary string of the node (requires an admin/unrestricted /// connection for most details) /// /// If the endpoint is a restricted (i.e. admin) endpoint then the following fields are also /// included: /// - /// - \p alt_blocks_count Number of alternative blocks to main chain. - /// - \p outgoing_connections_count Number of peers that you are connected to and getting + /// - `alt_blocks_count` -- Number of alternative blocks to main chain. + /// - `outgoing_connections_count` -- Number of peers that you are connected to and getting /// information from. - /// - \p incoming_connections_count Number of peers connected to and pulling from your node. - /// - \p white_peerlist_size White Peerlist Size - /// - \p grey_peerlist_size Grey Peerlist Size - /// - \p service_node Will be true if the node is running in --service-node mode. - /// - \p start_time Start time of the daemon, as UNIX time. - /// - \p last_storage_server_ping Last ping time of the storage server (0 if never or not running + /// - `incoming_connections_count` -- Number of peers connected to and pulling from your node. + /// - `white_peerlist_size` -- White Peerlist Size + /// - `grey_peerlist_size` -- Grey Peerlist Size + /// - `service_node` -- Will be true if the node is running in --service-node mode. + /// - `start_time` -- Start time of the daemon, as UNIX time. + /// - `last_storage_server_ping` -- Last ping time of the storage server (0 if never or not running /// as a service node) - /// - \p last_lokinet_ping Last ping time of lokinet (0 if never or not running as a service node) - /// - \p free_space Available disk space on the node. + /// - `last_lokinet_ping` -- Last ping time of lokinet (0 if never or not running as a service node) + /// - `free_space` -- Available disk space on the node. + /// + /// Example-JSON-Fetch struct GET_INFO : PUBLIC, LEGACY, NO_ARGS { static constexpr auto names() { return NAMES("get_info", "getinfo"); } }; - //----------------------------------------------- - /// Retrieve general information about the state of the network. + /// RPC: daemon/get_net_stats + /// + /// Retrieve general information about the network statistics of the daemon. /// /// Inputs: none. /// - /// Output values available from a restricted/admin RPC endpoint: + /// Outputs: /// - /// - \p status General RPC status string. `"OK"` means everything looks good. - /// - \p start_time something. - /// - \p total_packets_in something. - /// - \p total_bytes_in something. - /// - \p total_packets_out something. - /// - \p total_bytes_out something. + /// - `status` -- General RPC status string. `"OK"` means everything looks good. + /// - `start_time` -- something. + /// - `total_packets_in` -- something. + /// - `total_bytes_in` -- something. + /// - `total_packets_out` -- something. + /// - `total_bytes_out` -- something. struct GET_NET_STATS : LEGACY, NO_ARGS { static constexpr auto names() { return NAMES("get_net_stats"); } @@ -583,46 +605,70 @@ namespace cryptonote::rpc { }; - //----------------------------------------------- + /// RPC: daemon/save_bc + /// /// Save the blockchain. The blockchain does not need saving and is always saved when modified, /// however it does a sync to flush the filesystem cache onto the disk for safety purposes, /// against Operating System or Hardware crashes. /// /// Inputs: none /// - /// Output values available from a restricted/admin RPC endpoint: + /// Outputs: /// - /// - \p status General RPC status string. `"OK"` means everything looks good. + /// - `status` -- General RPC status string. `"OK"` means everything looks good. struct SAVE_BC : LEGACY, NO_ARGS { static constexpr auto names() { return NAMES("save_bc"); } }; - //----------------------------------------------- + /// RPC: blockchain/get_block_count + /// /// Look up how many blocks are in the longest chain known to the node. /// /// Inputs: none /// - /// Output values available from a public RPC endpoint: + /// Outputs: /// - /// - \p status General RPC status string. `"OK"` means everything looks good. - /// - \p count Number of blocks in logest chain seen by the node. + /// - `status` -- General RPC status string. `"OK"` means everything looks good. + /// - `count` -- Number of blocks in logest chain seen by the node. + /// + /// Example-JSON-Fetch struct GET_BLOCK_COUNT : PUBLIC, NO_ARGS { static constexpr auto names() { return NAMES("get_block_count", "getblockcount"); } }; + /// RPC: blockchain/get_block_hash + /// /// Look up one or more blocks' hashes by their height. /// /// Inputs: /// - heights array of block heights of which to look up the block hashes. Accepts at most 1000 /// heights per request. /// - /// Output values are pairs of heights as keys to block hashes as values: - /// - \p status General RPC status string. `"OK"` means everything looks good. - /// - \p height the current blockchain height of this node - /// - \p the block hash of the block with the given height. Note that each height key is - /// the stringified integer value, e.g. "3456" rather than 3456. + /// Output: + /// + /// - `status` -- General RPC status string. `"OK"` means everything looks good. + /// - `height` -- the current blockchain height of this node + /// - `""` the block hash of the block with the given height. Note that each height key + /// is the stringified integer value, e.g. "3456" rather than 3456. + /// + /// Example input: + /// + /// ```json + /// { "heights": [42, 123456] } + /// ``` + /// + /// Example output: + /// + /// ```json + /// { + /// "status": "OK", + /// "height": 123456, + /// "42": "b269367374fa87ec517405bf120f831e9b13b12c0ee6721dcca69d2c0fe73a0f", + /// "123456": "aa1f3b566aba42e522f8097403a3c513069206286ff08c2ff2871757dbc3e436" + /// } + /// ``` struct GET_BLOCK_HASH : PUBLIC { static constexpr auto names() { return NAMES("get_block_hash", "on_get_block_hash", "on_getblockhash"); } @@ -634,47 +680,86 @@ namespace cryptonote::rpc { } request; }; - OXEN_RPC_DOC_INTROSPECT + // FIXME: This struct should go; it's just a bit of indirection (in _commands_defs.cpp) that isn't + // solve anything (because we can just set the fields directly in the output json values rather + // than use `fill_block_header_response`). struct block_header_response { - uint8_t major_version; // The major version of the oxen protocol at this block height. - uint8_t minor_version; // The minor version of the oxen protocol at this block height. - uint64_t timestamp; // The unix time at which the block was recorded into the blockchain. - std::string prev_hash; // The hash of the block immediately preceding this block in the chain. - uint32_t nonce; // A cryptographic random one-time number used in mining a Loki block. - bool orphan_status; // Usually `false`. If `true`, this block is not part of the longest chain. - uint64_t height; // The number of blocks preceding this block on the blockchain. - uint64_t depth; // The number of blocks succeeding this block on the blockchain. A larger number means an older block. - std::string hash; // The hash of this block. - difficulty_type difficulty; // The strength of the Loki network based on mining power. - difficulty_type cumulative_difficulty; // The cumulative strength of the Loki network based on mining power. - uint64_t reward; // The amount of new OXEN (in atomic units) generated in this block and allocated to service nodes and governance. As of Oxen 10 (HF 19) this is the *earned* amount, but not the *paid* amount which occurs in batches. - uint64_t coinbase_payouts; // The amount of OXEN paid out in this block. As of Oxen 10 (HF 19), this reflects the current batched amounts being paid from earnings batched over previous blocks, not the amounts *earned* in the current block. - uint64_t block_size; // The block size in bytes. - uint64_t block_weight; // The block weight in bytes. - uint64_t num_txes; // Number of transactions in the block, not counting the coinbase tx. - std::optional pow_hash; // The hash of the block's proof of work (requires `fill_pow_hash`) - uint64_t long_term_weight; // Long term weight of the block. - std::string miner_tx_hash; // The TX hash of the miner transaction - std::vector tx_hashes; // The TX hashes of all non-coinbase transactions (requires `get_tx_hashes`) - std::string service_node_winner; // Service node that received a reward for this block - - KV_MAP_SERIALIZABLE + uint8_t major_version; + uint8_t minor_version; + uint64_t timestamp; + std::string prev_hash; + uint32_t nonce; + bool orphan_status; + uint64_t height; + uint64_t depth; + std::string hash; + difficulty_type difficulty; + difficulty_type cumulative_difficulty; + uint64_t reward; + uint64_t coinbase_payouts; + uint64_t block_size; + uint64_t block_weight; + uint64_t num_txes; + std::optional pow_hash; + uint64_t long_term_weight; + std::string miner_tx_hash; + std::vector tx_hashes; + std::string service_node_winner; }; void to_json(nlohmann::json& j, const block_header_response& h); void from_json(const nlohmann::json& j, block_header_response& h); - /// Block header information for the most recent block is easily retrieved with this method. No inputs are needed. + /// RPC: blockchain/get_last_block_header + /// + /// Block header information for the most recent block is easily retrieved with this method. No + /// inputs are needed. /// /// Inputs: - /// - \p fill_pow_hash Tell the daemon if it should fill out pow_hash field. - /// - \p get_tx_hashes If true (default false) then include the hashes of non-coinbase transactions + /// - `fill_pow_hash` -- Tell the daemon if it should fill out pow_hash field. + /// - `get_tx_hashes` -- If true (default false) then include the hashes of non-coinbase + /// transactions /// - /// Output values available from a public RPC endpoint: + /// Outputs: /// - /// - \p status General RPC status string. `"OK"` means everything looks good. - /// - \p block_header A structure containing block header information. + /// - `status` -- General RPC status string. `"OK"` means everything looks good. + /// - `block_header` -- A dict containing block header information. Contains keys: + /// - `major_version` -- The major version of the oxen protocol at this block height. + /// - `minor_version` -- The minor version of the oxen protocol at this block height. + /// - `timestamp` -- The unix time at which the block was recorded into the blockchain. + /// - `prev_hash` -- The hash of the block immediately preceding this block in the chain. + /// - `nonce` -- A cryptographic random one-time number used in mining a Loki block. + /// - `orphan_status` -- Usually `false`. If `true`, this block is not part of the longest + /// chain. + /// - `height` -- The number of blocks preceding this block on the blockchain. + /// - `depth` -- The number of blocks succeeding this block on the blockchain. A larger number + /// means an older block. + /// - `hash` -- The hash of this block. + /// - `difficulty` -- The strength of the Loki network based on mining power. + /// - `cumulative_difficulty` -- The cumulative strength of the Loki network based on mining + /// power. + /// - `reward` -- The amount of new OXEN (in atomic units) generated in this block and allocated + /// to service nodes and governance. As of Oxen 10 (HF 19) this is the *earned* amount, but + /// not the *paid* amount which occurs in batches. + /// - `coinbase_payouts` -- The amount of OXEN paid out in this block. As of Oxen 10 (HF 19), + /// this reflects the current batched amounts being paid from earnings batched over previous + /// blocks, not the amounts *earned* in the current block. + /// - `block_size` -- The block size in bytes. + /// - `block_weight` -- The block weight in bytes. + /// - `num_txes` -- Number of transactions in the block, not counting the coinbase tx. + /// - `pow_hash` -- The hash of the block's proof of work (requires `fill_pow_hash`) + /// - `long_term_weight` -- Long term weight of the block. + /// - `miner_tx_hash` -- The TX hash of the miner transaction + /// - `tx_hashes` -- The TX hashes of all non-coinbase transactions (requires `get_tx_hashes`) + /// - `service_node_winner` -- Service node that received a reward for this block + /// + /// Example input: + /// ```json + /// {} + /// ``` + /// + /// Example-JSON-Fetch struct GET_LAST_BLOCK_HEADER : PUBLIC { static constexpr auto names() { return NAMES("get_last_block_header", "getlastblockheader"); } @@ -686,106 +771,127 @@ namespace cryptonote::rpc { } request; }; - OXEN_RPC_DOC_INTROSPECT - /// Block header information can be retrieved using either a block's hash or height. This method includes a block's hash as an input parameter to retrieve basic information about the block. + /// RPC: blockchain/get_block_header_by_hash + /// + /// Block header information can be retrieved using either a block's hash or height. This method + /// includes a block's hash as an input parameter to retrieve basic information about the block. /// /// Inputs: - /// - \p hash The block's SHA256 hash. - /// - \p hashes Request multiple blocks via an array of hashes - /// - \p fill_pow_hash Tell the daemon if it should fill out pow_hash field. - /// - \p get_tx_hashes If true (default false) then include the hashes of non-coinbase transactions + /// - `hash` -- The block's hash. + /// - `hashes` -- Request multiple blocks via an array of hashes + /// - `fill_pow_hash` -- Tell the daemon if it should fill out pow_hash field. + /// - `get_tx_hashes` -- If true (default false) then include the hashes of non-coinbase + /// transactions /// - /// Output values available from a public RPC endpoint: + /// Outputs: /// - /// - \p status General RPC status string. `"OK"` means everything looks good. - /// - \p block_header Block header information for the requested `hash` block - /// - \p block_headers Block header information for the requested `hashes` blocks + /// - `status` -- General RPC status string. `"OK"` means everything looks good. + /// - `block_header` -- Block header information for the requested `hash` block + /// - `block_headers` -- Block header information for the requested `hashes` blocks struct GET_BLOCK_HEADER_BY_HASH : PUBLIC { static constexpr auto names() { return NAMES("get_block_header_by_hash", "getblockheaderbyhash"); } struct request_parameters { - std::string hash; // The block's SHA256 hash. - std::vector hashes; // Request multiple blocks via an array of hashes - bool fill_pow_hash; // Tell the daemon if it should fill out pow_hash field. - bool get_tx_hashes; // If true (default false) then include the hashes of non-coinbase transactions + std::string hash; + std::vector hashes; + bool fill_pow_hash; + bool get_tx_hashes; } request; }; - /// Similar to get_block_header_by_hash above, this method includes a block's height as an input parameter to retrieve basic information about the block. + /// RPC: blockchain/get_block_header_by_height + /// + /// Similar to get_block_header_by_hash above, this method includes a block's height as an input + /// parameter to retrieve basic information about the block. /// /// Inputs: /// - /// - \p height A block height to look up; returned in `block_header` - /// - \p heights Block heights to retrieve; returned in `block_headers` - /// - \p fill_pow_hash Tell the daemon if it should fill out pow_hash field. - /// - \p get_tx_hashes If true (default false) then include the hashes of non-coinbase transactions + /// - `height` -- A block height to look up; returned in `block_header` + /// - `heights` -- Block heights to retrieve; returned in `block_headers` + /// - `fill_pow_hash` -- Tell the daemon if it should fill out pow_hash field. + /// - `get_tx_hashes` -- If true (default false) then include the hashes of non-coinbase + /// transactions /// - /// Output values available from a public RPC endpoint: + /// Outputs: /// - /// - \p status General RPC status string. `"OK"` means everything looks good. - /// - \p block_header Block header information for the requested `height` block - /// - \p block_headers Block header information for the requested `heights` blocks + /// - `status` -- General RPC status string. `"OK"` means everything looks good. + /// - `block_header` -- Block header information for the requested `height` block + /// - `block_headers` -- Block header information for the requested `heights` blocks struct GET_BLOCK_HEADER_BY_HEIGHT : PUBLIC { static constexpr auto names() { return NAMES("get_block_header_by_height", "getblockheaderbyheight"); } struct request_parameters { - std::optional height; // A block height to look up; returned in `block_header` - std::vector heights; // Block heights to retrieve; returned in `block_headers` - bool fill_pow_hash; // Tell the daemon if it should fill out pow_hash field. - bool get_tx_hashes; // If true (default false) then include the hashes of non-coinbase transactions + std::optional height; + std::vector heights; + bool fill_pow_hash; + bool get_tx_hashes; } request; }; - /// Full block information can be retrieved by either block height or hash, like with the above block header calls. - /// For full block information, both lookups use the same method, but with different input parameters. + /// RPC: blockchain/get_block + /// + /// Full block information can be retrieved by either block height or hash, like with the above + /// block header calls. For full block information, both lookups use the same method, but with + /// different input parameters. /// /// Inputs: /// - /// - \p hash The block's hash. - /// - \p height A block height to look up; returned in `block_header` - /// - \p fill_pow_hash Tell the daemon if it should fill out pow_hash field. + /// - `hash` -- The block's hash. + /// - `height` -- A block height to look up; returned in `block_header` + /// - `fill_pow_hash` -- Tell the daemon if it should fill out pow_hash field. /// - /// Output values available from a public RPC endpoint: + /// Outputs: /// - /// - \p status General RPC status string. `"OK"` means everything looks good. - /// - \p block_header Block header information for the requested `height` block - /// - \p tx_hashes List of hashes of non-coinbase transactions in the block. If there are no other transactions, this will be an empty list. - /// - \p blob Hexadecimal blob of block information. - /// - \p json JSON formatted block details. + /// - `status` -- General RPC status string. `"OK"` means everything looks good. + /// - `block_header` -- Block header information for the requested `height` block + /// - `tx_hashes` -- List of hashes of non-coinbase transactions in the block. If there are no + /// other transactions, this will be an empty list. + /// - `blob` -- Hexadecimal blob of block information. + /// - `json` -- JSON formatted block details. + /// + /// Example input: + /// + /// ```json + /// { "height": 42 } + /// ``` + /// + /// Example-JSON-Fetch struct GET_BLOCK : PUBLIC { static constexpr auto names() { return NAMES("get_block", "getblock"); } struct request_parameters { - std::string hash; // The block's hash. - uint64_t height; // The block's height. - bool fill_pow_hash; // Tell the daemon if it should fill out pow_hash field. + std::string hash; + uint64_t height; + bool fill_pow_hash; } request; }; + /// RPC: daemon/get_peer_list + /// /// Get the list of current network peers known to this node. /// /// Inputs: none /// - /// Output values (requires a restricted/admin RPC endpoint): + /// Output: /// - /// - \p status General RPC status string. `"OK"` means everything looks good. - /// - \p white_list list of "whitelist" peers (see below), that is, peers that were recorded + /// - `status` -- General RPC status string. `"OK"` means everything looks good. + /// - `white_list` -- list of "whitelist" peers (see below), that is, peers that were recorded /// reachable the last time this node connected to them. Peers that are unreachable or not /// synchronized with the network are moved to the graylist. - /// - \p gray_list list of peers (see below) that this node knows of but has not (recently) tried + /// - `gray_list` -- list of peers (see below) that this node knows of but has not (recently) tried /// to connect to. /// /// Each peer list is an array of dicts containing the following fields: - /// - \p id a unique integer locally identifying the peer - /// - \p host the peer's IP address (as a string) - /// - \p port the port on which the peer is reachable - /// - \p last_seen unix timestamp when this node last connected to the peer. Will be omitted if + /// - `id` -- a unique integer locally identifying the peer + /// - `host` -- the peer's IP address (as a string) + /// - `port` -- the port on which the peer is reachable + /// - `last_seen` -- unix timestamp when this node last connected to the peer. Will be omitted if /// never connected (e.g. for a peer we received from another node but haven't yet tried). struct GET_PEER_LIST : LEGACY { @@ -798,41 +904,37 @@ namespace cryptonote::rpc { }; + /// RPC: daemon/set_log_level + /// /// Set the daemon log level. By default, log level is set to `0`. For more fine-tuned logging /// control set the set_log_categories command instead. /// /// Inputs: - /// - \p level Daemon log level to set from `0` (less verbose) to `4` (most verbose) + /// - `level` -- Daemon log level to set from `0` (less verbose) to `4` (most verbose) /// - /// Output values (requires a restricted/admin RPC endpoint): + /// Output: /// - /// - \p status General RPC status string. `"OK"` means everything looks good. + /// - `status` -- General RPC status string. `"OK"` means everything looks good. struct SET_LOG_LEVEL : LEGACY { static constexpr auto names() { return NAMES("set_log_level"); } struct request_parameters { - int8_t level; // Daemon log level to set from `0` (less verbose) to `4` (most verbose) - + int8_t level; } request; }; - /// Set the daemon log categories. Categories are represented as a comma separated list of - /// `:` (similarly to syslog standard `:`), where: - /// Category is one of the following: * (all facilities), default, net, net.http, net.p2p, - /// logging, net.trottle, blockchain.db, blockchain.db.lmdb, bcutil, checkpoints, net.dns, net.dl, - /// i18n, perf,stacktrace, updates, account, cn ,difficulty, hardfork, miner, blockchain, txpool, - /// cn.block_queue, net.cn, daemon, debugtools.deserialize, debugtools.objectsizes, device.ledger, - /// wallet.gen_multisig, multisig, bulletproofs, ringct, daemon.rpc, wallet.simplewallet, - /// WalletAPI, wallet.ringdb, wallet.wallet2, wallet.rpc, tests.core. + /// RPC: daemon/set_log_categories /// - /// Level is one of the following: FATAL - higher level, ERROR, WARNING, INFO, DEBUG, TRACE. + /// Set the daemon log categories for debugging purposes. /// - /// Lower level A level automatically includes higher level. By default, categories are set to: - /// `*:WARNING,net:FATAL,net.p2p:FATAL,net.cn:FATAL,global:INFO,verify:FATAL,stacktrace:INFO,logging:INFO,msgwriter:INFO` - /// Setting the categories to "" prevents any log output. + /// Categories are represented as a comma separated list of `:`, where + /// `` is is one of the various internal debugging categories defined in the oxen source + /// code, or `*` to refer to all logging categories. + /// + /// Level is one of the following: FATAL, ERROR, WARNING, INFO, DEBUG, TRACE. /// /// You can append to the current the log level for updating just one or more categories while /// leaving other log levels unchanged by specifying one or more ":" pairs @@ -840,73 +942,75 @@ namespace cryptonote::rpc { /// /// Inputs: /// - /// - \p categories Optional, daemon log categores to enable + /// - `categories` -- Optional, daemon log categores to enable /// - /// Output values (requires a restricted/admin RPC endpoint): + /// Output: /// - /// - \p status General RPC status string. `"OK"` means everything looks good. - /// - \p categories Daemon log enabled categories + /// - `status` -- General RPC status string. `"OK"` means everything looks good. + /// - `categories` -- Daemon log enabled categories struct SET_LOG_CATEGORIES : LEGACY { static constexpr auto names() { return NAMES("set_log_categories"); } struct request_parameters { - std::string categories; // Optional, daemon log categories to enable + std::string categories; } request; }; - //----------------------------------------------- + /// RPC: blockchain/get_transaction_pool_hashes + /// /// Get hashes from transaction pool. /// /// Inputs: none /// - /// Output values available from a public RPC endpoint: + /// Outputs: /// - /// - \p status General RPC status string. `"OK"` means everything looks good. - /// - \p tx_hashes List of transaction hashes, + /// - `status` -- General RPC status string. `"OK"` means everything looks good. + /// - `tx_hashes` -- List of transaction hashes, struct GET_TRANSACTION_POOL_HASHES : PUBLIC, LEGACY, NO_ARGS { static constexpr auto names() { return NAMES("get_transaction_pool_hashes"); } }; - //----------------------------------------------- + /// RPC: blockchain/get_transaction_pool_stats + /// /// Get the transaction pool statistics. /// /// Inputs: none /// - /// Output values available from a public RPC endpoint: + /// Outputs: /// - /// - \p status General RPC status string. `"OK"` means everything looks good. - /// - \p pool_stats Dict of pool statistics: - /// - \p bytes_total the total size (in bytes) of the transactions in the transaction pool. - /// - \p bytes_min the size of the smallest transaction in the tx pool. - /// - \p bytes_max the size of the largest transaction in the pool. - /// - \p bytes_med the median transaction size in the pool. - /// - \p fee_total the total fees of all transactions in the transaction pool. - /// - \p txs_total the total number of transactions in the transaction pool - /// - \p num_failing the number of failing transactions: that is, transactions that are in the + /// - `status` -- General RPC status string. `"OK"` means everything looks good. + /// - `pool_stats` -- Dict of pool statistics: + /// - `bytes_total` -- the total size (in bytes) of the transactions in the transaction pool. + /// - `bytes_min` -- the size of the smallest transaction in the tx pool. + /// - `bytes_max` -- the size of the largest transaction in the pool. + /// - `bytes_med` -- the median transaction size in the pool. + /// - `fee_total` -- the total fees of all transactions in the transaction pool. + /// - `txs_total` -- the total number of transactions in the transaction pool + /// - `num_failing` -- the number of failing transactions: that is, transactions that are in the /// mempool but are not currently eligible to be added to the blockchain. - /// - \p num_10m the number of transactions received within the last ten minutes - /// - \p num_not_relayed the number of transactions which are not being relayed to the - /// network. Only included when the \p include_unrelayed request parameter is set to true. - /// - \p num_double_spends the number of transactions in the mempool that are marked as + /// - `num_10m` -- the number of transactions received within the last ten minutes + /// - `num_not_relayed` -- the number of transactions which are not being relayed to the + /// network. Only included when the `include_unrelayed` request parameter is set to true. + /// - `num_double_spends` -- the number of transactions in the mempool that are marked as /// double-spends of existing blockchain transactions. - /// - \p oldest the unix timestamp of the oldest transaction in the pool. - /// - \p histo pairs of [# txes, size of bytes] that form a histogram of transactions in the + /// - `oldest` -- the unix timestamp of the oldest transaction in the pool. + /// - `histo` -- pairs of [# txes, size of bytes] that form a histogram of transactions in the /// mempool, if there are at least two transactions in the mempool (and omitted entirely /// otherwise). When present, this field will contain 10 pairs: /// - When `histo_max` is given then `histo` consists of 10 equally-spaced bins from - /// newest to oldest where the newest bin begins at age 0 and the oldest bin ends at age `\p - /// histo_max`. For example, bin `[3]` contains statistics for transactions with ages + /// newest to oldest where the newest bin begins at age 0 and the oldest bin ends at age + /// `histo_max`. For example, bin `[3]` contains statistics for transactions with ages /// between `3*histo_max/10` and `4*histo_max/10`. /// - Otherwise `histo_98pc` will be present in which case `histo` contains 9 equally spaced /// bins from newest to oldest where the newest bin begins at age 0 and the oldest bin ends /// at age `histo_98pc`, and at least 98% of the mempool transactions will fall in these 9 /// bins. The 10th bin contains statistics for all transactions with ages greater than /// `histo_98pc`. - /// - \p histo_98pc See `histo` for details. - /// - \p histo_max See `histo` for details. + /// - `histo_98pc` -- See `histo` for details. + /// - `histo_max` -- See `histo` for details. struct GET_TRANSACTION_POOL_STATS : PUBLIC, LEGACY { static constexpr auto names() { return NAMES("get_transaction_pool_stats"); } @@ -919,113 +1023,194 @@ namespace cryptonote::rpc { } request; }; + /// RPC: daemon/get_connections + /// /// Retrieve information about incoming and outgoing P2P connections to your node. /// /// Inputs: none /// - /// Output values available from a public RPC endpoint: + /// Outputs: /// - /// - \p status General RPC status string. `"OK"` means everything looks good. - /// - \p connections List of all connections and their info; each element is a dict containing: - /// - \p incoming bool of whether this connection was established by the remote to us (true) or + /// - `status` -- General RPC status string. `"OK"` means everything looks good. + /// - `connections` -- List of all connections and their info; each element is a dict containing: + /// - `incoming` -- bool of whether this connection was established by the remote to us (true) or /// by us to the remove (false). - /// - \p ip address of the remote peer - /// - \p port the remote port of the peer connection - /// - \p address_type - 1/2/3/4 for ipv4/ipv6/i2p/tor, respectively. - /// - \p peer_id a string that uniquely identifies a peer node - /// - \p recv_count number of bytes of data received from this peer - /// - \p recv_idle_ms number of milliseconds since we last received data from this peer - /// - \p send_count number of bytes of data send to this peer - /// - \p send_idle_ms number of milliseconds since we last sent data to this peer - /// - \p state returns the current state of the connection with this peer as a string, one of: - /// - \c before_handshake - the connection is still being established/negotiated - /// - \c synchronizing - we are synchronizing the blockchain with this peer - /// - \c standby - the peer is available for synchronizing but we are not currently using it - /// - \c normal - this is a regular, synchronized peer - /// - \p live_ms - number of milliseconds since this connection was initiated - /// - \p avg_download - the average download speed from this peer in bytes per second - /// - \p current_download - the current (i.e. average over a very recent period) download speed + /// - `ip` -- address of the remote peer + /// - `port` -- the remote port of the peer connection + /// - `address_type` -- 1/2/3/4 for ipv4/ipv6/i2p/tor, respectively. + /// - `peer_id` -- a string that uniquely identifies a peer node + /// - `recv_count` -- number of bytes of data received from this peer + /// - `recv_idle_ms` -- number of milliseconds since we last received data from this peer + /// - `send_count` -- number of bytes of data send to this peer + /// - `send_idle_ms` -- number of milliseconds since we last sent data to this peer + /// - `state` -- returns the current state of the connection with this peer as a string, one of: + /// - `"before_handshake"` -- the connection is still being established/negotiated + /// - `"synchronizing"` -- we are synchronizing the blockchain with this peer + /// - `"standby"` -- the peer is available for synchronizing but we are not currently using it + /// - `"normal"` -- this is a regular, synchronized peer + /// - `live_ms` -- number of milliseconds since this connection was initiated + /// - `avg_download` -- the average download speed from this peer in bytes per second + /// - `current_download` -- the current (i.e. average over a very recent period) download speed /// from this peer in bytes per second. - /// - \p avg_upload - the average upload speed to this peer in bytes per second - /// - \p current_upload - the current upload speed to this peer in bytes per second - /// - \p connection_id - a unique random string identifying this connection - /// - \p height - the height of the peer - /// - \p host - the hostname for this peer; only included if != \p ip - /// - \p localhost - set to true if the peer is a localhost connection; omitted otherwise. - /// - \p local_ip - set to true if the peer is a non-public, local network connection; omitted + /// - `avg_upload` -- the average upload speed to this peer in bytes per second + /// - `current_upload` -- the current upload speed to this peer in bytes per second + /// - `connection_id` -- a unique random string identifying this connection + /// - `height` -- the height of the peer + /// - `host` -- the hostname for this peer; only included if not the same as `ip` + /// - `localhost` -- set to true if the peer is a localhost connection; omitted otherwise. + /// - `local_ip` -- set to true if the peer is a non-public, local network connection; omitted /// otherwise. + /// + /// Example output: + /// ```json + /// { + /// "connections": [ + /// { + /// "address": "1.2.3.4:51890", + /// "address_type": 1, + /// "avg_download": 0, + /// "avg_upload": 2, + /// "connection_id": "abcdef0123456789abcdef0123456789", + /// "current_download": 0, + /// "current_upload": 0, + /// "height": 1088107, + /// "host": "1.2.3.4", + /// "incoming": true, + /// "ip": "1.2.3.4", + /// "live_time": 33, + /// "local_ip": false, + /// "localhost": false, + /// "peer_id": "fedcba9876543210", + /// "port": "51890", + /// "pruning_seed": 0, + /// "recv_count": 20628, + /// "recv_idle_time": 0, + /// "rpc_port": 0, + /// "send_count": 83253, + /// "send_idle_time": 0, + /// "state": "normal", + /// "support_flags": 1 + /// }, + /// { + /// "address": "5.6.7.8:22022", + /// "address_type": 1, + /// "avg_download": 1, + /// "avg_upload": 1, + /// "connection_id": "00112233445566778899aabbccddeeff", + /// "current_download": 0, + /// "current_upload": 0, + /// "height": 1088107, + /// "host": "5.6.7.8", + /// "incoming": false, + /// "ip": "5.6.7.8", + /// "live_time": 66, + /// "local_ip": false, + /// "localhost": false, + /// "peer_id": "ffddbb9977553311", + /// "port": "22022", + /// "pruning_seed": 0, + /// "recv_count": 95687, + /// "recv_idle_time": 0, + /// "rpc_port": 0, + /// "send_count": 85542, + /// "send_idle_time": 0, + /// "state": "normal", + /// "support_flags": 1 + /// } + /// ], + /// "status": "OK" + /// } + /// ``` struct GET_CONNECTIONS : NO_ARGS { static constexpr auto names() { return NAMES("get_connections"); } }; + /// RPC: blockchain/get_block_headers_range + /// /// Similar to get_block_header_by_height above, but for a range of blocks. /// This method includes a starting block height and an ending block height as /// parameters to retrieve basic information about the range of blocks. /// /// Inputs: /// - /// - \p start_height The starting block's height. - /// - \p end_height The ending block's height. - /// - \p fill_pow_hash Tell the daemon if it should fill out pow_hash field. - /// - \p get_tx_hashes If true (default false) then include the hashes of non-coinbase transactions + /// - `start_height` -- The starting block's height. + /// - `end_height` -- The ending block's height. + /// - `fill_pow_hash` -- Tell the daemon if it should fill out pow_hash field. + /// - `get_tx_hashes` -- If true (default false) then include the hashes of non-coinbase + /// transactions /// - /// Output values available from a public RPC endpoint: + /// Outputs: /// - /// - \p status General RPC status string. `"OK"` means everything looks good. - /// - \p headers Array of block_header (a structure containing block header information. See get_last_block_header). + /// - `status` -- General RPC status string. `"OK"` means everything looks good. + /// - `headers` -- Array of block_header (a structure containing block header information. See + /// get_last_block_header). + /// + /// Example input: + /// ```json + /// { "start_height": 1087845, "end_height": 1087847, "get_tx_hashes": true } + /// ``` + /// + /// Example-JSON-Fetch struct GET_BLOCK_HEADERS_RANGE : PUBLIC { static constexpr auto names() { return NAMES("get_block_headers_range", "getblockheadersrange"); } struct request_parameters { - uint64_t start_height; // The starting block's height. - uint64_t end_height; // The ending block's height. - bool fill_pow_hash; // Tell the daemon if it should fill out pow_hash field. - bool get_tx_hashes; // If true (default false) then include the hashes or txes in the block details + uint64_t start_height; + uint64_t end_height; + bool fill_pow_hash; + bool get_tx_hashes; } request; }; - //----------------------------------------------- + /// RPC: daemon/stop_daemon + /// /// Stop the daemon. /// /// Inputs: none /// - /// Output values available from a restricted/admin RPC endpoint: + /// Outputs: /// - /// - \p status General RPC status string. `"OK"` means everything looks good. + /// - `status` -- General RPC status string. `"OK"` means everything looks good. struct STOP_DAEMON : LEGACY, NO_ARGS { static constexpr auto names() { return NAMES("stop_daemon"); } }; + /// RPC: daemon/get_limit + /// /// Get daemon p2p bandwidth limits. /// - /// Output values available from a restricted/admin RPC endpoint: + /// Inputs: none. /// - /// - \p status General RPC status string. `"OK"` means everything looks good. - /// - \p limit_up Upload limit in kiB/s - /// - \p limit_down Download limit in kiB/s + /// Outputs: + /// + /// - `status` -- General RPC status string. `"OK"` means everything looks good. + /// - `limit_up` -- Upload limit in kiB/s + /// - `limit_down` -- Download limit in kiB/s struct GET_LIMIT : LEGACY, NO_ARGS { static constexpr auto names() { return NAMES("get_limit"); } }; + /// RPC: daemon/set_limit + /// /// Set daemon p2p bandwidth limits. /// /// Inputs: /// - /// - \p limit_down Download limit in kBytes per second. -1 means reset to default; 0 (or + /// - `limit_down` -- Download limit in kBytes per second. -1 means reset to default; 0 (or /// omitted) means don't change the current limit - /// - \p limit_up Upload limit in kBytes per second. -1 means reset to default; 0 (or omitted) + /// - `limit_up` -- Upload limit in kBytes per second. -1 means reset to default; 0 (or omitted) /// means don't change the current limit /// - /// Output values available from a restricted/admin RPC endpoint: + /// Outputs: /// - /// - \p status General RPC status string. `"OK"` means everything looks good. - /// - \p limit_up The new (or existing, if unchanged) upload limit in kiB/s - /// - \p limit_down The new (or existing, if unchanged) download limit in kiB/s + /// - `status` -- General RPC status string. `"OK"` means everything looks good. + /// - `limit_up` -- The new (or existing, if unchanged) upload limit in kiB/s + /// - `limit_down` -- The new (or existing, if unchanged) download limit in kiB/s struct SET_LIMIT : LEGACY { static constexpr auto names() { return NAMES("set_limit"); } @@ -1036,18 +1221,20 @@ namespace cryptonote::rpc { } request; }; + /// RPC: daemon/out_peers + /// /// Limit number of Outgoing peers. /// /// Inputs: /// - /// - \p set If true, set the number of outgoing peers, otherwise the response returns the current + /// - `set` -- If true, set the number of outgoing peers, otherwise the response returns the current /// limit of outgoing peers. (Defaults to true) - /// - \p out_peers Max number of outgoing peers + /// - `out_peers` -- Max number of outgoing peers /// - /// Output values available from a restricted/admin RPC endpoint: + /// Outputs: /// - /// - \p status General RPC status string. `"OK"` means everything looks good. - /// - \p out_peers The current limit set for outgoing peers. + /// - `status` -- General RPC status string. `"OK"` means everything looks good. + /// - `out_peers` -- The current limit set for outgoing peers. struct OUT_PEERS : LEGACY { static constexpr auto names() { return NAMES("out_peers"); } @@ -1059,18 +1246,20 @@ namespace cryptonote::rpc { } request; }; + /// RPC: daemon/in_peers + /// /// Limit number of Incoming peers. /// /// Inputs: /// - /// - \p set If true, set the number of incoming peers, otherwise the response returns the current + /// - `set` -- If true, set the number of incoming peers, otherwise the response returns the current /// limit of incoming peers. (Defaults to true) - /// - \p in_peers Max number of incoming peers + /// - `in_peers` -- Max number of incoming peers /// - /// Output values available from a restricted/admin RPC endpoint: + /// Outputs: /// - /// - \p status General RPC status string. `"OK"` means everything looks good. - /// - \p in_peers The current limit set for incoming peers. + /// - `status` -- General RPC status string. `"OK"` means everything looks good. + /// - `in_peers` -- The current limit set for incoming peers. struct IN_PEERS : LEGACY { static constexpr auto names() { return NAMES("in_peers"); } @@ -1082,38 +1271,76 @@ namespace cryptonote::rpc { } request; }; - /// Output values available from a public RPC endpoint: + /// RPC: network/hard_fork_info /// - /// - \p status General RPC status string. `"OK"` means everything looks good. - /// - \p version The major block version for the fork. - /// - \p enabled Indicates whether the hard fork is enforced on the blockchain (that is, whether + /// Retrieves information about the current or a specific hard fork network rules. + /// + /// Inputs: + /// + /// - `version` -- If specified, this is the hard fork (i.e. major block) version for the fork. + /// Only one of `version` and `height` may be given; returns the current hard fork info if + /// neither is given. + /// - `height` -- Request hard fork info by querying a particular height. Only one of `version` + /// and `height` may be given. + /// + /// Outputs: + /// + /// - `status` -- General RPC status string. `"OK"` means everything looks good. + /// - `version` -- The major block version for the fork. + /// - `enabled` -- Indicates whether the hard fork is enforced on the blockchain (that is, whether /// the blockchain height is at or above the requested hardfork). - /// - \p earliest_height Block height at which the hard fork will become enabled. - /// - \p last_height The last block height at which this hard fork will be active; will be omitted - /// if this oxend is not aware of any following hard fork. + /// - `earliest_height` -- Block height at which the hard fork will become enabled. + /// - `last_height` -- The last block height at which this hard fork will be active; will be + /// omitted if this oxend is not aware of any following hard fork. + /// + /// Example input: + /// + /// ```json + /// { "version": 19 } + /// ``` + /// + /// Example-JSON-Fetch struct HARD_FORK_INFO : PUBLIC { static constexpr auto names() { return NAMES("hard_fork_info"); } struct request_parameters { - /// If specified, this is the hard fork (i.e. major block) version for the fork. Only one of - /// `version` and `height` may be given; returns the current hard fork info if neither is - /// given. uint8_t version = 0; - /// Request hard fork info by querying a particular height. Only one of `version` and - /// `height` may be given. uint64_t height = 0; } request; }; + /// RPC: daemon/get_bans + /// /// Get list of banned IPs. /// /// Inputs: None /// - /// Output values available from a restricted/admin RPC endpoint: + /// Outputs: /// - /// - \p status General RPC status string. `"OK"` means everything looks good. - /// - \p bans List of banned nodes + /// - `status` -- General RPC status string. `"OK"` means everything looks good. + /// - `bans` -- List of banned nodes. Each element is a dict containing: + /// - `host` -- Banned host (IP in A.B.C.D form). + /// - `seconds` -- Unix timestamp when the ban expires + /// + /// Example output: + /// ```json + /// { + /// "bans": [ + /// { + /// "host": "1.2.3.4", + /// "ip": 67305985, + /// "seconds": 5504 + /// }, + /// { + /// "host": "8.8.8.8", + /// "ip": 134744072, + /// "seconds": 679104 + /// } + /// ], + /// "status": "OK" + /// } + /// ``` struct GET_BANS : NO_ARGS { static constexpr auto names() { return NAMES("get_bans"); } @@ -1121,46 +1348,74 @@ namespace cryptonote::rpc { struct ban { - std::string host; // Banned host (IP in A.B.C.D form). - uint32_t ip; // Banned IP address, in Int format. - uint32_t seconds; // Local Unix time that IP is banned until + std::string host; + uint32_t seconds; }; - inline void to_json(nlohmann::json& j, const ban& b) { j = nlohmann::json{{"host", b.host}, {"ip", b.ip}, {"seconds", b.seconds} }; }; + inline void to_json(nlohmann::json& j, const ban& b) { j = nlohmann::json{{"host", b.host}, {"seconds", b.seconds} }; }; + /// RPC: daemon/set_bans + /// /// Ban another node by IP. /// /// Inputs: - /// - \p host Banned host (IP in A.B.C.D form). - /// - \p ip Banned IP address, in Int format. - /// - \p seconds Local Unix time that IP is banned until, or Number of seconds to ban node - /// - \p ban Set true to ban. + /// - `host` -- Banned host (IP in A.B.C.D form). + /// - `seconds` -- Number of seconds to ban node + /// - `ban` -- Set true to ban, false to remove a ban. /// - /// Output values available from a restricted/admin RPC endpoint: + /// Outputs: /// - /// - \p status General RPC status string. `"OK"` means everything looks good. + /// - `status` -- General RPC status string. `"OK"` means everything looks good. struct SET_BANS : RPC_COMMAND { static constexpr auto names() { return NAMES("set_bans"); } struct request_parameters { - std::string host; // Banned host (IP in A.B.C.D form). - uint32_t ip; // Banned IP address, in Int format. - uint32_t seconds; // Local Unix time that IP is banned until, or Number of seconds to ban node - bool ban; // Set true to ban. + std::string host; + uint32_t seconds; + bool ban; } request; }; + /// RPC: daemon/banned + /// /// Determine whether a given IP address is banned /// /// Inputs: - /// - \p address The IP address to check. + /// - `address` -- The IP address to check. /// - /// Output values available from a restricted/admin RPC endpoint: + /// Outputs: /// - /// - \p status General RPC status string. `"OK"` means everything looks good. - /// - \p banned True if the given address is banned, false otherwise. - /// - \p seconds The number of seconds remaining in the ban. + /// - `status` -- General RPC status string. `"OK"` means everything looks good. + /// - `banned` -- True if the given address is banned, false otherwise. + /// - `seconds` -- The number of seconds remaining in the ban. + /// + /// Example input: + /// ```json + /// { "address": "1.2.3.4" } + /// ``` + /// + /// Example output: + /// ```json + /// { + /// "banned": true, + /// "seconds": 5710, + /// "status": "OK" + /// } + /// + /// Example input: + /// ```json + /// { "addess": "4.3.2.1" } + /// ``` + /// + /// Example output: + /// ```json + /// { + /// "banned": false, + /// "seconds": 0, + /// "status": "OK" + /// } + /// ``` struct BANNED : RPC_COMMAND { static constexpr auto names() { return NAMES("banned"); } @@ -1171,14 +1426,16 @@ namespace cryptonote::rpc { } request; }; + /// RPC: daemon/flush_txpool + /// /// Flush tx ids from transaction pool.. /// /// Inputs: - /// - \p txids Optional, list of transactions IDs to flosh from pool (all tx ids flushed if empty) + /// - `txids` -- Optional, list of transactions IDs to flosh from pool (all tx ids flushed if empty) /// - /// Output values available from a restricted/admin RPC endpoint: + /// Outputs: /// - /// - \p status General RPC status string. `"OK"` means everything looks good. + /// - `status` -- General RPC status string. `"OK"` means everything looks good. struct FLUSH_TRANSACTION_POOL : RPC_COMMAND { static constexpr auto names() { return NAMES("flush_txpool"); } @@ -1189,41 +1446,43 @@ namespace cryptonote::rpc { } request; }; + /// RPC: blockchain/get_output_histogram + /// /// Get a histogram of output amounts. For all amounts (possibly filtered by parameters), /// gives the number of outputs on the chain for that amount. RingCT outputs counts as 0 amount. /// /// Inputs: /// - /// - \p amounts list of amounts in Atomic Units. - /// - \p min_count The minimum amounts you are requesting. - /// - \p max_count The maximum amounts you are requesting. - /// - \p unlocked Look for locked only. - /// - \p recent_cutoff + /// - `amounts` -- list of amounts in Atomic Units. + /// - `min_count` -- The minimum amounts you are requesting. + /// - `max_count` -- The maximum amounts you are requesting. + /// - `unlocked` -- Look for locked only. + /// - `recent_cutoff` /// - /// Output values available from a public RPC endpoint: + /// Outputs: /// - /// - \p status General RPC status string. `"OK"` means everything looks good. - /// - \p histogram List of histogram entries. Each element is structured as follows: - /// - \p uint64_t amount Output amount in atomic units. - /// - \p uint64_t total_instances - /// - \p uint64_t unlocked_instances - /// - \p uint64_t recent_instances + /// - `status` -- General RPC status string. `"OK"` means everything looks good. + /// - `histogram` -- List of histogram entries. Each element is structured as follows: + /// - `uint64_t` -- amount Output amount in atomic units. + /// - `uint64_t` -- total_instances + /// - `uint64_t` -- unlocked_instances + /// - `uint64_t` -- recent_instances struct GET_OUTPUT_HISTOGRAM : PUBLIC { static constexpr auto names() { return NAMES("get_output_histogram"); } struct request_parameters { - std::vector amounts; // list of amounts in Atomic Units. - uint64_t min_count; // The minimum amounts you are requesting. - uint64_t max_count; // The maximum amounts you are requesting. - bool unlocked; // Look for locked only. + std::vector amounts; + uint64_t min_count; + uint64_t max_count; + bool unlocked; uint64_t recent_cutoff; } request; struct entry { - uint64_t amount; // Output amount in atomic units. + uint64_t amount; uint64_t total_instances; uint64_t unlocked_instances; uint64_t recent_instances; @@ -1232,32 +1491,56 @@ namespace cryptonote::rpc { void to_json(nlohmann::json& j, const GET_OUTPUT_HISTOGRAM::entry& c); void from_json(const nlohmann::json& j, GET_OUTPUT_HISTOGRAM::entry& c); + /// RPC: daemon/get_version + /// /// Get current RPC protocol version. /// /// Inputs: None /// - /// Output values available from a public RPC endpoint: + /// Outputs: /// - /// - \p status General RPC status string. `"OK"` means everything looks good. - /// - \p version RPC current version. + /// - `status` -- General RPC status string. `"OK"` means everything looks good. + /// - `version` -- RPC current version. struct GET_VERSION : PUBLIC, NO_ARGS { static constexpr auto names() { return NAMES("get_version"); } }; + /// RPC: blockchain/get_coinbase_tx_sum + /// /// Get the coinbase amount and the fees amount for n last blocks starting at particular height. /// + /// Note that this call can be extremely slow the first time it is called, particularly when + /// requesting the values for the entire chain (by specifying `height=0`), as it has to scan the + /// full blockchain to calculate the result. As such this call is restricted to admin + /// connections. Future versions may lift this restriction. + /// /// Inputs: /// - /// - \p height Block height from which getting the amounts. - /// - \p count Number of blocks to include in the sum. + /// - `height` -- Block height from which getting the amounts. + /// - `count` -- Number of blocks to include in the sum. /// - /// Output values available from a restricted/admin RPC endpoint: + /// Outputs: /// - /// - \p status General RPC status string. `"OK"` means everything looks good. - /// - \p emission_amount Amount of coinbase reward in atomic units. - /// - \p fee_amount Amount of fees in atomic units. - /// - \p burn_amount Amount of burnt oxen. + /// - `status` -- General RPC status string. `"OK"` means everything looks good. + /// - `emission_amount` -- Amount of coinbase reward in atomic units. + /// - `fee_amount` -- Amount of fees in atomic units. + /// - `burn_amount` -- Amount of burnt oxen. + /// + /// Example input: + /// ```json + /// {"height": 0, "count":1000000000} + /// ``` + /// + /// Example output: + /// ```json + /// { + /// "burn_amount": 720279959424405, + /// "emission_amount": 59537648307402880, + /// "fee_amount": 80671056941541, + /// "status": "OK" + /// } + /// ``` struct GET_COINBASE_TX_SUM : RPC_COMMAND { static constexpr auto names() { return NAMES("get_coinbase_tx_sum"); } @@ -1269,29 +1552,39 @@ namespace cryptonote::rpc { } request; }; + /// RPC: network/get_fee_estimate + /// /// Gives an estimation of per-output + per-byte fees /// /// Inputs: /// - /// - \p grace_blocks If specified, make sure that the fee is high enough to cover any fee + /// - `grace_blocks` -- If specified, make sure that the fee is high enough to cover any fee /// increases in the next `grace_blocks` blocks. /// - /// Output values available from a public RPC endpoint: + /// Outputs: /// - /// - \p status General RPC status string. `"OK"` means everything looks good. - /// - \p emission_amount Amount of coinbase reward in atomic units. - /// - \p fee_amount Amount of fees in atomic units. - /// - \p burn_amount Amount of burnt oxen. - /// - \p fee_per_byte Amount of fees estimated per byte in atomic units - /// - \p fee_per_output Amount of fees per output generated by the tx (adds to the `fee_per_byte` + /// - `status` -- General RPC status string. `"OK"` means everything looks good. + /// - `emission_amount` -- Amount of coinbase reward in atomic units. + /// - `fee_amount` -- Amount of fees in atomic units. + /// - `burn_amount` -- Amount of burnt oxen. + /// - `fee_per_byte` -- Amount of fees estimated per byte in atomic units + /// - `fee_per_output` -- Amount of fees per output generated by the tx (adds to the `fee_per_byte` /// per-byte value) - /// - \p blink_fee_per_byte Value for sending a blink. The portion of the overall blink fee above + /// - `blink_fee_per_byte` -- Value for sending a blink. The portion of the overall blink fee above /// the overall base fee is burned. - /// - \p blink_fee_per_output Value for sending a blink. The portion of the overall blink fee + /// - `blink_fee_per_output` -- Value for sending a blink. The portion of the overall blink fee /// above the overall base fee is burned. - /// - \p blink_fee_fixed Fixed blink fee in addition to the per-output and per-byte amounts. The + /// - `blink_fee_fixed` -- Fixed blink fee in addition to the per-output and per-byte amounts. The /// portion of the overall blink fee above the overall base fee is burned. - /// - \p quantization_mask + /// - `quantization_mask` + /// + /// Example input: + /// + /// ```json + /// {} + /// ``` + /// + /// Example-JSON-Fetch struct GET_BASE_FEE_ESTIMATE : PUBLIC { static constexpr auto names() { return NAMES("get_fee_estimate"); } @@ -1302,30 +1595,32 @@ namespace cryptonote::rpc { } request; }; + /// RPC: blockchain/get_alternative_chains + /// /// Display alternative chains seen by the node. /// /// Inputs: None /// - /// Output values available from a public RPC endpoint: + /// Outputs: /// - /// - \p status General RPC status string. `"OK"` means everything looks good. - /// - \p chains Array of Chains. Each element is contains the following keys: - /// - \p block_hash The block hash of the first diverging block of this alternative chain. - /// - \p height The block height of the first diverging block of this alternative chain. - /// - \p length The length in blocks of this alternative chain, after divergence. - /// - \p difficulty The cumulative difficulty of all blocks in the alternative chain. - /// - \p block_hashes List containing hex block hashes - /// - \p main_chain_parent_block + /// - `status` -- General RPC status string. `"OK"` means everything looks good. + /// - `chains` -- Array of Chains. Each element is contains the following keys: + /// - `block_hash` -- The block hash of the first diverging block of this alternative chain. + /// - `height` -- The block height of the first diverging block of this alternative chain. + /// - `length` -- The length in blocks of this alternative chain, after divergence. + /// - `difficulty` -- The cumulative difficulty of all blocks in the alternative chain. + /// - `block_hashes` -- List containing hex block hashes + /// - `main_chain_parent_block` struct GET_ALTERNATE_CHAINS : NO_ARGS { static constexpr auto names() { return NAMES("get_alternative_chains"); } struct chain_info { - std::string block_hash; // The block hash of the first diverging block of this alternative chain. - uint64_t height; // The block height of the first diverging block of this alternative chain. - uint64_t length; // The length in blocks of this alternative chain, after divergence. - uint64_t difficulty; // The cumulative difficulty of all blocks in the alternative chain. + std::string block_hash; + uint64_t height; + uint64_t length; + uint64_t difficulty; std::vector block_hashes; std::string main_chain_parent_block; }; @@ -1333,25 +1628,29 @@ namespace cryptonote::rpc { void to_json(nlohmann::json& j, const GET_ALTERNATE_CHAINS::chain_info& c); void from_json(const nlohmann::json& j, GET_ALTERNATE_CHAINS::chain_info& c); + /// RPC: daemon/relay_tx + /// /// Relay a list of transaction IDs. /// /// Inputs: /// - /// - \p txids List of transactions IDs to relay from pool. + /// - `txids` -- List of transactions IDs to relay from pool. /// - /// Output values available from a restricted/admin RPC endpoint: + /// Outputs: /// - /// - \p status General RPC status string. `"OK"` means everything looks good. + /// - `status` -- General RPC status string. `"OK"` means everything looks good. struct RELAY_TX : RPC_COMMAND { static constexpr auto names() { return NAMES("relay_tx"); } struct request_parameters { - std::vector txids; // List of transactions IDs to relay from pool. + std::vector txids; } request; }; + /// RPC: daemon/sync_info + /// /// Get node synchronisation information. This returns information on the node's syncing "spans" /// which are block segments being downloaded from peers while syncing; spans are generally /// downloaded out of order from multiple peers, and so these spans reflect in-progress downloaded @@ -1361,25 +1660,25 @@ namespace cryptonote::rpc { /// /// Inputs: none /// - /// Output values available from a restricted/admin RPC endpoint: + /// Outputs: /// - /// - \p status General RPC status string. `"OK"` means everything looks good. - /// - \p height Current block height - /// - \p target_height If the node is currently syncing then this is the target height the node + /// - `status` -- General RPC status string. `"OK"` means everything looks good. + /// - `height` -- Current block height + /// - `target_height` -- If the node is currently syncing then this is the target height the node /// wants to reach. If fully synced then this field is omitted. - /// - \p peers dict of connection information about peers. The key is the peer connection_id; the - /// value is identical to the values of the \p connections field of GET_CONNECTIONS. \sa - /// GET_CONNECTIONS. - /// - \p span array of span information of current in progress synchronization. Element element + /// - `peers` -- dict of connection information about peers. The key is the peer connection_id; the + /// value is identical to the values of the `connections` field of the + /// [`get_connections`](#get_connections) endpoint. + /// - `span` -- array of span information of current in progress synchronization. Each element /// contains: - /// - \p start_block_height Block height of the first block in the span - /// - \p nblocks the number of blocks in the span - /// - \p connection_id the connection_id of the connection from which we are downloading the + /// - `start_block_height` -- Block height of the first block in the span + /// - `nblocks` -- the number of blocks in the span + /// - `connection_id` -- the connection_id of the connection from which we are downloading the /// span - /// - \p rate the most recent connection speed measurement - /// - \p speed the average connection speed over recent downloaded blocks - /// - \p size total number of block and transaction data stored in the span - /// - \p overview a string containing a one-line ascii-art depiction of the current sync status + /// - `rate` -- the most recent connection speed measurement + /// - `speed` -- the average connection speed over recent downloaded blocks + /// - `size` -- total number of block and transaction data stored in the span + /// - `overview` -- a string containing a one-line ascii-art depiction of the current sync status struct SYNC_INFO : NO_ARGS { static constexpr auto names() { return NAMES("sync_info"); } @@ -1393,7 +1692,44 @@ namespace cryptonote::rpc { }; - OXEN_RPC_DOC_INTROSPECT + /// RPC: blockchain/get_output_distribution + /// + /// This endpoint returns the output distribution of the blockchain. Its primary use is for the + /// wallet to obtain the distribution of outputs on the blockchain so as to construct a feasible + /// decoy set. + /// + /// Inputs: + /// + /// - `amounts` -- Amounts to look for in atomic units. + /// - `from_height` -- starting height to check from. Optional (default is 0). + /// - `to_height` -- ending height to check up to; 0 (or omitted) means the current chain height. + /// - `cumulative` -- if true then results are cumulative output counts up to the given block; if + /// false (or omitted) then results are the number of outputs added in the given block. + /// - `binary` -- request the result in binary format (ignored for JSON requests) + /// - `compressed` -- (required `binary`) -- use varint encoding of the binary result + /// + /// Outputs: + /// - `status` -- General RPC status string. `"OK"` means everything looks good. + /// - `distributions` -- array of distribution data; each element is an object containing keys: + /// - `amount` -- the requested amount + /// - `start_height` -- the requested start height + /// - `base` -- the number of outputs at the start_height + /// - `binary` -- true if the result is binary. This will always be false for JSON-encoded + /// responses. + /// - `compressed` -- true if the result is binary and using varint encoding. Will always be + /// false for JSON-encoded responses. + /// - `distribution` -- the distribution of rct outputs in blocks beginning after + /// `start_height`. If `binary` and `compressed` are true then this is a binary value + /// consisting of varint-encoded values; if just `binary` is set then this is a raw dump of + /// unsigned 64-bit integer binary data of the values. When `binary` is unset (i.e. for a + /// JSON response) this is an array of integer values. + /// + /// Example input: + /// ```json + /// { "amounts": [0], "from_height": 100002, "to_height": 100008, "cumulative": false } + /// ``` + /// + /// Example-JSON-Fetch struct GET_OUTPUT_DISTRIBUTION : PUBLIC { static constexpr auto names() { return NAMES("get_output_distribution"); } @@ -1430,26 +1766,30 @@ namespace cryptonote::rpc { }; }; + /// RPC: daemon/pop_blocks + /// /// Pop blocks off the main chain /// /// Inputs: /// - /// - \p nblocks Number of blocks in that span. + /// - `nblocks` -- Number of blocks in that span. /// - /// Output values available from a restricted/admin RPC endpoint: + /// Outputs: /// - /// - \p status General RPC status string. `"OK"` means everything looks good. - /// - \p height Height of the blockchain after blocks have been popped. + /// - `status` -- General RPC status string. `"OK"` means everything looks good. + /// - `height` -- Height of the blockchain after blocks have been popped. struct POP_BLOCKS : LEGACY { static constexpr auto names() { return NAMES("pop_blocks"); } struct request_parameters { - uint64_t nblocks; // Number of blocks in that span. + uint64_t nblocks; } request; }; + /// RPC: daemon/prune_blockchain + /// /// Pruning is the process of removing non-critical blockchain information from local storage. /// Full nodes keep an entire copy of everything that is stored on the blockchain, including data /// that is not very useful anymore. Pruned nodes remove much of this less relevant information @@ -1458,13 +1798,13 @@ namespace cryptonote::rpc { /// /// Inputs: /// - /// - \p check Instead of running check if the blockchain has already been pruned. + /// - `check` -- Instead of running check if the blockchain has already been pruned. /// - /// Output values available from a restricted/admin RPC endpoint: + /// Outputs: /// - /// - \p status General RPC status string. `"OK"` means everything looks good. - /// - \p pruned Bool returning whether the blockchain was pruned or not. - /// - \p pruning_seed The seed that determined how the blockchain was to be pruned. + /// - `status` -- General RPC status string. `"OK"` means everything looks good. + /// - `pruned` -- Bool returning whether the blockchain was pruned or not. + /// - `pruning_seed` -- The seed that determined how the blockchain was to be pruned. struct PRUNE_BLOCKCHAIN : RPC_COMMAND { static constexpr auto names() { return NAMES("prune_blockchain"); } @@ -1476,24 +1816,47 @@ namespace cryptonote::rpc { }; + /// RPC: network/get_quorum_state + /// /// Accesses the list of public keys of the nodes who are participating or being tested in a quorum. /// /// Inputs: /// - /// - \p start_height (Optional): Start height, omit both start and end height to request the latest quorum. Note that "latest" means different heights for different types of quorums as not all quorums exist at every block heights. - /// - \p end_height (Optional): End height, omit both start and end height to request the latest quorum - /// - \p quorum_type (Optional): Set value to request a specific quorum, 0 = Obligation, 1 = Checkpointing, 2 = Blink, 3 = Pulse, 255 = all quorums, default is all quorums. For Pulse quorums, requesting the blockchain height (or latest) returns the primary pulse quorum responsible for the next block; for heights with blocks this returns the actual quorum, which may be a backup quorum if the primary quorum did not produce in time. + /// - `start_height` -- (Optional): Start height, omit both start and end height to request the + /// latest quorum. Note that "latest" means different heights for different types of quorums as + /// not all quorums exist at every block heights. + /// - `end_height` -- (Optional): End height, omit both start and end height to request the latest + /// quorum + /// - `quorum_type` -- (Optional): Set value to request a specific quorum, 0 = Obligation, 1 = + /// Checkpointing, 2 = Blink, 3 = Pulse, 255 = all quorums, default is all quorums. For Pulse + /// quorums, requesting the blockchain height (or latest) returns the primary pulse quorum + /// responsible for the next block; for heights with blocks this returns the actual quorum, + /// which may be a backup quorum if the primary quorum did not produce in time. /// - /// Output values available from a public RPC endpoint: + /// Outputs: /// - /// - \p status General RPC status string. `"OK"` means everything looks good. - /// - \p quorums An array of quorums associated with the requested height. Each element is structured with the following keys: - /// - \p service_node_pubkey The public key of the Service Node, in hex (json) or binary (bt). - /// - \p height The height the quorums are relevant for - /// - \p quorum_type The quorum type - /// - \p quorum Quorum of Service Nodes. Each element is structured with the following keys: - /// - \p validators List of service node public keys in the quorum. For obligations quorums these are the testing nodes; for checkpoint and blink these are the participating nodes (there are no workers); for Pulse blink quorums these are the block signers. This is hex encoded, even for bt-encoded requests. - /// - \p workers Public key of the quorum workers. For obligations quorums these are the nodes being tested; for Pulse quorums this is the block producer. Checkpoint and Blink quorums do not populate this field. This is hex encoded, even for bt-encoded requests. + /// - `status` -- General RPC status string. `"OK"` means everything looks good. + /// - `quorums` -- An array of quorums associated with the requested height. Each element is + /// structured with the following keys: + /// - `service_node_pubkey` -- The public key of the Service Node, in hex (json) or binary (bt). + /// - `height` -- The height the quorums are relevant for + /// - `quorum_type` -- The quorum type + /// - `quorum` -- Quorum of Service Nodes. Each element is structured with the following keys: + /// - `validators` -- List of service node public keys in the quorum. For obligations quorums + /// these are the testing nodes; for checkpoint and blink these are the participating nodes + /// (there are no workers); for Pulse blink quorums these are the block signers. This is hex + /// encoded, even for bt-encoded requests. + /// - `workers` -- Public key of the quorum workers. For obligations quorums these are the + /// nodes being tested; for Pulse quorums this is the block producer. Checkpoint and Blink + /// quorums do not populate this field. This is hex encoded, even for bt-encoded requests. + /// + /// Example input: + /// + /// ```json + /// { "quorum_type": 3 } + /// ``` + /// + /// Example-JSON-Fetch struct GET_QUORUM_STATE : PUBLIC { static constexpr auto names() { return NAMES("get_quorum_state"); } @@ -1501,49 +1864,53 @@ namespace cryptonote::rpc { static constexpr size_t MAX_COUNT = 256; struct request_parameters { - std::optional start_height; // (Optional): Start height, omit both start and end height to request the latest quorum. Note that "latest" means different heights for different types of quorums as not all quorums exist at every block heights. - std::optional end_height; // (Optional): End height, omit both start and end height to request the latest quorum - std::optional quorum_type; // (Optional): Set value to request a specific quorum, 0 = Obligation, 1 = Checkpointing, 2 = Blink, 3 = Pulse, omitted or 255 = all quorums. For Pulse quorums, requesting the blockchain height (or latest) returns the primary pulse quorum responsible for the next block; for heights with blocks this returns the actual quorum, which may be a backup quorum if the primary quorum did not produce in time. + std::optional start_height; + std::optional end_height; + std::optional quorum_type; } request; struct quorum_t { - std::vector validators; // List of service node public keys in the quorum. For obligations quorums these are the testing nodes; for checkpoint and blink these are the participating nodes (there are no workers); for Pulse blink quorums these are the block signers. - std::vector workers; // Public key of the quorum workers. For obligations quorums these are the nodes being tested; for Pulse quorums this is the block producer. Checkpoint and Blink quorums do not populate this field. + std::vector validators; + std::vector workers; }; struct quorum_for_height { - uint64_t height; // The height the quorums are relevant for - uint8_t quorum_type; // The quorum type - quorum_t quorum; // Quorum of Service Nodes + uint64_t height; + uint8_t quorum_type; + quorum_t quorum; }; }; void to_json(nlohmann::json& j, const GET_QUORUM_STATE::quorum_t& q); void to_json(nlohmann::json& j, const GET_QUORUM_STATE::quorum_for_height& q); - /// Returns the command that should be run to prepare a service node, includes correct parameters - /// and service node ids formatted ready for cut and paste into daemon console. + /// RPC: service_node/get_service_node_registration_cmd_raw + /// + /// Generates a signed service node registration command for use in the operator's Oxen wallet. + /// This endpoint is primarily for internal use by the `oxend prepare_registration` command. /// /// Inputs: /// - /// - \p args (Developer) The list of arguments used in raw registration, i.e. portions - /// - \p make_friendly Provide information about how to use the command in the result. - /// - \p staking_requirement The staking requirement to become a Service Node the registration command will be generated upon + /// - `args` -- (Developer) The list of arguments used in raw registration, i.e. portions + /// - `make_friendly` -- Provide information about how to use the command in the result. + /// - `staking_requirement` -- The staking requirement to become a Service Node the registration + /// command will be generated upon /// - /// Output values available from a restricted/admin RPC endpoint: + /// Outputs: /// - /// - \p status General RPC status string. `"OK"` means everything looks good. - /// - \p registration_cmd The command to execute in the wallet CLI to register the queried daemon as a Service Node. + /// - `status` -- General RPC status string. `"OK"` means everything looks good. + /// - `registration_cmd` -- The command to execute in the wallet CLI to register the queried + /// daemon as a Service Node. struct GET_SERVICE_NODE_REGISTRATION_CMD_RAW : RPC_COMMAND { static constexpr auto names() { return NAMES("get_service_node_registration_cmd_raw"); } struct request_parameters { - std::vector args; // (Developer) The arguments used in raw registration, i.e. portions - bool make_friendly; // Provide information about how to use the command in the result. - uint64_t staking_requirement; // The staking requirement to become a Service Node the registration command will be generated upon + std::vector args; + bool make_friendly; + uint64_t staking_requirement; } request; }; @@ -1578,23 +1945,28 @@ namespace cryptonote::rpc { }; }; + /// RPC: service_node/get_service_keys + /// /// Get the service public keys of the queried daemon, encoded in hex. All three keys are used /// when running as a service node; when running as a regular node only the x25519 key is regularly /// used for some RPC and and node-to-SN communication requests. /// /// Inputs: None /// - /// Output values available from a restricted/admin RPC endpoint: + /// Outputs: /// - /// - \p status General RPC status string. `"OK"` means everything looks good. - /// - \p service_node_pubkey The queried daemon's service node public key. Will be empty if not running as a service node. - /// - \p service_node_ed25519_pubkey The daemon's ed25519 auxiliary public key. - /// - \p service_node_x25519_pubkey The daemon's x25519 auxiliary public key. + /// - `status` -- General RPC status string. `"OK"` means everything looks good. + /// - `service_node_pubkey` -- The queried daemon's service node public key. Will be empty if not + /// running as a service node. + /// - `service_node_ed25519_pubkey` -- The daemon's ed25519 auxiliary public key. + /// - `service_node_x25519_pubkey` -- The daemon's x25519 auxiliary public key. struct GET_SERVICE_KEYS : NO_ARGS { static constexpr auto names() { return NAMES("get_service_keys", "get_service_node_key"); } }; + /// RPC: service_node/get_service_privkeys + /// /// Get the service private keys of the queried daemon, encoded in hex. Do not ever share /// these keys: they would allow someone to impersonate your service node. All three keys are used /// when running as a service node; when running as a regular node only the x25519 key is regularly @@ -1602,245 +1974,264 @@ namespace cryptonote::rpc { /// /// Inputs: None /// - /// Output values available from a restricted/admin RPC endpoint: + /// Outputs: /// - /// - \p status General RPC status string. `"OK"` means everything looks good. - /// - \p service_node_privkey The queried daemon's service node private key. Will be empty if not running as a service node. - /// - \p service_node_ed25519_privkey The daemon's ed25519 private key (note that this is in sodium's format, which consists of the private and public keys concatenated together) - /// - \p service_node_x25519_privkey The daemon's x25519 private key. + /// - `status` -- General RPC status string. `"OK"` means everything looks good. + /// - `service_node_privkey` -- The queried daemon's service node private key. Will be empty if + /// not running as a service node. + /// - `service_node_ed25519_privkey` -- The daemon's ed25519 private key (note that this is in + /// sodium's format, which consists of the private and public keys concatenated together) + /// - `service_node_x25519_privkey` -- The daemon's x25519 private key. struct GET_SERVICE_PRIVKEYS : NO_ARGS { static constexpr auto names() { return NAMES("get_service_privkeys", "get_service_node_privkey"); } }; + /// RPC: service_node/get_service_nodes + /// /// Get information on some, all, or a random subset of Service Nodes. /// + /// Inputs: + /// - `fields` -- Set of fields to return; listed fields apply to both the top level (such as + /// `"height"` or `"block_hash"`) and to keys inside `service_node_states`. Fields should be + /// provided as a list of field names to include. For backwards compatibility when making a + /// json request field names can also be provided as a dictionary of `{"field_name": true}` + /// pairs, but this usage is deprecated (and not supported for bt-encoded requests). + /// + /// The special field name `"all"` can be used to request all available fields; this is the + /// default when no fields key are provided at all. Be careful when requesting all fields: + /// the response can be very large. + /// + /// When providing a list you may prefix a field name with a `-` (e.g. `"-funded"`) to remove + /// the field from the list; this is mainly useful when following `"all"` to remove some + /// fields from the returned results. (There is no equivalent mode when using the deprecated + /// dict value). + /// + /// - `service_node_pubkeys` -- Array of public keys of registered service nodes to request + /// information about. Omit to query all service nodes. For a JSON request pubkeys must be + /// specified in hex; for a bt-encoded request pubkeys can be hex or bytes. + /// + /// - `active_only` -- If true then only return active service nodes. + /// + /// - `limit` -- If specified and non-zero then only return a random selection of this number of + /// service nodes (in random order) from the result. If negative then no limiting is performed + /// but the returned result is still shuffled. + /// + /// - `poll_block_hash` -- If specified then only return results if the current top block hash is + /// different than the hash given here. This is intended to allow quick polling of results + /// without needing to do anything if the block (and thus SN registrations) have not changed + /// since the last request. + /// + /// Outputs: + /// /// Output variables available are as follows (you can request which parameters are returned; see /// the request parameters description). Note that OXEN values are returned in atomic OXEN units, /// which are nano-OXEN (i.e. 1.000000000 OXEN will be returned as 1000000000). /// - /// - \p height the height of the current top block. (Note that this is one less than the - /// "blockchain height" as would be returned by the \c get_info endpoint). - /// - \p target_height the target height of the blockchain; will be greater than height+1 if this + /// - `height` -- the height of the current top block. (Note that this is one less than the + /// "blockchain height" as would be returned by the [`get_info`](#get_info) endpoint). + /// - `target_height` -- the target height of the blockchain; will be greater than height+1 if this /// node is still syncing the chain. - /// - \p block_hash the hash of the most recent block - /// - \p hardfork the current hardfork version of the daemon - /// - \p snode_revision the current snode revision for non-hardfork, but mandatory, service node + /// - `block_hash` -- the hash of the most recent block + /// - `hardfork` -- the current hardfork version of the daemon + /// - `snode_revision` -- the current snode revision for non-hardfork, but mandatory, service node /// updates. - /// - \p status generic RPC error code; "OK" means the request was successful. - /// - \p unchanged when using poll_block_hash, this value is set to true and results are omitted + /// - `status` -- generic RPC error code; "OK" means the request was successful. + /// - `unchanged` -- when using poll_block_hash, this value is set to true and results are omitted /// if the current block hash has not changed from the requested polling block hash. If block /// hash has changed this is set to false (and results included). When not polling this value /// is omitted entirely. - /// - \p service_node_states list of information about all known service nodes; each element is a + /// - `service_node_states` -- list of information about all known service nodes; each element is a /// dict containing the following keys (which fields are included/omitted can be controlled via /// the "fields" input parameter): - /// - \p service_node_pubkey The public key of the Service Node, in hex (json) or binary (bt). - /// - \p registration_height The height at which the registration for the Service Node arrived + /// - `service_node_pubkey` -- The public key of the Service Node, in hex (json) or binary (bt). + /// - `registration_height` -- The height at which the registration for the Service Node arrived /// on the blockchain. - /// - \p registration_hf_version The current hard fork at which the registration for the Service + /// - `registration_hf_version` -- The current hard fork at which the registration for the Service /// Node arrived on the blockchain. - /// - \p requested_unlock_height If an unlock has been requested for this SN, this field + /// - `requested_unlock_height` -- If an unlock has been requested for this SN, this field /// contains the height at which the Service Node registration expires and contributions will /// be released. - /// - \p last_reward_block_height The height that determines when this service node will next + /// - `last_reward_block_height` -- The height that determines when this service node will next /// receive a reward. This field is somewhat misnamed for historic reasons: it is updated /// when receiving a reward, but is also updated when a SN is activated, recommissioned, or /// has an IP change position reset, and so does not strictly indicate when a reward was /// received. - /// - \p last_reward_transaction_index When multiple Service Nodes register (or become + /// - `last_reward_transaction_index` -- When multiple Service Nodes register (or become /// active/reactivated) at the same height (i.e. have the same last_reward_block_height), this /// field contains the activating transaction position in the block which is used to break /// ties in determining which SN is next in the reward list. - /// - \p active True if fully funded and not currently decommissioned (and so `funded && - /// !active` implicitly defines decommissioned). - /// - \p funded True if the required stakes have been submitted to activate this Service Node. - /// - \p state_height Indicates the height at which the service node entered its current state: - /// - If \p active: this is the height at which the service node last became active (i.e. - /// became fully staked, or was last recommissioned); - /// - If decommissioned (i.e. \p funded but not \p active): the decommissioning height; - /// - If awaiting contributions (i.e. not \p funded): the height at which the last - /// contribution (or registration) was processed. - /// - \p decommission_count The number of times the Service Node has been decommissioned since + /// - `active` -- True if fully funded and not currently decommissioned (and so `funded and not + /// active` implicitly defines decommissioned). + /// - `funded` -- True if the required stakes have been submitted to activate this Service Node. + /// - `state_height` -- Indicates the height at which the service node entered its current state: + /// - If `active` is true: this is the height at which the service node last became active + /// (i.e. became fully staked, or was last recommissioned); + /// - If decommissioned (i.e. `funded and not active`): the decommissioning height; + /// - If awaiting contributions (i.e. `not funded`): the height at which the last contribution + /// (or registration) was processed. + /// - `decommission_count` -- The number of times the Service Node has been decommissioned since /// registration - /// - \p last_decommission_reason_consensus_all The reason for the last decommission as voted by + /// - `last_decommission_reason_consensus_all` -- The reason for the last decommission as voted by /// the testing quorum SNs that decommissioned the node. This is a numeric bitfield made up /// of the sum of given reasons (multiple reasons may be given for a decommission). Values /// are included here if *all* quorum members agreed on the reasons: - /// - \c 0x01 - Missing uptime proofs - /// - \c 0x02 - Missed too many checkpoint votes - /// - \c 0x04 - Missed too many pulse blocks - /// - \c 0x08 - Storage server unreachable - /// - \c 0x10 - oxend quorumnet unreachable for timesync checks - /// - \c 0x20 - oxend system clock is too far off - /// - \c 0x40 - Lokinet unreachable + /// - `0x01` - Missing uptime proofs + /// - `0x02` - Missed too many checkpoint votes + /// - `0x04` - Missed too many pulse blocks + /// - `0x08` - Storage server unreachable + /// - `0x10` - oxend quorumnet unreachable for timesync checks + /// - `0x20` - oxend system clock is too far off + /// - `0x40` - Lokinet unreachable /// - other bit values are reserved for future use. - /// - \p last_decommission_reason_consensus_any The reason for the last decommission as voted by - /// *any* SNs. Reasons are set here if *any* quorum member gave a reason, even if not all - /// quorum members agreed. Bit values are the same as \p - /// last_decommission_reason_consensus_all. - /// - \p decomm_reasons - a gentler version of the last_decommission_reason_consensus_all/_any - /// values: this is returned as a dict with two keys, \c "all" and \c "some", containing a - /// list of short string identifiers of the reasons. \c "all" contains reasons that are - /// agreed upon by all voting nodes; \c "some" contains reasons that were provided by some but - /// not all nodes (and is included only if there are at least one such value). Note that, - /// unlike \p last_decommission_reason_consensus_any, the \c "some" field only includes - /// reasons that are *not* included in \c "all". Returned values in the lists are: - /// - \p "uptime" - /// - \p "checkpoints" - /// - \p "pulse" - /// - \p "storage" - /// - \p "timecheck" - /// - \p "timesync" - /// - \p "lokinet" + /// - `last_decommission_reason_consensus_any` -- The reason for the last decommission as voted + /// by *any* SNs. Reasons are set here if *any* quorum member gave a reason, even if not all + /// quorum members agreed. Bit values are the same as + /// `last_decommission_reason_consensus_all`. + /// - `decomm_reasons` -- a gentler version of the last_decommission_reason_consensus_all/_any + /// values: this is returned as a dict with two keys, `"all"` and `"some"`, containing a list + /// of short string identifiers of the reasons. `"all"` contains reasons that are agreed upon + /// by all voting nodes; `"some"` contains reasons that were provided by some but not all + /// nodes (and is included only if there are at least one such value). Note that, + /// unlike `last_decommission_reason_consensus_any`, the `"some"` field only includes reasons + /// that are *not* included in `"all"`. Returned values in the lists are: + /// - `"uptime"` + /// - `"checkpoints"` + /// - `"pulse"` + /// - `"storage"` + /// - `"timecheck"` + /// - `"timesync"` + /// - `"lokinet"` /// - other values are reserved for future use. - /// - \p earned_downtime_blocks The number of blocks earned towards decommissioning (if + /// - `earned_downtime_blocks` -- The number of blocks earned towards decommissioning (if /// currently active), or the number of blocks remaining until the service node is eligible /// for deregistration (if currently decommissioned). - /// - \p service_node_version The three-element numeric version of the Service Node (as received + /// - `service_node_version` -- The three-element numeric version of the Service Node (as received /// in the last uptime proof). Omitted if we have never received a proof. - /// - \p lokinet_version The major, minor, patch version of the Service Node's lokinet router + /// - `lokinet_version` -- The major, minor, patch version of the Service Node's lokinet router /// (as received in the last uptime proof). Omitted if we have never received a proof. - /// - \p storage_server_version The major, minor, patch version of the Service Node's storage + /// - `storage_server_version` -- The major, minor, patch version of the Service Node's storage /// server (as received in the last uptime proof). Omitted if we have never received a proof. - /// - \p contributors Array of contributors, contributing to this Service Node. Each element is + /// - `contributors` -- Array of contributors, contributing to this Service Node. Each element is /// a dict containing: - /// - \p amount The total amount of OXEN staked by this contributor into + /// - `amount` -- The total amount of OXEN staked by this contributor into /// this Service Node. - /// - \p reserved The amount of OXEN reserved by this contributor for this Service Node; this + /// - `reserved` -- The amount of OXEN reserved by this contributor for this Service Node; this /// field will be included only if the contributor has unfilled, reserved space in the /// service node. - /// - \p address The wallet address of this contributor to which rewards are sent and from + /// - `address` -- The wallet address of this contributor to which rewards are sent and from /// which contributions were made. - /// - \p locked_contributions Array of contributions from this contributor; this field (unlike - /// the other fields inside \p contributors) is controlled by the "fields" input parameter. - /// Each element contains: - /// - \p key_image The contribution's key image which is locked on the network. - /// - \p key_image_pub_key The contribution's key image, public key component. - /// - \p amount The amount of OXEN that is locked in this contribution. - /// - /// - \p total_contributed The total amount of OXEN contributed to this Service Node. - /// - \p total_reserved The total amount of OXEN contributed or reserved for this Service Node. + /// - `locked_contributions` -- Array of contributions from this contributor; this field + /// (unlike the other fields inside `contributors`) is controlled by the `fields` input + /// parameter. Each element contains: + /// - `key_image` -- The contribution's key image which is locked on the network. + /// - `key_image_pub_key` -- The contribution's key image, public key component. + /// - `amount` -- The amount of OXEN that is locked in this contribution. + /// - `total_contributed` -- The total amount of OXEN contributed to this Service Node. + /// - `total_reserved` -- The total amount of OXEN contributed or reserved for this Service Node. /// Only included in the response if there are still unfilled reservations (i.e. if it is /// greater than total_contributed). - /// - \p staking_requirement The total OXEN staking requirement in that is/was required to be + /// - `staking_requirement` -- The total OXEN staking requirement in that is/was required to be /// contributed for this Service Node. - /// - \p portions_for_operator The operator fee to take from the service node reward, as a + /// - `portions_for_operator` -- The operator fee to take from the service node reward, as a /// fraction of 18446744073709551612 (2^64 - 4) (that is, this number corresponds to 100%). /// Note that some JSON parsers may silently change this value while parsing as typical values /// do not fit into a double without loss of precision. - /// - \p operator_fee The operator fee expressed in millionths (and rounded to the nearest + /// - `operator_fee` -- The operator fee expressed in millionths (and rounded to the nearest /// integer value). That is, 1000000 corresponds to a 100% fee, 34567 corresponds to a /// 3.4567% fee. Note that this number is for human consumption; the actual value that - /// matters for the blockchain is the precise \p portions_for_operator value. - /// - \p swarm_id The numeric identifier of the Service Node's current swarm. Note that + /// matters for the blockchain is the precise `portions_for_operator` value. + /// - `swarm_id` -- The numeric identifier of the Service Node's current swarm. Note that /// returned values can exceed the precision available in a double value, which can result in - /// (changed) incorrect values by some JSON parsers. Consider using \p swarm instead if you + /// (changed) incorrect values by some JSON parsers. Consider using `swarm` instead if you /// are not sure your JSON parser supports 64-bit values. - /// - \p swarm The swarm id, expressed in hexadecimal, such as \c "f4ffffffffffffff". - /// - \p operator_address The wallet address of the Service Node operator. - /// - \p public_ip The public ip address of the service node; omitted if we have not yet + /// - `swarm` -- The swarm id, expressed in hexadecimal, such as `"f4ffffffffffffff"`. + /// - `operator_address` -- The wallet address of the Service Node operator. + /// - `public_ip` -- The public ip address of the service node; omitted if we have not yet /// received a network proof containing this information from the service node. - /// - \p storage_port The port number associated with the storage server; omitted if we have no + /// - `storage_port` -- The port number associated with the storage server; omitted if we have no /// uptime proof yet. - /// - \p storage_lmq_port The port number associated with the storage server (oxenmq interface); + /// - `storage_lmq_port` -- The port number associated with the storage server (oxenmq interface); /// omitted if we have no uptime proof yet. - /// - \p quorumnet_port The port for direct SN-to-SN oxend communication (oxenmq interface). + /// - `quorumnet_port` -- The port for direct SN-to-SN oxend communication (oxenmq interface). /// Omitted if we have no uptime proof yet. - /// - \p pubkey_ed25519 The service node's ed25519 public key for auxiliary services. Omitted if + /// - `pubkey_ed25519` -- The service node's ed25519 public key for auxiliary services. Omitted if /// we have no uptime proof yet. Note that for newer registrations this will be the same as - /// the \p service_node_pubkey. - /// - \p pubkey_x25519 The service node's x25519 public key for auxiliary services (mainly used - /// for \p quorumnet_port and the \p storage_lmq_port OxenMQ encrypted connections). - /// - \p last_uptime_proof The last time we received an uptime proof for this service node from + /// the `service_node_pubkey`. + /// - `pubkey_x25519` -- The service node's x25519 public key for auxiliary services (mainly + /// used for `quorumnet_port` and the `storage_lmq_port` OxenMQ encrypted connections). + /// - `last_uptime_proof` -- The last time we received an uptime proof for this service node from /// the network, in unix epoch time. 0 if we have never received one. - /// - \p storage_server_reachable True if this storage server is currently passing tests for the + /// - `storage_server_reachable` -- True if this storage server is currently passing tests for the /// purposes of SN node testing: true if the last test passed, or if it has been unreachable /// for less than an hour; false if it has been failing tests for more than an hour (and thus /// is considered unreachable). This field is omitted if the queried oxend is not a service /// node. - /// - \p storage_server_first_unreachable If the last test we received was a failure, this field + /// - `storage_server_first_unreachable` -- If the last test we received was a failure, this field /// contains the timestamp when failures started. Will be 0 if the last result was a success, /// and will be omitted if the node has not yet been tested since this oxend last restarted. - /// - \p storage_server_last_unreachable The last time this service node's storage server failed + /// - `storage_server_last_unreachable` -- The last time this service node's storage server failed /// a ping test (regardless of whether or not it is currently failing). Will be omitted if it /// has never failed a test since startup. - /// - \p storage_server_last_reachable The last time we received a successful ping response for + /// - `storage_server_last_reachable` -- The last time we received a successful ping response for /// this storage server (whether or not it is currently failing). Will be omitted if we have /// never received a successful ping response since startup. - /// - \p lokinet_reachable Same as \p storage_server_reachable, but for lokinet router testing. - /// - \p lokinet_first_unreachable Same as \p storage_server_first_unreachable, but for lokinet + /// - `lokinet_reachable` -- Same as `storage_server_reachable`, but for lokinet router testing. + /// - `lokinet_first_unreachable` -- Same as `storage_server_first_unreachable`, but for lokinet /// router testing. - /// - \p lokinet_last_unreachable Same as \p storage_server_last_unreachable, but for lokinet + /// - `lokinet_last_unreachable` -- Same as `storage_server_last_unreachable`, but for lokinet /// router testing. - /// - \p lokinet_last_reachable Same as \p storage_server_last_reachable, but for lokinet router + /// - `lokinet_last_reachable` -- Same as `storage_server_last_reachable`, but for lokinet router /// testing. - /// - \p checkpoint_votes dict containing recent received checkpoint voting information for this + /// - `checkpoint_votes` -- dict containing recent received checkpoint voting information for this /// service node. Service node tests will fail if too many recent pulse blocks are missed. /// Contains keys: - /// - \p voted list of blocks heights at which a required vote was received from this + /// - `voted` -- list of blocks heights at which a required vote was received from this /// service node - /// - \p missed list of block heights at which a vote from this service node was required + /// - `missed` -- list of block heights at which a vote from this service node was required /// but not received. - /// - \p pulse_votes dict containing recent pulse blocks in which this service node was supposed + /// - `pulse_votes` -- dict containing recent pulse blocks in which this service node was supposed /// to have participated. Service node testing will fail if too many recent pulse blocks are /// missed. Contains keys: - /// - \p voted list of [HEIGHT,ROUND] pairs in which an expected pulse participation was - /// recorded for this node. ROUND starts at 0 and increments for backup pulse quorums if a - /// previous round does not broadcast a pulse block for the given height in time. - /// - \p missed list of [HEIGHT,ROUND] pairs in which pulse participation by this service node - /// was expected but did not occur. - /// - \p quorumnet_tests array containing the results of recent attempts to connect to the + /// - `voted` -- list of `[, ]` pairs in which an expected pulse participation + /// was recorded for this node. `` starts at `0` and increments for backup pulse + /// quorums if a previous round does not broadcast a pulse block for the given height in + /// time. + /// - `missed` -- list of `[, ]` pairs in which pulse participation by this + /// service node was expected but did not occur. + /// - `quorumnet_tests` -- array containing the results of recent attempts to connect to the /// remote node's quorumnet port (while conducting timesync checks). The array contains two - /// values: [SUCCESSES,FAILURES], where SUCCESSES is the number of recent successful - /// connections and FAILURES is the number of recent connection and/or request timeouts. If - /// there are two many failures then the service node will fail testing. - /// - \p timesync_tests array containing the results of recent time synchronization checks of - /// this service node. Contains [SUCCESSES,FAILURES] counts where SUCCESSES is the number of - /// recent checks where the system clock was relatively close and FAILURES is the number of - /// recent checks where we received a significantly out-of-sync timestamp response from the - /// service node. A service node fails tests if there are too many recent out-of-sync - /// responses. + /// values: `[, ]`, where `` is the number of recent + /// successful connections and FAILURES is the number of recent connection and/or request + /// timeouts. If there are two many failures then the service node will fail testing. + /// - `timesync_tests` -- array containing the results of recent time synchronization checks of + /// this service node. Contains `[, ]` counts where `` is the + /// number of recent checks where the system clock was relatively close and FAILURES is the + /// number of recent checks where we received a significantly out-of-sync timestamp response + /// from the service node. A service node fails tests if there are too many recent + /// out-of-sync responses. + /// + /// Example input: + /// ```json + /// { "limit": 1 } + /// ``` + /// + /// Example-JSON-Fetch struct GET_SERVICE_NODES : PUBLIC { static constexpr auto names() { return NAMES("get_service_nodes", "get_n_service_nodes", "get_all_service_nodes"); } struct request_parameters { - /// Set of fields to return; listed fields apply to both the top level (such as \p "height" or - /// \p "block_hash") and to keys inside \p service_node_states. Fields should be provided as - /// a list of field names to include. For backwards compatibility when making a json request - /// field names can also be provided as a dictionary of {"field_name": true} pairs, but this - /// usage is deprecated (and not supported for bt-encoded requests). - /// - /// The special field name "all" can be used to request all available fields; this is the - /// default when no fields key are provided at all. Be careful when requesting all fields: - /// the response can be very large. - /// - /// When providing a list you may prefix a field name with a \c - to remove the field from the - /// list; this is mainly useful when following "all" to remove some fields from the returned - /// results. (There is no equivalent mode when using the deprecated dict value). std::unordered_set fields; - - /// Array of public keys of registered service nodes to request information about. Omit to - /// query all service nodes. For a JSON request pubkeys must be specified in hex; for a - /// bt-encoded request pubkeys can be hex or bytes. std::vector service_node_pubkeys; - - /// If true then only return active service nodes. bool active_only = false; - - /// If specified and non-zero then only return a random selection of this number of service - /// nodes (in random order) from the result. If negative then no limiting is performed but - /// the returned result is still shuffled. int limit = 0; - - /// If specified then only return results if the current top block hash is different than the - /// hash given here. This is intended to allow quick polling of results without needing to do - /// anything if the block (and thus SN registrations) have not changed since the last request. crypto::hash poll_block_hash{}; } request; }; + /// RPC: service_node/get_service_node_status + /// /// Retrieves information on the current daemon's Service Node state. The returned information is /// the same as what would be returned by "get_service_nodes" when passed this service node's /// public key. @@ -1848,31 +2239,32 @@ namespace cryptonote::rpc { /// Inputs: none. /// /// Outputs: - /// - \p service_node_state - if this is a registered service node then all available fields for - /// this service node. \sa GET_SERVICE_NODES for the list of fields. Note that some fields - /// (such as remote testing results) will not be available (through this call or \p - /// "get_service_nodes") because a service node is incapable of testing itself for remote - /// connectivity. If this daemon is running in service node mode but not registered then only - /// SN pubkey, ip, and port fields are returned. - /// - \p height current top block height at the time of the request (note that this is generally + /// - `service_node_state` -- if this is a registered service node then all available fields for + /// this service node. See [`get_service_nodes`](#get_service_nodes) for the list of fields. + /// Note that some fields (such as remote testing results) will not be available (through this + /// call or [`get_service_nodes`](#get_service_nodes)) because a service node is incapable of + /// testing itself for remote connectivity. If this daemon is running in service node mode but + /// not registered then only SN pubkey, ip, and port fields are returned. + /// - `height` -- current top block height at the time of the request (note that this is generally /// one less than the "blockchain height"). - /// - \p block_hash current top block hash at the time of the request - /// - \p status generic RPC error code; "OK" means the request was successful. + /// - `block_hash` -- current top block hash at the time of the request + /// - `status` -- generic RPC error code; "OK" means the request was successful. struct GET_SERVICE_NODE_STATUS : NO_ARGS { static constexpr auto names() { return NAMES("get_service_node_status"); } }; - /// Retrieve the current "balance" of accrued service node rewards for - /// the given addresses. + /// RPC: blockchain/get_accrued_batched_earnings + /// + /// Retrieve the current "balance" of accrued service node rewards for the given addresses. /// /// Inputs: - /// - /// - \p addresses a set of addresses about which to query + /// - `addresses` -- a set of addresses about which to query. If omitted/empty then all addresses + /// with balances are returned. /// /// Outputs: - /// - /// - \p balances a dict of {address: balance} + /// - `balances` -- a dict where keys are the wallet addresses and values are the balance (in + /// atomic OXEN units). struct GET_ACCRUED_BATCHED_EARNINGS : PUBLIC { static constexpr auto names() { return NAMES("get_accrued_batched_earnings"); } @@ -1883,6 +2275,8 @@ namespace cryptonote::rpc { } request; }; + /// Dev-RPC: service_node/storage_server_ping + /// /// Endpoint to receive an uptime ping from the connected storage server. This is used /// to record whether the storage server is ready before the service node starts /// sending uptime proofs. This is usually called internally from the storage server @@ -1890,27 +2284,34 @@ namespace cryptonote::rpc { /// /// Inputs: /// - /// - \p version Storage server version - /// - \p https_port Storage server https port to include in uptime proofs. - /// - \p omq_port Storage server oxenmq port to include in uptime proofs. + /// - `version` -- Storage server version (as an array of three integers). + /// - `https_port` -- Storage server https port to include in uptime proofs. + /// - `omq_port` -- Storage server oxenmq port to include in uptime proofs. + /// - `ed25519_pubkey` -- Service node Ed25519 pubkey for verifying that storage server is running + /// with the correct service node keys. + /// - `error` -- If given and non-empty then this is an error message telling oxend to *not* + /// submit an uptime proof and to report this error in the logs instead. Oxend won't send + /// proofs until it gets another ping (without an error). /// - /// Output values available from a restricted/admin RPC endpoint: + /// Outputs: /// - /// - \p status generic RPC error code; "OK" means the request was successful. + /// - `status` -- generic RPC error code; "OK" means the request was successful. struct STORAGE_SERVER_PING : RPC_COMMAND { static constexpr auto names() { return NAMES("storage_server_ping"); } struct request_parameters { - std::array version; // Storage server version - uint16_t https_port; // Storage server https port to include in uptime proofs - uint16_t omq_port; // Storage Server oxenmq port to include in uptime proofs - std::string ed25519_pubkey; // Service node Ed25519 pubkey for verifying that storage server is using the right one - std::string error; // If given and non-empty then this is an error message telling oxend to *not* submit an uptime proof and to report this error in the logs instead. Oxend won't send proofs until it gets another ping (without an error). + std::array version; + uint16_t https_port; + uint16_t omq_port; + std::string ed25519_pubkey; + std::string error; } request; }; + /// Dev-RPC: service_node/lokinet_ping + /// /// Endpoint to receive an uptime ping from the connected lokinet server. This is used /// to record whether lokinet is ready before the service node starts sending uptime proofs. /// This is usually called internally from Lokinet and this endpoint is mostly @@ -1918,74 +2319,98 @@ namespace cryptonote::rpc { /// /// Inputs: /// - /// - \p version Lokinet version + /// - `version` -- Lokinet version (as an array of three integers). + /// - `ed25519_pubkey` -- Service node Ed25519 pubkey for verifying that lokinet is running with + /// the correct service node keys. + /// - `error` -- If given and non-empty then this is an error message telling oxend to *not* + /// submit an uptime proof and to report this error in the logs instead. Oxend won't send + /// proofs until it gets another ping (without an error). /// - /// Output values available from a restricted/admin RPC endpoint: + /// Outputs: /// - /// - \p status generic RPC error code; "OK" means the request was successful. + /// - `status` -- generic RPC error code; "OK" means the request was successful. struct LOKINET_PING : RPC_COMMAND { static constexpr auto names() { return NAMES("lokinet_ping"); } struct request_parameters { - std::array version; // Lokinet version - std::string ed25519_pubkey; // Service node Ed25519 pubkey for verifying that lokinet is using the right one - std::string error; // If given and non-empty then this is an error message telling oxend to *not* submit an uptime proof and to report this error in the logs instead. Oxend won't send proofs until it gets another ping (without an error). + std::array version; + std::string ed25519_pubkey; + std::string error; } request; }; + /// RPC: service_node/get_staking_requirement + /// /// Get the required amount of Oxen to become a Service Node at the queried height. /// For devnet and testnet values, ensure the daemon is started with the /// `--devnet` or `--testnet` flags respectively. /// /// Inputs: /// - /// - \p height The height to query the staking requirement for. 0 (or omitting) means current height. + /// - `height` -- The height to query the staking requirement for. 0 (or omitting) means current + /// height. /// - /// Output values available from a public RPC endpoint: + /// Outputs: /// - /// - \p status generic RPC error code; "OK" means the request was successful. - /// - \p staking_requirement The staking requirement in Oxen, in atomic units. - /// - \p height The height requested (or current height if 0 was requested) + /// - `status` -- generic RPC error code; "OK" means the request was successful. + /// - `staking_requirement` -- The staking requirement in Oxen, in atomic units. + /// - `height` -- The height requested (or current height if 0 was requested) struct GET_STAKING_REQUIREMENT : PUBLIC { static constexpr auto names() { return NAMES("get_staking_requirement"); } struct request_parameters { - uint64_t height; // The height to query the staking requirement for. 0 (or omitting) means current height. + uint64_t height; } request; }; + /// RPC: blockchain/get_service_node_blacklisted_key_images + /// /// Get information on blacklisted Service Node key images. /// /// Inputs: None /// - /// Output values available from a public RPC endpoint: + /// Outputs: /// - /// - \p status generic RPC error code; "OK" means the request was successful. - /// - \p blacklist Array of blacklisted key images, i.e. unspendable transactions. Each entry contains - /// - \p key_image The key image of the transaction that is blacklisted on the network. - /// - \p unlock_height The height at which the key image is removed from the blacklist and becomes spendable. - /// - \p amount The total amount of locked Loki in atomic units in this blacklisted stake. + /// - `status` -- generic RPC error code; "OK" means the request was successful. + /// - `blacklist` -- Array of blacklisted key images, i.e. unspendable transactions. Each entry + /// contains: + /// - `key_image` -- The key image of the transaction that is blacklisted on the network. + /// - `unlock_height` -- The height at which the key image is removed from the blacklist and + /// becomes spendable. + /// - `amount` -- The total amount of locked Loki in atomic units in this blacklisted stake. struct GET_SERVICE_NODE_BLACKLISTED_KEY_IMAGES : PUBLIC, NO_ARGS { static constexpr auto names() { return NAMES("get_service_node_blacklisted_key_images"); } }; - /// Query hardcoded/service node checkpoints stored for the blockchain. Omit all arguments to retrieve the latest "count" checkpoints. + /// RPC: blockchain/get_checkpoints + /// + /// Query hardcoded/service node checkpoints stored for the blockchain. Omit all arguments to + /// retrieve the latest "count" checkpoints. /// /// Inputs: /// - /// - \p start_height Optional: Get the first count checkpoints starting from this height. Specify both start and end to get the checkpoints inbetween. - /// - \p end_height Optional: Get the first count checkpoints before end height. Specify both start and end to get the checkpoints inbetween. - /// - \p count Optional: Number of checkpoints to query. + /// - `start_height` -- Optional: Get the first count checkpoints starting from this height. + /// Specify both start and end to get the checkpoints inbetween. + /// - `end_height` -- Optional: Get the first count checkpoints before end height. Specify both + /// start and end to get the checkpoints inbetween. + /// - `count` -- Optional: Number of checkpoints to query. /// - /// Output values available from a public RPC endpoint: + /// Outputs: /// - /// - \p status generic RPC error code; "OK" means the request was successful. - /// - \p checkpoints Array of requested checkpoints + /// - `status` -- generic RPC error code; "OK" means the request was successful. + /// - `checkpoints` -- Array of requested checkpoints + /// + /// Example input: + /// ```json + /// { "count": 2 } + /// ``` + /// + /// Example-JSON-Fetch struct GET_CHECKPOINTS : PUBLIC { static constexpr auto names() { return NAMES("get_checkpoints"); } @@ -1994,30 +2419,38 @@ namespace cryptonote::rpc { static constexpr uint32_t NUM_CHECKPOINTS_TO_QUERY_BY_DEFAULT = 60; struct request_parameters { - std::optional start_height; // Optional: Get the first count checkpoints starting from this height. Specify both start and end to get the checkpoints inbetween. - std::optional end_height; // Optional: Get the first count checkpoints before end height. Specify both start and end to get the checkpoints inbetween. - std::optional count; // Optional: Number of checkpoints to query. + std::optional start_height; + std::optional end_height; + std::optional count; } request; }; - /// Query recent service node state changes processed on the blockchain. + /// RPC: blockchain/get_service_nodes_state_changes + /// + /// Query the number of service node state change transactions contained in a range of blocks. /// /// Inputs: /// - /// - \p start_height Returns counts starting from this block height. Required. - /// - \p end_height Optional: returns count ending at this block height; if omitted, counts to the - /// current height. + /// - `start_height` -- The starting block's height. + /// - `end_height` -- The ending block's height. /// - /// Output values available from a private/admin RPC endpoint: + /// Outputs: /// - /// - \p status Generic RPC error code. "OK" is the success value. - /// - \p total_deregister - /// - \p total_ip_change_penalty - /// - \p total_decommission - /// - \p total_recommission - /// - \p total_unlock - /// - \p start_height - /// - \p end_height + /// - `status` -- Generic RPC error code. "OK" is the success value. + /// - `total_deregister` -- the total number of service node deregistrations + /// - `total_ip_change_penalty` -- the total number of IP change penalties + /// - `total_decommission` -- the total number of service node decommissions + /// - `total_recommission` -- the total number of service node recommissions + /// - `total_unlock` -- the total number of service node unlock requests + /// - `start_height` -- the start height of the given statistics + /// - `end_height` -- the end height of the given statistics + /// + /// Example input: + /// ```json + /// { "start_height": 1085000, "end_height": 1085191 } + /// ``` + /// + /// Example-JSON-Fetch struct GET_SN_STATE_CHANGES : RPC_COMMAND { static constexpr auto names() { return NAMES("get_service_nodes_state_changes"); } @@ -2030,18 +2463,20 @@ namespace cryptonote::rpc { }; + /// Dev-RPC: service_node/report_peer_status + /// /// Reports service node peer status (success/fail) from lokinet and storage server. /// /// Inputs: /// - /// - \p type test type; currently supported are: "storage" and "lokinet" for storage server and + /// - `type` -- test type; currently supported are: "storage" and "lokinet" for storage server and /// lokinet tests, respectively. - /// - \p pubkey service node pubkey - /// - \p passed whether node is passing the test + /// - `pubkey` -- service node pubkey + /// - `passed` -- whether node is passing the test /// - /// Output values available from a private/admin RPC endpoint: + /// Outputs: /// - /// - \p status Generic RPC error code. "OK" is the success value. + /// - `status` -- Generic RPC error code. "OK" is the success value. struct REPORT_PEER_STATUS : RPC_COMMAND { // TODO: remove the `report_peer_storage_server_status` once we require a storage server version @@ -2050,33 +2485,37 @@ namespace cryptonote::rpc { struct request_parameters { - std::string type; // test type; currently supported are: "storage" and "lokinet" for storage server and lokinet tests, respectively. - std::string pubkey; // service node pubkey - bool passed; // whether the node is passing the test + std::string type; + std::string pubkey; + bool passed; } request; }; + /// Dev-RPC: daemon/test_trigger_p2p_resync + /// /// Deliberately undocumented; this RPC call is really only useful for testing purposes to reset /// the resync idle timer (which normally fires every 60s) for the test suite. /// /// Inputs: none /// - /// Output values available from a private/admin RPC endpoint: + /// Outputs: /// - /// - \p status Generic RPC error code. "OK" is the success value. + /// - `status` -- Generic RPC error code. "OK" is the success value. struct TEST_TRIGGER_P2P_RESYNC : NO_ARGS { static constexpr auto names() { return NAMES("test_trigger_p2p_resync"); } }; + /// Dev-RPC: service_node/test_trigger_uptime_proof + /// /// Deliberately undocumented; this RPC call is really only useful for testing purposes to /// force send an uptime proof. NOT available on mainnet /// /// Inputs: none /// - /// Output values available from a private/admin RPC endpoint: + /// Outputs: /// - /// - \p status Generic RPC error code. "OK" is the success value. + /// - `status` -- Generic RPC error code. "OK" is the success value. struct TEST_TRIGGER_UPTIME_PROOF : NO_ARGS { static constexpr auto names() { return NAMES("test_trigger_uptime_proof"); } @@ -2131,27 +2570,39 @@ namespace cryptonote::rpc { }; }; - /// Get all the name mappings for the queried owner. The owner can be either a ed25519 public key or Monero style - /// public key; by default purchases are owned by the spend public key of the purchasing wallet. + /// RPC: ons/ons_owners_to_names + /// + /// Get all the name mappings for the queried owner. The owner can be either a ed25519 public key + /// or Monero style public key; by default purchases are owned by the spend public key of the + /// purchasing wallet. /// /// Inputs: /// - /// - \p entries List of owner's public keys to find all Oxen Name Service entries for. - /// - \p include_expired Optional: if provided and true, include entries in the results even if they are expired + /// - `entries` -- List of owner's public keys to find all Oxen Name Service entries for. + /// - `include_expired` -- Optional: if provided and true, include entries in the results even if + /// they are expired /// - /// Output values available from a public RPC endpoint: + /// Outputs: /// - /// - \p status Generic RPC error code. "OK" is the success value. - /// - \p entries List of ONS names. Each element is structured as follows: - /// - \p request_index (Deprecated) The index in request's `entries` array that was resolved via Loki Name Service. - /// - \p type The category the Loki Name Service entry belongs to; currently 0 for Session, 1 for Wallet and 2 for Lokinet. - /// - \p name_hash The hash of the name that the owner purchased via Loki Name Service in base64 - /// - \p owner The backup public key specified by the owner that purchased the Loki Name Service entry. - /// - \p backup_owner The backup public key specified by the owner that purchased the Loki Name Service entry. Omitted if no backup owner. - /// - \p encrypted_value The encrypted value that the name maps to, in hex. This value is encrypted using the name (not the hash) as the secret. - /// - \p update_height The last height that this Loki Name Service entry was updated on the Blockchain. - /// - \p expiration_height For records that expire, this will be set to the expiration block height. - /// - \p txid The txid of the mapping's most recent update or purchase. + /// - `status` -- Generic RPC error code. "OK" is the success value. + /// - `entries` -- List of ONS names. Each element is structured as follows: + /// - `request_index` -- (Deprecated) The index in request's `entries` array that was resolved + /// via Loki Name Service. + /// - `type` -- The category the Loki Name Service entry belongs to; currently 0 for Session, 1 + /// for Wallet and 2 for Lokinet. + /// - `name_hash` -- The hash of the name that the owner purchased via Loki Name Service in + /// base64 + /// - `owner` -- The backup public key specified by the owner that purchased the Loki Name + /// Service entry. + /// - `backup_owner` -- The backup public key specified by the owner that purchased the Loki + /// Name Service entry. Omitted if no backup owner. + /// - `encrypted_value` -- The encrypted value that the name maps to, in hex. This value is + /// encrypted using the name (not the hash) as the secret. + /// - `update_height` -- The last height that this Loki Name Service entry was updated on the + /// Blockchain. + /// - `expiration_height` -- For records that expire, this will be set to the expiration block + /// height. + /// - `txid` -- The txid of the mapping's most recent update or purchase. struct ONS_OWNERS_TO_NAMES : PUBLIC { static constexpr auto names() { return NAMES("ons_owners_to_names", "lns_owners_to_names"); } @@ -2159,34 +2610,44 @@ namespace cryptonote::rpc { static constexpr size_t MAX_REQUEST_ENTRIES = 256; struct request_parameters { - std::vector entries; // The owner's public key to find all Loki Name Service entries for. - bool include_expired; // Optional: if provided and true, include entries in the results even if they are expired + std::vector entries; + bool include_expired; } request; struct response_entry { - uint64_t request_index; // (Deprecated) The index in request's `entries` array that was resolved via Loki Name Service. - ons::mapping_type type; // The category the Loki Name Service entry belongs to; currently 0 for Session, 1 for Wallet and 2 for Lokinet. - std::string name_hash; // The hash of the name that the owner purchased via Loki Name Service in base64 - std::string owner; // The backup public key specified by the owner that purchased the Loki Name Service entry. - std::optional backup_owner; // The backup public key specified by the owner that purchased the Loki Name Service entry. Omitted if no backup owner. - std::string encrypted_value; // The encrypted value that the name maps to, in hex. This value is encrypted using the name (not the hash) as the secret. - uint64_t update_height; // The last height that this Loki Name Service entry was updated on the Blockchain. - std::optional expiration_height; // For records that expire, this will be set to the expiration block height. - std::string txid; // The txid of the mapping's most recent update or purchase. + uint64_t request_index; + ons::mapping_type type; + std::string name_hash; + std::string owner; + std::optional backup_owner; + std::string encrypted_value; + uint64_t update_height; + std::optional expiration_height; + std::string txid; }; }; void to_json(nlohmann::json& j, const ONS_OWNERS_TO_NAMES::response_entry& r); + /// RPC: ons/ons_resolve + /// /// Performs a simple ONS lookup of a BLAKE2b-hashed name. This RPC method is meant for simple, /// single-value resolutions that do not care about registration details, etc.; if you need more /// information use ONS_NAMES_TO_OWNERS instead. /// - /// Returned values: + /// Inputs: /// - /// - \p encrypted_value The encrypted ONS value, in hex. Will be omitted from the response if + /// - `type` -- The ONS type (mandatory); currently support values are: `0` for Session, `1` for + /// wallet, and `2` for Lokinet. + /// - `name_hash` -- The 32-byte BLAKE2b hash of the name to look up, encoded as 64 hex digits or + /// 44/43 base64 characters (with/without padding). For bt-encoded requests this can also be + /// the raw 32 bytes. + /// + /// Outputs: + /// + /// - `encrypted_value` -- The encrypted ONS value, in hex. Will be omitted from the response if /// the given name_hash is not registered. - /// - \p nonce The nonce value used for encryption, in hex. Will be omitted if the given name is + /// - `nonce` -- The nonce value used for encryption, in hex. Will be omitted if the given name is /// not registered. /// /// Technical details: the returned value is encrypted using the name itself so that neither this @@ -2203,6 +2664,88 @@ namespace cryptonote::rpc { /// 5. Decrypt (and verify) using XChaCha20-Poly1305 (for example libsodium's /// crypto_aead_xchacha20poly1305_ietf_decrypt) using the above decryption key and using the /// first 24 bytes of the name hash as the public nonce. + /// + /// Example input: + /// + /// To look up the lokinet address for blocks.loki, we first need to get the name hash. Using + /// Python, for example: + /// + /// ```python + /// >>> import hashlib + /// >>> import base64 + /// >>> name_hash = hashlib.blake2b(b'blocks.loki', digest_size=32).digest() + /// >>> base64.b64encode(name_hash) + /// b'IeynFEjyxigd0Lcmo5FWYaGp/uVXsa5grK8Jml0ai3o=' + /// ``` + /// + /// Which then allows the RPC lookup: + /// + /// ```json + /// { "type": 2, "name_hash": "IeynFEjyxigd0Lcmo5FWYaGp/uVXsa5grK8Jml0ai3o=" } + /// ``` + /// + /// Example output: + /// + /// ```json + /// { + /// "encrypted_value": "b52c088ae51171a9e2e44cc98c10006547e2981d4cbe196525c948fa2fa48a11e8712eccd0ba20e4b93fb3989361df8a", + /// "nonce": "6e3e80c7927108612475a0eeddf472af6177c9776d6943ed" + /// } + /// ``` + /// + /// To decrypt, again using Python for an example: + /// + /// ```python + /// >>> import hashlib + /// >>> import base64 + /// >>> import nacl.bindings + /// >>> import oxenc + /// >>> data = bytes.fromhex("b52c088ae51171a9e2e44cc98c10006547e2981d4cbe196525c948fa2fa48a11e8712eccd0ba20e4b93fb3989361df8a") + /// >>> nonce = bytes.fromhex("6e3e80c7927108612475a0eeddf472af6177c9776d6943ed") + /// >>> name_hash = hashlib.blake2b(b'blocks.loki', digest_size=32).digest() + /// >>> key = hashlib.blake2b(b'blocks.loki', key=name_hash, digest_size=32).digest() + /// >>> val = nacl.bindings.crypto_aead_xchacha20poly1305_ietf_decrypt(ciphertext=data, nonce=nonce, aad=b'', key=key) + /// >>> oxenc.to_base32z(val) + ".loki" + /// 'kcpyawm9se7trdbzncimdi5t7st4p5mh9i1mg7gkpuubi4k4ku1y.loki' + /// ``` + /// + /// which is the full lokinet address of the blocks.loki. + /// + /// Example input: + /// + /// For a Session lookup you follow exactly the same steps as the above example, but using the + /// session ID instead of `blocks.loki`. For example for the Session ONS `jagerman` you would get + /// the name_hash and then request: + /// + /// ```json + /// { "type": 0, "name_hash": "yB7mbm2q1MaczqNZCYguH+71z5jooEMeXA0sncfni+g=" } + /// ``` + /// + /// Example output: + /// + /// ```json + /// { + /// "encrypted_value": "d9bca6752665f2254ec7522f98aa5f2dfb13c9fa1ad1e39cd3d7a89a0df04719e348da537bc310a53e3b59ca24639b9b42", + /// "nonce": "73e8243f3fadd471be36c6df3d62f863f9bb3a9d1cc696c0" + /// } + /// ``` + /// + /// Decryption here is exactly the same as the above example except for the last step: + /// + /// ```python + /// >>> import hashlib + /// >>> import base64 + /// >>> import nacl.bindings + /// >>> data = bytes.fromhex("d9bca6752665f2254ec7522f98aa5f2dfb13c9fa1ad1e39cd3d7a89a0df04719e348da537bc310a53e3b59ca24639b9b42") + /// >>> nonce = bytes.fromhex("73e8243f3fadd471be36c6df3d62f863f9bb3a9d1cc696c0") + /// >>> name_hash = hashlib.blake2b(b'jagerman', digest_size=32).digest() + /// >>> key = hashlib.blake2b(b'jagerman', key=name_hash, digest_size=32).digest() + /// >>> val = nacl.bindings.crypto_aead_xchacha20poly1305_ietf_decrypt(ciphertext=data, nonce=nonce, aad=b'', key=key) + /// >>> '05' + val.hex() + /// '0505fb466d312e1666ad1c84c4ee55b7e034151c0e366a313d95d11436a5f36e1e75' + /// ``` + /// + /// which is jagerman's full Session ID. struct ONS_RESOLVE : PUBLIC { static constexpr auto names() { return NAMES("ons_resolve", "lns_resolve"); } @@ -2211,39 +2754,38 @@ namespace cryptonote::rpc { /// The ONS type (mandatory); currently supported values are: 0 = session, 1 = wallet, 2 = /// lokinet. int type = -1; - /// The 32-byte BLAKE2b hash of the name to look up, encoded as 64 hex digits or 44/43 base64 - /// characters (with/without padding). For bt-encoded requests this can also be the raw 32 - /// bytes. std::string name_hash; } request; }; + /// RPC: daemon/flush_cache + /// /// Clear TXs from the daemon cache, currently only the cache storing TX hashes that were /// previously verified bad by the daemon. /// /// Inputs: /// - /// - \p bad_txs Clear the cache storing TXs that failed verification. - /// - \p bad_blocks Clear the cache storing blocks that failed verfication. + /// - `bad_txs` -- Clear the cache storing TXs that failed verification. + /// - `bad_blocks` -- Clear the cache storing blocks that failed verfication. /// - /// Output values available from a private/admin RPC endpoint: + /// Outputs: /// - /// - \p status Generic RPC error code. "OK" is the success value. + /// - `status` -- Generic RPC error code. "OK" is the success value. struct FLUSH_CACHE : RPC_COMMAND { static constexpr auto names() { return NAMES("flush_cache"); } struct request_parameter { - bool bad_txs; // Clear the cache storing TXs that failed verification. - bool bad_blocks; // Clear the cache storing blocks that failed verfication. + bool bad_txs; + bool bad_blocks; } request; }; - /// List of all supported rpc command structs to allow compile-time enumeration of all supported - /// RPC types. Every type added above that has an RPC endpoint needs to be added here, and needs - /// a core_rpc_server::invoke() overload that takes a ::request and returns a - /// ::response. The ::request has to be unique (for overload resolution); - /// ::response does not. + // List of all supported rpc command structs to allow compile-time enumeration of all supported + // RPC types. Every type added above that has an RPC endpoint needs to be added here, and needs + // a core_rpc_server::invoke() overload that takes a ::request and returns a + // ::response. The ::request has to be unique (for overload resolution); + // ::response does not. using core_rpc_types = tools::type_list< BANNED, FLUSH_CACHE,