Update stratum.cpp

This commit is contained in:
Ralph 2024-03-01 15:50:22 -05:00 committed by GitHub
parent b0cb82cb0e
commit 2f4fa35ec2
No known key found for this signature in database
GPG key ID: B5690EEEBB952194

View file

@ -76,407 +76,406 @@ void *monitor_thread(void *p);
static void scrypt_hash(const char* input, char* output, uint32_t len) static void scrypt_hash(const char* input, char* output, uint32_t len)
{ {
scrypt_1024_1_1_256((unsigned char *)input, (unsigned char *)output); scrypt_1024_1_1_256((unsigned char *)input, (unsigned char *)output);
} }
static void scryptn_hash(const char* input, char* output, uint32_t len) static void scryptn_hash(const char* input, char* output, uint32_t len)
{ {
time_t time_table[][2] = time_t time_table[][2] =
{ {
{2048, 1389306217}, {2048, 1389306217},
{4096, 1456415081}, {4096, 1456415081},
{8192, 1506746729}, {8192, 1506746729},
{16384, 1557078377}, {16384, 1557078377},
{32768, 1657741673}, {32768, 1657741673},
{65536, 1859068265}, {65536, 1859068265},
{131072, 2060394857}, {131072, 2060394857},
{262144, 1722307603}, {262144, 1722307603},
{524288, 1769642992}, {524288, 1769642992},
{0, 0}, {0, 0},
}; };
for(int i=0; time_table[i][0]; i++) for(int i=0; time_table[i][0]; i++)
if(time(NULL) < time_table[i+1][1]) if(time(NULL) < time_table[i+1][1])
{ {
scrypt_N_R_1_256(input, output, time_table[i][0], 1, len); scrypt_N_R_1_256(input, output, time_table[i][0], 1, len);
return; return;
} }
} }
static void neoscrypt_hash(const char* input, char* output, uint32_t len) static void neoscrypt_hash(const char* input, char* output, uint32_t len)
{ {
neoscrypt((unsigned char *)input, (unsigned char *)output, 0x80000620); neoscrypt((unsigned char *)input, (unsigned char *)output, 0x80000620);
} }
YAAMP_ALGO g_algos[] = YAAMP_ALGO g_algos[] =
{ {
{"sha256", sha256_double_hash, 1, 0, 0}, {"sha256", sha256_double_hash, 1, 0, 0},
{"scrypt", scrypt_hash, 0x10000, 0, 0}, {"scrypt", scrypt_hash, 0x10000, 0, 0},
{"scryptn", scryptn_hash, 0x10000, 0, 0}, {"scryptn", scryptn_hash, 0x10000, 0, 0},
{"neoscrypt", neoscrypt_hash, 0x10000, 0, 0}, {"neoscrypt", neoscrypt_hash, 0x10000, 0, 0},
{"c11", c11_hash, 1, 0, 0}, {"c11", c11_hash, 1, 0, 0},
{"x11", x11_hash, 1, 0, 0}, {"x11", x11_hash, 1, 0, 0},
{"x12", x12_hash, 1, 0, 0}, {"x12", x12_hash, 1, 0, 0},
{"x13", x13_hash, 1, 0, 0}, {"x13", x13_hash, 1, 0, 0},
{"x14", x14_hash, 1, 0, 0}, {"x14", x14_hash, 1, 0, 0},
{"x15", x15_hash, 1, 0, 0}, {"x15", x15_hash, 1, 0, 0},
{"x17", x17_hash, 1, 0, 0}, {"x17", x17_hash, 1, 0, 0},
{"x22i", x22i_hash, 1, 0, 0}, {"x22i", x22i_hash, 1, 0, 0},
{"x11evo", x11evo_hash, 1, 0, 0}, {"x11evo", x11evo_hash, 1, 0, 0},
{"xevan", xevan_hash, 0x100, 0, 0}, {"xevan", xevan_hash, 0x100, 0, 0},
{"x16r", x16r_hash, 0x100, 0, 0}, {"x16r", x16r_hash, 0x100, 0, 0},
{"x16rv2", x16rv2_hash, 0x100, 0, 0}, {"x16rv2", x16rv2_hash, 0x100, 0, 0},
{"x16s", x16s_hash, 0x100, 0, 0}, {"x16s", x16s_hash, 0x100, 0, 0},
{"timetravel", timetravel_hash, 0x100, 0, 0}, {"timetravel", timetravel_hash, 0x100, 0, 0},
{"bitcore", timetravel10_hash, 0x100, 0, 0}, {"bitcore", timetravel10_hash, 0x100, 0, 0},
{"exosis", exosis_hash, 0x100, 0, 0}, {"exosis", exosis_hash, 0x100, 0, 0},
{"hsr", hsr_hash, 1, 0, 0}, {"hsr", hsr_hash, 1, 0, 0},
{"hmq1725", hmq17_hash, 0x10000, 0, 0}, {"hmq1725", hmq17_hash, 0x10000, 0, 0},
{"jha", jha_hash, 0x10000, 0}, {"jha", jha_hash, 0x10000, 0},
{"allium", allium_hash, 0x100, 0, 0}, {"allium", allium_hash, 0x100, 0, 0},
{"lyra2", lyra2re_hash, 0x80, 0, 0}, {"lyra2", lyra2re_hash, 0x80, 0, 0},
{"lyra2v2", lyra2v2_hash, 0x100, 0, 0}, {"lyra2v2", lyra2v2_hash, 0x100, 0, 0},
{"lyra2v3", lyra2v3_hash, 0x100, 0, 0}, {"lyra2v3", lyra2v3_hash, 0x100, 0, 0},
{"lyra2z", lyra2z_hash, 0x100, 0, 0}, {"lyra2z", lyra2z_hash, 0x100, 0, 0},
{"lyra2zz", lyra2zz_hash, 0x100, 0, 0}, {"lyra2zz", lyra2zz_hash, 0x100, 0, 0},
{"bastion", bastion_hash, 1, 0 }, {"bastion", bastion_hash, 1, 0 },
{"blake", blake_hash, 1, 0 }, {"blake", blake_hash, 1, 0 },
{"blakecoin", blakecoin_hash, 1 /*0x100*/, 0, sha256_hash_hex }, {"blakecoin", blakecoin_hash, 1 /*0x100*/, 0, sha256_hash_hex },
{"blake2b", blake2b_hash, 1, 0 }, {"blake2b", blake2b_hash, 1, 0 },
{"blake2s", blake2s_hash, 1, 0 }, {"blake2s", blake2s_hash, 1, 0 },
{"vanilla", blakecoin_hash, 1, 0 }, {"vanilla", blakecoin_hash, 1, 0 },
{"decred", decred_hash, 1, 0 }, {"decred", decred_hash, 1, 0 },
{"deep", deep_hash, 1, 0, 0}, {"deep", deep_hash, 1, 0, 0},
{"fresh", fresh_hash, 0x100, 0, 0}, {"fresh", fresh_hash, 0x100, 0, 0},
{"quark", quark_hash, 1, 0, 0}, {"quark", quark_hash, 1, 0, 0},
{"nist5", nist5_hash, 1, 0, 0}, {"nist5", nist5_hash, 1, 0, 0},
{"qubit", qubit_hash, 1, 0, 0}, {"qubit", qubit_hash, 1, 0, 0},
{"groestl", groestl_hash, 0x100, 0, sha256_hash_hex }, /* groestlcoin */ {"groestl", groestl_hash, 0x100, 0, sha256_hash_hex }, /* groestlcoin */
{"dmd-gr", groestl_hash, 0x100, 0, 0}, /* diamond (double groestl) */ {"dmd-gr", groestl_hash, 0x100, 0, 0}, /* diamond (double groestl) */
{"myr-gr", groestlmyriad_hash, 1, 0, 0}, /* groestl + sha 64 */ {"myr-gr", groestlmyriad_hash, 1, 0, 0}, /* groestl + sha 64 */
{"skein", skein_hash, 1, 0, 0}, {"skein", skein_hash, 1, 0, 0},
{"sonoa", sonoa_hash, 1, 0, 0}, {"sonoa", sonoa_hash, 1, 0, 0},
{"tribus", tribus_hash, 1, 0, 0}, {"tribus", tribus_hash, 1, 0, 0},
{"keccak", keccak256_hash, 0x80, 0, sha256_hash_hex }, {"keccak", keccak256_hash, 0x80, 0, sha256_hash_hex },
{"keccakc", keccak256_hash, 0x100, 0, 0}, {"keccakc", keccak256_hash, 0x100, 0, 0},
{"hex", hex_hash, 0x100, 0, sha256_hash_hex }, {"hex", hex_hash, 0x100, 0, sha256_hash_hex },
{"phi", phi_hash, 1, 0, 0},
{"phi2", phi2_hash, 0x100, 0, 0},
{"polytimos", polytimos_hash, 1, 0, 0}, {"phi", phi_hash, 1, 0, 0},
{"skunk", skunk_hash, 1, 0, 0}, {"phi2", phi2_hash, 0x100, 0, 0},
{"bmw", bmw_hash, 1, 0, 0}, {"polytimos", polytimos_hash, 1, 0, 0},
{"lbk3", lbk3_hash, 0x100, 0, 0}, {"skunk", skunk_hash, 1, 0, 0},
{"lbry", lbry_hash, 0x100, 0, 0},
{"luffa", luffa_hash, 1, 0, 0},
{"penta", penta_hash, 1, 0, 0},
{"rainforest", rainforest_hash, 0x100, 0, 0},
{"skein2", skein2_hash, 1, 0, 0},
{"yescrypt", yescrypt_hash, 0x10000, 0, 0},
{"yescryptR16", yescryptR16_hash, 0x10000, 0, 0 },
{"yescryptR32", yescryptR32_hash, 0x10000, 0, 0 },
{"zr5", zr5_hash, 1, 0, 0},
{"a5a", a5a_hash, 0x10000, 0, 0}, {"bmw", bmw_hash, 1, 0, 0},
{"hive", hive_hash, 0x10000, 0, 0}, {"lbk3", lbk3_hash, 0x100, 0, 0},
{"m7m", m7m_hash, 0x10000, 0, 0}, {"lbry", lbry_hash, 0x100, 0, 0},
{"veltor", veltor_hash, 1, 0, 0}, {"luffa", luffa_hash, 1, 0, 0},
{"velvet", velvet_hash, 0x10000, 0, 0}, {"penta", penta_hash, 1, 0, 0},
{"argon2", argon2a_hash, 0x10000, 0, sha256_hash_hex }, {"rainforest", rainforest_hash, 0x100, 0, 0},
{"argon2d-dyn", argon2d_dyn_hash, 0x10000, 0, 0 }, // Dynamic Argon2d Implementation {"skein2", skein2_hash, 1, 0, 0},
{"vitalium", vitalium_hash, 1, 0, 0}, {"yescrypt", yescrypt_hash, 0x10000, 0, 0},
{"aergo", aergo_hash, 1, 0, 0}, {"yescryptR16", yescryptR16_hash, 0x10000, 0, 0 },
{"yescryptR32", yescryptR32_hash, 0x10000, 0, 0 },
{"zr5", zr5_hash, 1, 0, 0},
{"sha256t", sha256t_hash, 1, 0, 0}, // sha256 3x {"a5a", a5a_hash, 0x10000, 0, 0},
{"hive", hive_hash, 0x10000, 0, 0},
{"m7m", m7m_hash, 0x10000, 0, 0},
{"veltor", veltor_hash, 1, 0, 0},
{"velvet", velvet_hash, 0x10000, 0, 0},
{"argon2", argon2a_hash, 0x10000, 0, sha256_hash_hex },
{"argon2d-dyn", argon2d_dyn_hash, 0x10000, 0, 0 }, // Dynamic Argon2d Implementation
{"vitalium", vitalium_hash, 1, 0, 0},
{"aergo", aergo_hash, 1, 0, 0},
{"sha256q", sha256q_hash, 1, 0, 0}, // sha256 4x {"sha256t", sha256t_hash, 1, 0, 0}, // sha256 3x
{"sib", sib_hash, 1, 0, 0}, {"sha256q", sha256q_hash, 1, 0, 0}, // sha256 4x
{"whirlcoin", whirlpool_hash, 1, 0, sha256_hash_hex }, /* old sha merkleroot */ {"sib", sib_hash, 1, 0, 0},
{"whirlpool", whirlpool_hash, 1, 0 }, /* sha256d merkleroot */
{"whirlpoolx", whirlpoolx_hash, 1, 0, 0},
{"", NULL, 0, 0}, {"whirlcoin", whirlpool_hash, 1, 0, sha256_hash_hex }, /* old sha merkleroot */
{"whirlpool", whirlpool_hash, 1, 0 }, /* sha256d merkleroot */
{"whirlpoolx", whirlpoolx_hash, 1, 0, 0},
{"", NULL, 0, 0},
}; };
YAAMP_ALGO *g_current_algo = NULL; YAAMP_ALGO *g_current_algo = NULL;
YAAMP_ALGO *stratum_find_algo(const char *name) YAAMP_ALGO *stratum_find_algo(const char *name)
{ {
for(int i=0; g_algos[i].name[0]; i++) for(int i=0; g_algos[i].name[0]; i++)
if(!strcmp(name, g_algos[i].name)) if(!strcmp(name, g_algos[i].name))
return &g_algos[i]; return &g_algos[i];
return NULL; return NULL;
} }
//////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////
int main(int argc, char **argv) int main(int argc, char **argv)
{ {
if(argc < 2) if(argc < 2)
{ {
printf("usage: %s <algo>\n", argv[0]); printf("usage: %s <algo>\n", argv[0]);
return 1; return 1;
} }
srand(time(NULL)); srand(time(NULL));
getifaddrs(&g_ifaddr); getifaddrs(&g_ifaddr);
initlog(argv[1]); initlog(argv[1]);
#ifdef NO_EXCHANGE #ifdef NO_EXCHANGE
// todo: init with a db setting or a yiimp shell command // todo: init with a db setting or a yiimp shell command
g_autoexchange = false; g_autoexchange = false;
#endif #endif
char configfile[1024]; char configfile[1024];
sprintf(configfile, "%s.conf", argv[1]); sprintf(configfile, "%s.conf", argv[1]);
dictionary *ini = iniparser_load(configfile); dictionary *ini = iniparser_load(configfile);
if(!ini) if(!ini)
{ {
debuglog("cant load config file %s\n", configfile); debuglog("cant load config file %s\n", configfile);
return 1; return 1;
} }
g_tcp_port = iniparser_getint(ini, "TCP:port", 3333); g_tcp_port = iniparser_getint(ini, "TCP:port", 3333);
strcpy(g_tcp_server, iniparser_getstring(ini, "TCP:server", NULL)); strcpy(g_tcp_server, iniparser_getstring(ini, "TCP:server", NULL));
strcpy(g_tcp_password, iniparser_getstring(ini, "TCP:password", NULL)); strcpy(g_tcp_password, iniparser_getstring(ini, "TCP:password", NULL));
strcpy(g_sql_host, iniparser_getstring(ini, "SQL:host", NULL)); strcpy(g_sql_host, iniparser_getstring(ini, "SQL:host", NULL));
strcpy(g_sql_database, iniparser_getstring(ini, "SQL:database", NULL)); strcpy(g_sql_database, iniparser_getstring(ini, "SQL:database", NULL));
strcpy(g_sql_username, iniparser_getstring(ini, "SQL:username", NULL)); strcpy(g_sql_username, iniparser_getstring(ini, "SQL:username", NULL));
strcpy(g_sql_password, iniparser_getstring(ini, "SQL:password", NULL)); strcpy(g_sql_password, iniparser_getstring(ini, "SQL:password", NULL));
g_sql_port = iniparser_getint(ini, "SQL:port", 3306); g_sql_port = iniparser_getint(ini, "SQL:port", 3306);
// optional coin filters (to mine only one on a special port or a test instance) // optional coin filters (to mine only one on a special port or a test instance)
char *coin_filter = iniparser_getstring(ini, "WALLETS:include", NULL); char *coin_filter = iniparser_getstring(ini, "WALLETS:include", NULL);
strcpy(g_stratum_coin_include, coin_filter ? coin_filter : ""); strcpy(g_stratum_coin_include, coin_filter ? coin_filter : "");
coin_filter = iniparser_getstring(ini, "WALLETS:exclude", NULL); coin_filter = iniparser_getstring(ini, "WALLETS:exclude", NULL);
strcpy(g_stratum_coin_exclude, coin_filter ? coin_filter : ""); strcpy(g_stratum_coin_exclude, coin_filter ? coin_filter : "");
strcpy(g_stratum_algo, iniparser_getstring(ini, "STRATUM:algo", NULL)); strcpy(g_stratum_algo, iniparser_getstring(ini, "STRATUM:algo", NULL));
g_stratum_difficulty = iniparser_getdouble(ini, "STRATUM:difficulty", 16); g_stratum_difficulty = iniparser_getdouble(ini, "STRATUM:difficulty", 16);
g_stratum_min_diff = iniparser_getdouble(ini, "STRATUM:diff_min", g_stratum_difficulty/2); g_stratum_min_diff = iniparser_getdouble(ini, "STRATUM:diff_min", g_stratum_difficulty/2);
g_stratum_max_diff = iniparser_getdouble(ini, "STRATUM:diff_max", g_stratum_difficulty*8192); g_stratum_max_diff = iniparser_getdouble(ini, "STRATUM:diff_max", g_stratum_difficulty*8192);
g_stratum_max_cons = iniparser_getint(ini, "STRATUM:max_cons", 5000); g_stratum_max_cons = iniparser_getint(ini, "STRATUM:max_cons", 5000);
g_stratum_max_ttf = iniparser_getint(ini, "STRATUM:max_ttf", 0x70000000); g_stratum_max_ttf = iniparser_getint(ini, "STRATUM:max_ttf", 0x70000000);
g_stratum_reconnect = iniparser_getint(ini, "STRATUM:reconnect", true); g_stratum_reconnect = iniparser_getint(ini, "STRATUM:reconnect", true);
g_stratum_renting = iniparser_getint(ini, "STRATUM:renting", true); g_stratum_renting = iniparser_getint(ini, "STRATUM:renting", true);
g_handle_haproxy_ips = iniparser_getint(ini, "STRATUM:haproxy_ips", g_handle_haproxy_ips); g_handle_haproxy_ips = iniparser_getint(ini, "STRATUM:haproxy_ips", g_handle_haproxy_ips);
g_socket_recv_timeout = iniparser_getint(ini, "STRATUM:recv_timeout", 600); g_socket_recv_timeout = iniparser_getint(ini, "STRATUM:recv_timeout", 600);
g_max_shares = iniparser_getint(ini, "STRATUM:max_shares", g_max_shares); g_max_shares = iniparser_getint(ini, "STRATUM:max_shares", g_max_shares);
g_limit_txs_per_block = iniparser_getint(ini, "STRATUM:max_txs_per_block", 0); g_limit_txs_per_block = iniparser_getint(ini, "STRATUM:max_txs_per_block", 0);
g_debuglog_client = iniparser_getint(ini, "DEBUGLOG:client", false); g_debuglog_client = iniparser_getint(ini, "DEBUGLOG:client", false);
g_debuglog_hash = iniparser_getint(ini, "DEBUGLOG:hash", false); g_debuglog_hash = iniparser_getint(ini, "DEBUGLOG:hash", false);
g_debuglog_socket = iniparser_getint(ini, "DEBUGLOG:socket", false); g_debuglog_socket = iniparser_getint(ini, "DEBUGLOG:socket", false);
g_debuglog_rpc = iniparser_getint(ini, "DEBUGLOG:rpc", false); g_debuglog_rpc = iniparser_getint(ini, "DEBUGLOG:rpc", false);
g_debuglog_list = iniparser_getint(ini, "DEBUGLOG:list", false); g_debuglog_list = iniparser_getint(ini, "DEBUGLOG:list", false);
g_debuglog_remote = iniparser_getint(ini, "DEBUGLOG:remote", false); g_debuglog_remote = iniparser_getint(ini, "DEBUGLOG:remote", false);
iniparser_freedict(ini); iniparser_freedict(ini);
g_current_algo = stratum_find_algo(g_stratum_algo); g_current_algo = stratum_find_algo(g_stratum_algo);
if(!g_current_algo) yaamp_error("invalid algo"); if(!g_current_algo) yaamp_error("invalid algo");
if(!g_current_algo->hash_function) yaamp_error("no hash function"); if(!g_current_algo->hash_function) yaamp_error("no hash function");
// struct rlimit rlim_files = {0x10000, 0x10000}; // struct rlimit rlim_files = {0x10000, 0x10000};
// setrlimit(RLIMIT_NOFILE, &rlim_files); // setrlimit(RLIMIT_NOFILE, &rlim_files);
struct rlimit rlim_threads = {0x8000, 0x8000}; struct rlimit rlim_threads = {0x8000, 0x8000};
setrlimit(RLIMIT_NPROC, &rlim_threads); setrlimit(RLIMIT_NPROC, &rlim_threads);
stratumlogdate("starting stratum for %s on %s:%d\n", stratumlogdate("starting stratum for %s on %s:%d\n",
g_current_algo->name, g_tcp_server, g_tcp_port); g_current_algo->name, g_tcp_server, g_tcp_port);
// ntime should not be changed by miners for these algos // ntime should not be changed by miners for these algos
g_allow_rolltime = strcmp(g_stratum_algo,"x11evo"); g_allow_rolltime = strcmp(g_stratum_algo,"x11evo");
g_allow_rolltime = g_allow_rolltime && strcmp(g_stratum_algo,"timetravel"); g_allow_rolltime = g_allow_rolltime && strcmp(g_stratum_algo,"timetravel");
g_allow_rolltime = g_allow_rolltime && strcmp(g_stratum_algo,"bitcore"); g_allow_rolltime = g_allow_rolltime && strcmp(g_stratum_algo,"bitcore");
g_allow_rolltime = g_allow_rolltime && strcmp(g_stratum_algo,"exosis"); g_allow_rolltime = g_allow_rolltime && strcmp(g_stratum_algo,"exosis");
if (!g_allow_rolltime) if (!g_allow_rolltime)
stratumlog("note: time roll disallowed for %s algo\n", g_current_algo->name); stratumlog("note: time roll disallowed for %s algo\n", g_current_algo->name);
g_db = db_connect(); g_db = db_connect();
if(!g_db) yaamp_error("Cant connect database"); if(!g_db) yaamp_error("Cant connect database");
// db_query(g_db, "update mining set stratumids='loading'"); // db_query(g_db, "update mining set stratumids='loading'");
yaamp_create_mutex(&g_db_mutex); yaamp_create_mutex(&g_db_mutex);
yaamp_create_mutex(&g_nonce1_mutex); yaamp_create_mutex(&g_nonce1_mutex);
yaamp_create_mutex(&g_job_create_mutex); yaamp_create_mutex(&g_job_create_mutex);
YAAMP_DB *db = db_connect(); YAAMP_DB *db = db_connect();
if(!db) yaamp_error("Cant connect database"); if(!db) yaamp_error("Cant connect database");
db_register_stratum(db); db_register_stratum(db);
db_update_algos(db); db_update_algos(db);
db_update_coinds(db); db_update_coinds(db);
sleep(2); sleep(2);
job_init(); job_init();
// job_signal(); // job_signal();
//////////////////////////////////////////////// ////////////////////////////////////////////////
pthread_t thread1; pthread_t thread1;
pthread_create(&thread1, NULL, monitor_thread, NULL); pthread_create(&thread1, NULL, monitor_thread, NULL);
pthread_t thread2; pthread_t thread2;
pthread_create(&thread2, NULL, stratum_thread, NULL); pthread_create(&thread2, NULL, stratum_thread, NULL);
sleep(20); sleep(20);
while(!g_exiting) while(!g_exiting)
{ {
db_register_stratum(db); db_register_stratum(db);
db_update_workers(db); db_update_workers(db);
db_update_algos(db); db_update_algos(db);
db_update_coinds(db); db_update_coinds(db);
if(g_stratum_renting) if(g_stratum_renting)
{ {
db_update_renters(db); db_update_renters(db);
db_update_remotes(db); db_update_remotes(db);
} }
share_write(db); share_write(db);
share_prune(db); share_prune(db);
block_prune(db); block_prune(db);
submit_prune(db); submit_prune(db);
sleep(1); sleep(1);
job_signal(); job_signal();
//////////////////////////////////// ////////////////////////////////////
// source_prune(); // source_prune();
object_prune(&g_list_coind, coind_delete); object_prune(&g_list_coind, coind_delete);
object_prune(&g_list_remote, remote_delete); object_prune(&g_list_remote, remote_delete);
object_prune(&g_list_job, job_delete); object_prune(&g_list_job, job_delete);
object_prune(&g_list_client, client_delete); object_prune(&g_list_client, client_delete);
object_prune(&g_list_block, block_delete); object_prune(&g_list_block, block_delete);
object_prune(&g_list_worker, worker_delete); object_prune(&g_list_worker, worker_delete);
object_prune(&g_list_share, share_delete); object_prune(&g_list_share, share_delete);
object_prune(&g_list_submit, submit_delete); object_prune(&g_list_submit, submit_delete);
if (!g_exiting) sleep(20); if (!g_exiting) sleep(20);
} }
stratumlog("closing database...\n"); stratumlog("closing database...\n");
db_close(db); db_close(db);
pthread_join(thread2, NULL); pthread_join(thread2, NULL);
db_close(g_db); // client threads (called by stratum one) db_close(g_db); // client threads (called by stratum one)
closelogs(); closelogs();
return 0; return 0;
} }
/////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////
void *monitor_thread(void *p) void *monitor_thread(void *p)
{ {
while(!g_exiting) while(!g_exiting)
{ {
sleep(120); sleep(120);
if(g_last_broadcasted + YAAMP_MAXJOBDELAY < time(NULL)) if(g_last_broadcasted + YAAMP_MAXJOBDELAY < time(NULL))
{ {
g_exiting = true; g_exiting = true;
stratumlogdate("%s dead lock, exiting...\n", g_stratum_algo); stratumlogdate("%s dead lock, exiting...\n", g_stratum_algo);
exit(1); exit(1);
} }
if(g_max_shares && g_shares_counter) { if(g_max_shares && g_shares_counter) {
if((g_shares_counter - g_shares_log) > 10000) { if((g_shares_counter - g_shares_log) > 10000) {
stratumlogdate("%s %luK shares...\n", g_stratum_algo, (g_shares_counter/1000u)); stratumlogdate("%s %luK shares...\n", g_stratum_algo, (g_shares_counter/1000u));
g_shares_log = g_shares_counter; g_shares_log = g_shares_counter;
} }
if(g_shares_counter > g_max_shares) { if(g_shares_counter > g_max_shares) {
g_exiting = true; g_exiting = true;
stratumlogdate("%s need a restart (%lu shares), exiting...\n", g_stratum_algo, (unsigned long) g_max_shares); stratumlogdate("%s need a restart (%lu shares), exiting...\n", g_stratum_algo, (unsigned long) g_max_shares);
exit(1); exit(1);
} }
} }
} }
} }
/////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////
void *stratum_thread(void *p) void *stratum_thread(void *p)
{ {
int listen_sock = socket(AF_INET, SOCK_STREAM, 0); int listen_sock = socket(AF_INET, SOCK_STREAM, 0);
if(listen_sock <= 0) yaamp_error("socket"); if(listen_sock <= 0) yaamp_error("socket");
int optval = 1; int optval = 1;
setsockopt(listen_sock, SOL_SOCKET, SO_REUSEADDR, &optval, sizeof optval); setsockopt(listen_sock, SOL_SOCKET, SO_REUSEADDR, &optval, sizeof optval);
struct sockaddr_in serv; struct sockaddr_in serv;
serv.sin_family = AF_INET; serv.sin_family = AF_INET;
serv.sin_addr.s_addr = htonl(INADDR_ANY); serv.sin_addr.s_addr = htonl(INADDR_ANY);
serv.sin_port = htons(g_tcp_port); serv.sin_port = htons(g_tcp_port);
int res = bind(listen_sock, (struct sockaddr*)&serv, sizeof(serv)); int res = bind(listen_sock, (struct sockaddr*)&serv, sizeof(serv));
if(res < 0) yaamp_error("bind"); if(res < 0) yaamp_error("bind");
res = listen(listen_sock, 4096); res = listen(listen_sock, 4096);
if(res < 0) yaamp_error("listen"); if(res < 0) yaamp_error("listen");
///////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////
int failcount = 0; int failcount = 0;
while(!g_exiting) while(!g_exiting)
{ {
int sock = accept(listen_sock, NULL, NULL); int sock = accept(listen_sock, NULL, NULL);
if(sock <= 0) if(sock <= 0)
{ {
int error = errno; int error = errno;
stratumlog("%s socket accept() error %d\n", g_stratum_algo, error); stratumlog("%s socket accept() error %d\n", g_stratum_algo, error);
failcount++; failcount++;
usleep(50000); usleep(50000);
if (error == 24 && failcount > 5) { if (error == 24 && failcount > 5) {
g_exiting = true; // happen when max open files is reached (see ulimit) g_exiting = true; // happen when max open files is reached (see ulimit)
stratumlogdate("%s too much socket failure, exiting...\n", g_stratum_algo); stratumlogdate("%s too much socket failure, exiting...\n", g_stratum_algo);
exit(error); exit(error);
} }
continue; continue;
} }
failcount = 0; failcount = 0;
pthread_t thread; pthread_t thread;
int res = pthread_create(&thread, NULL, client_thread, (void *)(long)sock); int res = pthread_create(&thread, NULL, client_thread, (void *)(long)sock);
if(res != 0) if(res != 0)
{ {
int error = errno; int error = errno;
close(sock); close(sock);
g_exiting = true; g_exiting = true;
stratumlog("%s pthread_create error %d %d\n", g_stratum_algo, res, error); stratumlog("%s pthread_create error %d %d\n", g_stratum_algo, res, error);
} }
pthread_detach(thread); pthread_detach(thread);
} }
} }