Rename LMQ -> OMQ in code

(This doesn't rename the `--lmq-...` cli options because that would
break backwards compatibility.)
This commit is contained in:
Jason Rhinelander 2022-12-19 13:11:08 -04:00
parent d3d0a4460d
commit 402aa450c9
No known key found for this signature in database
GPG key ID: C4992CE7A88D4262
12 changed files with 52 additions and 54 deletions

View file

@ -952,7 +952,7 @@ namespace cryptonote
log::info(logcat, fg(fmt::terminal_color::yellow), "- x25519: {}", tools::type_to_hex(keys.pub_x25519));
} else {
// Only print the x25519 version because it's the only thing useful for a non-SN (for
// encrypted LMQ RPC connections).
// encrypted OMQ RPC connections).
log::info(logcat, fg(fmt::terminal_color::yellow), "x25519 public key: {}", tools::type_to_hex(keys.pub_x25519));
}
@ -2286,7 +2286,7 @@ namespace cryptonote
if (pk != m_service_keys.pub && proof.proof->public_ip == m_sn_public_ip &&
(proof.proof->qnet_port == m_quorumnet_port || (
m_nettype != network_type::DEVNET && (proof.proof->storage_https_port == storage_https_port() || proof.proof->storage_omq_port == storage_omq_port()))))
log::info(logcat, fg(fmt::terminal_color::red), "Another service node ({}) is broadcasting the same public IP and ports as this service node ({}:{}[qnet], :{}[SS-HTTP], :{}[SS-LMQ]). This will lead to deregistration of one or both service nodes if not corrected. (Do both service nodes have the correct IP for the service-node-public-ip setting?)", pk, epee::string_tools::get_ip_string_from_int32(m_sn_public_ip), proof.proof->qnet_port, proof.proof->storage_https_port, proof.proof->storage_omq_port);
log::info(logcat, fg(fmt::terminal_color::red), "Another service node ({}) is broadcasting the same public IP and ports as this service node ({}:{}[qnet], :{}[SS-HTTP], :{}[SS-OMQ]). This will lead to deregistration of one or both service nodes if not corrected. (Do both service nodes have the correct IP for the service-node-public-ip setting?)", pk, epee::string_tools::get_ip_string_from_int32(m_sn_public_ip), proof.proof->qnet_port, proof.proof->storage_https_port, proof.proof->storage_omq_port);
});
}

View file

@ -1188,8 +1188,8 @@ namespace cryptonote
// avoid linking issues (protocol does not link against core).
void* m_quorumnet_state = nullptr;
/// Stores x25519 -> access level for LMQ authentication.
/// Not to be modified after the LMQ listener starts.
/// Stores x25519 -> access level for OMQ authentication.
/// Not to be modified after the OMQ listener starts.
std::unordered_map<crypto::x25519_public_key, oxenmq::AuthLevel> m_omq_auth;
size_t block_sync_size;

View file

