// Copyright (c) 2014-2017, 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. #include "cryptonote_config.h" #include "version.h" #include "daemon/command_server.h" #undef MONERO_DEFAULT_LOG_CATEGORY #define MONERO_DEFAULT_LOG_CATEGORY "daemon" namespace daemonize { namespace p = std::placeholders; t_command_server::t_command_server( uint32_t ip , uint16_t port , const boost::optional& login , bool is_rpc , cryptonote::core_rpc_server* rpc_server ) : m_parser(ip, port, login, is_rpc, rpc_server) , m_command_lookup() , m_is_rpc(is_rpc) { m_command_lookup.set_handler( "q" , [] (const std::vector& args) {return true;} , "ignored" ); m_command_lookup.set_handler( "help" , std::bind(&t_command_server::help, this, p::_1) , "Show this help" ); m_command_lookup.set_handler( "print_height" , std::bind(&t_command_parser_executor::print_height, &m_parser, p::_1) , "Print 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" ); 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" ); m_command_lookup.set_handler( "print_cn" , std::bind(&t_command_parser_executor::print_connections, &m_parser, p::_1) , "Print 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 []" ); m_command_lookup.set_handler( "print_block" , std::bind(&t_command_parser_executor::print_block, &m_parser, p::_1) , "Print block, print_block | " ); m_command_lookup.set_handler( "print_tx" , std::bind(&t_command_parser_executor::print_transaction, &m_parser, p::_1) , "Print transaction, print_tx " ); 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 " ); 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 [] [do_background_mining] [ignore_battery], default 1 thread, no background mining" ); m_command_lookup.set_handler( "stop_mining" , std::bind(&t_command_parser_executor::stop_mining, &m_parser, p::_1) , "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)" ); 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)" ); 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" ); m_command_lookup.set_handler( "show_hr" , std::bind(&t_command_parser_executor::show_hash_rate, &m_parser, p::_1) , "Start showing 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" ); m_command_lookup.set_handler( "save" , std::bind(&t_command_parser_executor::save_blockchain, &m_parser, p::_1) , "Save blockchain" ); m_command_lookup.set_handler( "set_log" , std::bind(&t_command_parser_executor::set_log_level, &m_parser, p::_1) , "set_log | - Change current loglevel, 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" ); m_command_lookup.set_handler( "status" , std::bind(&t_command_parser_executor::show_status, &m_parser, p::_1) , "Show status" ); m_command_lookup.set_handler( "stop_daemon" , std::bind(&t_command_parser_executor::stop_daemon, &m_parser, p::_1) , "Stop the daemon" ); m_command_lookup.set_handler( "exit" , std::bind(&t_command_parser_executor::stop_daemon, &m_parser, p::_1) , "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" ); m_command_lookup.set_handler( "limit" , std::bind(&t_command_parser_executor::set_limit, &m_parser, p::_1) , "limit - Set 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 - Set upload limit" ); m_command_lookup.set_handler( "limit_down" , std::bind(&t_command_parser_executor::set_limit_down, &m_parser, p::_1) , "limit - Set 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" ); 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" ); 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" ); 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" ); m_command_lookup.set_handler( "bans" , std::bind(&t_command_parser_executor::show_bans, &m_parser, p::_1) , "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" ); m_command_lookup.set_handler( "unban" , std::bind(&t_command_parser_executor::unban, &m_parser, p::_1) , "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" ); m_command_lookup.set_handler( "output_histogram" , std::bind(&t_command_parser_executor::output_histogram, &m_parser, p::_1) , "Print output histogram (amount, instances)" ); 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 [block count]" ); 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" ); 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" ); 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)" ); 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" ); 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" ); } bool t_command_server::process_command_str(const std::string& cmd) { return m_command_lookup.process_command_str(cmd); } bool t_command_server::process_command_vec(const std::vector& cmd) { bool result = m_command_lookup.process_command_vec(cmd); if (!result) { help(std::vector()); } return result; } bool t_command_server::start_handling(std::function exit_handler) { if (m_is_rpc) return false; m_command_lookup.start_handling("", get_commands_str(), exit_handler); return true; } void t_command_server::stop_handling() { if (m_is_rpc) return; m_command_lookup.stop_handling(); } bool t_command_server::help(const std::vector& args) { std::cout << get_commands_str() << std::endl; return true; } std::string t_command_server::get_commands_str() { std::stringstream ss; ss << "Monero '" << MONERO_RELEASE_NAME << "' (v" << MONERO_VERSION_FULL << ")" << std::endl; ss << "Commands: " << std::endl; std::string usage = m_command_lookup.get_usage(); boost::replace_all(usage, "\n", "\n "); usage.insert(0, " "); ss << usage << std::endl; return ss.str(); } } // namespace daemonize