mirror of
https://github.com/monero-project/monero.git
synced 2024-12-23 12:09:54 +00:00
add daemonizer to rpc wallet
This commit is contained in:
parent
d743994086
commit
c336d0f217
2 changed files with 166 additions and 111 deletions
|
@ -90,6 +90,8 @@ target_link_libraries(wallet_rpc_server
|
||||||
cncrypto
|
cncrypto
|
||||||
common
|
common
|
||||||
version
|
version
|
||||||
|
daemonizer
|
||||||
|
${EPEE_READLINE}
|
||||||
${Boost_CHRONO_LIBRARY}
|
${Boost_CHRONO_LIBRARY}
|
||||||
${Boost_PROGRAM_OPTIONS_LIBRARY}
|
${Boost_PROGRAM_OPTIONS_LIBRARY}
|
||||||
${Boost_FILESYSTEM_LIBRARY}
|
${Boost_FILESYSTEM_LIBRARY}
|
||||||
|
|
|
@ -51,6 +51,7 @@ using namespace epee;
|
||||||
#include "mnemonics/electrum-words.h"
|
#include "mnemonics/electrum-words.h"
|
||||||
#include "rpc/rpc_args.h"
|
#include "rpc/rpc_args.h"
|
||||||
#include "rpc/core_rpc_server_commands_defs.h"
|
#include "rpc/core_rpc_server_commands_defs.h"
|
||||||
|
#include "daemonizer/daemonizer.h"
|
||||||
|
|
||||||
#undef MONERO_DEFAULT_LOG_CATEGORY
|
#undef MONERO_DEFAULT_LOG_CATEGORY
|
||||||
#define MONERO_DEFAULT_LOG_CATEGORY "wallet.rpc"
|
#define MONERO_DEFAULT_LOG_CATEGORY "wallet.rpc"
|
||||||
|
@ -3265,12 +3266,172 @@ namespace tools
|
||||||
//------------------------------------------------------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------------------------------------------------------
|
||||||
}
|
}
|
||||||
|
|
||||||
|
class t_daemon
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
const boost::program_options::variables_map& vm;
|
||||||
|
|
||||||
|
public:
|
||||||
|
t_daemon(boost::program_options::variables_map const & _vm)
|
||||||
|
: vm(_vm)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
bool run()
|
||||||
|
{
|
||||||
|
std::unique_ptr<tools::wallet2> wal;
|
||||||
|
try
|
||||||
|
{
|
||||||
|
const bool testnet = tools::wallet2::has_testnet_option(vm);
|
||||||
|
const bool stagenet = tools::wallet2::has_stagenet_option(vm);
|
||||||
|
if (testnet && stagenet)
|
||||||
|
{
|
||||||
|
MERROR(tools::wallet_rpc_server::tr("Can't specify more than one of --testnet and --stagenet"));
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
const auto arg_wallet_file = wallet_args::arg_wallet_file();
|
||||||
|
const auto arg_from_json = wallet_args::arg_generate_from_json();
|
||||||
|
|
||||||
|
const auto wallet_file = command_line::get_arg(vm, arg_wallet_file);
|
||||||
|
const auto from_json = command_line::get_arg(vm, arg_from_json);
|
||||||
|
const auto wallet_dir = command_line::get_arg(vm, arg_wallet_dir);
|
||||||
|
const auto prompt_for_password = command_line::get_arg(vm, arg_prompt_for_password);
|
||||||
|
const auto password_prompt = prompt_for_password ? password_prompter : nullptr;
|
||||||
|
|
||||||
|
if(!wallet_file.empty() && !from_json.empty())
|
||||||
|
{
|
||||||
|
LOG_ERROR(tools::wallet_rpc_server::tr("Can't specify more than one of --wallet-file and --generate-from-json"));
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!wallet_dir.empty())
|
||||||
|
{
|
||||||
|
wal = NULL;
|
||||||
|
goto just_dir;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (wallet_file.empty() && from_json.empty())
|
||||||
|
{
|
||||||
|
LOG_ERROR(tools::wallet_rpc_server::tr("Must specify --wallet-file or --generate-from-json or --wallet-dir"));
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
LOG_PRINT_L0(tools::wallet_rpc_server::tr("Loading wallet..."));
|
||||||
|
if(!wallet_file.empty())
|
||||||
|
{
|
||||||
|
wal = tools::wallet2::make_from_file(vm, true, wallet_file, password_prompt).first;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
wal = tools::wallet2::make_from_json(vm, true, from_json, password_prompt);
|
||||||
|
}
|
||||||
|
catch (const std::exception &e)
|
||||||
|
{
|
||||||
|
MERROR("Error creating wallet: " << e.what());
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!wal)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool quit = false;
|
||||||
|
tools::signal_handler::install([&wal, &quit](int) {
|
||||||
|
assert(wal);
|
||||||
|
quit = true;
|
||||||
|
wal->stop();
|
||||||
|
});
|
||||||
|
|
||||||
|
wal->refresh(wal->is_trusted_daemon());
|
||||||
|
// if we ^C during potentially length load/refresh, there's no server loop yet
|
||||||
|
if (quit)
|
||||||
|
{
|
||||||
|
MINFO(tools::wallet_rpc_server::tr("Saving wallet..."));
|
||||||
|
wal->store();
|
||||||
|
MINFO(tools::wallet_rpc_server::tr("Successfully saved"));
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
MINFO(tools::wallet_rpc_server::tr("Successfully loaded"));
|
||||||
|
}
|
||||||
|
catch (const std::exception& e)
|
||||||
|
{
|
||||||
|
LOG_ERROR(tools::wallet_rpc_server::tr("Wallet initialization failed: ") << e.what());
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
just_dir:
|
||||||
|
tools::wallet_rpc_server wrpc;
|
||||||
|
if (wal) wrpc.set_wallet(wal.release());
|
||||||
|
bool r = wrpc.init(&vm);
|
||||||
|
CHECK_AND_ASSERT_MES(r, false, tools::wallet_rpc_server::tr("Failed to initialize wallet RPC server"));
|
||||||
|
tools::signal_handler::install([&wrpc](int) {
|
||||||
|
wrpc.send_stop_signal();
|
||||||
|
});
|
||||||
|
LOG_PRINT_L0(tools::wallet_rpc_server::tr("Starting wallet RPC server"));
|
||||||
|
try
|
||||||
|
{
|
||||||
|
wrpc.run();
|
||||||
|
}
|
||||||
|
catch (const std::exception &e)
|
||||||
|
{
|
||||||
|
LOG_ERROR(tools::wallet_rpc_server::tr("Failed to run wallet: ") << e.what());
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
LOG_PRINT_L0(tools::wallet_rpc_server::tr("Stopped wallet RPC server"));
|
||||||
|
try
|
||||||
|
{
|
||||||
|
LOG_PRINT_L0(tools::wallet_rpc_server::tr("Saving wallet..."));
|
||||||
|
wrpc.stop();
|
||||||
|
LOG_PRINT_L0(tools::wallet_rpc_server::tr("Successfully saved"));
|
||||||
|
}
|
||||||
|
catch (const std::exception& e)
|
||||||
|
{
|
||||||
|
LOG_ERROR(tools::wallet_rpc_server::tr("Failed to save wallet: ") << e.what());
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
class t_executor final
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
static std::string const NAME;
|
||||||
|
|
||||||
|
std::string const & name()
|
||||||
|
{
|
||||||
|
return NAME;
|
||||||
|
}
|
||||||
|
|
||||||
|
t_daemon create_daemon(boost::program_options::variables_map const & vm)
|
||||||
|
{
|
||||||
|
return t_daemon(vm);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool run_non_interactive(boost::program_options::variables_map const & vm)
|
||||||
|
{
|
||||||
|
return t_daemon(vm).run();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool run_interactive(boost::program_options::variables_map const & vm)
|
||||||
|
{
|
||||||
|
return t_daemon(vm).run();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
std::string const t_executor::NAME = "Wallet RPC Daemon";
|
||||||
|
|
||||||
int main(int argc, char** argv) {
|
int main(int argc, char** argv) {
|
||||||
namespace po = boost::program_options;
|
namespace po = boost::program_options;
|
||||||
|
|
||||||
const auto arg_wallet_file = wallet_args::arg_wallet_file();
|
const auto arg_wallet_file = wallet_args::arg_wallet_file();
|
||||||
const auto arg_from_json = wallet_args::arg_generate_from_json();
|
const auto arg_from_json = wallet_args::arg_generate_from_json();
|
||||||
|
|
||||||
|
po::options_description hidden_options("Hidden");
|
||||||
|
|
||||||
po::options_description desc_params(wallet_args::tr("Wallet options"));
|
po::options_description desc_params(wallet_args::tr("Wallet options"));
|
||||||
tools::wallet2::init_options(desc_params);
|
tools::wallet2::init_options(desc_params);
|
||||||
command_line::add_arg(desc_params, arg_rpc_bind_port);
|
command_line::add_arg(desc_params, arg_rpc_bind_port);
|
||||||
|
@ -3282,6 +3443,8 @@ int main(int argc, char** argv) {
|
||||||
command_line::add_arg(desc_params, arg_wallet_dir);
|
command_line::add_arg(desc_params, arg_wallet_dir);
|
||||||
command_line::add_arg(desc_params, arg_prompt_for_password);
|
command_line::add_arg(desc_params, arg_prompt_for_password);
|
||||||
|
|
||||||
|
daemonizer::init_options(hidden_options, desc_params);
|
||||||
|
|
||||||
boost::optional<po::variables_map> vm;
|
boost::optional<po::variables_map> vm;
|
||||||
bool should_terminate = false;
|
bool should_terminate = false;
|
||||||
std::tie(vm, should_terminate) = wallet_args::main(
|
std::tie(vm, should_terminate) = wallet_args::main(
|
||||||
|
@ -3303,115 +3466,5 @@ int main(int argc, char** argv) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::unique_ptr<tools::wallet2> wal;
|
return daemonizer::daemonize(argc, const_cast<const char**>(argv), t_executor{}, *vm) ? 0 : 1;
|
||||||
try
|
|
||||||
{
|
|
||||||
const bool testnet = tools::wallet2::has_testnet_option(*vm);
|
|
||||||
const bool stagenet = tools::wallet2::has_stagenet_option(*vm);
|
|
||||||
if (testnet && stagenet)
|
|
||||||
{
|
|
||||||
MERROR(tools::wallet_rpc_server::tr("Can't specify more than one of --testnet and --stagenet"));
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
const auto wallet_file = command_line::get_arg(*vm, arg_wallet_file);
|
|
||||||
const auto from_json = command_line::get_arg(*vm, arg_from_json);
|
|
||||||
const auto wallet_dir = command_line::get_arg(*vm, arg_wallet_dir);
|
|
||||||
const auto prompt_for_password = command_line::get_arg(*vm, arg_prompt_for_password);
|
|
||||||
const auto password_prompt = prompt_for_password ? password_prompter : nullptr;
|
|
||||||
|
|
||||||
if(!wallet_file.empty() && !from_json.empty())
|
|
||||||
{
|
|
||||||
LOG_ERROR(tools::wallet_rpc_server::tr("Can't specify more than one of --wallet-file and --generate-from-json"));
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!wallet_dir.empty())
|
|
||||||
{
|
|
||||||
wal = NULL;
|
|
||||||
goto just_dir;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (wallet_file.empty() && from_json.empty())
|
|
||||||
{
|
|
||||||
LOG_ERROR(tools::wallet_rpc_server::tr("Must specify --wallet-file or --generate-from-json or --wallet-dir"));
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
LOG_PRINT_L0(tools::wallet_rpc_server::tr("Loading wallet..."));
|
|
||||||
if(!wallet_file.empty())
|
|
||||||
{
|
|
||||||
wal = tools::wallet2::make_from_file(*vm, true, wallet_file, password_prompt).first;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
wal = tools::wallet2::make_from_json(*vm, true, from_json, password_prompt);
|
|
||||||
}
|
|
||||||
catch (const std::exception &e)
|
|
||||||
{
|
|
||||||
MERROR("Error creating wallet: " << e.what());
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (!wal)
|
|
||||||
{
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool quit = false;
|
|
||||||
tools::signal_handler::install([&wal, &quit](int) {
|
|
||||||
assert(wal);
|
|
||||||
quit = true;
|
|
||||||
wal->stop();
|
|
||||||
});
|
|
||||||
|
|
||||||
wal->refresh(wal->is_trusted_daemon());
|
|
||||||
// if we ^C during potentially length load/refresh, there's no server loop yet
|
|
||||||
if (quit)
|
|
||||||
{
|
|
||||||
MINFO(tools::wallet_rpc_server::tr("Saving wallet..."));
|
|
||||||
wal->store();
|
|
||||||
MINFO(tools::wallet_rpc_server::tr("Successfully saved"));
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
MINFO(tools::wallet_rpc_server::tr("Successfully loaded"));
|
|
||||||
}
|
|
||||||
catch (const std::exception& e)
|
|
||||||
{
|
|
||||||
LOG_ERROR(tools::wallet_rpc_server::tr("Wallet initialization failed: ") << e.what());
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
just_dir:
|
|
||||||
tools::wallet_rpc_server wrpc;
|
|
||||||
if (wal) wrpc.set_wallet(wal.release());
|
|
||||||
bool r = wrpc.init(&(vm.get()));
|
|
||||||
CHECK_AND_ASSERT_MES(r, 1, tools::wallet_rpc_server::tr("Failed to initialize wallet RPC server"));
|
|
||||||
tools::signal_handler::install([&wrpc](int) {
|
|
||||||
wrpc.send_stop_signal();
|
|
||||||
});
|
|
||||||
LOG_PRINT_L0(tools::wallet_rpc_server::tr("Starting wallet RPC server"));
|
|
||||||
try
|
|
||||||
{
|
|
||||||
wrpc.run();
|
|
||||||
}
|
|
||||||
catch (const std::exception &e)
|
|
||||||
{
|
|
||||||
LOG_ERROR(tools::wallet_rpc_server::tr("Failed to run wallet: ") << e.what());
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
LOG_PRINT_L0(tools::wallet_rpc_server::tr("Stopped wallet RPC server"));
|
|
||||||
try
|
|
||||||
{
|
|
||||||
LOG_PRINT_L0(tools::wallet_rpc_server::tr("Saving wallet..."));
|
|
||||||
wrpc.stop();
|
|
||||||
LOG_PRINT_L0(tools::wallet_rpc_server::tr("Successfully saved"));
|
|
||||||
}
|
|
||||||
catch (const std::exception& e)
|
|
||||||
{
|
|
||||||
LOG_ERROR(tools::wallet_rpc_server::tr("Failed to save wallet: ") << e.what());
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue