mirror of
https://github.com/oxen-io/oxen-core.git
synced 2023-12-14 02:22:56 +01:00
RPC: +peerlist, -publicnodes
Updates GET_PEER_LIST to new RPC. Removes GET_PUBLIC_NODES because we don't use this option at all in oxend. (At the point where we need a decentralized public node repository we'll almost certainly want to use the service node network to do it, not the p2p layer).
This commit is contained in:
parent
e1ef4a44e4
commit
ff0c76d7f3
|
@ -225,6 +225,7 @@ namespace net_utils
|
|||
|
||||
virtual std::string str() const = 0;
|
||||
virtual std::string host_str() const = 0;
|
||||
virtual uint16_t port() const = 0;
|
||||
virtual bool is_loopback() const = 0;
|
||||
virtual bool is_local() const = 0;
|
||||
virtual address_type get_type_id() const = 0;
|
||||
|
@ -255,6 +256,7 @@ namespace net_utils
|
|||
|
||||
virtual std::string str() const override { return value.str(); }
|
||||
virtual std::string host_str() const override { return value.host_str(); }
|
||||
virtual uint16_t port() const override { return value.port(); }
|
||||
virtual bool is_loopback() const override { return value.is_loopback(); }
|
||||
virtual bool is_local() const override { return value.is_local(); }
|
||||
virtual address_type get_type_id() const override { return value.get_type_id(); }
|
||||
|
@ -303,6 +305,7 @@ namespace net_utils
|
|||
bool is_same_host(const network_address &other) const;
|
||||
std::string str() const { return self ? self->str() : "<none>"; }
|
||||
std::string host_str() const { return self ? self->host_str() : "<none>"; }
|
||||
uint16_t port() const { return self ? self->port() : 0; }
|
||||
bool is_loopback() const { return self ? self->is_loopback() : false; }
|
||||
bool is_local() const { return self ? self->is_local() : false; }
|
||||
address_type get_type_id() const { return self ? self->get_type_id() : address_type::invalid; }
|
||||
|
|
|
@ -112,24 +112,6 @@ namespace {
|
|||
return input_line_result::yes;
|
||||
}
|
||||
|
||||
void print_peer(std::string const & prefix, GET_PEER_LIST::peer const & peer, bool pruned_only, bool publicrpc_only)
|
||||
{
|
||||
if (pruned_only && peer.pruning_seed == 0)
|
||||
return;
|
||||
if (publicrpc_only && peer.rpc_port == 0)
|
||||
return;
|
||||
|
||||
time_t now = std::time(nullptr);
|
||||
time_t last_seen = static_cast<time_t>(peer.last_seen);
|
||||
|
||||
std::string elapsed = peer.last_seen == 0 ? "never" : epee::misc_utils::get_time_interval_string(now - last_seen);
|
||||
std::string id_str = epee::string_tools::pad_string(epee::string_tools::to_string_hex(peer.id), 16, '0', true);
|
||||
std::string addr_str = peer.host + ":" + std::to_string(peer.port);
|
||||
std::string rpc_port = peer.rpc_port ? std::to_string(peer.rpc_port) : "-";
|
||||
std::string pruning_seed = epee::string_tools::to_string_hex(peer.pruning_seed);
|
||||
tools::msg_writer() << fmt::format("{:<10} {:<25} {:<25} {:<5} %{:-4} {}", prefix, id_str, addr_str, rpc_port, pruning_seed, elapsed);
|
||||
}
|
||||
|
||||
void print_block_header(block_header_response const & header)
|
||||
{
|
||||
tools::success_msg_writer()
|
||||
|
@ -178,6 +160,36 @@ namespace {
|
|||
std::string get_human_time_ago(std::time_t t, std::time_t now, bool abbreviate = false) {
|
||||
return get_human_time_ago(std::chrono::seconds{now - t}, abbreviate);
|
||||
}
|
||||
|
||||
bool print_peer(std::string_view prefix, const json& peer, bool pruned_only, bool publicrpc_only)
|
||||
{
|
||||
auto pruning_seed = peer.value<uint64_t>("pruning_seed", 0);
|
||||
if (pruned_only && pruning_seed == 0)
|
||||
return false;
|
||||
auto rpc_port = peer.value<uint16_t>("rpc_port", 0);
|
||||
if (publicrpc_only && rpc_port == 0)
|
||||
return false;
|
||||
|
||||
time_t now = std::time(nullptr);
|
||||
time_t last_seen = peer.value<time_t>("last_seen", 0);
|
||||
|
||||
tools::msg_writer() << fmt::format("{:<10} {:016x} {:<30} {:<5} {:<4x} {}",
|
||||
prefix,
|
||||
peer["id"].get<uint64_t>(),
|
||||
fmt::format("{}:{}", peer["host"].get<std::string_view>(), peer["ip"].get<uint16_t>()),
|
||||
rpc_port == 0 ? "-" : tools::int_to_string(rpc_port),
|
||||
pruning_seed,
|
||||
last_seen == 0 ? "never" : get_human_time_ago(last_seen, now));
|
||||
return true;
|
||||
}
|
||||
|
||||
template <typename... Args>
|
||||
void print_peers(std::string_view prefix, const json& peers, size_t& limit, Args&&... args) {
|
||||
for (auto it = peers.begin(); it != peers.end() && limit > 0; it++)
|
||||
if (print_peer(prefix, *it, std::forward<Args>(args)...))
|
||||
limit--;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
rpc_command_executor::rpc_command_executor(
|
||||
|
@ -334,43 +346,35 @@ bool rpc_command_executor::print_sn_state_changes(uint64_t start_height, uint64_
|
|||
}
|
||||
|
||||
bool rpc_command_executor::print_peer_list(bool white, bool gray, size_t limit, bool pruned_only, bool publicrpc_only) {
|
||||
GET_PEER_LIST::response res{};
|
||||
|
||||
if (!invoke<GET_PEER_LIST>({}, res, "Couldn't retrieve peer list"))
|
||||
auto maybe_pl = try_running([this] { return invoke<GET_PEER_LIST>(); }, "Failed to retrieve peer list");
|
||||
if (!maybe_pl)
|
||||
return false;
|
||||
auto& pl = *maybe_pl;
|
||||
|
||||
if (white)
|
||||
{
|
||||
auto peer = res.white_list.cbegin();
|
||||
const auto end = limit ? peer + std::min(limit, res.white_list.size()) : res.white_list.cend();
|
||||
for (; peer != end; ++peer)
|
||||
{
|
||||
print_peer("white", *peer, pruned_only, publicrpc_only);
|
||||
}
|
||||
}
|
||||
|
||||
print_peers("white", pl["white_list"], limit, pruned_only, publicrpc_only);
|
||||
if (gray)
|
||||
{
|
||||
auto peer = res.gray_list.cbegin();
|
||||
const auto end = limit ? peer + std::min(limit, res.gray_list.size()) : res.gray_list.cend();
|
||||
for (; peer != end; ++peer)
|
||||
{
|
||||
print_peer("gray", *peer, pruned_only, publicrpc_only);
|
||||
}
|
||||
}
|
||||
print_peers("gray", pl["gray_list"], limit, pruned_only, publicrpc_only);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool rpc_command_executor::print_peer_list_stats() {
|
||||
GET_PEER_LIST::response res{};
|
||||
|
||||
if (!invoke<GET_PEER_LIST>({}, res, "Couldn't retrieve peer list"))
|
||||
auto maybe_info = try_running([this] { return invoke<GET_INFO>(); }, "Failed to retrieve node info");
|
||||
if (!maybe_info)
|
||||
return false;
|
||||
auto& info = *maybe_info;
|
||||
|
||||
auto wls = info.find("white_peerlist_size");
|
||||
auto gls = info.find("grey_peerlist_size");
|
||||
if (wls == info.end() || gls == info.end()) {
|
||||
tools::fail_msg_writer() << "Failed to retrieve whitelist info";
|
||||
return false;
|
||||
}
|
||||
|
||||
tools::msg_writer()
|
||||
<< "White list size: " << res.white_list.size() << "/" << P2P_LOCAL_WHITE_PEERLIST_LIMIT << " (" << res.white_list.size() * 100.0 / P2P_LOCAL_WHITE_PEERLIST_LIMIT << "%)" << std::endl
|
||||
<< "Gray list size: " << res.gray_list.size() << "/" << P2P_LOCAL_GRAY_PEERLIST_LIMIT << " (" << res.gray_list.size() * 100.0 / P2P_LOCAL_GRAY_PEERLIST_LIMIT << "%)";
|
||||
<< "White list size: " << wls->get<int>() << "/" << P2P_LOCAL_WHITE_PEERLIST_LIMIT << " (" << wls->get<int>() * 100.0 / P2P_LOCAL_WHITE_PEERLIST_LIMIT << "%)\n"
|
||||
<< "Gray list size: " << gls->get<int>() << "/" << P2P_LOCAL_GRAY_PEERLIST_LIMIT << " (" << gls->get<int>() * 100.0 / P2P_LOCAL_GRAY_PEERLIST_LIMIT << "%)";
|
||||
|
||||
return true;
|
||||
}
|
||||
|
|
|
@ -260,8 +260,6 @@ namespace cryptonote::rpc {
|
|||
|
||||
if (address.empty())
|
||||
m_bootstrap_daemon.reset();
|
||||
else if (address == "auto")
|
||||
m_bootstrap_daemon = std::make_unique<bootstrap_daemon>([this]{ return get_random_public_node(); });
|
||||
else
|
||||
m_bootstrap_daemon = std::make_unique<bootstrap_daemon>(address, credentials);
|
||||
|
||||
|
@ -270,46 +268,6 @@ namespace cryptonote::rpc {
|
|||
return true;
|
||||
}
|
||||
//------------------------------------------------------------------------------------------------------------------------------
|
||||
std::optional<std::string> core_rpc_server::get_random_public_node()
|
||||
{
|
||||
GET_PUBLIC_NODES::response response{};
|
||||
try
|
||||
{
|
||||
GET_PUBLIC_NODES::request request{};
|
||||
request.gray = true;
|
||||
request.white = true;
|
||||
|
||||
rpc_context context = {};
|
||||
context.admin = true;
|
||||
response = invoke(std::move(request), context);
|
||||
}
|
||||
catch(const std::exception &e)
|
||||
{
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
const auto get_random_node_address = [](const std::vector<public_node>& public_nodes) -> std::string {
|
||||
const auto& random_node = public_nodes[crypto::rand_idx(public_nodes.size())];
|
||||
const auto address = random_node.host + ":" + std::to_string(random_node.rpc_port);
|
||||
return address;
|
||||
};
|
||||
|
||||
if (!response.white.empty())
|
||||
{
|
||||
return get_random_node_address(response.white);
|
||||
}
|
||||
|
||||
MDEBUG("No white public node found, checking gray peers");
|
||||
|
||||
if (!response.gray.empty())
|
||||
{
|
||||
return get_random_node_address(response.gray);
|
||||
}
|
||||
|
||||
MERROR("Failed to find any suitable public node");
|
||||
return std::nullopt;
|
||||
}
|
||||
//------------------------------------------------------------------------------------------------------------------------------
|
||||
void core_rpc_server::init(const boost::program_options::variables_map& vm)
|
||||
{
|
||||
if (!set_bootstrap_daemon(command_line::get_arg(vm, arg_bootstrap_daemon_address),
|
||||
|
@ -1397,81 +1355,35 @@ namespace cryptonote::rpc {
|
|||
}
|
||||
save_bc.response["status"] = STATUS_OK;
|
||||
}
|
||||
//------------------------------------------------------------------------------------------------------------------------------
|
||||
GET_PEER_LIST::response core_rpc_server::invoke(GET_PEER_LIST::request&& req, rpc_context context)
|
||||
{
|
||||
GET_PEER_LIST::response res{};
|
||||
|
||||
PERF_TIMER(on_get_peer_list);
|
||||
std::vector<nodetool::peerlist_entry> white_list;
|
||||
std::vector<nodetool::peerlist_entry> gray_list;
|
||||
|
||||
if (req.public_only)
|
||||
{
|
||||
m_p2p.get_public_peerlist(gray_list, white_list);
|
||||
}
|
||||
else
|
||||
{
|
||||
m_p2p.get_peerlist(gray_list, white_list);
|
||||
}
|
||||
|
||||
for (auto & entry : white_list)
|
||||
{
|
||||
if (entry.adr.get_type_id() == epee::net_utils::ipv4_network_address::get_type_id())
|
||||
res.white_list.emplace_back(entry.id, entry.adr.as<epee::net_utils::ipv4_network_address>().ip(),
|
||||
entry.adr.as<epee::net_utils::ipv4_network_address>().port(), entry.last_seen, entry.pruning_seed, entry.rpc_port);
|
||||
else if (entry.adr.get_type_id() == epee::net_utils::ipv6_network_address::get_type_id())
|
||||
res.white_list.emplace_back(entry.id, entry.adr.as<epee::net_utils::ipv6_network_address>().host_str(),
|
||||
entry.adr.as<epee::net_utils::ipv6_network_address>().port(), entry.last_seen, entry.pruning_seed, entry.rpc_port);
|
||||
else
|
||||
res.white_list.emplace_back(entry.id, entry.adr.str(), entry.last_seen, entry.pruning_seed, entry.rpc_port);
|
||||
}
|
||||
|
||||
for (auto & entry : gray_list)
|
||||
{
|
||||
if (entry.adr.get_type_id() == epee::net_utils::ipv4_network_address::get_type_id())
|
||||
res.gray_list.emplace_back(entry.id, entry.adr.as<epee::net_utils::ipv4_network_address>().ip(),
|
||||
entry.adr.as<epee::net_utils::ipv4_network_address>().port(), entry.last_seen, entry.pruning_seed, entry.rpc_port);
|
||||
else if (entry.adr.get_type_id() == epee::net_utils::ipv6_network_address::get_type_id())
|
||||
res.gray_list.emplace_back(entry.id, entry.adr.as<epee::net_utils::ipv6_network_address>().host_str(),
|
||||
entry.adr.as<epee::net_utils::ipv6_network_address>().port(), entry.last_seen, entry.pruning_seed, entry.rpc_port);
|
||||
else
|
||||
res.gray_list.emplace_back(entry.id, entry.adr.str(), entry.last_seen, entry.pruning_seed, entry.rpc_port);
|
||||
}
|
||||
|
||||
res.status = STATUS_OK;
|
||||
return res;
|
||||
}
|
||||
//------------------------------------------------------------------------------------------------------------------------------
|
||||
GET_PUBLIC_NODES::response core_rpc_server::invoke(GET_PUBLIC_NODES::request&& req, rpc_context context)
|
||||
{
|
||||
PERF_TIMER(on_get_public_nodes);
|
||||
|
||||
GET_PEER_LIST::response peer_list_res = invoke(GET_PEER_LIST::request{}, context);
|
||||
GET_PUBLIC_NODES::response res{};
|
||||
res.status = std::move(peer_list_res.status);
|
||||
|
||||
const auto collect = [](const std::vector<GET_PEER_LIST::peer> &peer_list, std::vector<public_node> &public_nodes)
|
||||
{
|
||||
for (const auto &entry : peer_list)
|
||||
{
|
||||
if (entry.rpc_port != 0)
|
||||
{
|
||||
public_nodes.emplace_back(entry);
|
||||
}
|
||||
}
|
||||
static nlohmann::json json_peer_info(const nodetool::peerlist_entry& peer) {
|
||||
auto addr_type = peer.adr.get_type_id();
|
||||
nlohmann::json p{
|
||||
{"id", peer.id},
|
||||
{"host", peer.adr.host_str()},
|
||||
{"port", peer.adr.port()},
|
||||
{"last_seen", peer.last_seen}
|
||||
};
|
||||
if (peer.pruning_seed) p["pruning_seed"] = peer.pruning_seed;
|
||||
if (peer.rpc_port) p["rpc_port"] = peer.rpc_port;
|
||||
return p;
|
||||
}
|
||||
|
||||
if (req.white)
|
||||
{
|
||||
collect(peer_list_res.white_list, res.white);
|
||||
}
|
||||
if (req.gray)
|
||||
{
|
||||
collect(peer_list_res.gray_list, res.gray);
|
||||
}
|
||||
//------------------------------------------------------------------------------------------------------------------------------
|
||||
void core_rpc_server::invoke(GET_PEER_LIST& pl, rpc_context context)
|
||||
{
|
||||
PERF_TIMER(on_get_peer_list);
|
||||
std::vector<nodetool::peerlist_entry> white_list, gray_list;
|
||||
|
||||
return res;
|
||||
if (pl.request.public_only)
|
||||
m_p2p.get_public_peerlist(gray_list, white_list);
|
||||
else
|
||||
m_p2p.get_peerlist(gray_list, white_list);
|
||||
|
||||
std::transform(white_list.begin(), white_list.end(), std::back_inserter(pl.response["white_list"]), json_peer_info);
|
||||
std::transform(gray_list.begin(), gray_list.end(), std::back_inserter(pl.response["gray_list"]), json_peer_info);
|
||||
|
||||
pl.response["status"] = STATUS_OK;
|
||||
}
|
||||
//------------------------------------------------------------------------------------------------------------------------------
|
||||
SET_LOG_LEVEL::response core_rpc_server::invoke(SET_LOG_LEVEL::request&& req, rpc_context context)
|
||||
|
|
|
@ -225,6 +225,7 @@ namespace cryptonote::rpc {
|
|||
void invoke(IS_KEY_IMAGE_SPENT& spent, rpc_context context);
|
||||
void invoke(SUBMIT_TRANSACTION& tx, rpc_context context);
|
||||
void invoke(GET_BLOCK_HASH& req, rpc_context context);
|
||||
void invoke(GET_PEER_LIST& pl, rpc_context context);
|
||||
|
||||
// Deprecated Monero NIH binary endpoints:
|
||||
GET_ALT_BLOCKS_HASHES_BIN::response invoke(GET_ALT_BLOCKS_HASHES_BIN::request&& req, rpc_context context);
|
||||
|
@ -238,8 +239,6 @@ namespace cryptonote::rpc {
|
|||
GET_TX_GLOBAL_OUTPUTS_INDEXES_BIN::response invoke(GET_TX_GLOBAL_OUTPUTS_INDEXES_BIN::request&& req, rpc_context context);
|
||||
|
||||
// FIXME: unconverted JSON RPC endpoints:
|
||||
GET_PEER_LIST::response invoke(GET_PEER_LIST::request&& req, rpc_context context);
|
||||
GET_PUBLIC_NODES::response invoke(GET_PUBLIC_NODES::request&& req, rpc_context context);
|
||||
SET_LOG_LEVEL::response invoke(SET_LOG_LEVEL::request&& req, rpc_context context);
|
||||
SET_LOG_CATEGORIES::response invoke(SET_LOG_CATEGORIES::request&& req, rpc_context context);
|
||||
SET_BOOTSTRAP_DAEMON::response invoke(SET_BOOTSTRAP_DAEMON::request&& req, rpc_context context);
|
||||
|
@ -293,7 +292,6 @@ private:
|
|||
|
||||
//utils
|
||||
uint64_t get_block_reward(const block& blk);
|
||||
std::optional<std::string> get_random_public_node();
|
||||
bool set_bootstrap_daemon(const std::string &address, std::string_view username_password);
|
||||
bool set_bootstrap_daemon(const std::string &address, std::string_view username, std::string_view password);
|
||||
void fill_block_header_response(const block& blk, bool orphan_status, uint64_t height, const crypto::hash& hash, block_header_response& response, bool fill_pow_hash, bool get_tx_hashes);
|
||||
|
|
|
@ -393,4 +393,8 @@ namespace cryptonote::rpc {
|
|||
if (bh.request.heights.size() > bh.MAX_HEIGHTS)
|
||||
throw std::domain_error{"Error: too many block heights requested at once"};
|
||||
}
|
||||
|
||||
void parse_request(GET_PEER_LIST& pl, rpc_input in) {
|
||||
get_values(in, "public_only", pl.request.public_only);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -21,4 +21,5 @@ namespace cryptonote::rpc {
|
|||
void parse_request(IS_KEY_IMAGE_SPENT& spent, rpc_input in);
|
||||
void parse_request(SUBMIT_TRANSACTION& tx, rpc_input in);
|
||||
void parse_request(GET_BLOCK_HASH& bh, rpc_input in);
|
||||
void parse_request(GET_PEER_LIST& bh, rpc_input in);
|
||||
}
|
||||
|
|
|
@ -106,44 +106,6 @@ KV_SERIALIZE_MAP_CODE_BEGIN(GET_BLOCK::response)
|
|||
KV_SERIALIZE_MAP_CODE_END()
|
||||
|
||||
|
||||
KV_SERIALIZE_MAP_CODE_BEGIN(GET_PEER_LIST::peer)
|
||||
KV_SERIALIZE(id)
|
||||
KV_SERIALIZE(host)
|
||||
KV_SERIALIZE(ip)
|
||||
KV_SERIALIZE(port)
|
||||
KV_SERIALIZE_OPT(rpc_port, (uint16_t)0)
|
||||
KV_SERIALIZE(last_seen)
|
||||
KV_SERIALIZE_OPT(pruning_seed, (uint32_t)0)
|
||||
KV_SERIALIZE_MAP_CODE_END()
|
||||
|
||||
KV_SERIALIZE_MAP_CODE_BEGIN(GET_PEER_LIST::request)
|
||||
KV_SERIALIZE_OPT(public_only, true)
|
||||
KV_SERIALIZE_MAP_CODE_END()
|
||||
|
||||
KV_SERIALIZE_MAP_CODE_BEGIN(GET_PEER_LIST::response)
|
||||
KV_SERIALIZE(status)
|
||||
KV_SERIALIZE(white_list)
|
||||
KV_SERIALIZE(gray_list)
|
||||
KV_SERIALIZE_MAP_CODE_END()
|
||||
|
||||
KV_SERIALIZE_MAP_CODE_BEGIN(public_node)
|
||||
KV_SERIALIZE(host)
|
||||
KV_SERIALIZE(last_seen)
|
||||
KV_SERIALIZE(rpc_port)
|
||||
KV_SERIALIZE_MAP_CODE_END()
|
||||
|
||||
KV_SERIALIZE_MAP_CODE_BEGIN(GET_PUBLIC_NODES::request)
|
||||
KV_SERIALIZE_OPT(gray, false)
|
||||
KV_SERIALIZE_OPT(white, true)
|
||||
KV_SERIALIZE_MAP_CODE_END()
|
||||
|
||||
KV_SERIALIZE_MAP_CODE_BEGIN(GET_PUBLIC_NODES::response)
|
||||
KV_SERIALIZE(status)
|
||||
KV_SERIALIZE(gray)
|
||||
KV_SERIALIZE(white)
|
||||
KV_SERIALIZE_MAP_CODE_END()
|
||||
|
||||
|
||||
KV_SERIALIZE_MAP_CODE_BEGIN(SET_LOG_LEVEL::request)
|
||||
KV_SERIALIZE(level)
|
||||
KV_SERIALIZE_MAP_CODE_END()
|
||||
|
|
|
@ -871,88 +871,34 @@ namespace cryptonote::rpc {
|
|||
};
|
||||
};
|
||||
|
||||
OXEN_RPC_DOC_INTROSPECT
|
||||
// Get the known peers list.
|
||||
/// Get the list of current network peers known to this node.
|
||||
///
|
||||
/// Inputs: none
|
||||
///
|
||||
/// Output values (requires a restricted/admin RPC endpoint):
|
||||
///
|
||||
/// - \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
|
||||
/// 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
|
||||
/// 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
|
||||
/// never connected (e.g. for a peer we received from another node but haven't yet tried).
|
||||
struct GET_PEER_LIST : LEGACY
|
||||
{
|
||||
static constexpr auto names() { return NAMES("get_peer_list"); }
|
||||
|
||||
struct request
|
||||
struct request_parameters
|
||||
{
|
||||
bool public_only;
|
||||
KV_MAP_SERIALIZABLE
|
||||
};
|
||||
bool public_only = false; // Hidden option: can be set to false to also include non-public-zone peers (Tor, I2P), but since Oxen currently only really exists in public zones, we don't put this in the RPC docs.
|
||||
} request;
|
||||
|
||||
struct peer
|
||||
{
|
||||
uint64_t id; // Peer id.
|
||||
std::string host; // IP address in string format.
|
||||
uint32_t ip; // IP address in integer format.
|
||||
uint16_t port; // TCP port the peer is using to connect to oxen network.
|
||||
uint16_t rpc_port; // RPC port the peer is using
|
||||
uint64_t last_seen; // Unix time at which the peer has been seen for the last time
|
||||
uint32_t pruning_seed; //
|
||||
|
||||
peer() = default;
|
||||
|
||||
peer(uint64_t id, const std::string &host, uint64_t last_seen, uint32_t pruning_seed, uint16_t rpc_port)
|
||||
: id(id), host(host), ip(0), port(0), rpc_port(rpc_port), last_seen(last_seen), pruning_seed(pruning_seed)
|
||||
{}
|
||||
peer(uint64_t id, const std::string &host, uint16_t port, uint64_t last_seen, uint32_t pruning_seed, uint16_t rpc_port)
|
||||
: id(id), host(host), ip(0), port(port), rpc_port(rpc_port), last_seen(last_seen), pruning_seed(pruning_seed)
|
||||
{}
|
||||
peer(uint64_t id, uint32_t ip, uint16_t port, uint64_t last_seen, uint32_t pruning_seed, uint16_t rpc_port)
|
||||
: id(id), host(epee::string_tools::get_ip_string_from_int32(ip)), ip(ip), port(port), rpc_port(rpc_port), last_seen(last_seen), pruning_seed(pruning_seed)
|
||||
{}
|
||||
|
||||
KV_MAP_SERIALIZABLE
|
||||
};
|
||||
|
||||
struct response
|
||||
{
|
||||
std::string status; // General RPC error code. "OK" means everything looks good. Any other value means that something went wrong.
|
||||
std::vector<peer> white_list; // Array of online peer structure.
|
||||
std::vector<peer> gray_list; // Array of offline peer structure.
|
||||
|
||||
KV_MAP_SERIALIZABLE
|
||||
};
|
||||
};
|
||||
|
||||
OXEN_RPC_DOC_INTROSPECT
|
||||
struct public_node
|
||||
{
|
||||
std::string host;
|
||||
uint64_t last_seen;
|
||||
uint16_t rpc_port;
|
||||
|
||||
public_node() = default;
|
||||
public_node(const GET_PEER_LIST::peer &peer) : host(peer.host), last_seen(peer.last_seen), rpc_port(peer.rpc_port) {}
|
||||
|
||||
KV_MAP_SERIALIZABLE
|
||||
};
|
||||
|
||||
OXEN_RPC_DOC_INTROSPECT
|
||||
// Query the daemon's peerlist and retrieve peers who have set their public rpc port.
|
||||
struct GET_PUBLIC_NODES : PUBLIC
|
||||
{
|
||||
static constexpr auto names() { return NAMES("get_public_nodes"); }
|
||||
|
||||
struct request
|
||||
{
|
||||
bool gray; // Get peers that have recently gone offline.
|
||||
bool white; // Get peers that are online
|
||||
|
||||
KV_MAP_SERIALIZABLE
|
||||
};
|
||||
|
||||
struct response
|
||||
{
|
||||
std::string status; // General RPC error code. "OK" means everything looks good. Any other value means that something went wrong.
|
||||
std::vector<public_node> gray; // Graylist peers
|
||||
std::vector<public_node> white; // Whitelist peers
|
||||
|
||||
KV_MAP_SERIALIZABLE
|
||||
};
|
||||
};
|
||||
|
||||
OXEN_RPC_DOC_INTROSPECT
|
||||
|
@ -2432,7 +2378,8 @@ namespace cryptonote::rpc {
|
|||
GET_SERVICE_NODES,
|
||||
GET_SERVICE_NODE_STATUS,
|
||||
SUBMIT_TRANSACTION,
|
||||
GET_BLOCK_HASH
|
||||
GET_BLOCK_HASH,
|
||||
GET_PEER_LIST
|
||||
>;
|
||||
|
||||
using FIXME_old_rpc_types = tools::type_list<
|
||||
|
@ -2441,8 +2388,6 @@ namespace cryptonote::rpc {
|
|||
GET_BLOCK_HEADER_BY_HASH,
|
||||
GET_BLOCK_HEADER_BY_HEIGHT,
|
||||
GET_BLOCK,
|
||||
GET_PEER_LIST,
|
||||
GET_PUBLIC_NODES,
|
||||
SET_LOG_LEVEL,
|
||||
SET_LOG_CATEGORIES,
|
||||
GET_BLOCK_HEADERS_RANGE,
|
||||
|
|
Loading…
Reference in a new issue