Permalink
700407b Jun 4, 2017
3073 lines (2696 sloc) 106 KB
#include "miner.h"
// Initialize static member data
const InstructionSet::InstructionSet_Internal InstructionSet::CPU_Rep;
void Log_init(void)
{
if (use_log)
{
std::stringstream ss;
if (CreateDirectory(L"Logs", nullptr) == ERROR_PATH_NOT_FOUND)
{
wattron(win_main, COLOR_PAIR(12));
wprintw(win_main, "CreateDirectory failed (%d)\n", GetLastError(), 0);
wattroff(win_main, COLOR_PAIR(12));
use_log = false;
return;
}
GetLocalTime(&cur_time);
//sprintf_s(filename, MAX_PATH, "Logs\\%02d-%02d-%02d_%02d_%02d_%02d.log", cur_time.wYear, cur_time.wMonth, cur_time.wDay, cur_time.wHour, cur_time.wMinute, cur_time.wSecond);
ss << "Logs\\" << cur_time.wYear << "-" << cur_time.wMonth << "-" << cur_time.wDay << "_" << cur_time.wHour << "_" << cur_time.wMinute << "_" << cur_time.wSecond << ".log";
std::string filename = ss.str();
if (fopen_s(&fp_Log, filename.c_str(), "wt") != 0)
{
wattron(win_main, COLOR_PAIR(12));
wprintw(win_main, "LOG: file openinig error\n", 0);
wattroff(win_main, COLOR_PAIR(12));
use_log = false;
}
}
}
void Log(char const *const strLog)
{
if (use_log && fp_Log)
{
// если строка содержит интер, то добавить время
if (strLog[0] == '\n')
{
GetLocalTime(&cur_time);
fprintf_s(fp_Log, "\n%02d:%02d:%02d %s", cur_time.wHour, cur_time.wMinute, cur_time.wSecond, strLog + 1);
}
else fprintf_s(fp_Log, "%s", strLog);
fflush(fp_Log);
}
}
void Log_server(char const *const strLog)
{
size_t len_str = strlen(strLog);
if ((len_str> 0) && use_log && fp_Log)
{
char * Msg_log = (char*)HeapAlloc(hHeap, HEAP_ZERO_MEMORY, len_str * 2 + 1);
if (Msg_log == nullptr) ShowMemErrorExit();
for (size_t i = 0, j = 0; i<len_str; i++, j++)
{
if(strLog[i] == '\r')
{
Msg_log[j] = '\\';
j++;
Msg_log[j] = 'r';}
else
if(strLog[i] == '\n')
{
Msg_log[j] = '\\';
j++;
Msg_log[j] = 'n';
}
else
if (strLog[i] == '%')
{
Msg_log[j] = '%';
j++;
Msg_log[j] = '%';
}
else Msg_log[j] = strLog[i];
}
fprintf_s(fp_Log, "%s", Msg_log);
fflush(fp_Log);
HeapFree(hHeap, 0, Msg_log);
}
}
void Log_llu(unsigned long long const llu_num)
{
if (use_log && fp_Log)
{
fprintf_s(fp_Log, "%llu", llu_num);
fflush(fp_Log);
}
}
void Log_u(size_t const u_num)
{
if (use_log && fp_Log)
{
fprintf_s(fp_Log, "%u", (unsigned)u_num);
fflush(fp_Log);
}
}
void ShowMemErrorExit(void)
{
Log("\n!!! Error allocating memory");
wattron(win_main, COLOR_PAIR(12));
wprintw(win_main, "\nError allocating memory\n", 0);
wattroff(win_main, COLOR_PAIR(12));
wrefresh(win_main);
system("pause");
exit(-1);
}
int load_config(char const *const filename)
{
FILE * pFile;
fopen_s(&pFile, filename, "rt");
if (pFile == nullptr)
{
fprintf(stderr, "\nError. file %s not found\n", filename);
system("pause");
exit(-1);
}
_fseeki64(pFile, 0, SEEK_END);
__int64 const size = _ftelli64(pFile);
_fseeki64(pFile, 0, SEEK_SET);
char *json_ = (char*)HeapAlloc(hHeap, HEAP_ZERO_MEMORY, size + 1);
if (json_ == nullptr)
{
fprintf(stderr, "\nError allocating memory\n");
system("pause");
exit(-1);
}
fread_s(json_, size, 1, size - 1, pFile);
fclose(pFile);
Document document; // Default template parameter uses UTF8 and MemoryPoolAllocator.
if (document.Parse<0>(json_).HasParseError()){
fprintf(stderr, "\nJSON format error (offset %u) check miner.conf\n%s\n", (unsigned)document.GetErrorOffset(), GetParseError_En(document.GetParseError())); //(offset %s %s", (unsigned)document.GetErrorOffset(), (char*)document.GetParseError());
system("pause");
exit(-1);
}
if(document.IsObject())
{ // Document is a JSON value represents the root of DOM. Root can be either an object or array.
if (document.HasMember("UseLog") && (document["UseLog"].IsBool())) use_log = document["UseLog"].GetBool();
Log_init();
if(document.HasMember("Mode") && document["Mode"].IsString())
{
Log("\nMode: ");
if(strcmp(document["Mode"].GetString(), "solo") == 0) miner_mode = 0;
else
if(strcmp(document["Mode"].GetString(), "pool") == 0) miner_mode = 1;
else
if (strcmp(document["Mode"].GetString(), "poolV2") == 0) miner_mode = 2;
Log_u(miner_mode);
}
Log("\nServer: ");
if (document.HasMember("Server") && document["Server"].IsString()) nodeaddr = document["Server"].GetString();//strcpy_s(nodeaddr, document["Server"].GetString());
Log(nodeaddr.c_str());
Log("\nPort: ");
if (document.HasMember("Port"))
{
if (document["Port"].IsString()) nodeport = document["Port"].GetString();
else if (document["Port"].IsUint()) nodeport = std::to_string(document["Port"].GetUint()); //_itoa_s(document["Port"].GetUint(), nodeport, INET_ADDRSTRLEN-1, 10);
Log(nodeport.c_str());
}
if(document.HasMember("Paths") && document["Paths"].IsArray()){
const Value& Paths = document["Paths"]; // Using a reference for consecutive access is handy and faster.
for (SizeType i = 0; i < Paths.Size(); i++)
{
Log("\nPath: ");
paths_dir.push_back(Paths[i].GetString());
Log((char*)paths_dir[i].c_str());
}
}
Log("\nCacheSize: ");
if(document.HasMember("CacheSize") && (document["CacheSize"].IsUint64())) cache_size = document["CacheSize"].GetUint64();
Log_u(cache_size);
Log("\nUseHDDWakeUp: ");
if(document.HasMember("UseHDDWakeUp") && (document["UseHDDWakeUp"].IsBool())) use_wakeup = document["UseHDDWakeUp"].GetBool();
Log_u(use_wakeup);
Log("\nShowMsg: ");
if(document.HasMember("ShowMsg") && (document["ShowMsg"].IsBool())) show_msg = document["ShowMsg"].GetBool();
Log_u(show_msg);
Log("\nShowUpdates: ");
if(document.HasMember("ShowUpdates") && (document["ShowUpdates"].IsBool())) show_updates = document["ShowUpdates"].GetBool();
Log_u(show_updates);
Log("\nSendInterval: ");
if(document.HasMember("SendInterval") && (document["SendInterval"].IsUint())) send_interval = (size_t)document["SendInterval"].GetUint();
Log_u(send_interval);
Log("\nUpdateInterval: ");
if(document.HasMember("UpdateInterval") && (document["UpdateInterval"].IsUint())) update_interval = (size_t)document["UpdateInterval"].GetUint();
Log_u(update_interval);
Log("\nUseFastRcv: ");
if(document.HasMember("UseFastRcv") && (document["UseFastRcv"].IsBool())) use_fast_rcv = document["UseFastRcv"].GetBool();
Log_u(use_fast_rcv);
Log("\nDebug: ");
if(document.HasMember("Debug") && (document["Debug"].IsBool())) use_debug = document["Debug"].GetBool();
Log_u(use_debug);
Log("\nUpdater address: ");
if (document.HasMember("UpdaterAddr") && document["UpdaterAddr"].IsString()) updateraddr =document["UpdaterAddr"].GetString(); //strcpy_s(updateraddr, document["UpdaterAddr"].GetString());
Log(updateraddr.c_str());
Log("\nUpdater port: ");
if (document.HasMember("UpdaterPort"))
{
if (document["UpdaterPort"].IsString()) updaterport = document["UpdaterPort"].GetString();
else if (document["UpdaterPort"].IsUint()) updaterport = std::to_string(document["UpdaterPort"].GetUint());
}
Log(updaterport.c_str());
Log("\nInfo address: ");
if (document.HasMember("InfoAddr") && document["InfoAddr"].IsString()) infoaddr = document["InfoAddr"].GetString();
else infoaddr = updateraddr;
Log(infoaddr.c_str());
Log("\nInfo port: ");
if (document.HasMember("InfoPort"))
{
if (document["InfoPort"].IsString()) infoport = document["InfoPort"].GetString();
else if (document["InfoPort"].IsUint()) infoport = std::to_string(document["InfoPort"].GetUint());
}
else infoport = updaterport;
Log(infoport.c_str());
Log("\nEnableProxy: ");
if (document.HasMember("EnableProxy") && (document["EnableProxy"].IsBool())) enable_proxy = document["EnableProxy"].GetBool();
Log_u(enable_proxy);
Log("\nProxyPort: ");
if (document.HasMember("ProxyPort"))
{
if (document["ProxyPort"].IsString()) proxyport = document["ProxyPort"].GetString();
else if (document["ProxyPort"].IsUint()) proxyport = std::to_string(document["ProxyPort"].GetUint());
}
Log(proxyport.c_str());
Log("\nShowWinner: ");
if (document.HasMember("ShowWinner") && (document["ShowWinner"].IsBool())) show_winner = document["ShowWinner"].GetBool();
Log_u(show_winner);
Log("\nSendBestOnly: ");
if (document.HasMember("SendBestOnly") && (document["SendBestOnly"].IsBool())) send_best_only = document["SendBestOnly"].GetBool();
Log_u(send_best_only);
Log("\nTargetDeadline: ");
if (document.HasMember("TargetDeadline") && (document["TargetDeadline"].IsInt64())) my_target_deadline = document["TargetDeadline"].GetUint64();
Log_llu(my_target_deadline);
Log("\nUseBoost: ");
if (document.HasMember("UseBoost") && (document["UseBoost"].IsBool())) use_boost = document["UseBoost"].GetBool();
Log_u(use_boost);
Log("\nWinSizeX: ");
if(document.HasMember("WinSizeX") && (document["WinSizeX"].IsUint())) win_size_x = (short)document["WinSizeX"].GetUint();
Log_u(win_size_x);
Log("\nWinSizeY: ");
if(document.HasMember("WinSizeY") && (document["WinSizeY"].IsUint())) win_size_y = (short)document["WinSizeY"].GetUint();
Log_u(win_size_y);
#ifdef GPU_ON_C
Log("\nGPU_Platform: ");
if (document.HasMember("GPU_Platform") && (document["GPU_Platform"].IsInt())) gpu_devices.use_gpu_platform = (size_t)document["GPU_Platform"].GetUint();
Log_llu(gpu_devices.use_gpu_platform);
Log("\nGPU_Device: ");
if (document.HasMember("GPU_Device") && (document["GPU_Device"].IsInt())) gpu_devices.use_gpu_device = (size_t)document["GPU_Device"].GetUint();
Log_llu(gpu_devices.use_gpu_device);
#endif
}
Log("\n=== Config loaded ===");
HeapFree(hHeap, 0, json_);
return 1;
}
/*
LPSTR DisplayErrorText( DWORD dwLastError )
{
#pragma warning(suppress: 6102)
HMODULE hModule = nullptr; // default to system source
LPSTR MessageBuffer = nullptr;
DWORD dwBufferLength;
DWORD dwFormatFlags = FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_IGNORE_INSERTS | FORMAT_MESSAGE_FROM_SYSTEM ;
if(dwLastError >= NERR_BASE && dwLastError <= MAX_NERR)
{
hModule = LoadLibraryEx( TEXT("netmsg.dll"), nullptr, LOAD_LIBRARY_AS_DATAFILE );
if(hModule != nullptr) dwFormatFlags |= FORMAT_MESSAGE_FROM_HMODULE;
}
dwBufferLength = FormatMessageA(dwFormatFlags, hModule, dwLastError, MAKELANGID(LANG_SYSTEM_DEFAULT, SUBLANG_SYS_DEFAULT), (LPSTR)&MessageBuffer, 0, nullptr);
if(hModule != nullptr) FreeLibrary(hModule);
return MessageBuffer;
}
*/
// Helper routines taken from http://stackoverflow.com/questions/1557400/hex-to-char-array-in-c
int xdigit( char const digit ){
int val;
if( '0' <= digit && digit <= '9' ) val = digit -'0';
else if( 'a' <= digit && digit <= 'f' ) val = digit -'a'+10;
else if( 'A' <= digit && digit <= 'F' ) val = digit -'A'+10;
else val = -1;
return val;
}
size_t xstr2strr(char *buf, size_t const bufsize, const char *const in) {
if( !in ) return 0; // missing input string
size_t inlen = (size_t)strlen(in);
if( inlen%2 != 0 ) inlen--; // hex string must even sized
size_t i,j;
for(i=0; i<inlen; i++ )
if( xdigit(in[i])<0 ) return 0; // bad character in hex string
if( !buf || bufsize<inlen/2+1 ) return 0; // no buffer or too small
for(i=0,j=0; i<inlen; i+=2,j++ )
buf[j] = xdigit(in[i])*16 + xdigit(in[i+1]);
buf[inlen/2] = '\0';
return inlen/2+1;
}
/*
std::wstring str2wstr(std::string &s)
{
int slen = (int)s.length() + 1;
size_t len = MultiByteToWideChar(CP_ACP, 0, s.c_str(), slen, 0, 0);
wchar_t *buf = new wchar_t[len];
MultiByteToWideChar(CP_ACP, 0, s.c_str(), slen, buf, (int)len);
std::wstring r(buf);
delete[] buf;
return r;
}
*/
void GetPass(char const *const p_strFolderPath)
{
FILE * pFile;
unsigned char * buffer;
size_t len_pass;
char * filename = (char*)HeapAlloc(hHeap, HEAP_ZERO_MEMORY, MAX_PATH);
if (filename == nullptr) ShowMemErrorExit();
sprintf_s(filename, MAX_PATH, "%s%s", p_strFolderPath, "passphrases.txt");
// printf_s("\npass from: %s\n",filename);
fopen_s(&pFile, filename, "rt");
if (pFile==nullptr)
{
wattron(win_main, COLOR_PAIR(12));
wprintw(win_main, "passphrases.txt not found\n", 0);
wattroff(win_main, COLOR_PAIR(12));
system("pause");
exit (-1);
}
HeapFree(hHeap, 0, filename);
_fseeki64(pFile , 0 , SEEK_END);
size_t const lSize = _ftelli64(pFile);
_fseeki64(pFile, 0, SEEK_SET);
buffer = (unsigned char*)HeapAlloc(hHeap, HEAP_ZERO_MEMORY, lSize + 1);
if (buffer == nullptr) ShowMemErrorExit();
len_pass = fread(buffer, 1, lSize, pFile);
fclose(pFile);
pass = (char*)HeapAlloc(hHeap, HEAP_ZERO_MEMORY, lSize * 3);
if (pass == nullptr) ShowMemErrorExit();
for(size_t i=0, j=0; i<len_pass; i++, j++)
{
if ((buffer[i] == '\n') || (buffer[i] == '\r') || (buffer[i] == '\t')) j--; // Пропускаем символы, переделать buffer[i] < 20
else
if (buffer[i] == ' ') pass[j] = '+';
else
if (isalnum(buffer[i]) == 0)
{
sprintf_s(pass + j, lSize * 3, "%%%x", (unsigned char)buffer[i]);
j = j+2;
}
else memcpy(&pass[j],&buffer[i],1);
}
//printf_s("\n%s\n",pass);
HeapFree(hHeap, 0, buffer);
}
size_t GetFiles(const std::string &str, std::vector <t_files> *p_files)
{
HANDLE hFile = INVALID_HANDLE_VALUE;
WIN32_FIND_DATAA FindFileData;
size_t count = 0;
std::vector<std::string> path;
size_t first = 0;
size_t last = 0;
do{
last = str.find("+", first);
if (last == -1) last = str.length();
std::string str2(str.substr(first, last - first));
if (str2.rfind("\\") < str2.length() - 1) str2 = str2 + "\\";
path.push_back(str2);
first = last + 1;
} while (last != str.length());
for (auto iter = path.begin(); iter != path.end(); ++iter)
{
hFile = FindFirstFileA(LPCSTR((*iter + "*").c_str()), &FindFileData);
if (INVALID_HANDLE_VALUE != hFile)
{
do
{
if (FILE_ATTRIBUTE_DIRECTORY & FindFileData.dwFileAttributes) continue; //Skip directories
char* ekey = strstr(FindFileData.cFileName, "_");
if (ekey != nullptr)
{
char* estart = strstr(ekey + 1, "_");
if (estart != nullptr)
{
char* enonces = strstr(estart + 1, "_");
if (enonces != nullptr)
{
unsigned long long key, nonce, nonces, stagger;
if (sscanf_s(FindFileData.cFileName, "%llu_%llu_%llu_%llu", &key, &nonce, &nonces, &stagger) == 4)
{
p_files->push_back({
*iter,
FindFileData.cFileName,
(((static_cast<ULONGLONG>(FindFileData.nFileSizeHigh) << (sizeof(FindFileData.nFileSizeLow) * 8)) | FindFileData.nFileSizeLow)),
key, nonce, nonces, stagger
});
count++;
}
}
}
}
} while (FindNextFileA(hFile, &FindFileData));
FindClose(hFile);
}
}
return count;
}
size_t Get_index_acc(unsigned long long const key)
{
EnterCriticalSection(&bestsLock);
size_t acc_index = 0;
for (auto it = bests.begin(); it != bests.end(); ++it)
{
if (it->account_id == key)
{
LeaveCriticalSection(&bestsLock);
return acc_index;
}
acc_index++;
}
bests.push_back({key, 0, 0, 0, targetDeadlineInfo});
LeaveCriticalSection(&bestsLock);
return bests.size() - 1;
}
/*
void gen_nonce(unsigned long long addr, unsigned long long start_nonce, unsigned long long count) {
#define PLOT_SIZE (4096 * 64)
#define HASH_SIZE 32
#define HASH_CAP 4096
char * final = (char *)calloc(32, 1);
char * gendata = (char *)calloc(16 + PLOT_SIZE, 1);
char * cache = (char *)calloc(64 * count, 1);
char *xv = (char*)&addr;
sph_shabal_context x;
size_t i;
size_t len;
//gendata[PLOT_SIZE] = xv[7]; gendata[PLOT_SIZE+1] = xv[6]; gendata[PLOT_SIZE+2] = xv[5]; gendata[PLOT_SIZE+3] = xv[4];
//gendata[PLOT_SIZE+4] = xv[3]; gendata[PLOT_SIZE+5] = xv[2]; gendata[PLOT_SIZE+6] = xv[1]; gendata[PLOT_SIZE+7] = xv[0];
for (size_t i = 0; i < 8; i++) gendata[PLOT_SIZE+i] = xv[7-i];
for (unsigned long long z = start_nonce; z < (start_nonce + count); z++) {
xv = (char*)&z;
//gendata[PLOT_SIZE + 8] = xv[7]; gendata[PLOT_SIZE + 9] = xv[6]; gendata[PLOT_SIZE + 10] = xv[5]; gendata[PLOT_SIZE + 11] = xv[4];
//gendata[PLOT_SIZE + 12] = xv[3]; gendata[PLOT_SIZE + 13] = xv[2]; gendata[PLOT_SIZE + 14] = xv[1]; gendata[PLOT_SIZE + 15] = xv[0];
for (i = 8; i < 16; i++) gendata[PLOT_SIZE + i] = xv[15 - i];
for (i = PLOT_SIZE; i > 0; i -= HASH_SIZE) {
sph_shabal256_init(&x);
len = PLOT_SIZE + 16 - i;
if (len > HASH_CAP) len = HASH_CAP;
sph_shabal256(&x, (const unsigned char*)&gendata[i], len);
sph_shabal256_close(&x, &gendata[i - HASH_SIZE]);
}
sph_shabal256_init(&x);
sph_shabal256(&x, (const unsigned char*)gendata, 16 + PLOT_SIZE);
sph_shabal256_close(&x, final);
// XOR with final
//for(i = 0; i < PLOT_SIZE; i ++) gendata[i] ^= (final[i % HASH_SIZE]);
//for (i = scoop * 64; i < ((scoop + 1) * 64); i++) gendata[i] ^= (final[i % HASH_SIZE]);
gendata[scoop * 64] ^= (final[(scoop * 64) % HASH_SIZE]);
memmove(&cache[(z - start_nonce) * 64], &gendata[scoop * 64], 64);
}
free(final);
free(gendata);
//acc = Get_index_acc(key);
//procscoop_sph(n, size, cache, 0, std::string("generator"));
procscoop_m_4(start_nonce, count, cache, 0, std::string("generator"));
}
void generator_i(size_t number)
{
unsigned long long start_nonce = 100000000 * (number + 1);// * (local_num + 1);
unsigned long long size = 400;
clock_t start_work_time;
//wprintw(win_main, "\ngenerator RUNING !");
while (!stopThreads)
{
start_work_time = clock();
gen_nonce(bests[0].account_id, start_nonce, size);
wprintw(win_main, "\n%llu\tnoces/min: %f", start_nonce, (float)((float)size * CLOCKS_PER_SEC * 60 / (float)(clock() - start_work_time)));
//wrefresh(win_main);
start_nonce = start_nonce + size;
};
return;
}
*/
void proxy_i(void)
{
int iResult;
size_t const buffer_size = 1000;
char* buffer = (char*)HeapAlloc(hHeap, HEAP_ZERO_MEMORY, buffer_size);
if (buffer == nullptr) ShowMemErrorExit();
char* tmp_buffer = (char*)HeapAlloc(hHeap, HEAP_ZERO_MEMORY, buffer_size);
if (tmp_buffer == nullptr) ShowMemErrorExit();
char tbuffer[9];
SOCKET ServerSocket = INVALID_SOCKET;
SOCKET ClientSocket = INVALID_SOCKET;
struct addrinfo *result = nullptr;
struct addrinfo hints;
RtlSecureZeroMemory(&hints, sizeof(hints));
hints.ai_family = AF_INET;
hints.ai_socktype = SOCK_STREAM;
hints.ai_protocol = IPPROTO_TCP;
hints.ai_flags = AI_PASSIVE;
iResult = getaddrinfo(nullptr, proxyport.c_str(), &hints, &result);
if (iResult != 0) {
wattron(win_main, COLOR_PAIR(12));
wprintw(win_main, "PROXY: getaddrinfo failed with error: %d\n", iResult, 0);
wattroff(win_main, COLOR_PAIR(12));
}
ServerSocket = socket(result->ai_family, result->ai_socktype, result->ai_protocol);
if (ServerSocket == INVALID_SOCKET) {
wattron(win_main, COLOR_PAIR(12));
wprintw(win_main, "PROXY: socket failed with error: %ld\n", WSAGetLastError(), 0);
wattroff(win_main, COLOR_PAIR(12));
freeaddrinfo(result);
}
iResult = bind(ServerSocket, result->ai_addr, (int)result->ai_addrlen);
if (iResult == SOCKET_ERROR) {
wattron(win_main, COLOR_PAIR(12));
wprintw(win_main, "PROXY: bind failed with error: %d\n", WSAGetLastError(), 0);
wattroff(win_main, COLOR_PAIR(12));
freeaddrinfo(result);
closesocket(ServerSocket);
}
freeaddrinfo(result);
BOOL l = TRUE;
iResult = ioctlsocket(ServerSocket, FIONBIO, (unsigned long*)&l);
if (iResult == SOCKET_ERROR)
{
Log("\nProxy: ! Error ioctlsocket's: "); Log_u(WSAGetLastError());
wattron(win_main, COLOR_PAIR(12));
wprintw(win_main, "PROXY: ioctlsocket failed: %ld\n", WSAGetLastError(), 0);
wattroff(win_main, COLOR_PAIR(12));
}
iResult = listen(ServerSocket, 8);
if (iResult == SOCKET_ERROR) {
wattron(win_main, COLOR_PAIR(12));
wprintw(win_main, "PROXY: listen failed with error: %d\n", WSAGetLastError(), 0);
wattroff(win_main, COLOR_PAIR(12));
closesocket(ServerSocket);
}
Log("\nProxy thread started");
for (; !exit_flag;)
{
struct sockaddr_in client_socket_address;
int iAddrSize = sizeof(struct sockaddr_in);
ClientSocket = accept(ServerSocket, (struct sockaddr *)&client_socket_address, (socklen_t*)&iAddrSize);
char client_address_str[INET_ADDRSTRLEN];
inet_ntop(hints.ai_family, &(client_socket_address.sin_addr), client_address_str, INET_ADDRSTRLEN);
if (ClientSocket == INVALID_SOCKET)
{
if (WSAGetLastError() != WSAEWOULDBLOCK)
{
Log("\nProxy:! Error Proxy's accept: "); Log_u(WSAGetLastError());
wattron(win_main, COLOR_PAIR(12));
wprintw(win_main, "PROXY: can't accept. Error: %ld\n", WSAGetLastError(), 0);
wattroff(win_main, COLOR_PAIR(12));
}
}
else
{
RtlSecureZeroMemory(buffer, buffer_size);
do{
RtlSecureZeroMemory(tmp_buffer, buffer_size);
iResult = recv(ClientSocket, tmp_buffer, (int)(buffer_size - 1), 0);
strcat_s(buffer, buffer_size, tmp_buffer);
} while ((iResult > 0) && !use_fast_rcv);
Log("\nProxy get info: "); Log_server(buffer);
unsigned long long get_accountId = 0;
unsigned long long get_nonce = 0;
unsigned long long get_deadline = 0;
unsigned long long get_totalsize = 0;
// locate HTTP header
char *find = strstr(buffer, "\r\n\r\n");
if (find != nullptr)
{
if (strstr(buffer, "submitNonce") != nullptr)
{
char *startaccountId = strstr(buffer, "accountId=");
if (startaccountId != nullptr)
{
startaccountId = strpbrk(startaccountId, "0123456789");
char *endaccountId = strpbrk(startaccountId, "& }\"");
char *startnonce = strstr(buffer, "nonce=");
char *startdl = strstr(buffer, "deadline=");
char *starttotalsize = strstr(buffer, "X-Capacity");
if ((startnonce != nullptr) && (startdl != nullptr))
{
startnonce = strpbrk(startnonce, "0123456789");
char *endnonce = strpbrk(startnonce, "& }\"");
startdl = strpbrk(startdl, "0123456789");
char *enddl = strpbrk(startdl, "& }\"");
endaccountId[0] = 0;
endnonce[0] = 0;
enddl[0] = 0;
get_accountId = _strtoui64(startaccountId, 0, 10);
get_nonce = _strtoui64(startnonce, 0, 10);
get_deadline = _strtoui64(startdl, 0, 10);
if (starttotalsize != nullptr)
{
starttotalsize = strpbrk(starttotalsize, "0123456789");
char *endtotalsize = strpbrk(starttotalsize, "& }\"");
endtotalsize[0] = 0;
get_totalsize = _strtoui64(starttotalsize, 0, 10);
satellite_size.insert(std::pair <u_long, unsigned long long>(client_socket_address.sin_addr.S_un.S_addr, get_totalsize));
}
EnterCriticalSection(&sharesLock);
shares.push_back({ client_address_str, get_accountId, get_deadline, get_nonce });
LeaveCriticalSection(&sharesLock);
_strtime_s(tbuffer);
wattron(win_main, COLOR_PAIR(2));
wprintw(win_main, "%s [%20llu]\treceived DL: %11llu {%s}\n", tbuffer, get_accountId, get_deadline / baseTarget, client_address_str, 0);
wattroff(win_main, COLOR_PAIR(2));
Log("Proxy: received DL "); Log_llu(get_deadline); Log(" from "); Log(client_address_str);
//Подтверждаем
RtlSecureZeroMemory(buffer, buffer_size);
size_t acc = Get_index_acc(get_accountId);
int bytes = sprintf_s(buffer, buffer_size, "HTTP/1.0 200 OK\r\nConnection: close\r\n\r\n{\"result\": \"proxy\",\"accountId\": %llu,\"deadline\": %llu,\"targetDeadline\": %llu}", get_accountId, get_deadline / baseTarget, bests[acc].targetDeadline);
iResult = send(ClientSocket, buffer, bytes, 0);
if (iResult == SOCKET_ERROR)
{
Log("\nProxy: ! Error sending to client: "); Log_u(WSAGetLastError());
wattron(win_main, COLOR_PAIR(12));
wprintw(win_main, "PROXY: failed sending to client: %ld\n", WSAGetLastError(), 0);
wattroff(win_main, COLOR_PAIR(12));
}
else
{
if (use_debug)
{
_strtime_s(tbuffer);
wattron(win_main, COLOR_PAIR(9));
wprintw(win_main, "%s [%20llu]\tsent confirmation to %s\n", tbuffer, get_accountId, client_address_str, 0);
wattroff(win_main, COLOR_PAIR(9));
}
Log("\nProxy: sent confirmation to "); Log(client_address_str);
}
}
}
}
else
{
if (strstr(buffer, "getMiningInfo") != nullptr)
{
RtlSecureZeroMemory(buffer, buffer_size);
int bytes = sprintf_s(buffer, buffer_size, "HTTP/1.0 200 OK\r\nConnection: close\r\n\r\n{\"baseTarget\":\"%llu\",\"height\":\"%llu\",\"generationSignature\":\"%s\",\"targetDeadline\":%llu}", baseTarget, height, str_signature, targetDeadlineInfo);
iResult = send(ClientSocket, buffer, bytes, 0);
if (iResult == SOCKET_ERROR)
{
Log("\nProxy: ! Error sending to client: "); Log_u(WSAGetLastError());
wattron(win_main, COLOR_PAIR(12));
wprintw(win_main, "PROXY: failed sending to client: %ld\n", WSAGetLastError(), 0);
wattroff(win_main, COLOR_PAIR(12));
}
else
{
Log("\nProxy: sent update to "); Log(client_address_str);
}
}
else
{
if ((strstr(buffer, "getBlocks") != nullptr) || (strstr(buffer, "getAccount") != nullptr) || (strstr(buffer, "getRewardRecipient") != nullptr))
{
; // ничего не делаем, не ошибка, пропускаем
}
else
{
find[0] = 0;
wattron(win_main, COLOR_PAIR(15));
wprintw(win_main, "PROXY: %s\n", buffer, 0);
wattroff(win_main, COLOR_PAIR(15));
}
}
}
}
iResult = closesocket(ClientSocket);
}
std::this_thread::yield();
std::this_thread::sleep_for(std::chrono::milliseconds(200));
}
HeapFree(hHeap, 0, buffer);
HeapFree(hHeap, 0, tmp_buffer);
}
void send_i(void)
{
Log("\nSender: started thread");
SOCKET ConnectSocket;
int iResult = 0;
size_t const buffer_size = 1000;
char* buffer = (char*)HeapAlloc(hHeap, HEAP_ZERO_MEMORY, buffer_size);
if (buffer == nullptr) ShowMemErrorExit();
char tbuffer[9];
struct addrinfo *result = nullptr;
struct addrinfo hints;
for (; !exit_flag;)
{
if (stopThreads == 1)
{
HeapFree(hHeap, 0, buffer);
return;
}
for (auto iter = shares.begin(); iter != shares.end();)
{
if (send_best_only) //Гасим шару если она больше текущего targetDeadline, актуально для режима Proxy
{
if ((iter->best / baseTarget) > bests[Get_index_acc(iter->account_id)].targetDeadline)
{
if (use_debug)
{
_strtime_s(tbuffer);
wattron(win_main, COLOR_PAIR(4));
wprintw(win_main, "%s [%20llu]\t%llu > %llu discarded\n", tbuffer, iter->account_id, iter->best / baseTarget, bests[Get_index_acc(iter->account_id)].targetDeadline, 0);
wattroff(win_main, COLOR_PAIR(4));
}
EnterCriticalSection(&sharesLock);
iter = shares.erase(iter);
LeaveCriticalSection(&sharesLock);
continue;
}
}
RtlSecureZeroMemory(&hints, sizeof(hints));
hints.ai_family = AF_INET;
hints.ai_socktype = SOCK_STREAM;
hints.ai_protocol = IPPROTO_TCP;
iResult = getaddrinfo(nodeaddr.c_str(), nodeport.c_str(), &hints, &result);
if (iResult != 0) {
if (network_quality > 0) network_quality--;
wattron(win_main, COLOR_PAIR(12));
wprintw(win_main, "SENDER: getaddrinfo failed with error: %d\n", iResult, 0);
wattroff(win_main, COLOR_PAIR(12));
continue;
}
ConnectSocket = socket(result->ai_family, result->ai_socktype, result->ai_protocol);
if (ConnectSocket == INVALID_SOCKET) {
if (network_quality > 0) network_quality--;
wattron(win_main, COLOR_PAIR(12));
wprintw(win_main, "SENDER: socket failed with error: %ld\n", WSAGetLastError(), 0);
wattroff(win_main, COLOR_PAIR(12));
freeaddrinfo(result);
continue;
}
const unsigned t = 1000;
setsockopt(ConnectSocket, SOL_SOCKET, SO_RCVTIMEO, (char *)&t, sizeof(unsigned));
iResult = connect(ConnectSocket, result->ai_addr, (int)result->ai_addrlen);
if (iResult == SOCKET_ERROR)
{
if (network_quality > 0) network_quality--;
Log("\nSender:! Error Sender's connect: "); Log_u(WSAGetLastError());
wattron(win_main, COLOR_PAIR(12));
_strtime_s(tbuffer);
wprintw(win_main, "%s SENDER: can't connect. Error: %ld\n", tbuffer, WSAGetLastError(), 0);
wattroff(win_main, COLOR_PAIR(12));
freeaddrinfo(result);
continue;
}
else
{
freeaddrinfo(result);
int bytes = 0;
RtlSecureZeroMemory(buffer, buffer_size);
if (miner_mode == 0)
{
bytes = sprintf_s(buffer, buffer_size, "POST /burst?requestType=submitNonce&secretPhrase=%s&nonce=%llu HTTP/1.0\r\nConnection: close\r\n\r\n", pass, iter->nonce);
}
if (miner_mode == 1)
{
unsigned long long total = total_size / 1024 / 1024 / 1024;
for (auto It = satellite_size.begin(); It != satellite_size.end(); ++It) total = total + It->second;
bytes = sprintf_s(buffer, buffer_size, "POST /burst?requestType=submitNonce&accountId=%llu&nonce=%llu&deadline=%llu HTTP/1.0\r\nHost: %s:%s\r\nX-Miner: Blago %s\r\nX-Capacity: %llu\r\nContent-Length: 0\r\nConnection: close\r\n\r\n", iter->account_id, iter->nonce, iter->best, nodeaddr.c_str(), nodeport.c_str(), version, total, 0);
}
if (miner_mode == 2)
{
char* f1 = (char*)HeapAlloc(hHeap, HEAP_ZERO_MEMORY, MAX_PATH);
char* str_len = (char*)HeapAlloc(hHeap, HEAP_ZERO_MEMORY, MAX_PATH);
if ((f1 == nullptr) || (str_len == nullptr)) ShowMemErrorExit();
int len = sprintf_s(f1, MAX_PATH, "%llu:%llu:%llu", iter->account_id, iter->nonce, height);
_itoa_s(len, str_len, MAX_PATH - 1, 10);
bytes = sprintf_s(buffer, buffer_size, "POST /pool/submitWork HTTP/1.0\r\nHost: %s:%s\r\nContent-Type: text/plain;charset=UTF-8\r\nContent-Length: %i\r\n\r\n%s", nodeaddr.c_str(), nodeport.c_str(), len, f1);
HeapFree(hHeap, 0, f1);
HeapFree(hHeap, 0, str_len);
}
// Sending to server
iResult = send(ConnectSocket, buffer, bytes, 0);
if (iResult == SOCKET_ERROR)
{
if (network_quality > 0) network_quality--;
Log("\nSender: ! Error deadline's sending: "); Log_u(WSAGetLastError());
wattron(win_main, COLOR_PAIR(12));
wprintw(win_main, "SENDER: send failed: %ld\n", WSAGetLastError(), 0);
wattroff(win_main, COLOR_PAIR(12));
continue;
}
else
{
unsigned long long dl = iter->best / baseTarget;
_strtime_s(tbuffer);
if (network_quality < 100) network_quality++;
wattron(win_main, COLOR_PAIR(9));
wprintw(win_main, "%s [%20llu] sent DL: %15llu %5llud %02llu:%02llu:%02llu\n", tbuffer, iter->account_id, dl, (dl) / (24 * 60 * 60), (dl % (24 * 60 * 60)) / (60 * 60), (dl % (60 * 60)) / 60, dl % 60, 0);
wattroff(win_main, COLOR_PAIR(9));
if (show_msg) wprintw(win_main, "send: %s\n", buffer, 0); // показываем послание
Log("\nSender: Sent: "); Log_server(buffer);
EnterCriticalSection(&sessionsLock);
//sessions.push_back({ ConnectSocket, iter->account_id, dl, iter->best, iter->nonce });
sessions.push_back({ ConnectSocket, dl, *iter });
LeaveCriticalSection(&sessionsLock);
if (send_best_only) bests[Get_index_acc(iter->account_id)].targetDeadline = dl;
EnterCriticalSection(&sharesLock);
iter = shares.erase(iter);
LeaveCriticalSection(&sharesLock);
}
}
}
if (!sessions.empty())
{
EnterCriticalSection(&sessionsLock);
for (auto iter = sessions.begin(); iter != sessions.end() && !stopThreads;)
{
ConnectSocket = iter->Socket;
BOOL l = TRUE;
iResult = ioctlsocket(ConnectSocket, FIONBIO, (unsigned long*)&l);
if (iResult == SOCKET_ERROR)
{
if (network_quality > 0) network_quality--;
Log("\nSender: ! Error ioctlsocket's: "); Log_u(WSAGetLastError());
wattron(win_main, COLOR_PAIR(12));
wprintw(win_main, "SENDER: ioctlsocket failed: %ld\n", WSAGetLastError(), 0);
wattroff(win_main, COLOR_PAIR(12));
continue;
}
RtlSecureZeroMemory(buffer, buffer_size);
size_t pos = 0;
iResult = 0;
do{
iResult = recv(ConnectSocket, &buffer[pos], (int)(buffer_size - pos - 1), 0);
if (iResult > 0) pos += (size_t)iResult;
} while ((iResult > 0) && !use_fast_rcv);
if (iResult == SOCKET_ERROR)
{
if (WSAGetLastError() != WSAEWOULDBLOCK) //разрыв соединения, молча переотправляем дедлайн
{
if (network_quality > 0) network_quality--;
//wattron(win_main, COLOR_PAIR(6));
//wprintw(win_main, "%s [%20llu] not confirmed DL %10llu\n", tbuffer, iter->body.account_id, iter->deadline, 0);
//wattroff(win_main, COLOR_PAIR(6));
Log("\nSender: ! Error getting confirmation for DL: "); Log_llu(iter->deadline); Log(" code: "); Log_u(WSAGetLastError());
iter = sessions.erase(iter);
shares.push_back({ iter->body.file_name, iter->body.account_id, iter->body.best, iter->body.nonce });
}
}
else //что-то получили от сервера
{
if (show_msg) wprintw(win_main, "\nReceived: %s\n", buffer, 0);
Log("\nSender: Received: "); Log_server(buffer);
if (network_quality < 100) network_quality++;
//получили пустую строку, переотправляем дедлайн
if (buffer[0] == '\0')
{
Log("\nSender: zero-length message for DL: "); Log_llu(iter->deadline);
shares.push_back({ iter->body.file_name, iter->body.account_id, iter->body.best, iter->body.nonce });
}
else //получили ответ пула
{
char *find = strstr(buffer, "{");
if (find == nullptr)
{
find = strstr(buffer, "\r\n\r\n");
if (find != nullptr) find = find + 4;
else find = buffer;
}
unsigned long long ndeadline;
unsigned long long naccountId = 0;
unsigned long long ntargetDeadline = 0;
rapidjson::Document answ;
// burst.ninja {"requestProcessingTime":0,"result":"success","block":216280,"deadline":304917,"deadlineString":"3 days, 12 hours, 41 mins, 57 secs","targetDeadline":304917}
// pool.burst-team.us {"requestProcessingTime":0,"result":"success","block":227289,"deadline":867302,"deadlineString":"10 days, 55 mins, 2 secs","targetDeadline":867302}
// proxy {"result": "proxy","accountId": 17930413153828766298,"deadline": 1192922,"targetDeadline": 197503}
if (!answ.Parse<0>(find).HasParseError())
{
if (answ.IsObject())
{
if (answ.HasMember("deadline")) {
if (answ["deadline"].IsString()) ndeadline = _strtoui64(answ["deadline"].GetString(), 0, 10);
else
if (answ["deadline"].IsInt64()) ndeadline = answ["deadline"].GetInt64();
Log("\nSender: confirmed deadline: "); Log_llu(ndeadline);
if (answ.HasMember("targetDeadline")) {
if (answ["targetDeadline"].IsString()) ntargetDeadline = _strtoui64(answ["targetDeadline"].GetString(), 0, 10);
else
if (answ["targetDeadline"].IsInt64()) ntargetDeadline = answ["targetDeadline"].GetInt64();
}
if (answ.HasMember("accountId")) {
if (answ["accountId"].IsString()) naccountId = _strtoui64(answ["accountId"].GetString(), 0, 10);
else
if (answ["accountId"].IsInt64()) naccountId = answ["accountId"].GetInt64();
}
unsigned long long days = (ndeadline) / (24 * 60 * 60);
unsigned hours = (ndeadline % (24 * 60 * 60)) / (60 * 60);
unsigned min = (ndeadline % (60 * 60)) / 60;
unsigned sec = ndeadline % 60;
_strtime_s(tbuffer);
wattron(win_main, COLOR_PAIR(10));
if ((naccountId != 0) && (ntargetDeadline != 0))
{
EnterCriticalSection(&bestsLock);
bests[Get_index_acc(naccountId)].targetDeadline = ntargetDeadline;
LeaveCriticalSection(&bestsLock);
wprintw(win_main, "%s [%20llu] confirmed DL: %10llu %5llud %02u:%02u:%02u\n", tbuffer, naccountId, ndeadline, days, hours, min, sec, 0);
if (use_debug) wprintw(win_main, "%s [%20llu] set targetDL: %10llu\n", tbuffer, naccountId, ntargetDeadline, 0);
}
else wprintw(win_main, "%s [%20llu] confirmed DL: %10llu %5llud %02u:%02u:%02u\n", tbuffer, iter->body.account_id, ndeadline, days, hours, min, sec, 0);
wattroff(win_main, COLOR_PAIR(10));
if (ndeadline < deadline || deadline == 0) deadline = ndeadline;
if (ndeadline != iter->deadline)
{
wattron(win_main, COLOR_PAIR(6));
wprintw(win_main, "----Fast block or corrupted file?----\nSent deadline:\t%llu\nServer's deadline:\t%llu \n----\n", iter->deadline, ndeadline, 0); //shares[i].file_name.c_str());
wattroff(win_main, COLOR_PAIR(6));
}
}
else{
if (answ.HasMember("errorDescription")) {
wattron(win_main, COLOR_PAIR(15));
wprintw(win_main, "[ERROR %u] %s\n", answ["errorCode"].GetInt(), answ["errorDescription"].GetString(),0);
wattroff(win_main, COLOR_PAIR(15));
wattron(win_main, COLOR_PAIR(12));
if (answ["errorCode"].GetInt() == 1004) wprintw(win_main, "You need change reward assignment and wait 4 blocks (~16 minutes)\n"); //error 1004
wattroff(win_main, COLOR_PAIR(12));
}
else {
wattron(win_main, COLOR_PAIR(15));
wprintw(win_main, "%s\n", find);
wattroff(win_main, COLOR_PAIR(15));
}
}
}
}
else
{
if (strstr(find, "Received share") != nullptr)
{
_strtime_s(tbuffer);
deadline = bests[Get_index_acc(iter->body.account_id)].DL; //может лучше iter->deadline ?
// if(deadline > iter->deadline) deadline = iter->deadline;
wattron(win_main, COLOR_PAIR(10));
wprintw(win_main, "%s [%20llu] confirmed DL %10llu\n", tbuffer, iter->body.account_id, iter->deadline, 0);
wattroff(win_main, COLOR_PAIR(10));
}
else //получили нераспознанный ответ
{
int minor_version;
int status = 0;
const char *msg;
size_t msg_len;
struct phr_header headers[12];
size_t num_headers = sizeof(headers) / sizeof(headers[0]);
phr_parse_response(buffer, strlen(buffer), &minor_version, &status, &msg, &msg_len, headers, &num_headers, 0);
if (status != 0)
{
wattron(win_main, COLOR_PAIR(6));
//wprintw(win_main, "%s [%20llu] NOT confirmed DL %10llu\n", tbuffer, iter->body.account_id, iter->deadline, 0);
std::string error_str(msg, msg_len);
wprintw(win_main, "Server error: %d %s\n", status, error_str.c_str());
wattroff(win_main, COLOR_PAIR(6));
Log("\nSender: server error for DL: "); Log_llu(iter->deadline);
shares.push_back({ iter->body.file_name, iter->body.account_id, iter->body.best, iter->body.nonce });
}
else //получили непонятно что
{
wattron(win_main, COLOR_PAIR(7));
wprintw(win_main, "%s\n", buffer);
wattroff(win_main, COLOR_PAIR(7));
}
}
}
}
iResult = closesocket(ConnectSocket);
Log("\nSender: Close socket. Code = "); Log_u(WSAGetLastError());
iter = sessions.erase(iter);
}
if (iter != sessions.end()) ++iter;
}
LeaveCriticalSection(&sessionsLock);
}
std::this_thread::yield();
std::this_thread::sleep_for(std::chrono::milliseconds(send_interval));
}
HeapFree(hHeap, 0, buffer);
return;
}
void procscoop_m_4(unsigned long long const nonce, unsigned long long const n, char const *const data, size_t const acc, const std::string &file_name) {
char const *cache;
char sig0[32 + 64];
char sig1[32 + 64];
char sig2[32 + 64];
char sig3[32 + 64];
cache = data;
memcpy(sig0, signature, 32);
memcpy(sig1, signature, 32);
memcpy(sig2, signature, 32);
memcpy(sig3, signature, 32);
char res0[32];
char res1[32];
char res2[32];
char res3[32];
unsigned posn;
mshabal_context x;
for (unsigned long long v = 0; v < n; v += 4)
{
memcpy(&sig0[32], &cache[(v + 0) * 64], 64);
memcpy(&sig1[32], &cache[(v + 1) * 64], 64);
memcpy(&sig2[32], &cache[(v + 2) * 64], 64);
memcpy(&sig3[32], &cache[(v + 3) * 64], 64);
avx1_mshabal_init(&x, 256);
avx1_mshabal(&x, (const unsigned char*)sig0, (const unsigned char*)sig1, (const unsigned char*)sig2, (const unsigned char*)sig3, 64 + 32);
avx1_mshabal_close(&x, 0, 0, 0, 0, 0, res0, res1, res2, res3);
unsigned long long *wertung = (unsigned long long*)res0;
unsigned long long *wertung1 = (unsigned long long*)res1;
unsigned long long *wertung2 = (unsigned long long*)res2;
unsigned long long *wertung3 = (unsigned long long*)res3;
posn = 0;
if (*wertung1 < *wertung)
{
*wertung = *wertung1;
posn = 1;
}
if (*wertung2 < *wertung)
{
*wertung = *wertung2;
posn = 2;
}
if (*wertung3 < *wertung)
{
*wertung = *wertung3;
posn = 3;
}
if ((*wertung / baseTarget) <= bests[acc].targetDeadline)
{
if (send_best_only)
{
if (bests[acc].nonce == 0 || *wertung < bests[acc].best)
{
Log("\nfound deadline="); Log_llu(*wertung / baseTarget); Log(" nonce="); Log_llu(nonce + v + posn); Log(" for account: "); Log_llu(bests[acc].account_id); Log(" file: "); Log((char*)file_name.c_str());
EnterCriticalSection(&bestsLock);
bests[acc].best = *wertung;
bests[acc].nonce = nonce + v + posn;
bests[acc].DL = *wertung / baseTarget;
LeaveCriticalSection(&bestsLock);
EnterCriticalSection(&sharesLock);
shares.push_back({ file_name, bests[acc].account_id, bests[acc].best, bests[acc].nonce });
LeaveCriticalSection(&sharesLock);
if (use_debug)
{
char tbuffer[9];
_strtime_s(tbuffer);
wattron(win_main, COLOR_PAIR(2));
wprintw(win_main, "%s [%20llu] found DL: %9llu\n", tbuffer, bests[acc].account_id, bests[acc].DL, 0);
wattroff(win_main, COLOR_PAIR(2));
}
}
}
else
{
if (bests[acc].nonce == 0 || *wertung < bests[acc].best)
{
Log("\nfound deadline="); Log_llu(*wertung / baseTarget); Log(" nonce="); Log_llu(nonce + v); Log(" for account: "); Log_llu(bests[acc].account_id); Log(" file: "); Log((char*)file_name.c_str());
EnterCriticalSection(&bestsLock);
bests[acc].best = *wertung;
bests[acc].nonce = nonce + v + posn;
bests[acc].DL = *wertung / baseTarget;
LeaveCriticalSection(&bestsLock);
}
EnterCriticalSection(&sharesLock);
shares.push_back({ file_name, bests[acc].account_id, *wertung, nonce + v + posn });
LeaveCriticalSection(&sharesLock);
if (use_debug)
{
char tbuffer[9];
_strtime_s(tbuffer);
wattron(win_main, COLOR_PAIR(2));
wprintw(win_main, "%s [%20llu] found DL: %9llu\n", tbuffer, bests[acc].account_id, *wertung / baseTarget, 0);
wattroff(win_main, COLOR_PAIR(2));
}
}
}
}
}
void procscoop_m256_8(unsigned long long const nonce, unsigned long long const n, char const *const data, size_t const acc, const std::string &file_name) {
char const *cache;
char sig0[32 + 64];
char sig1[32 + 64];
char sig2[32 + 64];
char sig3[32 + 64];
char sig4[32 + 64];
char sig5[32 + 64];
char sig6[32 + 64];
char sig7[32 + 64];
cache = data;
unsigned long long v;
char tbuffer[9];
memmove(sig0, signature, 32);
memmove(sig1, signature, 32);
memmove(sig2, signature, 32);
memmove(sig3, signature, 32);
memmove(sig4, signature, 32);
memmove(sig5, signature, 32);
memmove(sig6, signature, 32);
memmove(sig7, signature, 32);
for (v = 0; v<n; v += 8) {
memmove(&sig0[32], &cache[(v + 0) * 64], 64);
memmove(&sig1[32], &cache[(v + 1) * 64], 64);
memmove(&sig2[32], &cache[(v + 2) * 64], 64);
memmove(&sig3[32], &cache[(v + 3) * 64], 64);
memmove(&sig4[32], &cache[(v + 4) * 64], 64);
memmove(&sig5[32], &cache[(v + 5) * 64], 64);
memmove(&sig6[32], &cache[(v + 6) * 64], 64);
memmove(&sig7[32], &cache[(v + 7) * 64], 64);
char res0[32];
char res1[32];
char res2[32];
char res3[32];
char res4[32];
char res5[32];
char res6[32];
char res7[32];
mshabal256_context x;
mshabal256_init(&x, 256);
mshabal256(&x, (const unsigned char*)sig0, (const unsigned char*)sig1, (const unsigned char*)sig2, (const unsigned char*)sig3, (const unsigned char*)sig4, (const unsigned char*)sig5, (const unsigned char*)sig6, (const unsigned char*)sig7, 64 + 32);
mshabal256_close(&x, 0, 0, 0, 0, 0, 0, 0, 0, 0, res0, res1, res2, res3, res4, res5, res6, res7);
unsigned long long *wertung = (unsigned long long*)res0;
unsigned long long *wertung1 = (unsigned long long*)res1;
unsigned long long *wertung2 = (unsigned long long*)res2;
unsigned long long *wertung3 = (unsigned long long*)res3;
unsigned long long *wertung4 = (unsigned long long*)res4;
unsigned long long *wertung5 = (unsigned long long*)res5;
unsigned long long *wertung6 = (unsigned long long*)res6;
unsigned long long *wertung7 = (unsigned long long*)res7;
unsigned posn = 0;
if (*wertung1 < *wertung)
{
*wertung = *wertung1;
posn = 1;
}
if (*wertung2 < *wertung)
{
*wertung = *wertung2;
posn = 2;
}
if (*wertung3 < *wertung)
{
*wertung = *wertung3;
posn = 3;
}
if (*wertung4 < *wertung)
{
*wertung = *wertung4;
posn = 4;
}
if (*wertung5 < *wertung)
{
*wertung = *wertung5;
posn = 5;
}
if (*wertung6 < *wertung)
{
*wertung = *wertung6;
posn = 6;
}
if (*wertung7 < *wertung)
{
*wertung = *wertung7;
posn = 7;
}
if ((*wertung / baseTarget) <= bests[acc].targetDeadline)
{
if (send_best_only)
{
if (bests[acc].nonce == 0 || *wertung < bests[acc].best)
{
Log("\nfound deadline="); Log_llu(*wertung / baseTarget); Log(" nonce="); Log_llu(nonce + v + posn); Log(" for account: "); Log_llu(bests[acc].account_id); Log(" file: "); Log((char*)file_name.c_str());
EnterCriticalSection(&bestsLock);
bests[acc].best = *wertung;
bests[acc].nonce = nonce + v + posn;
bests[acc].DL = *wertung / baseTarget;
LeaveCriticalSection(&bestsLock);
EnterCriticalSection(&sharesLock);
shares.push_back({ file_name, bests[acc].account_id, bests[acc].best, bests[acc].nonce });
LeaveCriticalSection(&sharesLock);
if (use_debug)
{
char tbuffer[9];
_strtime_s(tbuffer);
wattron(win_main, COLOR_PAIR(2));
wprintw(win_main, "%s [%20llu] found DL: %9llu\n", tbuffer, bests[acc].account_id, bests[acc].DL, 0);
wattroff(win_main, COLOR_PAIR(2));
}
}
}
else
{
if (bests[acc].nonce == 0 || *wertung < bests[acc].best)
{
Log("\nfound deadline="); Log_llu(*wertung / baseTarget); Log(" nonce="); Log_llu(nonce + v); Log(" for account: "); Log_llu(bests[acc].account_id); Log(" file: "); Log((char*)file_name.c_str());
EnterCriticalSection(&bestsLock);
bests[acc].best = *wertung;
bests[acc].nonce = nonce + v + posn;
bests[acc].DL = *wertung / baseTarget;
LeaveCriticalSection(&bestsLock);
}
EnterCriticalSection(&sharesLock);
shares.push_back({ file_name, bests[acc].account_id, *wertung, nonce + v + posn });
LeaveCriticalSection(&sharesLock);
if (use_debug)
{
_strtime_s(tbuffer);
wattron(win_main, COLOR_PAIR(2));
wprintw(win_main, "%s [%20llu] found DL: %9llu\n", tbuffer, bests[acc].account_id, *wertung / baseTarget, 0);
wattroff(win_main, COLOR_PAIR(2));
}
}
}
}
}
void procscoop_sph(const unsigned long long nonce, const unsigned long long n, char const *const data, const size_t acc, const std::string &file_name) {
char const *cache;
char sig[32 + 64];
cache = data;
char res[32];
memcpy_s(sig, sizeof(sig), signature, sizeof(char) * 32);
sph_shabal_context x;
for (unsigned long long v = 0; v < n; v++)
{
memcpy_s(&sig[32], sizeof(sig)-32, &cache[v * 64], sizeof(char)* 64);
sph_shabal256_init(&x);
sph_shabal256(&x, (const unsigned char*)sig, 64 + 32);
sph_shabal256_close(&x, res);
unsigned long long *wertung = (unsigned long long*)res;
if ((*wertung / baseTarget) <= bests[acc].targetDeadline)
{
if (send_best_only)
{
if (bests[acc].nonce == 0 || *wertung < bests[acc].best)
{
Log("\nfound deadline="); Log_llu(*wertung / baseTarget); Log(" nonce="); Log_llu(nonce + v); Log(" for account: "); Log_llu(bests[acc].account_id); Log(" file: "); Log((char*)file_name.c_str());
EnterCriticalSection(&bestsLock);
bests[acc].best = *wertung;
bests[acc].nonce = nonce + v;
bests[acc].DL = *wertung / baseTarget;
LeaveCriticalSection(&bestsLock);
EnterCriticalSection(&sharesLock);
shares.push_back({ file_name, bests[acc].account_id, bests[acc].best, bests[acc].nonce });
LeaveCriticalSection(&sharesLock);
if (use_debug)
{
char tbuffer[9];
_strtime_s(tbuffer);
wattron(win_main, COLOR_PAIR(2));
wprintw(win_main, "%s [%20llu] found DL: %9llu\n", tbuffer, bests[acc].account_id, bests[acc].DL, 0);
wattroff(win_main, COLOR_PAIR(2));
}
}
}
else
{
if (bests[acc].nonce == 0 || *wertung < bests[acc].best)
{
Log("\nfound deadline="); Log_llu(*wertung / baseTarget); Log(" nonce="); Log_llu(nonce + v); Log(" for account: "); Log_llu(bests[acc].account_id); Log(" file: "); Log((char*)file_name.c_str());
EnterCriticalSection(&bestsLock);
bests[acc].best = *wertung;
bests[acc].nonce = nonce + v;
bests[acc].DL = *wertung / baseTarget;
LeaveCriticalSection(&bestsLock);
}
EnterCriticalSection(&sharesLock);
shares.push_back({ file_name, bests[acc].account_id, *wertung, nonce + v });
LeaveCriticalSection(&sharesLock);
if (use_debug)
{
char tbuffer[9];
_strtime_s(tbuffer);
wattron(win_main, COLOR_PAIR(2));
wprintw(win_main, "%s [%20llu] found DL: %9llu\n", tbuffer, bests[acc].account_id, *wertung / baseTarget, 0);
wattroff(win_main, COLOR_PAIR(2));
}
}
}
}
}
void procscoop_asm(const unsigned long long nonce, const unsigned long long n, char const *const data, const size_t acc, const std::string &file_name) {
char const *cache;
char sig[32 + 64];
cache = data;
char res[32];
memcpy_s(sig, sizeof(sig), signature, sizeof(char) * 32);
asm_shabal_context x;
for (unsigned long long v = 0; v < n; v++)
{
memcpy_s(&sig[32], sizeof(sig) - 32, &cache[v * 64], sizeof(char) * 64);
asm_shabal_init(&x, 256);
asm_shabal(&x, (const unsigned char*)sig, 64 + 32);
asm_shabal_close(&x, 0, 0, res);
unsigned long long *wertung = (unsigned long long*)res;
if ((*wertung / baseTarget) <= bests[acc].targetDeadline)
{
if (send_best_only)
{
if (bests[acc].nonce == 0 || *wertung < bests[acc].best)
{
Log("\nfound deadline="); Log_llu(*wertung / baseTarget); Log(" nonce="); Log_llu(nonce + v); Log(" for account: "); Log_llu(bests[acc].account_id); Log(" file: "); Log((char*)file_name.c_str());
EnterCriticalSection(&bestsLock);
bests[acc].best = *wertung;
bests[acc].nonce = nonce + v;
bests[acc].DL = *wertung / baseTarget;
LeaveCriticalSection(&bestsLock);
EnterCriticalSection(&sharesLock);
shares.push_back({ file_name, bests[acc].account_id, bests[acc].best, bests[acc].nonce });
LeaveCriticalSection(&sharesLock);
if (use_debug)
{
char tbuffer[9];
_strtime_s(tbuffer);
wattron(win_main, COLOR_PAIR(2));
wprintw(win_main, "%s [%20llu] found DL: %9llu\n", tbuffer, bests[acc].account_id, bests[acc].DL, 0);
wattroff(win_main, COLOR_PAIR(2));
}
}
}
else
{
if (bests[acc].nonce == 0 || *wertung < bests[acc].best)
{
Log("\nfound deadline="); Log_llu(*wertung / baseTarget); Log(" nonce="); Log_llu(nonce + v); Log(" for account: "); Log_llu(bests[acc].account_id); Log(" file: "); Log((char*)file_name.c_str());
EnterCriticalSection(&bestsLock);
bests[acc].best = *wertung;
bests[acc].nonce = nonce + v;
bests[acc].DL = *wertung / baseTarget;
LeaveCriticalSection(&bestsLock);
}
EnterCriticalSection(&sharesLock);
shares.push_back({ file_name, bests[acc].account_id, *wertung, nonce + v });
LeaveCriticalSection(&sharesLock);
if (use_debug)
{
char tbuffer[9];
_strtime_s(tbuffer);
wattron(win_main, COLOR_PAIR(2));
wprintw(win_main, "%s [%20llu] found DL: %9llu\n", tbuffer, bests[acc].account_id, *wertung / baseTarget, 0);
wattroff(win_main, COLOR_PAIR(2));
}
}
}
}
}
void work_i(const size_t local_num) {
__int64 start_work_time, end_work_time;
__int64 start_time_read, end_time_read;
__int64 start_time_proc;
double sum_time_proc = 0;
LARGE_INTEGER li;
QueryPerformanceFrequency(&li);
double const pcFreq = double(li.QuadPart);
QueryPerformanceCounter((LARGE_INTEGER*)&start_work_time);
if (use_boost)
{
//SetThreadPriority(GetCurrentThread(), THREAD_PRIORITY_HIGHEST);
//SetThreadAffinityMask(GetCurrentThread(), 1 << (int)(working_threads));
SetThreadIdealProcessor(GetCurrentThread(), (DWORD)(local_num % std::thread::hardware_concurrency()) );
}
std::string const path_loc_str = paths_dir[local_num];
unsigned long long files_size_per_thread = 0;
Log("\nStart thread: ["); Log_llu(local_num); Log("] "); Log((char*)path_loc_str.c_str());
std::vector<t_files> files;
GetFiles(path_loc_str, &files);
size_t cache_size_local;
DWORD sectorsPerCluster;
DWORD bytesPerSector;
DWORD numberOfFreeClusters;
DWORD totalNumberOfClusters;
for (auto iter = files.begin(); iter != files.end(); ++iter)
{
unsigned long long key, nonce, nonces, stagger, tail;
QueryPerformanceCounter((LARGE_INTEGER*)&start_time_read);
key = iter->Key;
nonce = iter->StartNonce;
nonces = iter->Nonces;
stagger = iter->Stagger;
tail = 0;
// Проверка кратности нонсов стаггеру
if ((double)(nonces % stagger) > DBL_EPSILON)
{
wattron(win_main, COLOR_PAIR(12));
wprintw(win_main, "File %s wrong stagger?\n", iter->Name.c_str(), 0);
wattroff(win_main, COLOR_PAIR(12));
}
// Проверка на повреждения плота
if (nonces != (iter->Size) / (4096 * 64))
{
wattron(win_main, COLOR_PAIR(12));
wprintw(win_main, "file \"%s\" name/size mismatch\n", iter->Name.c_str(), 0);
wattroff(win_main, COLOR_PAIR(12));
if (nonces != stagger)
nonces = (((iter->Size) / (4096 * 64)) / stagger) * stagger; //обрезаем плот по размеру и стаггеру
else
if (scoop > (iter->Size) / (stagger * 64)) //если номер скупа попадает в поврежденный смерженный плот, то пропускаем
{
wattron(win_main, COLOR_PAIR(12));
wprintw(win_main, "skipped\n", 0);
wattroff(win_main, COLOR_PAIR(12));
continue;
}
}
if (!GetDiskFreeSpaceA((iter->Path).c_str(), &sectorsPerCluster, &bytesPerSector, &numberOfFreeClusters, &totalNumberOfClusters))
{
wattron(win_main, COLOR_PAIR(12));
wprintw(win_main, "GetDiskFreeSpace failed\n", 0);
wattroff(win_main, COLOR_PAIR(12));
continue;
}
// Если стаггер в плоте меньше чем размер сектора - пропускаем
if ((stagger * 64) < bytesPerSector)
{
wattron(win_main, COLOR_PAIR(12));
wprintw(win_main, "stagger (%llu) must be >= %llu\n", stagger, bytesPerSector/64, 0);
wattroff(win_main, COLOR_PAIR(12));
continue;
}
// Если нонсов в плоте меньше чем размер сектора - пропускаем
if ((nonces * 64) < bytesPerSector)
{
wattron(win_main, COLOR_PAIR(12));
wprintw(win_main, "nonces (%llu) must be >= %llu\n", nonces, bytesPerSector/64, 0);
wattroff(win_main, COLOR_PAIR(12));
continue;
}
// Если стаггер не выровнен по сектору - можем читать сдвигая последний стагер назад (доделать)
if ((stagger % (bytesPerSector/64)) != 0)
{
wattron(win_main, COLOR_PAIR(12));
wprintw(win_main, "stagger (%llu) must be a multiple of %llu\n", stagger, bytesPerSector / 64, 0);
//unsigned long long new_stagger = (stagger / (bytesPerSector / 64)) * (bytesPerSector / 64);
//tail = stagger - new_stagger;
//stagger = new_stagger;
//nonces = (nonces/stagger) * stagger;
//Нужно добавить остаток от предыдущего значения стаггера для компенсации сдвига по нонсам
//wprintw(win_main, "stagger changed to %llu\n", stagger, 0);
//wprintw(win_main, "nonces changed to %llu\n", nonces, 0);
wattroff(win_main, COLOR_PAIR(12));
//continue;
}
if ((stagger == nonces) && (cache_size < stagger)) cache_size_local = cache_size; // оптимизированный плот
else cache_size_local = stagger; // обычный плот
// Выравниваем cache_size_local по размеру сектора
cache_size_local = (cache_size_local / (size_t)(bytesPerSector / 64)) * (size_t)(bytesPerSector / 64);
//wprintw(win_main, "round: %llu\n", cache_size_local);
char *cache = (char *)VirtualAlloc(nullptr, cache_size_local * 64, MEM_COMMIT, PAGE_READWRITE);
if (cache == nullptr) ShowMemErrorExit();
Log("\nRead file : "); Log((char*)iter->Name.c_str());
//wprintw(win_main, "%S \n", str2wstr(iter->Path + iter->Name).c_str());
HANDLE ifile = CreateFileA((iter->Path + iter->Name).c_str(), GENERIC_READ, FILE_SHARE_READ, 0, OPEN_EXISTING, FILE_FLAG_NO_BUFFERING, nullptr);
if (ifile == INVALID_HANDLE_VALUE)
{
wattron(win_main, COLOR_PAIR(12));
wprintw(win_main, "File \"%s\" error opening. code = %llu\n", iter->Name.c_str(), GetLastError(), 0);
wattroff(win_main, COLOR_PAIR(12));
VirtualFree(cache, 0, MEM_RELEASE);
continue;
}
files_size_per_thread += iter->Size;
unsigned long long start, bytes;
DWORD b = 0;
LARGE_INTEGER liDistanceToMove;
size_t acc = Get_index_acc(key);
for (unsigned long long n = 0; n < nonces; n += stagger)
{
start = n * 4096 * 64 + scoop * stagger * 64;
for (unsigned long long i = 0; i < stagger; i += cache_size_local)
{
if (i + cache_size_local > stagger)
{
cache_size_local = stagger - i; // остаток
//wprintw(win_main, "%llu\n", cache_size_local);
}
bytes = 0;
b = 0;
liDistanceToMove.QuadPart = start + i*64;
if (!SetFilePointerEx(ifile, liDistanceToMove, nullptr, FILE_BEGIN))
{
wprintw(win_main, "error SetFilePointerEx. code = %llu\n", GetLastError(), 0);
continue;
}
do {
if (!ReadFile(ifile, &cache[bytes], (DWORD)(cache_size_local * 64), &b, NULL))
{
wattron(win_main, COLOR_PAIR(12));
wprintw(win_main, "error ReadFile. code = %llu\n", GetLastError(), 0);
wattroff(win_main, COLOR_PAIR(12));
break;
}
bytes += b;
//wprintw(win_main, "%llu %llu\n", bytes, readsize);
} while (bytes < cache_size_local * 64);
if (bytes == cache_size_local * 64)
{
QueryPerformanceCounter((LARGE_INTEGER*)&start_time_proc);
#ifdef __AVX2__
procscoop_m256_8(n + nonce + i, cache_size_local, cache, acc, iter->Name);// Process block AVX2
#else
#ifdef __AVX__
procscoop_m_4(n + nonce + i, cache_size_local, cache, acc, iter->Name);// Process block AVX
#else
procscoop_sph(n + nonce + i, cache_size_local, cache, acc, iter->Name);// Process block SSE4
#endif
#endif
QueryPerformanceCounter(&li);
sum_time_proc += (double)(li.QuadPart - start_time_proc);
worker_progress[local_num].Reads_bytes += bytes;
}
else
{
wattron(win_main, COLOR_PAIR(12));
wprintw(win_main, "Unexpected end of file %s\n", iter->Name.c_str(), 0);
wattroff(win_main, COLOR_PAIR(12));
break;
}
if (stopThreads) // New block while processing: Stop.
{
worker_progress[local_num].isAlive = false;
Log("\nReading file: "); Log((char*)iter->Name.c_str()); Log(" interrupted");
CloseHandle(ifile);
files.clear();
VirtualFree(cache, 0, MEM_RELEASE);
//if (use_boost) SetThreadPriority(GetCurrentThread(), THREAD_PRIORITY_NORMAL);
return;
}
}
}
QueryPerformanceCounter((LARGE_INTEGER*)&end_time_read);
Log("\nClose file: "); Log((char*)iter->Name.c_str()); Log(" [@ "); Log_llu((long long unsigned)((double)(end_time_read - start_time_read) * 1000 / pcFreq)); Log(" ms]");
CloseHandle(ifile);
VirtualFree(cache, 0, MEM_RELEASE);
}
worker_progress[local_num].isAlive = false;
QueryPerformanceCounter((LARGE_INTEGER*)&end_work_time);
//if (use_boost) SetThreadPriority(GetCurrentThread(), THREAD_PRIORITY_NORMAL);
double thread_time = (double)(end_work_time - start_work_time) / pcFreq;
if (use_debug)
{
char tbuffer[9];
_strtime_s(tbuffer);
wattron(win_main, COLOR_PAIR(7));
wprintw(win_main, "%s Thread \"%s\" @ %.1f sec (%.1f MB/s) CPU %.2f%%\n", tbuffer, path_loc_str.c_str(), thread_time, (double)(files_size_per_thread) / thread_time / 1024 / 1024 / 4096, sum_time_proc / pcFreq * 100 / thread_time, 0);
wattroff(win_main, COLOR_PAIR(7));
}
return;
}
char* GetJSON(char const *const req) {
const unsigned BUF_SIZE = 1024;
char *buffer = (char*)HeapAlloc(hHeap, HEAP_ZERO_MEMORY, BUF_SIZE);
if (buffer == nullptr) ShowMemErrorExit();
char *find = nullptr;
unsigned long long msg_len = 0;
int iResult = 0;
struct addrinfo *result = nullptr;
struct addrinfo hints;
SOCKET WalletSocket = INVALID_SOCKET;
char *json = nullptr;
RtlSecureZeroMemory(&hints, sizeof(hints));
hints.ai_family = AF_INET;
hints.ai_socktype = SOCK_STREAM;
hints.ai_protocol = IPPROTO_TCP;
iResult = getaddrinfo(infoaddr.c_str(), infoport.c_str(), &hints, &result);
if (iResult != 0) {
wattron(win_main, COLOR_PAIR(12));
wprintw(win_main, "WINNER: Getaddrinfo failed with error: %d\n", iResult, 0);
wattroff(win_main, COLOR_PAIR(12));
Log("\nWinner: getaddrinfo error");
}
else
{
WalletSocket = socket(result->ai_family, result->ai_socktype, result->ai_protocol);
if (WalletSocket == INVALID_SOCKET)
{
wattron(win_main, COLOR_PAIR(12));
wprintw(win_main, "WINNER: Socket function failed with error: %ld\n", WSAGetLastError(), 0);
wattroff(win_main, COLOR_PAIR(12));
Log("\nWinner: Socket error: "); Log_u(WSAGetLastError());
}
else
{
unsigned t = 3000;
setsockopt(WalletSocket, SOL_SOCKET, SO_RCVTIMEO, (char *)&t, sizeof(unsigned));
iResult = connect(WalletSocket, result->ai_addr, (int)result->ai_addrlen);
if (iResult == SOCKET_ERROR) {
wattron(win_main, COLOR_PAIR(12));
wprintw(win_main, "WINNER: Connect function failed with error: %ld\n", WSAGetLastError(), 0);
wattroff(win_main, COLOR_PAIR(12));
Log("\nWinner: Connect server error "); Log_u(WSAGetLastError());
}
else
{
iResult = send(WalletSocket, req, (int)strlen(req), 0);
if (iResult == SOCKET_ERROR)
{
wattron(win_main, COLOR_PAIR(12));
wprintw(win_main, "WINNER: Send request failed: %ld\n", WSAGetLastError(), 0);
wattroff(win_main, COLOR_PAIR(12));
Log("\nWinner: Error sending request: "); Log_u(WSAGetLastError());
}
else
{
char *tmp_buffer;
unsigned long long msg_len = 0;
int iReceived_size = 0;
while ((iReceived_size = recv(WalletSocket, buffer + msg_len, BUF_SIZE - 1, 0)) > 0)
{
msg_len = msg_len + iReceived_size;
Log("\nrealloc: ");
tmp_buffer = (char*)HeapAlloc(hHeap, HEAP_ZERO_MEMORY, msg_len + BUF_SIZE);
if (tmp_buffer == nullptr) ShowMemErrorExit();
memcpy(tmp_buffer, buffer, msg_len);
HeapFree(hHeap, 0, buffer);
buffer = tmp_buffer;
buffer[msg_len + 1] = 0;
Log_llu(msg_len);
}
if (iReceived_size < 0)
{
wattron(win_main, COLOR_PAIR(12));
wprintw(win_main, "WINNER: Get info failed: %ld\n", WSAGetLastError(), 0);
wattroff(win_main, COLOR_PAIR(12));
Log("\nWinner: Error response: "); Log_u(WSAGetLastError());
}
else
{
find = strstr(buffer, "\r\n\r\n");
if (find != nullptr)
{
json = (char*)HeapAlloc(hHeap, HEAP_ZERO_MEMORY, msg_len);
if (json == nullptr) ShowMemErrorExit();
sprintf_s(json, HeapSize(hHeap, 0, json), "%s", find + 4 * sizeof(char));
}
} // recv() != SOCKET_ERROR
} //send() != SOCKET_ERROR
} // Connect() != SOCKET_ERROR
} // socket() != INVALID_SOCKET
iResult = closesocket(WalletSocket);
} // getaddrinfo() == 0
HeapFree(hHeap, 0, buffer);
freeaddrinfo(result);
return json;
}
void GetBlockInfo(unsigned const num_block)
{
char* generator = nullptr;
char* generatorRS = nullptr;
unsigned long long last_block_height = 0;
char* name = nullptr;
char* rewardRecipient = nullptr;
char* pool_accountRS = nullptr;
char* pool_name = nullptr;
unsigned long long timestamp0 = 0;
unsigned long long timestamp1 = 0;
char tbuffer[9];
char* json;
// Запрос двух последних блоков из блокчейна
char* str_req = (char*)HeapAlloc(hHeap, HEAP_ZERO_MEMORY, MAX_PATH);
if (str_req == nullptr) ShowMemErrorExit();
sprintf_s(str_req, HeapSize(hHeap, 0, str_req), "POST /burst?requestType=getBlocks&firstIndex=%u&lastIndex=%u HTTP/1.0\r\nConnection: close\r\n\r\n", num_block, num_block + 1);
json = GetJSON(str_req);
//Log("\n getBlocks: ");
if (json == nullptr) Log("\n-! error in message from pool (getBlocks)\n");
else
{
rapidjson::Document doc_block;
if (doc_block.Parse<0>(json).HasParseError() == false)
{
const Value& blocks = doc_block["blocks"];
if (blocks.IsArray())
{
const Value& bl_0 = blocks[SizeType(0)];
const Value& bl_1 = blocks[SizeType(1)];
generatorRS = (char*)HeapAlloc(hHeap, HEAP_ZERO_MEMORY, strlen(bl_0["generatorRS"].GetString()) + 1);
if (generatorRS == nullptr) ShowMemErrorExit();
strcpy_s(generatorRS, HeapSize(hHeap, 0, generatorRS), bl_0["generatorRS"].GetString());
generator = (char*)HeapAlloc(hHeap, HEAP_ZERO_MEMORY, strlen(bl_0["generator"].GetString()) + 1);
if (generator == nullptr) ShowMemErrorExit();
strcpy_s(generator, HeapSize(hHeap, 0, generator), bl_0["generator"].GetString());
last_block_height = bl_0["height"].GetUint();
timestamp0 = bl_0["timestamp"].GetUint64();
timestamp1 = bl_1["timestamp"].GetUint64();
}
}
else Log("\n- error parsing JSON getBlocks");
}
HeapFree(hHeap, 0, str_req);
if (json != nullptr) HeapFree(hHeap, 0, json);
if ((generator != nullptr) && (generatorRS != nullptr) && (timestamp0 != 0) && (timestamp1 != 0))
if (last_block_height == height - 1)
{
// Запрос данных аккаунта
str_req = (char*)HeapAlloc(hHeap, HEAP_ZERO_MEMORY, MAX_PATH);
if (str_req == nullptr) ShowMemErrorExit();
sprintf_s(str_req, HeapSize(hHeap, 0, str_req), "POST /burst?requestType=getAccount&account=%s HTTP/1.0\r\nConnection: close\r\n\r\n", generator);
json = GetJSON(str_req);
//Log("\n getAccount: ");
if (json == nullptr) Log("\n- error in message from pool (getAccount)\n");
else
{
rapidjson::Document doc_acc;
if (doc_acc.Parse<0>(json).HasParseError() == false)
{
if (doc_acc.HasMember("name"))
{
name = (char*)HeapAlloc(hHeap, HEAP_ZERO_MEMORY, strlen(doc_acc["name"].GetString()) + 1);
if (name == nullptr) ShowMemErrorExit();
strcpy_s(name, HeapSize(hHeap, 0, name), doc_acc["name"].GetString());
}
}
else Log("\n- error parsing JSON getAccount");
}
HeapFree(hHeap, 0, str_req);
if (json != nullptr) HeapFree(hHeap, 0, json);
// Запрос RewardAssighnment по данному аккаунту
str_req = (char*)HeapAlloc(hHeap, HEAP_ZERO_MEMORY, MAX_PATH);
if (str_req == nullptr) ShowMemErrorExit();
sprintf_s(str_req, HeapSize(hHeap, 0, str_req), "POST /burst?requestType=getRewardRecipient&account=%s HTTP/1.0\r\nConnection: close\r\n\r\n", generator);
json = GetJSON(str_req);
HeapFree(hHeap, 0, str_req);
//Log("\n getRewardRecipient: ");
if (json == nullptr) Log("\n- error in message from pool (getRewardRecipient)\n");
else
{
rapidjson::Document doc_reward;
if (doc_reward.Parse<0>(json).HasParseError() == false)
{
if (doc_reward.HasMember("rewardRecipient"))
{
rewardRecipient = (char*)HeapAlloc(hHeap, HEAP_ZERO_MEMORY, strlen(doc_reward["rewardRecipient"].GetString()) + 1);
if (rewardRecipient == nullptr) ShowMemErrorExit();
strcpy_s(rewardRecipient, HeapSize(hHeap, 0, rewardRecipient), doc_reward["rewardRecipient"].GetString());
}
}
else Log("\n-! error parsing JSON getRewardRecipient");
}
if (json != nullptr) HeapFree(hHeap, 0, json);
if (rewardRecipient != nullptr)
{
// Если rewardRecipient != generator, то майнит на пул, узнаём имя пула...
if (strcmp(generator, rewardRecipient) != 0)
{
// Запрос данных аккаунта пула
str_req = (char*)HeapAlloc(hHeap, HEAP_ZERO_MEMORY, MAX_PATH);
if (str_req == nullptr) ShowMemErrorExit();
sprintf_s(str_req, HeapSize(hHeap, 0, str_req), "POST /burst?requestType=getAccount&account=%s HTTP/1.0\r\nConnection: close\r\n\r\n", rewardRecipient);
json = GetJSON(str_req);
//Log("\n getAccount: ");
if (json == nullptr)
{
Log("\n- error in message from pool (pool getAccount)\n");
}
else
{
rapidjson::Document doc_pool;
if (doc_pool.Parse<0>(json).HasParseError() == false)
{
pool_accountRS = (char*)HeapAlloc(hHeap, HEAP_ZERO_MEMORY, strlen(doc_pool["accountRS"].GetString()) + 1);
if (pool_accountRS == nullptr) ShowMemErrorExit();
strcpy_s(pool_accountRS, HeapSize(hHeap, 0, pool_accountRS), doc_pool["accountRS"].GetString());
if (doc_pool.HasMember("name"))
{
pool_name = (char*)HeapAlloc(hHeap, HEAP_ZERO_MEMORY, strlen(doc_pool["name"].GetString()) + 1);
if (pool_name == nullptr) ShowMemErrorExit();
strcpy_s(pool_name, HeapSize(hHeap, 0, pool_name), doc_pool["name"].GetString());
}
}
else Log("\n- error parsing JSON pool getAccount");
}
HeapFree(hHeap, 0, str_req);
HeapFree(hHeap, 0, json);
}
}
wattron(win_main, COLOR_PAIR(11));
_strtime_s(tbuffer);
if (name != nullptr) wprintw(win_main, "%s Winner: %llus by %s (%s)\n", tbuffer, timestamp0 - timestamp1, generatorRS + 6, name, 0);
else wprintw(win_main, "%s Winner: %llus by %s\n", tbuffer, timestamp0 - timestamp1, generatorRS + 6, 0);
if (pool_accountRS != nullptr)
{
if (pool_name != nullptr) wprintw(win_main, "%s Winner's pool: %s (%s)\n", tbuffer, pool_accountRS + 6, pool_name, 0);
else wprintw(win_main, "%s Winner's pool: %s\n", tbuffer, pool_accountRS + 6, 0);
}
wattroff(win_main, COLOR_PAIR(11));
}
else
{
_strtime_s(tbuffer);
wattron(win_main, COLOR_PAIR(11));
wprintw(win_main, "%s Winner: no info yet\n", tbuffer, 0);
wattroff(win_main, COLOR_PAIR(11));
}
HeapFree(hHeap, 0, generatorRS);
HeapFree(hHeap, 0, generator);
HeapFree(hHeap, 0, name);
HeapFree(hHeap, 0, rewardRecipient);
HeapFree(hHeap, 0, pool_name);
HeapFree(hHeap, 0, pool_accountRS);
}
void pollLocal(void) {
size_t const buffer_size = 1000;
char *buffer = (char*)HeapAlloc(hHeap, HEAP_ZERO_MEMORY, buffer_size);
if (buffer == nullptr) ShowMemErrorExit();
int iResult;
struct addrinfo *result = nullptr;
struct addrinfo hints;
SOCKET UpdaterSocket = INVALID_SOCKET;
RtlSecureZeroMemory(&hints, sizeof(hints));
hints.ai_family = AF_INET;
hints.ai_socktype = SOCK_STREAM;
hints.ai_protocol = IPPROTO_TCP;
iResult = getaddrinfo(updateraddr.c_str(), updaterport.c_str(), &hints, &result);
if (iResult != 0) {
if (network_quality > 0) network_quality--;
Log("\n*! GMI: getaddrinfo failed with error: "); Log_u(WSAGetLastError());
}
else {
UpdaterSocket = socket(result->ai_family, result->ai_socktype, result->ai_protocol);
if (UpdaterSocket == INVALID_SOCKET)
{
if (network_quality > 0) network_quality--;
Log("\n*! GMI: socket function failed with error: "); Log_u(WSAGetLastError());
}
else {
const unsigned t = 1000;
setsockopt(UpdaterSocket, SOL_SOCKET, SO_RCVTIMEO, (char *)&t, sizeof(unsigned));
//Log("\n*Connecting to server: "); Log(updateraddr); Log(":"); Log(updaterport);
iResult = connect(UpdaterSocket, result->ai_addr, (int)result->ai_addrlen);
if (iResult == SOCKET_ERROR) {
if (network_quality > 0) network_quality--;
Log("\n*! GMI: connect function failed with error: "); Log_u(WSAGetLastError());
}
else {
int bytes;
if (miner_mode == 2) bytes = sprintf_s(buffer, buffer_size, "GET /pool/getMiningInfo HTTP/1.0\r\nHost: %s:%s\r\nContent-Type: text/plain;charset=UTF-8\r\n\r\n", updateraddr.c_str(), updaterport.c_str());
else bytes = sprintf_s(buffer, buffer_size, "POST /burst?requestType=getMiningInfo HTTP/1.0\r\nHost: %s:%s\r\nContent-Length: 0\r\nConnection: close\r\n\r\n", nodeaddr.c_str(), nodeport.c_str());
iResult = send(UpdaterSocket, buffer, bytes, 0);
if (iResult == SOCKET_ERROR)
{
if (network_quality > 0) network_quality--;
Log("\n*! GMI: send request failed: "); Log_u(WSAGetLastError());
}
else{
if (show_updates) wprintw(win_main, "Sent: \n%s\n", buffer, 0);
Log("\n* GMI: Sent: "); Log_server(buffer);
RtlSecureZeroMemory(buffer, buffer_size);
size_t pos = 0;
iResult = 0;
do{
iResult = recv(UpdaterSocket, &buffer[pos], (int)(buffer_size - pos - 1), 0);
if (iResult > 0) pos += (size_t)iResult;
} while ((iResult > 0) && !use_fast_rcv);
if (iResult == SOCKET_ERROR)
{
if (network_quality > 0) network_quality--;
Log("\n*! GMI: get mining info failed:: "); Log_u(WSAGetLastError());
}
else {
if (network_quality < 100) network_quality++;
Log("\n* GMI: Received: "); Log_server(buffer);
if (show_updates) wprintw(win_main, "Received: %s\n", buffer, 0);
// locate HTTP header
char *find = strstr(buffer, "\r\n\r\n");
if (find == nullptr) Log("\n*! GMI: error message from pool");
else {
rapidjson::Document gmi;
if (gmi.Parse<0>(find).HasParseError()) Log("\n*! GMI: error parsing JSON message from pool");
else {
if (gmi.IsObject())
{
if (gmi.HasMember("baseTarget")) {
if (gmi["baseTarget"].IsString()) baseTarget = _strtoui64(gmi["baseTarget"].GetString(), 0, 10);
else
if (gmi["baseTarget"].IsInt64()) baseTarget = gmi["baseTarget"].GetInt64();
}
if (gmi.HasMember("height")) {
if (gmi["height"].IsString()) height = _strtoui64(gmi["height"].GetString(), 0, 10);
else
if (gmi["height"].IsInt64()) height = gmi["height"].GetInt64();
}
if (gmi.HasMember("generationSignature")) {
strcpy_s(str_signature, gmi["generationSignature"].GetString());
if (xstr2strr(signature, 33, gmi["generationSignature"].GetString()) == 0) Log("\n*! GMI: Node response: Error decoding generationsignature\n");
}
if (gmi.HasMember("targetDeadline")) {
if (gmi["targetDeadline"].IsString()) targetDeadlineInfo = _strtoui64(gmi["targetDeadline"].GetString(), 0, 10);
else
if (gmi["targetDeadline"].IsInt64()) targetDeadlineInfo = gmi["targetDeadline"].GetInt64();
}
}
}
}
}
}
}
iResult = closesocket(UpdaterSocket);
}
freeaddrinfo(result);
}
HeapFree(hHeap, 0, buffer);
}
void updater_i(void) {
if (updateraddr.length() <= 3) {
Log("\nGMI: ERROR in UpdaterAddr");
exit(2);
}
for (; !exit_flag;) {
pollLocal();
std::this_thread::yield();
std::this_thread::sleep_for(std::chrono::milliseconds(update_interval));
}
}
void hostname_to_ip(char const *const in_addr, char* out_addr)
{
struct addrinfo *result = nullptr;
struct addrinfo *ptr = nullptr;
struct addrinfo hints;
DWORD dwRetval;
struct sockaddr_in *sockaddr_ipv4;
RtlSecureZeroMemory(&hints, sizeof(hints));
hints.ai_family = AF_INET;
hints.ai_socktype = SOCK_STREAM;
hints.ai_protocol = IPPROTO_TCP;
dwRetval = getaddrinfo(in_addr, NULL, &hints, &result);
if (dwRetval != 0) {
Log("\n getaddrinfo failed with error: "); Log_llu(dwRetval);
WSACleanup();
exit(-1);
}
for (ptr = result; ptr != nullptr; ptr = ptr->ai_next) {
if(ptr->ai_family == AF_INET)
{
sockaddr_ipv4 = (struct sockaddr_in *) ptr->ai_addr;
char str[INET_ADDRSTRLEN];
inet_ntop(hints.ai_family, &(sockaddr_ipv4->sin_addr), str, INET_ADDRSTRLEN);
//strcpy(out_addr, inet_ntoa(sockaddr_ipv4->sin_addr));
strcpy_s(out_addr, 50, str);
Log("\nAddress: "); Log(in_addr); Log(" defined as: "); Log(out_addr);
}
}
freeaddrinfo(result);
}
void GetCPUInfo(void)
{
ULONGLONG TotalMemoryInKilobytes = 0;
wprintw(win_main, "CPU support: ");
if (InstructionSet::AES()) wprintw(win_main, " AES ", 0);
if (InstructionSet::SSE()) wprintw(win_main, " SSE ", 0);
if (InstructionSet::SSE2()) wprintw(win_main, " SSE2 ", 0);
if (InstructionSet::SSE3()) wprintw(win_main, " SSE3 ", 0);
if (InstructionSet::SSE42()) wprintw(win_main, " SSE4.2 ", 0);
if (InstructionSet::AVX()) wprintw(win_main, " AVX ", 0);
if (InstructionSet::AVX2()) wprintw(win_main, " AVX2 ", 0);
#ifndef __AVX__
// Checking for AVX requires 3 things:
// 1) CPUID indicates that the OS uses XSAVE and XRSTORE instructions (allowing saving YMM registers on context switch)
// 2) CPUID indicates support for AVX
// 3) XGETBV indicates the AVX registers will be saved and restored on context switch
bool avxSupported = false;
int cpuInfo[4];
__cpuid(cpuInfo, 1);
bool osUsesXSAVE_XRSTORE = cpuInfo[2] & (1 << 27) || false;
bool cpuAVXSuport = cpuInfo[2] & (1 << 28) || false;
if (osUsesXSAVE_XRSTORE && cpuAVXSuport)
{
// Check if the OS will save the YMM registers
unsigned long long xcrFeatureMask = _xgetbv(_XCR_XFEATURE_ENABLED_MASK);
avxSupported = (xcrFeatureMask & 0x6) == 0x6;
}
if (avxSupported) wprintw(win_main, " [recomend use AVX]", 0);
#endif
if (InstructionSet::AVX2()) wprintw(win_main, " [recomend use AVX2]", 0);
SYSTEM_INFO sysinfo;
GetSystemInfo(&sysinfo);
wprintw(win_main, "\n%s", InstructionSet::Vendor().c_str(), 0);
wprintw(win_main, " %s [%u cores]", InstructionSet::Brand().c_str(), sysinfo.dwNumberOfProcessors);
if (GetPhysicallyInstalledSystemMemory(&TotalMemoryInKilobytes))
wprintw(win_main, "\nRAM: %llu Mb", (unsigned long long)TotalMemoryInKilobytes / 1024, 0);
wprintw(win_main, "\n", 0);
}
/*
#ifdef GPU_ON_CPP
std::vector<std::shared_ptr<OpenclPlatform>> GPU_PlatformInfo(void)
{
//инициализация платформы
try {
std::vector<std::shared_ptr<OpenclPlatform>> platforms(OpenclPlatform::list());
printf("\nPlatforms number: %u\n", platforms.size());
std::size_t i = 0;
for (const std::shared_ptr<OpenclPlatform>& platform : platforms) {
printf("\n----");
printf("\nId: %u", i++);
printf("\nName: %s", (platform->getName()).c_str());
printf("\nVendor: %s", (platform->getVendor()).c_str());
printf("\nVersion: %s\n", (platform->getVersion()).c_str());
}
return platforms;
}
catch (const OpenclError& ex) {
printf("\n[ERROR][%u][%s] %s", ex.getCode(), ex.getCodeString().c_str(), ex.what());
//return -1;
}
catch (const std::exception& ex) {
printf("\n[ERROR] %s", ex.what());
//return -1;
}
}
int GPU_DeviceInfo(unsigned platform)
{
//инициализация девайсов
try {
std::size_t platformId = platform; //std::atol(p_args[0].c_str());
std::vector<std::shared_ptr<OpenclPlatform>> platforms(OpenclPlatform::list());
if (platformId >= platforms.size()) {
throw std::runtime_error("No platform found with the provided id");
}
//std::vector<unsigned long long> sizeUnits{ 1024, 1024, 1024 };
//std::vector<std::string> sizeLabels{ "KB", "MB", "GB", "TB" };
std::vector<std::shared_ptr<OpenclDevice>> devices(OpenclDevice::list(platforms[platformId]));
printf("\nDevices number : %u", devices.size());
std::size_t i = 0;
for (const std::shared_ptr<OpenclDevice>& device : devices) {
printf("\n----");
printf("\nId: %u", i++);
printf("\nType: %s", device->getType().c_str());
printf("\nName: %s", device->getName().c_str());
printf("\nVendor: %s", device->getVendor().c_str());
printf("\nVersion: %s", device->getVersion().c_str());
printf("\nDriver version: %s", device->getDriverVersion().c_str());
printf("\nMax clock frequency: %u Mhz", device->getMaxClockFrequency());
printf("\nMax compute units: %u", device->getMaxComputeUnits());
printf("\nGlobal memory size: %llu Mb", device->getGlobalMemorySize()>>20); //cryo::util::formatValue(device->getGlobalMemorySize() >> 10, sizeUnits, sizeLabels));
printf("\nMax memory allocation size: %llu Mb", device->getMaxMemoryAllocationSize()>>20); // cryo::util::formatValue(device->getMaxMemoryAllocationSize() >> 10, sizeUnits, sizeLabels));
printf("\nMax work group size: %u", device->getMaxWorkGroupSize());
printf("\nLocal memory size: %llu Kb", device->getLocalMemorySize()>>10);// cryo::util::formatValue(device->getLocalMemorySize() >> 10, sizeUnits, sizeLabels));
std::vector<std::size_t> maxWorkItemSizes(device->getMaxWorkItemSizes());
//printf("\nMax work-item sizes: (" << cryo::util::join(maxWorkItemSizes.begin(), maxWorkItemSizes.end(), ", ") << ")" << std::endl;
printf("\n----");
}
}
catch (const OpenclError& ex) {
printf("\n[ERROR][%u][%s] %s", ex.getCode(), ex.getCodeString().c_str(), ex.what());
return -1;
}
catch (const std::exception& ex) {
printf("\n[ERROR] %s", ex.what());
return -1;
}
return 0;
}
int GPU(void)
{
//std::vector<std::shared_ptr<OpenclPlatform>> plat = GPU_PlatformInfo();
//GPU_DeviceInfo(0);
//Loading platforms
//std::vector<std::shared_ptr<OpenclPlatform>> platforms(OpenclPlatform::list());
//Loading devices
//std::vector<std::vector<std::shared_ptr<OpenclDevice>>> devices;
//for (const std::shared_ptr<OpenclPlatform>& platform : platforms) {
// devices.push_back(OpenclDevice::list(platform));
//}
//Initializing generation contexts
//std::shared_ptr<GenerationContext> generationContext;
//generationContext = std::shared_ptr<GenerationContext>(new GenerationContextBuffer(config, plotsFile));
cl_int err = CL_SUCCESS;
//OpenclError& ex;
// try
{
std::vector<cl::Platform> platforms;
cl::Platform::get(&platforms);
cl_context_properties properties[] = { CL_CONTEXT_PLATFORM, (cl_context_properties)(platforms[0])(), 0 };
cl::Context context(CL_DEVICE_TYPE_GPU, properties);
std::vector<cl::Device> devices = context.getInfo<CL_CONTEXT_DEVICES>();
//Load OpenCL source code
std::ifstream sourceFile("kernel\\nonce.cl");
std::string sourceCode(std::istreambuf_iterator<char>(sourceFile), (std::istreambuf_iterator<char>()));
cl::Program::Sources source(1, std::make_pair(sourceCode.c_str(), sourceCode.length() + 1));
printf("\nmake program");
cl::Program program_ = cl::Program(context, source, &err);
//program_.build(contextDevices);
//cl::Kernel kernel(program_, "TestKernel");
//cl::Program::Sources source(1, std::make_pair(helloStr, strlen(helloStr)));
//cl::Program program_ = cl::Program(context, source);
printf("\nbuild program");
const char options[] = "-Werror";
program_.build(devices, options);
char* programLog;
err = program_.getBuildInfo(devices[0], CL_PROGRAM_BUILD_LOG, &programLog);
// check build log
//clGetProgramBuildInfo(program, device, CL_PROGRAM_BUILD_LOG, 0, nullptr, &logSize);
//programLog = (char*)calloc(logSize + 1, sizeof(char));
//clGetProgramBuildInfo(program, device, CL_PROGRAM_BUILD_LOG, logSize + 1, programLog, nullptr);
printf("Build failed: error=%d, programLog:\n%s", err, programLog);
//free(programLog);
printf("\nkernel");
cl::Kernel kernel(program_, "nonce_step3");
//cl::Event event;
//cl::CommandQueue queue(context, devices[0], 0, &err);
//queue.enqueueNDRangeKernel(
// kernel,
// cl::nullptrRange,
// cl::NDRange(4, 4),
// cl::nullptrRange,
// nullptr,
// &event);
//event.wait();
printf("\n\nDONE\n");
}
catch (const OpenclError& err) {
printf("\n[ERROR][%u][%s] %s\n", err.getCode(), err.getCodeString().c_str(), err.what());
return -1;
}
catch (const std::exception& err) {
printf("\n[ERROR] %s\n", err.what());
return -1;
}
return 0;
}
#endif
#ifdef GPU_ON_C
int GPU_init(void)
{
cl_int ret_err = 0;
//cl_uint num_devices = 0;
cl_uint num_platforms = 0;
//gpu_devices;
wprintw(win_main, "\nInit GPU platform and devices:");
wrefresh(win_main);
ret_err = clGetPlatformIDs(1, nullptr, &num_platforms);
if (CL_SUCCESS == ret_err)
{
wprintw(win_main, "\n Detected OpenCL platforms: %d", num_platforms);
if (num_platforms < (cl_uint)gpu_devices.use_gpu_platform+1)
{
wattron(win_main, COLOR_PAIR(12));
wprintw(win_main, "\nError. Set correct gpu_platform");
wattroff(win_main, COLOR_PAIR(12));
wrefresh(win_main);
return -1;
}
}
else
{
wattron(win_main, COLOR_PAIR(12));
wprintw(win_main, "\nError calling clGetPlatformIDs. Error code: %d", ret_err);
wattroff(win_main, COLOR_PAIR(12));
wrefresh(win_main);
return -1;
}
cl_platform_id *platforms = (cl_platform_id*)calloc((size_t)num_platforms, sizeof(cl_platform_id));
if (platforms == nullptr) ShowMemErrorExit();
ret_err = clGetPlatformIDs(num_platforms, platforms, &num_platforms);
if (ret_err != CL_SUCCESS)
{
wattron(win_main, COLOR_PAIR(12));
wprintw(win_main, "\n clGetPlatformIDs (error %i)", ret_err);
wattroff(win_main, COLOR_PAIR(12));
wrefresh(win_main);
free(platforms);
return -1;
}
ret_err = clGetDeviceIDs(platforms[gpu_devices.use_gpu_platform], CL_DEVICE_TYPE_GPU, 0, nullptr, &gpu_devices.num_devices);
if (CL_SUCCESS == ret_err)
{
char *str_info_platform = (char*)calloc(255, sizeof(char));
ret_err = clGetPlatformInfo(platforms[gpu_devices.use_gpu_platform], CL_PLATFORM_VERSION, 254, str_info_platform, nullptr);
wprintw(win_main, "\n Platform #%d: %s\n Detected GPU devices: %llu", (cl_uint)gpu_devices.use_gpu_platform, str_info_platform, gpu_devices.num_devices, 0);
free(str_info_platform);
if (gpu_devices.num_devices < (cl_uint)gpu_devices.use_gpu_device + 1)
{
wattron(win_main, COLOR_PAIR(12));
wprintw(win_main, "\nError. Set correct gpu_device");
wattroff(win_main, COLOR_PAIR(12));
wrefresh(win_main);
free(platforms);
return -2;
}
}
else
{
wattron(win_main, COLOR_PAIR(12));
wprintw(win_main, "\nError calling clGetDeviceIDs. Error code: %d", ret_err);
wattroff(win_main, COLOR_PAIR(12));
wrefresh(win_main);
free(platforms);
return -2;
}
gpu_devices.devices = (cl_device_id*)calloc((size_t)gpu_devices.num_devices, sizeof(cl_device_id));
if (gpu_devices.devices == nullptr)
{
free(platforms);
ShowMemErrorExit();
return -2;
}
ret_err = clGetDeviceIDs(platforms[gpu_devices.use_gpu_platform], CL_DEVICE_TYPE_GPU, gpu_devices.num_devices, gpu_devices.devices, &gpu_devices.num_devices);
if (ret_err != CL_SUCCESS)
{
wattron(win_main, COLOR_PAIR(12));
wprintw(win_main, "\n clGetDeviceIDs (error %i)", gpu_devices.num_devices, ret_err);
wattroff(win_main, COLOR_PAIR(12));
wrefresh(win_main);
free(platforms);
return -2;
}
ret_err = clGetDeviceInfo(gpu_devices.devices[gpu_devices.use_gpu_device], CL_DEVICE_MAX_WORK_GROUP_SIZE, sizeof(size_t), &gpu_devices.max_WorkGroupSize, nullptr);
ret_err = clGetDeviceInfo(gpu_devices.devices[gpu_devices.use_gpu_device], CL_DEVICE_MAX_COMPUTE_UNITS, sizeof(size_t), &gpu_devices.max_ComputeUnits, nullptr);
char *str_info_1 = (char*)calloc(255, sizeof(char));
ret_err = clGetDeviceInfo(gpu_devices.devices[gpu_devices.use_gpu_device], CL_DEVICE_NAME, 254, str_info_1, nullptr);
char *str_info_2 = (char*)calloc(255, sizeof(char));
ret_err = clGetDeviceInfo(gpu_devices.devices[gpu_devices.use_gpu_device], CL_DEVICE_VERSION, 254, str_info_2, nullptr);
wprintw(win_main, "\n Device: %s, %s, %u", str_info_1, str_info_2, gpu_devices.max_ComputeUnits);
wrefresh(win_main);
free(str_info_1);
free(str_info_2);
free(platforms);
return 0;
}
int GPU1(void)
{
const unsigned int HASH_SIZE = 32;
const unsigned int HASHES_PER_SCOOP = 2;
const unsigned int SCOOP_SIZE = HASHES_PER_SCOOP * HASH_SIZE;
const unsigned int SCOOPS_PER_PLOT = 4096;
const unsigned int PLOT_SIZE = SCOOPS_PER_PLOT * SCOOP_SIZE;
const unsigned int HASH_CAP = 4096;
const unsigned int GEN_SIZE = PLOT_SIZE + 16;
unsigned int WorkSize = 64;
cl_context context;
cl_command_queue commandQueue;
cl_mem bufferDevice;
FILE* programHandle;
size_t programSize;
char *programBuffer;
cl_program program;
cl_int ret_err = 0;
context = clCreateContext(nullptr, gpu_devices.num_devices, gpu_devices.devices, nullptr, nullptr, &ret_err);
wprintw(win_main, "\nclCreateContext (error %i)", ret_err);
wrefresh(win_main);
commandQueue = clCreateCommandQueue(context, gpu_devices.devices[gpu_devices.use_gpu_device], 0, &ret_err);
wprintw(win_main, "\nclCreateCommandQueue (error %i)", ret_err);
wrefresh(win_main);
bufferDevice = clCreateBuffer(context, CL_MEM_READ_WRITE, sizeof(unsigned char)* WorkSize * GEN_SIZE, 0, &ret_err);
wprintw(win_main, "\nclCreateBuffer (error %i)", ret_err);
wrefresh(win_main);
wprintw(win_main, "\nget size of kernel source: ");
// get size of kernel source
programHandle = fopen("calcdeadlines.cl", "rb");
_fseeki64(programHandle, 0, SEEK_END);
programSize = _ftelli64(programHandle);
rewind(programHandle);
wprintw(win_main, "%Iu", programSize);
wrefresh(win_main);
wprintw(win_main, "\nread kernel source into buffer");
// read kernel source into buffer
programBuffer = (char*)calloc(programSize+1, sizeof(char));
programBuffer[programSize] = '\0';
fread(programBuffer, sizeof(char), programSize, programHandle);
fclose(programHandle);
wrefresh(win_main);
wprintw(win_main, "\ncreate program from buffer");
// create program from buffer
program = clCreateProgramWithSource(context, 1, (const char**)&programBuffer, &programSize, &ret_err);
free(programBuffer);
wprintw(win_main, " (error %i)", ret_err);
wrefresh(win_main);
wprintw(win_main, "\nbuild program");
// build program
char *opt = (char*)calloc(strlen(p_minerPath)+12, sizeof(char));
opt = strcat(opt, "-I ");
opt = strcat(opt, p_minerPath);
opt = strcat(opt, " -Werror");
wprintw(win_main, "\n%s", opt);
wrefresh(win_main);
ret_err = clBuildProgram(program, 1, gpu_devices.devices, opt, nullptr, nullptr);
wprintw(win_main, "\nclBuildProgram %d", ret_err);
wrefresh(win_main);
free(opt);
// build failed
if (ret_err != CL_SUCCESS) {
cl_build_status status;
size_t logSize;
wprintw(win_main, "\nbuild ERROR");
wrefresh(win_main);
// check build error and build status first
clGetProgramBuildInfo(program, gpu_devices.devices[gpu_devices.use_gpu_device], CL_PROGRAM_BUILD_STATUS, sizeof(cl_build_status), &status, nullptr);
wprintw(win_main, "\nCL_PROGRAM_BUILD_STATUS",0);
wrefresh(win_main);
// check build log
clGetProgramBuildInfo(program, gpu_devices.devices[gpu_devices.use_gpu_device], CL_PROGRAM_BUILD_LOG, 0, nullptr, &logSize);
wprintw(win_main, "\nCL_PROGRAM_BUILD_LOG %Iu", logSize);
wrefresh(win_main);
char *programLog = (char*)calloc(logSize + 1, sizeof(char));
clGetProgramBuildInfo(program, gpu_devices.devices[gpu_devices.use_gpu_device], CL_PROGRAM_BUILD_LOG, logSize, programLog, &logSize);
wprintw(win_main, "\nCL_PROGRAM_BUILD_LOG");
programLog[475] = 0;
wprintw(win_main, "\nBuild failed: error=%d, status=%d, programLog:\n%s", ret_err, status, programLog);
wrefresh(win_main);
free(programLog);
}
//cl_kernel kernel[3];
cl_kernel *kernels = (cl_kernel*)calloc(3, sizeof(cl_kernel));
kernels[0] = clCreateKernel(program, "calculate_deadlines", &ret_err);
wprintw(win_main, "\nclCreateKernel_1 %d", ret_err);
wrefresh(win_main);
//size_t lwg = 0;
//ret_err = clGetKernelWorkGroupInfo(kernels[0], gpu_devices.devices[gpu_devices.use_gpu_device], CL_KERNEL_WORK_GROUP_SIZE, sizeof(lwg), (void*)&lwg, nullptr);
//wprintw(win_main, "\nlocal WGS %llu", lwg);
//wrefresh(win_main);
ret_err = clSetKernelArg(kernels[0], 0, sizeof(cl_mem), (void*)&bufferDevice);
wprintw(win_main, "\nclSetKernelArg_1 %d", ret_err);
wrefresh(win_main);
kernels[1] = clCreateKernel(program, "reduce_best", &ret_err);
wprintw(win_main, "\nclCreateKernel_2 %d", ret_err);
wrefresh(win_main);
ret_err = clSetKernelArg(kernels[1], 0, sizeof(cl_mem), (void*)&bufferDevice);
wprintw(win_main, "\nclSetKernelArg_2 %d", ret_err);
wrefresh(win_main);
kernels[2] = clCreateKernel(program, "reduce_target", &ret_err);
wprintw(win_main, "\nclCreateKernel_3 %d", ret_err);
wrefresh(win_main);
ret_err = clSetKernelArg(kernels[2], 0, sizeof(cl_mem), (void*)&bufferDevice);
wprintw(win_main, "\nclSetKernelArg_3 %d", ret_err);
wrefresh(win_main);
free(gpu_devices.devices);
if (kernels[2]) { clReleaseKernel(kernels[2]); }
if (kernels[1]) { clReleaseKernel(kernels[1]); }
if (kernels[0]) { clReleaseKernel(kernels[0]); }
if (program) { clReleaseProgram(program); }
if (bufferDevice) { clReleaseMemObject(bufferDevice); }
if (commandQueue) { clReleaseCommandQueue(commandQueue); }
if (context) { clReleaseContext(context); }
wprintw(win_main, "\n--\n");
wrefresh(win_main);
return 0;
}
#endif
*/
int main(int argc, char **argv) {
hHeap = GetProcessHeap();
//low fragmentation heap. При переключении кучи в данный режим повышается расход памяти за счёт выделения чаще всего существенно большего фрагмента, чем был запрошен, но повышается общее быстродействие кучи
//ULONG HeapInformation = 2;
//HeapSetInformation(hHeap, HeapCompatibilityInformation, &HeapInformation, sizeof(HeapInformation));
HeapSetInformation(NULL, HeapEnableTerminationOnCorruption, NULL, 0);
LARGE_INTEGER li;
__int64 start_threads_time, end_threads_time, curr_time;
QueryPerformanceFrequency(&li);
double pcFreq = double(li.QuadPart);
std::thread proxy;
//std::vector<std::thread> generator;
InitializeCriticalSection(&sessionsLock);
InitializeCriticalSection(&bestsLock);
InitializeCriticalSection(&sharesLock);
char tbuffer[9];
unsigned long long bytesRead = 0;
shares.reserve(20);
bests.reserve(4);
sessions.reserve(20);
size_t const cwdsz = GetCurrentDirectoryA(0, 0);
p_minerPath = (char*)HeapAlloc(hHeap, HEAP_ZERO_MEMORY, cwdsz + 2);
if (p_minerPath == nullptr)
{
fprintf(stderr, "\nError allocating memory\n");
system("pause");
exit(-1);
}
GetCurrentDirectoryA(DWORD(cwdsz), LPSTR(p_minerPath));
strcat_s(p_minerPath, cwdsz + 2, "\\");
char* conf_filename = (char*)HeapAlloc(hHeap, HEAP_ZERO_MEMORY, MAX_PATH);
if (conf_filename == nullptr)
{
fprintf(stderr, "\nError allocating memory\n");
system("pause");
exit(-1);
}
if ((argc >= 2) && (strcmp(argv[1], "-config") == 0)){
if (strstr(argv[2], ":\\")) sprintf_s(conf_filename, MAX_PATH, "%s", argv[2]);
else sprintf_s(conf_filename, MAX_PATH, "%s%s", p_minerPath, argv[2]);
}
else sprintf_s(conf_filename, MAX_PATH, "%s%s", p_minerPath, "miner.conf");
load_config(conf_filename);
HeapFree(hHeap, 0, conf_filename);
Log("\nMiner path: "); Log(p_minerPath);
HANDLE hConsole = GetStdHandle(STD_OUTPUT_HANDLE);
COORD max_coord = GetLargestConsoleWindowSize(hConsole);
if (win_size_x > max_coord.X) win_size_x = max_coord.X;
if (win_size_y > max_coord.Y) win_size_y = max_coord.Y;
COORD coord;
coord.X = win_size_x;
coord.Y = win_size_y;
SMALL_RECT Rect;
Rect.Top = 0;
Rect.Left = 0;
Rect.Bottom = coord.Y - 1;
Rect.Right = coord.X - 1;
SetConsoleScreenBufferSize(hConsole, coord);
SetConsoleWindowInfo(hConsole, TRUE, &Rect);
RECT wSize;
GetWindowRect(GetConsoleWindow(), &wSize);
MoveWindow(GetConsoleWindow(), 0, 0, wSize.right - wSize.left, wSize.bottom - wSize.top, true);
initscr();
raw();
cbreak(); // не использовать буфер для getch()
noecho(); // не отображать нажатия клавиш
curs_set(0); // убрать курсор
start_color(); // будет всё цветное
init_pair(2, COLOR_GREEN, COLOR_BLACK);
init_pair(4, COLOR_RED, COLOR_BLACK);
init_pair(6, COLOR_CYAN, COLOR_BLACK);
init_pair(7, COLOR_WHITE, COLOR_BLACK);
init_pair(9, 9, COLOR_BLACK);
init_pair(10, 10, COLOR_BLACK);
init_pair(11, 11, COLOR_BLACK);
init_pair(12, 12, COLOR_BLACK);
init_pair(14, 14, COLOR_BLACK);
init_pair(15, 15, COLOR_BLACK);
init_pair(25, 15, COLOR_BLUE);
win_main = newwin(LINES - 2, COLS, 0, 0);
//box(win_main, 0, 0);
scrollok(win_main, true);
//leaveok(win_main, true);
keypad(win_main, true);
nodelay(win_main, true);
//wsetscrreg(win_main, 0, 25);
//wrefresh(win_main);
//panel_main = new_panel(win_main);
WINDOW * win_progress = newwin(3, COLS, LINES - 3, 0);
leaveok(win_progress, true);
// box(win_progress, 0, 0);
// wrefresh(win_progress);
wattron(win_main, COLOR_PAIR(12));
wprintw(win_main, "\nBURST miner, %s", version, 0);
wattroff(win_main, COLOR_PAIR(12));
wattron(win_main, COLOR_PAIR(4));
wprintw(win_main, "\nProgramming: dcct (Linux) & Blago (Windows)\n", 0);
wattroff(win_main, COLOR_PAIR(4));
GetCPUInfo();
wrefresh(win_main);
wrefresh(win_progress);
//GPU_init();
//GPU1();
//wrefresh(win_main);
//wrefresh(win_progress);
if (miner_mode == 0) GetPass(p_minerPath);
// адрес и порт сервера
Log("\nSearching servers...");
WSADATA wsaData;
if (WSAStartup(MAKEWORD(2, 2), &wsaData) != 0) {
wprintw(win_main, "WSAStartup failed\n", 0);
exit(-1);
}
char* updaterip = (char*)HeapAlloc(hHeap, HEAP_ZERO_MEMORY, 50);
if (updaterip == nullptr) ShowMemErrorExit();
char* nodeip = (char*)HeapAlloc(hHeap, HEAP_ZERO_MEMORY, 50);
if (nodeip == nullptr) ShowMemErrorExit();
wattron(win_main, COLOR_PAIR(11));
hostname_to_ip(nodeaddr.c_str(), nodeip);
wprintw(win_main, "Pool address %s (ip %s:%s)\n", nodeaddr.c_str(), nodeip, nodeport.c_str(), 0);
if (updateraddr.length() > 3) hostname_to_ip(updateraddr.c_str(), updaterip);
wprintw(win_main, "Updater address %s (ip %s:%s)\n", updateraddr.c_str(), updaterip, updaterport.c_str(), 0);
wattroff(win_main, COLOR_PAIR(11));
HeapFree(hHeap, 0, updaterip);
HeapFree(hHeap, 0, nodeip);
// обнуляем сигнатуру
RtlSecureZeroMemory(oldSignature, 33);
RtlSecureZeroMemory(signature, 33);
// Инфа по файлам
wattron(win_main, COLOR_PAIR(15));
wprintw(win_main, "Using plots:\n", 0);
wattroff(win_main, COLOR_PAIR(15));
std::vector<t_files> all_files;
total_size = 0;
for (auto iter = paths_dir.begin(); iter != paths_dir.end(); ++iter) {
std::vector<t_files> files;
GetFiles(*iter, &files);
unsigned long long tot_size = 0;
for (auto it = files.begin(); it != files.end(); ++it){
tot_size += it->Size;
all_files.push_back(*it);
}
wprintw(win_main, "%s\tfiles: %2Iu\t size: %4llu Gb\n", (char*)iter->c_str(), (unsigned)files.size(), tot_size / 1024 / 1024 / 1024, 0);
total_size += tot_size;
}
wattron(win_main, COLOR_PAIR(15));
wprintw(win_main, "TOTAL: %llu Gb\n", total_size / 1024 / 1024 / 1024, 0);
wattroff(win_main, COLOR_PAIR(15));
if (total_size == 0) {
wattron(win_main, COLOR_PAIR(12));
wprintw(win_main, "\n Plot files not found...please check the \"PATHS\" parameter in your config file.\n Press any key for exit...");
wattroff(win_main, COLOR_PAIR(12));
wrefresh(win_main);
system("pause");
exit(0);
}
// Check overlapped plots
for (size_t cx = 0; cx < all_files.size(); cx++) {
for (size_t cy = cx + 1; cy < all_files.size(); cy++) {
if (all_files[cy].Key == all_files[cx].Key)
if (all_files[cy].StartNonce >= all_files[cx].StartNonce) {
if (all_files[cy].StartNonce < all_files[cx].StartNonce + all_files[cx].Nonces){
wattron(win_main, COLOR_PAIR(12));
wprintw(win_main, "\nWARNING: %s%s and \n%s%s are overlapped\n", all_files[cx].Path.c_str(), all_files[cx].Name.c_str(), all_files[cy].Path.c_str(), all_files[cy].Name.c_str(), 0);
wattroff(win_main, COLOR_PAIR(12));
}
}
else
if (all_files[cy].StartNonce + all_files[cy].Nonces > all_files[cx].StartNonce){
wattron(win_main, COLOR_PAIR(12));
wprintw(win_main, "\nWARNING: %s%s and \n%s%s are overlapped\n", all_files[cx].Path.c_str(), all_files[cx].Name.c_str(), all_files[cy].Path.c_str(), all_files[cy].Name.c_str(), 0);
wattroff(win_main, COLOR_PAIR(12));
}
}
}
//all_files.~vector(); // ???
// Run Proxy
if (enable_proxy)
{
proxy = std::thread(proxy_i);
wattron(win_main, COLOR_PAIR(25));
wprintw(win_main, "Proxy thread started\n", 0);
wattroff(win_main, COLOR_PAIR(25));
}
// Run updater;
std::thread updater(updater_i);
Log("\nUpdater thread started");
Log("\nUpdate mining info");
while (height == 0)
{
std::this_thread::yield();
std::this_thread::sleep_for(std::chrono::milliseconds(2));
};
// Main loop
for (; !exit_flag;)
{
worker.clear();
worker_progress.clear();
stopThreads = 0;
char scoopgen[40];
memmove(scoopgen, signature, 32);
const char *mov = (char*)&height;
scoopgen[32] = mov[7]; scoopgen[33] = mov[6]; scoopgen[34] = mov[5]; scoopgen[35] = mov[4]; scoopgen[36] = mov[3]; scoopgen[37] = mov[2]; scoopgen[38] = mov[1]; scoopgen[39] = mov[0];
sph_shabal_context x;
sph_shabal256_init(&x);
sph_shabal256(&x, (const unsigned char*)(const unsigned char*)scoopgen, 40);
char xcache[32];
sph_shabal256_close(&x, xcache);
scoop = (((unsigned char)xcache[31]) + 256 * (unsigned char)xcache[30]) % 4096;
deadline = 0;
Log("\n------------------------ New block: "); Log_llu(height);
_strtime_s(tbuffer);
wattron(win_main, COLOR_PAIR(25));
wprintw(win_main, "\n%s New block %llu, baseTarget %llu, netDiff %llu Tb \n", tbuffer, height, baseTarget, 4398046511104 / 240 / baseTarget, 0);
wattron(win_main, COLOR_PAIR(25));
if (miner_mode == 0)
{
unsigned long long sat_total_size = 0;
for (auto It = satellite_size.begin(); It != satellite_size.end(); ++It) sat_total_size += It->second;
wprintw(win_main, "*** Chance to find a block: %.5f%% (%llu Gb)\n", ((double)((sat_total_size * 1024 + total_size / 1024 / 1024) * 100 * 60)*(double)baseTarget) / 1152921504606846976, sat_total_size + total_size / 1024 / 1024 / 1024, 0);
}
EnterCriticalSection(&sessionsLock);
for (auto it = sessions.begin(); it != sessions.end(); ++it) closesocket(it->Socket);
sessions.clear();
LeaveCriticalSection(&sessionsLock);
EnterCriticalSection(&sharesLock);
shares.clear();
LeaveCriticalSection(&sharesLock);
EnterCriticalSection(&bestsLock);
bests.clear();
LeaveCriticalSection(&bestsLock);
if ((targetDeadlineInfo > 0) && (targetDeadlineInfo < my_target_deadline)){
Log("\nUpdate targetDeadline: "); Log_llu(targetDeadlineInfo);
}
else targetDeadlineInfo = my_target_deadline;
// Run Sender
std::thread sender(send_i);
// Run Threads
QueryPerformanceCounter((LARGE_INTEGER*)&start_threads_time);
double threads_speed = 0;
for (size_t i = 0; i < paths_dir.size(); i++)
{
worker_progress.push_back({ i, 0, true });
worker.push_back(std::thread(work_i, i));
}
memmove(oldSignature, signature, 32);
unsigned long long old_baseTarget = baseTarget;
unsigned long long old_height = height;
wclear(win_progress);
// Wait until signature changed or exit
while ((memcmp(signature, oldSignature, 32) == 0) && !exit_flag)
{
switch (wgetch(win_main))
{
case 'q':
exit_flag = true;
break;
case 'r':
wattron(win_main, COLOR_PAIR(15));
wprintw(win_main, "Recommended size for this block: %llu Gb\n", (4398046511104 / baseTarget)*1024 / targetDeadlineInfo);
wattroff(win_main, COLOR_PAIR(15));
break;
case 'c':
wprintw(win_main, "*** Chance to find a block: %.5f%% (%llu Gb)\n", ((double)((total_size / 1024 / 1024) * 100 * 60)*(double)baseTarget) / 1152921504606846976, total_size / 1024 / 1024 / 1024, 0);
break;
}
box(win_progress, 0, 0);
bytesRead = 0;
int threads_runing = 0;
for (auto it = worker_progress.begin(); it != worker_progress.end(); ++it)
{
bytesRead += it->Reads_bytes;
threads_runing += it->isAlive;
}
if (threads_runing)
{
QueryPerformanceCounter((LARGE_INTEGER*)&end_threads_time);
threads_speed = (double)(bytesRead / (1024 * 1024)) / ((double)(end_threads_time - start_threads_time) / pcFreq);
}
else{
/*
if (can_generate == 1)
{
Log("\nStart Generator. ");
for (size_t i = 0; i < std::thread::hardware_concurrency()-1; i++) generator.push_back(std::thread(generator_i, i));
can_generate = 2;
}
*/
if (use_wakeup)
{
QueryPerformanceCounter((LARGE_INTEGER*)&curr_time);
if ((curr_time - end_threads_time) / pcFreq > 180) // 3 minutes
{
std::vector<t_files> tmp_files;
for (size_t i = 0; i < paths_dir.size(); i++) GetFiles(paths_dir[i], &tmp_files);
if (use_debug)
{
char tbuffer[9];
_strtime_s(tbuffer);
wattron(win_main, COLOR_PAIR(7));
wprintw(win_main, "%s HDD, WAKE UP !\n", tbuffer, 0);
wattroff(win_main, COLOR_PAIR(7));
}
end_threads_time = curr_time;
}
}
}
wmove(win_progress, 1, 1);
wattron(win_progress, COLOR_PAIR(14));
if (deadline == 0)
wprintw(win_progress, "%3llu%% %6llu GB (%.2f MB/s). no deadline Network quality: %3u%%", (bytesRead * 4096 * 100 / total_size), (bytesRead / (256 * 1024)), threads_speed, network_quality, 0);
else
wprintw(win_progress, "%3llu%% %6llu GB (%.2f MB/s). Deadline =%10llu Network quality: %3u%%", (bytesRead * 4096 * 100 / total_size), (bytesRead / (256 * 1024)), threads_speed, deadline, network_quality, 0);
wattroff(win_progress, COLOR_PAIR(14));
wrefresh(win_main);
wrefresh(win_progress);
std::this_thread::yield();
std::this_thread::sleep_for(std::chrono::milliseconds(39));
}
stopThreads = 1; // Tell all threads to stop
if (show_winner && !exit_flag) GetBlockInfo(0);
for (auto it = worker.begin(); it != worker.end(); ++it)
{
Log("\nInterrupt thread. ");
if (it->joinable()) it->join();
}
Log("\nInterrupt Sender. ");
if (sender.joinable()) sender.join();
/*
if (can_generate != 0){
Log("\nInterrupt Generator. ");
for (auto it = generator.begin(); it != generator.end(); ++it){
if (it->joinable()) it->join();
}
can_generate = 1;
}
*/
}
if (pass != nullptr) HeapFree(hHeap, 0, pass);
if (updater.joinable()) updater.join();
Log("\nUpdater stopped");
if (enable_proxy) proxy.join();
worker.~vector();
worker_progress.~vector();
paths_dir.~vector();
bests.~vector();
shares.~vector();
sessions.~vector();
DeleteCriticalSection(&sessionsLock);
DeleteCriticalSection(&sharesLock);
DeleteCriticalSection(&bestsLock);
HeapFree(hHeap, 0, p_minerPath);
WSACleanup();
Log("\nexit");
fclose(fp_Log);
return 0;
}
// todo list
// проблема с облаками / разрыв связи