From 5ce4256e3d6ff2e1595750e3875865089e20a03b Mon Sep 17 00:00:00 2001 From: rfree2monero Date: Thu, 12 Feb 2015 20:59:39 +0100 Subject: 2014 network limit 1.1 +utils +toc -doc -drmonero Update of the PR with network limits works very well for all speeds (but remember that low download speed can stop upload because we then slow down downloading of blockchain requests too) more debug options fixed pedantic warnings in our code should work again on Mac OS X and FreeBSD fixed warning about size_t tested on Debian, Ubuntu, Windows(testing now) TCP options and ToS (QoS) flag FIXED peer number limit FIXED some spikes in ingress/download FIXED problems when other up and down limit --- src/daemon/daemon.cpp | 36 ++++++++++++++++++++++++------------ 1 file changed, 24 insertions(+), 12 deletions(-) (limited to 'src/daemon/daemon.cpp') diff --git a/src/daemon/daemon.cpp b/src/daemon/daemon.cpp index 9f2ae3167..27a1129dc 100644 --- a/src/daemon/daemon.cpp +++ b/src/daemon/daemon.cpp @@ -69,7 +69,9 @@ namespace , "Run on testnet. The wallet must be launched with --testnet flag." , false }; - const command_line::arg_descriptor arg_dns_checkpoints = {"enforce-dns-checkpointing", "checkpoints from DNS server will be enforced", false}; + const command_line::arg_descriptor arg_dns_checkpoints = {"enforce-dns-checkpointing", "checkpoints from DNS server will be enforced", false}; + const command_line::arg_descriptor arg_test_drop_download = {"test-drop-download", "For network testing, drop downloaded blocks instead checking/adding them to blockchain. Can fake-download blocks very fast."}; + const command_line::arg_descriptor arg_save_graph = {"save-graph", "Save data for dr monero", false}; } bool command_line_preprocessor(const boost::program_options::variables_map& vm) @@ -99,6 +101,8 @@ bool command_line_preprocessor(const boost::program_options::variables_map& vm) else if (log_space::get_set_log_detalisation_level(false) != new_log_level) { log_space::get_set_log_detalisation_level(true, new_log_level); + int otshell_utils_log_level = 100 - (new_log_level * 25); + gCurrentLogger.setDebugLevel(otshell_utils_log_level); LOG_PRINT_L0("LOG_LEVEL set to " << new_log_level); } @@ -107,7 +111,7 @@ bool command_line_preprocessor(const boost::program_options::variables_map& vm) int main(int argc, char* argv[]) { - + string_tools::set_module_name_and_folder(argv[0]); #ifdef WIN32 _CrtSetDbgFlag ( _CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF ); @@ -137,6 +141,8 @@ int main(int argc, char* argv[]) 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); + command_line::add_arg(desc_cmd_sett, arg_test_drop_download); + command_line::add_arg(desc_cmd_sett, arg_save_graph); cryptonote::core::init_options(desc_cmd_sett); cryptonote::core_rpc_server::init_options(desc_cmd_sett); @@ -231,7 +237,17 @@ int main(int argc, char* argv[]) 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); + std::shared_ptr dch(new daemon_cmmands_handler(p2psrv, testnet_mode)); + if(command_line::has_arg(vm, arg_save_graph)) + p2psrv.set_save_graph(true); + + //initialize core here + LOG_PRINT_L0("Initializing core..."); + res = ccore.init(vm, testnet_mode); + CHECK_AND_ASSERT_MES(res, 1, "Failed to initialize core"); + if (command_line::get_arg(vm, arg_test_drop_download)) + ccore.no_check_blocks(); + LOG_PRINT_L0("Core initialized OK"); //initialize objects LOG_PRINT_L0("Initializing P2P server..."); @@ -248,17 +264,11 @@ int main(int argc, char* argv[]) 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)) { - dch.start_handling(); + dch->start_handling(); } LOG_PRINT_L0("Starting core RPC server..."); @@ -267,7 +277,7 @@ int main(int argc, char* argv[]) LOG_PRINT_L0("Core RPC server started ok"); tools::signal_handler::install([&dch, &p2psrv] { - dch.stop_handling(); + dch->stop_handling(); p2psrv.send_stop_signal(); }); @@ -276,6 +286,8 @@ int main(int argc, char* argv[]) LOG_PRINT_L0("P2P net loop stopped"); //stop components + dch->stop_handling(); + dch.reset(); LOG_PRINT_L0("Stopping core rpc server..."); rpc_server.send_stop_signal(); rpc_server.timed_wait_server_stop(5000); -- cgit v1.2.3 From ae2a50659f7dc74a5446a0dc3a5f8f78563b9e1f Mon Sep 17 00:00:00 2001 From: rfree2monero Date: Fri, 20 Feb 2015 22:28:03 +0100 Subject: 2014 network limit 1.2 +utils +toc -doc -drmonero new update of the pr with network limits more debug options: discarding downloaded blocks all or after given height. trying to trigger the locking errors. debug levels polished/tuned to sane values. debug/logging improved. warning: this pr should be correct code, but it could make an existing (in master version) locking error appear more often. it's a race on the list (map) of peers, e.g. between closing/deleting them versus working on them in net-limit sleep in sending chunk. the bug is not in this code/this pr, but in the master version. the locking problem of master will be fixed in other pr. problem is ub, and in practice is seems to usually cause program abort (tested on debian stable with updated gcc). see --help for option to add sleep to trigger the error faster. --- contrib/epee/include/net/abstract_tcp_server2.inl | 21 ++-- contrib/epee/include/syncobj.h | 12 ++- contrib/otshell_utils/lib_common1.hpp | 1 + contrib/otshell_utils/utils.cpp | 17 ++- contrib/otshell_utils/utils.hpp | 57 ++++++++-- src/connectivity_tool/conn_tool.cpp | 2 + src/cryptonote_core/blockchain_storage.cpp | 19 +--- src/cryptonote_core/blockchain_storage.h | 1 - src/cryptonote_core/cryptonote_core.cpp | 24 ++++- src/cryptonote_core/cryptonote_core.h | 10 +- .../cryptonote_protocol_handler-base.cpp | 2 +- .../cryptonote_protocol_handler.h | 3 + .../cryptonote_protocol_handler.inl | 118 ++++++++++----------- src/daemon/daemon.cpp | 25 +++-- src/daemon/daemon_commands_handler.h | 20 ++-- src/miner/simpleminer.cpp | 1 + src/p2p/connection_basic.cpp | 15 +-- src/p2p/data_logger.cpp | 36 +++++-- src/p2p/data_logger.hpp | 3 + src/p2p/net_node.h | 4 +- src/p2p/net_node.inl | 45 +++----- src/p2p/network_throttle-detail.cpp | 4 +- src/simplewallet/simplewallet.cpp | 1 + 23 files changed, 257 insertions(+), 184 deletions(-) (limited to 'src/daemon/daemon.cpp') diff --git a/contrib/epee/include/net/abstract_tcp_server2.inl b/contrib/epee/include/net/abstract_tcp_server2.inl index 3dff6da56..31836fe9e 100644 --- a/contrib/epee/include/net/abstract_tcp_server2.inl +++ b/contrib/epee/include/net/abstract_tcp_server2.inl @@ -198,8 +198,9 @@ PRAGMA_WARNING_DISABLE_VS(4355) bool connection::add_ref() { TRY_ENTRY(); - //_info("[sock " << socket_.native_handle() << "] add_ref"); + //_dbg3("[sock " << socket_.native_handle() << "] add_ref, m_peer_number=" << mI->m_peer_number); CRITICAL_REGION_LOCAL(m_self_refs_lock); + //_dbg3("[sock " << socket_.native_handle() << "] add_ref 2, m_peer_number=" << mI->m_peer_number); // Use safe_shared_from_this, because of this is public method and it can be called on the object being deleted auto self = safe_shared_from_this(); @@ -364,8 +365,7 @@ PRAGMA_WARNING_DISABLE_VS(4355) { // LOCK: chunking epee::critical_region_t send_guard(m_chunking_lock); // *** critical *** - _mark_c("net/out/size", "do_send() will SPLIT into small chunks, from packet="< mutex_guard( nOT::nUtils::gLoggerGuard ); \ + part=1; \ + try { \ + ++nOT::nUtils::gLoggerGuardDepth_Get(); \ + std::ostringstream oss; \ + oss << nOT::nUtils::get_current_time() << ' ' << OT_CODE_STAMP << ' ' << VAR << gCurrentLogger.endline() << std::flush; \ + std::string as_string = oss.str(); \ +/* int counter = nOT::nUtils::gLoggerGuardDepth_Get(); if (counter!=1) gCurrentLogger.write_stream(100,"")<<"DEBUG-ERROR: recursion, counter="< arg_ip = {"ip", "set ip"}; diff --git a/src/cryptonote_core/blockchain_storage.cpp b/src/cryptonote_core/blockchain_storage.cpp index fe80d75ac..4e669daa5 100644 --- a/src/cryptonote_core/blockchain_storage.cpp +++ b/src/cryptonote_core/blockchain_storage.cpp @@ -50,6 +50,7 @@ #include "cryptonote_core/checkpoints_create.h" //#include "serialization/json_archive.h" #include "../../contrib/otshell_utils/utils.hpp" +#include "../../src/p2p/data_logger.hpp" using namespace cryptonote; @@ -178,22 +179,6 @@ bool blockchain_storage::store_genesis_block(bool testnet) { return true; } //------------------------------------------------------------------ -void blockchain_storage::logger_handle(long int ms) -{ - std::ofstream log_file; - log_file.open("log/dr-monero/blockchain_log.data", std::ofstream::out | std::ofstream::app); - log_file.precision(7); - - using namespace boost::chrono; - auto point = steady_clock::now(); - auto time_from_epoh = point.time_since_epoch(); - auto m_ms = duration_cast< milliseconds >( time_from_epoh ).count(); - double ms_f = m_ms; - ms_f /= 1000.; - - log_file << ms_f << " " << ms << std::endl; -} -//------------------------------------------------------------------ bool blockchain_storage::store_blockchain() { m_is_blockchain_storing = true; @@ -1776,7 +1761,7 @@ bool blockchain_storage::handle_block_to_main_chain(const block& bl, const crypt << "), coinbase_blob_size: " << coinbase_blob_size << ", cumulative size: " << cumulative_block_size << ", " << block_processing_time << "("<< target_calculating_time << "/" << longhash_calculating_time << ")ms"); - logger_handle(block_processing_time); + epee::net_utils::data_logger::get_instance().add_data("blockchain_processing_time", block_processing_time); bvc.m_added_to_main_chain = true; /*if(!m_orphanes_reorganize_in_work) diff --git a/src/cryptonote_core/blockchain_storage.h b/src/cryptonote_core/blockchain_storage.h index 6456689b9..38bdfbce7 100644 --- a/src/cryptonote_core/blockchain_storage.h +++ b/src/cryptonote_core/blockchain_storage.h @@ -249,7 +249,6 @@ namespace cryptonote bool complete_timestamps_vector(uint64_t start_height, std::vector& timestamps); bool update_next_comulative_size_limit(); bool store_genesis_block(bool testnet); - void logger_handle(long int ms); }; diff --git a/src/cryptonote_core/cryptonote_core.cpp b/src/cryptonote_core/cryptonote_core.cpp index c8daa3510..49ce63065 100644 --- a/src/cryptonote_core/cryptonote_core.cpp +++ b/src/cryptonote_core/cryptonote_core.cpp @@ -206,14 +206,30 @@ namespace cryptonote return m_fast_exit; } //----------------------------------------------------------------------------------------------- - void core::no_check_blocks() + void core::test_drop_download() { - m_check_blocks = false; + m_test_drop_download = false; } //----------------------------------------------------------------------------------------------- - bool core::get_check_blocks() + void core::test_drop_download_height(uint64_t height) { - return m_check_blocks; + m_test_drop_download_height = height; + } + //----------------------------------------------------------------------------------------------- + bool core::get_test_drop_download() + { + return m_test_drop_download; + } + //----------------------------------------------------------------------------------------------- + bool core::get_test_drop_download_height() + { + if (m_test_drop_download_height == 0) + return true; + + if (get_blockchain_storage().get_current_blockchain_height() <= m_test_drop_download_height) + return true; + + return false; } //----------------------------------------------------------------------------------------------- bool core::handle_incoming_tx(const blobdata& tx_blob, tx_verification_context& tvc, bool keeped_by_block) diff --git a/src/cryptonote_core/cryptonote_core.h b/src/cryptonote_core/cryptonote_core.h index 9218aef0f..795a6d214 100644 --- a/src/cryptonote_core/cryptonote_core.h +++ b/src/cryptonote_core/cryptonote_core.h @@ -77,8 +77,10 @@ namespace cryptonote bool deinit(); static void set_fast_exit(); static bool get_fast_exit(); - void no_check_blocks(); - bool get_check_blocks(); + void test_drop_download(); + void test_drop_download_height(uint64_t height); + bool get_test_drop_download(); + bool get_test_drop_download_height(); uint64_t get_current_blockchain_height(); bool get_blockchain_top(uint64_t& heeight, crypto::hash& top_id); bool get_blocks(uint64_t start_offset, size_t count, std::list& blocks, std::list& txs); @@ -151,8 +153,8 @@ namespace cryptonote bool check_tx_inputs_keyimages_diff(const transaction& tx); void graceful_exit(); static std::atomic m_fast_exit; - bool m_check_blocks = true; - + bool m_test_drop_download = true; + uint64_t m_test_drop_download_height = 0; tx_memory_pool m_mempool; blockchain_storage m_blockchain_storage; diff --git a/src/cryptonote_protocol/cryptonote_protocol_handler-base.cpp b/src/cryptonote_protocol/cryptonote_protocol_handler-base.cpp index b5a5ceea9..614ee8fab 100644 --- a/src/cryptonote_protocol/cryptonote_protocol_handler-base.cpp +++ b/src/cryptonote_protocol/cryptonote_protocol_handler-base.cpp @@ -128,7 +128,7 @@ void cryptonote_protocol_handler_base::handler_request_blocks_history(std::list< // TODO } -void cryptonote_protocol_handler_base::handler_response_blocks_now(size_t packet_size) { _scope_mark(""); +void cryptonote_protocol_handler_base::handler_response_blocks_now(size_t packet_size) { _scope_dbg1(""); using namespace epee::net_utils; double delay=0; // will be calculated _dbg1("Packet size: " << packet_size); diff --git a/src/cryptonote_protocol/cryptonote_protocol_handler.h b/src/cryptonote_protocol/cryptonote_protocol_handler.h index ada269678..571c36dc1 100644 --- a/src/cryptonote_protocol/cryptonote_protocol_handler.h +++ b/src/cryptonote_protocol/cryptonote_protocol_handler.h @@ -45,11 +45,14 @@ #include "cryptonote_core/connection_context.h" #include "cryptonote_core/cryptonote_stat_info.h" #include "cryptonote_core/verification_context.h" +// #include #include PUSH_WARNINGS DISABLE_VS_WARNINGS(4355) +#define LOCALHOST_INT 2130706433 + namespace cryptonote { diff --git a/src/cryptonote_protocol/cryptonote_protocol_handler.inl b/src/cryptonote_protocol/cryptonote_protocol_handler.inl index 0130cb384..023dd03a6 100644 --- a/src/cryptonote_protocol/cryptonote_protocol_handler.inl +++ b/src/cryptonote_protocol/cryptonote_protocol_handler.inl @@ -42,6 +42,7 @@ #include "profile_tools.h" #include "../../contrib/otshell_utils/utils.hpp" #include "../../src/p2p/network_throttle-detail.hpp" +#include "../../src/p2p/data_logger.hpp" using namespace nOT::nUtils; namespace cryptonote @@ -154,10 +155,10 @@ namespace cryptonote << std::setw(10) << std::fixed << (connection_time == 0 ? 0.0 : cntxt.m_send_cnt / connection_time / 1024) << std::setw(13) << std::fixed << cntxt.m_current_speed_up / 1024 << (local_ip ? "[LAN]" : "") - << std::left << (ip == 2130706433 ? "[LOCALHOST]" : "") // 127.0.0.1 + << std::left << (ip == LOCALHOST_INT ? "[LOCALHOST]" : "") // 127.0.0.1 << ENDL; - if (connection_time > 0) + if (connection_time > 1) { down_sum += (cntxt.m_recv_cnt / connection_time / 1024); up_sum += (cntxt.m_send_cnt / connection_time / 1024); @@ -397,11 +398,9 @@ namespace cryptonote // calculate size of request - mainly for logging/debug size_t size = 0; - for (auto element : arg.txs) - size += element.size(); + for (auto element : arg.txs) size += element.size(); - for (auto element : arg.blocks) - { + for (auto element : arg.blocks) { size += element.block.size(); for (auto tx : element.txs) size += tx.size(); @@ -491,66 +490,65 @@ namespace cryptonote return 1; } + { m_core.pause_mine(); epee::misc_utils::auto_scope_leave_caller scope_exit_handler = epee::misc_utils::create_scope_leave_handler( boost::bind(&t_core::resume_mine, &m_core)); LOG_PRINT_CCONTEXT_YELLOW( "Got NEW BLOCKS inside of " << __FUNCTION__ << ": size: " << arg.blocks.size() , LOG_LEVEL_0); - BOOST_FOREACH(const block_complete_entry& block_entry, arg.blocks) - { - //process transactions - TIME_MEASURE_START(transactions_process_time); - BOOST_FOREACH(auto& tx_blob, block_entry.txs) - { - tx_verification_context tvc = AUTO_VAL_INIT(tvc); - m_core.handle_incoming_tx(tx_blob, tvc, true); - if(tvc.m_verifivation_failed) - { - LOG_ERROR_CCONTEXT("transaction verification failed on NOTIFY_RESPONSE_GET_OBJECTS, \r\ntx_id = " - << epee::string_tools::pod_to_hex(get_blob_hash(tx_blob)) << ", dropping connection"); - m_p2p->drop_connection(context); - return 1; - } - } - TIME_MEASURE_FINISH(transactions_process_time); - - //process block - TIME_MEASURE_START(block_process_time); - block_verification_context bvc = boost::value_initialized(); - - if (m_core.get_check_blocks()) - m_core.handle_incoming_block(block_entry.block, bvc, false); - - if(bvc.m_verifivation_failed) - { - LOG_PRINT_CCONTEXT_L1("Block verification failed, dropping connection"); - m_p2p->drop_connection(context); - return 1; - } - if(bvc.m_marked_as_orphaned) - { - LOG_PRINT_CCONTEXT_L1("Block received at sync phase was marked as orphaned, dropping connection"); - m_p2p->drop_connection(context); - return 1; - } - - TIME_MEASURE_FINISH(block_process_time); - LOG_PRINT_CCONTEXT_L2("Block process time: " << block_process_time + transactions_process_time << "(" << transactions_process_time << "/" << block_process_time << ")ms"); - - std::ofstream log_file; - log_file.open("log/dr-monero/get_objects_calc_time.data", std::ofstream::out | std::ofstream::app); - log_file.precision(7); - - using namespace boost::chrono; - auto point = steady_clock::now(); - auto time_from_epoh = point.time_since_epoch(); - auto m_ms = duration_cast< milliseconds >( time_from_epoh ).count(); - double ms_f = m_ms; - ms_f /= 1000.; - - log_file << static_cast(ms_f) << " " << block_process_time + transactions_process_time << std::endl; - } + + if (m_core.get_test_drop_download() && m_core.get_test_drop_download_height()) { // DISCARD BLOCKS for testing + + + BOOST_FOREACH(const block_complete_entry& block_entry, arg.blocks) + { + // process transactions + TIME_MEASURE_START(transactions_process_time); + BOOST_FOREACH(auto& tx_blob, block_entry.txs) + { + tx_verification_context tvc = AUTO_VAL_INIT(tvc); + m_core.handle_incoming_tx(tx_blob, tvc, true); + if(tvc.m_verifivation_failed) + { + LOG_ERROR_CCONTEXT("transaction verification failed on NOTIFY_RESPONSE_GET_OBJECTS, \r\ntx_id = " + << epee::string_tools::pod_to_hex(get_blob_hash(tx_blob)) << ", dropping connection"); + m_p2p->drop_connection(context); + return 1; + } + } + TIME_MEASURE_FINISH(transactions_process_time); + + // process block + + TIME_MEASURE_START(block_process_time); + block_verification_context bvc = boost::value_initialized(); + + m_core.handle_incoming_block(block_entry.block, bvc, false); // <--- process block + + if(bvc.m_verifivation_failed) + { + LOG_PRINT_CCONTEXT_L1("Block verification failed, dropping connection"); + m_p2p->drop_connection(context); + return 1; + } + if(bvc.m_marked_as_orphaned) + { + LOG_PRINT_CCONTEXT_L1("Block received at sync phase was marked as orphaned, dropping connection"); + m_p2p->drop_connection(context); + return 1; + } + + TIME_MEASURE_FINISH(block_process_time); + LOG_PRINT_CCONTEXT_L2("Block process time: " << block_process_time + transactions_process_time << "(" << transactions_process_time << "/" << block_process_time << ")ms"); + + epee::net_utils::data_logger::get_instance().add_data("calc_time", block_process_time + transactions_process_time); + + } // each download block + + } // if not DISCARD BLOCK + + } request_missing_objects(context, true); return 1; diff --git a/src/daemon/daemon.cpp b/src/daemon/daemon.cpp index 27a1129dc..8497efbf2 100644 --- a/src/daemon/daemon.cpp +++ b/src/daemon/daemon.cpp @@ -34,6 +34,7 @@ #include "include_base_utils.h" #include "version.h" +#include "../../contrib/epee/include/syncobj.h" using namespace epee; @@ -57,6 +58,8 @@ using namespace epee; namespace po = boost::program_options; +unsigned int epee::g_test_dbg_lock_sleep = 0; + namespace { const command_line::arg_descriptor arg_config_file = {"config-file", "Specify configuration file", std::string(CRYPTONOTE_NAME ".conf")}; @@ -69,9 +72,11 @@ namespace , "Run on testnet. The wallet must be launched with --testnet flag." , false }; - const command_line::arg_descriptor arg_dns_checkpoints = {"enforce-dns-checkpointing", "checkpoints from DNS server will be enforced", false}; - const command_line::arg_descriptor arg_test_drop_download = {"test-drop-download", "For network testing, drop downloaded blocks instead checking/adding them to blockchain. Can fake-download blocks very fast."}; - const command_line::arg_descriptor arg_save_graph = {"save-graph", "Save data for dr monero", false}; + const command_line::arg_descriptor arg_dns_checkpoints = {"enforce-dns-checkpointing", "checkpoints from DNS server will be enforced", false}; + const command_line::arg_descriptor arg_test_drop_download = {"test-drop-download", "For net tests: in download, discard ALL blocks instead checking/saving them (very fast)"}; + const command_line::arg_descriptor arg_test_drop_download_height = {"test-drop-download-height", "Like test-drop-download but disards only after around certain height", 0}; + const command_line::arg_descriptor arg_save_graph = {"save-graph", "Save data for dr monero", false}; + const command_line::arg_descriptor test_dbg_lock_sleep = {"test-dbg-lock-sleep", "Sleep time in ms, defaults to 0 (off), used to debug before/after locking mutex. Values 100 to 1000 are good for tests.", 0}; } bool command_line_preprocessor(const boost::program_options::variables_map& vm) @@ -111,7 +116,6 @@ bool command_line_preprocessor(const boost::program_options::variables_map& vm) int main(int argc, char* argv[]) { - string_tools::set_module_name_and_folder(argv[0]); #ifdef WIN32 _CrtSetDbgFlag ( _CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF ); @@ -119,7 +123,10 @@ int main(int argc, char* argv[]) 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..."); - + + nOT::nUtils::cFilesystemUtils::CreateDirTree("log/dr-monero/net/"); + // _warn_c("log/test","Starting program"); // TODO + TRY_ENTRY(); boost::filesystem::path default_data_path {tools::get_default_data_dir()}; @@ -142,7 +149,9 @@ int main(int argc, char* argv[]) command_line::add_arg(desc_cmd_sett, arg_testnet_on); command_line::add_arg(desc_cmd_sett, arg_dns_checkpoints); command_line::add_arg(desc_cmd_sett, arg_test_drop_download); + command_line::add_arg(desc_cmd_sett, arg_test_drop_download_height); command_line::add_arg(desc_cmd_sett, arg_save_graph); + command_line::add_arg(desc_cmd_sett, test_dbg_lock_sleep); cryptonote::core::init_options(desc_cmd_sett); cryptonote::core_rpc_server::init_options(desc_cmd_sett); @@ -241,12 +250,16 @@ int main(int argc, char* argv[]) if(command_line::has_arg(vm, arg_save_graph)) p2psrv.set_save_graph(true); + epee::g_test_dbg_lock_sleep = command_line::get_arg(vm, test_dbg_lock_sleep); + //initialize core here LOG_PRINT_L0("Initializing core..."); res = ccore.init(vm, testnet_mode); CHECK_AND_ASSERT_MES(res, 1, "Failed to initialize core"); if (command_line::get_arg(vm, arg_test_drop_download)) - ccore.no_check_blocks(); + ccore.test_drop_download(); + + ccore.test_drop_download_height(command_line::get_arg(vm, arg_test_drop_download_height)); LOG_PRINT_L0("Core initialized OK"); //initialize objects diff --git a/src/daemon/daemon_commands_handler.h b/src/daemon/daemon_commands_handler.h index 6afbbb07f..c23df0443 100644 --- a/src/daemon/daemon_commands_handler.h +++ b/src/daemon/daemon_commands_handler.h @@ -426,27 +426,21 @@ private: return false; } - using namespace boost::chrono; - auto point = steady_clock::now(); - auto time_from_epoh = point.time_since_epoch(); - auto ms = duration_cast< milliseconds >( time_from_epoh ).count(); - double ms_f = ms; - ms_f /= 1000.; - - std::ofstream limitFile("log/dr-monero/peers_limit.info", std::ios::app); - limitFile.precision(7); - limitFile << ms_f << " " << static_cast(limit) << std::endl; if (m_srv.m_config.m_net_config.connections_count > limit) { m_srv.m_config.m_net_config.connections_count = limit; - if (m_srv.m_number_of_out_peers > limit) + epee::net_utils::data_logger::get_instance().add_data("peers_limit", m_srv.m_config.m_net_config.connections_count); + if (m_srv.m_current_number_of_out_peers > limit) { - int count = m_srv.m_number_of_out_peers - limit; + int count = m_srv.m_current_number_of_out_peers - limit; m_srv.delete_connections(count); } } else + { m_srv.m_config.m_net_config.connections_count = limit; + epee::net_utils::data_logger::get_instance().add_data("peers_limit", m_srv.m_config.m_net_config.connections_count); + } return true; } @@ -556,7 +550,7 @@ private: //-------------------------------------------------------------------------------- bool test_drop_download(const std::vector& args) { - m_srv.get_payload_object().get_core().no_check_blocks(); + m_srv.get_payload_object().get_core().test_drop_download(); return true; } //-------------------------------------------------------------------------------- diff --git a/src/miner/simpleminer.cpp b/src/miner/simpleminer.cpp index fafe6b3f3..6212f88f5 100644 --- a/src/miner/simpleminer.cpp +++ b/src/miner/simpleminer.cpp @@ -41,6 +41,7 @@ using namespace epee; namespace po = boost::program_options; +unsigned int epee::g_test_dbg_lock_sleep = 0; int main(int argc, char** argv) { diff --git a/src/p2p/connection_basic.cpp b/src/p2p/connection_basic.cpp index 0e2fd5942..4a4a32384 100644 --- a/src/p2p/connection_basic.cpp +++ b/src/p2p/connection_basic.cpp @@ -152,7 +152,7 @@ connection_basic::connection_basic(boost::asio::io_service& io_service, std::ato try { remote_addr_str = socket_.remote_endpoint().address().to_string(); } catch(...){} ; _note("Spawned connection p2p#"<m_peer_number<<" to " << remote_addr_str << " currently we have sockets count:" << m_ref_sock_count); - boost::filesystem::create_directories("log/dr-monero/net/"); + //boost::filesystem::create_directories("log/dr-monero/net/"); } connection_basic::~connection_basic() { @@ -192,24 +192,15 @@ void connection_basic::save_limit_to_file(int limit) { // saving limit to file if (!epee::net_utils::data_logger::m_save_graph) return; - std::ofstream file_up, file_down; - file_up.open("log/dr-monero/limit_up.info", std::ofstream::out | std::ofstream::app); - file_up.precision(8); - file_down.open("log/dr-monero/limit_down.info", std::ofstream::out | std::ofstream::app); - file_down.precision(8); - using namespace boost::chrono; - auto point = steady_clock::now(); - auto time_from_epoh = point.time_since_epoch(); - auto s = duration_cast< seconds >( time_from_epoh ).count(); { CRITICAL_REGION_LOCAL( network_throttle_manager::m_lock_get_global_throttle_out ); - file_up << s << " " << network_throttle_manager::get_global_throttle_out().get_terget_speed() / 1024 << "\n"; + epee::net_utils::data_logger::get_instance().add_data("upload_limit", network_throttle_manager::get_global_throttle_out().get_terget_speed() / 1024); } { CRITICAL_REGION_LOCAL( network_throttle_manager::m_lock_get_global_throttle_in ); - file_down << s << " " << network_throttle_manager::get_global_throttle_in().get_terget_speed() / 1024 << "\n"; + epee::net_utils::data_logger::get_instance().add_data("download_limit", network_throttle_manager::get_global_throttle_in().get_terget_speed() / 1024); } } diff --git a/src/p2p/data_logger.cpp b/src/p2p/data_logger.cpp index 6a8eb25be..77f647bed 100644 --- a/src/p2p/data_logger.cpp +++ b/src/p2p/data_logger.cpp @@ -1,7 +1,9 @@ #include "data_logger.hpp" #include +#include #include +#include "../../contrib/otshell_utils/utils.hpp" namespace epee { @@ -32,7 +34,16 @@ namespace net_utils mFilesMap["request"] = data_logger::fileData("log/dr-monero/net/req-all.data"); mFilesMap["sleep_down"] = data_logger::fileData("log/dr-monero/down_sleep_log.data"); mFilesMap["sleep_up"] = data_logger::fileData("log/dr-monero/up_sleep_log.data"); + mFilesMap["calc_time"] = data_logger::fileData("log/dr-monero/get_objects_calc_time.data"); + mFilesMap["blockchain_processing_time"] = data_logger::fileData("log/dr-monero/blockchain_log.data"); + mFilesMap["peers_limit"] = data_logger::fileData("log/dr-monero/peers_limit.info"); + mFilesMap["download_limit"] = data_logger::fileData("log/dr-monero/limit_down.info"); + mFilesMap["upload_limit"] = data_logger::fileData("log/dr-monero/limit_up.info"); + + mFilesMap["peers_limit"].mLimitFile = true; + mFilesMap["download_limit"].mLimitFile = true; + mFilesMap["upload_limit"].mLimitFile = true; } void data_logger::add_data(std::string filename, unsigned int data) @@ -40,7 +51,14 @@ namespace net_utils if (mFilesMap.find(filename) == mFilesMap.end()) return; // TODO: exception - mFilesMap[filename].mDataToSave += data; + + nOT::nUtils::cFilesystemUtils::CreateDirTree("log/dr-monero/net/"); + + std::lock_guard lock(mSaveMutex); + if (mFilesMap[filename].mLimitFile) + mFilesMap[filename].mDataToSave = data; + else + mFilesMap[filename].mDataToSave += data; } double data_logger::fileData::get_current_time() @@ -56,23 +74,27 @@ namespace net_utils data_logger::fileData::fileData(std::string pFile) { mFile = std::make_shared (pFile); + mPath = pFile; } void data_logger::fileData::save() { if (!data_logger::m_save_graph) return; + mFile->open(mPath, std::ios::app); *mFile << static_cast(get_current_time()) << " " << mDataToSave << std::endl; + mFile->close(); } void data_logger::saveToFile() { - std::lock_guard lock(mSaveMutex); - for (auto &element : mFilesMap) - { - element.second.save(); - element.second.mDataToSave = 0; - } + std::lock_guard lock(mSaveMutex); + for (auto &element : mFilesMap) + { + element.second.save(); + if (!element.second.mLimitFile) + element.second.mDataToSave = 0; + } } std::atomic data_logger::m_save_graph(false); diff --git a/src/p2p/data_logger.hpp b/src/p2p/data_logger.hpp index 2b8503df3..50beb847a 100644 --- a/src/p2p/data_logger.hpp +++ b/src/p2p/data_logger.hpp @@ -27,12 +27,15 @@ namespace net_utils { public: fileData(){} + fileData(const fileData &ob) = delete; fileData(std::string pFile); std::shared_ptr mFile; long int mDataToSave = 0; static double get_current_time(); void save(); + std::string mPath; + bool mLimitFile = false; }; std::map mFilesMap; diff --git a/src/p2p/net_node.h b/src/p2p/net_node.h index ea7d5c383..5417ffa52 100644 --- a/src/p2p/net_node.h +++ b/src/p2p/net_node.h @@ -87,7 +87,7 @@ namespace nodetool m_hide_my_port(false), m_network_id(std::move(network_id)) { - m_number_of_out_peers = 0; + m_current_number_of_out_peers = 0; m_save_graph = false; } @@ -228,7 +228,7 @@ namespace nodetool public: config m_config; // TODO was private, add getters? - std::atomic m_number_of_out_peers; + std::atomic m_current_number_of_out_peers; void set_save_graph(bool save_graph) { m_save_graph = save_graph; diff --git a/src/p2p/net_node.inl b/src/p2p/net_node.inl index 60eed1f36..a015763bf 100644 --- a/src/p2p/net_node.inl +++ b/src/p2p/net_node.inl @@ -296,20 +296,18 @@ namespace nodetool unsigned int number_of_peers; while (1) { - if (m_save_graph) + //number_of_peers = m_net_server.get_config_object().get_connections_count(); + number_of_peers = 0; + m_net_server.get_config_object().foreach_connection([&](const p2p_connection_context& cntxt) { - //number_of_peers = m_net_server.get_config_object().get_connections_count(); - number_of_peers = 0; - m_net_server.get_config_object().foreach_connection([&](const p2p_connection_context& cntxt) - { - if(!cntxt.m_is_income) - ++number_of_peers; - return true; - }); // lambda + if(!cntxt.m_is_income) + ++number_of_peers; + return true; + }); // lambda + + m_current_number_of_out_peers = number_of_peers; + epee::net_utils::data_logger::get_instance().add_data("peers", number_of_peers); - m_number_of_out_peers = number_of_peers; - epee::net_utils::data_logger::get_instance().add_data("peers", number_of_peers); - } std::this_thread::sleep_for(std::chrono::seconds(1)); } })); // lambda @@ -724,14 +722,14 @@ namespace nodetool template bool node_server::try_to_connect_and_handshake_with_new_peer(const net_address& na, bool just_take_peerlist, uint64_t last_seen_stamp, bool white) { - if (m_number_of_out_peers == m_config.m_net_config.connections_count) // out peers limit + if (m_current_number_of_out_peers == m_config.m_net_config.connections_count) // out peers limit { return false; } - else if (m_number_of_out_peers > m_config.m_net_config.connections_count) + else if (m_current_number_of_out_peers > m_config.m_net_config.connections_count) { m_net_server.get_config_object().del_out_connections(1); - m_number_of_out_peers --; // atomic variable, update time = 1s + m_current_number_of_out_peers --; // atomic variable, update time = 1s return false; } LOG_PRINT_L1("Connecting to " << epee::string_tools::get_ip_string_from_int32(na.ip) << ":" @@ -1378,25 +1376,14 @@ namespace nodetool template bool node_server::set_max_out_peers(const boost::program_options::variables_map& vm, int64_t max) - { - using namespace std::chrono; - auto point = steady_clock::now(); - auto time_from_epoh = point.time_since_epoch(); - auto ms = duration_cast< milliseconds >( time_from_epoh ).count(); - double ms_f = ms; - ms_f /= 1000.; - - std::ofstream limitFile("log/dr-monero/peers_limit.info", std::ios::app); - limitFile.precision(7); + { if(max == -1) { m_config.m_net_config.connections_count = P2P_DEFAULT_CONNECTIONS_COUNT; - if (m_save_graph) - limitFile << static_cast(ms_f) << " " << P2P_DEFAULT_CONNECTIONS_COUNT << std::endl; + epee::net_utils::data_logger::get_instance().add_data("peers_limit", m_config.m_net_config.connections_count); return true; } - + epee::net_utils::data_logger::get_instance().add_data("peers_limit", max); m_config.m_net_config.connections_count = max; - limitFile << static_cast(ms_f) << " " << max << std::endl; return true; } diff --git a/src/p2p/network_throttle-detail.cpp b/src/p2p/network_throttle-detail.cpp index 6b2ee698e..7426e6dc7 100644 --- a/src/p2p/network_throttle-detail.cpp +++ b/src/p2p/network_throttle-detail.cpp @@ -220,7 +220,7 @@ void network_throttle::_handle_trafic_exact(size_t packet_size, size_t orginal_s std::ostringstream oss; oss << "["; for (auto sample: m_history) oss << sample.m_size << " "; oss << "]" << std::ends; std::string history_str = oss.str(); - _info_c( "net/" + m_nameshort , "Throttle " << m_name << ": packet of ~"< 0 ? "SLEEP" : "") << "dbg " << m_name << ": " << "speed is A=" << std::setw(8) < Date: Tue, 24 Feb 2015 20:12:56 +0100 Subject: 2014 network limit 1.3 fix log/path/data +utils +toc -doc -drmonero Fixed the windows path, and improved logging and data (for graph) logging, fixed some locks and added more checks. Still there is a locking error, not added by my patches, but present in master version (locking of map/list of peers). --- .gitignore | 1 - contrib/otshell_utils/utils.cpp | 170 +++++++++++++++++++++++++++--------- contrib/otshell_utils/utils.hpp | 16 +++- src/common/util.cpp | 2 +- src/daemon/daemon.cpp | 6 +- src/p2p/connection_basic.cpp | 1 + src/p2p/data_logger.cpp | 143 ++++++++++++++++++++---------- src/p2p/data_logger.hpp | 52 ++++++++--- src/p2p/network_throttle.cpp | 1 - tests/core_proxy/core_proxy.cpp | 3 + tests/core_proxy/core_proxy.h | 2 + tests/core_tests/CMakeLists.txt | 2 + tests/core_tests/chaingen_main.cpp | 2 + tests/functional_tests/main.cpp | 2 + tests/net_load_tests/CMakeLists.txt | 2 + tests/net_load_tests/clt.cpp | 3 + tests/net_load_tests/srv.cpp | 4 +- tests/performance_tests/main.cpp | 2 + tests/unit_tests/main.cpp | 2 + 19 files changed, 306 insertions(+), 110 deletions(-) (limited to 'src/daemon/daemon.cpp') diff --git a/.gitignore b/.gitignore index 755cb1043..18653c238 100644 --- a/.gitignore +++ b/.gitignore @@ -59,7 +59,6 @@ version/ ### CMake ### CMakeCache.txt CMakeFiles -Makefile cmake_install.cmake install_manifest.txt *.cmake diff --git a/contrib/otshell_utils/utils.cpp b/contrib/otshell_utils/utils.cpp index 043260807..ff39d15e8 100644 --- a/contrib/otshell_utils/utils.cpp +++ b/contrib/otshell_utils/utils.cpp @@ -160,7 +160,7 @@ std::unique_ptr make_unique( Args&& ...args ) #endif // ==================================================================== -char cFilesystemUtils::GetDirSeparator() { +char cFilesystemUtils::GetDirSeparatorSys() { // TODO nicer os detection? #if defined(OS_TYPE_POSIX) return '/'; @@ -171,26 +171,49 @@ char cFilesystemUtils::GetDirSeparator() { #endif } +char cFilesystemUtils::GetDirSeparatorInter() { + return '/'; +} + +string cFilesystemUtils::FileInternalToSystem(const std::string &name) { + string ret; + ret.resize(name.size()); + std::replace_copy(name.begin(), name.end(), ret.begin(), + GetDirSeparatorInter() , GetDirSeparatorSys()); + return ret; +} + +string cFilesystemUtils::FileSystemToInternal(const std::string &name) { + string ret; + ret.reserve(name.size()); + std::replace_copy(name.begin(), name.end(), ret.begin(), + GetDirSeparatorSys() , GetDirSeparatorInter()); + return ret; +} + bool cFilesystemUtils::CreateDirTree(const std::string & dir, bool only_below) { const bool dbg=false; //struct stat st; - const char dirch = cFilesystemUtils::GetDirSeparator(); + const char dirchS = cFilesystemUtils::GetDirSeparatorSys(); + const char dirchI = cFilesystemUtils::GetDirSeparatorInter(); std::istringstream iss(dir); - string part, sofar=""; + string partI; // current par is in internal format (though it should not matter since it doesn't contain any slashes). eg "bar" + string sofarS=""; // sofarS - the so far created dir part is in SYSTEM format. eg "foo/bar" if (dir.size()<1) return false; // illegal name // dir[0] is valid from here - if (only_below && (dir[0]==dirch)) return false; // no jumping to top (on any os) - while (getline(iss,part,dirch)) { - if (dbg) cout << '['<= mLevel) && (mStream)) { + if ((level >= mLevel) && (mStream)) { // TODO now disabling mStream also disables writting to any channel ostream & output = SelectOutput(level,channel); output << icon(level) << ' '; std::thread::id this_id = std::this_thread::get_id(); @@ -278,33 +321,76 @@ std::string cLogger::GetLogBaseDir() const { return "log"; } -void cLogger::OpenNewChannel(const std::string & channel) { - size_t last_split = channel.find_last_of(cFilesystemUtils::GetDirSeparator()); - // log/test/aaa - // ^----- last_split - string dir = GetLogBaseDir() + cFilesystemUtils::GetDirSeparator() + channel.substr(0, last_split); - string basefile = channel.substr(last_split+1) + ".log"; - string fname = dir + cFilesystemUtils::GetDirSeparator() + cFilesystemUtils::GetDirSeparator() + basefile; - _dbg1("Starting debug to channel file: " + fname + " in directory ["+dir+"]"); - bool dirok = cFilesystemUtils::CreateDirTree(dir); - if (!dirok) { const string msg = "In logger failed to open directory (" + dir +")."; _erro(msg); throw std::runtime_error(msg); } - std::ofstream * thefile = new std::ofstream( fname.c_str() ); - *thefile << "====== (Log opened: " << fname << ") ======" << endl; - mChannels.insert( std::pair(channel , thefile ) ); -} - -std::ostream & cLogger::SelectOutput(int level, const std::string & channel) { - if (channel=="") return *mStream; - auto obj = mChannels.find(channel); - if (obj == mChannels.end()) { // new channel - OpenNewChannel(channel); - return SelectOutput(level,channel); +void cLogger::OpenNewChannel(const std::string & channel) noexcept { + try { + std::cerr<<"openning channel for channel="<second; + else { // there is a directory eg channel=="net/sleep" + // net/sleep + // ^----- last_split + string dir = GetLogBaseDir() + cFilesystemUtils::GetDirSeparatorInter() + channel.substr(0, last_split); + string basefile = channel.substr(last_split+1) + ".log"; + string fname = dir + cFilesystemUtils::GetDirSeparatorInter() + basefile; + fname_system = cFilesystemUtils::FileInternalToSystem(fname); // <- + bool dirok = cFilesystemUtils::CreateDirTree(dir); + if (!dirok) { string err = "In logger failed to open directory (" + dir +") for channel (" + channel +")"; throw std::runtime_error(err); } } + + std::ofstream * thefile = new std::ofstream( fname_system.c_str() ); // file system + *thefile << "====== Log opened: " << fname_system << " (in " << ((void*)thefile) << ") ======" << endl; + cerr << "====== Log opened: " << fname_system << " (in " << ((void*)thefile) << ") ======" << endl; + mChannels.insert( std::pair(channel , thefile ) ); // <- created the channel mapping } +std::ostream & cLogger::SelectOutput(int level, const std::string & channel) noexcept { + try { + if (mIsBroken) return *mStreamBrokenDebug; + if (channel=="") return *mStream; + + auto obj = mChannels.find(channel); + if (obj == mChannels.end()) { // not found - need to make new channel + OpenNewChannel(channel); // <- create channel + obj = mChannels.find(channel); // find again + if (obj == mChannels.end()) { // still not found! something is wrong + SetStreamBroken( OT_CODE_STAMP + " WARNING: can not get stream for channel="+ToStr(channel)+" level="+ToStr(channel) ); + return *mStreamBrokenDebug; + } + } + auto the_stream_ptr = obj->second; + ASRT(the_stream_ptr); + return *the_stream_ptr; // <--- RETURN + } + catch (std::exception &except) { + SetStreamBroken( OT_CODE_STAMP + " Got exception: " + ToStr(except.what()) ); + return *mStreamBrokenDebug; + } + catch (...) { + SetStreamBroken( OT_CODE_STAMP + " Got not-standard exception."); + return *mStreamBrokenDebug; + } + + // dead code +} void cLogger::setOutStreamFile(const string &fname) { // switch to using this file _mark("WILL SWITCH DEBUG NOW to file: " << fname); diff --git a/contrib/otshell_utils/utils.hpp b/contrib/otshell_utils/utils.hpp index 83e6b822d..35b464b42 100644 --- a/contrib/otshell_utils/utils.hpp +++ b/contrib/otshell_utils/utils.hpp @@ -185,6 +185,7 @@ const char* DbgShortenCodeFileName(const char *s); ///< Returns a pointer to som /*** @brief Class to write debug into. Used it by calling the debug macros _dbg1(...) _info(...) _erro(...) etc, NOT directly! @author rfree (maintainer) +@thread this class is NOT thread safe and must used only by one thread at once (use it via ot_debug_macros like _info macro they do proper locking) */ class cLogger { public: @@ -201,15 +202,21 @@ class cLogger { std::string endline() const; ///< returns string to be written at end of message protected: + void SetStreamBroken(); ///< call in case of internal error in logger (e.g. can not open a file) + void SetStreamBroken(const std::string &msg); ///< same but with error message + unique_ptr mOutfile; std::ostream * mStream; ///< pointing only! can point to our own mOutfile, or maye to global null stream + std::ostream * mStreamBrokenDebug; ///< pointing only! this is a pointer to some stream that should be used when normal debugging is broken eg std::cerr + bool mIsBroken; ///< is the debugging system broken (this should be set when internal problems occur and should cause fallback to std::cerr) std::map< std::string , std::ofstream * > mChannels; // the ofstream objects are owned by this class int mLevel; ///< current debug level - std::ostream & SelectOutput(int level, const std::string & channel); - void OpenNewChannel(const std::string & channel); + std::ostream & SelectOutput(int level, const std::string & channel) noexcept; ///< returns a proper stream for this level and channel (always usable string) + void OpenNewChannel(const std::string & channel) noexcept; ///< tries to prepare this channel. does NOT guarantee to created mChannels[] entry! + void OpenNewChannel_(const std::string & channel); ///< internal function, will throw in case of problems std::string GetLogBaseDir() const; std::map< std::thread::id , int > mThread2Number; // change long thread IDs into a short nice number to show @@ -360,7 +367,10 @@ eSubjectType String2SubjectType(const string & type); class cFilesystemUtils { // if we do not want to use boost in given project (or we could optionally write boost here later) public: static bool CreateDirTree(const std::string & dir, bool only_below=false); - static char GetDirSeparator(); // eg '/' or '\' + static char GetDirSeparatorSys(); /// < eg '/' or '\' + static char GetDirSeparatorInter(); /// < internal is '/' + static string FileInternalToSystem(const std::string &name); ///< converts from internal file name string to system file name string + static string FileSystemToInternal(const std::string &name); ///< converts from system file name string to internal file name string }; diff --git a/src/common/util.cpp b/src/common/util.cpp index 907a87cee..94c1e042e 100644 --- a/src/common/util.cpp +++ b/src/common/util.cpp @@ -326,7 +326,7 @@ std::string get_nix_version_display_string() std::string config_folder; #ifdef WIN32 - config_folder = get_special_folder_path(CSIDL_APPDATA, true) + "/" + CRYPTONOTE_NAME; + config_folder = get_special_folder_path(CSIDL_APPDATA, true) + "\\" + CRYPTONOTE_NAME; #else std::string pathRet; char* pszHome = getenv("HOME"); diff --git a/src/daemon/daemon.cpp b/src/daemon/daemon.cpp index 8497efbf2..8d584af5e 100644 --- a/src/daemon/daemon.cpp +++ b/src/daemon/daemon.cpp @@ -125,8 +125,9 @@ int main(int argc, char* argv[]) LOG_PRINT_L0("Starting..."); nOT::nUtils::cFilesystemUtils::CreateDirTree("log/dr-monero/net/"); - // _warn_c("log/test","Starting program"); // TODO - + _warn_c("test","Starting program (a test message)"); + _warn_c("main/program","Starting program"); + TRY_ENTRY(); boost::filesystem::path default_data_path {tools::get_default_data_dir()}; @@ -319,6 +320,7 @@ int main(int argc, char* argv[]) ccore.set_cryptonote_protocol(NULL); cprotocol.set_p2p_endpoint(NULL); + epee::net_utils::data_logger::get_instance().kill_instance(); LOG_PRINT("Node stopped.", LOG_LEVEL_0); return 0; diff --git a/src/p2p/connection_basic.cpp b/src/p2p/connection_basic.cpp index 4a4a32384..ed15c0986 100644 --- a/src/p2p/connection_basic.cpp +++ b/src/p2p/connection_basic.cpp @@ -272,6 +272,7 @@ void connection_basic::logger_handle_net_write(size_t size) { } double connection_basic::get_sleep_time(size_t cb) { + CRITICAL_REGION_LOCAL(epee::net_utils::network_throttle_manager::network_throttle_manager::m_lock_get_global_throttle_out); auto t = network_throttle_manager::get_global_throttle_out().get_sleep_time(cb); return t; } diff --git a/src/p2p/data_logger.cpp b/src/p2p/data_logger.cpp index 77f647bed..d62af133e 100644 --- a/src/p2p/data_logger.cpp +++ b/src/p2p/data_logger.cpp @@ -1,4 +1,5 @@ #include "data_logger.hpp" +#include #include #include @@ -9,25 +10,25 @@ namespace epee { namespace net_utils { - data_logger &data_logger::get_instance() - { - static data_logger instance; - return instance; + data_logger &data_logger::get_instance() { + std::call_once(m_singleton, + [] { + _info_c("dbg/data","Creating singleton of data_logger"); + if (m_state != data_logger_state::state_before_init) { _erro_c("dbg/data","Internal error in singleton"); throw std::runtime_error("data_logger singleton"); } + m_state = data_logger_state::state_during_init; + m_obj.reset(new data_logger()); + m_state = data_logger_state::state_ready_to_use; + } + ); + return * m_obj; } - data_logger::data_logger() - { - //create timer - std::shared_ptr logger_thread(new std::thread([&]() - { - while (true) - { - std::this_thread::sleep_for(std::chrono::seconds(1)); - saveToFile(); - } - })); - logger_thread->detach(); + data_logger::data_logger() { + _warn_c("dbg/data","Starting data logger (for graphs data)"); + if (m_state != data_logger_state::state_during_init) { _erro_c("dbg/data","Singleton ctor state"); throw std::runtime_error("data_logger ctor state"); } + std::lock_guard lock(mMutex); // lock + // prepare all the files for given data channels: mFilesMap["peers"] = data_logger::fileData("log/dr-monero/peers.data"); mFilesMap["download"] = data_logger::fileData("log/dr-monero/net/in-all.data"); mFilesMap["upload"] = data_logger::fileData("log/dr-monero/net/out-all.data"); @@ -44,25 +45,80 @@ namespace net_utils mFilesMap["peers_limit"].mLimitFile = true; mFilesMap["download_limit"].mLimitFile = true; mFilesMap["upload_limit"].mLimitFile = true; + + // do NOT modify mFilesMap below this point, since there is no locking for this used (yet) + + _note_c("dbg/data","Creating thread for data logger"); // create timer thread + m_thread_maybe_running=true; + std::shared_ptr logger_thread(new std::thread([&]() { + _note_c("dbg/data","Inside thread for data logger"); + while (m_state == data_logger_state::state_during_init) { // wait for creation to be done (in other thread, in singleton) before actually running + std::this_thread::sleep_for(std::chrono::seconds(1)); + } + _note_c("dbg/data","Inside thread for data logger - going into main loop"); + while (m_state == data_logger_state::state_ready_to_use) { // run as long as we are not closing the single object + std::this_thread::sleep_for(std::chrono::seconds(1)); + saveToFile(); // save all the pending data + } + _note_c("dbg/data","Inside thread for data logger - done the main loop"); + m_thread_maybe_running=false; + })); + logger_thread->detach(); + _info_c("dbg/data","Data logger constructed"); + } + + data_logger::~data_logger() { + _note_c("dbg/data","Destructor of the data logger"); + { + std::lock_guard lock(mMutex); + m_state = data_logger_state::state_dying; + } + _info_c("dbg/data","State was set to dying"); + while(m_thread_maybe_running) { // wait for the thread to exit + std::this_thread::sleep_for(std::chrono::seconds(1)); + _info_c("dbg/data","Waiting for background thread to exit"); + } + _info_c("dbg/data","Thread exited"); + } + + void data_logger::kill_instance() { + m_state = m_state = data_logger_state::state_dying; + m_obj.reset(); } - void data_logger::add_data(std::string filename, unsigned int data) - { - if (mFilesMap.find(filename) == mFilesMap.end()) - return; // TODO: exception - - - nOT::nUtils::cFilesystemUtils::CreateDirTree("log/dr-monero/net/"); + void data_logger::add_data(std::string filename, unsigned int data) { + std::lock_guard lock(mMutex); + if (m_state != data_logger_state::state_ready_to_use) { _info_c("dbg/data","Data logger is not ready, returning."); return; } + + if (mFilesMap.find(filename) == mFilesMap.end()) { // no such file/counter + _erro_c("dbg/data","Trying to use not opened data file filename="< lock(mSaveMutex); - if (mFilesMap[filename].mLimitFile) + if (mFilesMap[filename].mLimitFile) { // this holds a number (that is not additive) - e.g. the limit setting mFilesMap[filename].mDataToSave = data; - else - mFilesMap[filename].mDataToSave += data; + } else { + mFilesMap[filename].mDataToSave += data; // this holds a number that should be sum of all accumulated samples + } + } + + void data_logger::saveToFile() { + _dbg2_c("dbg/data","saving to files"); + std::lock_guard lock(mMutex); + if (m_state != data_logger_state::state_ready_to_use) { _info_c("dbg/data","Data logger is not ready, returning."); return; } + nOT::nUtils::cFilesystemUtils::CreateDirTree("log/dr-monero/net/"); + for (auto &element : mFilesMap) + { + element.second.save(); + if (!element.second.mLimitFile) element.second.mDataToSave = 0; + } } + + // the inner class: - double data_logger::fileData::get_current_time() - { + double data_logger::fileData::get_current_time() { using namespace boost::chrono; auto point = steady_clock::now(); auto time_from_epoh = point.time_since_epoch(); @@ -71,33 +127,28 @@ namespace net_utils return ms_f / 1000.; } - data_logger::fileData::fileData(std::string pFile) - { + data_logger::fileData::fileData(std::string pFile) { + _dbg3_c("dbg/data","opening data file named pFile="<close(); } - void data_logger::saveToFile() - { - std::lock_guard lock(mSaveMutex); - for (auto &element : mFilesMap) - { - element.second.save(); - if (!element.second.mLimitFile) - element.second.mDataToSave = 0; - } - } -std::atomic data_logger::m_save_graph(false); +data_logger_state data_logger::m_state(data_logger_state::state_before_init); ///< (static) state of the singleton object +std::atomic data_logger::m_save_graph(false); // (static) +std::atomic data_logger::m_thread_maybe_running(false); // (static) +std::once_flag data_logger::m_singleton; // (static) +std::unique_ptr data_logger::m_obj; // (static) } // namespace } // namespace + diff --git a/src/p2p/data_logger.hpp b/src/p2p/data_logger.hpp index 50beb847a..215912167 100644 --- a/src/p2p/data_logger.hpp +++ b/src/p2p/data_logger.hpp @@ -13,34 +13,60 @@ namespace epee { namespace net_utils { + +enum class data_logger_state { state_before_init, state_during_init, state_ready_to_use, state_dying }; +/*** +@note: use it ONLY via singleton! It will be spawned then, and will auto destruct on program exit. +@note: do call ::kill_instance() before exiting main, at end of main. But before make sure no one else (e.g. no other threads) will try to use this/singleton +@note: it is not allowed to use this class from code "runnig before or after main", e.g. from ctors of static objects, because of static-creation-order races +@note: on creation (e.g. from singleton), it spawns a thread that saves all data in background +*/ class data_logger { public: - static data_logger &get_instance(); - data_logger(const data_logger &ob) = delete; + static data_logger &get_instance(); ///< singleton + static void kill_instance(); ///< call this before ending main to allow more gracefull shutdown of the main singleton and it's background thread + ~data_logger(); ///< destr, will be called when singleton is killed when global m_obj dies. will kill theads etc + + private: + data_logger(); ///< constructor is private, use only via singleton get_instance + + public: + data_logger(const data_logger &ob) = delete; // use only one per program data_logger(data_logger &&ob) = delete; - void add_data(std::string filename, unsigned int data); - static std::atomic m_save_graph; + data_logger & operator=(const data_logger&) = delete; + data_logger & operator=(data_logger&&) = delete; + + void add_data(std::string filename, unsigned int data); ///< use this to append data here. Use it only the singleton. It locks itself. + + static std::atomic m_save_graph; ///< global setting flag, should we save all the data or not (can disable logging graphs data) + private: - data_logger(); - class fileData - { + static std::once_flag m_singleton; ///< to guarantee singleton creates the object exactly once + static data_logger_state m_state; ///< state of the singleton object + static std::atomic m_thread_maybe_running; ///< is the background thread (more or less) running, or is it fully finished + static std::unique_ptr m_obj; ///< the singleton object. Only use it via get_instance(). Can be killed by kill_instance() + + /*** + * one graph/file with data + */ + class fileData { public: - fileData(){} + fileData() = default; fileData(const fileData &ob) = delete; fileData(std::string pFile); std::shared_ptr mFile; - long int mDataToSave = 0; + long int mDataToSave = 0; ///< sum of the data (in current interval, will be counted from 0 on next interval) static double get_current_time(); void save(); std::string mPath; - bool mLimitFile = false; + bool mLimitFile = false; ///< this holds a number (that is not additive) - e.g. the limit setting }; - std::map mFilesMap; - std::mutex mSaveMutex; - void saveToFile(); + std::map mFilesMap; + std::mutex mMutex; + void saveToFile(); ///< write data to the target files. do not use this directly }; } // namespace diff --git a/src/p2p/network_throttle.cpp b/src/p2p/network_throttle.cpp index 3d5edcdcd..7bc89881d 100644 --- a/src/p2p/network_throttle.cpp +++ b/src/p2p/network_throttle.cpp @@ -78,7 +78,6 @@ int network_throttle_manager::xxx; // ================================================================================================ // methods: i_network_throttle & network_throttle_manager::get_global_throttle_in() { - std::call_once(m_once_get_global_throttle_in, [] { m_obj_get_global_throttle_in.reset(new network_throttle("in/all","<<< global-IN",10)); } ); return * m_obj_get_global_throttle_in; } diff --git a/tests/core_proxy/core_proxy.cpp b/tests/core_proxy/core_proxy.cpp index de8f45fc6..879f83ebe 100644 --- a/tests/core_proxy/core_proxy.cpp +++ b/tests/core_proxy/core_proxy.cpp @@ -62,6 +62,8 @@ using namespace crypto; BOOST_CLASS_VERSION(nodetool::node_server >, 1); +unsigned int epee::g_test_dbg_lock_sleep = 0; + int main(int argc, char* argv[]) { @@ -148,6 +150,7 @@ int main(int argc, char* argv[]) LOG_PRINT("Node stopped.", LOG_LEVEL_0); + epee::net_utils::data_logger::get_instance().kill_instance(); return 0; CATCH_ENTRY_L0("main", 1); diff --git a/tests/core_proxy/core_proxy.h b/tests/core_proxy/core_proxy.h index 2b807564d..b40c5b216 100644 --- a/tests/core_proxy/core_proxy.h +++ b/tests/core_proxy/core_proxy.h @@ -82,5 +82,7 @@ namespace tests bool find_blockchain_supplement(const std::list& qblock_ids, cryptonote::NOTIFY_RESPONSE_CHAIN_ENTRY::request& resp){return true;} bool handle_get_objects(cryptonote::NOTIFY_REQUEST_GET_OBJECTS::request& arg, cryptonote::NOTIFY_RESPONSE_GET_OBJECTS::request& rsp, cryptonote::cryptonote_connection_context& context){return true;} cryptonote::blockchain_storage &get_blockchain_storage() { throw std::runtime_error("Called invalid member function: please never call get_blockchain_storage on the TESTING class proxy_core."); } + bool get_test_drop_download() {return true;} + bool get_test_drop_download_height() {return true;} }; } diff --git a/tests/core_tests/CMakeLists.txt b/tests/core_tests/CMakeLists.txt index ac536b29e..2b9e0cf81 100644 --- a/tests/core_tests/CMakeLists.txt +++ b/tests/core_tests/CMakeLists.txt @@ -60,6 +60,8 @@ add_executable(coretests target_link_libraries(coretests LINK_PRIVATE cryptonote_core + p2p + ${Boost_CHRONO_LIBRARY} ${Boost_FILESYSTEM_LIBRARY} ${Boost_SYSTEM_LIBRARY} ${CMAKE_THREAD_LIBS_INIT} diff --git a/tests/core_tests/chaingen_main.cpp b/tests/core_tests/chaingen_main.cpp index 0ec4d4581..a9ef8b00b 100644 --- a/tests/core_tests/chaingen_main.cpp +++ b/tests/core_tests/chaingen_main.cpp @@ -44,6 +44,8 @@ namespace const command_line::arg_descriptor arg_test_transactions = {"test_transactions", ""}; } +unsigned int epee::g_test_dbg_lock_sleep = 0; + int main(int argc, char* argv[]) { TRY_ENTRY(); diff --git a/tests/functional_tests/main.cpp b/tests/functional_tests/main.cpp index fda64303f..a653e7b1b 100644 --- a/tests/functional_tests/main.cpp +++ b/tests/functional_tests/main.cpp @@ -55,6 +55,8 @@ namespace const command_line::arg_descriptor arg_test_repeat_count = {"test_repeat_count", "", 1}; } +unsigned int epee::g_test_dbg_lock_sleep = 0; + int main(int argc, char* argv[]) { TRY_ENTRY(); diff --git a/tests/net_load_tests/CMakeLists.txt b/tests/net_load_tests/CMakeLists.txt index 6095146fb..acd7c9ac9 100644 --- a/tests/net_load_tests/CMakeLists.txt +++ b/tests/net_load_tests/CMakeLists.txt @@ -39,6 +39,7 @@ target_link_libraries(net_load_tests_clt LINK_PRIVATE otshell_utils p2p + cryptonote_core ${GTEST_MAIN_LIBRARIES} ${Boost_CHRONO_LIBRARY} ${Boost_DATE_TIME_LIBRARY} @@ -60,6 +61,7 @@ target_link_libraries(net_load_tests_srv LINK_PRIVATE otshell_utils p2p + cryptonote_core ${GTEST_MAIN_LIBRARIES} ${Boost_CHRONO_LIBRARY} ${Boost_DATE_TIME_LIBRARY} diff --git a/tests/net_load_tests/clt.cpp b/tests/net_load_tests/clt.cpp index 7c9b86cbf..6307f18eb 100644 --- a/tests/net_load_tests/clt.cpp +++ b/tests/net_load_tests/clt.cpp @@ -623,6 +623,8 @@ TEST_F(net_load_test_clt, permament_open_and_close_and_connections_closed_by_ser ASSERT_EQ(RESERVED_CONN_CNT, m_tcp_server.get_config_object().get_connections_count()); } +unsigned int epee::g_test_dbg_lock_sleep = 0; + int main(int argc, char** argv) { epee::debug::get_set_enable_assert(true, false); @@ -631,5 +633,6 @@ int main(int argc, char** argv) epee::log_space::log_singletone::add_logger(LOGGER_CONSOLE, NULL, NULL); ::testing::InitGoogleTest(&argc, argv); + epee::net_utils::data_logger::get_instance().kill_instance(); return RUN_ALL_TESTS(); } diff --git a/tests/net_load_tests/srv.cpp b/tests/net_load_tests/srv.cpp index edb106ea7..582c9efdf 100644 --- a/tests/net_load_tests/srv.cpp +++ b/tests/net_load_tests/srv.cpp @@ -213,6 +213,8 @@ namespace }; } +unsigned int epee::g_test_dbg_lock_sleep = 0; + int main(int argc, char** argv) { //set up logging options @@ -232,6 +234,6 @@ int main(int argc, char** argv) if (!tcp_server.run_server(thread_count, true)) return 2; - + epee::net_utils::data_logger::get_instance().kill_instance(); return 0; } diff --git a/tests/performance_tests/main.cpp b/tests/performance_tests/main.cpp index 724b36386..588cf6529 100644 --- a/tests/performance_tests/main.cpp +++ b/tests/performance_tests/main.cpp @@ -42,6 +42,8 @@ #include "generate_key_image_helper.h" #include "is_out_to_acc.h" +unsigned int epee::g_test_dbg_lock_sleep = 0; + int main(int argc, char** argv) { set_process_affinity(1); diff --git a/tests/unit_tests/main.cpp b/tests/unit_tests/main.cpp index e187bf52d..471895b84 100644 --- a/tests/unit_tests/main.cpp +++ b/tests/unit_tests/main.cpp @@ -32,6 +32,8 @@ #include "include_base_utils.h" +unsigned int epee::g_test_dbg_lock_sleep = 0; + int main(int argc, char** argv) { epee::debug::get_set_enable_assert(true, false); -- cgit v1.2.3 From f79821ac7ebc269b18dd2edd8ac0cb022861ad11 Mon Sep 17 00:00:00 2001 From: rfree2monero Date: Tue, 24 Feb 2015 21:02:48 +0100 Subject: fix locking in count-peers thread (2) --- src/daemon/daemon.cpp | 2 +- src/p2p/data_logger.cpp | 8 +++++++- src/p2p/net_node.h | 11 ++++++++++- src/p2p/net_node.inl | 19 ++++++++++--------- 4 files changed, 28 insertions(+), 12 deletions(-) (limited to 'src/daemon/daemon.cpp') diff --git a/src/daemon/daemon.cpp b/src/daemon/daemon.cpp index 8d584af5e..4a93a0db8 100644 --- a/src/daemon/daemon.cpp +++ b/src/daemon/daemon.cpp @@ -320,7 +320,7 @@ int main(int argc, char* argv[]) ccore.set_cryptonote_protocol(NULL); cprotocol.set_p2p_endpoint(NULL); - epee::net_utils::data_logger::get_instance().kill_instance(); + epee::net_utils::data_logger::kill_instance(); LOG_PRINT("Node stopped.", LOG_LEVEL_0); return 0; diff --git a/src/p2p/data_logger.cpp b/src/p2p/data_logger.cpp index d62af133e..69e50141a 100644 --- a/src/p2p/data_logger.cpp +++ b/src/p2p/data_logger.cpp @@ -20,6 +20,12 @@ namespace net_utils m_state = data_logger_state::state_ready_to_use; } ); + + if (m_state != data_logger_state::state_ready_to_use) { + _erro ("trying to use not working data_logger"); + throw std::runtime_error("data_logger ctor state"); + } + return * m_obj; } @@ -82,7 +88,7 @@ namespace net_utils } void data_logger::kill_instance() { - m_state = m_state = data_logger_state::state_dying; + m_state = data_logger_state::state_dying; m_obj.reset(); } diff --git a/src/p2p/net_node.h b/src/p2p/net_node.h index 5417ffa52..5b034ce25 100644 --- a/src/p2p/net_node.h +++ b/src/p2p/net_node.h @@ -89,6 +89,7 @@ namespace nodetool { m_current_number_of_out_peers = 0; m_save_graph = false; + is_closing = false; } static void init_options(boost::program_options::options_description& desc); @@ -209,6 +210,13 @@ namespace nodetool bool set_rate_down_limit(const boost::program_options::variables_map& vm, int64_t limit); bool set_rate_limit(const boost::program_options::variables_map& vm, uint64_t limit); + void kill() { ///< will be called e.g. from deinit() + _info("Killing the net_node"); + is_closing = true; + mPeersLoggerThread->join(); // make sure the thread finishes + _info("Joined extra background net_node threads"); + } + //debug functions std::string print_connections_container(); @@ -247,7 +255,8 @@ namespace nodetool bool m_hide_my_port; bool m_no_igd; std::atomic m_save_graph; - + std::atomic is_closing; + std::unique_ptr mPeersLoggerThread; //critical_section m_connections_lock; //connections_indexed_container m_connections; diff --git a/src/p2p/net_node.inl b/src/p2p/net_node.inl index a015763bf..afc6436f3 100644 --- a/src/p2p/net_node.inl +++ b/src/p2p/net_node.inl @@ -291,17 +291,17 @@ namespace nodetool std::vector> dns_results; dns_results.resize(m_seed_nodes_list.size()); - std::shared_ptr peersLoggerThread (new std::thread([&]() + // creating thread to log number of connections + mPeersLoggerThread.reset(new std::thread([&]() { - unsigned int number_of_peers; - while (1) - { + _note("Thread monitor number of peers - start"); + while (!is_closing) + { // main loop of thread //number_of_peers = m_net_server.get_config_object().get_connections_count(); - number_of_peers = 0; + unsigned int number_of_peers = 0; m_net_server.get_config_object().foreach_connection([&](const p2p_connection_context& cntxt) { - if(!cntxt.m_is_income) - ++number_of_peers; + if (!cntxt.m_is_income) ++number_of_peers; return true; }); // lambda @@ -309,10 +309,10 @@ namespace nodetool epee::net_utils::data_logger::get_instance().add_data("peers", number_of_peers); std::this_thread::sleep_for(std::chrono::seconds(1)); - } + } // main loop of thread + _note("Thread monitor number of peers - done"); })); // lambda - peersLoggerThread->detach(); std::list dns_threads; uint64_t result_index = 0; @@ -509,6 +509,7 @@ namespace nodetool template bool node_server::deinit() { + kill(); m_peerlist.deinit(); m_net_server.deinit_server(); -- cgit v1.2.3 From c511abf0058b8c1d020255faaad418b0ffd2eb26 Mon Sep 17 00:00:00 2001 From: rfree2monero Date: Wed, 1 Apr 2015 19:00:45 +0200 Subject: remerged; commands JSON. logging upgrade. doxygen --- CMakeLists.txt | 40 ++++ .../include/net/levin_protocol_handler_async.h | 1 - contrib/otshell_utils/utils.cpp | 102 +++++++++-- contrib/otshell_utils/utils.hpp | 34 +++- src/common/command_line.cpp | 3 + src/common/command_line.h | 3 + src/common/dns_utils.cpp | 19 +- src/cryptonote_core/cryptonote_core.cpp | 5 + src/cryptonote_protocol/cryptonote_protocol_defs.h | 14 ++ .../cryptonote_protocol_handler.inl | 37 ++++ src/daemon/CMakeLists.txt | 3 + src/daemon/command_parser_executor.cpp | 37 ++++ src/daemon/command_parser_executor.h | 7 + src/daemon/command_server.cpp | 24 ++- src/daemon/daemon.cpp | 10 +- src/daemon/daemon_commands_handler.h | 204 +++++---------------- src/daemon/main.cpp | 10 +- src/daemon/rpc_command_executor.cpp | 152 +++++++++++++-- src/daemon/rpc_command_executor.h | 8 +- src/p2p/data_logger.cpp | 19 +- src/p2p/data_logger.hpp | 1 + src/p2p/net_node.h | 19 +- src/p2p/net_node.inl | 60 +++--- src/p2p/network_throttle-detail.cpp | 9 +- src/rpc/CMakeLists.txt | 1 + src/rpc/core_rpc_server.cpp | 39 ++++ src/rpc/core_rpc_server.h | 8 + src/rpc/core_rpc_server_commands_defs.h | 74 ++++++++ src/simplewallet/simplewallet.cpp | 2 + 29 files changed, 702 insertions(+), 243 deletions(-) (limited to 'src/daemon/daemon.cpp') diff --git a/CMakeLists.txt b/CMakeLists.txt index 5c6330162..392b04dea 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -62,9 +62,24 @@ endif() message(STATUS "BOOST_IGNORE_SYSTEM_PATHS defaults to ${BOOST_IGNORE_SYSTEM_PATHS_DEFAULT}") option(BOOST_IGNORE_SYSTEM_PATHS "Ignore boost system paths for local boost installation" ${BOOST_IGNORE_SYSTEM_PATHS_DEFAULT}) + +if (NOT DEFINED ENV{DEVELOPER_LIBUNBOUND_OLD}) + message(STATUS "Could not find DEVELOPER_LIBUNBOUND_OLD in env (not required)") +elseif ("$ENV{DEVELOPER_LIBUNBOUND_OLD}" EQUAL 1) + message(STATUS "Found: env DEVELOPER_LIBUNBOUND_OLD = 1, will use the work around") + add_definitions(-DDEVELOPER_LIBUNBOUND_OLD) +elseif ("$ENV{DEVELOPER_LIBUNBOUND_OLD}" EQUAL 0) + message(STATUS "Found: env DEVELOPER_LIBUNBOUND_OLD = 0") +else() + message(STATUS "Found: env DEVELOPER_LIBUNBOUND_OLD with bad value. Will NOT use the work around") +endif() + set_property(GLOBAL PROPERTY USE_FOLDERS ON) enable_testing() +option(BUILD_DOCUMENTATION "Build the Doxygen documentation." ON) + + # Check if we're on FreeBSD so we can exclude the local miniupnpc (it should be installed from ports instead) # CMAKE_SYSTEM_NAME checks are commonly known, but specifically taken from libsdl's CMakeLists if(CMAKE_SYSTEM_NAME MATCHES "kFreeBSD.*") @@ -276,3 +291,28 @@ add_subdirectory(src) if(BUILD_TESTS) add_subdirectory(tests) endif() + + + +if(BUILD_DOCUMENTATION) + set(DOC_GRAPHS "YES" CACHE STRING "Create dependency graphs (needs graphviz)") + set(DOC_FULLGRAPHS "NO" CACHE STRING "Create call/callee graphs (large)") + + find_program(DOT_PATH dot) + + if (DOT_PATH STREQUAL "DOT_PATH-NOTFOUND") + message("Doxygen: graphviz not found - graphs disabled") + set(DOC_GRAPHS "NO") + endif() + + find_package(Doxygen) + if(DOXYGEN_FOUND) + configure_file("cmake/Doxyfile.in" "Doxyfile" @ONLY) + configure_file("cmake/Doxygen.extra.css.in" "Doxygen.extra.css" @ONLY) + add_custom_target(doc + ${DOXYGEN_EXECUTABLE} ${CMAKE_CURRENT_BINARY_DIR}/Doxyfile + WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR} + COMMENT "Generating API documentation with Doxygen.." VERBATIM) + endif() +endif() + diff --git a/contrib/epee/include/net/levin_protocol_handler_async.h b/contrib/epee/include/net/levin_protocol_handler_async.h index 92f75161a..dacbfd4d9 100644 --- a/contrib/epee/include/net/levin_protocol_handler_async.h +++ b/contrib/epee/include/net/levin_protocol_handler_async.h @@ -690,7 +690,6 @@ void async_protocol_handler_config::del_out_connections(si { close(*out_connections.begin()); del_connection(m_connects.at(*out_connections.begin())); - out_connections.erase(out_connections.begin()); --count; } diff --git a/contrib/otshell_utils/utils.cpp b/contrib/otshell_utils/utils.cpp index ff39d15e8..3ca84da8e 100644 --- a/contrib/otshell_utils/utils.cpp +++ b/contrib/otshell_utils/utils.cpp @@ -40,6 +40,7 @@ #error "Compiler/OS platform detection failed - not supported" #endif + namespace nOT { namespace nUtils { @@ -246,6 +247,13 @@ bool cFilesystemUtils::CreateDirTree(const std::string & dir, bool only_below) { namespace nDetail { +struct channel_use_info { ///< feedback information about using (e.g. opening) given debug channel - used internally by logging system +/// TODO not yet used in code +/// e.g. used to write into channel net/in/all that given message was a first logged message from never-before-logged thread or PID etc + bool m_was_interesting; ///< anything interesting happened when using the channel? + std::vector m_extra_msg; ///< any additional messages about this channel use +}; + cDebugScopeGuard::cDebugScopeGuard() : mLevel(-1) { } @@ -269,13 +277,18 @@ cLogger::cLogger() : mStream(NULL), mStreamBrokenDebug(NULL), mIsBroken(true), // before constructor finishes -mLevel(85), -mThread2Number_Biggest(0) // the CURRENT biggest value (no thread yet in map) +mLevel(70), +mThread2Number_Biggest(0), // the CURRENT biggest value (no thread yet in map) +mPid2Number_Biggest(0) { mStream = & std::cout; - mStreamBrokenDebug = & std::cerr; - Thread2Number( std::this_thread::get_id() ); // convert current id to short number, useful to reserve a number so that main thread is usually called 1 + mStreamBrokenDebug = & std::cerr; // the backup stream + *mStreamBrokenDebug << "Creating the logger system" << endl; mIsBroken=false; // ok, constr. succeeded, so string is not broken now + + // this is here, because it could be using logging itself to log creation of first thread/PID etc + Thread2Number( std::this_thread::get_id() ); // convert current id to short number, useful to reserve a number so that main thread is usually called 1 + Pid2Number( getpid() ); // add this proces ID as first one } cLogger::~cLogger() { @@ -291,7 +304,9 @@ void cLogger::SetStreamBroken() { } void cLogger::SetStreamBroken(const std::string &msg) { + _dbg_dbg("Stream is broken (msg: " << msg << ")"); if (!mIsBroken) { // if not already marked as broken + _dbg_dbg("(It was not broken before)"); std::cerr << OT_CODE_STAMP << "WARNING: due to debug stream problem ("<= mLevel) && (mStream)) { // TODO now disabling mStream also disables writting to any channel - ostream & output = SelectOutput(level,channel); - output << icon(level) << ' '; - std::thread::id this_id = std::this_thread::get_id(); - output << "{" << Thread2Number(this_id) << "} "; - return output; - } + _dbg_dbg("level="<0) output << " {p" << nicePid << "}"; + output << ' '; + return output; // <--- return + } else _dbg_dbg("Not writting: No mStream"); + } else _dbg_dbg("Not writting: Too low level level="<= mLevel="<(channel , thefile ) ); // <- created the channel mapping } std::ostream & cLogger::SelectOutput(int level, const std::string & channel) noexcept { try { - if (mIsBroken) return *mStreamBrokenDebug; - if (channel=="") return *mStream; + if (mIsBroken) { + _dbg_dbg("The stream is broken mIsBroken="<second; + _dbg_dbg("Found the stream file for channel="<= 100) return cc::back::red + ToStr(cc::fore::black) + ToStr("ERROR ") + ToStr(cc::fore::lightyellow) + " " ; + #if defined(OS_TYPE_POSIX) + if (level >= 100) return cc::back::lightred + ToStr(cc::fore::lightyellow) + ToStr("ERROR ") + ToStr(cc::fore::lightyellow) + " " ; if (level >= 90) return cc::back::lightyellow + ToStr(cc::fore::black) + ToStr("Warn ") + ToStr(cc::fore::red)+ " " ; if (level >= 80) return cc::back::lightmagenta + ToStr(cc::fore::black) + ToStr("MARK "); //+ zkr::cc::console + ToStr(cc::fore::lightmagenta)+ " "; - if (level >= 75) return cc::back::lightyellow + ToStr(cc::fore::black) + ToStr("FACT ") + zkr::cc::console + ToStr(cc::fore::lightyellow)+ " "; + if (level >= 75) return cc::back::lightyellow + ToStr(cc::fore::black) + ToStr("FACT ") + zkr::cc::console + ToStr(cc::fore::lightyellow)+ " "; if (level >= 70) return cc::fore::green + ToStr("Note "); if (level >= 50) return cc::fore::cyan + ToStr("info "); if (level >= 40) return cc::fore::lightwhite + ToStr("dbg "); if (level >= 30) return cc::fore::lightblue + ToStr("dbg "); if (level >= 20) return cc::fore::blue + ToStr("dbg "); + #elif defined(OS_TYPE_WINDOWS) + if (level >= 100) return ToStr("ERROR "); + if (level >= 90) return ToStr("Warn "); + if (level >= 80) return ToStr("MARK "); + if (level >= 75) return ToStr("FACT "); + if (level >= 70) return ToStr("Note "); + if (level >= 50) return ToStr("info "); + if (level >= 40) return ToStr("dbg "); + if (level >= 30) return ToStr("dbg "); + if (level >= 20) return ToStr("dbg "); + #endif + return " "; } std::string cLogger::endline() const { + #if defined(OS_TYPE_POSIX) return ToStr("") + zkr::cc::console + ToStr("\n"); // TODO replan to avoid needles converting back and forth char*, string etc + #elif defined(OS_TYPE_WINDOWS) + return ToStr("\n"); + #endif } int cLogger::Thread2Number(const std::thread::id id) { @@ -451,13 +506,24 @@ int cLogger::Thread2Number(const std::thread::id id) { if (found == mThread2Number.end()) { // new one mThread2Number_Biggest++; mThread2Number[id] = mThread2Number_Biggest; + _mark_c("dbg/main", "This is a new thread (used in debug), thread id="< & gLoggerGuardDepth_Get(); // getter for the global singleton o // detect stream e.g. operator<< error #define _debug_level(LEVEL,VAR) do { if (_dbg_ignore< LEVEL) { \ + _dbg_dbg("WRITE DEBUG: LEVEL="< mutex_guard( nOT::nUtils::gLoggerGuard ); \ @@ -93,6 +108,7 @@ std::atomic & gLoggerGuardDepth_Get(); // getter for the global singleton o // info for code below: oss object is normal stack variable, using it does not need lock protection #define _debug_level_c(CHANNEL,LEVEL,VAR) do { if (_dbg_ignore< LEVEL) { \ + _dbg_dbg("WRITE DEBUG: LEVEL="< mutex_guard( nOT::nUtils::gLoggerGuard ); \ @@ -102,9 +118,11 @@ std::atomic & gLoggerGuardDepth_Get(); // getter for the global singleton o std::ostringstream oss; \ oss << nOT::nUtils::get_current_time() << ' ' << OT_CODE_STAMP << ' ' << VAR << gCurrentLogger.endline() << std::flush; \ std::string as_string = oss.str(); \ + _dbg_dbg("START will write to log LEVEL="< mThread2Number; // change long thread IDs into a short nice number to show - int mThread2Number_Biggest; // current biggest value held there (biggest key) - works as growing-only counter basically - int Thread2Number(const std::thread::id id); // convert the system's thread id into a nice short our id; make one if new thread + std::map< std::thread::id , int > mThread2Number; ///< change long thread IDs into a short nice number to show + int mThread2Number_Biggest; ///< current biggest value held there (biggest key) - works as growing-only counter basically + int Thread2Number(const std::thread::id id); ///< convert the system's thread id into a nice short our id; make one if new thread + + std::map< t_anypid , int > mPid2Number; ///< change long proces PID into a short nice number to show + int mPid2Number_Biggest; ///< current biggest value held there (biggest key) - works as growing-only counter basically + int Pid2Number(const t_anypid id); ///< convert the system's PID id into a nice short our id; make one if new thread }; diff --git a/src/common/command_line.cpp b/src/common/command_line.cpp index 36d9905b8..d2cd75e5b 100644 --- a/src/common/command_line.cpp +++ b/src/common/command_line.cpp @@ -48,4 +48,7 @@ namespace command_line const arg_descriptor arg_version = {"version", "Output version information"}; const arg_descriptor arg_data_dir = {"data-dir", "Specify data directory"}; const arg_descriptor arg_testnet_data_dir = {"testnet-data-dir", "Specify testnet data directory"}; + const arg_descriptor arg_test_drop_download = {"test-drop-download", "For net tests: in download, discard ALL blocks instead checking/saving them (very fast)"}; + const arg_descriptor arg_test_drop_download_height = {"test-drop-download-height", "Like test-drop-download but disards only after around certain height", 0}; + const arg_descriptor arg_test_dbg_lock_sleep = {"test-dbg-lock-sleep", "Sleep time in ms, defaults to 0 (off), used to debug before/after locking mutex. Values 100 to 1000 are good for tests."}; } diff --git a/src/common/command_line.h b/src/common/command_line.h index 5176f0f67..ae79f0a05 100644 --- a/src/common/command_line.h +++ b/src/common/command_line.h @@ -204,4 +204,7 @@ namespace command_line extern const arg_descriptor arg_version; extern const arg_descriptor arg_data_dir; extern const arg_descriptor arg_testnet_data_dir; + extern const arg_descriptor arg_test_drop_download; + extern const arg_descriptor arg_test_drop_download_height; + extern const arg_descriptor arg_test_dbg_lock_sleep; } diff --git a/src/common/dns_utils.cpp b/src/common/dns_utils.cpp index 4ab93cce8..38b880231 100644 --- a/src/common/dns_utils.cpp +++ b/src/common/dns_utils.cpp @@ -168,7 +168,24 @@ DNSResolver::DNSResolver() : m_data(new DNSResolverData()) ub_ctx_resolvconf(m_data->m_ub_context, &empty_string); ub_ctx_hosts(m_data->m_ub_context, &empty_string); - ub_ctx_add_ta(m_data->m_ub_context, ::get_builtin_ds()); + #ifdef DEVELOPER_LIBUNBOUND_OLD + #warning "Using the work around for old libunbound" + { // work around for bug https://www.nlnetlabs.nl/bugs-script/show_bug.cgi?id=515 needed for it to compile on e.g. Debian 7 + char * ds_copy = NULL; // this will be the writable copy of string that bugged version of libunbound requires + try { + char * ds_copy = strdup( ::get_builtin_ds() ); + ub_ctx_add_ta(m_data->m_ub_context, ds_copy); + } catch(...) { // probably not needed but to work correctly in every case... + if (ds_copy) { free(ds_copy); ds_copy=NULL; } // for the strdup + throw ; + } + if (ds_copy) { free(ds_copy); ds_copy=NULL; } // for the strdup + } + #else + // normal version for fixed libunbound + ub_ctx_add_ta(m_data->m_ub_context, ::get_builtin_ds() ); + #endif + } DNSResolver::~DNSResolver() diff --git a/src/cryptonote_core/cryptonote_core.cpp b/src/cryptonote_core/cryptonote_core.cpp index 505feb563..9be5eca9b 100644 --- a/src/cryptonote_core/cryptonote_core.cpp +++ b/src/cryptonote_core/cryptonote_core.cpp @@ -145,6 +145,11 @@ namespace cryptonote set_enforce_dns_checkpoints(command_line::get_arg(vm, daemon_args::arg_dns_checkpoints)); + test_drop_download_height(command_line::get_arg(vm, command_line::arg_test_drop_download_height)); + + if (command_line::get_arg(vm, command_line::arg_test_drop_download) == true) + test_drop_download(); + return true; } //----------------------------------------------------------------------------------------------- diff --git a/src/cryptonote_protocol/cryptonote_protocol_defs.h b/src/cryptonote_protocol/cryptonote_protocol_defs.h index f761274c5..7e019b533 100644 --- a/src/cryptonote_protocol/cryptonote_protocol_defs.h +++ b/src/cryptonote_protocol/cryptonote_protocol_defs.h @@ -46,6 +46,8 @@ namespace cryptonote struct connection_info { bool incoming; + bool localhost; + bool local_ip; std::string ip; std::string port; @@ -62,8 +64,16 @@ namespace cryptonote uint64_t live_time; + uint64_t avg_download; + uint64_t current_download; + + uint64_t avg_upload; + uint64_t current_upload; + BEGIN_KV_SERIALIZE_MAP() KV_SERIALIZE(incoming) + KV_SERIALIZE(localhost) + KV_SERIALIZE(local_ip) KV_SERIALIZE(ip) KV_SERIALIZE(port) KV_SERIALIZE(peer_id) @@ -73,6 +83,10 @@ namespace cryptonote KV_SERIALIZE(send_idle_time) KV_SERIALIZE(state) KV_SERIALIZE(live_time) + KV_SERIALIZE(avg_download) + KV_SERIALIZE(current_download) + KV_SERIALIZE(avg_upload) + KV_SERIALIZE(current_upload) END_KV_SERIALIZE_MAP() }; diff --git a/src/cryptonote_protocol/cryptonote_protocol_handler.inl b/src/cryptonote_protocol/cryptonote_protocol_handler.inl index 023dd03a6..1cf66521f 100644 --- a/src/cryptonote_protocol/cryptonote_protocol_handler.inl +++ b/src/cryptonote_protocol/cryptonote_protocol_handler.inl @@ -210,6 +210,42 @@ namespace cryptonote cnx.live_time = timestamp - cntxt.m_started; + uint32_t ip; + ip = ntohl(cntxt.m_remote_ip); + if (ip == LOCALHOST_INT) + { + cnx.localhost = true; + } + else + { + cnx.localhost = false; + } + + if (ip > 3232235520 && ip < 3232301055) // 192.168.x.x + { + cnx.local_ip = true; + } + else + { + cnx.local_ip = false; + } + + auto connection_time = time(NULL) - cntxt.m_started; + if (connection_time == 0) + { + cnx.avg_download = 0; + cnx.avg_upload = 0; + } + + else + { + cnx.avg_download = cntxt.m_recv_cnt / connection_time / 1024; + cnx.avg_upload = cntxt.m_send_cnt / connection_time / 1024; + } + + cnx.current_download = cntxt.m_current_speed_down / 1024; + cnx.current_upload = cntxt.m_current_speed_up / 1024; + connections.push_back(cnx); return true; @@ -543,6 +579,7 @@ namespace cryptonote LOG_PRINT_CCONTEXT_L2("Block process time: " << block_process_time + transactions_process_time << "(" << transactions_process_time << "/" << block_process_time << ")ms"); epee::net_utils::data_logger::get_instance().add_data("calc_time", block_process_time + transactions_process_time); + epee::net_utils::data_logger::get_instance().add_data("block_processing", 1); } // each download block diff --git a/src/daemon/CMakeLists.txt b/src/daemon/CMakeLists.txt index 4de8b82b8..f9c2af32a 100644 --- a/src/daemon/CMakeLists.txt +++ b/src/daemon/CMakeLists.txt @@ -77,6 +77,9 @@ target_link_libraries(daemon cryptonote_core crypto common + otshell_utils + p2p + cryptonote_protocol daemonizer ${Boost_CHRONO_LIBRARY} ${Boost_FILESYSTEM_LIBRARY} diff --git a/src/daemon/command_parser_executor.cpp b/src/daemon/command_parser_executor.cpp index 8f023da9a..fd7b40be2 100644 --- a/src/daemon/command_parser_executor.cpp +++ b/src/daemon/command_parser_executor.cpp @@ -296,4 +296,41 @@ bool t_command_parser_executor::set_limit_down(const std::vector& a return m_executor.set_limit_down(limit); } + +bool t_command_parser_executor::fast_exit(const std::vector& args) +{ + if (!args.empty()) return false; + return m_executor.fast_exit(); +} + +bool t_command_parser_executor::out_peers(const std::vector& args) +{ + if (args.empty()) return false; + + unsigned int limit; + try { + limit = std::stoi(args[0]); + } + + catch(std::invalid_argument& ex) { + _erro("stoi exception"); + return false; + } + + return m_executor.out_peers(limit); +} + +bool t_command_parser_executor::start_save_graph(const std::vector& args) +{ + if (!args.empty()) return false; + return m_executor.start_save_graph(); +} + +bool t_command_parser_executor::stop_save_graph(const std::vector& args) +{ + if (!args.empty()) return false; + return m_executor.stop_save_graph(); +} + + } // namespace daemonize diff --git a/src/daemon/command_parser_executor.h b/src/daemon/command_parser_executor.h index 07d2e70a9..27ffabc1c 100644 --- a/src/daemon/command_parser_executor.h +++ b/src/daemon/command_parser_executor.h @@ -93,6 +93,13 @@ public: bool set_limit_down(const std::vector& args); + bool fast_exit(const std::vector& args); + + bool out_peers(const std::vector& args); + + bool start_save_graph(const std::vector& args); + + bool stop_save_graph(const std::vector& args); }; } // namespace daemonize diff --git a/src/daemon/command_server.cpp b/src/daemon/command_server.cpp index 601b12d57..f0f4cd676 100644 --- a/src/daemon/command_server.cpp +++ b/src/daemon/command_server.cpp @@ -150,15 +150,35 @@ t_command_server::t_command_server( , "limit - Set download and upload limit" ); m_command_lookup.set_handler( - "limit-up" + "limit_up" , std::bind(&t_command_parser_executor::set_limit_up, &m_parser, p::_1) , "limit - Set upload limit" ); m_command_lookup.set_handler( - "limit-down" + "limit_down" , std::bind(&t_command_parser_executor::set_limit_down, &m_parser, p::_1) , "limit - Set download limit" ); + m_command_lookup.set_handler( + "fast_exit" + , std::bind(&t_command_parser_executor::fast_exit, &m_parser, p::_1) + , "Exit" + ); + m_command_lookup.set_handler( + "out_peers" + , std::bind(&t_command_parser_executor::out_peers, &m_parser, p::_1) + , "Set max limit of out peers" + ); + m_command_lookup.set_handler( + "start_save_graph" + , std::bind(&t_command_parser_executor::start_save_graph, &m_parser, p::_1) + , "Start save data for dr monero" + ); + m_command_lookup.set_handler( + "stop_save_graph" + , std::bind(&t_command_parser_executor::stop_save_graph, &m_parser, p::_1) + , "Stop save data for dr monero" + ); } bool t_command_server::process_command_str(const std::string& cmd) diff --git a/src/daemon/daemon.cpp b/src/daemon/daemon.cpp index ec12c281c..7931ba03f 100644 --- a/src/daemon/daemon.cpp +++ b/src/daemon/daemon.cpp @@ -1,5 +1,5 @@ -// Copyright (c) 2014, The Monero Project -// +// Copyright (c) 2014-2015, The Monero Project +// // All rights reserved. // // Redistribution and use in source and binary forms, with or without modification, are @@ -38,10 +38,16 @@ #include "daemon/command_server.h" #include "misc_log_ex.h" #include "version.h" +#include "../../contrib/epee/include/syncobj.h" + +using namespace epee; + #include #include #include +unsigned int epee::g_test_dbg_lock_sleep = 0; + namespace daemonize { struct t_internals { diff --git a/src/daemon/daemon_commands_handler.h b/src/daemon/daemon_commands_handler.h index 7baca596d..215cf26de 100644 --- a/src/daemon/daemon_commands_handler.h +++ b/src/daemon/daemon_commands_handler.h @@ -1,7 +1,35 @@ -// 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. - +// 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... */ #pragma once #include @@ -44,10 +72,14 @@ 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 - Change current log detalization 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"); + m_cmd_binder.set_handler("limit_up", boost::bind(&daemon_cmmands_handler::limit_up, this, _1), "Set upload limit [kB/s]"); + m_cmd_binder.set_handler("limit_down", boost::bind(&daemon_cmmands_handler::limit_down, this, _1), "Set download limit [kB/s]"); + m_cmd_binder.set_handler("limit", boost::bind(&daemon_cmmands_handler::limit, this, _1), "Set download and upload limit [kB/s]"); + m_cmd_binder.set_handler("fast_exit", boost::bind(&daemon_cmmands_handler::fast_exit, this, _1), "Exit"); + m_cmd_binder.set_handler("test_drop_download", boost::bind(&daemon_cmmands_handler::test_drop_download, this, _1), "For network testing, drop downloaded blocks instead checking/adding them to blockchain. Can fake-download blocks very fast."); + m_cmd_binder.set_handler("start_save_graph", boost::bind(&daemon_cmmands_handler::start_save_graph, this, _1), ""); + m_cmd_binder.set_handler("stop_save_graph", boost::bind(&daemon_cmmands_handler::stop_save_graph, this, _1), ""); } bool start_handling() @@ -328,6 +360,8 @@ private: PUSH_WARNINGS DISABLE_GCC_WARNING(maybe-uninitialized) log_space::log_singletone::get_set_log_detalisation_level(true, l); + int otshell_utils_log_level = 100 - (l * 25); + gCurrentLogger.setDebugLevel(otshell_utils_log_level); POP_WARNINGS return true; @@ -492,160 +526,4 @@ POP_WARNINGS m_srv.get_payload_object().get_core().get_miner().stop(); return true; } - //-------------------------------------------------------------------------------- - bool out_peers_limit(const std::vector& args) { - if(args.size()!=1) { - std::cout << "Usage: out_peers " << ENDL; - return true; - } - - unsigned int limit; - try { - limit = std::stoi(args[0]); - } - - catch(std::invalid_argument& ex) { - _erro("stoi exception"); - return false; - } - - if (m_srv.m_config.m_net_config.connections_count > limit) - { - m_srv.m_config.m_net_config.connections_count = limit; - epee::net_utils::data_logger::get_instance().add_data("peers_limit", m_srv.m_config.m_net_config.connections_count); - if (m_srv.m_current_number_of_out_peers > limit) - { - int count = m_srv.m_current_number_of_out_peers - limit; - m_srv.delete_connections(count); - } - } - else - { - m_srv.m_config.m_net_config.connections_count = limit; - epee::net_utils::data_logger::get_instance().add_data("peers_limit", m_srv.m_config.m_net_config.connections_count); - } - - return true; - } - //-------------------------------------------------------------------------------- - bool limit_up(const std::vector& args) - { - if(args.size()!=1) { - std::cout << "Usage: limit_up " << 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 >::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& args) - { - - if(args.size()!=1) { - std::cout << "Usage: limit_down " << 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 >::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& args) - { - if(args.size()!=1) { - std::cout << "Usage: limit_down " << 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 >::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 fast_exit(const std::vector& args) - { - m_srv.get_payload_object().get_core().set_fast_exit(); - m_srv.send_stop_signal(); - return true; - } - //-------------------------------------------------------------------------------- - bool test_drop_download(const std::vector& args) - { - m_srv.get_payload_object().get_core().test_drop_download(); - return true; - } - //-------------------------------------------------------------------------------- - bool start_save_graph(const std::vector& args) - { - m_srv.set_save_graph(true); - return true; - } - //-------------------------------------------------------------------------------- - bool stop_save_graph(const std::vector& args) - { - m_srv.set_save_graph(false); - return true; - } }; diff --git a/src/daemon/main.cpp b/src/daemon/main.cpp index 5d8baf497..6f7511e2a 100644 --- a/src/daemon/main.cpp +++ b/src/daemon/main.cpp @@ -71,7 +71,10 @@ int main(int argc, char const * argv[]) command_line::add_arg(visible_options, command_line::arg_testnet_data_dir, default_testnet_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()); - + command_line::add_arg(visible_options, command_line::arg_test_drop_download); + command_line::add_arg(visible_options, command_line::arg_test_dbg_lock_sleep); + command_line::add_arg(visible_options, command_line::arg_test_drop_download_height); + // 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()); @@ -127,6 +130,8 @@ int main(int argc, char const * argv[]) std::cout << "OS: " << tools::get_os_version_string() << ENDL; return 0; } + + epee::g_test_dbg_lock_sleep = command_line::get_arg(vm, command_line::arg_test_dbg_lock_sleep); bool testnet_mode = command_line::get_arg(vm, daemon_args::arg_testnet_on); @@ -209,6 +214,8 @@ int main(int argc, char const * argv[]) 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); + int otshell_utils_log_level = 100 - (new_log_level * 25); + gCurrentLogger.setDebugLevel(otshell_utils_log_level); LOG_PRINT_L0("LOG_LEVEL set to " << new_log_level); } } @@ -223,6 +230,7 @@ int main(int argc, char const * argv[]) , log_file_path.parent_path().string().c_str() ); } + _erro("Test error"); return daemonizer::daemonize(argc, argv, daemonize::t_executor{}, vm); } diff --git a/src/daemon/rpc_command_executor.cpp b/src/daemon/rpc_command_executor.cpp index f06f48544..46900b071 100644 --- a/src/daemon/rpc_command_executor.cpp +++ b/src/daemon/rpc_command_executor.cpp @@ -32,6 +32,7 @@ #include "common/scoped_message_writer.h" #include "daemon/rpc_command_executor.h" #include "rpc/core_rpc_server_commands_defs.h" +#include "cryptonote_core/cryptonote_core.h" #include #include @@ -267,11 +268,38 @@ bool t_rpc_command_executor::print_connections() { } } + tools::msg_writer() << std::setw(30) << std::left << "Remote Host" + << std::setw(20) << "Peer id" + << std::setw(30) << "Recv/Sent (inactive,sec)" + << std::setw(25) << "State" + << std::setw(20) << "Livetime(sec)" + << std::setw(12) << "Down (kB/s)" + << std::setw(14) << "Down(now)" + << std::setw(10) << "Up (kB/s)" + << std::setw(13) << "Up(now)" + << std::endl; + 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; + std::string address = info.incoming ? "INC " : "OUT "; + address += info.ip + ":" + info.port; + //std::string in_out = info.incoming ? "INC " : "OUT "; + tools::msg_writer() + //<< std::setw(30) << std::left << in_out + << std::setw(30) << std::left << address + << std::setw(20) << info.peer_id + << std::setw(30) << std::to_string(info.recv_count) + "(" + std::to_string(info.recv_idle_time) + ")/" + std::to_string(info.send_count) + "(" + std::to_string(info.send_idle_time) + ")" + << std::setw(25) << info.state + << std::setw(20) << info.live_time + << std::setw(12) << info.avg_download + << std::setw(14) << info.current_download + << std::setw(10) << info.avg_upload + << std::setw(13) << info.current_upload + + << std::left << (info.localhost ? "[LOCALHOST]" : "") + << std::left << (info.local_ip ? "[LAN]" : ""); + //tools::msg_writer() << boost::format("%-25s peer_id: %-25s %s") % address % info.peer_id % in_out; + } return true; @@ -659,34 +687,134 @@ bool t_rpc_command_executor::print_status() 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; } +bool t_rpc_command_executor::fast_exit() +{ + cryptonote::COMMAND_RPC_FAST_EXIT::request req; + cryptonote::COMMAND_RPC_FAST_EXIT::response res; + + std::string fail_message = "Daemon did not stop"; + + if (m_is_rpc) + { + if (!m_rpc_client->rpc_request(req, res, "/fast_exit", fail_message.c_str())) + { + return true; + } + } + + else + { + if (!m_rpc_server->on_fast_exit(req, res)) + { + tools::fail_msg_writer() << fail_message.c_str(); + return true; + } + } + + tools::success_msg_writer() << "Daemon stopped"; + return true; +} + +bool t_rpc_command_executor::out_peers(uint64_t limit) +{ + cryptonote::COMMAND_RPC_OUT_PEERS::request req; + cryptonote::COMMAND_RPC_OUT_PEERS::response res; + + epee::json_rpc::error error_resp; + + req.out_peers = limit; + + std::string fail_message = "Unsuccessful"; + + if (m_is_rpc) + { + if (!m_rpc_client->json_rpc_request(req, res, "/out_peers", fail_message.c_str())) + { + return true; + } + } + else + { + if (!m_rpc_server->on_out_peers(req, res)) + { + tools::fail_msg_writer() << fail_message.c_str(); + return true; + } + } + + return true; +} + +bool t_rpc_command_executor::start_save_graph() +{ + cryptonote::COMMAND_RPC_START_SAVE_GRAPH::request req; + cryptonote::COMMAND_RPC_START_SAVE_GRAPH::response res; + std::string fail_message = "Unsuccessful"; + + if (m_is_rpc) + { + if (!m_rpc_client->rpc_request(req, res, "/start_save_graph", fail_message.c_str())) + { + return true; + } + } + + else + { + if (!m_rpc_server->on_start_save_graph(req, res)) + { + tools::fail_msg_writer() << fail_message.c_str(); + return true; + } + } + + return true; +} + +bool t_rpc_command_executor::stop_save_graph() +{ + cryptonote::COMMAND_RPC_STOP_SAVE_GRAPH::request req; + cryptonote::COMMAND_RPC_STOP_SAVE_GRAPH::response res; + std::string fail_message = "Unsuccessful"; + + if (m_is_rpc) + { + if (!m_rpc_client->rpc_request(req, res, "/stop_save_graph", fail_message.c_str())) + { + return true; + } + } + + else + { + if (!m_rpc_server->on_stop_save_graph(req, res)) + { + tools::fail_msg_writer() << fail_message.c_str(); + return true; + } + } + return true; +} + }// namespace daemonize diff --git a/src/daemon/rpc_command_executor.h b/src/daemon/rpc_command_executor.h index fe0181e62..43b8a9fe0 100644 --- a/src/daemon/rpc_command_executor.h +++ b/src/daemon/rpc_command_executor.h @@ -105,7 +105,13 @@ public: bool set_limit_down(int limit); - + bool fast_exit(); + + bool out_peers(uint64_t limit); + + bool start_save_graph(); + + bool stop_save_graph(); }; } // namespace daemonize diff --git a/src/p2p/data_logger.cpp b/src/p2p/data_logger.cpp index 69e50141a..bbb9fba3e 100644 --- a/src/p2p/data_logger.cpp +++ b/src/p2p/data_logger.cpp @@ -43,6 +43,7 @@ namespace net_utils mFilesMap["sleep_up"] = data_logger::fileData("log/dr-monero/up_sleep_log.data"); mFilesMap["calc_time"] = data_logger::fileData("log/dr-monero/get_objects_calc_time.data"); mFilesMap["blockchain_processing_time"] = data_logger::fileData("log/dr-monero/blockchain_log.data"); + mFilesMap["block_processing"] = data_logger::fileData("log/dr-monero/block_proc.data"); mFilesMap["peers_limit"] = data_logger::fileData("log/dr-monero/peers_limit.info"); mFilesMap["download_limit"] = data_logger::fileData("log/dr-monero/limit_down.info"); @@ -109,6 +110,15 @@ namespace net_utils mFilesMap[filename].mDataToSave += data; // this holds a number that should be sum of all accumulated samples } } + + bool data_logger::is_dying() { + if (m_state == data_logger_state::state_dying) { + return true; + } + else { + return false; + } + } void data_logger::saveToFile() { _dbg2_c("dbg/data","saving to files"); @@ -125,10 +135,13 @@ namespace net_utils // the inner class: double data_logger::fileData::get_current_time() { - using namespace boost::chrono; - auto point = steady_clock::now(); + #if defined(__APPLE__) + auto point = std::chrono::system_clock::now(); + #else + auto point = std::chrono::steady_clock::now(); + #endif auto time_from_epoh = point.time_since_epoch(); - auto ms = duration_cast< milliseconds >( time_from_epoh ).count(); + auto ms = std::chrono::duration_cast< std::chrono::milliseconds >( time_from_epoh ).count(); double ms_f = ms; return ms_f / 1000.; } diff --git a/src/p2p/data_logger.hpp b/src/p2p/data_logger.hpp index 215912167..f38dacdcb 100644 --- a/src/p2p/data_logger.hpp +++ b/src/p2p/data_logger.hpp @@ -40,6 +40,7 @@ enum class data_logger_state { state_before_init, state_during_init, state_ready void add_data(std::string filename, unsigned int data); ///< use this to append data here. Use it only the singleton. It locks itself. static std::atomic m_save_graph; ///< global setting flag, should we save all the data or not (can disable logging graphs data) + static bool is_dying(); private: static std::once_flag m_singleton; ///< to guarantee singleton creates the object exactly once diff --git a/src/p2p/net_node.h b/src/p2p/net_node.h index f94fedae0..d956b37f0 100644 --- a/src/p2p/net_node.h +++ b/src/p2p/net_node.h @@ -80,13 +80,16 @@ namespace nodetool public: typedef t_payload_net_handler payload_net_handler; - node_server( - t_payload_net_handler& payload_handler - ) - : m_payload_handler(payload_handler) - , m_allow_local_ip(false) - , m_hide_my_port(false) - {} + node_server(t_payload_net_handler& payload_handler) + :m_payload_handler(payload_handler), + m_allow_local_ip(false), + m_no_igd(false), + m_hide_my_port(false) + { + m_current_number_of_out_peers = 0; + m_save_graph = false; + is_closing = false; + } static void init_options(boost::program_options::options_description& desc); @@ -233,12 +236,12 @@ namespace nodetool public: config m_config; // TODO was private, add getters? std::atomic m_current_number_of_out_peers; + void set_save_graph(bool save_graph) { m_save_graph = save_graph; epee::net_utils::connection_basic::set_save_graph(save_graph); } - private: std::string m_config_folder; diff --git a/src/p2p/net_node.inl b/src/p2p/net_node.inl index ef158d9a1..c7413ec15 100644 --- a/src/p2p/net_node.inl +++ b/src/p2p/net_node.inl @@ -46,6 +46,7 @@ #include "net/local_ip.h" #include "crypto/crypto.h" #include "storages/levin_abstract_invoke2.h" +#include "data_logger.hpp" #include "daemon/command_line_args.h" // We have to look for miniupnpc headers in different places, dependent on if its compiled or external @@ -93,6 +94,8 @@ namespace nodetool const command_line::arg_descriptor arg_limit_rate_up = {"limit-rate-up", "set limit-rate-up [kB/s]", -1}; const command_line::arg_descriptor arg_limit_rate_down = {"limit-rate-down", "set limit-rate-down [kB/s]", -1}; const command_line::arg_descriptor arg_limit_rate = {"limit-rate", "set limit-rate [kB/s]", 128}; + + const command_line::arg_descriptor arg_save_graph = {"save-graph", "Save data for dr monero", false}; } //----------------------------------------------------------------------------------- @@ -114,7 +117,9 @@ namespace nodetool command_line::add_arg(desc, arg_tos_flag); command_line::add_arg(desc, arg_limit_rate_up); command_line::add_arg(desc, arg_limit_rate_down); - command_line::add_arg(desc, arg_limit_rate); } + command_line::add_arg(desc, arg_limit_rate); + command_line::add_arg(desc, arg_save_graph); + } //----------------------------------------------------------------------------------- template bool node_server::init_config() @@ -193,6 +198,11 @@ namespace nodetool m_command_line_peers.push_back(pe); } } + + if(command_line::has_arg(vm, arg_save_graph)) + { + set_save_graph(true); + } if (command_line::has_arg(vm,arg_p2p_add_exclusive_node)) { @@ -294,29 +304,6 @@ namespace nodetool std::vector> dns_results; dns_results.resize(m_seed_nodes_list.size()); - - // creating thread to log number of connections - mPeersLoggerThread.reset(new std::thread([&]() - { - _note("Thread monitor number of peers - start"); - while (!is_closing) - { // main loop of thread - //number_of_peers = m_net_server.get_config_object().get_connections_count(); - unsigned int number_of_peers = 0; - m_net_server.get_config_object().foreach_connection([&](const p2p_connection_context& cntxt) - { - if (!cntxt.m_is_income) ++number_of_peers; - return true; - }); // lambda - - m_current_number_of_out_peers = number_of_peers; - epee::net_utils::data_logger::get_instance().add_data("peers", number_of_peers); - - std::this_thread::sleep_for(std::chrono::seconds(1)); - } // main loop of thread - _note("Thread monitor number of peers - done"); - })); // lambda - std::list dns_threads; uint64_t result_index = 0; @@ -483,6 +470,30 @@ namespace nodetool template bool node_server::run() { + // creating thread to log number of connections + mPeersLoggerThread.reset(new std::thread([&]() + { + _note("Thread monitor number of peers - start"); + while (!is_closing) + { // main loop of thread + //number_of_peers = m_net_server.get_config_object().get_connections_count(); + unsigned int number_of_peers = 0; + m_net_server.get_config_object().foreach_connection([&](const p2p_connection_context& cntxt) + { + if (!cntxt.m_is_income) ++number_of_peers; + return true; + }); // lambda + + m_current_number_of_out_peers = number_of_peers; + if (epee::net_utils::data_logger::is_dying()) + break; + epee::net_utils::data_logger::get_instance().add_data("peers", number_of_peers); + + std::this_thread::sleep_for(std::chrono::seconds(1)); + } // main loop of thread + _note("Thread monitor number of peers - done"); + })); // lambda + //here you can set worker threads count int thrds_count = 10; @@ -516,7 +527,6 @@ namespace nodetool kill(); m_peerlist.deinit(); m_net_server.deinit_server(); - return store_config(); } //----------------------------------------------------------------------------------- diff --git a/src/p2p/network_throttle-detail.cpp b/src/p2p/network_throttle-detail.cpp index 7426e6dc7..6fa27b62a 100644 --- a/src/p2p/network_throttle-detail.cpp +++ b/src/p2p/network_throttle-detail.cpp @@ -330,10 +330,13 @@ void network_throttle::calculate_times(size_t packet_size, calculate_times_struc } double network_throttle::get_time_seconds() const { - using namespace std::chrono; - auto point = steady_clock::now(); + #if defined(__APPLE__) + auto point = std::chrono::system_clock::now(); + #else + auto point = std::chrono::steady_clock::now(); + #endif auto time_from_epoh = point.time_since_epoch(); - auto ms = duration_cast< milliseconds >( time_from_epoh ).count(); + auto ms = std::chrono::duration_cast< std::chrono::milliseconds >( time_from_epoh ).count(); double ms_f = ms; return ms_f / 1000.; } diff --git a/src/rpc/CMakeLists.txt b/src/rpc/CMakeLists.txt index d737ee6f8..cb8a8426c 100644 --- a/src/rpc/CMakeLists.txt +++ b/src/rpc/CMakeLists.txt @@ -45,6 +45,7 @@ bitmonero_add_library(rpc target_link_libraries(rpc LINK_PRIVATE cryptonote_core + cryptonote_protocol ${Boost_CHRONO_LIBRARY} ${Boost_REGEX_LIBRARY} ${Boost_SYSTEM_LIBRARY} diff --git a/src/rpc/core_rpc_server.cpp b/src/rpc/core_rpc_server.cpp index f29d0c604..71eb5b753 100644 --- a/src/rpc/core_rpc_server.cpp +++ b/src/rpc/core_rpc_server.cpp @@ -753,6 +753,45 @@ namespace cryptonote return true; } //------------------------------------------------------------------------------------------------------------------------------ + bool core_rpc_server::on_fast_exit(const COMMAND_RPC_FAST_EXIT::request& req, COMMAND_RPC_FAST_EXIT::response& res) + { + cryptonote::core::set_fast_exit(); + m_p2p.deinit(); + m_core.deinit(); + return true; + } + //------------------------------------------------------------------------------------------------------------------------------ + bool core_rpc_server::on_out_peers(const COMMAND_RPC_OUT_PEERS::request& req, COMMAND_RPC_OUT_PEERS::response& res) + { + // TODO + /*if (m_p2p.get_outgoing_connections_count() > req.out_peers) + { + m_p2p.m_config.m_net_config.connections_count = req.out_peers; + if (m_p2p.get_outgoing_connections_count() > req.out_peers) + { + int count = m_p2p.get_outgoing_connections_count() - req.out_peers; + m_p2p.delete_connections(count); + } + } + + else + m_p2p.m_config.m_net_config.connections_count = req.out_peers; + */ + return true; + } + //------------------------------------------------------------------------------------------------------------------------------ + bool core_rpc_server::on_start_save_graph(const COMMAND_RPC_START_SAVE_GRAPH::request& req, COMMAND_RPC_START_SAVE_GRAPH::response& res) + { + m_p2p.set_save_graph(true); + return true; + } + //------------------------------------------------------------------------------------------------------------------------------ + bool core_rpc_server::on_stop_save_graph(const COMMAND_RPC_STOP_SAVE_GRAPH::request& req, COMMAND_RPC_STOP_SAVE_GRAPH::response& res) + { + m_p2p.set_save_graph(false); + return true; + } + //------------------------------------------------------------------------------------------------------------------------------ const command_line::arg_descriptor core_rpc_server::arg_rpc_bind_ip = { "rpc-bind-ip" diff --git a/src/rpc/core_rpc_server.h b/src/rpc/core_rpc_server.h index 6e603acbd..cee8df25d 100644 --- a/src/rpc/core_rpc_server.h +++ b/src/rpc/core_rpc_server.h @@ -87,6 +87,10 @@ namespace cryptonote MAP_URI_AUTO_JON2("/get_transaction_pool", on_get_transaction_pool, COMMAND_RPC_GET_TRANSACTION_POOL) MAP_URI_AUTO_JON2("/stop_daemon", on_stop_daemon, COMMAND_RPC_STOP_DAEMON) MAP_URI_AUTO_JON2("/getinfo", on_get_info, COMMAND_RPC_GET_INFO) + MAP_URI_AUTO_JON2("/fast_exit", on_fast_exit, COMMAND_RPC_FAST_EXIT) + MAP_URI_AUTO_JON2("/out_peers", on_out_peers, COMMAND_RPC_OUT_PEERS) + MAP_URI_AUTO_JON2("/start_save_graph", on_start_save_graph, COMMAND_RPC_START_SAVE_GRAPH) + MAP_URI_AUTO_JON2("/stop_save_graph", on_stop_save_graph, COMMAND_RPC_STOP_SAVE_GRAPH) BEGIN_JSON_RPC_MAP("/json_rpc") MAP_JON_RPC("getblockcount", on_getblockcount, COMMAND_RPC_GETBLOCKCOUNT) MAP_JON_RPC_WE("on_getblockhash", on_getblockhash, COMMAND_RPC_GETBLOCKHASH) @@ -116,6 +120,10 @@ namespace cryptonote bool on_set_log_level(const COMMAND_RPC_SET_LOG_LEVEL::request& req, COMMAND_RPC_SET_LOG_LEVEL::response& res); bool on_get_transaction_pool(const COMMAND_RPC_GET_TRANSACTION_POOL::request& req, COMMAND_RPC_GET_TRANSACTION_POOL::response& res); bool on_stop_daemon(const COMMAND_RPC_STOP_DAEMON::request& req, COMMAND_RPC_STOP_DAEMON::response& res); + bool on_fast_exit(const COMMAND_RPC_FAST_EXIT::request& req, COMMAND_RPC_FAST_EXIT::response& res); + bool on_out_peers(const COMMAND_RPC_OUT_PEERS::request& req, COMMAND_RPC_OUT_PEERS::response& res); + bool on_start_save_graph(const COMMAND_RPC_START_SAVE_GRAPH::request& req, COMMAND_RPC_START_SAVE_GRAPH::response& res); + bool on_stop_save_graph(const COMMAND_RPC_STOP_SAVE_GRAPH::request& req, COMMAND_RPC_STOP_SAVE_GRAPH::response& res); //json_rpc bool on_getblockcount(const COMMAND_RPC_GETBLOCKCOUNT::request& req, COMMAND_RPC_GETBLOCKCOUNT::response& res); diff --git a/src/rpc/core_rpc_server_commands_defs.h b/src/rpc/core_rpc_server_commands_defs.h index 5cb547521..e54dec2c9 100644 --- a/src/rpc/core_rpc_server_commands_defs.h +++ b/src/rpc/core_rpc_server_commands_defs.h @@ -703,5 +703,79 @@ namespace cryptonote END_KV_SERIALIZE_MAP() }; }; + + struct COMMAND_RPC_FAST_EXIT + { + struct request + { + BEGIN_KV_SERIALIZE_MAP() + END_KV_SERIALIZE_MAP() + }; + + struct response + { + std::string status; + + BEGIN_KV_SERIALIZE_MAP() + KV_SERIALIZE(status) + END_KV_SERIALIZE_MAP() + }; + }; + + struct COMMAND_RPC_OUT_PEERS + { + struct request + { + uint64_t out_peers; + BEGIN_KV_SERIALIZE_MAP() + KV_SERIALIZE(out_peers) + END_KV_SERIALIZE_MAP() + }; + + struct response + { + std::string status; + + BEGIN_KV_SERIALIZE_MAP() + KV_SERIALIZE(status) + END_KV_SERIALIZE_MAP() + }; + }; + + struct COMMAND_RPC_START_SAVE_GRAPH + { + struct request + { + BEGIN_KV_SERIALIZE_MAP() + END_KV_SERIALIZE_MAP() + }; + + struct response + { + std::string status; + + BEGIN_KV_SERIALIZE_MAP() + KV_SERIALIZE(status) + END_KV_SERIALIZE_MAP() + }; + }; + + struct COMMAND_RPC_STOP_SAVE_GRAPH + { + struct request + { + BEGIN_KV_SERIALIZE_MAP() + END_KV_SERIALIZE_MAP() + }; + + struct response + { + std::string status; + + BEGIN_KV_SERIALIZE_MAP() + KV_SERIALIZE(status) + END_KV_SERIALIZE_MAP() + }; + }; } diff --git a/src/simplewallet/simplewallet.cpp b/src/simplewallet/simplewallet.cpp index 4ecf00c92..9ac80fa9e 100644 --- a/src/simplewallet/simplewallet.cpp +++ b/src/simplewallet/simplewallet.cpp @@ -67,6 +67,8 @@ namespace po = boost::program_options; #define EXTENDED_LOGS_FILE "wallet_details.log" +unsigned int epee::g_test_dbg_lock_sleep = 0; + #define DEFAULT_MIX 3 namespace -- cgit v1.2.3