aboutsummaryrefslogtreecommitdiff
path: root/src/daemon
diff options
context:
space:
mode:
authorThomas Winget <tewinget@gmail.com>2015-01-29 17:10:53 -0500
committerThomas Winget <tewinget@gmail.com>2015-02-24 00:05:19 -0500
commit9193d6fb5be92df732af18b08b1e052f84cc2f9d (patch)
treedfe58f501122beec786322d30d04efacf8c90259 /src/daemon
parentMerge pull request #221 (diff)
downloadmonero-9193d6fb5be92df732af18b08b1e052f84cc2f9d.tar.xz
Daemonize changes pulled in -- daemon builds
many RPC functions added by the daemonize changes (and related changes on the upstream dev branch that were not merged) were commented out (apart from return). Other than that, this *should* work...at any rate, it builds, and that's something.
Diffstat (limited to 'src/daemon')
-rw-r--r--src/daemon/CMakeLists.txt18
-rw-r--r--src/daemon/command_line_args.h76
-rw-r--r--src/daemon/command_parser_executor.cpp297
-rw-r--r--src/daemon/command_parser_executor.h95
-rw-r--r--src/daemon/command_server.cpp179
-rw-r--r--src/daemon/command_server.h67
-rw-r--r--src/daemon/core.h98
-rw-r--r--src/daemon/daemon.cpp342
-rw-r--r--src/daemon/daemon.h54
-rw-r--r--src/daemon/daemon_commands_handler.h183
-rw-r--r--src/daemon/executor.cpp71
-rw-r--r--src/daemon/executor.h60
-rw-r--r--src/daemon/main.cpp229
-rw-r--r--src/daemon/p2p.h99
-rw-r--r--src/daemon/protocol.h88
-rw-r--r--src/daemon/rpc.h96
-rw-r--r--src/daemon/rpc_command_executor.cpp435
-rw-r--r--src/daemon/rpc_command_executor.h103
18 files changed, 2294 insertions, 296 deletions
diff --git a/src/daemon/CMakeLists.txt b/src/daemon/CMakeLists.txt
index 5f60857d6..4de8b82b8 100644
--- a/src/daemon/CMakeLists.txt
+++ b/src/daemon/CMakeLists.txt
@@ -27,12 +27,27 @@
# THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
set(daemon_sources
- daemon.cpp)
+ command_parser_executor.cpp
+ command_server.cpp
+ daemon.cpp
+ executor.cpp
+ main.cpp
+ rpc_command_executor.cpp
+)
set(daemon_headers)
set(daemon_private_headers
+ command_parser_executor.h
+ command_server.h
+ core.h
+ daemon.h
daemon_commands_handler.h
+ executor.h
+ p2p.h
+ protocol.h
+ rpc.h
+ rpc_command_executor.h
# cryptonote_protocol
../cryptonote_protocol/blobdatatype.h
@@ -62,6 +77,7 @@ target_link_libraries(daemon
cryptonote_core
crypto
common
+ daemonizer
${Boost_CHRONO_LIBRARY}
${Boost_FILESYSTEM_LIBRARY}
${Boost_PROGRAM_OPTIONS_LIBRARY}
diff --git a/src/daemon/command_line_args.h b/src/daemon/command_line_args.h
new file mode 100644
index 000000000..bcf599128
--- /dev/null
+++ b/src/daemon/command_line_args.h
@@ -0,0 +1,76 @@
+// Copyright (c) 2014, 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.
+
+#ifndef DAEMON_COMMAND_LINE_ARGS_H
+#define DAEMON_COMMAND_LINE_ARGS_H
+
+#include "common/command_line.h"
+#include "cryptonote_config.h"
+#include <boost/program_options.hpp>
+
+namespace daemon_args
+{
+ std::string const WINDOWS_SERVICE_NAME = "Monero Daemon";
+
+ const command_line::arg_descriptor<std::string> arg_config_file = {
+ "config-file"
+ , "Specify configuration file"
+ , std::string(CRYPTONOTE_NAME ".conf")
+ };
+ const command_line::arg_descriptor<std::string> arg_log_file = {
+ "log-file"
+ , "Specify log file"
+ , ""
+ };
+ const command_line::arg_descriptor<int> arg_log_level = {
+ "log-level"
+ , ""
+ , LOG_LEVEL_0
+ };
+ const command_line::arg_descriptor<std::vector<std::string>> arg_command = {
+ "daemon_command"
+ , "Hidden"
+ };
+ const command_line::arg_descriptor<bool> arg_os_version = {
+ "os-version"
+ , "OS for which this executable was compiled"
+ };
+ const command_line::arg_descriptor<bool> arg_testnet_on = {
+ "testnet"
+ , "Run on testnet. The wallet must be launched with --testnet flag."
+ , false
+ };
+ const command_line::arg_descriptor<bool> arg_dns_checkpoints = {
+ "enforce-dns-checkpointing"
+ , "checkpoints from DNS server will be enforced"
+ , false
+ };
+
+} // namespace daemon_args
+
+#endif // DAEMON_COMMAND_LINE_ARGS_H
diff --git a/src/daemon/command_parser_executor.cpp b/src/daemon/command_parser_executor.cpp
new file mode 100644
index 000000000..d3af50b66
--- /dev/null
+++ b/src/daemon/command_parser_executor.cpp
@@ -0,0 +1,297 @@
+// Copyright (c) 2014, 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_core/cryptonote_basic_impl.h"
+#include "daemon/command_parser_executor.h"
+
+namespace daemonize {
+
+t_command_parser_executor::t_command_parser_executor(
+ uint32_t ip
+ , uint16_t port
+ )
+ : m_executor(ip, port)
+{}
+
+bool t_command_parser_executor::print_peer_list(const std::vector<std::string>& args)
+{
+ if (!args.empty()) return false;
+
+ return m_executor.print_peer_list();
+}
+
+bool t_command_parser_executor::save_blockchain(const std::vector<std::string>& args)
+{
+ if (!args.empty()) return false;
+
+ return m_executor.save_blockchain();
+}
+
+bool t_command_parser_executor::show_hash_rate(const std::vector<std::string>& args)
+{
+ if (!args.empty()) return false;
+
+ return m_executor.show_hash_rate();
+}
+
+bool t_command_parser_executor::hide_hash_rate(const std::vector<std::string>& args)
+{
+ if (!args.empty()) return false;
+
+ return m_executor.hide_hash_rate();
+}
+
+bool t_command_parser_executor::show_difficulty(const std::vector<std::string>& args)
+{
+ if (!args.empty()) return false;
+
+ return m_executor.show_difficulty();
+}
+
+bool t_command_parser_executor::print_connections(const std::vector<std::string>& args)
+{
+ if (!args.empty()) return false;
+
+ return m_executor.print_connections();
+}
+
+bool t_command_parser_executor::print_blockchain_info(const std::vector<std::string>& args)
+{
+ if(!args.size())
+ {
+ std::cout << "need block index parameter" << std::endl;
+ return false;
+ }
+ uint64_t start_index = 0;
+ uint64_t end_index = 0;
+ if(!epee::string_tools::get_xtype_from_string(start_index, args[0]))
+ {
+ std::cout << "wrong starter block index parameter" << std::endl;
+ return false;
+ }
+ if(args.size() >1 && !epee::string_tools::get_xtype_from_string(end_index, args[1]))
+ {
+ std::cout << "wrong end block index parameter" << std::endl;
+ return false;
+ }
+
+ return m_executor.print_blockchain_info(start_index, end_index);
+}
+
+bool t_command_parser_executor::set_log_level(const std::vector<std::string>& args)
+{
+ if(args.size() != 1)
+ {
+ std::cout << "use: set_log <log_level_number_0-4>" << std::endl;
+ return true;
+ }
+
+ uint16_t l = 0;
+ if(!epee::string_tools::get_xtype_from_string(l, args[0]))
+ {
+ std::cout << "wrong number format, use: set_log <log_level_number_0-4>" << std::endl;
+ return true;
+ }
+
+ if(LOG_LEVEL_4 < l)
+ {
+ std::cout << "wrong number range, use: set_log <log_level_number_0-4>" << std::endl;
+ return true;
+ }
+
+ return m_executor.set_log_level(l);
+}
+
+bool t_command_parser_executor::print_height(const std::vector<std::string>& args)
+{
+ if (!args.empty()) return false;
+
+ return m_executor.print_height();
+}
+
+bool t_command_parser_executor::print_block(const std::vector<std::string>& args)
+{
+ if (args.empty())
+ {
+ std::cout << "expected: print_block (<block_hash> | <block_height>)" << std::endl;
+ return false;
+ }
+
+ const std::string& arg = args.front();
+ try
+ {
+ uint64_t height = boost::lexical_cast<uint64_t>(arg);
+ return m_executor.print_block_by_height(height);
+ }
+ catch (boost::bad_lexical_cast&)
+ {
+ crypto::hash block_hash;
+ if (parse_hash256(arg, block_hash))
+ {
+ return m_executor.print_block_by_hash(block_hash);
+ }
+ }
+
+ return false;
+}
+
+bool t_command_parser_executor::print_transaction(const std::vector<std::string>& args)
+{
+ if (args.empty())
+ {
+ std::cout << "expected: print_tx <transaction hash>" << std::endl;
+ return true;
+ }
+
+ const std::string& str_hash = args.front();
+ crypto::hash tx_hash;
+ if (parse_hash256(str_hash, tx_hash))
+ {
+ m_executor.print_transaction(tx_hash);
+ }
+
+ return true;
+}
+
+bool t_command_parser_executor::print_transaction_pool_long(const std::vector<std::string>& args)
+{
+ if (!args.empty()) return false;
+
+ return m_executor.print_transaction_pool_long();
+}
+
+bool t_command_parser_executor::print_transaction_pool_short(const std::vector<std::string>& args)
+{
+ if (!args.empty()) return false;
+
+ return m_executor.print_transaction_pool_short();
+}
+
+bool t_command_parser_executor::start_mining(const std::vector<std::string>& args)
+{
+ if(!args.size())
+ {
+ std::cout << "Please specify a wallet address to mine for: start_mining <addr> [threads=1]" << std::endl;
+ return true;
+ }
+
+ cryptonote::account_public_address adr;
+ if(!cryptonote::get_account_address_from_str(adr, false, args.front()))
+ {
+ if(!cryptonote::get_account_address_from_str(adr, true, args.front()))
+ {
+ std::cout << "target account address has wrong format" << std::endl;
+ return true;
+ }
+ std::cout << "Mining to a testnet address, make sure this is intentional!" << std::endl;
+ }
+ uint64_t threads_count = 1;
+ if(args.size() > 2)
+ {
+ return false;
+ }
+ else if(args.size() == 2)
+ {
+ bool ok = epee::string_tools::get_xtype_from_string(threads_count, args[1]);
+ threads_count = (ok && 0 < threads_count) ? threads_count : 1;
+ }
+
+ m_executor.start_mining(adr, threads_count);
+
+ return true;
+}
+
+bool t_command_parser_executor::stop_mining(const std::vector<std::string>& args)
+{
+ if (!args.empty()) return false;
+
+ return m_executor.stop_mining();
+}
+
+bool t_command_parser_executor::stop_daemon(const std::vector<std::string>& args)
+{
+ if (!args.empty()) return false;
+
+ return m_executor.stop_daemon();
+}
+
+bool t_command_parser_executor::print_status(const std::vector<std::string>& args)
+{
+ if (!args.empty()) return false;
+
+ return m_executor.print_status();
+}
+
+bool t_command_parser_executor::set_limit(const std::vector<std::string>& args)
+{
+ if(args.size()!=1) return false;
+ int limit;
+ try {
+ limit = std::stoi(args[0]);
+ }
+ catch(std::invalid_argument& ex) {
+ return false;
+ }
+ if (limit==-1) limit=128;
+ limit *= 1024;
+
+ return m_executor.set_limit(limit);
+}
+
+bool t_command_parser_executor::set_limit_up(const std::vector<std::string>& args)
+{
+ if(args.size()!=1) return false;
+ int limit;
+ try {
+ limit = std::stoi(args[0]);
+ }
+ catch(std::invalid_argument& ex) {
+ return false;
+ }
+ if (limit==-1) limit=128;
+ limit *= 1024;
+
+ return m_executor.set_limit_up(limit);
+}
+
+bool t_command_parser_executor::set_limit_down(const std::vector<std::string>& args)
+{
+ if(args.size()!=1) return false;
+ int limit;
+ try {
+ limit = std::stoi(args[0]);
+ }
+ catch(std::invalid_argument& ex) {
+ return false;
+ }
+ if (limit==-1) limit=128;
+ limit *= 1024;
+
+ return m_executor.set_limit_down(limit);
+}
+} // namespace daemonize
diff --git a/src/daemon/command_parser_executor.h b/src/daemon/command_parser_executor.h
new file mode 100644
index 000000000..19ed8ada7
--- /dev/null
+++ b/src/daemon/command_parser_executor.h
@@ -0,0 +1,95 @@
+/**
+@file
+@details
+
+@image html images/other/runtime-commands.png
+
+*/
+
+// Copyright (c) 2014, 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 "daemon/rpc_command_executor.h"
+
+namespace daemonize {
+
+class t_command_parser_executor final
+{
+private:
+ t_rpc_command_executor m_executor;
+public:
+ t_command_parser_executor(
+ uint32_t ip
+ , uint16_t port
+ );
+
+ bool print_peer_list(const std::vector<std::string>& args);
+
+ bool save_blockchain(const std::vector<std::string>& args);
+
+ bool show_hash_rate(const std::vector<std::string>& args);
+
+ bool hide_hash_rate(const std::vector<std::string>& args);
+
+ bool show_difficulty(const std::vector<std::string>& args);
+
+ bool print_connections(const std::vector<std::string>& args);
+
+ bool print_blockchain_info(const std::vector<std::string>& args);
+
+ bool set_log_level(const std::vector<std::string>& args);
+
+ bool print_height(const std::vector<std::string>& args);
+
+ bool print_block(const std::vector<std::string>& args);
+
+ bool print_transaction(const std::vector<std::string>& args);
+
+ bool print_transaction_pool_long(const std::vector<std::string>& args);
+
+ bool print_transaction_pool_short(const std::vector<std::string>& args);
+
+ bool start_mining(const std::vector<std::string>& args);
+
+ bool stop_mining(const std::vector<std::string>& args);
+
+ bool stop_daemon(const std::vector<std::string>& args);
+
+ bool print_status(const std::vector<std::string>& args);
+
+ bool set_limit(const std::vector<std::string>& args);
+
+ bool set_limit_up(const std::vector<std::string>& args);
+
+ bool set_limit_down(const std::vector<std::string>& args);
+
+};
+
+} // namespace daemonize
diff --git a/src/daemon/command_server.cpp b/src/daemon/command_server.cpp
new file mode 100644
index 000000000..ed92fd348
--- /dev/null
+++ b/src/daemon/command_server.cpp
@@ -0,0 +1,179 @@
+// Copyright (c) 2014, 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"
+
+namespace daemonize {
+
+namespace p = std::placeholders;
+
+t_command_server::t_command_server(
+ uint32_t ip
+ , uint16_t port
+ )
+ : m_parser(ip, port)
+ , m_command_lookup()
+{
+ 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_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 <begin_height> [<end_height>]"
+ );
+ 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>"
+ );
+ 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>"
+ );
+ 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=1]"
+ );
+ 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(
+ "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 <level> - Change current log detalization level, <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"
+ );
+ 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(
+ "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 <kB/s> - 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 <kB/s> - Set 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"
+ );
+}
+
+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<std::string>& cmd)
+{
+ return m_command_lookup.process_command_vec(cmd);
+}
+
+bool t_command_server::help(const std::vector<std::string>& args)
+{
+ std::cout << get_commands_str() << std::endl;
+ return true;
+}
+
+std::string t_command_server::get_commands_str()
+{
+ std::stringstream ss;
+ ss << CRYPTONOTE_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
diff --git a/src/daemon/command_server.h b/src/daemon/command_server.h
new file mode 100644
index 000000000..ab2d33a3a
--- /dev/null
+++ b/src/daemon/command_server.h
@@ -0,0 +1,67 @@
+/**
+@file
+@details
+
+
+Passing RPC commands:
+
+@image html images/other/runtime-commands.png
+
+*/
+
+// Copyright (c) 2014, 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 "console_handler.h"
+#include "daemon/command_parser_executor.h"
+
+namespace daemonize {
+
+class t_command_server {
+private:
+ t_command_parser_executor m_parser;
+ epee::command_handler m_command_lookup;
+public:
+ t_command_server(
+ uint32_t ip
+ , uint16_t port
+ );
+
+ bool process_command_str(const std::string& cmd);
+
+ bool process_command_vec(const std::vector<std::string>& cmd);
+
+private:
+ bool help(const std::vector<std::string>& args);
+
+ std::string get_commands_str();
+};
+
+} // namespace daemonize
diff --git a/src/daemon/core.h b/src/daemon/core.h
new file mode 100644
index 000000000..3cea70601
--- /dev/null
+++ b/src/daemon/core.h
@@ -0,0 +1,98 @@
+// Copyright (c) 2014, 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 "cryptonote_core/checkpoints_create.h"
+#include "cryptonote_core/cryptonote_core.h"
+#include "cryptonote_protocol/cryptonote_protocol_handler.h"
+#include "misc_log_ex.h"
+#include <stdexcept>
+#include <boost/program_options.hpp>
+
+namespace daemonize
+{
+
+class t_core final
+{
+public:
+ static void init_options(boost::program_options::options_description & option_spec)
+ {
+ cryptonote::core::init_options(option_spec);
+ cryptonote::miner::init_options(option_spec);
+ }
+private:
+ typedef cryptonote::t_cryptonote_protocol_handler<cryptonote::core> t_protocol_raw;
+ cryptonote::core m_core;
+ // TEMPORARY HACK - Yes, this creates a copy, but otherwise the original
+ // variable map could go out of scope before the run method is called
+ boost::program_options::variables_map const m_vm_HACK;
+public:
+ t_core(
+ boost::program_options::variables_map const & vm
+ )
+ : m_core{nullptr}
+ , m_vm_HACK{vm}
+ {
+ }
+
+ // TODO - get rid of circular dependencies in internals
+ void set_protocol(t_protocol_raw & protocol)
+ {
+ m_core.set_cryptonote_protocol(&protocol);
+ }
+
+ void run()
+ {
+ //initialize core here
+ LOG_PRINT_L0("Initializing core...");
+ if (!m_core.init(m_vm_HACK))
+ {
+ throw std::runtime_error("Failed to initialize core");
+ }
+ LOG_PRINT_L0("Core initialized OK");
+ }
+
+ cryptonote::core & get()
+ {
+ return m_core;
+ }
+
+ ~t_core()
+ {
+ LOG_PRINT_L0("Deinitializing core...");
+ try {
+ m_core.deinit();
+ m_core.set_cryptonote_protocol(nullptr);
+ } catch (...) {
+ LOG_PRINT_L0("Failed to deinitialize core...");
+ }
+ }
+};
+
+}
diff --git a/src/daemon/daemon.cpp b/src/daemon/daemon.cpp
index 9f2ae3167..728b239a0 100644
--- a/src/daemon/daemon.cpp
+++ b/src/daemon/daemon.cpp
@@ -1,21 +1,21 @@
-// Copyright (c) 2014-2015, The Monero Project
-//
+// Copyright (c) 2014, 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
@@ -25,278 +25,120 @@
// 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.
-//
+//
// Parts of this file are originally copyright (c) 2012-2013 The Cryptonote developers
-// node.cpp : Defines the entry point for the console application.
-// Does this file exist?
+#include "daemon/daemon.h"
-
-#include "include_base_utils.h"
+#include "common/util.h"
+#include "daemon/core.h"
+#include "daemon/p2p.h"
+#include "daemon/protocol.h"
+#include "daemon/rpc.h"
+#include "misc_log_ex.h"
#include "version.h"
-
-using namespace epee;
-
#include <boost/program_options.hpp>
+#include <functional>
+#include <memory>
+
+namespace daemonize {
+
+struct t_internals {
+private:
+ t_protocol protocol;
+public:
+ t_core core;
+ t_p2p p2p;
+ t_rpc rpc;
+
+ t_internals(
+ boost::program_options::variables_map const & vm
+ )
+ : 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());
+ }
+};
-#include "crypto/hash.h"
-#include "console_handler.h"
-#include "p2p/net_node.h"
-#include "cryptonote_config.h"
-#include "cryptonote_core/checkpoints_create.h"
-#include "cryptonote_core/checkpoints.h"
-#include "cryptonote_core/cryptonote_core.h"
-#include "rpc/core_rpc_server.h"
-#include "cryptonote_protocol/cryptonote_protocol_handler.h"
-#include "daemon_commands_handler.h"
-#include "version.h"
-
-#if defined(WIN32)
-#include <crtdbg.h>
-#endif
-
-namespace po = boost::program_options;
-
-namespace
+void t_daemon::init_options(boost::program_options::options_description & option_spec)
{
- const command_line::arg_descriptor<std::string> arg_config_file = {"config-file", "Specify configuration file", std::string(CRYPTONOTE_NAME ".conf")};
- const command_line::arg_descriptor<bool> arg_os_version = {"os-version", ""};
- const command_line::arg_descriptor<std::string> arg_log_file = {"log-file", "", ""};
- const command_line::arg_descriptor<int> arg_log_level = {"log-level", "", LOG_LEVEL_0};
- const command_line::arg_descriptor<bool> arg_console = {"no-console", "Disable daemon console commands"};
- const command_line::arg_descriptor<bool> arg_testnet_on = {
- "testnet"
- , "Run on testnet. The wallet must be launched with --testnet flag."
- , false
- };
- const command_line::arg_descriptor<bool> arg_dns_checkpoints = {"enforce-dns-checkpointing", "checkpoints from DNS server will be enforced", false};
+ t_core::init_options(option_spec);
+ t_p2p::init_options(option_spec);
+ t_rpc::init_options(option_spec);
}
-bool command_line_preprocessor(const boost::program_options::variables_map& vm)
-{
- bool exit = false;
- if (command_line::get_arg(vm, command_line::arg_version))
- {
- std::cout << CRYPTONOTE_NAME << " v" << MONERO_VERSION_FULL << ENDL;
- exit = true;
- }
- if (command_line::get_arg(vm, arg_os_version))
- {
- std::cout << "OS: " << tools::get_os_version_string() << ENDL;
- exit = true;
- }
+t_daemon::t_daemon(
+ boost::program_options::variables_map const & vm
+ )
+ : mp_internals{new t_internals{vm}}
+{}
- if (exit)
- {
- return true;
- }
+t_daemon::~t_daemon() = default;
- int new_log_level = command_line::get_arg(vm, arg_log_level);
- if(new_log_level < LOG_LEVEL_MIN || new_log_level > LOG_LEVEL_MAX)
- {
- LOG_PRINT_L0("Wrong log level value: ");
- }
- else if (log_space::get_set_log_detalisation_level(false) != new_log_level)
+// MSVC is brain-dead and can't default this...
+t_daemon::t_daemon(t_daemon && other)
+{
+ if (this != &other)
{
- log_space::get_set_log_detalisation_level(true, new_log_level);
- LOG_PRINT_L0("LOG_LEVEL set to " << new_log_level);
+ mp_internals = std::move(other.mp_internals);
+ other.mp_internals.reset(nullptr);
}
-
- return false;
}
-int main(int argc, char* argv[])
+// or this
+t_daemon & t_daemon::operator=(t_daemon && other)
{
-
- string_tools::set_module_name_and_folder(argv[0]);
-#ifdef WIN32
- _CrtSetDbgFlag ( _CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF );
-#endif
- log_space::get_set_log_detalisation_level(true, LOG_LEVEL_0);
- log_space::log_singletone::add_logger(LOGGER_CONSOLE, NULL, NULL);
- LOG_PRINT_L0("Starting...");
-
- TRY_ENTRY();
-
- boost::filesystem::path default_data_path {tools::get_default_data_dir()};
- boost::filesystem::path default_testnet_data_path {default_data_path / "testnet"};
-
- po::options_description desc_cmd_only("Command line options");
- po::options_description desc_cmd_sett("Command line options and settings options");
-
- command_line::add_arg(desc_cmd_only, command_line::arg_help);
- command_line::add_arg(desc_cmd_only, command_line::arg_version);
- command_line::add_arg(desc_cmd_only, arg_os_version);
- // tools::get_default_data_dir() can't be called during static initialization
- command_line::add_arg(desc_cmd_only, command_line::arg_data_dir, default_data_path.string());
- command_line::add_arg(desc_cmd_only, command_line::arg_testnet_data_dir, default_testnet_data_path.string());
- command_line::add_arg(desc_cmd_only, arg_config_file);
-
- command_line::add_arg(desc_cmd_sett, arg_log_file);
- command_line::add_arg(desc_cmd_sett, arg_log_level);
- command_line::add_arg(desc_cmd_sett, arg_console);
- command_line::add_arg(desc_cmd_sett, arg_testnet_on);
- command_line::add_arg(desc_cmd_sett, arg_dns_checkpoints);
-
- cryptonote::core::init_options(desc_cmd_sett);
- cryptonote::core_rpc_server::init_options(desc_cmd_sett);
- nodetool::node_server<cryptonote::t_cryptonote_protocol_handler<cryptonote::core> >::init_options(desc_cmd_sett);
- cryptonote::miner::init_options(desc_cmd_sett);
-
- po::options_description desc_options("Allowed options");
- desc_options.add(desc_cmd_only).add(desc_cmd_sett);
-
- po::variables_map vm;
- bool r = command_line::handle_error_helper(desc_options, [&]()
- {
- po::store(po::parse_command_line(argc, argv, desc_options), vm);
- po::notify(vm);
-
- return true;
- });
- if (!r)
- return 1;
-
- if (command_line::get_arg(vm, command_line::arg_help))
+ if (this != &other)
{
- std::cout << CRYPTONOTE_NAME << " v" << MONERO_VERSION_FULL << ENDL << ENDL;
- std::cout << desc_options << std::endl;
- return false;
+ mp_internals = std::move(other.mp_internals);
+ other.mp_internals.reset(nullptr);
}
+ return *this;
+}
- bool testnet_mode = command_line::get_arg(vm, arg_testnet_on);
-
- auto data_dir_arg = testnet_mode ? command_line::arg_testnet_data_dir : command_line::arg_data_dir;
-
- std::string data_dir = command_line::get_arg(vm, data_dir_arg);
- tools::create_directories_if_necessary(data_dir);
- std::string config = command_line::get_arg(vm, arg_config_file);
-
- boost::filesystem::path data_dir_path(data_dir);
- boost::filesystem::path config_path(config);
- if (!config_path.has_parent_path())
+bool t_daemon::run()
+{
+ if (nullptr == mp_internals)
{
- config_path = data_dir_path / config_path;
+ throw std::runtime_error{"Can't run stopped daemon"};
}
+ tools::signal_handler::install(std::bind(&daemonize::t_daemon::stop, this));
- boost::system::error_code ec;
- if (boost::filesystem::exists(config_path, ec))
+ try
{
- po::store(po::parse_config_file<char>(config_path.string<std::string>().c_str(), desc_cmd_sett), vm);
+ mp_internals->core.run();
+ mp_internals->rpc.run();
+ mp_internals->p2p.run();
+ mp_internals->rpc.stop();
+ LOG_PRINT("Node stopped.", LOG_LEVEL_0);
+ return true;
}
-
- //set up logging options
- boost::filesystem::path log_file_path(command_line::get_arg(vm, arg_log_file));
- if (log_file_path.empty())
- log_file_path = log_space::log_singletone::get_default_log_file();
- std::string log_dir;
- log_dir = log_file_path.has_parent_path() ? log_file_path.parent_path().string() : log_space::log_singletone::get_default_log_folder();
-
- log_space::log_singletone::add_logger(LOGGER_FILE, log_file_path.filename().string().c_str(), log_dir.c_str());
- LOG_PRINT_L0(CRYPTONOTE_NAME << " v" << MONERO_VERSION_FULL);
-
- if (command_line_preprocessor(vm))
+ catch (std::exception const & ex)
{
- return 0;
+ LOG_ERROR("Uncaught exception! " << ex.what());
+ return false;
}
-
- LOG_PRINT("Module folder: " << argv[0], LOG_LEVEL_0);
-
- bool res = true;
- cryptonote::checkpoints checkpoints;
- res = cryptonote::create_checkpoints(checkpoints);
- CHECK_AND_ASSERT_MES(res, 1, "Failed to initialize checkpoints");
- boost::filesystem::path json(JSON_HASH_FILE_NAME);
- boost::filesystem::path checkpoint_json_hashfile_fullpath = data_dir / json;
-
- //create objects and link them
- cryptonote::core ccore(NULL);
-
- // tell core if we're enforcing dns checkpoints
- bool enforce_dns = command_line::get_arg(vm, arg_dns_checkpoints);
- ccore.set_enforce_dns_checkpoints(enforce_dns);
-
- if (testnet_mode) {
- LOG_PRINT_L0("Starting in testnet mode!");
- } else {
- ccore.set_checkpoints(std::move(checkpoints));
- ccore.set_checkpoints_file_path(checkpoint_json_hashfile_fullpath.string());
+ catch (...)
+ {
+ LOG_ERROR("Uncaught exception!");
+ return false;
}
+}
- cryptonote::t_cryptonote_protocol_handler<cryptonote::core> cprotocol(ccore, NULL);
- nodetool::node_server<cryptonote::t_cryptonote_protocol_handler<cryptonote::core> > p2psrv {
- cprotocol
- , testnet_mode ? std::move(config::testnet::NETWORK_ID) : std::move(config::NETWORK_ID)
- };
- cryptonote::core_rpc_server rpc_server {ccore, p2psrv, testnet_mode};
- cprotocol.set_p2p_endpoint(&p2psrv);
- ccore.set_cryptonote_protocol(&cprotocol);
- daemon_cmmands_handler dch(p2psrv, testnet_mode);
-
- //initialize objects
- LOG_PRINT_L0("Initializing P2P server...");
- res = p2psrv.init(vm, testnet_mode);
- CHECK_AND_ASSERT_MES(res, 1, "Failed to initialize P2P server.");
- LOG_PRINT_L0("P2P server initialized OK");
-
- LOG_PRINT_L0("Initializing protocol...");
- res = cprotocol.init(vm);
- CHECK_AND_ASSERT_MES(res, 1, "Failed to initialize protocol.");
- LOG_PRINT_L0("Protocol initialized OK");
-
- LOG_PRINT_L0("Initializing core RPC server...");
- res = rpc_server.init(vm);
- CHECK_AND_ASSERT_MES(res, 1, "Failed to initialize core RPC server.");
- LOG_PRINT_GREEN("Core RPC server initialized OK on port: " << rpc_server.get_binded_port(), LOG_LEVEL_0);
-
- //initialize core here
- LOG_PRINT_L0("Initializing core...");
- res = ccore.init(vm, testnet_mode);
- CHECK_AND_ASSERT_MES(res, 1, "Failed to initialize core");
- LOG_PRINT_L0("Core initialized OK");
-
- // start components
- if(!command_line::has_arg(vm, arg_console))
+void t_daemon::stop()
+{
+ if (nullptr == mp_internals)
{
- dch.start_handling();
+ throw std::runtime_error{"Can't stop stopped daemon"};
}
-
- LOG_PRINT_L0("Starting core RPC server...");
- res = rpc_server.run(2, false);
- CHECK_AND_ASSERT_MES(res, 1, "Failed to initialize core RPC server.");
- LOG_PRINT_L0("Core RPC server started ok");
-
- tools::signal_handler::install([&dch, &p2psrv] {
- dch.stop_handling();
- p2psrv.send_stop_signal();
- });
-
- LOG_PRINT_L0("Starting P2P net loop...");
- p2psrv.run();
- LOG_PRINT_L0("P2P net loop stopped");
-
- //stop components
- LOG_PRINT_L0("Stopping core rpc server...");
- rpc_server.send_stop_signal();
- rpc_server.timed_wait_server_stop(5000);
-
- //deinitialize components
- LOG_PRINT_L0("Deinitializing core...");
- ccore.deinit();
- LOG_PRINT_L0("Deinitializing RPC server ...");
- rpc_server.deinit();
- LOG_PRINT_L0("Deinitializing protocol...");
- cprotocol.deinit();
- LOG_PRINT_L0("Deinitializing P2P...");
- p2psrv.deinit();
-
-
- ccore.set_cryptonote_protocol(NULL);
- cprotocol.set_p2p_endpoint(NULL);
-
- LOG_PRINT("Node stopped.", LOG_LEVEL_0);
- return 0;
-
- CATCH_ENTRY_L0("main", 1);
+ mp_internals->p2p.stop();
+ mp_internals->rpc.stop();
+ mp_internals.reset(nullptr); // Ensure resources are cleaned up before we return
}
+} // namespace daemonize
diff --git a/src/daemon/daemon.h b/src/daemon/daemon.h
new file mode 100644
index 000000000..5c5c27b6b
--- /dev/null
+++ b/src/daemon/daemon.h
@@ -0,0 +1,54 @@
+// Copyright (c) 2014, 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 <memory>
+#include <boost/program_options.hpp>
+
+namespace daemonize {
+
+class t_internals;
+
+class t_daemon final {
+public:
+ static void init_options(boost::program_options::options_description & option_spec);
+private:
+ std::unique_ptr<t_internals> mp_internals;
+public:
+ t_daemon(
+ boost::program_options::variables_map const & vm
+ );
+ t_daemon(t_daemon && other);
+ t_daemon & operator=(t_daemon && other);
+ ~t_daemon();
+
+ bool run();
+ void stop();
+};
+}
diff --git a/src/daemon/daemon_commands_handler.h b/src/daemon/daemon_commands_handler.h
index 10a07cf89..7416af9c5 100644
--- a/src/daemon/daemon_commands_handler.h
+++ b/src/daemon/daemon_commands_handler.h
@@ -1,35 +1,7 @@
-// Copyright (c) 2014-2015, 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.
-//
-// Parts of this file are originally copyright (c) 2012-2013 The Cryptonote developers
-
-
-/* This isn't a header file, may want to refactor this... */
+// Copyright (c) 2012-2013 The Cryptonote developers
+// Distributed under the MIT/X11 software license, see the accompanying
+// file COPYING or http://www.opensource.org/licenses/mit-license.php.
+
#pragma once
#include <boost/lexical_cast.hpp>
@@ -41,21 +13,18 @@
#include "crypto/hash.h"
#include "version.h"
-/*!
- * \brief I don't really know right now
- *
- *
- */
+//#include "net/net_helper.h"
+//#include "../p2p/p2p_protocol_defs.h"
+//#include "../p2p/net_peerlist_boost_serialization.h"
+//#include "net/local_ip.h"
+//#include "crypto/crypto.h"
+//#include "storages/levin_abstract_invoke2.h"
+
class daemon_cmmands_handler
{
nodetool::node_server<cryptonote::t_cryptonote_protocol_handler<cryptonote::core> >& m_srv;
public:
- daemon_cmmands_handler(
- nodetool::node_server<cryptonote::t_cryptonote_protocol_handler<cryptonote::core> >& srv
- , bool testnet
- )
- : m_srv(srv)
- , m_testnet(testnet)
+ daemon_cmmands_handler(nodetool::node_server<cryptonote::t_cryptonote_protocol_handler<cryptonote::core> >& srv):m_srv(srv)
{
m_cmd_binder.set_handler("help", boost::bind(&daemon_cmmands_handler::help, this, _1), "Show this help");
m_cmd_binder.set_handler("print_pl", boost::bind(&daemon_cmmands_handler::print_pl, this, _1), "Print peer list");
@@ -74,6 +43,10 @@ public:
m_cmd_binder.set_handler("save", boost::bind(&daemon_cmmands_handler::save, this, _1), "Save blockchain");
m_cmd_binder.set_handler("set_log", boost::bind(&daemon_cmmands_handler::set_log, this, _1), "set_log <level> - Change current log detalization level, <level> is a number 0-4");
m_cmd_binder.set_handler("diff", boost::bind(&daemon_cmmands_handler::diff, this, _1), "Show difficulty");
+ m_cmd_binder.set_handler("limit-up", boost::bind(&daemon_cmmands_handler::limit_up, this, _1), "Set upload limit");
+ m_cmd_binder.set_handler("limit-down", boost::bind(&daemon_cmmands_handler::limit_down, this, _1), "Set download limit");
+ m_cmd_binder.set_handler("limit", boost::bind(&daemon_cmmands_handler::limit, this, _1), "Set download and upload limit");
+ m_cmd_binder.set_handler("out_peers", boost::bind(&daemon_cmmands_handler::out_peers_limit, this, _1), "Set max limit of out peers");
}
bool start_handling()
@@ -89,7 +62,7 @@ public:
private:
epee::srv_console_handlers_binder<nodetool::node_server<cryptonote::t_cryptonote_protocol_handler<cryptonote::core> > > m_cmd_binder;
- bool m_testnet;
+
//--------------------------------------------------------------------------------
std::string get_commands_str()
@@ -122,6 +95,122 @@ private:
return true;
}
//--------------------------------------------------------------------------------
+ bool limit_up(const std::vector<std::string>& args)
+ {
+ if(args.size()!=1) {
+ std::cout << "Usage: limit_up <speed>" << ENDL;
+ return false;
+ }
+
+ int limit;
+ try {
+ limit = std::stoi(args[0]);
+ }
+ catch(std::invalid_argument& ex) {
+ return false;
+ }
+
+ if (limit==-1) {
+ limit=128;
+ //this->islimitup=false;
+ }
+
+ limit *= 1024;
+
+
+ //nodetool::epee::net_utils::connection<epee::levin::async_protocol_handler<nodetool::p2p_connection_context> >::set_rate_up_limit( limit );
+ epee::net_utils::connection_basic::set_rate_up_limit( limit );
+ std::cout << "Set limit-up to " << limit/1024 << " kB/s" << std::endl;
+
+ return true;
+ }
+
+ //--------------------------------------------------------------------------------
+ bool limit_down(const std::vector<std::string>& args)
+ {
+
+ if(args.size()!=1) {
+ std::cout << "Usage: limit_down <speed>" << ENDL;
+ return true;
+ }
+
+ int limit;
+ try {
+ limit = std::stoi(args[0]);
+ }
+
+ catch(std::invalid_argument& ex) {
+ return false;
+ }
+
+ if (limit==-1) {
+ limit=128;
+ //this->islimitup=false;
+ }
+
+ limit *= 1024;
+
+
+ //nodetool::epee::net_utils::connection<epee::levin::async_protocol_handler<nodetool::p2p_connection_context> >::set_rate_up_limit( limit );
+ epee::net_utils::connection_basic::set_rate_down_limit( limit );
+ std::cout << "Set limit-down to " << limit/1024 << " kB/s" << std::endl;
+
+ return true;
+ }
+
+//--------------------------------------------------------------------------------
+ bool limit(const std::vector<std::string>& args)
+ {
+ if(args.size()!=1) {
+ std::cout << "Usage: limit_down <speed>" << ENDL;
+ return true;
+ }
+
+ int limit;
+ try {
+ limit = std::stoi(args[0]);
+ }
+ catch(std::invalid_argument& ex) {
+ return false;
+ }
+
+ if (limit==-1) {
+ limit=128;
+ //this->islimitup=false;
+ }
+
+ limit *= 1024;
+
+
+ //nodetool::epee::net_utils::connection<epee::levin::async_protocol_handler<nodetool::p2p_connection_context> >::set_rate_up_limit( limit );
+ epee::net_utils::connection_basic::set_rate_down_limit( limit );
+ epee::net_utils::connection_basic::set_rate_up_limit( limit );
+ std::cout << "Set limit-down to " << limit/1024 << " kB/s" << std::endl;
+ std::cout << "Set limit-up to " << limit/1024 << " kB/s" << std::endl;
+
+ return true;
+ }
+ //--------------------------------------------------------------------------------
+ bool out_peers_limit(const std::vector<std::string>& args) {
+ if(args.size()!=1) {
+ std::cout << "Usage: limit_down <speed>" << ENDL;
+ return true;
+ }
+
+ int limit;
+ try {
+ limit = std::stoi(args[0]);
+ }
+
+ catch(std::invalid_argument& ex) {
+ return false;
+ }
+
+ LOG_PRINT_RED_L0("connections_count: " << limit);
+ m_srv.m_config.m_net_config.connections_count = limit;
+ return true;
+ }
+ //--------------------------------------------------------------------------------
bool show_hr(const std::vector<std::string>& args)
{
if(!m_srv.get_payload_object().get_core().get_miner().is_mining())
@@ -234,7 +323,11 @@ private:
return true;
}
+ // TODO what the hell causes compilation warning in following code line
+PUSH_WARNINGS
+DISABLE_GCC_WARNING(maybe-uninitialized)
log_space::log_singletone::get_set_log_detalisation_level(true, l);
+POP_WARNINGS
return true;
}
@@ -374,7 +467,7 @@ private:
}
cryptonote::account_public_address adr;
- if(!cryptonote::get_account_address_from_str(adr, m_testnet, args.front()))
+ if(!cryptonote::get_account_address_from_str(adr, args.front()))
{
std::cout << "target account address has wrong format" << std::endl;
return true;
diff --git a/src/daemon/executor.cpp b/src/daemon/executor.cpp
new file mode 100644
index 000000000..f4def4d55
--- /dev/null
+++ b/src/daemon/executor.cpp
@@ -0,0 +1,71 @@
+// Copyright (c) 2014, 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 "daemon/executor.h"
+
+#include "misc_log_ex.h"
+
+#include "common/command_line.h"
+#include "cryptonote_config.h"
+#include "version.h"
+
+#include <string>
+
+namespace daemonize
+{
+ std::string const t_executor::NAME = "Monero Daemon";
+
+ void t_executor::init_options(
+ boost::program_options::options_description & configurable_options
+ )
+ {
+ t_daemon::init_options(configurable_options);
+ }
+
+ std::string const & t_executor::name()
+ {
+ return NAME;
+ }
+
+ t_daemon t_executor::create_daemon(
+ boost::program_options::variables_map const & vm
+ )
+ {
+ LOG_PRINT_L0(CRYPTONOTE_NAME << " v" << MONERO_VERSION_FULL);
+ return t_daemon{vm};
+ }
+
+ bool t_executor::run_interactive(
+ boost::program_options::variables_map const & vm
+ )
+ {
+ epee::log_space::log_singletone::add_logger(LOGGER_CONSOLE, NULL, NULL);
+ return t_daemon{vm}.run();
+ }
+}
+
diff --git a/src/daemon/executor.h b/src/daemon/executor.h
new file mode 100644
index 000000000..553896875
--- /dev/null
+++ b/src/daemon/executor.h
@@ -0,0 +1,60 @@
+// Copyright (c) 2014, 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 "daemon/daemon.h"
+#include <boost/program_options/options_description.hpp>
+#include <boost/program_options/variables_map.hpp>
+#include <string>
+#include <vector>
+
+namespace daemonize
+{
+ class t_executor final
+ {
+ public:
+ typedef ::daemonize::t_daemon t_daemon;
+
+ static std::string const NAME;
+
+ static void init_options(
+ boost::program_options::options_description & configurable_options
+ );
+
+ std::string const & name();
+
+ t_daemon create_daemon(
+ boost::program_options::variables_map const & vm
+ );
+
+ bool run_interactive(
+ boost::program_options::variables_map const & vm
+ );
+ };
+}
diff --git a/src/daemon/main.cpp b/src/daemon/main.cpp
new file mode 100644
index 000000000..a2b389292
--- /dev/null
+++ b/src/daemon/main.cpp
@@ -0,0 +1,229 @@
+// Copyright (c) 2014, 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.
+//
+// Parts of this file are originally copyright (c) 2012-2013 The Cryptonote developers
+
+#include "common/command_line.h"
+#include "common/scoped_message_writer.h"
+#include "common/util.h"
+#include "cryptonote_core/cryptonote_core.h"
+#include "cryptonote_core/miner.h"
+#include "daemon/command_server.h"
+#include "daemon/daemon.h"
+#include "daemon/executor.h"
+#include "daemonizer/daemonizer.h"
+#include "misc_log_ex.h"
+#include "p2p/net_node.h"
+#include "rpc/core_rpc_server.h"
+#include <boost/program_options.hpp>
+#include "daemon/command_line_args.h"
+
+namespace po = boost::program_options;
+namespace bf = boost::filesystem;
+
+int main(int argc, char const * argv[])
+{
+ try {
+
+ epee::string_tools::set_module_name_and_folder(argv[0]);
+
+ // Build argument description
+ po::options_description all_options("All");
+ po::options_description hidden_options("Hidden");
+ po::options_description visible_options("Options");
+ po::options_description core_settings("Settings");
+ po::positional_options_description positional_options;
+ {
+ bf::path default_data_dir = daemonizer::get_default_data_dir();
+
+ // Misc Options
+
+ command_line::add_arg(visible_options, command_line::arg_help);
+ command_line::add_arg(visible_options, command_line::arg_version);
+ command_line::add_arg(visible_options, daemon_args::arg_os_version);
+ command_line::add_arg(visible_options, command_line::arg_data_dir, default_data_dir.string());
+ bf::path default_conf = default_data_dir / std::string(CRYPTONOTE_NAME ".conf");
+ command_line::add_arg(visible_options, daemon_args::arg_config_file, default_conf.string());
+
+ // Settings
+ bf::path default_log = default_data_dir / std::string(CRYPTONOTE_NAME ".log");
+ command_line::add_arg(core_settings, daemon_args::arg_log_file, default_log.string());
+ command_line::add_arg(core_settings, daemon_args::arg_log_level);
+ command_line::add_arg(core_settings, daemon_args::arg_testnet_on);
+ command_line::add_arg(core_settings, daemon_args::arg_dns_checkpoints);
+ daemonizer::init_options(hidden_options, visible_options);
+ daemonize::t_executor::init_options(core_settings);
+
+ // Hidden options
+ command_line::add_arg(hidden_options, daemon_args::arg_command);
+
+ visible_options.add(core_settings);
+ all_options.add(visible_options);
+ all_options.add(hidden_options);
+
+ // Positional
+ positional_options.add(daemon_args::arg_command.name, -1); // -1 for unlimited arguments
+ }
+
+ // Do command line parsing
+ po::variables_map vm;
+ bool ok = command_line::handle_error_helper(visible_options, [&]()
+ {
+ boost::program_options::store(
+ boost::program_options::command_line_parser(argc, argv)
+ .options(all_options).positional(positional_options).run()
+ , vm
+ );
+
+ return true;
+ });
+ if (!ok) return 1;
+
+ if (command_line::get_arg(vm, command_line::arg_help))
+ {
+ std::cout << CRYPTONOTE_NAME << " v" << MONERO_VERSION_FULL << ENDL << ENDL;
+ std::cout << "Usage: " + std::string{argv[0]} + " [options|settings] [daemon_command...]" << std::endl << std::endl;
+ std::cout << visible_options << std::endl;
+ return 0;
+ }
+
+ // Monero Version
+ if (command_line::get_arg(vm, command_line::arg_version))
+ {
+ std::cout << CRYPTONOTE_NAME << " v" << MONERO_VERSION_FULL << ENDL;
+ return 0;
+ }
+
+ // OS
+ if (command_line::get_arg(vm, daemon_args::arg_os_version))
+ {
+ std::cout << "OS: " << tools::get_os_version_string() << ENDL;
+ return 0;
+ }
+
+ bool testnet_mode = command_line::get_arg(vm, daemon_args::arg_testnet_on);
+
+ auto data_dir_arg = testnet_mode ? command_line::arg_testnet_data_dir : command_line::arg_data_dir;
+
+ // Create data dir if it doesn't exist
+ boost::filesystem::path data_dir = boost::filesystem::absolute(
+ command_line::get_arg(vm, data_dir_arg));
+ tools::create_directories_if_necessary(data_dir.string());
+
+ // FIXME: not sure on windows implementation default, needs further review
+ //bf::path relative_path_base = daemonizer::get_relative_path_base(vm);
+ bf::path relative_path_base = data_dir;
+
+ std::string config = command_line::get_arg(vm, daemon_args::arg_config_file);
+
+ boost::filesystem::path data_dir_path(data_dir);
+ boost::filesystem::path config_path(config);
+ if (!config_path.has_parent_path())
+ {
+ config_path = data_dir / config_path;
+ }
+
+ boost::system::error_code ec;
+ if (bf::exists(config_path, ec))
+ {
+ po::store(po::parse_config_file<char>(config_path.string<std::string>().c_str(), core_settings), vm);
+ }
+ po::notify(vm);
+
+ // If there are positional options, we're running a daemon command
+ if (command_line::has_arg(vm, daemon_args::arg_command))
+ {
+ auto command = command_line::get_arg(vm, daemon_args::arg_command);
+ auto rpc_ip_str = command_line::get_arg(vm, cryptonote::core_rpc_server::arg_rpc_bind_ip);
+ auto rpc_port_str = command_line::get_arg(vm, cryptonote::core_rpc_server::arg_rpc_bind_port);
+
+ uint32_t rpc_ip;
+ uint16_t rpc_port;
+ if (!epee::string_tools::get_ip_int32_from_string(rpc_ip, rpc_ip_str))
+ {
+ std::cerr << "Invalid IP: " << rpc_ip_str << std::endl;
+ return 1;
+ }
+ if (!epee::string_tools::get_xtype_from_string(rpc_port, rpc_port_str))
+ {
+ std::cerr << "Invalid port: " << rpc_port_str << std::endl;
+ return 1;
+ }
+
+ daemonize::t_command_server rpc_commands{rpc_ip, rpc_port};
+ if (rpc_commands.process_command_vec(command))
+ {
+ return 0;
+ }
+ else
+ {
+ std::cerr << "Unknown command" << std::endl;
+ return 1;
+ }
+ }
+
+ // Start with log level 0
+ epee::log_space::get_set_log_detalisation_level(true, LOG_LEVEL_0);
+
+ // Set log level
+ {
+ int new_log_level = command_line::get_arg(vm, daemon_args::arg_log_level);
+ if(new_log_level < LOG_LEVEL_MIN || new_log_level > LOG_LEVEL_MAX)
+ {
+ LOG_PRINT_L0("Wrong log level value: " << new_log_level);
+ }
+ else if (epee::log_space::get_set_log_detalisation_level(false) != new_log_level)
+ {
+ epee::log_space::get_set_log_detalisation_level(true, new_log_level);
+ LOG_PRINT_L0("LOG_LEVEL set to " << new_log_level);
+ }
+ }
+
+ // Set log file
+ {
+ bf::path log_file_path{bf::absolute(command_line::get_arg(vm, daemon_args::arg_log_file), relative_path_base)};
+
+ epee::log_space::log_singletone::add_logger(
+ LOGGER_FILE
+ , log_file_path.filename().string().c_str()
+ , log_file_path.parent_path().string().c_str()
+ );
+ }
+
+ return daemonizer::daemonize(argc, argv, daemonize::t_executor{}, vm);
+ }
+ catch (std::exception const & ex)
+ {
+ LOG_ERROR("Exception in main! " << ex.what());
+ }
+ catch (...)
+ {
+ LOG_ERROR("Exception in main!");
+ }
+ return 1;
+}
diff --git a/src/daemon/p2p.h b/src/daemon/p2p.h
new file mode 100644
index 000000000..355a784b1
--- /dev/null
+++ b/src/daemon/p2p.h
@@ -0,0 +1,99 @@
+// Copyright (c) 2014, 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.
+//
+// Parts of this file are originally copyright (c) 2012-2013 The Cryptonote developers
+
+#pragma once
+
+#include "cryptonote_protocol/cryptonote_protocol_handler.h"
+#include "daemon/protocol.h"
+#include "misc_log_ex.h"
+#include "p2p/net_node.h"
+#include <stdexcept>
+#include <boost/program_options.hpp>
+
+namespace daemonize
+{
+
+class t_p2p final
+{
+private:
+ typedef cryptonote::t_cryptonote_protocol_handler<cryptonote::core> t_protocol_raw;
+ typedef nodetool::node_server<t_protocol_raw> t_node_server;
+public:
+ static void init_options(boost::program_options::options_description & option_spec)
+ {
+ t_node_server::init_options(option_spec);
+ }
+private:
+ t_node_server m_server;
+public:
+ t_p2p(
+ boost::program_options::variables_map const & vm
+ , t_protocol & protocol
+ )
+ : m_server{protocol.get()}
+ {
+ //initialize objects
+ LOG_PRINT_L0("Initializing p2p server...");
+ if (!m_server.init(vm))
+ {
+ throw std::runtime_error("Failed to initialize p2p server.");
+ }
+ LOG_PRINT_L0("P2p server initialized OK");
+ }
+
+ t_node_server & get()
+ {
+ return m_server;
+ }
+
+ void run()
+ {
+ LOG_PRINT_L0("Starting p2p net loop...");
+ m_server.run();
+ LOG_PRINT_L0("p2p net loop stopped");
+ }
+
+ void stop()
+ {
+ m_server.send_stop_signal();
+ }
+
+ ~t_p2p()
+ {
+ LOG_PRINT_L0("Deinitializing p2p...");
+ try {
+ m_server.deinit();
+ } catch (...) {
+ LOG_PRINT_L0("Failed to deinitialize p2p...");
+ }
+ }
+};
+
+}
diff --git a/src/daemon/protocol.h b/src/daemon/protocol.h
new file mode 100644
index 000000000..2f6a66f49
--- /dev/null
+++ b/src/daemon/protocol.h
@@ -0,0 +1,88 @@
+// Copyright (c) 2014, 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.
+//
+// Parts of this file are originally copyright (c) 2012-2013 The Cryptonote developers
+
+#pragma once
+
+#include "cryptonote_protocol/cryptonote_protocol_handler.h"
+#include "misc_log_ex.h"
+#include "p2p/net_node.h"
+#include <stdexcept>
+#include <boost/program_options.hpp>
+
+namespace daemonize
+{
+
+class t_protocol final
+{
+private:
+ typedef cryptonote::t_cryptonote_protocol_handler<cryptonote::core> t_protocol_raw;
+ typedef nodetool::node_server<t_protocol_raw> t_node_server;
+
+ t_protocol_raw m_protocol;
+public:
+ t_protocol(
+ boost::program_options::variables_map const & vm
+ , t_core & core
+ )
+ : m_protocol{core.get(), nullptr}
+ {
+ LOG_PRINT_L0("Initializing cryptonote protocol...");
+ if (!m_protocol.init(vm))
+ {
+ throw std::runtime_error("Failed to initialize cryptonote protocol.");
+ }
+ LOG_PRINT_L0("Cryptonote protocol initialized OK");
+ }
+
+ t_protocol_raw & get()
+ {
+ return m_protocol;
+ }
+
+ void set_p2p_endpoint(
+ t_node_server & server
+ )
+ {
+ m_protocol.set_p2p_endpoint(&server);
+ }
+
+ ~t_protocol()
+ {
+ LOG_PRINT_L0("Deinitializing cryptonote_protocol...");
+ try {
+ m_protocol.deinit();
+ m_protocol.set_p2p_endpoint(nullptr);
+ } catch (...) {
+ LOG_PRINT_L0("Failed to deinitialize protocol...");
+ }
+ }
+};
+
+}
diff --git a/src/daemon/rpc.h b/src/daemon/rpc.h
new file mode 100644
index 000000000..cf7da51a7
--- /dev/null
+++ b/src/daemon/rpc.h
@@ -0,0 +1,96 @@
+// Copyright (c) 2014, 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.
+//
+// Parts of this file are originally copyright (c) 2012-2013 The Cryptonote developers
+
+#pragma once
+
+#include "daemon/core.h"
+#include "daemon/p2p.h"
+#include "misc_log_ex.h"
+#include "rpc/core_rpc_server.h"
+#include <boost/program_options.hpp>
+#include <stdexcept>
+
+namespace daemonize
+{
+
+class t_rpc final
+{
+public:
+ static void init_options(boost::program_options::options_description & option_spec)
+ {
+ cryptonote::core_rpc_server::init_options(option_spec);
+ }
+private:
+ cryptonote::core_rpc_server m_server;
+public:
+ t_rpc(
+ boost::program_options::variables_map const & vm
+ , t_core & core
+ , t_p2p & p2p
+ )
+ : m_server{core.get(), p2p.get()}
+ {
+ LOG_PRINT_L0("Initializing core rpc server...");
+ if (!m_server.init(vm))
+ {
+ throw std::runtime_error("Failed to initialize core rpc server.");
+ }
+ LOG_PRINT_GREEN("Core rpc server initialized OK on port: " << m_server.get_binded_port(), LOG_LEVEL_0);
+ }
+
+ void run()
+ {
+ LOG_PRINT_L0("Starting core rpc server...");
+ if (!m_server.run(2, false))
+ {
+ throw std::runtime_error("Failed to start core rpc server.");
+ }
+ LOG_PRINT_L0("Core rpc server started ok");
+ }
+
+ void stop()
+ {
+ LOG_PRINT_L0("Stopping core rpc server...");
+ m_server.send_stop_signal();
+ m_server.timed_wait_server_stop(5000);
+ }
+
+ ~t_rpc()
+ {
+ LOG_PRINT_L0("Deinitializing rpc server...");
+ try {
+ m_server.deinit();
+ } catch (...) {
+ LOG_PRINT_L0("Failed to deinitialize rpc server...");
+ }
+ }
+};
+
+}
diff --git a/src/daemon/rpc_command_executor.cpp b/src/daemon/rpc_command_executor.cpp
new file mode 100644
index 000000000..bdad28f6c
--- /dev/null
+++ b/src/daemon/rpc_command_executor.cpp
@@ -0,0 +1,435 @@
+// Copyright (c) 2014, 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.
+//
+// Parts of this file are originally copyright (c) 2012-2013 The Cryptonote developers
+
+#include "string_tools.h"
+#include "common/scoped_message_writer.h"
+#include "daemon/rpc_command_executor.h"
+#include "rpc/core_rpc_server_commands_defs.h"
+#include <boost/format.hpp>
+#include <ctime>
+
+namespace daemonize {
+
+namespace {
+ /*
+ void print_peer(std::string const & prefix, cryptonote::peer const & peer)
+ {
+ time_t now;
+ time(&now);
+ time_t last_seen = static_cast<time_t>(peer.last_seen);
+
+ std::string id_str;
+ std::string port_str;
+ std::string elapsed = epee::misc_utils::get_time_interval_string(now - last_seen);
+ std::string ip_str = epee::string_tools::get_ip_string_from_int32(peer.ip);
+ epee::string_tools::xtype_to_string(peer.id, id_str);
+ epee::string_tools::xtype_to_string(peer.port, port_str);
+ std::string addr_str = ip_str + ":" + port_str;
+ tools::msg_writer() << boost::format("%-10s %-25s %-25s %s") % prefix % id_str % addr_str % elapsed;
+ }
+ */
+
+ void print_block_header(cryptonote::block_header_responce const & header)
+ {
+ tools::success_msg_writer()
+ << "timestamp: " << boost::lexical_cast<std::string>(header.timestamp) << std::endl
+ << "previous hash: " << header.prev_hash << std::endl
+ << "nonce: " << boost::lexical_cast<std::string>(header.nonce) << std::endl
+ << "is orphan: " << header.orphan_status << std::endl
+ << "height: " << boost::lexical_cast<std::string>(header.height) << std::endl
+ << "depth: " << boost::lexical_cast<std::string>(header.depth) << std::endl
+ << "hash: " << header.hash
+ << "difficulty: " << boost::lexical_cast<std::string>(header.difficulty) << std::endl
+ << "reward: " << boost::lexical_cast<std::string>(header.reward);
+ }
+}
+
+t_rpc_command_executor::t_rpc_command_executor(
+ uint32_t ip
+ , uint16_t port
+ )
+ : m_rpc_client{ip, port}
+{}
+
+bool t_rpc_command_executor::print_peer_list() {
+/*
+ cryptonote::COMMAND_RPC_GET_PEER_LIST::request req;
+ cryptonote::COMMAND_RPC_GET_PEER_LIST::response res;
+
+ bool ok = m_rpc_client.rpc_request(req, res, "/get_peer_list", "Couldn't retrieve peer list");
+
+ if (!ok) return false;
+
+ for (auto & peer : res.white_list)
+ {
+ print_peer("white", peer);
+ }
+
+ for (auto & peer : res.gray_list)
+ {
+ print_peer("gray", peer);
+ }
+
+*/
+ return true;
+}
+
+bool t_rpc_command_executor::save_blockchain() {
+ cryptonote::COMMAND_RPC_SAVE_BC::request req;
+ cryptonote::COMMAND_RPC_SAVE_BC::response res;
+
+ if (m_rpc_client.rpc_request(req, res, "/save_bc", "Couldn't save blockchain"))
+ {
+ tools::success_msg_writer() << "Blockchain saved";
+ }
+
+ return true;
+}
+
+bool t_rpc_command_executor::show_hash_rate() {
+/*
+ cryptonote::COMMAND_RPC_SET_LOG_HASH_RATE::request req;
+ cryptonote::COMMAND_RPC_SET_LOG_HASH_RATE::response res;
+ req.visible = true;
+
+ if (m_rpc_client.rpc_request(req, res, "/set_log_hash_rate", "Unsuccessful"))
+ {
+ tools::success_msg_writer() << "Hash rate logging is on";
+ }
+
+*/
+ return true;
+}
+
+bool t_rpc_command_executor::hide_hash_rate() {
+/*
+ cryptonote::COMMAND_RPC_SET_LOG_HASH_RATE::request req;
+ cryptonote::COMMAND_RPC_SET_LOG_HASH_RATE::response res;
+ req.visible = false;
+
+ if (m_rpc_client.rpc_request(req, res, "/set_log_hash_rate", "Unsuccessful"))
+ {
+ tools::success_msg_writer() << "Hash rate logging is off";
+ }
+
+*/
+ return true;
+}
+
+bool t_rpc_command_executor::show_difficulty() {
+ cryptonote::COMMAND_RPC_GET_INFO::request req;
+ cryptonote::COMMAND_RPC_GET_INFO::response res;
+
+ if (m_rpc_client.rpc_request(req, res, "/getinfo", "Problem fetching info"))
+ {
+ tools::success_msg_writer() << "BH: " << res.height
+ << ", DIFF: " << res.difficulty
+ << ", HR: " << (int) res.difficulty / 60L << " H/s";
+ }
+
+ return true;
+}
+
+bool t_rpc_command_executor::print_connections() {
+ cryptonote::COMMAND_RPC_GET_CONNECTIONS::request req;
+ cryptonote::COMMAND_RPC_GET_CONNECTIONS::response res;
+
+ if (m_rpc_client.rpc_request(req, res, "/get_connections", "Unsuccessful"))
+ {
+ for (auto & info : res.connections)
+ {
+ std::string address = info.ip + ":" + info.port;
+ std::string in_out = info.incoming ? "INC" : "OUT";
+ tools::msg_writer() << boost::format("%-25s peer_id: %-25s %s") % address % info.peer_id % in_out;
+ }
+ }
+
+ return true;
+}
+
+bool t_rpc_command_executor::print_blockchain_info(uint64_t start_block_index, uint64_t end_block_index) {
+/*
+ cryptonote::COMMAND_RPC_GET_BLOCK_HEADERS_RANGE::request req;
+ cryptonote::COMMAND_RPC_GET_BLOCK_HEADERS_RANGE::response res;
+
+ req.start_height = start_block_index;
+ req.end_height = end_block_index;
+
+ if (m_rpc_client.json_rpc_request(req, res, "getblockheadersrange", "Unsuccessful"))
+ {
+ for (auto & header : res.headers)
+ {
+ std::cout << "height " << header.height
+ << ", timestamp " << header.timestamp
+ << ", cumul_dif " << header.cumulative_difficulty
+ << ", cumul_size " << header.cumulative_size << std::endl
+ << "id " << header.hash << std::endl
+ << "difficulty " << header.difficulty
+ << ", nonce " << header.nonce
+ << ", tx_count " << header.tx_count << std::endl;
+ }
+ }
+
+*/
+ return true;
+}
+
+bool t_rpc_command_executor::set_log_level(int8_t level) {
+/*
+ cryptonote::COMMAND_RPC_SET_LOG_LEVEL::request req;
+ cryptonote::COMMAND_RPC_SET_LOG_LEVEL::response res;
+ req.level = level;
+
+ if (m_rpc_client.rpc_request(req, res, "/set_log_level", "Unsuccessful"))
+ {
+ tools::success_msg_writer() << "Log level is now " << boost::lexical_cast<std::string>(level);
+ }
+
+*/
+ return true;
+}
+
+bool t_rpc_command_executor::print_height() {
+ cryptonote::COMMAND_RPC_GET_HEIGHT::request req;
+ cryptonote::COMMAND_RPC_GET_HEIGHT::response res;
+
+ if (m_rpc_client.rpc_request(req, res, "/getheight", "Unsuccessful"))
+ {
+ tools::success_msg_writer() << boost::lexical_cast<std::string>(res.height);
+ }
+
+ return true;
+}
+
+bool t_rpc_command_executor::print_block_by_hash(crypto::hash block_hash) {
+ cryptonote::COMMAND_RPC_GET_BLOCK_HEADER_BY_HASH::request req;
+ cryptonote::COMMAND_RPC_GET_BLOCK_HEADER_BY_HASH::response res;
+
+ req.hash = epee::string_tools::pod_to_hex(block_hash);
+
+ if (m_rpc_client.json_rpc_request(req, res, "getblockheaderbyhash", "Unsuccessful"))
+ {
+ print_block_header(res.block_header);
+ }
+
+ return true;
+}
+
+bool t_rpc_command_executor::print_block_by_height(uint64_t height) {
+ cryptonote::COMMAND_RPC_GET_BLOCK_HEADER_BY_HEIGHT::request req;
+ cryptonote::COMMAND_RPC_GET_BLOCK_HEADER_BY_HEIGHT::response res;
+
+ req.height = height;
+
+ if (m_rpc_client.json_rpc_request(req, res, "getblockheaderbyheight", "Unsuccessful"))
+ {
+ print_block_header(res.block_header);
+ }
+
+ return true;
+}
+
+bool t_rpc_command_executor::print_transaction(crypto::hash transaction_hash) {
+ cryptonote::COMMAND_RPC_GET_TRANSACTIONS::request req;
+ cryptonote::COMMAND_RPC_GET_TRANSACTIONS::response res;
+
+ if (m_rpc_client.rpc_request(req, res, "/gettransactions", "Problem fetching transaction"))
+ {
+ if (1 == res.txs_as_hex.size())
+ {
+ tools::success_msg_writer() << res.txs_as_hex.front();
+ }
+ else
+ {
+ tools::fail_msg_writer() << "transaction wasn't found: <" << transaction_hash << '>' << std::endl;
+ }
+ }
+
+ return true;
+}
+
+bool t_rpc_command_executor::print_transaction_pool_long() {
+/*
+ cryptonote::COMMAND_RPC_GET_TRANSACTION_POOL::request req;
+ cryptonote::COMMAND_RPC_GET_TRANSACTION_POOL::response res;
+
+ if (m_rpc_client.rpc_request(req, res, "/get_transaction_pool", "Problem fetching transaction pool"))
+ {
+ if (res.transactions.empty())
+ {
+ tools::msg_writer() << "Pool is empty" << std::endl;
+ }
+ for (auto & tx_info : res.transactions)
+ {
+ tools::msg_writer() << "id: " << tx_info.id_hash << std::endl
+ << "blob_size: " << tx_info.blob_size << std::endl
+ << "fee: " << tx_info.fee << std::endl
+ << "kept_by_block: " << tx_info.kept_by_block << std::endl
+ << "max_used_block_height: " << tx_info.max_used_block_height << std::endl
+ << "max_used_block_id: " << tx_info.max_used_block_id_hash << std::endl
+ << "last_failed_height: " << tx_info.last_failed_height << std::endl
+ << "last_failed_id: " << tx_info.last_failed_id_hash << std::endl;
+ }
+ }
+
+*/
+ return true;
+}
+
+bool t_rpc_command_executor::print_transaction_pool_short() {
+/*
+ cryptonote::COMMAND_RPC_GET_TRANSACTION_POOL::request req;
+ cryptonote::COMMAND_RPC_GET_TRANSACTION_POOL::response res;
+
+ if (m_rpc_client.rpc_request(req, res, "/get_transaction_pool", "Problem fetching transaction pool"))
+ {
+ for (auto & tx_info : res.transactions)
+ {
+ if (res.transactions.empty())
+ {
+ tools::msg_writer() << "Pool is empty" << std::endl;
+ }
+ tools::msg_writer() << "id: " << tx_info.id_hash << std::endl
+ << tx_info.tx_json << std::endl
+ << "blob_size: " << tx_info.blob_size << std::endl
+ << "fee: " << tx_info.fee << std::endl
+ << "kept_by_block: " << tx_info.kept_by_block << std::endl
+ << "max_used_block_height: " << tx_info.max_used_block_height << std::endl
+ << "max_used_block_id: " << tx_info.max_used_block_id_hash << std::endl
+ << "last_failed_height: " << tx_info.last_failed_height << std::endl
+ << "last_failed_id: " << tx_info.last_failed_id_hash << std::endl;
+ }
+ }
+
+*/
+ return true;
+}
+
+// TODO: update this for testnet
+bool t_rpc_command_executor::start_mining(cryptonote::account_public_address address, uint64_t num_threads) {
+ cryptonote::COMMAND_RPC_START_MINING::request req;
+ cryptonote::COMMAND_RPC_START_MINING::response res;
+ req.miner_address = cryptonote::get_account_address_as_str(false, address);
+ req.threads_count = num_threads;
+
+ if (m_rpc_client.rpc_request(req, res, "/start_mining", "Mining did not start"))
+ {
+ tools::success_msg_writer() << "Mining started";
+ }
+ return true;
+}
+
+bool t_rpc_command_executor::stop_mining() {
+ cryptonote::COMMAND_RPC_STOP_MINING::request req;
+ cryptonote::COMMAND_RPC_STOP_MINING::response res;
+
+ if (m_rpc_client.rpc_request(req, res, "/stop_mining", "Mining did not stop"))
+ {
+ tools::success_msg_writer() << "Mining stopped";
+ }
+ return true;
+}
+
+bool t_rpc_command_executor::stop_daemon()
+{
+/*
+ cryptonote::COMMAND_RPC_STOP_DAEMON::request req;
+ cryptonote::COMMAND_RPC_STOP_DAEMON::response res;
+
+//# ifdef WIN32
+// // Stop via service API
+// // TODO - this is only temporary! Get rid of hard-coded constants!
+// bool ok = windows::stop_service("BitMonero Daemon");
+// ok = windows::uninstall_service("BitMonero Daemon");
+// //bool ok = windows::stop_service(SERVICE_NAME);
+// //ok = windows::uninstall_service(SERVICE_NAME);
+// if (ok)
+// {
+// return true;
+// }
+//# endif
+
+ // Stop via RPC
+ if(m_rpc_client.rpc_request(req, res, "/stop_daemon", "Daemon did not stop"))
+ {
+ tools::success_msg_writer() << "Stop signal sent";
+ }
+*/
+
+ return true;
+}
+
+bool t_rpc_command_executor::print_status()
+{
+ bool daemon_is_alive = m_rpc_client.check_connection();
+
+ if(daemon_is_alive) {
+ tools::success_msg_writer() << "bitmonerod is running";
+ }
+ else {
+ tools::fail_msg_writer() << "bitmonerod is NOT running";
+ }
+
+ return true;
+}
+
+bool t_rpc_command_executor::set_limit(int limit)
+{
+/*
+ epee::net_utils::connection_basic::set_rate_down_limit( limit );
+ epee::net_utils::connection_basic::set_rate_up_limit( limit );
+ std::cout << "Set limit-down to " << limit/1024 << " kB/s" << std::endl;
+ std::cout << "Set limit-up to " << limit/1024 << " kB/s" << std::endl;
+*/
+
+ return true;
+}
+
+bool t_rpc_command_executor::set_limit_up(int limit)
+{
+/*
+ epee::net_utils::connection_basic::set_rate_up_limit( limit );
+ std::cout << "Set limit-up to " << limit/1024 << " kB/s" << std::endl;
+*/
+
+ return true;
+}
+
+bool t_rpc_command_executor::set_limit_down(int limit)
+{
+/*
+ epee::net_utils::connection_basic::set_rate_down_limit( limit );
+ std::cout << "Set limit-down to " << limit/1024 << " kB/s" << std::endl;
+*/
+
+ return true;
+}
+
+}// namespace daemonize
diff --git a/src/daemon/rpc_command_executor.h b/src/daemon/rpc_command_executor.h
new file mode 100644
index 000000000..f1dc9cc76
--- /dev/null
+++ b/src/daemon/rpc_command_executor.h
@@ -0,0 +1,103 @@
+/**
+@file
+@details
+
+@image html images/other/runtime-commands.png
+
+*/
+
+// Copyright (c) 2014, 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.
+//
+// Parts of this file are originally copyright (c) 2012-2013 The Cryptonote developers
+
+#pragma once
+
+#include "common/rpc_client.h"
+#include "misc_log_ex.h"
+#include "cryptonote_core/cryptonote_core.h"
+#include "cryptonote_protocol/cryptonote_protocol_handler.h"
+#include "p2p/net_node.h"
+
+namespace daemonize {
+
+class t_rpc_command_executor final {
+private:
+ tools::t_rpc_client m_rpc_client;
+public:
+ t_rpc_command_executor(
+ uint32_t ip
+ , uint16_t port
+ );
+
+ bool print_peer_list();
+
+ bool save_blockchain();
+
+ bool show_hash_rate();
+
+ bool hide_hash_rate();
+
+ bool show_difficulty();
+
+ bool print_connections();
+
+ bool print_blockchain_info(uint64_t start_block_index, uint64_t end_block_index);
+
+ bool set_log_level(int8_t level);
+
+ bool print_height();
+
+ bool print_block_by_hash(crypto::hash block_hash);
+
+ bool print_block_by_height(uint64_t height);
+
+ bool print_transaction(crypto::hash transaction_hash);
+
+ bool print_transaction_pool_long();
+
+ bool print_transaction_pool_short();
+
+ bool start_mining(cryptonote::account_public_address address, uint64_t num_threads);
+
+ bool stop_mining();
+
+ bool stop_daemon();
+
+ bool print_status();
+
+ bool set_limit(int limit);
+
+ bool set_limit_up(int limit);
+
+ bool set_limit_down(int limit);
+
+
+};
+
+} // namespace daemonize