remerged; commands JSON. logging upgrade. doxygen

This commit is contained in:
rfree2monero 2015-04-01 19:00:45 +02:00
parent 3cbdf198f1
commit c511abf005
29 changed files with 701 additions and 242 deletions

View File

@ -62,9 +62,24 @@ endif()
message(STATUS "BOOST_IGNORE_SYSTEM_PATHS defaults to ${BOOST_IGNORE_SYSTEM_PATHS_DEFAULT}") 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}) 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) set_property(GLOBAL PROPERTY USE_FOLDERS ON)
enable_testing() 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) # 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 # CMAKE_SYSTEM_NAME checks are commonly known, but specifically taken from libsdl's CMakeLists
if(CMAKE_SYSTEM_NAME MATCHES "kFreeBSD.*") if(CMAKE_SYSTEM_NAME MATCHES "kFreeBSD.*")
@ -276,3 +291,28 @@ add_subdirectory(src)
if(BUILD_TESTS) if(BUILD_TESTS)
add_subdirectory(tests) add_subdirectory(tests)
endif() 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()

View File

@ -690,7 +690,6 @@ void async_protocol_handler_config<t_connection_context>::del_out_connections(si
{ {
close(*out_connections.begin()); close(*out_connections.begin());
del_connection(m_connects.at(*out_connections.begin())); del_connection(m_connects.at(*out_connections.begin()));
out_connections.erase(out_connections.begin());
--count; --count;
} }

View File

@ -40,6 +40,7 @@
#error "Compiler/OS platform detection failed - not supported" #error "Compiler/OS platform detection failed - not supported"
#endif #endif
namespace nOT { namespace nOT {
namespace nUtils { namespace nUtils {
@ -246,6 +247,13 @@ bool cFilesystemUtils::CreateDirTree(const std::string & dir, bool only_below) {
namespace nDetail { 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) { cDebugScopeGuard::cDebugScopeGuard() : mLevel(-1) {
} }
@ -269,13 +277,18 @@ cLogger::cLogger() :
mStream(NULL), mStream(NULL),
mStreamBrokenDebug(NULL), mStreamBrokenDebug(NULL),
mIsBroken(true), // before constructor finishes mIsBroken(true), // before constructor finishes
mLevel(85), mLevel(70),
mThread2Number_Biggest(0) // the CURRENT biggest value (no thread yet in map) mThread2Number_Biggest(0), // the CURRENT biggest value (no thread yet in map)
mPid2Number_Biggest(0)
{ {
mStream = & std::cout; mStream = & std::cout;
mStreamBrokenDebug = & std::cerr; mStreamBrokenDebug = & std::cerr; // the backup stream
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 << "Creating the logger system" << endl;
mIsBroken=false; // ok, constr. succeeded, so string is not broken now 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() { cLogger::~cLogger() {
@ -291,7 +304,9 @@ void cLogger::SetStreamBroken() {
} }
void cLogger::SetStreamBroken(const std::string &msg) { void cLogger::SetStreamBroken(const std::string &msg) {
_dbg_dbg("Stream is broken (msg: " << msg << ")");
if (!mIsBroken) { // if not already marked as broken 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; 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) { if (mStreamBrokenDebug == nullptr) {
std::cerr << OT_CODE_STAMP << " ERROR: in addition, while reporting this problem, mStreamBrokenDebug stream is NULL." << std::endl; 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 ) { 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 _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); 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) << ' '; output << icon(level) << ' ';
std::thread::id this_id = std::this_thread::get_id(); std::thread::id this_id = std::this_thread::get_id();
output << "{" << Thread2Number(this_id) << "}"; output << "{" << Thread2Number(this_id) << "}";
return output; 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; return g_nullstream;
} }
@ -323,7 +349,7 @@ std::string cLogger::GetLogBaseDir() const {
void cLogger::OpenNewChannel(const std::string & channel) noexcept { void cLogger::OpenNewChannel(const std::string & channel) noexcept {
try { try {
std::cerr<<"openning channel for channel="<<channel<<endl; _dbg_dbg("Openning channel for channel="<<channel);
OpenNewChannel_(channel); OpenNewChannel_(channel);
} }
catch (const std::exception &except) { 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" 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()); size_t last_split = channel.find_last_of(cFilesystemUtils::GetDirSeparatorInter());
string fname_system; // the full file name in system format 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); } 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 std::ofstream * thefile = new std::ofstream( fname_system.c_str() ); // file system
*thefile << "====== Log opened: " << fname_system << " (in " << ((void*)thefile) << ") ======" << endl; *thefile << "====== Log opened: " << fname_system << " (in " << ((void*)thefile) << ") ======" << endl;
cerr << "====== 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 mChannels.insert( std::pair<string,std::ofstream*>(channel , thefile ) ); // <- created the channel mapping
} }
std::ostream & cLogger::SelectOutput(int level, const std::string & channel) noexcept { std::ostream & cLogger::SelectOutput(int level, const std::string & channel) noexcept {
try { try {
if (mIsBroken) return *mStreamBrokenDebug; if (mIsBroken) {
if (channel=="") return *mStream; _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); auto obj = mChannels.find(channel);
if (obj == mChannels.end()) { // not found - need to make new 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 OpenNewChannel(channel); // <- create channel
obj = mChannels.find(channel); // find again obj = mChannels.find(channel); // find again
if (obj == mChannels.end()) { // still not found! something is wrong 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; 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); ASRT(the_stream_ptr);
return *the_stream_ptr; // <--- RETURN return *the_stream_ptr; // <--- RETURN
} }
catch (std::exception &except) { catch (std::exception &except) {
SetStreamBroken( OT_CODE_STAMP + " Got exception: " + ToStr(except.what()) ); SetStreamBroken( OT_CODE_STAMP + " Got exception: " + ToStr(except.what()) );
_dbg_dbg("Exception! Returning broken stream");
return *mStreamBrokenDebug; return *mStreamBrokenDebug;
} }
catch (...) { catch (...) {
SetStreamBroken( OT_CODE_STAMP + " Got not-standard exception."); SetStreamBroken( OT_CODE_STAMP + " Got not-standard exception.");
_dbg_dbg("Exception! Returning broken stream");
return *mStreamBrokenDebug; return *mStreamBrokenDebug;
} }
@ -428,8 +467,8 @@ std::string cLogger::icon(int level) const {
// TODO replan to avoid needles converting back and forth char*, string etc // TODO replan to avoid needles converting back and forth char*, string etc
using namespace zkr; using namespace zkr;
#if defined(OS_TYPE_POSIX)
if (level >= 100) return cc::back::red + ToStr(cc::fore::black) + ToStr("ERROR ") + ToStr(cc::fore::lightyellow) + " " ; 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 >= 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 >= 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)+ " ";
@ -439,11 +478,27 @@ std::string cLogger::icon(int level) const {
if (level >= 30) return cc::fore::lightblue + ToStr("dbg "); if (level >= 30) return cc::fore::lightblue + ToStr("dbg ");
if (level >= 20) return cc::fore::blue + 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 " "; return " ";
} }
std::string cLogger::endline() const { 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 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) { 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 if (found == mThread2Number.end()) { // new one
mThread2Number_Biggest++; mThread2Number_Biggest++;
mThread2Number[id] = 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; return mThread2Number_Biggest;
// _info("(This is a new thread)"); // recursion!
} else { } else {
return mThread2Number[id]; 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 // object gCurrentLogger is defined later - in global namespace below

View File

@ -13,6 +13,10 @@
#include <unistd.h> #include <unistd.h>
#endif #endif
#if defined(_WIN32)
#include"windows_stream.h"
#endif
#ifndef CFG_WITH_TERMCOLORS #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)." //#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 #endif
@ -21,6 +25,16 @@
#define MAKE_CLASS_NAME(NAME) private: static std::string GetObjectName() { return #NAME; } #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 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 nOT {
namespace nUtils { namespace nUtils {
@ -74,6 +88,7 @@ std::atomic<int> & gLoggerGuardDepth_Get(); // getter for the global singleton o
// detect stream e.g. operator<< error // detect stream e.g. operator<< error
#define _debug_level(LEVEL,VAR) do { if (_dbg_ignore< LEVEL) { \ #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; \ auto level=LEVEL; short int part=0; \
try { \ try { \
std::lock_guard<std::recursive_mutex> mutex_guard( nOT::nUtils::gLoggerGuard ); \ 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 // 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) { \ #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; \ auto level=LEVEL; short int part=0; \
try { \ try { \
std::lock_guard<std::recursive_mutex> mutex_guard( nOT::nUtils::gLoggerGuard ); \ 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; \ std::ostringstream oss; \
oss << nOT::nUtils::get_current_time() << ' ' << OT_CODE_STAMP << ' ' << VAR << gCurrentLogger.endline() << std::flush; \ oss << nOT::nUtils::get_current_time() << ' ' << OT_CODE_STAMP << ' ' << VAR << gCurrentLogger.endline() << std::flush; \
std::string as_string = oss.str(); \ 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(); */ \ /* 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,"" ) << as_string << gCurrentLogger.endline() << std::flush; \
gCurrentLogger.write_stream(LEVEL,CHANNEL) << 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; \ part=9; \
} catch(...) { \ } catch(...) { \
gCurrentLogger.write_stream(std::max(level,90),CHANNEL) << nOT::nUtils::get_current_time() << ' ' << OT_CODE_STAMP << ' ' << "(ERROR IN DEBUG)" << gCurrentLogger.endline(); \ 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 ========== // ========== 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! @brief Class to write debug into. Used it by calling the debug macros _dbg1(...) _info(...) _erro(...) etc, NOT directly!
@author rfree (maintainer) @author rfree (maintainer)
@ -202,6 +224,8 @@ class cLogger {
std::string endline() const; ///< returns string to be written at end of message std::string endline() const; ///< returns string to be written at end of message
protected: 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(); ///< 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 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 void OpenNewChannel_(const std::string & channel); ///< internal function, will throw in case of problems
std::string GetLogBaseDir() const; std::string GetLogBaseDir() const;
std::map< std::thread::id , int > mThread2Number; // change long thread IDs into a short nice number to show 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 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 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
}; };

View File

@ -48,4 +48,7 @@ namespace command_line
const arg_descriptor<bool> arg_version = {"version", "Output version information"}; 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_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<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."};
} }

View File

@ -204,4 +204,7 @@ namespace command_line
extern const arg_descriptor<bool> arg_version; extern const arg_descriptor<bool> arg_version;
extern const arg_descriptor<std::string> arg_data_dir; extern const arg_descriptor<std::string> arg_data_dir;
extern const arg_descriptor<std::string> arg_testnet_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;
} }

View File

@ -168,7 +168,24 @@ DNSResolver::DNSResolver() : m_data(new DNSResolverData())
ub_ctx_resolvconf(m_data->m_ub_context, &empty_string); ub_ctx_resolvconf(m_data->m_ub_context, &empty_string);
ub_ctx_hosts(m_data->m_ub_context, &empty_string); ub_ctx_hosts(m_data->m_ub_context, &empty_string);
#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() ); ub_ctx_add_ta(m_data->m_ub_context, ::get_builtin_ds() );
#endif
} }
DNSResolver::~DNSResolver() DNSResolver::~DNSResolver()

View File

@ -145,6 +145,11 @@ namespace cryptonote
set_enforce_dns_checkpoints(command_line::get_arg(vm, daemon_args::arg_dns_checkpoints)); 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; return true;
} }
//----------------------------------------------------------------------------------------------- //-----------------------------------------------------------------------------------------------

View File

@ -46,6 +46,8 @@ namespace cryptonote
struct connection_info struct connection_info
{ {
bool incoming; bool incoming;
bool localhost;
bool local_ip;
std::string ip; std::string ip;
std::string port; std::string port;
@ -62,8 +64,16 @@ namespace cryptonote
uint64_t live_time; uint64_t live_time;
uint64_t avg_download;
uint64_t current_download;
uint64_t avg_upload;
uint64_t current_upload;
BEGIN_KV_SERIALIZE_MAP() BEGIN_KV_SERIALIZE_MAP()
KV_SERIALIZE(incoming) KV_SERIALIZE(incoming)
KV_SERIALIZE(localhost)
KV_SERIALIZE(local_ip)
KV_SERIALIZE(ip) KV_SERIALIZE(ip)
KV_SERIALIZE(port) KV_SERIALIZE(port)
KV_SERIALIZE(peer_id) KV_SERIALIZE(peer_id)
@ -73,6 +83,10 @@ namespace cryptonote
KV_SERIALIZE(send_idle_time) KV_SERIALIZE(send_idle_time)
KV_SERIALIZE(state) KV_SERIALIZE(state)
KV_SERIALIZE(live_time) KV_SERIALIZE(live_time)
KV_SERIALIZE(avg_download)
KV_SERIALIZE(current_download)
KV_SERIALIZE(avg_upload)
KV_SERIALIZE(current_upload)
END_KV_SERIALIZE_MAP() END_KV_SERIALIZE_MAP()
}; };

View File

@ -210,6 +210,42 @@ namespace cryptonote
cnx.live_time = timestamp - cntxt.m_started; 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); connections.push_back(cnx);
return true; 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"); 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("calc_time", block_process_time + transactions_process_time);
epee::net_utils::data_logger::get_instance().add_data("block_processing", 1);
} // each download block } // each download block

View File

@ -77,6 +77,9 @@ target_link_libraries(daemon
cryptonote_core cryptonote_core
crypto crypto
common common
otshell_utils
p2p
cryptonote_protocol
daemonizer daemonizer
${Boost_CHRONO_LIBRARY} ${Boost_CHRONO_LIBRARY}
${Boost_FILESYSTEM_LIBRARY} ${Boost_FILESYSTEM_LIBRARY}

View File

@ -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); 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 } // namespace daemonize

View File

@ -93,6 +93,13 @@ public:
bool set_limit_down(const std::vector<std::string>& args); 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 } // namespace daemonize

View File

@ -150,15 +150,35 @@ t_command_server::t_command_server(
, "limit <kB/s> - Set download and upload limit" , "limit <kB/s> - Set download and upload limit"
); );
m_command_lookup.set_handler( m_command_lookup.set_handler(
"limit-up" "limit_up"
, std::bind(&t_command_parser_executor::set_limit_up, &m_parser, p::_1) , std::bind(&t_command_parser_executor::set_limit_up, &m_parser, p::_1)
, "limit <kB/s> - Set upload limit" , "limit <kB/s> - Set upload limit"
); );
m_command_lookup.set_handler( m_command_lookup.set_handler(
"limit-down" "limit_down"
, std::bind(&t_command_parser_executor::set_limit_down, &m_parser, p::_1) , std::bind(&t_command_parser_executor::set_limit_down, &m_parser, p::_1)
, "limit <kB/s> - Set download limit" , "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) bool t_command_server::process_command_str(const std::string& cmd)

View File

@ -1,4 +1,4 @@
// Copyright (c) 2014, The Monero Project // Copyright (c) 2014-2015, The Monero Project
// //
// All rights reserved. // All rights reserved.
// //
@ -38,10 +38,16 @@
#include "daemon/command_server.h" #include "daemon/command_server.h"
#include "misc_log_ex.h" #include "misc_log_ex.h"
#include "version.h" #include "version.h"
#include "../../contrib/epee/include/syncobj.h"
using namespace epee;
#include <boost/program_options.hpp> #include <boost/program_options.hpp>
#include <functional> #include <functional>
#include <memory> #include <memory>
unsigned int epee::g_test_dbg_lock_sleep = 0;
namespace daemonize { namespace daemonize {
struct t_internals { struct t_internals {

View File

@ -1,7 +1,35 @@
// Copyright (c) 2012-2013 The Cryptonote developers // Copyright (c) 2014-2015, The Monero Project
// Distributed under the MIT/X11 software license, see the accompanying //
// file COPYING or http://www.opensource.org/licenses/mit-license.php. // 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 #pragma once
#include <boost/lexical_cast.hpp> #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("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("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("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("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() bool start_handling()
@ -328,6 +360,8 @@ private:
PUSH_WARNINGS PUSH_WARNINGS
DISABLE_GCC_WARNING(maybe-uninitialized) DISABLE_GCC_WARNING(maybe-uninitialized)
log_space::log_singletone::get_set_log_detalisation_level(true, l); 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 POP_WARNINGS
return true; return true;
@ -492,160 +526,4 @@ POP_WARNINGS
m_srv.get_payload_object().get_core().get_miner().stop(); m_srv.get_payload_object().get_core().get_miner().stop();
return true; 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;
}
}; };

View File

@ -71,6 +71,9 @@ int main(int argc, char const * argv[])
command_line::add_arg(visible_options, command_line::arg_testnet_data_dir, default_testnet_data_dir.string()); 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"); 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, 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 // Settings
bf::path default_log = default_data_dir / std::string(CRYPTONOTE_NAME ".log"); bf::path default_log = default_data_dir / std::string(CRYPTONOTE_NAME ".log");
@ -128,6 +131,8 @@ int main(int argc, char const * argv[])
return 0; 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); bool testnet_mode = command_line::get_arg(vm, daemon_args::arg_testnet_on);
auto data_dir_arg = testnet_mode ? command_line::arg_testnet_data_dir : command_line::arg_data_dir; auto data_dir_arg = testnet_mode ? command_line::arg_testnet_data_dir : command_line::arg_data_dir;
@ -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) 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); 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); 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() , log_file_path.parent_path().string().c_str()
); );
} }
_erro("Test error");
return daemonizer::daemonize(argc, argv, daemonize::t_executor{}, vm); return daemonizer::daemonize(argc, argv, daemonize::t_executor{}, vm);
} }

View File

@ -32,6 +32,7 @@
#include "common/scoped_message_writer.h" #include "common/scoped_message_writer.h"
#include "daemon/rpc_command_executor.h" #include "daemon/rpc_command_executor.h"
#include "rpc/core_rpc_server_commands_defs.h" #include "rpc/core_rpc_server_commands_defs.h"
#include "cryptonote_core/cryptonote_core.h"
#include <boost/format.hpp> #include <boost/format.hpp>
#include <ctime> #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) for (auto & info : res.connections)
{ {
std::string address = info.ip + ":" + info.port; std::string address = info.incoming ? "INC " : "OUT ";
std::string in_out = info.incoming ? "INC" : "OUT"; address += info.ip + ":" + info.port;
tools::msg_writer() << boost::format("%-25s peer_id: %-25s %s") % address % info.peer_id % in_out; //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; return true;
@ -659,34 +687,134 @@ bool t_rpc_command_executor::print_status()
bool t_rpc_command_executor::set_limit(int limit) 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_down_limit( limit );
epee::net_utils::connection_basic::set_rate_up_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-down to " << limit/1024 << " kB/s" << std::endl;
std::cout << "Set limit-up to " << limit/1024 << " kB/s" << std::endl; std::cout << "Set limit-up to " << limit/1024 << " kB/s" << std::endl;
*/
return true; return true;
} }
bool t_rpc_command_executor::set_limit_up(int limit) bool t_rpc_command_executor::set_limit_up(int limit)
{ {
/*
epee::net_utils::connection_basic::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; std::cout << "Set limit-up to " << limit/1024 << " kB/s" << std::endl;
*/
return true; return true;
} }
bool t_rpc_command_executor::set_limit_down(int limit) bool t_rpc_command_executor::set_limit_down(int limit)
{ {
/*
epee::net_utils::connection_basic::set_rate_down_limit( limit ); epee::net_utils::connection_basic::set_rate_down_limit( limit );
std::cout << "Set limit-down to " << limit/1024 << " kB/s" << std::endl; 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; 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 }// namespace daemonize

View File

@ -105,7 +105,13 @@ public:
bool set_limit_down(int limit); 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 } // namespace daemonize

View File

@ -43,6 +43,7 @@ namespace net_utils
mFilesMap["sleep_up"] = data_logger::fileData("log/dr-monero/up_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["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["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["peers_limit"] = data_logger::fileData("log/dr-monero/peers_limit.info");
mFilesMap["download_limit"] = data_logger::fileData("log/dr-monero/limit_down.info"); mFilesMap["download_limit"] = data_logger::fileData("log/dr-monero/limit_down.info");
@ -110,6 +111,15 @@ namespace net_utils
} }
} }
bool data_logger::is_dying() {
if (m_state == data_logger_state::state_dying) {
return true;
}
else {
return false;
}
}
void data_logger::saveToFile() { void data_logger::saveToFile() {
_dbg2_c("dbg/data","saving to files"); _dbg2_c("dbg/data","saving to files");
std::lock_guard<std::mutex> lock(mMutex); std::lock_guard<std::mutex> lock(mMutex);
@ -125,10 +135,13 @@ namespace net_utils
// the inner class: // the inner class:
double data_logger::fileData::get_current_time() { double data_logger::fileData::get_current_time() {
using namespace boost::chrono; #if defined(__APPLE__)
auto point = steady_clock::now(); 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 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; double ms_f = ms;
return ms_f / 1000.; return ms_f / 1000.;
} }

View File

@ -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. 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 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: private:
static std::once_flag m_singleton; ///< to guarantee singleton creates the object exactly once static std::once_flag m_singleton; ///< to guarantee singleton creates the object exactly once

View File

@ -80,13 +80,16 @@ namespace nodetool
public: public:
typedef t_payload_net_handler payload_net_handler; typedef t_payload_net_handler payload_net_handler;
node_server( node_server(t_payload_net_handler& payload_handler)
t_payload_net_handler& payload_handler :m_payload_handler(payload_handler),
) m_allow_local_ip(false),
: m_payload_handler(payload_handler) m_no_igd(false),
, m_allow_local_ip(false) m_hide_my_port(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); static void init_options(boost::program_options::options_description& desc);
@ -233,12 +236,12 @@ namespace nodetool
public: public:
config m_config; // TODO was private, add getters? config m_config; // TODO was private, add getters?
std::atomic<unsigned int> m_current_number_of_out_peers; std::atomic<unsigned int> m_current_number_of_out_peers;
void set_save_graph(bool save_graph) void set_save_graph(bool save_graph)
{ {
m_save_graph = save_graph; m_save_graph = save_graph;
epee::net_utils::connection_basic::set_save_graph(save_graph); epee::net_utils::connection_basic::set_save_graph(save_graph);
} }
private: private:
std::string m_config_folder; std::string m_config_folder;

View File

@ -46,6 +46,7 @@
#include "net/local_ip.h" #include "net/local_ip.h"
#include "crypto/crypto.h" #include "crypto/crypto.h"
#include "storages/levin_abstract_invoke2.h" #include "storages/levin_abstract_invoke2.h"
#include "data_logger.hpp"
#include "daemon/command_line_args.h" #include "daemon/command_line_args.h"
// We have to look for miniupnpc headers in different places, dependent on if its compiled or external // 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_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<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<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_tos_flag);
command_line::add_arg(desc, arg_limit_rate_up); 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_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> template<class t_payload_net_handler>
bool node_server<t_payload_net_handler>::init_config() bool node_server<t_payload_net_handler>::init_config()
@ -194,6 +199,11 @@ namespace nodetool
} }
} }
if(command_line::has_arg(vm, arg_save_graph))
{
set_save_graph(true);
}
if (command_line::has_arg(vm,arg_p2p_add_exclusive_node)) if (command_line::has_arg(vm,arg_p2p_add_exclusive_node))
{ {
if (!parse_peers_and_add_to_container(vm, arg_p2p_add_exclusive_node, m_exclusive_peers)) if (!parse_peers_and_add_to_container(vm, arg_p2p_add_exclusive_node, m_exclusive_peers))
@ -295,29 +305,6 @@ namespace nodetool
std::vector<std::vector<std::string>> dns_results; std::vector<std::vector<std::string>> dns_results;
dns_results.resize(m_seed_nodes_list.size()); 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; std::list<boost::thread*> dns_threads;
uint64_t result_index = 0; uint64_t result_index = 0;
for (const std::string& addr_str : m_seed_nodes_list) for (const std::string& addr_str : m_seed_nodes_list)
@ -483,6 +470,30 @@ namespace nodetool
template<class t_payload_net_handler> template<class t_payload_net_handler>
bool node_server<t_payload_net_handler>::run() 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 //here you can set worker threads count
int thrds_count = 10; int thrds_count = 10;
@ -516,7 +527,6 @@ namespace nodetool
kill(); kill();
m_peerlist.deinit(); m_peerlist.deinit();
m_net_server.deinit_server(); m_net_server.deinit_server();
return store_config(); return store_config();
} }
//----------------------------------------------------------------------------------- //-----------------------------------------------------------------------------------

View File

@ -330,10 +330,13 @@ void network_throttle::calculate_times(size_t packet_size, calculate_times_struc
} }
double network_throttle::get_time_seconds() const { double network_throttle::get_time_seconds() const {
using namespace std::chrono; #if defined(__APPLE__)
auto point = steady_clock::now(); 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 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; double ms_f = ms;
return ms_f / 1000.; return ms_f / 1000.;
} }

View File

@ -45,6 +45,7 @@ bitmonero_add_library(rpc
target_link_libraries(rpc target_link_libraries(rpc
LINK_PRIVATE LINK_PRIVATE
cryptonote_core cryptonote_core
cryptonote_protocol
${Boost_CHRONO_LIBRARY} ${Boost_CHRONO_LIBRARY}
${Boost_REGEX_LIBRARY} ${Boost_REGEX_LIBRARY}
${Boost_SYSTEM_LIBRARY} ${Boost_SYSTEM_LIBRARY}

View File

@ -753,6 +753,45 @@ namespace cryptonote
return true; 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 = { const command_line::arg_descriptor<std::string> core_rpc_server::arg_rpc_bind_ip = {
"rpc-bind-ip" "rpc-bind-ip"

View File

@ -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("/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("/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("/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") BEGIN_JSON_RPC_MAP("/json_rpc")
MAP_JON_RPC("getblockcount", on_getblockcount, COMMAND_RPC_GETBLOCKCOUNT) MAP_JON_RPC("getblockcount", on_getblockcount, COMMAND_RPC_GETBLOCKCOUNT)
MAP_JON_RPC_WE("on_getblockhash", on_getblockhash, COMMAND_RPC_GETBLOCKHASH) 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_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_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_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 //json_rpc
bool on_getblockcount(const COMMAND_RPC_GETBLOCKCOUNT::request& req, COMMAND_RPC_GETBLOCKCOUNT::response& res); bool on_getblockcount(const COMMAND_RPC_GETBLOCKCOUNT::request& req, COMMAND_RPC_GETBLOCKCOUNT::response& res);

View File

@ -703,5 +703,79 @@ namespace cryptonote
END_KV_SERIALIZE_MAP() 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()
};
};
} }

View File

@ -67,6 +67,8 @@ namespace po = boost::program_options;
#define EXTENDED_LOGS_FILE "wallet_details.log" #define EXTENDED_LOGS_FILE "wallet_details.log"
unsigned int epee::g_test_dbg_lock_sleep = 0;
#define DEFAULT_MIX 3 #define DEFAULT_MIX 3
namespace namespace