/*** * @brief Read input from the user * @param prompt the prompt to display * @param line what the user typed */ void cli::getline( const std::string& prompt, std::string& line) { // getting file descriptor for C++ streams is near impossible // so we just assume it's the same as the C stream... #ifdef HAVE_EDITLINE #ifndef WIN32 if( isatty( fileno( stdin ) ) ) #else // it's implied by // https://msdn.microsoft.com/en-us/library/f4s0ddew.aspx // that this is the proper way to do this on Windows, but I have // no access to a Windows compiler and thus, // no idea if this actually works if( _isatty( _fileno( stdin ) ) ) #endif { rl_set_complete_func(my_rl_complete); rl_set_list_possib_func(cli_completion); rl_set_check_secret_func(cli_check_secret); static fc::thread getline_thread("getline"); getline_thread.async( [&](){ char* line_read = nullptr; std::cout.flush(); //readline doesn't use cin, so we must manually flush _out line_read = readline(prompt.c_str()); if( line_read == nullptr ) FC_THROW_EXCEPTION( fc::eof_exception, "" ); line = line_read; // we don't need here to add line in editline's history, cause it will be doubled free(line_read); }).wait(); } else #endif { std::cout << prompt; // sync_call( cin_thread, [&](){ std::getline( *input_stream, line ); }, "getline"); fc::getline( fc::cin, line ); return; } }
void mining_loop() { while( !_mining_loop_complete.canceled() ) { try { if( _current_block.prev == block_id_type() || !_callback || _effort < 0.01 || _prev_header.next_difficulty == 0 ) { ilog( "${current.prev} _effort ${effort} prev_header: ${prev_header}", ("current.prev",_current_block.prev)("effort",_effort)("prev_header",_prev_header) ); fc::usleep( fc::microseconds( 1000*1000 ) ); continue; } auto start = fc::time_point::now(); block_header tmp = _current_block; tmp.timestamp = fc::time_point::now(); auto next_diff = _prev_header.next_difficulty * 300*1000000ll / (tmp.timestamp - _prev_header.timestamp).count(); tmp.next_difficulty = (_prev_header.next_difficulty * 24 + next_diff ) / 25; tmp.noncea = 0; tmp.nonceb = 0; auto tmp_id = tmp.id(); auto seed = fc::sha256::hash( (char*)&tmp_id, sizeof(tmp_id) ); auto pairs = momentum_search( seed ); for( auto collision : pairs ) { tmp.noncea = collision.first; tmp.nonceb = collision.second; FC_ASSERT( _min_votes > 0 ); FC_ASSERT( _prev_header.next_difficulty > 0 ); ilog( "difficlty ${d} target ${t} tmp.get_difficulty ${dd} mv ${mv} min: ${min} block:\n${block}", ("min",_min_votes)("mv",_miner_votes)("dd",tmp.get_difficulty()) ("d",(tmp.get_difficulty() * _miner_votes)/_min_votes)("t",_prev_header.next_difficulty)("block",_current_block) ); if( (tmp.get_difficulty() * _miner_votes)/_min_votes >= _prev_header.next_difficulty ) { if( _callback ) { auto cb = _callback; _main_thread->async( [cb,tmp](){cb( tmp );} ); } _effort = 0; break; } } // search space... auto end = fc::time_point::now(); // wait while checking for cancel... if( _effort < 1.0 ) { auto calc_time = (end-start).count(); auto wait_time = ((1-_effort)/_effort) * calc_time; auto wait_until = end + fc::microseconds(wait_time); if( wait_until > fc::time_point::now() && !_mining_loop_complete.canceled() ) { ilog( "." ); fc::usleep( fc::microseconds( 1000*100 ) ); } } else { ilog( "." ); fc::usleep( fc::microseconds(1000*10) ); } } catch ( const fc::exception& e ) { wlog( "${e}", ("e",e.to_detail_string() )); } } // while } /// mining_loop