diff options
29 files changed, 702 insertions, 243 deletions
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<t_connection_context>::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<std::string> 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 ("<<msg<<") - switching back to fallback stream (e.g. cerr)" << std::endl; if (mStreamBrokenDebug == nullptr) { std::cerr << OT_CODE_STAMP << " ERROR: in addition, while reporting this problem, mStreamBrokenDebug stream is NULL." << std::endl; @@ -307,13 +322,24 @@ std::ostream & cLogger::write_stream(int level) { } std::ostream & cLogger::write_stream(int level, const std::string & channel ) { - 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(); - output << "{" << Thread2Number(this_id) << "} "; - return output; - } + _dbg_dbg("level="<<level<<" channel="<<channel); + if (level >= mLevel) { + if (mStream) { // TODO now disabling mStream also disables writting to any channel + _dbg_dbg("Selecting output..."); + ostream & output = SelectOutput(level,channel); + _dbg_dbg("Selecting output... done, output=" << (void*)(&output)); + #if defined(OS_TYPE_WINDOWS) + output << windows_stream(level); + #endif + output << icon(level) << ' '; + std::thread::id this_id = std::this_thread::get_id(); + output << "{" << Thread2Number(this_id) << "}"; + auto nicePid = Pid2Number(getpid()); + if (nicePid>0) output << " {p" << nicePid << "}"; + output << ' '; + return output; // <--- return + } else _dbg_dbg("Not writting: No mStream"); + } else _dbg_dbg("Not writting: Too low level level="<<level<<" not >= mLevel="<<mLevel); return g_nullstream; } @@ -323,7 +349,7 @@ std::string cLogger::GetLogBaseDir() const { void cLogger::OpenNewChannel(const std::string & channel) noexcept { try { - std::cerr<<"openning channel for channel="<<channel<<endl; + _dbg_dbg("Openning channel for channel="<<channel); OpenNewChannel_(channel); } catch (const std::exception &except) { @@ -335,6 +361,7 @@ void cLogger::OpenNewChannel(const std::string & channel) noexcept { } void cLogger::OpenNewChannel_(const std::string & channel) { // channel=="net/sleep" + _dbg_dbg("Openning channel for channel="<<channel); size_t last_split = channel.find_last_of(cFilesystemUtils::GetDirSeparatorInter()); string fname_system; // the full file name in system format @@ -356,19 +383,28 @@ void cLogger::OpenNewChannel_(const std::string & channel) { // channel=="net/sl if (!dirok) { string err = "In logger failed to open directory (" + dir +") for channel (" + channel +")"; throw std::runtime_error(err); } } + _dbg_dbg("Openning fname_system="<<fname_system); 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; + _dbg_dbg( "====== Log opened: " << fname_system << " (in " << ((void*)thefile) << ") ======" ); mChannels.insert( std::pair<string,std::ofstream*>(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="<<mIsBroken<<" so will return backup stream"); + return *mStreamBrokenDebug; + } + if (channel=="") { + _dbg_dbg("No channel given (channel="<<channel<<") so will return main stream"); + return *mStream; + } auto obj = mChannels.find(channel); if (obj == mChannels.end()) { // not found - need to make new channel + _dbg_dbg("No stream openened for channel="<<channel<<" so will create it now"); OpenNewChannel(channel); // <- create channel obj = mChannels.find(channel); // find again if (obj == mChannels.end()) { // still not found! something is wrong @@ -377,15 +413,18 @@ std::ostream & cLogger::SelectOutput(int level, const std::string & channel) noe } } auto the_stream_ptr = obj->second; + _dbg_dbg("Found the stream file for channel="<<channel<<" as the_stream_ptr="<<the_stream_ptr); ASRT(the_stream_ptr); return *the_stream_ptr; // <--- RETURN } catch (std::exception &except) { SetStreamBroken( OT_CODE_STAMP + " Got exception: " + ToStr(except.what()) ); + _dbg_dbg("Exception! Returning broken stream"); return *mStreamBrokenDebug; } catch (...) { SetStreamBroken( OT_CODE_STAMP + " Got not-standard exception."); + _dbg_dbg("Exception! Returning broken stream"); return *mStreamBrokenDebug; } @@ -428,22 +467,38 @@ std::string cLogger::icon(int level) const { // TODO replan to avoid needles converting back and forth char*, string etc using namespace zkr; - - if (level >= 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="<<id); // can cause some recursion return mThread2Number_Biggest; - // _info("(This is a new thread)"); // recursion! } else { return mThread2Number[id]; } } +int cLogger::Pid2Number(const t_anypid id) { + auto found = mPid2Number.find( id ); + if (found == mPid2Number.end()) { // new one + mPid2Number_Biggest++; + mPid2Number[id] = mPid2Number_Biggest; + _mark_c("dbg/main", "This is a new process (used in debug), process pid="<<id); // can cause some recursion + return mPid2Number_Biggest; + } else { + return mPid2Number[id]; + } +} // ==================================================================== // object gCurrentLogger is defined later - in global namespace below diff --git a/contrib/otshell_utils/utils.hpp b/contrib/otshell_utils/utils.hpp index 35b464b42..6fb0fc5f5 100644 --- a/contrib/otshell_utils/utils.hpp +++ b/contrib/otshell_utils/utils.hpp @@ -13,6 +13,10 @@ #include <unistd.h> #endif +#if defined(_WIN32) + #include"windows_stream.h" +#endif + #ifndef CFG_WITH_TERMCOLORS //#error "You requested to turn off terminal colors (CFG_WITH_TERMCOLORS), however currently they are hardcoded (this option to turn them off is not yet implemented)." #endif @@ -21,6 +25,16 @@ #define MAKE_CLASS_NAME(NAME) private: static std::string GetObjectName() { return #NAME; } #define MAKE_STRUCT_NAME(NAME) private: static std::string GetObjectName() { return #NAME; } public: +// define this to debug the debug system itself: +// #define opt_debug_debug + +#ifdef opt_debug_debug + #define _dbg_dbg(X) do { std::cerr<<"_dbg_dbg: " << OT_CODE_STAMP << " {thread=" << std::this_thread::get_id()<<"} " \ + << " {pid="<<getpid()<<"} " << ": " << X << std::endl; } while(0) +#else + #define _dbg_dbg(X) do { } while(0) +#endif + namespace nOT { namespace nUtils { @@ -74,6 +88,7 @@ std::atomic<int> & 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="<<LEVEL<<" VAR: " << VAR ); \ auto level=LEVEL; short int part=0; \ try { \ std::lock_guard<std::recursive_mutex> mutex_guard( nOT::nUtils::gLoggerGuard ); \ @@ -93,6 +108,7 @@ std::atomic<int> & 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="<<LEVEL<<" CHANNEL="<<CHANNEL<<" VAR: " << VAR ); \ auto level=LEVEL; short int part=0; \ try { \ std::lock_guard<std::recursive_mutex> mutex_guard( nOT::nUtils::gLoggerGuard ); \ @@ -102,9 +118,11 @@ std::atomic<int> & 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="<<LEVEL<<" to CHANNEL="<<CHANNEL<<" as_string="<<as_string); \ /* int counter = nOT::nUtils::gLoggerGuardDepth_Get(); if (counter!=1) gCurrentLogger.write_stream(100,"")<<"DEBUG-ERROR: recursion, counter="<<counter<<gCurrentLogger.endline(); */ \ gCurrentLogger.write_stream(LEVEL,"" ) << as_string << gCurrentLogger.endline() << std::flush; \ gCurrentLogger.write_stream(LEVEL,CHANNEL) << as_string << gCurrentLogger.endline() << std::flush; \ + _dbg_dbg("DONE will write to log LEVEL="<<LEVEL<<" to CHANNEL="<<CHANNEL<<" as_string="<<as_string); \ part=9; \ } catch(...) { \ gCurrentLogger.write_stream(std::max(level,90),CHANNEL) << nOT::nUtils::get_current_time() << ' ' << OT_CODE_STAMP << ' ' << "(ERROR IN DEBUG)" << gCurrentLogger.endline(); \ @@ -182,6 +200,10 @@ const char* DbgShortenCodeFileName(const char *s); ///< Returns a pointer to som // ========== logger ========== +namespace nDetail { + struct channel_use_info; +} // namespace nDetail + /*** @brief Class to write debug into. Used it by calling the debug macros _dbg1(...) _info(...) _erro(...) etc, NOT directly! @author rfree (maintainer) @@ -202,6 +224,8 @@ class cLogger { std::string endline() const; ///< returns string to be written at end of message protected: + typedef long int t_anypid; // a portable representation of PID. long int should cover all platforms + 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 @@ -219,9 +243,13 @@ class cLogger { 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 - 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<bool> arg_version = {"version", "Output version information"}; const arg_descriptor<std::string> arg_data_dir = {"data-dir", "Specify data directory"}; const arg_descriptor<std::string> arg_testnet_data_dir = {"testnet-data-dir", "Specify testnet data directory"}; + const arg_descriptor<bool> arg_test_drop_download = {"test-drop-download", "For net tests: in download, discard ALL blocks instead checking/saving them (very fast)"}; + const arg_descriptor<uint64_t> arg_test_drop_download_height = {"test-drop-download-height", "Like test-drop-download but disards only after around certain height", 0}; + const arg_descriptor<int> 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<bool> arg_version; extern const arg_descriptor<std::string> arg_data_dir; extern const arg_descriptor<std::string> arg_testnet_data_dir; + extern const arg_descriptor<bool> arg_test_drop_download; + extern const arg_descriptor<uint64_t> arg_test_drop_download_height; + extern const arg_descriptor<int> 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<std::string>& a return m_executor.set_limit_down(limit); } + +bool t_command_parser_executor::fast_exit(const std::vector<std::string>& args) +{ + if (!args.empty()) return false; + return m_executor.fast_exit(); +} + +bool t_command_parser_executor::out_peers(const std::vector<std::string>& 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<std::string>& args) +{ + if (!args.empty()) return false; + return m_executor.start_save_graph(); +} + +bool t_command_parser_executor::stop_save_graph(const std::vector<std::string>& 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<std::string>& args); + bool fast_exit(const std::vector<std::string>& args); + + bool out_peers(const std::vector<std::string>& args); + + bool start_save_graph(const std::vector<std::string>& args); + + bool stop_save_graph(const std::vector<std::string>& 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 <kB/s> - 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 <kB/s> - 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 <kB/s> - 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 <boost/program_options.hpp> #include <functional> #include <memory> +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 <boost/lexical_cast.hpp> @@ -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 <level> - Change current log detalization level, <level> is a number 0-4"); m_cmd_binder.set_handler("diff", boost::bind(&daemon_cmmands_handler::diff, this, _1), "Show difficulty"); - m_cmd_binder.set_handler("limit-up", boost::bind(&daemon_cmmands_handler::limit_up, this, _1), "Set upload limit"); - m_cmd_binder.set_handler("limit-down", boost::bind(&daemon_cmmands_handler::limit_down, this, _1), "Set download limit"); - m_cmd_binder.set_handler("limit", boost::bind(&daemon_cmmands_handler::limit, this, _1), "Set download and upload limit"); m_cmd_binder.set_handler("out_peers", boost::bind(&daemon_cmmands_handler::out_peers_limit, this, _1), "Set max limit of out peers"); + 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<std::string>& args) { - if(args.size()!=1) { - std::cout << "Usage: out_peers <number_of_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<std::string>& args) - { - if(args.size()!=1) { - std::cout << "Usage: limit_up <speed>" << ENDL; - return false; - } - - int limit; - try { - limit = std::stoi(args[0]); - } - catch(std::invalid_argument& ex) { - return false; - } - - if (limit==-1) { - limit=128; - //this->islimitup=false; - } - - limit *= 1024; - - - //nodetool::epee::net_utils::connection<epee::levin::async_protocol_handler<nodetool::p2p_connection_context> >::set_rate_up_limit( limit ); - epee::net_utils::connection_basic::set_rate_up_limit( limit ); - std::cout << "Set limit-up to " << limit/1024 << " kB/s" << std::endl; - - return true; - } - - //-------------------------------------------------------------------------------- - bool limit_down(const std::vector<std::string>& args) - { - - if(args.size()!=1) { - std::cout << "Usage: limit_down <speed>" << ENDL; - return true; - } - - int limit; - try { - limit = std::stoi(args[0]); - } - - catch(std::invalid_argument& ex) { - return false; - } - - if (limit==-1) { - limit=128; - //this->islimitup=false; - } - - limit *= 1024; - - - //nodetool::epee::net_utils::connection<epee::levin::async_protocol_handler<nodetool::p2p_connection_context> >::set_rate_up_limit( limit ); - epee::net_utils::connection_basic::set_rate_down_limit( limit ); - std::cout << "Set limit-down to " << limit/1024 << " kB/s" << std::endl; - - return true; - } - - //-------------------------------------------------------------------------------- - bool limit(const std::vector<std::string>& args) - { - if(args.size()!=1) { - std::cout << "Usage: limit_down <speed>" << ENDL; - return true; - } - - int limit; - try { - limit = std::stoi(args[0]); - } - catch(std::invalid_argument& ex) { - return false; - } - - if (limit==-1) { - limit=128; - //this->islimitup=false; - } - - limit *= 1024; - - - //nodetool::epee::net_utils::connection<epee::levin::async_protocol_handler<nodetool::p2p_connection_context> >::set_rate_up_limit( limit ); - epee::net_utils::connection_basic::set_rate_down_limit( limit ); - epee::net_utils::connection_basic::set_rate_up_limit( limit ); - std::cout << "Set limit-down to " << limit/1024 << " kB/s" << std::endl; - std::cout << "Set limit-up to " << limit/1024 << " kB/s" << std::endl; - - return true; - } - //-------------------------------------------------------------------------------- - bool fast_exit(const std::vector<std::string>& 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<std::string>& args) - { - m_srv.get_payload_object().get_core().test_drop_download(); - return true; - } - //-------------------------------------------------------------------------------- - bool start_save_graph(const std::vector<std::string>& args) - { - m_srv.set_save_graph(true); - return true; - } - //-------------------------------------------------------------------------------- - bool stop_save_graph(const std::vector<std::string>& 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 <boost/format.hpp> #include <ctime> @@ -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<bool> 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<unsigned int> 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<int64_t> arg_limit_rate_up = {"limit-rate-up", "set limit-rate-up [kB/s]", -1}; const command_line::arg_descriptor<int64_t> arg_limit_rate_down = {"limit-rate-down", "set limit-rate-down [kB/s]", -1}; const command_line::arg_descriptor<uint64_t> arg_limit_rate = {"limit-rate", "set limit-rate [kB/s]", 128}; + + const command_line::arg_descriptor<bool> 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<class t_payload_net_handler> bool node_server<t_payload_net_handler>::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<std::vector<std::string>> 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<boost::thread*> dns_threads; uint64_t result_index = 0; @@ -483,6 +470,30 @@ namespace nodetool template<class t_payload_net_handler> bool node_server<t_payload_net_handler>::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<std::string> 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 |