oxen-core/src/daemon/command_server.h
Jason Rhinelander 4a8023ade6 Make RPC more flexible & add bt-encoding
The bt-encoding, in particular, is aimed at more efficient wallet3 rpc
interactions with a daemon.

This removes the rigidity from RPC request responses, making it easier
to return useful constructs that the current epee code doesn't support
(like lists of lists), and also adds support for bt-encoded RPC requests
(intended to eventually replace the ".bin" endpoints with Monero NIH
binary encoding).

Instead endpoints now set a nlohmann::json response object with whatever
arbitrary values they want without having to add a bunch of limited epee
serialization macro hell.

So, for example, to set the value "foo" to 20, you use:

    rpc.response["height"] = 20;

Binary values (for things like hashes) are handled by going through a proxy object:

    rpc.response_hex["hash"] = hash; // hash is a crypto::hash

which, for json, is equivalent to:

    rpc.response["hash"] = tools::type_to_hex(hash);

but when the response is to be bt-encoded it leaves it as binary for
more efficient transfers.

There is also a `response_b64` that converts json-destined values to
base64 instead of hex (and again leaves bt-destined values as binary).

Parsing of incoming requests now moves to a new
core_rpc_server_command_parser file, which does free-form parsing from a
nlohmann::json or bt_dict_consumer, and has various templated helper
functions to make this easier.

This is preliminary: this builds the basic infrastucture for handling
requests, and converts three endpoints:

- get_info
- get_height
- ons_resolve

Currently only `make daemon` builds (there is code in the wallet that
hasn't been updated yet), and the other RPC interfaces are disabled by
this commit (until they get converted to the new style).
2021-11-01 14:53:05 -04:00

71 lines
2.6 KiB
C++

// Copyright (c) 2018-2020, The Loki Project
// Copyright (c) 2014-2019, The Monero Project
//
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without modification, are
// permitted provided that the following conditions are met:
//
// 1. Redistributions of source code must retain the above copyright notice, this list of
// conditions and the following disclaimer.
//
// 2. Redistributions in binary form must reproduce the above copyright notice, this list
// of conditions and the following disclaimer in the documentation and/or other
// materials provided with the distribution.
//
// 3. Neither the name of the copyright holder nor the names of its contributors may be
// used to endorse or promote products derived from this software without specific
// prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY
// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
// THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
// STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
// THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#pragma once
#include <optional>
#include "common/common_fwd.h"
#include "epee/console_handler.h"
#include "daemon/command_parser_executor.h"
namespace daemonize {
class command_server {
private:
command_parser_executor m_parser;
epee::console_handlers_binder m_command_lookup;
std::optional<oxenmq::OxenMQ> m_omq;
public:
/// command_server constructor; forwards to command_parser_executor
template <typename... T>
command_server(T&&... args)
: m_parser{std::forward<T>(args)...}
{
init_commands();
}
template <typename... T>
bool process_command_and_log(T&&... args) { return m_command_lookup.process_command_and_log(std::forward<T>(args)...); }
bool start_handling(std::function<void()> exit_handler = {});
void stop_handling();
private:
void init_commands(cryptonote::rpc::core_rpc_server* rpc_server = nullptr);
bool help(const std::vector<std::string>& args);
std::string get_commands_str();
std::string get_command_usage(const std::vector<std::string> &args);
};
} // namespace daemonize