diff --git a/.github/workflows/build-release.yml b/.github/workflows/build-release.yml index 10243cd..50e930d 100644 --- a/.github/workflows/build-release.yml +++ b/.github/workflows/build-release.yml @@ -1,7 +1,7 @@ name: build on: push: - branches: [ main ] + branches: [ main, devel ] tags: - "*" jobs: @@ -44,7 +44,7 @@ jobs: noso-2m.cpp inet.cpp comm.cpp util.cpp tool.cpp misc.cpp mining.cpp hashing.cpp md5-c.cpp \ -o noso-2m-linux-i686 \ -std=c++20 -Ofast -DNDEBUG \ - --stdlib=libc++ -fuse-ld=lld-12 \ + --stdlib=libc++ -fuse-ld=lld-12 -flto -finline-functions -funroll-loops -fvectorize \ -lpthread -lc++ -lc++abi \ -lncurses -lform -ltermcap \ -static -s @@ -55,6 +55,7 @@ jobs: -o noso-2m-linux-x86_64 \ -std=c++20 -Ofast -DNDEBUG \ --stdlib=libc++ -fuse-ld=lld-12 \ + -flto -finline-functions -funroll-loops -fvectorize \ -lpthread -lc++ -lc++abi \ -lncurses -lform -ltermcap \ -static -s @@ -68,6 +69,7 @@ jobs: -o noso-2m-linux-armv7a \ -std=c++20 -Ofast -DNDEBUG \ --stdlib=libc++ -fuse-ld=lld-12 \ + -flto -finline-functions -funroll-loops -fvectorize \ -lpthread -lc++ -lc++abi \ -lncurses -lform -ltermcap \ -static -s @@ -81,6 +83,7 @@ jobs: -o noso-2m-linux-aarch64 \ -std=c++20 -Ofast -DNDEBUG \ --stdlib=libc++ -fuse-ld=lld-12 \ + -flto -finline-functions -funroll-loops -fvectorize \ -lpthread -lc++ -lc++abi \ -lncurses -lform -ltermcap \ -static -s @@ -117,6 +120,7 @@ jobs: noso-2m.cpp inet.cpp comm.cpp util.cpp tool.cpp misc.cpp mining.cpp hashing.cpp md5-c.cpp \ -o noso-2m-android-armv7a \ -std=c++20 -Ofast -DNDEBUG \ + -flto -finline-functions -funroll-loops -fvectorize \ -lncurses -lform \ -static -s file noso-2m-android-armv7a @@ -128,6 +132,7 @@ jobs: noso-2m.cpp inet.cpp comm.cpp util.cpp tool.cpp misc.cpp mining.cpp hashing.cpp md5-c.cpp \ -o noso-2m-android-aarch64 \ -std=c++20 -Ofast -DNDEBUG \ + -flto -finline-functions -funroll-loops -fvectorize \ -lncurses -lform \ -static -s file noso-2m-android-aarch64 @@ -197,6 +202,7 @@ jobs: noso-2m.cpp inet.cpp comm.cpp util.cpp tool.cpp misc.cpp mining.cpp hashing.cpp md5-c.cpp \ -o noso-2m-darwin \ -std=c++20 -Ofast -DNDEBUG \ + -flto -finline-functions -funroll-loops -fvectorize \ -lncurses -lform -ltermcap strip -x noso-2m-darwin file noso-2m-darwin diff --git a/.gitignore b/.gitignore index 8ff7dab..83c1773 100644 --- a/.gitignore +++ b/.gitignore @@ -3,6 +3,7 @@ noso-2m compile_commands.json compile_flags.txt cache +build *.log .DS_Store @@ -44,3 +45,5 @@ cache *.dSYM.zip *.dSYM + +hint_nodes.txt diff --git a/CHANGELOG.md b/CHANGELOG.md index dda1308..b22c870 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,4 +1,14 @@ -Version 0.2.5 - on main branch +Version 0.2.6 + +- Dynamic mining nodes in solo mode instead of seed nodes +- No more timestamp checking in solo mode +- Improve hashrate by new hashing algo, and mining improvement. +- Mining algo improvement +- Fixed terminfo path that causes xterm-256color error on android/termux +- Other bugs fixed and refining +- Remove pool devnoso from config as it was offline + +Version 0.2.5 - New function for fastly converting integer to string during hashing, so improve hashrate - Split the origin big source code file noso-2m.cpp into multiple source files as this is important for further developments. diff --git a/README.md b/README.md index cfc8cd9..6fcdad2 100644 --- a/README.md +++ b/README.md @@ -56,6 +56,8 @@ $ ./noso-2m -a WALLETADDRESS -t THREADCOUNT 2>errors.txt - Arguments loading from the config file will override the options provided on the command line. +*** NOTE: pool devnoso has been removed (temporally) as it was offline + - By default, `noso-2m` mines in `pool mode`, and does failover between two pools: the `f04ever` pool and the `devnoso` pool. - You can provide custom pool addresses on the command line by using option `--pools="POOL-URL-LIST"` (opening and closing quotation marks (`"`) are mandatory if having more than one pool URLs provided) diff --git a/comm.cpp b/comm.cpp index f7b222f..cd58c7a 100644 --- a/comm.cpp +++ b/comm.cpp @@ -1,3 +1,7 @@ +#ifdef _WIN32 +#define _CRT_SECURE_NO_WARNINGS +#endif +#include #include #include #include @@ -7,15 +11,18 @@ #include "util.hpp" #include "output.hpp" -inline void next_status_token( char sep, size_t &p_pos, size_t &c_pos, const std::string &status ) { +inline +void next_status_token( char sep, size_t &p_pos, size_t &c_pos, const std::string &status ) { p_pos = c_pos; c_pos = status.find( sep, c_pos + 1 ); }; -inline std::string extract_status_token( size_t p_pos, size_t c_pos, const std::string& status ) { +inline +std::string extract_status_token( size_t p_pos, size_t c_pos, const std::string& status ) { return status.substr( p_pos + 1, c_pos == std::string::npos ? std::string::npos : ( c_pos - p_pos - 1 ) ); }; +inline CNodeStatus::CNodeStatus( const char *ns_line ) { assert( ns_line != nullptr && std::strlen( ns_line ) > 0 ); std::string status { ns_line }; @@ -94,6 +101,7 @@ CPoolInfo::CPoolInfo( const char *pi ) { this->pool_fee = std::stoul( extract_status_token( p_pos, c_pos, status ) ); } +inline CPoolStatus::CPoolStatus( const char *ps_line ) { assert( ps_line != nullptr && std::strlen( ps_line ) > 0 ); std::string status { ps_line }; @@ -169,8 +177,176 @@ extern bool g_still_running; extern bool g_solo_mining; CCommThread::CCommThread() - : m_mining_nodes { g_default_nodes }, - m_mining_pools { g_mining_pools }, m_mining_pools_id { 0 } { + : m_mining_pools { g_mining_pools }, m_mining_pools_id { 0 } { + this->UpdateMiningNodesInSoloModeIfNeed(); +} + +inline +std::vector> const & CCommThread::GetDefaultNodes() { + // TODO: load default nodes from mainnet.cfg when it is implemented + return g_default_nodes; +} + +inline +bool CCommThread::SaveHintNodes( std::vector> const &nodes ) { + std::ofstream nodes_ostream( "hint_nodes.txt" ); + if( !nodes_ostream.good() ) { + std::string msg { "Failed to save hint nodes to file 'hint_nodes.txt'!" }; + NOSO_LOG_ERROR << msg << std::endl; + NOSO_TUI_OutputHistPad( msg.c_str() ); + NOSO_TUI_OutputHistWin(); + return false; + } + for( auto node : nodes ) { + nodes_ostream << std::get<0>( node ) << ":" << std::get<1>( node ) << std::endl; + } + std::string msg { "Saved hint nodes to file 'hint_nodes.txt'" }; + NOSO_LOG_INFO << msg << std::endl; + return true; +} + +inline +std::vector> CCommThread::LoadHintNodes() { + std::vector> nodes; + std::ifstream nodes_istream( "hint_nodes.txt" ); + if( !nodes_istream.good() ) { + std::string msg { "Hint nodes file 'hint_nodes.txt' not found!" }; + NOSO_LOG_WARN << msg << std::endl; + NOSO_TUI_OutputHistPad( msg.c_str() ); + msg = "Trying with default hint nodes."; + NOSO_LOG_INFO << msg << std::endl; + NOSO_TUI_OutputHistPad( msg.c_str() ); + NOSO_TUI_OutputHistWin(); + } else { + std::string msg { "Load hint nodes from file 'hint_nodes.txt'" }; + NOSO_LOG_INFO << msg << std::endl; + std::regex const re { // IP-ADDRESS:PORT + "^" + "(" + "(25[0-5]|2[0-4][0-9]|1[0-9]{2}|[1-9][0-9]|[0-9])\\." + "(25[0-5]|2[0-4][0-9]|1[0-9]{2}|[1-9][0-9]|[0-9])\\." + "(25[0-5]|2[0-4][0-9]|1[0-9]{2}|[1-9][0-9]|[0-9])\\." + "(25[0-5]|2[0-4][0-9]|1[0-9]{2}|[1-9][0-9]|[0-9])" + ")" + "\\:" + "(" + "6553[0-5]|655[0-2][0-9]|65[0-4][0-9]{2}|6[0-4][0-9]{3}|[1-5][0-9]{4}|[0-5]{0,5}|[0-9]{1,4}" + ")" + "$" }; + std::smatch sm; + for_each( + std::istream_iterator{ nodes_istream }, + std::istream_iterator{}, + [&]( auto const &line ) { + if( std::regex_match( line, sm, re ) ) { + std::string const host { sm[1] }; + std::string const port { sm[6] }; + nodes.push_back( { host, port } ); + } + } ); + } + return nodes; +} + +inline +std::vector> CCommThread::GetValidators( + std::vector> const &hints ) { + std::vector> nodes; + std::size_t const NSLMNS_INET_BUFFER_SIZE { 32'000 }; // appro. max 500 * 64 bytes per MN + char inet_buffer[NSLMNS_INET_BUFFER_SIZE]; + for ( auto itor = hints.begin(); + g_still_running + && itor != hints.end(); + itor = std::next( itor ) ) { + CNodeInet inet { std::get<0>( *itor ), std::get<1>( *itor ), DEFAULT_NODE_INET_TIMEOSEC }; + int rsize { inet.RequestMNList( inet_buffer, NSLMNS_INET_BUFFER_SIZE ) }; + if ( rsize <= 0 ) { + NOSO_LOG_DEBUG + << "sync_nodes <- CNodeInet::RequestMNList Poor connecting with node " + << inet.m_host << ":" << inet.m_port + << std::endl; + NOSO_TUI_OutputStatPad( "A poor connectivity while connecting with a node!" ); + } else { + std::regex const re { + "(" + "(25[0-5]|2[0-4][0-9]|1[0-9]{2}|[1-9][0-9]|[0-9])\\." + "(25[0-5]|2[0-4][0-9]|1[0-9]{2}|[1-9][0-9]|[0-9])\\." + "(25[0-5]|2[0-4][0-9]|1[0-9]{2}|[1-9][0-9]|[0-9])\\." + "(25[0-5]|2[0-4][0-9]|1[0-9]{2}|[1-9][0-9]|[0-9])" + ")" + ";" + "(" + "6553[0-5]|655[0-2][0-9]|65[0-4][0-9]{2}|6[0-4][0-9]{3}|[1-5][0-9]{4}|[0-5]{0,5}|[0-9]{1,4}" + ")" + "\\:" + "N[0-9A-Za-z]{29,30}" + "\\:" + "([0-9]{1,})" }; + std::string mn_list { inet_buffer }; + std::vector> validators; + try { + std::for_each( + std::sregex_iterator { mn_list.begin(), mn_list.end(), re }, + std::sregex_iterator {}, + [&]( auto const &sm0 ) { + std::string host { sm0[1].str() }; + std::string port { sm0[6].str() }; + std::string ages { sm0[7].str() }; + validators.push_back( { host, port, std::stol( ages ) } ); + } ); + } catch ( const std::exception &e ) { + NOSO_LOG_DEBUG + << "CCommThread::GetValidators Unrecognised response from node " + << inet.m_host << ":" << inet.m_port + << "[" << inet_buffer << "](size=" << rsize << ")" << e.what() + << std::endl; + NOSO_TUI_OutputStatPad( "An unrecognised response from a node!" ); + continue; + } + std::sort( validators.begin(), validators.end(), + []( auto const &a, auto const &b ){ + return std::get<2>( a ) > std::get<2>( b ); + } ); + std::size_t validators_count { validators.size() / 10 + 3 }; + auto const &validators_begin = validators.begin(); + std::for_each( validators_begin, validators_begin + validators_count, + [&]( auto const &a ) { + nodes.push_back( { std::get<0>( a ), std::get<1>( a ) } ); + } ); + if ( nodes.size() > 0 ) break; + } + NOSO_TUI_OutputStatWin(); + } + return nodes; +} + +inline +void CCommThread::UpdateMiningNodesInSoloModeIfNeed() { + if( !g_solo_mining ) return; + if( m_mining_nodes.size() < DEFAULT_CONSENSUS_NODES_COUNT ) { + std::vector> hints; + if ( m_mining_nodes.size() <= 0 ) { + hints = CCommThread::LoadHintNodes(); + if ( hints.size() <= 0 ) hints = this->GetDefaultNodes(); + if ( hints.size() <= 0 ) hints.push_back( { "localhost", "8080" } ); + } else { + hints = m_mining_nodes; + } + std::shuffle( m_mining_nodes.begin(), m_mining_nodes.end(), m_random_engine ); + m_mining_nodes = CCommThread::GetValidators( hints ); + std::stringstream msg; + msg << "Do mining randomly on nodes:"; + NOSO_LOG_INFO << msg.str() << std::endl; + NOSO_TUI_OutputHistPad( msg.str().c_str() ); + for ( auto node : m_mining_nodes ) { + msg.str( std::string() ); + msg << "- " << std::get<0>( node ) << ":" << std::get<1>( node ); + NOSO_LOG_INFO << msg.str() << std::endl; + NOSO_TUI_OutputHistPad( msg.str().c_str() ); + } + NOSO_TUI_OutputHistWin(); + CCommThread::SaveHintNodes( m_mining_nodes ); + } } std::shared_ptr CCommThread::GetInstance() { @@ -178,6 +354,11 @@ std::shared_ptr CCommThread::GetInstance() { return singleton; } +std::vector> const & CCommThread::GetMiningNodes() { + return m_mining_nodes; +} + +inline void CCommThread::CloseMiningBlock( const std::chrono::duration& elapsed_blck ) { m_last_block_hashes_count = 0; m_last_block_elapsed_secs = elapsed_blck.count(); @@ -193,6 +374,7 @@ void CCommThread::CloseMiningBlock( const std::chrono::duration& elapsed m_last_block_hashrate = m_last_block_hashes_count / m_last_block_elapsed_secs; } +inline void CCommThread::ResetMiningBlock() { m_accepted_solutions_count = 0; m_rejected_solutions_count = 0; @@ -200,6 +382,7 @@ void CCommThread::ResetMiningBlock() { this->ClearSolutions(); }; +inline void CCommThread::_ReportMiningTarget( const std::shared_ptr& target ) { char msg[100]; if ( m_last_block_hashrate > 0 ) { @@ -280,6 +463,7 @@ void CCommThread::_ReportMiningTarget( const std::shared_ptr& target ) NOSO_TUI_OutputStatWin(); } +inline void CCommThread::_ReportTargetSummary( const std::shared_ptr& target ) { char msg[100]; std::snprintf( msg, 100, "---------------------------------------------------" ); @@ -312,6 +496,7 @@ void CCommThread::_ReportTargetSummary( const std::shared_ptr& target ) NOSO_TUI_OutputActiWinDefault(); }; +inline void CCommThread::_ReportErrorSubmitting( int code, const std::shared_ptr &solution ) { char msg[100]; if ( code == 1 ) { @@ -362,40 +547,45 @@ void CCommThread::_ReportErrorSubmitting( int code, const std::shared_ptr& solution ) { m_mutex_solutions.lock(); - m_solutions.insert( solution ); + if ( g_solo_mining ) m_solo_solutions.insert( solution ); + else m_pool_solutions.push_back( solution ); m_mutex_solutions.unlock(); } +inline void CCommThread::ClearSolutions() { m_mutex_solutions.lock(); - m_solutions.clear(); + if ( g_solo_mining ) m_solo_solutions.clear(); + else m_pool_solutions.clear(); m_mutex_solutions.unlock(); } +inline const std::shared_ptr CCommThread::BestSolution() { std::shared_ptr best_solution { nullptr }; m_mutex_solutions.lock(); - if ( m_solutions.begin() != m_solutions.end() ) { - auto itor_best_solution = m_solutions.begin(); + if ( m_solo_solutions.begin() != m_solo_solutions.end() ) { + auto itor_best_solution = m_solo_solutions.begin(); best_solution = *itor_best_solution; - m_solutions.clear(); + m_solo_solutions.clear(); } m_mutex_solutions.unlock(); return best_solution; } +inline const std::shared_ptr CCommThread::GoodSolution() { std::shared_ptr good_solution { nullptr }; m_mutex_solutions.lock(); - if ( m_solutions.begin() != m_solutions.end() ) { - auto itor_good_solution = m_solutions.begin(); - good_solution = *itor_good_solution; - m_solutions.erase( itor_good_solution ); + if ( m_pool_solutions.begin() != m_pool_solutions.end() ) { + good_solution = m_pool_solutions.back(); + m_pool_solutions.pop_back(); } m_mutex_solutions.unlock(); return good_solution; } +inline std::shared_ptr CCommThread::GetSolution() { return g_solo_mining ? this->BestSolution() : this->GoodSolution(); } @@ -403,13 +593,16 @@ std::shared_ptr CCommThread::GetSolution() { std::time_t CCommThread::RequestTimestamp() { if ( m_mining_nodes.size() <= 0 ) return std::time_t( -1 ); std::shuffle( m_mining_nodes.begin(), m_mining_nodes.end(), m_random_engine ); + std::time_t ret_time { -1 }; + std::vector>::iterator> bad_mining_nodes; for ( auto itor = m_mining_nodes.begin(); g_still_running && itor != m_mining_nodes.end(); itor = std::next( itor ) ) { CNodeInet inet { std::get<0>( *itor ), std::get<1>( *itor ), DEFAULT_NODE_INET_TIMEOSEC }; - int rsize { inet.RequestTimestamp( m_inet_buffer, INET_BUFFER_SIZE ) }; + int rsize { inet.RequestTimestamp( m_inet_buffer, DEFAULT_INET_BUFFER_SIZE ) }; if ( rsize <= 0 ) { + bad_mining_nodes.push_back( itor ); NOSO_LOG_DEBUG << "CCommThread::RequestTimestamp Poor connecting with node " << inet.m_host << ":" << inet.m_port @@ -417,8 +610,10 @@ std::time_t CCommThread::RequestTimestamp() { NOSO_TUI_OutputStatPad( "A poor connectivity while connecting with a node!" ); } else { try { - return std::time_t( std::atol( m_inet_buffer ) ); + ret_time = std::time_t( std::atol( m_inet_buffer ) ); + break; } catch ( const std::exception &e ) { + bad_mining_nodes.push_back( itor ); NOSO_LOG_DEBUG << "CCommThread::RequestTimestamp Unrecognised response from node " << inet.m_host << ":" << inet.m_port @@ -429,22 +624,27 @@ std::time_t CCommThread::RequestTimestamp() { } NOSO_TUI_OutputStatWin(); } - return std::time_t( -1 ); + std::for_each( bad_mining_nodes.begin(), bad_mining_nodes.end(), + [&]( auto const &itor ) { m_mining_nodes.erase( itor ); } ); + return ret_time; } +inline std::vector> CCommThread::RequestNodeSources( std::size_t min_nodes_count ) { std::vector> sources; if ( m_mining_nodes.size() < min_nodes_count ) return sources; std::shuffle( m_mining_nodes.begin(), m_mining_nodes.end(), m_random_engine ); std::size_t nodes_count { 0 }; + std::vector>::iterator> bad_mining_nodes; for ( auto itor = m_mining_nodes.begin(); g_still_running && nodes_count < min_nodes_count && itor != m_mining_nodes.end(); itor = std::next( itor ) ) { CNodeInet inet { std::get<0>( *itor ), std::get<1>( *itor ), DEFAULT_NODE_INET_TIMEOSEC }; - int rsize { inet.RequestSource( m_inet_buffer, INET_BUFFER_SIZE ) }; + int rsize { inet.RequestSource( m_inet_buffer, DEFAULT_INET_BUFFER_SIZE ) }; if ( rsize <= 0 ) { + bad_mining_nodes.push_back( itor ); NOSO_LOG_DEBUG << "CCommThread::RequestNodeSources Poor connecting with node " << inet.m_host << ":" << inet.m_port @@ -455,6 +655,7 @@ std::vector> CCommThread::RequestNodeSources( std:: sources.push_back( std::make_shared( m_inet_buffer ) ); nodes_count ++; } catch ( const std::exception &e ) { + bad_mining_nodes.push_back( itor ); NOSO_LOG_DEBUG << "CCommThread::RequestNodeSources Unrecognised response from node " << inet.m_host << ":" << inet.m_port @@ -465,12 +666,15 @@ std::vector> CCommThread::RequestNodeSources( std:: } NOSO_TUI_OutputStatWin(); } + std::for_each( bad_mining_nodes.begin(), bad_mining_nodes.end(), + [&]( auto const &itor ) { m_mining_nodes.erase( itor ); } ); return sources; } +inline std::shared_ptr CCommThread::GetNodeTargetConsensus() { - std::vector> status_of_nodes = this->RequestNodeSources( CONSENSUS_NODES_COUNT ); - if ( status_of_nodes.size() < CONSENSUS_NODES_COUNT ) return nullptr; + std::vector> status_of_nodes = this->RequestNodeSources( DEFAULT_CONSENSUS_NODES_COUNT ); + if ( status_of_nodes.size() < DEFAULT_CONSENSUS_NODES_COUNT ) return nullptr; const auto max_freq = []( const auto &freq ) { return std::max_element( std::begin( freq ), std::end( freq ), @@ -501,11 +705,12 @@ std::shared_ptr CCommThread::GetNodeTargetConsensus() { return target; } +inline std::shared_ptr CCommThread::RequestPoolTarget( const char address[32] ) { assert( std::strlen( address ) == 30 || std::strlen( address ) == 31 ); auto pool { m_mining_pools[m_mining_pools_id] }; CPoolInet inet { std::get<0>( pool ), std::get<1>( pool ), std::get<2>( pool ), DEFAULT_POOL_INET_TIMEOSEC }; - int rsize { inet.RequestSource( address, m_inet_buffer, INET_BUFFER_SIZE ) }; + int rsize { inet.RequestSource( address, m_inet_buffer, DEFAULT_INET_BUFFER_SIZE ) }; if ( rsize <= 0 ) { NOSO_LOG_DEBUG << "CCommThread::RequestPoolTarget Poor connecting with pool " @@ -544,6 +749,7 @@ std::shared_ptr CCommThread::RequestPoolTarget( const char address[ return nullptr; } +inline std::shared_ptr CCommThread::GetPoolTargetFailover() { static const int max_tries_count { 5 }; bool first_fail { true }; @@ -589,39 +795,44 @@ std::shared_ptr CCommThread::GetPoolTargetFailover() { NOSO_TUI_OutputStatWin(); } } - std::this_thread::sleep_for( std::chrono::milliseconds( static_cast( tries_count * 1'000 * INET_CIRCLE_SECONDS ) ) ); + std::this_thread::sleep_for( std::chrono::milliseconds( static_cast( tries_count * 1'000 * DEFAULT_INET_CIRCLE_SECONDS ) ) ); pool_target = this->RequestPoolTarget( g_miner_address ); ++tries_count; } return pool_target; } +inline std::shared_ptr CCommThread::GetTarget( const char prev_lb_hash[32] ) { assert( std::strlen( prev_lb_hash ) == 32 ); std::shared_ptr target { nullptr }; if ( g_solo_mining ) target = this->GetNodeTargetConsensus(); else target = this->GetPoolTargetFailover(); while ( g_still_running && ( target == nullptr || ( target !=nullptr && target->lb_hash == prev_lb_hash ) ) ) { - std::this_thread::sleep_for( std::chrono::milliseconds( static_cast( 1'000 * INET_CIRCLE_SECONDS ) ) ); + std::this_thread::sleep_for( std::chrono::milliseconds( static_cast( 1'000 * DEFAULT_INET_CIRCLE_SECONDS ) ) ); if ( g_solo_mining ) target = this->GetNodeTargetConsensus(); else target = this->GetPoolTargetFailover(); } return target; } +inline int CCommThread::SubmitSoloSolution( std::uint32_t blck, const char base[19], const char address[32], char new_mn_diff[33] ) { assert( std::strlen( base ) == 18 && ( std::strlen( address ) == 30 || std::strlen( address ) == 31 ) ); if ( m_mining_nodes.size() <= 0 ) return ( -1 ); std::shuffle( m_mining_nodes.begin(), m_mining_nodes.end(), m_random_engine ); + int ret_code { -1 }; + std::vector>::iterator> bad_mining_nodes; for ( auto itor = m_mining_nodes.begin(); g_still_running && itor != m_mining_nodes.end(); itor = std::next( itor ) ) { CNodeInet inet { std::get<0>( *itor ), std::get<1>( *itor ), DEFAULT_NODE_INET_TIMEOSEC }; - int rsize { inet.SubmitSolution( blck, base, address, m_inet_buffer, INET_BUFFER_SIZE ) }; + int rsize { inet.SubmitSolution( blck, base, address, m_inet_buffer, DEFAULT_INET_BUFFER_SIZE ) }; if ( rsize <= 0 ) { + bad_mining_nodes.push_back( itor ); NOSO_LOG_DEBUG << "CCommThread::SubmitSoloSolution Poor connecting with node " << inet.m_host << ":" << inet.m_port @@ -637,7 +848,8 @@ int CCommThread::SubmitSoloSolution( std::uint32_t blck, const char base[19], // len=(40+2)~[False Diff(32) Code#(1)\r\n] std::strncpy( new_mn_diff, m_inet_buffer + 6, 32 ); new_mn_diff[32] = '\0'; - return m_inet_buffer[39] - '0'; + ret_code = m_inet_buffer[39] - '0'; + break; } else if ( rsize >= 72 && std::strncmp( m_inet_buffer, "True ", 5 ) == 0 @@ -645,9 +857,11 @@ int CCommThread::SubmitSoloSolution( std::uint32_t blck, const char base[19], // len=(70+2)~[True Diff(32) Hash(32)\r\n] std::strncpy( new_mn_diff, m_inet_buffer + 5, 32 ); new_mn_diff[32] = '\0'; - return 0; + ret_code = 0; + break; } // } catch ( const std::exception &e ) {} + bad_mining_nodes.push_back( itor ); NOSO_LOG_DEBUG << "CCommThread::SubmitSoloSolution Unrecognised response from node " << inet.m_host << ":" << inet.m_port @@ -657,20 +871,24 @@ int CCommThread::SubmitSoloSolution( std::uint32_t blck, const char base[19], } NOSO_TUI_OutputStatWin(); } - return ( -1 ); + std::for_each( bad_mining_nodes.begin(), bad_mining_nodes.end(), + [&]( auto const &itor ) { m_mining_nodes.erase( itor ); } ); + return ret_code; } +inline int CCommThread::SubmitPoolSolution( std::uint32_t blck_no, const char base[19], const char address[32] ) { assert( std::strlen( base ) == 18 && ( std::strlen( address ) == 30 || std::strlen( address ) == 31 ) ); static const int max_tries_count { 5 }; auto pool { m_mining_pools[m_mining_pools_id] }; CPoolInet inet { std::get<0>( pool ), std::get<1>( pool ), std::get<2>( pool ), DEFAULT_POOL_INET_TIMEOSEC }; + int ret_code { -1 }; for ( int tries_count = 0; g_still_running && tries_count < max_tries_count; ++tries_count ) { - int rsize { inet.SubmitSolution( blck_no, base, address, m_inet_buffer, INET_BUFFER_SIZE ) }; + int rsize { inet.SubmitSolution( blck_no, base, address, m_inet_buffer, DEFAULT_INET_BUFFER_SIZE ) }; if ( rsize <= 0 ) { NOSO_LOG_DEBUG << "CCommThread::SubmitPoolSolution Poor connecting with pool " @@ -682,12 +900,16 @@ int CCommThread::SubmitPoolSolution( std::uint32_t blck_no, const char base[19], // try { // m_inet_buffer ~ len=(4+2)~[True\r\n] OR len=(7+2)~[False Code#(1)\r\n] if ( rsize >= 6 - && std::strncmp( m_inet_buffer, "True", 4 ) == 0 ) - return ( 0 ); + && std::strncmp( m_inet_buffer, "True", 4 ) == 0 ) { + ret_code = 0; + break; + } else if ( rsize >= 9 && std::strncmp( m_inet_buffer, "False ", 6 ) == 0 - && '1' <= m_inet_buffer[6] && m_inet_buffer[6] <= '7' ) - return ( m_inet_buffer[6] - '0' ); + && '1' <= m_inet_buffer[6] && m_inet_buffer[6] <= '7' ) { + ret_code = m_inet_buffer[6] - '0'; + break; + } // } catch ( const std::exception &e ) {} NOSO_LOG_DEBUG << "CCommThread::SubmitPoolSolution Unrecognised response from pool " @@ -697,30 +919,33 @@ int CCommThread::SubmitPoolSolution( std::uint32_t blck_no, const char base[19], NOSO_TUI_OutputStatPad( "An unrecognised response from pool!" ); } NOSO_TUI_OutputStatWin(); - std::this_thread::sleep_for( std::chrono::milliseconds( static_cast( 1'000 * INET_CIRCLE_SECONDS ) ) ); + std::this_thread::sleep_for( std::chrono::milliseconds( static_cast( 1'000 * DEFAULT_INET_CIRCLE_SECONDS ) ) ); } - return ( -1 ); + return ret_code; } +inline void CCommThread::SubmitSolution( const std::shared_ptr &solution, std::shared_ptr &target ) { int code { 0 }; if ( g_solo_mining ) { target->mn_diff = solution->diff; char new_mn_diff[33] { NOSO_MAX_DIFF }; code = this->SubmitSoloSolution( solution->blck, solution->base.c_str(), g_miner_address, new_mn_diff ); - if ( target->mn_diff > new_mn_diff ) { - target->mn_diff = new_mn_diff; - NOSO_TUI_OutputActiWinMiningDiff( target->mn_diff.substr( 0, 32 ) ); - } - if ( code == 6 ) { - if ( solution->diff < new_mn_diff ) this->AddSolution( solution ); - NOSO_LOG_DEBUG - << " WAITBLCK" - << ")base[" << solution->base - << "]hash[" << solution->hash - << "]Network building block!" - << std::endl; - NOSO_TUI_OutputStatPad( "A submission while network building block! The solution will be re-submited." ); + if ( code >= 0 ) { + if ( target->mn_diff > new_mn_diff ) { + target->mn_diff = new_mn_diff; + NOSO_TUI_OutputActiWinMiningDiff( target->mn_diff.substr( 0, 32 ) ); + } + if ( code == 6 ) { + if ( solution->diff < new_mn_diff ) this->AddSolution( solution ); + NOSO_LOG_DEBUG + << " WAITBLCK" + << ")base[" << solution->base + << "]hash[" << solution->hash + << "]Network building block!" + << std::endl; + NOSO_TUI_OutputStatPad( "A submission while network building block! The solution will be re-submited." ); + } } } else { code = this->SubmitPoolSolution( solution->blck, solution->base.c_str(), g_miner_address ); @@ -772,14 +997,15 @@ void CCommThread::Communicate() { NOSO_TUI_OutputStatPad( "Wait next block..." ); NOSO_TUI_OutputStatWin(); do { - std::this_thread::sleep_for( std::chrono::milliseconds( static_cast( 1'000 * INET_CIRCLE_SECONDS ) ) ); + std::this_thread::sleep_for( std::chrono::milliseconds( static_cast( 1'000 * DEFAULT_INET_CIRCLE_SECONDS ) ) ); } while ( g_still_running && ( NOSO_BLOCK_AGE < NOSO_BLOCK_AGE_TARGET_SAFE || 585 < NOSO_BLOCK_AGE ) ); if ( !g_still_running ) break; } NOSO_BLOCK_AGE_TARGET_SAFE = g_solo_mining ? 1 : 6; + this->UpdateMiningNodesInSoloModeIfNeed(); std::shared_ptr target = this->GetTarget( prev_lb_hash ); + if ( !g_still_running || target == nullptr ) break; std::strcpy( prev_lb_hash, target->lb_hash.c_str() ); - if ( !g_still_running ) break; begin_blck = std::chrono::steady_clock::now(); for ( auto const & mo : g_mine_objects ) mo->NewTarget( target ); this->_ReportMiningTarget( target ); @@ -790,9 +1016,10 @@ void CCommThread::Communicate() { if ( solution != nullptr && solution->diff < target->mn_diff ) this->SubmitSolution( solution, target ); } + this->UpdateMiningNodesInSoloModeIfNeed(); std::chrono::duration elapsed_submit = std::chrono::steady_clock::now() - begin_submit; - if ( elapsed_submit.count() < INET_CIRCLE_SECONDS ) { - std::this_thread::sleep_for( std::chrono::milliseconds( static_cast( 1'000 * INET_CIRCLE_SECONDS ) ) ); + if ( elapsed_submit.count() < DEFAULT_INET_CIRCLE_SECONDS ) { + std::this_thread::sleep_for( std::chrono::milliseconds( static_cast( 1'000 * DEFAULT_INET_CIRCLE_SECONDS ) ) ); } } this->CloseMiningBlock( std::chrono::steady_clock::now() - begin_blck ); @@ -802,4 +1029,3 @@ void CCommThread::Communicate() { for ( auto &obj : g_mine_objects ) obj->CleanupSyncState(); for ( auto &thr : g_mine_threads ) thr.join(); } - diff --git a/comm.hpp b/comm.hpp index 27c80ab..55b2098 100644 --- a/comm.hpp +++ b/comm.hpp @@ -1,5 +1,8 @@ #ifndef __NOSO2M_COMM_HPP__ #define __NOSO2M_COMM_HPP__ +#ifdef _WIN32 +#define _CRT_SECURE_NO_WARNINGS +#endif #include #include #include @@ -61,7 +64,8 @@ class CCommThread { // A singleton pattern class std::vector> m_mining_nodes; std::vector>& m_mining_pools; std::uint32_t m_mining_pools_id; - std::multiset, CSolsSetCompare> m_solutions; + std::multiset, CSolsSetCompare> m_solo_solutions; + std::vector> m_pool_solutions; std::uint64_t m_last_block_hashes_count { 0 }; double m_last_block_elapsed_secs { 0. }; double m_last_block_hashrate { 0. }; @@ -73,8 +77,24 @@ class CCommThread { // A singleton pattern class std::map m_freq_mn_diff; std::map m_freq_lb_time; std::map m_freq_lb_addr; - char m_inet_buffer[INET_BUFFER_SIZE]; + char m_inet_buffer[DEFAULT_INET_BUFFER_SIZE]; CCommThread(); + std::vector> const & GetDefaultNodes(); + static std::vector> LoadHintNodes(); + static bool SaveHintNodes( std::vector> const &nodes ); + static std::vector> GetValidators( + std::vector> const &hints ); + void UpdateMiningNodesInSoloModeIfNeed(); + const std::shared_ptr BestSolution(); + const std::shared_ptr GoodSolution(); + std::shared_ptr GetSolution(); + void ClearSolutions(); + std::vector> RequestNodeSources( std::size_t min_nodes_count ); + std::shared_ptr GetNodeTargetConsensus(); + std::shared_ptr RequestPoolTarget( const char address[32] ); + std::shared_ptr GetPoolTargetFailover(); + int SubmitSoloSolution( std::uint32_t blck, const char base[19], const char address[32], char new_mn_diff[33] ); + int SubmitPoolSolution( std::uint32_t blck_no, const char base[19], const char address[32] ); void CloseMiningBlock( const std::chrono::duration& elapsed_blck ); void ResetMiningBlock(); void _ReportMiningTarget( const std::shared_ptr& target ); @@ -86,19 +106,10 @@ class CCommThread { // A singleton pattern class void operator=( const CCommThread& ) = delete; // Assignment prohibited CCommThread& operator=( CCommThread&& ) = delete; // Move assignment prohibited static std::shared_ptr GetInstance(); + std::vector> const & GetMiningNodes(); void AddSolution( const std::shared_ptr& solution ); - void ClearSolutions(); - const std::shared_ptr BestSolution(); - const std::shared_ptr GoodSolution(); - std::shared_ptr GetSolution(); std::time_t RequestTimestamp(); - std::vector> RequestNodeSources( std::size_t min_nodes_count ); - std::shared_ptr GetNodeTargetConsensus(); - std::shared_ptr RequestPoolTarget( const char address[32] ); - std::shared_ptr GetPoolTargetFailover(); std::shared_ptr GetTarget( const char prev_lb_hash[32] ); - int SubmitSoloSolution( std::uint32_t blck, const char base[19], const char address[32], char new_mn_diff[33] ); - int SubmitPoolSolution( std::uint32_t blck_no, const char base[19], const char address[32] ); void SubmitSolution( const std::shared_ptr &solution, std::shared_ptr &target ); void Communicate(); }; diff --git a/config.hpp b/config.hpp new file mode 100644 index 0000000..b6977f0 --- /dev/null +++ b/config.hpp @@ -0,0 +1,24 @@ +#ifndef __NOSO2M_CONFIG_HPP__ +#define __NOSO2M_CONFIG_HPP__ + +#define NOSO_2M_VERSION "0.2.6" +#define NOSO_2M_VERSION_MAJOR 0 +#define NOSO_2M_VERSION_MINOR 2 +#define NOSO_2M_VERSION_PATCH 6 +#define NOSO_2M_VERSION_TWEAK + +#define DEFAULT_CONFIG_FILENAME "noso-2m.cfg" +#define DEFAULT_LOGGING_FILENAME "noso-2m.log" +#define DEFAULT_POOL_URL_LIST "f04ever" +#define DEFAULT_MINER_ADDRESS "N3G1HhkpXvmLcsWFXySdAxX3GZpkMFS" + +#define DEFAULT_MINER_ID 0 +#define DEFAULT_THREADS_COUNT 2 +#define DEFAULT_NODE_INET_TIMEOSEC 10 +#define DEFAULT_POOL_INET_TIMEOSEC 60 +#define DEFAULT_TIMESTAMP_DIFFERENCES 3 +#define DEFAULT_CONSENSUS_NODES_COUNT 3 +#define DEFAULT_INET_CIRCLE_SECONDS 0.1 +#define DEFAULT_INET_BUFFER_SIZE 1024 + +#endif // __NOSO2M_CONFIG_HPP__ diff --git a/hashing.cpp b/hashing.cpp index 3871991..bbd60a1 100644 --- a/hashing.cpp +++ b/hashing.cpp @@ -1,3 +1,6 @@ +#ifdef _WIN32 +#define _CRT_SECURE_NO_WARNINGS +#endif #include #include "hashing.hpp" @@ -6,123 +9,101 @@ constexpr char const CNosoHasher::hex_char2dec_table[]; constexpr std::uint16_t const CNosoHasher::nosohash_chars_table[]; inline -void CNosoHasher::_ito9a( std::uint32_t n, char * buff ) { - // constexpr static - // std::uint32_t const number_of_row[] { - // 100'000'000, - // 10'000'000, - // 1'000'000, - // 100'000, - // 10'000, - // 1'000, - // 100, - // 10, - // 1, }; - // n = n % 1'000'000'000; - // for ( std::uint8_t i = 0; i < 9; i++ ) { - // assert( 0 <= n / number_of_row[i] && n / number_of_row[i] <= 9 ); - // buff[i] = n / number_of_row[i] + '0'; - // n = n % number_of_row[i]; - // } - // buff[9] = '\0'; - n = n % 1'000'000'000; - buff[0] = n / 100'000'000 + '0'; - n = n % 100'000'000; - buff[1] = n / 10'000'000 + '0'; - n = n % 10'000'000; - buff[2] = n / 1'000'000 + '0'; - n = n % 1'000'000; - buff[3] = n / 1'00'000 + '0'; - n = n % 1'00'000; - buff[4] = n / 10'000 + '0'; - n = n % 10'000; - buff[5] = n / 1'000 + '0'; - n = n % 1'000; - buff[6] = n / 100 + '0'; - n = n % 100; - buff[7] = n / 10 + '0'; - n = n % 10; - // buff[8] = n / 1 + '0'; - buff[8] = n + '0'; - buff[9] = '\0'; +void CNosoHasher::_init( char const prefix[10], char const address[32] ) { + assert( std::strlen( prefix ) == 9 + && ( std::strlen( address ) == 30 || std::strlen( address ) == 31 ) ); + std::memcpy( m_stat, prefix, 9 ); + std::memcpy( m_stat + 9, "000000000", 9 ); + std::memcpy( m_stat + 18, address, 32 ); + constexpr static char const filler_chars[] = "%)+/5;=CGIOSYaegk%)+/5;=CGIOSYaegk%)+/5;=CGIOSYaegk%)+/5;=CGIOSYaegk%)+/5;=CGIOSYaegk"; + size_t const len = 18 + 30 + (address[30] ? 1 : 0); + std::memcpy( m_stat + len, filler_chars, 128 - len ); + assert( std::none_of( m_stat, m_stat + 128, []( int c ){ return 33 > c || c > 126; } ) ); + std::memcpy( m_base, m_stat, 18 ); + m_base[18] = '\0'; + assert( std::strlen( m_base ) == 18 ); + m_hash[32] = '\0'; + m_diff[32] = '\0'; } inline -void CNosoHasher::_hash() { -// constexpr static std::uint8_t const _col2ndid[] { -// 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, -// 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, -// 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, -// 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, -// 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, -// 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, -// 121, 122, 123, 124, 125, 126, 127, 0, }; - for( int row = 1; row < 129; row++ ) { - int const row0_128 = (row-0)*128; - int const row1_128 = (row-1)*128; - for( int col = 0; col < 127; col++ ) { - // m_stat[row*128+col] = nosohash_chars_table[ m_stat[(row-1)*128+col] + m_stat[(row-1)*128+col+1] ]; - m_stat[row0_128+col] = nosohash_chars_table[ m_stat[row1_128+col] + m_stat[row1_128+col+1] ]; +void CNosoHasher::_itoa( std::uint32_t n ) { + n = n % 1'000'000'000; + m_stat[ 9] = n / 100'000'000 + '0'; + n = n % 100'000'000; + m_stat[10] = n / 10'000'000 + '0'; + n = n % 10'000'000; + m_stat[11] = n / 1'000'000 + '0'; + n = n % 1'000'000; + m_stat[12] = n / 1'00'000 + '0'; + n = n % 1'00'000; + m_stat[13] = n / 10'000 + '0'; + n = n % 10'000; + m_stat[14] = n / 1'000 + '0'; + n = n % 1'000; + m_stat[15] = n / 100 + '0'; + n = n % 100; + m_stat[16] = n / 10 + '0'; + n = n % 10; + m_stat[17] = n + '0'; +} + +inline +void CNosoHasher::_stat() { + char * stat_1 = m_stat + 129; + std::memcpy( stat_1, m_stat, 128 ); + stat_1[128]=stat_1[0]; + for( size_t row = 0; row < 128; ++row ) { + for( size_t col = 0; col < 128; ++col ) { + stat_1[col] = nosohash_chars_table[stat_1[col + 0] + stat_1[col + 1]]; } - m_stat[row0_128+127] = nosohash_chars_table[ m_stat[row1_128+127] + m_stat[row1_128+0] ]; - // for( int col = 0; col < 128; col++ ) { - // // m_stat[row*128+col] = nosohash_chars_table[ m_stat[(row-1)*128+col] + m_stat[(row-1)*128+(col+1)%128] ]; - // // m_stat[row0_128+col] = nosohash_chars_table[ m_stat[row1_128+col] + m_stat[row1_128+(col+1)%128] ]; - // m_stat[row0_128+col] = nosohash_chars_table[ m_stat[row1_128+col] + m_stat[row1_128+_col2ndid[col]] ]; - // } + stat_1[128]=stat_1[0]; } - // for ( int i = 0; i < 32; i++ ) { - // int const i_hash = 128*128 + i*4; - // m_hash[i] = hex_dec2char_table[ nosohash_chars_table[ m_stat[i_hash+0] + m_stat[i_hash+1] + m_stat[i_hash+2] + m_stat[i_hash+3] ] % 16 ]; - // } - // m_hash[32] = '\0'; - m_hash[ 0] = hex_dec2char_table[ nosohash_chars_table[ m_stat[16384+ 0] + m_stat[16384+ 1] + m_stat[16384+ 2] + m_stat[16384+ 3] ] % 16 ]; - m_hash[ 1] = hex_dec2char_table[ nosohash_chars_table[ m_stat[16384+ 4] + m_stat[16384+ 5] + m_stat[16384+ 6] + m_stat[16384+ 7] ] % 16 ]; - m_hash[ 2] = hex_dec2char_table[ nosohash_chars_table[ m_stat[16384+ 8] + m_stat[16384+ 9] + m_stat[16384+ 10] + m_stat[16384+ 11] ] % 16 ]; - m_hash[ 3] = hex_dec2char_table[ nosohash_chars_table[ m_stat[16384+ 12] + m_stat[16384+ 13] + m_stat[16384+ 14] + m_stat[16384+ 15] ] % 16 ]; - m_hash[ 4] = hex_dec2char_table[ nosohash_chars_table[ m_stat[16384+ 16] + m_stat[16384+ 17] + m_stat[16384+ 18] + m_stat[16384+ 19] ] % 16 ]; - m_hash[ 5] = hex_dec2char_table[ nosohash_chars_table[ m_stat[16384+ 20] + m_stat[16384+ 21] + m_stat[16384+ 22] + m_stat[16384+ 23] ] % 16 ]; - m_hash[ 6] = hex_dec2char_table[ nosohash_chars_table[ m_stat[16384+ 24] + m_stat[16384+ 25] + m_stat[16384+ 26] + m_stat[16384+ 27] ] % 16 ]; - m_hash[ 7] = hex_dec2char_table[ nosohash_chars_table[ m_stat[16384+ 28] + m_stat[16384+ 29] + m_stat[16384+ 30] + m_stat[16384+ 31] ] % 16 ]; - m_hash[ 8] = hex_dec2char_table[ nosohash_chars_table[ m_stat[16384+ 32] + m_stat[16384+ 33] + m_stat[16384+ 34] + m_stat[16384+ 35] ] % 16 ]; - m_hash[ 9] = hex_dec2char_table[ nosohash_chars_table[ m_stat[16384+ 36] + m_stat[16384+ 37] + m_stat[16384+ 38] + m_stat[16384+ 39] ] % 16 ]; - m_hash[10] = hex_dec2char_table[ nosohash_chars_table[ m_stat[16384+ 40] + m_stat[16384+ 41] + m_stat[16384+ 42] + m_stat[16384+ 43] ] % 16 ]; - m_hash[11] = hex_dec2char_table[ nosohash_chars_table[ m_stat[16384+ 44] + m_stat[16384+ 45] + m_stat[16384+ 46] + m_stat[16384+ 47] ] % 16 ]; - m_hash[12] = hex_dec2char_table[ nosohash_chars_table[ m_stat[16384+ 48] + m_stat[16384+ 49] + m_stat[16384+ 50] + m_stat[16384+ 51] ] % 16 ]; - m_hash[13] = hex_dec2char_table[ nosohash_chars_table[ m_stat[16384+ 52] + m_stat[16384+ 53] + m_stat[16384+ 54] + m_stat[16384+ 55] ] % 16 ]; - m_hash[14] = hex_dec2char_table[ nosohash_chars_table[ m_stat[16384+ 56] + m_stat[16384+ 57] + m_stat[16384+ 58] + m_stat[16384+ 59] ] % 16 ]; - m_hash[15] = hex_dec2char_table[ nosohash_chars_table[ m_stat[16384+ 60] + m_stat[16384+ 61] + m_stat[16384+ 62] + m_stat[16384+ 63] ] % 16 ]; - m_hash[16] = hex_dec2char_table[ nosohash_chars_table[ m_stat[16384+ 64] + m_stat[16384+ 65] + m_stat[16384+ 66] + m_stat[16384+ 67] ] % 16 ]; - m_hash[17] = hex_dec2char_table[ nosohash_chars_table[ m_stat[16384+ 68] + m_stat[16384+ 69] + m_stat[16384+ 70] + m_stat[16384+ 71] ] % 16 ]; - m_hash[18] = hex_dec2char_table[ nosohash_chars_table[ m_stat[16384+ 72] + m_stat[16384+ 73] + m_stat[16384+ 74] + m_stat[16384+ 75] ] % 16 ]; - m_hash[19] = hex_dec2char_table[ nosohash_chars_table[ m_stat[16384+ 76] + m_stat[16384+ 77] + m_stat[16384+ 78] + m_stat[16384+ 79] ] % 16 ]; - m_hash[20] = hex_dec2char_table[ nosohash_chars_table[ m_stat[16384+ 80] + m_stat[16384+ 81] + m_stat[16384+ 82] + m_stat[16384+ 83] ] % 16 ]; - m_hash[21] = hex_dec2char_table[ nosohash_chars_table[ m_stat[16384+ 84] + m_stat[16384+ 85] + m_stat[16384+ 86] + m_stat[16384+ 87] ] % 16 ]; - m_hash[22] = hex_dec2char_table[ nosohash_chars_table[ m_stat[16384+ 88] + m_stat[16384+ 89] + m_stat[16384+ 90] + m_stat[16384+ 91] ] % 16 ]; - m_hash[23] = hex_dec2char_table[ nosohash_chars_table[ m_stat[16384+ 92] + m_stat[16384+ 93] + m_stat[16384+ 94] + m_stat[16384+ 95] ] % 16 ]; - m_hash[24] = hex_dec2char_table[ nosohash_chars_table[ m_stat[16384+ 96] + m_stat[16384+ 97] + m_stat[16384+ 98] + m_stat[16384+ 99] ] % 16 ]; - m_hash[25] = hex_dec2char_table[ nosohash_chars_table[ m_stat[16384+100] + m_stat[16384+101] + m_stat[16384+102] + m_stat[16384+103] ] % 16 ]; - m_hash[26] = hex_dec2char_table[ nosohash_chars_table[ m_stat[16384+104] + m_stat[16384+105] + m_stat[16384+106] + m_stat[16384+107] ] % 16 ]; - m_hash[27] = hex_dec2char_table[ nosohash_chars_table[ m_stat[16384+108] + m_stat[16384+109] + m_stat[16384+110] + m_stat[16384+111] ] % 16 ]; - m_hash[28] = hex_dec2char_table[ nosohash_chars_table[ m_stat[16384+112] + m_stat[16384+113] + m_stat[16384+114] + m_stat[16384+115] ] % 16 ]; - m_hash[29] = hex_dec2char_table[ nosohash_chars_table[ m_stat[16384+116] + m_stat[16384+117] + m_stat[16384+118] + m_stat[16384+119] ] % 16 ]; - m_hash[30] = hex_dec2char_table[ nosohash_chars_table[ m_stat[16384+120] + m_stat[16384+121] + m_stat[16384+122] + m_stat[16384+123] ] % 16 ]; - m_hash[31] = hex_dec2char_table[ nosohash_chars_table[ m_stat[16384+124] + m_stat[16384+125] + m_stat[16384+126] + m_stat[16384+127] ] % 16 ]; - m_hash[32] = '\0'; } inline -void CNosoHasher::_md5() { +void CNosoHasher::_pack() { + m_hash[ 0] = hex_dec2char_table[nosohash_chars_table[m_stat[129+ 0]+m_stat[129+ 1]+m_stat[129+ 2]+m_stat[129+ 3]]%16]; + m_hash[ 1] = hex_dec2char_table[nosohash_chars_table[m_stat[129+ 4]+m_stat[129+ 5]+m_stat[129+ 6]+m_stat[129+ 7]]%16]; + m_hash[ 2] = hex_dec2char_table[nosohash_chars_table[m_stat[129+ 8]+m_stat[129+ 9]+m_stat[129+ 10]+m_stat[129+ 11]]%16]; + m_hash[ 3] = hex_dec2char_table[nosohash_chars_table[m_stat[129+ 12]+m_stat[129+ 13]+m_stat[129+ 14]+m_stat[129+ 15]]%16]; + m_hash[ 4] = hex_dec2char_table[nosohash_chars_table[m_stat[129+ 16]+m_stat[129+ 17]+m_stat[129+ 18]+m_stat[129+ 19]]%16]; + m_hash[ 5] = hex_dec2char_table[nosohash_chars_table[m_stat[129+ 20]+m_stat[129+ 21]+m_stat[129+ 22]+m_stat[129+ 23]]%16]; + m_hash[ 6] = hex_dec2char_table[nosohash_chars_table[m_stat[129+ 24]+m_stat[129+ 25]+m_stat[129+ 26]+m_stat[129+ 27]]%16]; + m_hash[ 7] = hex_dec2char_table[nosohash_chars_table[m_stat[129+ 28]+m_stat[129+ 29]+m_stat[129+ 30]+m_stat[129+ 31]]%16]; + m_hash[ 8] = hex_dec2char_table[nosohash_chars_table[m_stat[129+ 32]+m_stat[129+ 33]+m_stat[129+ 34]+m_stat[129+ 35]]%16]; + m_hash[ 9] = hex_dec2char_table[nosohash_chars_table[m_stat[129+ 36]+m_stat[129+ 37]+m_stat[129+ 38]+m_stat[129+ 39]]%16]; + m_hash[10] = hex_dec2char_table[nosohash_chars_table[m_stat[129+ 40]+m_stat[129+ 41]+m_stat[129+ 42]+m_stat[129+ 43]]%16]; + m_hash[11] = hex_dec2char_table[nosohash_chars_table[m_stat[129+ 44]+m_stat[129+ 45]+m_stat[129+ 46]+m_stat[129+ 47]]%16]; + m_hash[12] = hex_dec2char_table[nosohash_chars_table[m_stat[129+ 48]+m_stat[129+ 49]+m_stat[129+ 50]+m_stat[129+ 51]]%16]; + m_hash[13] = hex_dec2char_table[nosohash_chars_table[m_stat[129+ 52]+m_stat[129+ 53]+m_stat[129+ 54]+m_stat[129+ 55]]%16]; + m_hash[14] = hex_dec2char_table[nosohash_chars_table[m_stat[129+ 56]+m_stat[129+ 57]+m_stat[129+ 58]+m_stat[129+ 59]]%16]; + m_hash[15] = hex_dec2char_table[nosohash_chars_table[m_stat[129+ 60]+m_stat[129+ 61]+m_stat[129+ 62]+m_stat[129+ 63]]%16]; + m_hash[16] = hex_dec2char_table[nosohash_chars_table[m_stat[129+ 64]+m_stat[129+ 65]+m_stat[129+ 66]+m_stat[129+ 67]]%16]; + m_hash[17] = hex_dec2char_table[nosohash_chars_table[m_stat[129+ 68]+m_stat[129+ 69]+m_stat[129+ 70]+m_stat[129+ 71]]%16]; + m_hash[18] = hex_dec2char_table[nosohash_chars_table[m_stat[129+ 72]+m_stat[129+ 73]+m_stat[129+ 74]+m_stat[129+ 75]]%16]; + m_hash[19] = hex_dec2char_table[nosohash_chars_table[m_stat[129+ 76]+m_stat[129+ 77]+m_stat[129+ 78]+m_stat[129+ 79]]%16]; + m_hash[20] = hex_dec2char_table[nosohash_chars_table[m_stat[129+ 80]+m_stat[129+ 81]+m_stat[129+ 82]+m_stat[129+ 83]]%16]; + m_hash[21] = hex_dec2char_table[nosohash_chars_table[m_stat[129+ 84]+m_stat[129+ 85]+m_stat[129+ 86]+m_stat[129+ 87]]%16]; + m_hash[22] = hex_dec2char_table[nosohash_chars_table[m_stat[129+ 88]+m_stat[129+ 89]+m_stat[129+ 90]+m_stat[129+ 91]]%16]; + m_hash[23] = hex_dec2char_table[nosohash_chars_table[m_stat[129+ 92]+m_stat[129+ 93]+m_stat[129+ 94]+m_stat[129+ 95]]%16]; + m_hash[24] = hex_dec2char_table[nosohash_chars_table[m_stat[129+ 96]+m_stat[129+ 97]+m_stat[129+ 98]+m_stat[129+ 99]]%16]; + m_hash[25] = hex_dec2char_table[nosohash_chars_table[m_stat[129+100]+m_stat[129+101]+m_stat[129+102]+m_stat[129+103]]%16]; + m_hash[26] = hex_dec2char_table[nosohash_chars_table[m_stat[129+104]+m_stat[129+105]+m_stat[129+106]+m_stat[129+107]]%16]; + m_hash[27] = hex_dec2char_table[nosohash_chars_table[m_stat[129+108]+m_stat[129+109]+m_stat[129+110]+m_stat[129+111]]%16]; + m_hash[28] = hex_dec2char_table[nosohash_chars_table[m_stat[129+112]+m_stat[129+113]+m_stat[129+114]+m_stat[129+115]]%16]; + m_hash[29] = hex_dec2char_table[nosohash_chars_table[m_stat[129+116]+m_stat[129+117]+m_stat[129+118]+m_stat[129+119]]%16]; + m_hash[30] = hex_dec2char_table[nosohash_chars_table[m_stat[129+120]+m_stat[129+121]+m_stat[129+122]+m_stat[129+123]]%16]; + m_hash[31] = hex_dec2char_table[nosohash_chars_table[m_stat[129+124]+m_stat[129+125]+m_stat[129+126]+m_stat[129+127]]%16]; + assert( std::strlen( m_hash ) == 32 ); +} + +inline +void CNosoHasher::_md5d() { assert( std::strlen( m_hash ) == 32 ); md5Init( &m_md5_ctx ); md5Update( &m_md5_ctx, (uint8_t *)m_hash, 32 ); md5Finalize( &m_md5_ctx ); - // int i_hash = 0; - // for ( int i = 0; i < 16; i++ ) { - // m_hash[i_hash++] = hex_dec2char_table[m_md5_ctx.digest[i] >> 4]; - // m_hash[i_hash++] = hex_dec2char_table[m_md5_ctx.digest[i] & 0xF]; - // } - // m_hash[32] = '\0'; m_hash[ 0] = hex_dec2char_table[m_md5_ctx.digest[ 0] >> 4]; m_hash[ 1] = hex_dec2char_table[m_md5_ctx.digest[ 0] & 0xF]; m_hash[ 2] = hex_dec2char_table[m_md5_ctx.digest[ 1] >> 4]; @@ -155,85 +136,74 @@ void CNosoHasher::_md5() { m_hash[29] = hex_dec2char_table[m_md5_ctx.digest[14] & 0xF]; m_hash[30] = hex_dec2char_table[m_md5_ctx.digest[15] >> 4]; m_hash[31] = hex_dec2char_table[m_md5_ctx.digest[15] & 0xF]; - m_hash[32] = '\0'; + assert( std::strlen( m_hash ) == 32 ); +} + +void CNosoHasher::_diff( char const target[33] ) { + assert( std::strlen( m_hash ) == 32 + && std::strlen( target ) == 32 ); + m_diff[ 0] = hex_dec2char_table[std::abs(hex_char2dec_table[(int)m_hash[ 0]]-hex_char2dec_table[(int)target[ 0]])]; + m_diff[ 1] = hex_dec2char_table[std::abs(hex_char2dec_table[(int)m_hash[ 1]]-hex_char2dec_table[(int)target[ 1]])]; + m_diff[ 2] = hex_dec2char_table[std::abs(hex_char2dec_table[(int)m_hash[ 2]]-hex_char2dec_table[(int)target[ 2]])]; + m_diff[ 3] = hex_dec2char_table[std::abs(hex_char2dec_table[(int)m_hash[ 3]]-hex_char2dec_table[(int)target[ 3]])]; + m_diff[ 4] = hex_dec2char_table[std::abs(hex_char2dec_table[(int)m_hash[ 4]]-hex_char2dec_table[(int)target[ 4]])]; + m_diff[ 5] = hex_dec2char_table[std::abs(hex_char2dec_table[(int)m_hash[ 5]]-hex_char2dec_table[(int)target[ 5]])]; + m_diff[ 6] = hex_dec2char_table[std::abs(hex_char2dec_table[(int)m_hash[ 6]]-hex_char2dec_table[(int)target[ 6]])]; + m_diff[ 7] = hex_dec2char_table[std::abs(hex_char2dec_table[(int)m_hash[ 7]]-hex_char2dec_table[(int)target[ 7]])]; + m_diff[ 8] = hex_dec2char_table[std::abs(hex_char2dec_table[(int)m_hash[ 8]]-hex_char2dec_table[(int)target[ 8]])]; + m_diff[ 9] = hex_dec2char_table[std::abs(hex_char2dec_table[(int)m_hash[ 9]]-hex_char2dec_table[(int)target[ 9]])]; + m_diff[10] = hex_dec2char_table[std::abs(hex_char2dec_table[(int)m_hash[10]]-hex_char2dec_table[(int)target[10]])]; + m_diff[11] = hex_dec2char_table[std::abs(hex_char2dec_table[(int)m_hash[11]]-hex_char2dec_table[(int)target[11]])]; + m_diff[12] = hex_dec2char_table[std::abs(hex_char2dec_table[(int)m_hash[12]]-hex_char2dec_table[(int)target[12]])]; + m_diff[13] = hex_dec2char_table[std::abs(hex_char2dec_table[(int)m_hash[13]]-hex_char2dec_table[(int)target[13]])]; + m_diff[14] = hex_dec2char_table[std::abs(hex_char2dec_table[(int)m_hash[14]]-hex_char2dec_table[(int)target[14]])]; + m_diff[15] = hex_dec2char_table[std::abs(hex_char2dec_table[(int)m_hash[15]]-hex_char2dec_table[(int)target[15]])]; + m_diff[16] = hex_dec2char_table[std::abs(hex_char2dec_table[(int)m_hash[16]]-hex_char2dec_table[(int)target[16]])]; + m_diff[17] = hex_dec2char_table[std::abs(hex_char2dec_table[(int)m_hash[17]]-hex_char2dec_table[(int)target[17]])]; + m_diff[18] = hex_dec2char_table[std::abs(hex_char2dec_table[(int)m_hash[18]]-hex_char2dec_table[(int)target[18]])]; + m_diff[19] = hex_dec2char_table[std::abs(hex_char2dec_table[(int)m_hash[19]]-hex_char2dec_table[(int)target[19]])]; + m_diff[20] = hex_dec2char_table[std::abs(hex_char2dec_table[(int)m_hash[20]]-hex_char2dec_table[(int)target[20]])]; + m_diff[21] = hex_dec2char_table[std::abs(hex_char2dec_table[(int)m_hash[21]]-hex_char2dec_table[(int)target[21]])]; + m_diff[22] = hex_dec2char_table[std::abs(hex_char2dec_table[(int)m_hash[22]]-hex_char2dec_table[(int)target[22]])]; + m_diff[23] = hex_dec2char_table[std::abs(hex_char2dec_table[(int)m_hash[23]]-hex_char2dec_table[(int)target[23]])]; + m_diff[24] = hex_dec2char_table[std::abs(hex_char2dec_table[(int)m_hash[24]]-hex_char2dec_table[(int)target[24]])]; + m_diff[25] = hex_dec2char_table[std::abs(hex_char2dec_table[(int)m_hash[25]]-hex_char2dec_table[(int)target[25]])]; + m_diff[26] = hex_dec2char_table[std::abs(hex_char2dec_table[(int)m_hash[26]]-hex_char2dec_table[(int)target[26]])]; + m_diff[27] = hex_dec2char_table[std::abs(hex_char2dec_table[(int)m_hash[27]]-hex_char2dec_table[(int)target[27]])]; + m_diff[28] = hex_dec2char_table[std::abs(hex_char2dec_table[(int)m_hash[28]]-hex_char2dec_table[(int)target[28]])]; + m_diff[29] = hex_dec2char_table[std::abs(hex_char2dec_table[(int)m_hash[29]]-hex_char2dec_table[(int)target[29]])]; + m_diff[30] = hex_dec2char_table[std::abs(hex_char2dec_table[(int)m_hash[30]]-hex_char2dec_table[(int)target[30]])]; + m_diff[31] = hex_dec2char_table[std::abs(hex_char2dec_table[(int)m_hash[31]]-hex_char2dec_table[(int)target[31]])]; + assert( std::strlen( m_diff ) == 32 ); } -CNosoHasher::CNosoHasher( char const prefix[10], char const address[32] ) { - constexpr static const char NOSOHASH_FILLER_CHARS[] = "%)+/5;=CGIOSYaegk"; - constexpr static const int NOSOHASH_FILLER_COUNT = 17; +void CNosoHasher::Init( char const prefix[10], char const address[32] ) { assert( std::strlen( prefix ) == 9 && ( std::strlen( address ) == 30 || std::strlen( address ) == 31 ) ); - std::memcpy( m_base, prefix, 9 ); - std::memcpy( m_stat, m_base, 9 ); - CNosoHasher::_ito9a( 0, m_base + 9 ); + this->_init( prefix, address ); assert( std::strlen( m_base ) == 18 ); - std::memcpy( m_stat + 9, m_base + 9, 9 ); - int addr_len = 30 + (address[30] ? 1 : 0); - std::memcpy( m_stat + 9 + 9, address, addr_len ); - int len = 18 + addr_len; - int div = ( 128 - len ) / NOSOHASH_FILLER_COUNT; - int mod = ( 128 - len ) % NOSOHASH_FILLER_COUNT; - for ( int i = 0; i < div; i++ ) { - std::memcpy( m_stat + len, NOSOHASH_FILLER_CHARS, NOSOHASH_FILLER_COUNT ); - len += NOSOHASH_FILLER_COUNT; - } - std::memcpy( m_stat + len, NOSOHASH_FILLER_CHARS, mod ); - assert( std::none_of( m_stat, m_stat + 128, []( int c ){ return 33 > c || c > 126; } ) ); } char const * CNosoHasher::GetBase( std::uint32_t counter ) { - CNosoHasher::_ito9a( counter, m_base + 9 ); + this->_itoa( counter ); + std::memcpy( m_base + 9, m_stat + 9, 9 ); assert( std::strlen( m_base ) == 18 ); - std::memcpy( m_stat + 9, m_base + 9, 9 ); return m_base; } char const * CNosoHasher::GetHash() { - this->_hash(); - this->_md5(); + this->_stat(); + this->_pack(); + this->_md5d(); + assert( std::strlen( m_hash ) == 32 ); return m_hash; } char const * CNosoHasher::GetDiff( char const target[33] ) { assert( std::strlen( m_hash ) == 32 && std::strlen( target ) == 32 ); - // for ( int i = 0; i < 32; i++ ) - // m_diff[i] = hex_dec2char_table[ std::abs( hex_char2dec_table[ (int)m_hash[i] ] - hex_char2dec_table[ (int)target[i] ] ) ]; - // m_diff[32] = '\0'; - // return m_diff; - m_diff[ 0] = hex_dec2char_table[ std::abs( hex_char2dec_table[ (int)m_hash[ 0] ] - hex_char2dec_table[ (int)target[ 0] ] ) ]; - m_diff[ 1] = hex_dec2char_table[ std::abs( hex_char2dec_table[ (int)m_hash[ 1] ] - hex_char2dec_table[ (int)target[ 1] ] ) ]; - m_diff[ 2] = hex_dec2char_table[ std::abs( hex_char2dec_table[ (int)m_hash[ 2] ] - hex_char2dec_table[ (int)target[ 2] ] ) ]; - m_diff[ 3] = hex_dec2char_table[ std::abs( hex_char2dec_table[ (int)m_hash[ 3] ] - hex_char2dec_table[ (int)target[ 3] ] ) ]; - m_diff[ 4] = hex_dec2char_table[ std::abs( hex_char2dec_table[ (int)m_hash[ 4] ] - hex_char2dec_table[ (int)target[ 4] ] ) ]; - m_diff[ 5] = hex_dec2char_table[ std::abs( hex_char2dec_table[ (int)m_hash[ 5] ] - hex_char2dec_table[ (int)target[ 5] ] ) ]; - m_diff[ 6] = hex_dec2char_table[ std::abs( hex_char2dec_table[ (int)m_hash[ 6] ] - hex_char2dec_table[ (int)target[ 6] ] ) ]; - m_diff[ 7] = hex_dec2char_table[ std::abs( hex_char2dec_table[ (int)m_hash[ 7] ] - hex_char2dec_table[ (int)target[ 7] ] ) ]; - m_diff[ 8] = hex_dec2char_table[ std::abs( hex_char2dec_table[ (int)m_hash[ 8] ] - hex_char2dec_table[ (int)target[ 8] ] ) ]; - m_diff[ 9] = hex_dec2char_table[ std::abs( hex_char2dec_table[ (int)m_hash[ 9] ] - hex_char2dec_table[ (int)target[ 9] ] ) ]; - m_diff[10] = hex_dec2char_table[ std::abs( hex_char2dec_table[ (int)m_hash[10] ] - hex_char2dec_table[ (int)target[10] ] ) ]; - m_diff[11] = hex_dec2char_table[ std::abs( hex_char2dec_table[ (int)m_hash[11] ] - hex_char2dec_table[ (int)target[11] ] ) ]; - m_diff[12] = hex_dec2char_table[ std::abs( hex_char2dec_table[ (int)m_hash[12] ] - hex_char2dec_table[ (int)target[12] ] ) ]; - m_diff[13] = hex_dec2char_table[ std::abs( hex_char2dec_table[ (int)m_hash[13] ] - hex_char2dec_table[ (int)target[13] ] ) ]; - m_diff[14] = hex_dec2char_table[ std::abs( hex_char2dec_table[ (int)m_hash[14] ] - hex_char2dec_table[ (int)target[14] ] ) ]; - m_diff[15] = hex_dec2char_table[ std::abs( hex_char2dec_table[ (int)m_hash[15] ] - hex_char2dec_table[ (int)target[15] ] ) ]; - m_diff[16] = hex_dec2char_table[ std::abs( hex_char2dec_table[ (int)m_hash[16] ] - hex_char2dec_table[ (int)target[16] ] ) ]; - m_diff[17] = hex_dec2char_table[ std::abs( hex_char2dec_table[ (int)m_hash[17] ] - hex_char2dec_table[ (int)target[17] ] ) ]; - m_diff[18] = hex_dec2char_table[ std::abs( hex_char2dec_table[ (int)m_hash[18] ] - hex_char2dec_table[ (int)target[18] ] ) ]; - m_diff[19] = hex_dec2char_table[ std::abs( hex_char2dec_table[ (int)m_hash[19] ] - hex_char2dec_table[ (int)target[19] ] ) ]; - m_diff[20] = hex_dec2char_table[ std::abs( hex_char2dec_table[ (int)m_hash[20] ] - hex_char2dec_table[ (int)target[20] ] ) ]; - m_diff[21] = hex_dec2char_table[ std::abs( hex_char2dec_table[ (int)m_hash[21] ] - hex_char2dec_table[ (int)target[21] ] ) ]; - m_diff[22] = hex_dec2char_table[ std::abs( hex_char2dec_table[ (int)m_hash[22] ] - hex_char2dec_table[ (int)target[22] ] ) ]; - m_diff[23] = hex_dec2char_table[ std::abs( hex_char2dec_table[ (int)m_hash[23] ] - hex_char2dec_table[ (int)target[23] ] ) ]; - m_diff[24] = hex_dec2char_table[ std::abs( hex_char2dec_table[ (int)m_hash[24] ] - hex_char2dec_table[ (int)target[24] ] ) ]; - m_diff[25] = hex_dec2char_table[ std::abs( hex_char2dec_table[ (int)m_hash[25] ] - hex_char2dec_table[ (int)target[25] ] ) ]; - m_diff[26] = hex_dec2char_table[ std::abs( hex_char2dec_table[ (int)m_hash[26] ] - hex_char2dec_table[ (int)target[26] ] ) ]; - m_diff[27] = hex_dec2char_table[ std::abs( hex_char2dec_table[ (int)m_hash[27] ] - hex_char2dec_table[ (int)target[27] ] ) ]; - m_diff[28] = hex_dec2char_table[ std::abs( hex_char2dec_table[ (int)m_hash[28] ] - hex_char2dec_table[ (int)target[28] ] ) ]; - m_diff[29] = hex_dec2char_table[ std::abs( hex_char2dec_table[ (int)m_hash[29] ] - hex_char2dec_table[ (int)target[29] ] ) ]; - m_diff[30] = hex_dec2char_table[ std::abs( hex_char2dec_table[ (int)m_hash[30] ] - hex_char2dec_table[ (int)target[30] ] ) ]; - m_diff[31] = hex_dec2char_table[ std::abs( hex_char2dec_table[ (int)m_hash[31] ] - hex_char2dec_table[ (int)target[31] ] ) ]; - m_diff[32] = '\0'; + this->_diff( target ); + assert( std::strlen( m_diff ) == 32 ); return m_diff; } @@ -245,4 +215,3 @@ std::string nosohash_prefix( int num ) { NOSOHASH_HASHEABLE_CHARS[ num / NOSOHASH_HASHEABLE_COUNT ], NOSOHASH_HASHEABLE_CHARS[ num % NOSOHASH_HASHEABLE_COUNT ], }; } - diff --git a/hashing.hpp b/hashing.hpp index 7add27b..e2f6a3a 100644 --- a/hashing.hpp +++ b/hashing.hpp @@ -1,5 +1,8 @@ #ifndef __NOSO2M_HASHING__HPP__ #define __NOSO2M_HASHING__HPP__ +#ifdef _WIN32 +#define _CRT_SECURE_NO_WARNINGS +#endif #include #include #include @@ -9,9 +12,9 @@ class CNosoHasher { char m_base[19]; char m_hash[33]; char m_diff[33]; - char m_stat[129*128]; + char m_stat[258]; MD5Context m_md5_ctx; - constexpr static char const hex_dec2char_table[16] { + constexpr static char const hex_dec2char_table[] { '0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F' }; constexpr static char const hex_char2dec_table[] { 0, @@ -22,7 +25,7 @@ class CNosoHasher { 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 0, 0, 0, 0, 0, 0, 10, 11, 12, 13, 14, 15, }; - constexpr static std::uint16_t const nosohash_chars_table[505] { + constexpr static std::uint16_t const nosohash_chars_table[] { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, @@ -46,12 +49,15 @@ class CNosoHasher { 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, }; - static - void _ito9a( std::uint32_t n, char * buff ); - void _hash(); - void _md5(); + void _init( char const prefix[10], char const address[32] ); + void _itoa( std::uint32_t n ); + void _stat(); + void _pack(); + void _md5d(); + void _diff( char const target[33] ); public: - CNosoHasher( char const prefix[10], char const address[32] ); + CNosoHasher() = default; + void Init( char const prefix[10], char const address[32] ); char const * GetBase( std::uint32_t counter ); char const * GetHash(); char const * GetDiff( char const target[33] ); diff --git a/images/textui.png b/images/textui.png index 47dcfe8..c6a71e6 100644 Binary files a/images/textui.png and b/images/textui.png differ diff --git a/inet.cpp b/inet.cpp index 5d6f66f..45077e2 100644 --- a/inet.cpp +++ b/inet.cpp @@ -1,3 +1,6 @@ +#ifdef _WIN32 +#define _CRT_SECURE_NO_WARNINGS +#endif #include #include #ifdef _WIN32 @@ -12,7 +15,7 @@ #include "output.hpp" #include "noso-2m.hpp" - int inet_init() { +int inet_init() { #ifdef _WIN32 WSADATA wsaData; return WSAStartup( MAKEWORD( 2, 2 ), &wsaData ) != NO_ERROR ? -1 : 0; @@ -26,7 +29,8 @@ void inet_cleanup() { #endif } -inline void inet_close_socket( int sockfd ) { +inline +void inet_close_socket( int sockfd ) { #ifdef _WIN32 closesocket( sockfd ); #else @@ -34,7 +38,8 @@ inline void inet_close_socket( int sockfd ) { #endif } -inline int inet_set_nonblock( int sockfd ) { +inline +int inet_set_nonblock( int sockfd ) { #ifdef _WIN32 u_long mode = 1; if ( ioctlsocket( sockfd, FIONBIO, &mode ) != NO_ERROR ) return -1; @@ -46,7 +51,8 @@ inline int inet_set_nonblock( int sockfd ) { return sockfd; } -inline int inet_socket( struct addrinfo *serv_info, int timeosec ) { +inline +int inet_socket( struct addrinfo *serv_info, int timeosec ) { struct addrinfo *psi = serv_info; struct timeval timeout { .tv_sec = timeosec, @@ -98,7 +104,8 @@ inline int inet_socket( struct addrinfo *serv_info, int timeosec ) { return -1; } -inline int inet_send( int sockfd, int timeosec, const char *message, size_t size ) { +inline +int inet_send( int sockfd, int timeosec, const char *message, size_t size ) { struct timeval timeout { .tv_sec = timeosec, .tv_usec = 0 @@ -113,7 +120,8 @@ inline int inet_send( int sockfd, int timeosec, const char *message, size_t size return slen; } -inline int inet_recv( int sockfd, int timeosec, char *buffer, size_t buffsize ) { +inline +int inet_recv( int sockfd, int timeosec, char *buffer, size_t buffsize ) { struct timeval timeout { .tv_sec = timeosec, .tv_usec = 0 @@ -129,7 +137,8 @@ inline int inet_recv( int sockfd, int timeosec, char *buffer, size_t buffsize ) return rlen; } -inline int inet_command( struct addrinfo *serv_info, uint32_t timeosec, char *buffer, size_t buffsize ) { +inline +int inet_command( struct addrinfo *serv_info, uint32_t timeosec, char *buffer, size_t buffsize ) { int sockfd = inet_socket( serv_info, timeosec ); if ( sockfd < 0 ) return sockfd; int rlen = 0; @@ -140,11 +149,13 @@ inline int inet_command( struct addrinfo *serv_info, uint32_t timeosec, char *bu return rlen; } -inline CInet::CInet( const std::string &host, const std::string &port, int timeosec ) +inline +CInet::CInet( const std::string &host, const std::string &port, int timeosec ) : m_host { host }, m_port { port }, m_timeosec( timeosec ) { } -inline struct addrinfo * CInet::InitService() { +inline +struct addrinfo * CInet::InitService() { struct addrinfo hints, *serv_info; std::memset( &hints, 0, sizeof( hints ) ); hints.ai_family = AF_INET; @@ -159,13 +170,15 @@ inline struct addrinfo * CInet::InitService() { return serv_info; } -inline void CInet::CleanService( struct addrinfo * serv_info ) { +inline +void CInet::CleanService( struct addrinfo * serv_info ) { if ( serv_info == NULL ) return; freeaddrinfo( serv_info ); serv_info = NULL; } -inline int CInet::ExecCommand( char *buffer, std::size_t buffsize ) { +inline +int CInet::ExecCommand( char *buffer, std::size_t buffsize ) { assert( buffer && buffsize > 0 ); struct addrinfo * serv_info = this->InitService(); if ( serv_info == NULL ) return -1; @@ -184,6 +197,12 @@ int CNodeInet::RequestTimestamp( char *buffer, std::size_t buffsize ) { return this->ExecCommand( buffer, buffsize ); } +int CNodeInet::RequestMNList( char *buffer, std::size_t buffsize ) { + assert( buffer && buffsize > 0 ); + std::strcpy( buffer, "NSLMNS\n" ); + return this->ExecCommand( buffer, buffsize ); +} + int CNodeInet::RequestSource( char *buffer, std::size_t buffsize ) { assert( buffer && buffsize > 0 ); std::strcpy( buffer, "NODESTATUS\n" ); @@ -213,7 +232,7 @@ int CPoolInet::RequestSource( const char address[32], char *buffer, std::size_t assert( buffer && buffsize > 0 ); assert( std::strlen( address ) == 30 || std::strlen( address ) == 31 ); // SOURCE {address} {MinerName} - std::snprintf( buffer, buffsize, "SOURCE %s noso-2m-v%s\n", address, NOSO_2M_VERSION_CTEXT ); + std::snprintf( buffer, buffsize, "SOURCE %s noso-2m-v%s\n", address, NOSO_2M_VERSION ); return this->ExecCommand( buffer, buffsize ); } @@ -223,6 +242,6 @@ int CPoolInet::SubmitSolution( std::uint32_t blck_no, const char base[19], const assert( std::strlen( base ) == 18 && std::strlen( address ) == 30 || std::strlen( address ) == 31 ); // SHARE {Address} {Hash} {MinerName} - std::snprintf( buffer, buffsize, "SHARE %s %s noso-2m-v%s %d\n", address, base, NOSO_2M_VERSION_CTEXT, blck_no ); + std::snprintf( buffer, buffsize, "SHARE %s %s noso-2m-v%s %d\n", address, base, NOSO_2M_VERSION, blck_no ); return this->ExecCommand( buffer, buffsize ); } diff --git a/inet.hpp b/inet.hpp index 31c3810..e9c92d4 100644 --- a/inet.hpp +++ b/inet.hpp @@ -1,5 +1,8 @@ #ifndef __NOSO2M_INET_HPP__ #define __NOSO2M_INET_HPP__ +#ifdef _WIN32 +#define _CRT_SECURE_NO_WARNINGS +#endif #include int inet_init(); @@ -22,6 +25,7 @@ class CNodeInet : public CInet { public: CNodeInet( const std::string &host, const std::string &port , int timeosec ); int RequestTimestamp( char *buffer, std::size_t buffsize ); + int RequestMNList( char *buffer, std::size_t buffsize ); int RequestSource( char *buffer, std::size_t buffsize ); int SubmitSolution( std::uint32_t blck, const char base[19], const char address[32], char *buffer, std::size_t buffsize ); diff --git a/logging.hpp b/logging.hpp index c3408fd..e65035f 100644 --- a/logging.hpp +++ b/logging.hpp @@ -1,5 +1,8 @@ #ifndef __NOSO2M_LOGGING_HPP__ #define __NOSO2M_LOGGING_HPP__ +#ifdef _WIN32 +#define _CRT_SECURE_NO_WARNINGS +#endif #include #include #include diff --git a/mining.cpp b/mining.cpp index 7040921..a35b4d1 100644 --- a/mining.cpp +++ b/mining.cpp @@ -1,12 +1,23 @@ +#ifdef _WIN32 +#define _CRT_SECURE_NO_WARNINGS +#endif #include #include #include "mining.hpp" #include "noso-2m.hpp" -#include "hashing.hpp" extern bool g_still_running; extern bool g_solo_mining; +CMineThread::CMineThread( std::uint32_t miner_id, std::uint32_t thread_id ) + : m_miner_id { miner_id }, m_thread_id { thread_id } { +} + +void CMineThread::CleanupSyncState() { + m_condv_blck_no.notify_one(); + m_condv_summary.notify_one(); +} + void CMineThread::SetBlockSummary( std::uint32_t hashes_count, double duration ) { m_mutex_summary.lock(); m_block_mining_duration = duration; @@ -26,12 +37,14 @@ std::tuple CMineThread::GetBlockSummary() { return summary; } +inline void CMineThread::WaitTarget() { std::unique_lock unique_lock_blck_no( m_mutex_blck_no ); m_condv_blck_no.wait( unique_lock_blck_no, [&]() { return !g_still_running || m_blck_no > 0; } ); unique_lock_blck_no.unlock(); } +inline void CMineThread::DoneTarget() { std::unique_lock unique_lock_blck_no( m_mutex_blck_no ); m_blck_no = 0; @@ -45,8 +58,12 @@ void CMineThread::NewTarget( const std::shared_ptr &target ) { + nosohash_prefix( m_thread_id ) }; thread_prefix.append( 9 - thread_prefix.size(), '!' ); m_mutex_blck_no.lock(); - std::strcpy( m_prefix, thread_prefix.c_str() ); - std::strcpy( m_address, target->address.c_str() ); + if ( m_prefix != thread_prefix + || m_address != target->address ) { + std::strcpy( m_prefix, thread_prefix.c_str() ); + std::strcpy( m_address, target->address.c_str() ); + m_hasher.Init( m_prefix, m_address ); + } std::strcpy( m_lb_hash, target->lb_hash.c_str() ); std::strcpy( m_mn_diff, target->mn_diff.c_str() ); m_blck_no = target->blck_no + 1; @@ -55,26 +72,25 @@ void CMineThread::NewTarget( const std::shared_ptr &target ) { } void CMineThread::Mine( void ( * NewSolFunc )( const std::shared_ptr& ) ) { + char best_diff[33]; while ( g_still_running ) { this->WaitTarget(); if ( !g_still_running ) break; assert( ( std::strlen( m_address ) == 30 || std::strlen( m_address ) == 31 ) && std::strlen( m_lb_hash ) == 32 && std::strlen( m_mn_diff ) == 32 ); - char best_diff[33]; std::strcpy( best_diff, m_mn_diff ); std::size_t match_len { 0 }; while ( best_diff[match_len] == '0' ) ++match_len; - std::uint32_t noso_hash_counter { 0 }; - CNosoHasher noso_hasher( m_prefix, m_address ); + std::uint32_t hashes_counter { 0 }; auto begin_mining { std::chrono::steady_clock::now() }; while ( g_still_running && 1 <= NOSO_BLOCK_AGE && NOSO_BLOCK_AGE <= 585 ) { - const char *base { noso_hasher.GetBase( noso_hash_counter++ ) }; - const char *hash { noso_hasher.GetHash() }; + const char *base { m_hasher.GetBase( hashes_counter++ ) }; + const char *hash { m_hasher.GetHash() }; assert( std::strlen( base ) == 18 && std::strlen( hash ) == 32 ); if ( std::strncmp( hash, m_lb_hash, match_len ) == 0 ) { if ( g_solo_mining ) { - const char *diff { noso_hasher.GetDiff( m_lb_hash ) }; + const char *diff { m_hasher.GetDiff( m_lb_hash ) }; assert( std::strlen( diff ) == 32 ); if ( std::strcmp( diff, best_diff ) < 0 ) { NewSolFunc( std::make_shared( m_blck_no, base, hash, diff ) ); @@ -85,7 +101,7 @@ void CMineThread::Mine( void ( * NewSolFunc )( const std::shared_ptr& } } std::chrono::duration elapsed_mining { std::chrono::steady_clock::now() - begin_mining }; - this->SetBlockSummary( noso_hash_counter, elapsed_mining.count() ); + this->SetBlockSummary( hashes_counter, elapsed_mining.count() ); this->DoneTarget(); } // END while ( g_still_running ) { } diff --git a/mining.hpp b/mining.hpp index 8feb80c..f5678ad 100644 --- a/mining.hpp +++ b/mining.hpp @@ -1,8 +1,13 @@ #ifndef __NOSO2M__MINING_HPP__ #define __NOSO2M__MINING_HPP__ +#ifdef _WIN32 +#define _CRT_SECURE_NO_WARNINGS +#endif #include #include +#include "hashing.hpp" + struct CSolution { std::uint32_t blck; std::string base; @@ -73,6 +78,7 @@ class CMineThread { std::uint32_t const m_miner_id; std::uint32_t const m_thread_id; protected: + CNosoHasher m_hasher; char m_address[32]; char m_prefix[10]; std::uint32_t m_blck_no { 0 }; @@ -85,14 +91,9 @@ class CMineThread { mutable std::mutex m_mutex_summary; mutable std::condition_variable m_condv_summary; public: - CMineThread( std::uint32_t miner_id, std::uint32_t thread_id ) - : m_miner_id { miner_id }, m_thread_id { thread_id } { - } + CMineThread( std::uint32_t miner_id, std::uint32_t thread_id ); virtual ~CMineThread() = default; - void CleanupSyncState() { - m_condv_blck_no.notify_one(); - m_condv_summary.notify_one(); - } + void CleanupSyncState(); void WaitTarget(); void DoneTarget(); void NewTarget( const std::shared_ptr &target ); diff --git a/misc.cpp b/misc.cpp index 8b02fa9..5c6d96b 100644 --- a/misc.cpp +++ b/misc.cpp @@ -1,3 +1,6 @@ +#ifdef _WIN32 +#define _CRT_SECURE_NO_WARNINGS +#endif #include #include "misc.hpp" #include "output.hpp" @@ -9,21 +12,25 @@ extern std::uint32_t g_miner_id; extern std::uint32_t g_threads_count; extern std::vector> const g_default_pools; -inline bool is_valid_address( std::string const & address ) { +inline +bool is_valid_address( std::string const & address ) { if ( address.length() < 30 || address.length() > 31 ) return false; return true; } -inline bool is_valid_minerid( std::uint32_t minerid ) { +inline +bool is_valid_minerid( std::uint32_t minerid ) { if ( minerid < 0 || minerid > 8100 ) return false; return true; } -inline bool is_valid_threads( std::uint32_t count ) { +inline +bool is_valid_threads( std::uint32_t count ) { if ( count < 2 ) return false; return true; } +inline std::vector> parse_pools_argv( std::string const & poolstr ) { const std::regex re_pool1 { ";|[[:space:]]" }; const std::regex re_pool2 { @@ -102,7 +109,8 @@ mining_options_t .minerid = -1, }; -inline void process_arg_options( cxxopts::ParseResult const & parsed_options ) { +inline +void process_arg_options( cxxopts::ParseResult const & parsed_options ) { try { g_arg_options.address = parsed_options["address"].as(); if ( !is_valid_address( g_arg_options.address ) ) @@ -123,7 +131,8 @@ inline void process_arg_options( cxxopts::ParseResult const & parsed_options ) { } } -inline void process_cfg_options( cxxopts::ParseResult const & parsed_options ) { +inline +void process_cfg_options( cxxopts::ParseResult const & parsed_options ) { g_cfg_options.filename = parsed_options["config"].as(); std::ifstream cfg_istream( g_cfg_options.filename ); if( !cfg_istream.good() ) { diff --git a/misc.hpp b/misc.hpp index 1520f01..76581ca 100644 --- a/misc.hpp +++ b/misc.hpp @@ -1,5 +1,8 @@ #ifndef __NOSO2M_MISC_HPP__ #define __NOSO2M_MISC_HPP__ +#ifdef _WIN32 +#define _CRT_SECURE_NO_WARNINGS +#endif #include #include #include diff --git a/noso-2m.cfg b/noso-2m.cfg index f4457e1..d383ca6 100644 --- a/noso-2m.cfg +++ b/noso-2m.cfg @@ -2,4 +2,4 @@ address N3G1HhkpXvmLcsWFXySdAxX3GZpkMFS minerid 0 threads 2 solo false -pools f04ever;devnoso +pools f04ever diff --git a/noso-2m.cpp b/noso-2m.cpp index 37c9ea3..272b2f5 100644 --- a/noso-2m.cpp +++ b/noso-2m.cpp @@ -18,21 +18,20 @@ extern std::vector> const g_default_nodes { - { "45.146.252.103" , "8080" }, { "109.230.238.240" , "8080" }, - { "194.156.88.117" , "8080" }, - { "23.94.21.83" , "8080" }, - { "107.175.59.177" , "8080" }, - { "107.172.193.176" , "8080" }, - { "107.175.194.151" , "8080" }, - { "192.3.73.184" , "8080" }, - { "107.175.24.151" , "8080" }, - { "107.174.137.27" , "8080" }, + { "149.57.235.14" , "8080" }, + { "149.57.226.244" , "8080" }, + { "81.22.38.101" , "8080" }, + { "66.151.117.247" , "8080" }, + { "149.57.229.81" , "8080" }, + { "149.57.242.211" , "8080" }, + { "149.57.138.12" , "8080" }, + { "159.196.1.198" , "8080" }, + { "101.100.138.125" , "8080" }, }; // seed nodes extern std::vector> const g_default_pools { { "f04ever", "209.126.80.203", "8082" }, - { "devnoso", "45.146.252.103", "8082" } }; bool g_solo_mining { false }; bool g_still_running { true }; @@ -70,13 +69,13 @@ int main( int argc, char *argv[] ) { std::exit( EXIT_SUCCESS ); } if ( parsed_options.count( "version" ) ) { - NOSO_STDOUT << "version " << NOSO_2M_VERSION_CTEXT << std::endl; + NOSO_STDOUT << "version " << NOSO_2M_VERSION << std::endl; std::exit( EXIT_SUCCESS ); } NOSO_LOG_INIT(); NOSO_LOG_INFO << "noso-2m - A miner for Nosocryptocurrency Protocol-2" << std::endl; NOSO_LOG_INFO << "f04ever (c) 2022 https://github.com/f04ever/noso-2m" << std::endl; - NOSO_LOG_INFO << "version " << NOSO_2M_VERSION_CTEXT << std::endl; + NOSO_LOG_INFO << "version " << NOSO_2M_VERSION << std::endl; NOSO_LOG_INFO << "--" << std::endl; try { NOSO_TUI_StartTUI(); @@ -123,10 +122,22 @@ int main( int argc, char *argv[] ) { NOSO_TUI_OutputHistWin(); try { if ( inet_init() < 0 ) throw std::runtime_error( "WSAStartup errors!" ); - std::time_t mainnet_timestamp { CCommThread::GetInstance()->RequestTimestamp() }; - if ( mainnet_timestamp < 0 ) throw std::runtime_error( "Can not check mainnet's timestamp!" ); - else if ( NOSO_TIMESTAMP - mainnet_timestamp > DEFAULT_TIMESTAMP_DIFFERENCES ) - throw std::runtime_error( "Your machine's time is different from mainnet. Synchronize clock!" ); + if ( g_solo_mining ) { + std::time_t mainnet_timestamp { CCommThread::GetInstance()->RequestTimestamp() }; + if ( mainnet_timestamp == std::time_t( -1 ) ) { + throw std::runtime_error( "Can not check mainnet's timestamp!" ); + } + else { + std::time_t computer_timestamp { static_cast( NOSO_TIMESTAMP ) }; + long timestamp_difference = std::abs( computer_timestamp - mainnet_timestamp ); + if ( timestamp_difference > DEFAULT_TIMESTAMP_DIFFERENCES ) { + msg = "Your machine's time is different (" + + std::to_string( timestamp_difference ) + + ") from mainnet. Synchronize clock!"; + throw std::runtime_error( msg ); + } + } + } for ( std::uint32_t thread_id = 0; thread_id < g_threads_count - 1; ++thread_id ) g_mine_objects.push_back( std::make_shared( g_miner_id, thread_id ) ); std::thread comm_thread( &CCommThread::Communicate, CCommThread::GetInstance() ); diff --git a/noso-2m.hpp b/noso-2m.hpp index aa5ceef..5b9b428 100644 --- a/noso-2m.hpp +++ b/noso-2m.hpp @@ -1,35 +1,11 @@ #ifndef __NOSO2M_HPP__ #define __NOSO2M_HPP__ -#define NOSO_2M_VERSION_MAJOR 0 -#define NOSO_2M_VERSION_MINOR 2 -#define NOSO_2M_VERSION_PATCH 5 -#define NOSO_2M_VERSION_CTEXT (\ - std::to_string(NOSO_2M_VERSION_MAJOR)\ - +"."+std::to_string(NOSO_2M_VERSION_MINOR)\ - +"."+std::to_string(NOSO_2M_VERSION_PATCH)\ - ).c_str() -#define NOSO_2M_VERSION_VTEXT (\ - std::string("version")\ - +" "+std::to_string(NOSO_2M_VERSION_MAJOR)\ - +"."+std::to_string(NOSO_2M_VERSION_MINOR)\ - +"."+std::to_string(NOSO_2M_VERSION_PATCH)\ - ).c_str() -#define DEFAULT_CONFIG_FILENAME "noso-2m.cfg" -#define DEFAULT_LOGGING_FILENAME "noso-2m.log" -#define DEFAULT_POOL_URL_LIST "f04ever;devnoso" -#define DEFAULT_MINER_ADDRESS "N3G1HhkpXvmLcsWFXySdAxX3GZpkMFS" -#define DEFAULT_MINER_ID 0 -#define DEFAULT_THREADS_COUNT 2 -#define DEFAULT_NODE_INET_TIMEOSEC 10 -#define DEFAULT_POOL_INET_TIMEOSEC 60 -#define DEFAULT_TIMESTAMP_DIFFERENCES 3 + +#include "config.hpp" #define NOSO_NUL_HASH "00000000000000000000000000000000" #define NOSO_MAX_DIFF "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF" #define NOSO_TIMESTAMP ( (long long)( std::time( 0 ) ) ) #define NOSO_BLOCK_AGE ( NOSO_TIMESTAMP % 600 ) -#define CONSENSUS_NODES_COUNT 3 -#define INET_CIRCLE_SECONDS 0.1 -#define INET_BUFFER_SIZE 1024 #endif // __NOSO2M_HPP__ diff --git a/output.hpp b/output.hpp index b926196..9904495 100644 --- a/output.hpp +++ b/output.hpp @@ -1,5 +1,8 @@ #ifndef __NOSO2M_OUTPUT_HPP__ #define __NOSO2M_OUTPUT_HPP__ +#ifdef _WIN32 +#define _CRT_SECURE_NO_WARNINGS +#endif #include #include #include "logging.hpp" diff --git a/textui.hpp b/textui.hpp index 2ef8137..241777a 100644 --- a/textui.hpp +++ b/textui.hpp @@ -1,5 +1,8 @@ #ifndef __NOSO2M_TEXTUI_HPP__ #define __NOSO2M_TEXTUI_HPP__ +#ifdef _WIN32 +#define _CRT_SECURE_NO_WARNINGS +#endif #include #include #include @@ -7,6 +10,7 @@ #include #include "util.hpp" #include "tool.hpp" +#include "comm.hpp" #include "noso-2m.hpp" #ifndef KEY_ESC @@ -268,12 +272,17 @@ class CTextUI { // A singleton pattern class this->OutputInfoPad( "Supported commands:" ); this->OutputInfoPad( "" ); this->OutputInfoPad( " threads - Show hashrate per thread last mining block" ); - this->OutputInfoPad( " pools - Show pool information of configured pools" ); + this->OutputInfoPad( " pools - Show information of configured pools" ); + this->OutputInfoPad( " nodes - Show current mining nodes" ); this->OutputInfoPad( " help - Show this list of supported commands" ); this->OutputInfoPad( " exit - Exit noso-2m, same as Ctrl+C" ); this->OutputInfoPad( "" ); this->OutputInfoPad( "--" ); this->OutputInfoWin(); + } else if ( iequal( "nodes", cmdstr ) ) { + this->OutputStatPad( "Showing nodes information" ); + this->OutputStatWin(); + CTools::ShowNodeInformation( CCommThread::GetInstance()->GetMiningNodes() ); } else if ( iequal( "pools", cmdstr ) ) { this->OutputStatPad( "Showing pools information" ); this->OutputStatWin(); @@ -548,7 +557,7 @@ class CTextUI { // A singleton pattern class this->ResetHeadPad(); this->OutputHeadPad( "noso-2m - A miner for Nosocryptocurrency Protocol-2" ); this->OutputHeadPad( "f04ever (c) 2022 https://github.com/f04ever/noso-2m" ); - this->OutputHeadPad( NOSO_2M_VERSION_VTEXT ); + this->OutputHeadPad( (std::string("version ") + NOSO_2M_VERSION).c_str() ); this->OutputHeadPad( "--" ); this->OutputHeadWin(); } diff --git a/tool.cpp b/tool.cpp index 6c48ab9..1c36397 100644 --- a/tool.cpp +++ b/tool.cpp @@ -1,3 +1,6 @@ +#ifdef _WIN32 +#define _CRT_SECURE_NO_WARNINGS +#endif #include #include "tool.hpp" #include "inet.hpp" @@ -6,8 +9,28 @@ #include "output.hpp" #include "noso-2m.hpp" +int CTools::ShowNodeInformation( std::vector> const & mining_nodes ) { + char msg[200]; + std::snprintf( msg, 200, "NODES INFORMATION" ); + NOSO_TUI_OutputInfoPad( msg ); + std::snprintf( msg, 200, "------------------------------------------------------------------------" ); + NOSO_TUI_OutputInfoPad( msg ); + std::for_each( + std::cbegin( mining_nodes ), + std::cend( mining_nodes ), + []( auto const & node ) { + std::string msg { "- " + std::get<0>( node ) + ":" + std::get<1>( node ) }; + NOSO_TUI_OutputInfoPad( msg.c_str() ); + NOSO_TUI_OutputInfoWin(); + } ); + std::snprintf( msg, 200, "--" ); + NOSO_TUI_OutputInfoPad( msg ); + NOSO_TUI_OutputInfoWin(); + return ( 0 ); +} + int CTools::ShowPoolInformation( std::vector> const & mining_pools ) { - char inet_buffer[INET_BUFFER_SIZE]; + char inet_buffer[DEFAULT_INET_BUFFER_SIZE]; char msg[200]; std::snprintf( msg, 200, "POOL INFORMATION" ); NOSO_TUI_OutputInfoPad( msg ); @@ -18,7 +41,7 @@ int CTools::ShowPoolInformation( std::vector const & pool ) mutable { CPoolInet inet { std::get<0>( pool ), std::get<1>( pool ), std::get<2>( pool ), DEFAULT_POOL_INET_TIMEOSEC }; - const int rsize { inet.RequestPoolInfo( inet_buffer, INET_BUFFER_SIZE ) }; + const int rsize { inet.RequestPoolInfo( inet_buffer, DEFAULT_INET_BUFFER_SIZE ) }; if ( rsize <= 0 ) { NOSO_LOG_DEBUG << "CUtils::ShowPoolInformation Poor connecting with pool " diff --git a/tool.hpp b/tool.hpp index 999040f..3f45e47 100644 --- a/tool.hpp +++ b/tool.hpp @@ -1,10 +1,14 @@ #ifndef __NOSO2M_TOOL_HPP__ #define __NOSO2M_TOOL_HPP__ +#ifdef _WIN32 +#define _CRT_SECURE_NO_WARNINGS +#endif #include #include class CTools { public: + static int ShowNodeInformation( std::vector> const & mining_nodes ); static int ShowPoolInformation( std::vector> const & mining_pools ); static int ShowThreadHashrates( std::vector> const & thread_hashrates ); }; diff --git a/util.cpp b/util.cpp index aee70b8..8a2712b 100644 --- a/util.cpp +++ b/util.cpp @@ -1,3 +1,6 @@ +#ifdef _WIN32 +#define _CRT_SECURE_NO_WARNINGS +#endif #include #include "util.hpp" diff --git a/util.hpp b/util.hpp index 57c569f..e0f24a9 100644 --- a/util.hpp +++ b/util.hpp @@ -1,5 +1,8 @@ #ifndef __NOSO2M_UTIL_HPP__ #define __NOSO2M_UTIL_HPP__ +#ifdef _WIN32 +#define _CRT_SECURE_NO_WARNINGS +#endif #include std::string lpad( std::string const & s, std::size_t n, char c );