aboutsummaryrefslogtreecommitdiff
path: root/src/daemon
diff options
context:
space:
mode:
Diffstat (limited to 'src/daemon')
-rw-r--r--src/daemon/command_server.cpp136
-rw-r--r--src/daemon/command_server.h1
-rw-r--r--src/daemon/daemon.cpp40
-rw-r--r--src/daemon/rpc.h28
4 files changed, 133 insertions, 72 deletions
diff --git a/src/daemon/command_server.cpp b/src/daemon/command_server.cpp
index b134aee61..7ff6b2bf3 100644
--- a/src/daemon/command_server.cpp
+++ b/src/daemon/command_server.cpp
@@ -49,214 +49,228 @@ t_command_server::t_command_server(
, m_is_rpc(is_rpc)
{
m_command_lookup.set_handler(
- "q"
- , [] (const std::vector<std::string>& args) {return true;}
- , "ignored"
- );
- m_command_lookup.set_handler(
"help"
, std::bind(&t_command_server::help, this, p::_1)
- , "Show this help"
+ , "help [<command>]"
+ , "Show the help section or the documentation about a <command>."
);
m_command_lookup.set_handler(
"print_height"
, std::bind(&t_command_parser_executor::print_height, &m_parser, p::_1)
- , "Print local blockchain height"
+ , "Print the local blockchain height."
);
m_command_lookup.set_handler(
"print_pl"
, std::bind(&t_command_parser_executor::print_peer_list, &m_parser, p::_1)
- , "Print peer list"
+ , "Print the current peer list."
);
m_command_lookup.set_handler(
"print_pl_stats"
, std::bind(&t_command_parser_executor::print_peer_list_stats, &m_parser, p::_1)
- , "Print peer list stats"
+ , "Print the peer list statistics."
);
m_command_lookup.set_handler(
"print_cn"
, std::bind(&t_command_parser_executor::print_connections, &m_parser, p::_1)
- , "Print connections"
+ , "Print the current connections."
);
m_command_lookup.set_handler(
"print_bc"
, std::bind(&t_command_parser_executor::print_blockchain_info, &m_parser, p::_1)
- , "Print blockchain info in a given blocks range, print_bc <begin_height> [<end_height>]"
+ , "print_bc <begin_height> [<end_height>]"
+ , "Print the blockchain info in a given blocks range."
);
m_command_lookup.set_handler(
"print_block"
, std::bind(&t_command_parser_executor::print_block, &m_parser, p::_1)
- , "Print block, print_block <block_hash> | <block_height>"
+ , "print_block <block_hash> | <block_height>"
+ , "Print a given block."
);
m_command_lookup.set_handler(
"print_tx"
, std::bind(&t_command_parser_executor::print_transaction, &m_parser, p::_1)
- , "Print transaction, print_tx <transaction_hash> [+hex] [+json]"
+ , "print_tx <transaction_hash> [+hex] [+json]"
+ , "Print a given transaction."
);
m_command_lookup.set_handler(
"is_key_image_spent"
, std::bind(&t_command_parser_executor::is_key_image_spent, &m_parser, p::_1)
- , "Prints whether a given key image is in the spent key images set, is_key_image_spent <key_image>"
+ , "is_key_image_spent <key_image>"
+ , "Print whether a given key image is in the spent key images set."
);
m_command_lookup.set_handler(
"start_mining"
, std::bind(&t_command_parser_executor::start_mining, &m_parser, p::_1)
- , "Start mining for specified address, start_mining <addr> [<threads>] [do_background_mining] [ignore_battery], default 1 thread, no background mining"
+ , "start_mining <addr> [<threads>] [do_background_mining] [ignore_battery]"
+ , "Start mining for specified address. Defaults to 1 thread and no background mining."
);
m_command_lookup.set_handler(
"stop_mining"
, std::bind(&t_command_parser_executor::stop_mining, &m_parser, p::_1)
- , "Stop mining"
+ , "Stop mining."
);
m_command_lookup.set_handler(
"print_pool"
, std::bind(&t_command_parser_executor::print_transaction_pool_long, &m_parser, p::_1)
- , "Print transaction pool (long format)"
+ , "Print the transaction pool using a long format."
);
m_command_lookup.set_handler(
"print_pool_sh"
, std::bind(&t_command_parser_executor::print_transaction_pool_short, &m_parser, p::_1)
- , "Print transaction pool (short format)"
+ , "Print transaction pool using a short format."
);
m_command_lookup.set_handler(
"print_pool_stats"
, std::bind(&t_command_parser_executor::print_transaction_pool_stats, &m_parser, p::_1)
- , "Print transaction pool statistics"
+ , "Print the transaction pool's statistics."
);
m_command_lookup.set_handler(
"show_hr"
, std::bind(&t_command_parser_executor::show_hash_rate, &m_parser, p::_1)
- , "Start showing hash rate"
+ , "Start showing the current hash rate."
);
m_command_lookup.set_handler(
"hide_hr"
, std::bind(&t_command_parser_executor::hide_hash_rate, &m_parser, p::_1)
- , "Stop showing hash rate"
+ , "Stop showing the hash rate."
);
m_command_lookup.set_handler(
"save"
, std::bind(&t_command_parser_executor::save_blockchain, &m_parser, p::_1)
- , "Save blockchain"
+ , "Save the blockchain."
);
m_command_lookup.set_handler(
"set_log"
, std::bind(&t_command_parser_executor::set_log_level, &m_parser, p::_1)
- , "set_log <level>|<{+,-,}categories> - Change current log level/categories, <level> is a number 0-4"
+ , "set_log <level>|<{+,-,}categories>"
+ , "Change the current log level/categories where <level> is a number 0-4."
);
m_command_lookup.set_handler(
"diff"
, std::bind(&t_command_parser_executor::show_difficulty, &m_parser, p::_1)
- , "Show difficulty"
+ , "Show the current difficulty."
);
m_command_lookup.set_handler(
"status"
, std::bind(&t_command_parser_executor::show_status, &m_parser, p::_1)
- , "Show status"
+ , "Show the current status."
);
m_command_lookup.set_handler(
"stop_daemon"
, std::bind(&t_command_parser_executor::stop_daemon, &m_parser, p::_1)
- , "Stop the daemon"
+ , "Stop the daemon."
);
m_command_lookup.set_handler(
"exit"
, std::bind(&t_command_parser_executor::stop_daemon, &m_parser, p::_1)
- , "Stop the daemon"
+ , "Stop the daemon."
);
m_command_lookup.set_handler(
"print_status"
, std::bind(&t_command_parser_executor::print_status, &m_parser, p::_1)
- , "Prints daemon status"
+ , "Print the current daemon status."
);
m_command_lookup.set_handler(
"limit"
, std::bind(&t_command_parser_executor::set_limit, &m_parser, p::_1)
- , "limit <kB/s> - Set download and upload limit"
+ , "limit [<kB/s>]"
+ , "Get or set the download and upload limit."
);
m_command_lookup.set_handler(
"limit_up"
, std::bind(&t_command_parser_executor::set_limit_up, &m_parser, p::_1)
- , "limit <kB/s> - Set upload limit"
+ , "limit_up [<kB/s>]"
+ , "Get or set the upload limit."
);
m_command_lookup.set_handler(
"limit_down"
, std::bind(&t_command_parser_executor::set_limit_down, &m_parser, p::_1)
- , "limit <kB/s> - Set download limit"
+ , "limit_down [<kB/s>]"
+ , "Get or set the download limit."
);
m_command_lookup.set_handler(
"out_peers"
, std::bind(&t_command_parser_executor::out_peers, &m_parser, p::_1)
- , "Set max number of out peers"
+ , "out_peers <max_number>"
+ , "Set the <max_number> of out peers."
);
m_command_lookup.set_handler(
"start_save_graph"
, std::bind(&t_command_parser_executor::start_save_graph, &m_parser, p::_1)
- , "Start save data for dr monero"
+ , "Start saving data for dr monero."
);
m_command_lookup.set_handler(
"stop_save_graph"
, std::bind(&t_command_parser_executor::stop_save_graph, &m_parser, p::_1)
- , "Stop save data for dr monero"
+ , "Stop saving data for dr monero."
);
m_command_lookup.set_handler(
"hard_fork_info"
, std::bind(&t_command_parser_executor::hard_fork_info, &m_parser, p::_1)
- , "Print hard fork voting information"
+ , "Print the hard fork voting information."
);
m_command_lookup.set_handler(
"bans"
, std::bind(&t_command_parser_executor::show_bans, &m_parser, p::_1)
- , "Show the currently banned IPs"
+ , "Show the currently banned IPs."
);
m_command_lookup.set_handler(
"ban"
, std::bind(&t_command_parser_executor::ban, &m_parser, p::_1)
- , "Ban a given IP for a time"
+ , "ban <IP> [<seconds>]"
+ , "Ban a given <IP> for a given amount of <seconds>."
);
m_command_lookup.set_handler(
"unban"
, std::bind(&t_command_parser_executor::unban, &m_parser, p::_1)
- , "Unban a given IP"
+ , "unban <IP>"
+ , "Unban a given <IP>."
);
m_command_lookup.set_handler(
"flush_txpool"
, std::bind(&t_command_parser_executor::flush_txpool, &m_parser, p::_1)
- , "Flush a transaction from the tx pool by its txid, or the whole tx pool"
+ , "flush_txpool [<txid>]"
+ , "Flush a transaction from the tx pool by its <txid>, or the whole tx pool."
);
m_command_lookup.set_handler(
"output_histogram"
, std::bind(&t_command_parser_executor::output_histogram, &m_parser, p::_1)
- , "Print output histogram (amount, instances)"
+ , "output_histogram [@<amount>] <min_count> [<max_count>]"
+ , "Print the output histogram of outputs."
);
m_command_lookup.set_handler(
"print_coinbase_tx_sum"
, std::bind(&t_command_parser_executor::print_coinbase_tx_sum, &m_parser, p::_1)
- , "Print sum of coinbase transactions <start height> [block count]"
+ , "print_coinbase_tx_sum <start_height> [<block_count>]"
+ , "Print the sum of coinbase transactions."
);
m_command_lookup.set_handler(
"alt_chain_info"
, std::bind(&t_command_parser_executor::alt_chain_info, &m_parser, p::_1)
- , "Print information about alternative chains"
+ , "Print the information about alternative chains."
);
m_command_lookup.set_handler(
"bc_dyn_stats"
, std::bind(&t_command_parser_executor::print_blockchain_dynamic_stats, &m_parser, p::_1)
- , "Print information about current blockchain dynamic state, bc_dyn_stats <last n blocks>"
+ , "bc_dyn_stats <last_block_count>"
+ , "Print the information about current blockchain dynamic state."
);
m_command_lookup.set_handler(
"update"
, std::bind(&t_command_parser_executor::update, &m_parser, p::_1)
- , "subcommands: check (check if an update is available), download (download it if there is), update (not implemented)"
+ , "update (check|download)"
+ , "Check if an update is available, optionally downloads it if there is. Updating is not yet implemented."
);
m_command_lookup.set_handler(
"relay_tx"
, std::bind(&t_command_parser_executor::relay_tx, &m_parser, p::_1)
- , "Relay a given transaction by its txid"
+ , "relay_tx <txid>"
+ , "Relay a given transaction by its <txid>."
);
m_command_lookup.set_handler(
"sync_info"
, std::bind(&t_command_parser_executor::sync_info, &m_parser, p::_1)
- , "Print information about blockchain sync state"
+ , "Print information about the blockchain sync state."
);
}
@@ -293,7 +307,14 @@ void t_command_server::stop_handling()
bool t_command_server::help(const std::vector<std::string>& args)
{
- std::cout << get_commands_str() << std::endl;
+ if(args.empty())
+ {
+ std::cout << get_commands_str() << std::endl;
+ }
+ else
+ {
+ std::cout << get_command_usage(args) << std::endl;
+ }
return true;
}
@@ -309,4 +330,25 @@ std::string t_command_server::get_commands_str()
return ss.str();
}
+ std::string t_command_server::get_command_usage(const std::vector<std::string> &args)
+ {
+ std::pair<std::string, std::string> documentation = m_command_lookup.get_documentation(args);
+ std::stringstream ss;
+ if(documentation.first.empty())
+ {
+ ss << "Unknown command: " << args.front() << std::endl;
+ }
+ else
+ {
+ std::string usage = documentation.second.empty() ? args.front() : documentation.first;
+ std::string description = documentation.second.empty() ? documentation.first : documentation.second;
+ usage.insert(0, " ");
+ ss << "Command usage: " << std::endl << usage << std::endl << std::endl;
+ boost::replace_all(description, "\n", "\n ");
+ description.insert(0, " ");
+ ss << "Command description: " << std::endl << description << std::endl;
+ }
+ return ss.str();
+ }
+
} // namespace daemonize
diff --git a/src/daemon/command_server.h b/src/daemon/command_server.h
index 476b75141..2ad277f4a 100644
--- a/src/daemon/command_server.h
+++ b/src/daemon/command_server.h
@@ -73,6 +73,7 @@ private:
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
diff --git a/src/daemon/daemon.cpp b/src/daemon/daemon.cpp
index cf7d5f8ab..f8acf1357 100644
--- a/src/daemon/daemon.cpp
+++ b/src/daemon/daemon.cpp
@@ -60,7 +60,7 @@ private:
public:
t_core core;
t_p2p p2p;
- t_rpc rpc;
+ std::vector<std::unique_ptr<t_rpc>> rpcs;
t_internals(
boost::program_options::variables_map const & vm
@@ -68,11 +68,22 @@ public:
: core{vm}
, protocol{vm, core}
, p2p{vm, protocol}
- , rpc{vm, core, p2p}
{
// Handle circular dependencies
protocol.set_p2p_endpoint(p2p.get());
core.set_protocol(protocol.get());
+
+ const auto testnet = command_line::get_arg(vm, cryptonote::arg_testnet_on);
+ const auto restricted = command_line::get_arg(vm, cryptonote::core_rpc_server::arg_restricted_rpc);
+ const auto main_rpc_port = command_line::get_arg(vm, testnet ? cryptonote::core_rpc_server::arg_testnet_rpc_bind_port : cryptonote::core_rpc_server::arg_rpc_bind_port);
+ rpcs.emplace_back(new t_rpc{vm, core, p2p, restricted, testnet, main_rpc_port, "core"});
+
+ auto restricted_rpc_port_arg = testnet ? cryptonote::core_rpc_server::arg_testnet_rpc_restricted_bind_port : cryptonote::core_rpc_server::arg_rpc_restricted_bind_port;
+ if(!command_line::is_arg_defaulted(vm, restricted_rpc_port_arg))
+ {
+ auto restricted_rpc_port = command_line::get_arg(vm, restricted_rpc_port_arg);
+ rpcs.emplace_back(new t_rpc{vm, core, p2p, true, testnet, restricted_rpc_port, "restricted"});
+ }
}
};
@@ -135,14 +146,15 @@ bool t_daemon::run(bool interactive)
{
if (!mp_internals->core.run())
return false;
- mp_internals->rpc.run();
- std::unique_ptr<daemonize::t_command_server> rpc_commands;
+ for(auto& rpc: mp_internals->rpcs)
+ rpc->run();
- if (interactive)
+ std::unique_ptr<daemonize::t_command_server> rpc_commands;
+ if (interactive && mp_internals->rpcs.size())
{
// The first three variables are not used when the fourth is false
- rpc_commands.reset(new daemonize::t_command_server(0, 0, boost::none, false, mp_internals->rpc.get_server()));
+ rpc_commands.reset(new daemonize::t_command_server(0, 0, boost::none, false, mp_internals->rpcs.front()->get_server()));
rpc_commands->start_handling(std::bind(&daemonize::t_daemon::stop_p2p, this));
}
@@ -154,12 +166,11 @@ bool t_daemon::run(bool interactive)
LOG_ERROR(std::string("Failed to add TCP Socket (") + zmq_rpc_bind_address
+ ":" + zmq_rpc_bind_port + ") to ZMQ RPC Server");
- if (interactive)
- {
+ if (rpc_commands)
rpc_commands->stop_handling();
- }
- mp_internals->rpc.stop();
+ for(auto& rpc : mp_internals->rpcs)
+ rpc->stop();
return false;
}
@@ -173,13 +184,12 @@ bool t_daemon::run(bool interactive)
mp_internals->p2p.run(); // blocks until p2p goes down
if (rpc_commands)
- {
rpc_commands->stop_handling();
- }
zmq_server.stop();
- mp_internals->rpc.stop();
+ for(auto& rpc : mp_internals->rpcs)
+ rpc->stop();
mp_internals->core.get().get_miner().stop();
MGINFO("Node stopped.");
return true;
@@ -204,7 +214,9 @@ void t_daemon::stop()
}
mp_internals->core.get().get_miner().stop();
mp_internals->p2p.stop();
- mp_internals->rpc.stop();
+ for(auto& rpc : mp_internals->rpcs)
+ rpc->stop();
+
mp_internals.reset(nullptr); // Ensure resources are cleaned up before we return
}
diff --git a/src/daemon/rpc.h b/src/daemon/rpc.h
index 0ecfdd120..9b7438053 100644
--- a/src/daemon/rpc.h
+++ b/src/daemon/rpc.h
@@ -47,35 +47,41 @@ public:
}
private:
cryptonote::core_rpc_server m_server;
+ const std::string m_description;
public:
t_rpc(
boost::program_options::variables_map const & vm
, t_core & core
, t_p2p & p2p
+ , const bool restricted
+ , const bool testnet
+ , const std::string & port
+ , const std::string & description
)
- : m_server{core.get(), p2p.get()}
+ : m_server{core.get(), p2p.get()}, m_description{description}
{
- MGINFO("Initializing core rpc server...");
- if (!m_server.init(vm))
+ MGINFO("Initializing " << m_description << " rpc server...");
+
+ if (!m_server.init(vm, restricted, testnet, port))
{
- throw std::runtime_error("Failed to initialize core rpc server.");
+ throw std::runtime_error("Failed to initialize " + m_description + " rpc server.");
}
- MGINFO("Core rpc server initialized OK on port: " << m_server.get_binded_port());
+ MGINFO(m_description << " rpc server initialized OK on port: " << m_server.get_binded_port());
}
void run()
{
- MGINFO("Starting core rpc server...");
+ MGINFO("Starting " << m_description << " rpc server...");
if (!m_server.run(2, false))
{
- throw std::runtime_error("Failed to start core rpc server.");
+ throw std::runtime_error("Failed to start " + m_description + " rpc server.");
}
- MGINFO("Core rpc server started ok");
+ MGINFO(m_description << " rpc server started ok");
}
void stop()
{
- MGINFO("Stopping core rpc server...");
+ MGINFO("Stopping " << m_description << " rpc server...");
m_server.send_stop_signal();
m_server.timed_wait_server_stop(5000);
}
@@ -87,11 +93,11 @@ public:
~t_rpc()
{
- MGINFO("Deinitializing rpc server...");
+ MGINFO("Deinitializing " << m_description << " rpc server...");
try {
m_server.deinit();
} catch (...) {
- MERROR("Failed to deinitialize rpc server...");
+ MERROR("Failed to deinitialize " << m_description << " rpc server...");
}
}
};