@ -741,13 +741,13 @@ namespace {
/*
Pulse progresses via a state-machine that is iterated through job submissions
to 1 dedicated Pulse thread, started by LMQ.
to 1 dedicated Pulse thread, started by OMQ.
Iterating the state-machine is done by a periodic invocation of
pulse::main(...) and messages received via Quorumnet for Pulse, which are
queued in the thread's job queue.
Using 1 dedicated thread via LMQ avoids any synchronization required in the
Using 1 dedicated thread via OMQ avoids any synchronization required in the
user code when implementing Pulse.
Skip control flow graph for textual description of stages.

View file

@ -44,7 +44,7 @@
#endif
#include "rpc/common/rpc_args.h"
#include "rpc/http_server.h"
#include "rpc/lmq_server.h"
#include "rpc/omq_server.h"
#include "cryptonote_protocol/quorumnet.h"
#include "cryptonote_core/uptime_proof.h"

View file

@ -34,7 +34,7 @@
#include "p2p/net_node.h"
#include "rpc/core_rpc_server.h"
#include "rpc/http_server.h"
#include "rpc/lmq_server.h"
#include "rpc/omq_server.h"
#include "blocks/blocks.h"
#include "rpc/core_rpc_server.h"

View file

@ -41,7 +41,7 @@ add_library(rpc
add_library(daemon_rpc_server
http_server.cpp
lmq_server.cpp
omq_server.cpp
)
add_library(rpc_http_client

View file

@ -17,7 +17,7 @@ namespace cryptonote::rpc {
/// Base class that all RPC commands must inherit from (either directly or via one or more of the
/// below tags). Inheriting from this (and no others) gives you a private, json, non-legacy RPC
/// command. For LMQ RPC the command will be available at `admin.whatever`; for HTTP RPC it'll be
/// command. For OMQ RPC the command will be available at `admin.whatever`; for HTTP RPC it'll be
/// at `whatever`. This base class is also where response objects are stored.
struct RPC_COMMAND {
private:
@ -72,7 +72,7 @@ namespace cryptonote::rpc {
/// Tag types that are used (via inheritance) to set rpc endpoint properties
/// Specifies that the RPC call is public (i.e. available through restricted rpc). If this is
/// *not* inherited from then the command is restricted (i.e. only available to admins). For LMQ,
/// *not* inherited from then the command is restricted (i.e. only available to admins). For OMQ,
/// PUBLIC commands are available at `rpc.command` (versus non-PUBLIC ones at `admin.command`).
struct PUBLIC : virtual RPC_COMMAND {};

View file

@ -241,8 +241,8 @@ namespace cryptonote::rpc {
struct request
{
bool blinked_txs_only; // Optional: If true only transactions that were sent via blink and approved are queried.
bool long_poll; // Optional: If true, this call is blocking until timeout OR tx pool has changed since the last query. TX pool change is detected by comparing the hash of all the hashes in the tx pool. Ignored when using LMQ RPC.
crypto::hash tx_pool_checksum; // Optional: If `long_poll` is true the caller must pass the hashes of all their known tx pool hashes, XOR'ed together. Ignored when using LMQ RPC.
bool long_poll; // Optional: If true, this call is blocking until timeout OR tx pool has changed since the last query. TX pool change is detected by comparing the hash of all the hashes in the tx pool. Ignored when using OMQ RPC.
crypto::hash tx_pool_checksum; // Optional: If `long_poll` is true the caller must pass the hashes of all their known tx pool hashes, XOR'ed together. Ignored when using OMQ RPC.
KV_MAP_SERIALIZABLE
};

View file

@ -87,7 +87,7 @@ namespace cryptonote::rpc {
: m_server{server}, m_restricted{restricted}
{
// uWS is designed to work from a single thread, which is good (we pull off the requests and
// then stick them into the LMQ job queue to be scheduled along with other jobs). But as a
// then stick them into the OMQ job queue to be scheduled along with other jobs). But as a
// consequence, we need to create everything inside that thread. We *also* need to get the
// (thread local) event loop pointer back from the thread so that we can shut it down later
// (injecting a callback into it is one of the few thread-safe things we can do across threads).
@ -268,7 +268,7 @@ namespace cryptonote::rpc {
void invoke_txpool_hashes_bin(std::shared_ptr<call_data> data);
// Invokes the actual RPC request; this is called (via oxenmq) from some random LMQ worker thread,
// Invokes the actual RPC request; this is called (via oxenmq) from some random OMQ worker thread,
// which means we can't just write our reply; instead we have to post it to the uWS loop.
void invoke_rpc(std::shared_ptr<call_data> dataptr)
{
@ -472,7 +472,7 @@ namespace cryptonote::rpc {
auto& omq = data->core_rpc.get_core().get_omq();
std::string cat{data->call->is_public ? "rpc" : "admin"};
std::string cmd{"http:" + data->uri}; // Used for LMQ job logging; prefixed with http: so we can distinguish it
std::string cmd{"http:" + data->uri}; // Used for OMQ job logging; prefixed with http: so we can distinguish it
std::string remote{data->request.context.remote};
omq.inject_task(std::move(cat), std::move(cmd), std::move(remote), [data=std::move(data)] { invoke_rpc(std::move(data)); });
});
@ -538,7 +538,7 @@ namespace cryptonote::rpc {
auto& omq = data->core_rpc.get_core().get_omq();
std::string cat{data->call->is_public ? "rpc" : "admin"};
std::string cmd{"jsonrpc:" + *method}; // Used for LMQ job logging; prefixed with jsonrpc: so we can distinguish it
std::string cmd{"jsonrpc:" + *method}; // Used for OMQ job logging; prefixed with jsonrpc: so we can distinguish it
std::string remote{data->request.context.remote};
omq.inject_task(std::move(cat), std::move(cmd), std::move(remote), [data=std::move(data)] { invoke_rpc(std::move(data)); });
});

View file

@ -1,5 +1,5 @@
#include "lmq_server.h"
#include "omq_server.h"
#include "rpc/common/param_parser.hpp"
#include "cryptonote_config.h"
#include <oxenc/bt.h>
@ -7,8 +7,6 @@
#include <oxenmq/fmt.h>
#include <fmt/core.h>
// FIXME: Rename this to omq_server.{h,cpp}
namespace cryptonote { namespace rpc {
using oxenmq::AuthLevel;
@ -53,7 +51,7 @@ const command_line::arg_descriptor<std::vector<std::string>> arg_omq_local_contr
#ifndef _WIN32
const command_line::arg_descriptor<std::string> arg_omq_umask{
"lmq-umask",
"Sets the umask to apply to any listening ipc:///path/to/sock LMQ sockets, in octal.",
"Sets the umask to apply to any listening ipc:///path/to/sock OMQ sockets, in octal.",
"0007"};
#endif
@ -71,20 +69,20 @@ auto as_x_pubkeys(const std::vector<std::string>& pk_strings) {
pks.reserve(pk_strings.size());
for (const auto& pkstr : pk_strings) {
if (pkstr.size() != 64 || !oxenc::is_hex(pkstr))
throw std::runtime_error("Invalid LMQ login pubkey: '" + pkstr + "'; expected 64-char hex pubkey");
throw std::runtime_error("Invalid OMQ login pubkey: '" + pkstr + "'; expected 64-char hex pubkey");
pks.emplace_back();
oxenc::to_hex(pkstr.begin(), pkstr.end(), reinterpret_cast<char *>(&pks.back()));
}
return pks;
}
// LMQ RPC responses consist of [CODE, DATA] for code we (partially) mimic HTTP error codes: 200
// OMQ RPC responses consist of [CODE, DATA] for code we (partially) mimic HTTP error codes: 200
// means success, anything else means failure. (We don't have codes for Forbidden or Not Found
// because those happen at the LMQ protocol layer).
// because those happen at the OMQ protocol layer).
constexpr std::string_view
LMQ_OK{"200"sv},
LMQ_BAD_REQUEST{"400"sv},
LMQ_ERROR{"500"sv};
OMQ_OK{"200"sv},
OMQ_BAD_REQUEST{"400"sv},
OMQ_ERROR{"500"sv};
} // end anonymous namespace
@ -112,21 +110,21 @@ omq_rpc::omq_rpc(cryptonote::core& core, core_rpc_server& rpc, const boost::prog
// the quorumnet listener set up in cryptonote_core).
for (const auto &addr : command_line::get_arg(vm, arg_omq_public)) {
check_omq_listen_addr(addr);
log::info(logcat, "LMQ listening on {} (public unencrypted)", addr);
log::info(logcat, "OMQ listening on {} (public unencrypted)", addr);
omq.listen_plain(addr,
[&core](std::string_view ip, std::string_view pk, bool /*sn*/) { return core.omq_allow(ip, pk, AuthLevel::basic); });
}
for (const auto &addr : command_line::get_arg(vm, arg_omq_curve_public)) {
check_omq_listen_addr(addr);
log::info(logcat, "LMQ listening on {} (public curve)", addr);
log::info(logcat, "OMQ listening on {} (public curve)", addr);
omq.listen_curve(addr,
[&core](std::string_view ip, std::string_view pk, bool /*sn*/) { return core.omq_allow(ip, pk, AuthLevel::basic); });
}
for (const auto &addr : command_line::get_arg(vm, arg_omq_curve)) {
check_omq_listen_addr(addr);
log::info(logcat, "LMQ listening on {} (curve restricted)", addr);
log::info(logcat, "OMQ listening on {} (curve restricted)", addr);
omq.listen_curve(addr,
[&core](std::string_view ip, std::string_view pk, bool /*sn*/) { return core.omq_allow(ip, pk, AuthLevel::denied); });
}
@ -196,7 +194,7 @@ omq_rpc::omq_rpc(cryptonote::core& core, core_rpc_server& rpc, const boost::prog
omq.add_request_command(cmd.second->is_public ? "rpc" : "admin", cmd.first,
[name=std::string_view{cmd.first}, &call=*cmd.second, this](oxenmq::Message& m) {
if (m.data.size() > 1)
m.send_reply(LMQ_BAD_REQUEST, "Bad request: RPC commands must have at most one data part "
m.send_reply(OMQ_BAD_REQUEST, "Bad request: RPC commands must have at most one data part "
"(received " + std::to_string(m.data.size()) + ")");
rpc_request request{};
@ -218,7 +216,7 @@ omq_rpc::omq_rpc(cryptonote::core& core, core_rpc_server& rpc, const boost::prog
return std::move(v);
}
}, call.invoke(std::move(request), rpc_));
m.send_reply(LMQ_OK, std::move(result));
m.send_reply(OMQ_OK, std::move(result));
return;
} catch (const parse_error& e) {
// This isn't really WARNable as it's the client fault; log at info level instead.
@ -227,22 +225,22 @@ omq_rpc::omq_rpc(cryptonote::core& core, core_rpc_server& rpc, const boost::prog
// warnings that get generated deep inside epee, for example when passing a string or
// number instead of a JSON object. If you want to find some, `grep number2 epee` (for
// real).
log::info(logcat, "LMQ RPC request '{}{}' called with invalid/unparseable data: {}", (call.is_public ? "rpc." : "admin."), name, e.what());
m.send_reply(LMQ_BAD_REQUEST, "Unable to parse request: "s + e.what());
log::info(logcat, "OMQ RPC request '{}{}' called with invalid/unparseable data: {}", (call.is_public ? "rpc." : "admin."), name, e.what());
m.send_reply(OMQ_BAD_REQUEST, "Unable to parse request: "s + e.what());
return;
} catch (const rpc_error& e) {
log::warning(logcat, "LMQ RPC request '{}{}' failed with: {}", (call.is_public ? "rpc." : "admin."), name, e.what());
m.send_reply(LMQ_ERROR, e.what());
log::warning(logcat, "OMQ RPC request '{}{}' failed with: {}", (call.is_public ? "rpc." : "admin."), name, e.what());
m.send_reply(OMQ_ERROR, e.what());
return;
} catch (const std::exception& e) {
log::warning(logcat, "LMQ RPC request '{}{}' raised an exception: {}", (call.is_public ? "rpc." : "admin."), name, e.what());
log::warning(logcat, "OMQ RPC request '{}{}' raised an exception: {}", (call.is_public ? "rpc." : "admin."), name, e.what());
} catch (...) {
log::warning(logcat, "LMQ RPC request '{}{}' raised an unknown exception", (call.is_public ? "rpc." : "admin."), name);
log::warning(logcat, "OMQ RPC request '{}{}' raised an unknown exception", (call.is_public ? "rpc." : "admin."), name);
}
// Don't include the exception message in case it contains something that we don't want go
// back to the user. If we want to support it eventually we could add some sort of
// `rpc::user_visible_exception` that carries a message to send back to the user.
m.send_reply(LMQ_ERROR, "An exception occured while processing your request");
m.send_reply(OMQ_ERROR, "An exception occured while processing your request");
});
}

View file

@ -40,7 +40,7 @@ namespace cryptonote::rpc {
void init_omq_options(boost::program_options::options_description& desc);
/**
* LMQ RPC server class. This doesn't actually hold the OxenMQ instance--that's in
* OMQ RPC server class. This doesn't actually hold the OxenMQ instance--that's in
* cryptonote_core--but it works with it to add RPC endpoints, make it listen on RPC ports, and
* handles RPC requests.
*/

View file

@ -13,13 +13,13 @@
namespace {
// LMQ RPC responses consist of [CODE, DATA] for code we (partially) mimic HTTP error codes: 200
// OMQ RPC responses consist of [CODE, DATA] for code we (partially) mimic HTTP error codes: 200
// means success, anything else means failure. (We don't have codes for Forbidden or Not Found
// because those happen at the LMQ protocol layer).
// because those happen at the OMQ protocol layer).
constexpr std::string_view
LMQ_OK{"200"sv},
LMQ_BAD_REQUEST{"400"sv},
LMQ_ERROR{"500"sv};
OMQ_OK{"200"sv},
OMQ_BAD_REQUEST{"400"sv},
OMQ_ERROR{"500"sv};
} // anonymous namespace
@ -46,7 +46,7 @@ OmqServer::set_omq(std::shared_ptr<oxenmq::OxenMQ> omq_in, wallet::rpc::Config c
omq->add_request_command(cmd.second->is_restricted ? "restricted" : "rpc", cmd.first,
[name=std::string_view{cmd.first}, &call=*cmd.second, this](oxenmq::Message& m) {
if (m.data.size() > 1)
m.send_reply(LMQ_BAD_REQUEST, "Bad request: RPC commands must have at most one data part "
m.send_reply(OMQ_BAD_REQUEST, "Bad request: RPC commands must have at most one data part "
"(received " + std::to_string(m.data.size()) + ")");
rpc_request request{};
@ -68,7 +68,7 @@ OmqServer::set_omq(std::shared_ptr<oxenmq::OxenMQ> omq_in, wallet::rpc::Config c
return std::move(v);
}
}, call.invoke(std::move(request), request_handler));
m.send_reply(LMQ_OK, std::move(result));
m.send_reply(OMQ_OK, std::move(result));
return;
} catch (const parse_error& e) {
// This isn't really WARNable as it's the client fault; log at info level instead.
@ -77,24 +77,24 @@ OmqServer::set_omq(std::shared_ptr<oxenmq::OxenMQ> omq_in, wallet::rpc::Config c
// warnings that get generated deep inside epee, for example when passing a string or
// number instead of a JSON object. If you want to find some, `grep number2 epee` (for
// real).
std::cout << "LMQ RPC request '" << (call.is_restricted ? "restricted." : "rpc.") << name << "' called with invalid/unparseable data: " << e.what() << "\n";
m.send_reply(LMQ_BAD_REQUEST, "Unable to parse request: "s + e.what());
std::cout << "OMQ RPC request '" << (call.is_restricted ? "restricted." : "rpc.") << name << "' called with invalid/unparseable data: " << e.what() << "\n";
m.send_reply(OMQ_BAD_REQUEST, "Unable to parse request: "s + e.what());
return;
} catch (const rpc_error& e) {
std::cout << "LMQ RPC request '" << (call.is_restricted ? "restricted." : "rpc.") << name << "' failed with: " << e.what() << "\n";
m.send_reply(LMQ_ERROR, e.what());
std::cout << "OMQ RPC request '" << (call.is_restricted ? "restricted." : "rpc.") << name << "' failed with: " << e.what() << "\n";
m.send_reply(OMQ_ERROR, e.what());
return;
} catch (const std::exception& e) {
std::cout << "LMQ RPC request '" << (call.is_restricted ? "restricted." : "rpc.") << name << "' "
std::cout << "OMQ RPC request '" << (call.is_restricted ? "restricted." : "rpc.") << name << "' "
"raised an exception: " << e.what() << "\n";
} catch (...) {
std::cout << "LMQ RPC request '" << (call.is_restricted ? "restricted." : "rpc.") << name << "' "
std::cout << "OMQ RPC request '" << (call.is_restricted ? "restricted." : "rpc.") << name << "' "
"raised an unknown exception" << "\n";
}
// Don't include the exception message in case it contains something that we don't want go
// back to the user. If we want to support it eventually we could add some sort of
// `rpc::user_visible_exception` that carries a message to send back to the user.
m.send_reply(LMQ_ERROR, "An exception occured while processing your request");
m.send_reply(OMQ_ERROR, "An exception occured while processing your request");
});
}
}