Advertisement
rasyaparsaoran

Github: cpu miner minergate.com

Nov 1st, 2017
474
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 58.39 KB | None | 0 0
  1. #include "cpuminer-config.h"
  2. #define _GNU_SOURCE
  3.  
  4. #include <stdio.h>
  5. #include <stdlib.h>
  6. #include <string.h>
  7. #include <stdbool.h>
  8. #include <inttypes.h>
  9. #include <unistd.h>
  10. #include <sys/time.h>
  11. #include <time.h>
  12. #ifdef WIN32
  13. #include <windows.h>
  14. #else
  15. #include <errno.h>
  16. #include <signal.h>
  17. #include <sys/resource.h>
  18. #if HAVE_SYS_SYSCTL_H
  19. #include <sys/types.h>
  20. #if HAVE_SYS_PARAM_H
  21. #include <sys/param.h>
  22. #endif
  23. #include <sys/sysctl.h>
  24. #endif
  25. #endif
  26. #include <jansson.h>
  27. #include <curl/curl.h>
  28. #ifndef USE_LOBOTOMIZED_AES
  29. #include <cpuid.h>
  30. #endif
  31. #include "compat.h"
  32. #include "miner.h"
  33. #include "cryptonight.h"
  34.  
  35. #if defined __unix__ && (!defined __APPLE__) && (!defined DISABLE_LINUX_HUGEPAGES)
  36. #include <sys/mman.h>
  37. #elif defined _WIN32
  38. #include <windows.h>
  39. #endif
  40.  
  41. #define PROGRAM_NAME "minerd"
  42. #define LP_SCANTIME 60
  43. #define JSON_BUF_LEN 345
  44.  
  45. #ifdef __unix__
  46. #include <sys/mman.h>
  47. #endif
  48.  
  49. #ifdef __linux /* Linux specific policy and affinity management */
  50. #include <sched.h>
  51. static inline void drop_policy(void) {
  52. struct sched_param param;
  53. param.sched_priority = 0;
  54.  
  55. sched_setscheduler(0, SCHED_OTHER, &param);
  56. }
  57.  
  58. static inline void affine_to_cpu(int id, int cpu) {
  59. cpu_set_t set;
  60.  
  61. CPU_ZERO(&set);
  62. CPU_SET(cpu, &set);
  63. sched_setaffinity(0, sizeof(set), &set);
  64. }
  65. #elif defined(__FreeBSD__) /* FreeBSD specific policy and affinity management */
  66. #include <sys/cpuset.h>
  67. static inline void drop_policy(void)
  68. {
  69. }
  70.  
  71. static inline void affine_to_cpu(int id, int cpu)
  72. {
  73. cpuset_t set;
  74. CPU_ZERO(&set);
  75. CPU_SET(cpu, &set);
  76. cpuset_setaffinity(CPU_LEVEL_WHICH, CPU_WHICH_TID, -1, sizeof(cpuset_t), &set);
  77. }
  78. #else
  79. static inline void drop_policy(void)
  80. {
  81. }
  82.  
  83. static inline void affine_to_cpu(int id, int cpu)
  84. {
  85. }
  86. #endif
  87.  
  88. #define MAX_THREADS 256
  89.  
  90. enum workio_commands {
  91. WC_GET_WORK, WC_SUBMIT_WORK,
  92. };
  93.  
  94. struct workio_cmd {
  95. enum workio_commands cmd;
  96. struct thr_info *thr;
  97. union {
  98. struct work *work;
  99. } u;
  100. };
  101.  
  102. enum mining_algo {
  103. ALGO_SCRYPT, /* scrypt(1024,1,1) */
  104. ALGO_SHA256D, /* SHA-256d */
  105. ALGO_KECCAK, /* Keccak */
  106. ALGO_HEAVY, /* Heavy */
  107. ALGO_QUARK, /* Quark */
  108. ALGO_SKEIN, /* Skein */
  109. ALGO_SHAVITE3, /* Shavite3 */
  110. ALGO_BLAKE, /* Blake */
  111. ALGO_X11, /* X11 */
  112. ALGO_CRYPTONIGHT, /* CryptoNight */
  113. };
  114.  
  115. static const char *algo_names[] = {
  116. [ALGO_SCRYPT] = "scrypt",
  117. [ALGO_SHA256D] = "sha256d",
  118. [ALGO_KECCAK] = "keccak",
  119. [ALGO_HEAVY] = "heavy",
  120. [ALGO_QUARK] = "quark",
  121. [ALGO_SKEIN] = "skein",
  122. [ALGO_SHAVITE3] = "shavite3",
  123. [ALGO_BLAKE] = "blake",
  124. [ALGO_X11] = "x11",
  125. [ALGO_CRYPTONIGHT] = "cryptonight",
  126. };
  127.  
  128. bool opt_debug = false;
  129. bool opt_protocol = false;
  130. static bool opt_benchmark = false;
  131. bool opt_redirect = true;
  132. bool want_longpoll = true;
  133. bool have_longpoll = false;
  134. bool want_stratum = true;
  135. bool have_stratum = false;
  136. static bool submit_old = false;
  137. bool use_syslog = false;
  138. static bool opt_background = false;
  139. static bool opt_quiet = false;
  140. static int opt_retries = -1;
  141. static int opt_fail_pause = 10;
  142. bool jsonrpc_2 = false;
  143. int opt_timeout = 0;
  144. static int opt_scantime = 5;
  145. static json_t *opt_config;
  146. static const bool opt_time = true;
  147. static enum mining_algo opt_algo = ALGO_CRYPTONIGHT;
  148. static int opt_n_threads;
  149. static int num_processors;
  150. static char *rpc_url;
  151. static char *rpc_userpass;
  152. static char *rpc_user, *rpc_pass;
  153. char *opt_cert;
  154. char *opt_proxy;
  155. long opt_proxy_type;
  156. struct thr_info *thr_info;
  157. static int work_thr_id;
  158. int longpoll_thr_id = -1;
  159. int stratum_thr_id = -1;
  160. struct work_restart *work_restart = NULL;
  161. static struct stratum_ctx stratum;
  162. static char rpc2_id[64] = "";
  163. static char *rpc2_blob = NULL;
  164. static int rpc2_bloblen = 0;
  165. static uint32_t rpc2_target = 0;
  166. static char *rpc2_job_id = NULL;
  167.  
  168. pthread_mutex_t applog_lock;
  169. static pthread_mutex_t stats_lock;
  170. static pthread_mutex_t rpc2_job_lock;
  171. static pthread_mutex_t rpc2_login_lock;
  172.  
  173. static unsigned long accepted_count = 0L;
  174. static unsigned long rejected_count = 0L;
  175. static double *thr_hashrates;
  176. static double *thr_times;
  177.  
  178. #ifdef HAVE_GETOPT_LONG
  179. #include <getopt.h>
  180. #else
  181. struct option {
  182. const char *name;
  183. int has_arg;
  184. int *flag;
  185. int val;
  186. };
  187. #endif
  188.  
  189. static char const usage[] =
  190. "\
  191. Usage: " PROGRAM_NAME " [OPTIONS]\n\
  192. Options:\n\
  193. -o, --url=URL URL of mining server\n\
  194. -O, --userpass=U:P username:password pair for mining server\n\
  195. -u, --user=USERNAME username for mining server\n\
  196. -p, --pass=PASSWORD password for mining server\n\
  197. --cert=FILE certificate for mining server using SSL\n\
  198. -x, --proxy=[PROTOCOL://]HOST[:PORT] connect through a proxy\n\
  199. -t, --threads=N number of miner threads (default: number of processors)\n\
  200. -r, --retries=N number of times to retry if a network call fails\n\
  201. (default: retry indefinitely)\n\
  202. -R, --retry-pause=N time to pause between retries, in seconds (default: 30)\n\
  203. -T, --timeout=N timeout for long polling, in seconds (default: none)\n\
  204. -s, --scantime=N upper bound on time spent scanning current work when\n\
  205. long polling is unavailable, in seconds (default: 5)\n\
  206. --no-longpoll disable X-Long-Polling support\n\
  207. --no-stratum disable X-Stratum support\n\
  208. --no-redirect ignore requests to change the URL of the mining server\n\
  209. -q, --quiet disable per-thread hashmeter output\n\
  210. -D, --debug enable debug output\n\
  211. -P, --protocol-dump verbose dump of protocol-level activities\n"
  212. #ifdef HAVE_SYSLOG_H
  213. "\
  214. -S, --syslog use system log for output messages\n"
  215. #endif
  216. #ifndef WIN32
  217. "\
  218. -B, --background run the miner in the background\n"
  219. #endif
  220. "\
  221. --benchmark run in offline benchmark mode\n\
  222. -c, --config=FILE load a JSON-format configuration file\n\
  223. -V, --version display version information and exit\n\
  224. -h, --help display this help text and exit\n\
  225. ";
  226.  
  227. static char const short_options[] =
  228. #ifndef WIN32
  229. "B"
  230. #endif
  231. #ifdef HAVE_SYSLOG_H
  232. "S"
  233. #endif
  234. "a:c:Dhp:Px:qr:R:s:t:T:o:u:O:V";
  235.  
  236. static struct option const options[] = {
  237. { "algo", 1, NULL, 'a' },
  238. #ifndef WIN32
  239. { "background", 0, NULL, 'B' },
  240. #endif
  241. { "benchmark", 0, NULL, 1005 },
  242. { "cert", 1, NULL, 1001 },
  243. { "config", 1, NULL, 'c' },
  244. { "debug", 0, NULL, 'D' },
  245. { "help", 0, NULL, 'h' },
  246. { "no-longpoll", 0, NULL, 1003 },
  247. { "no-redirect", 0, NULL, 1009 },
  248. { "no-stratum", 0, NULL, 1007 },
  249. { "pass", 1, NULL, 'p' },
  250. { "protocol-dump", 0, NULL, 'P' },
  251. { "proxy", 1, NULL, 'x' },
  252. { "quiet", 0, NULL, 'q' },
  253. { "retries", 1, NULL, 'r' },
  254. { "retry-pause", 1, NULL, 'R' },
  255. { "scantime", 1, NULL, 's' },
  256. #ifdef HAVE_SYSLOG_H
  257. { "syslog", 0, NULL, 'S' },
  258. #endif
  259. { "threads", 1, NULL, 't' },
  260. { "timeout", 1, NULL, 'T' },
  261. { "url", 1, NULL, 'o' },
  262. { "user", 1, NULL, 'u' },
  263. { "userpass", 1, NULL, 'O' },
  264. { "version", 0, NULL, 'V' },
  265. { 0, 0, 0, 0 }
  266. };
  267.  
  268. static struct work g_work;
  269. static time_t g_work_time;
  270. static pthread_mutex_t g_work_lock;
  271.  
  272. static bool rpc2_login(CURL *curl);
  273. static void workio_cmd_free(struct workio_cmd *wc);
  274.  
  275. json_t *json_rpc2_call_recur(CURL *curl, const char *url,
  276. const char *userpass, json_t *rpc_req,
  277. int *curl_err, int flags, int recur) {
  278. if(recur >= 5) {
  279. if(opt_debug)
  280. applog(LOG_DEBUG, "Failed to call rpc command after %i tries", recur);
  281. return NULL;
  282. }
  283. if(!strcmp(rpc2_id, "")) {
  284. if(opt_debug)
  285. applog(LOG_DEBUG, "Tried to call rpc2 command before authentication");
  286. return NULL;
  287. }
  288. json_t *params = json_object_get(rpc_req, "params");
  289. if (params) {
  290. json_t *auth_id = json_object_get(params, "id");
  291. if (auth_id) {
  292. json_string_set(auth_id, rpc2_id);
  293. }
  294. }
  295. json_t *res = json_rpc_call(curl, url, userpass, json_dumps(rpc_req, 0),
  296. curl_err, flags | JSON_RPC_IGNOREERR);
  297. if(!res) goto end;
  298. json_t *error = json_object_get(res, "error");
  299. if(!error) goto end;
  300. json_t *message;
  301. if(json_is_string(error))
  302. message = error;
  303. else
  304. message = json_object_get(error, "message");
  305. if(!message || !json_is_string(message)) goto end;
  306. const char *mes = json_string_value(message);
  307. if(!strcmp(mes, "Unauthenticated")) {
  308. pthread_mutex_lock(&rpc2_login_lock);
  309. rpc2_login(curl);
  310. sleep(1);
  311. pthread_mutex_unlock(&rpc2_login_lock);
  312. return json_rpc2_call_recur(curl, url, userpass, rpc_req,
  313. curl_err, flags, recur + 1);
  314. } else if(!strcmp(mes, "Low difficulty share") || !strcmp(mes, "Block expired") || !strcmp(mes, "Invalid job id") || !strcmp(mes, "Duplicate share")) {
  315. json_t *result = json_object_get(res, "result");
  316. if(!result) {
  317. goto end;
  318. }
  319. json_object_set(result, "reject-reason", json_string(mes));
  320. } else {
  321. applog(LOG_ERR, "json_rpc2.0 error: %s", mes);
  322. return NULL;
  323. }
  324. end:
  325. return res;
  326. }
  327.  
  328. json_t *json_rpc2_call(CURL *curl, const char *url,
  329. const char *userpass, const char *rpc_req,
  330. int *curl_err, int flags) {
  331. return json_rpc2_call_recur(curl, url, userpass, JSON_LOADS(rpc_req, NULL),
  332. curl_err, flags, 0);
  333. }
  334.  
  335. static inline void work_free(struct work *w) {
  336. free(w->job_id);
  337. free(w->xnonce2);
  338. }
  339.  
  340. static inline void work_copy(struct work *dest, const struct work *src) {
  341. memcpy(dest, src, sizeof(struct work));
  342. if (src->job_id)
  343. dest->job_id = strdup(src->job_id);
  344. if (src->xnonce2) {
  345. dest->xnonce2 = malloc(src->xnonce2_len);
  346. memcpy(dest->xnonce2, src->xnonce2, src->xnonce2_len);
  347. }
  348. }
  349.  
  350. static bool jobj_binary(const json_t *obj, const char *key, void *buf,
  351. size_t buflen) {
  352. const char *hexstr;
  353. json_t *tmp;
  354.  
  355. tmp = json_object_get(obj, key);
  356. if (unlikely(!tmp)) {
  357. applog(LOG_ERR, "JSON key '%s' not found", key);
  358. return false;
  359. }
  360. hexstr = json_string_value(tmp);
  361. if (unlikely(!hexstr)) {
  362. applog(LOG_ERR, "JSON key '%s' is not a string", key);
  363. return false;
  364. }
  365. if (!hex2bin(buf, hexstr, buflen))
  366. return false;
  367.  
  368. return true;
  369. }
  370.  
  371. bool rpc2_job_decode(const json_t *job, struct work *work) {
  372. if (!jsonrpc_2) {
  373. applog(LOG_ERR, "Tried to decode job without JSON-RPC 2.0");
  374. return false;
  375. }
  376. json_t *tmp;
  377. tmp = json_object_get(job, "job_id");
  378. if (!tmp) {
  379. applog(LOG_ERR, "JSON inval job id");
  380. goto err_out;
  381. }
  382. const char *job_id = json_string_value(tmp);
  383. tmp = json_object_get(job, "blob");
  384. if (!tmp) {
  385. applog(LOG_ERR, "JSON inval blob");
  386. goto err_out;
  387. }
  388. const char *hexblob = json_string_value(tmp);
  389. int blobLen = strlen(hexblob);
  390. if (blobLen % 2 != 0 || ((blobLen / 2) < 40 && blobLen != 0) || (blobLen / 2) > 128) {
  391. applog(LOG_ERR, "JSON invalid blob length");
  392. goto err_out;
  393. }
  394. if (blobLen != 0) {
  395. pthread_mutex_lock(&rpc2_job_lock);
  396. char *blob = malloc(blobLen / 2);
  397. if (!hex2bin(blob, hexblob, blobLen / 2)) {
  398. applog(LOG_ERR, "JSON inval blob");
  399. pthread_mutex_unlock(&rpc2_job_lock);
  400. goto err_out;
  401. }
  402. if (rpc2_blob) {
  403. free(rpc2_blob);
  404. }
  405. rpc2_bloblen = blobLen / 2;
  406. rpc2_blob = malloc(rpc2_bloblen);
  407. memcpy(rpc2_blob, blob, blobLen / 2);
  408.  
  409. free(blob);
  410.  
  411. uint32_t target;
  412. jobj_binary(job, "target", &target, 4);
  413. if(rpc2_target != target) {
  414. float hashrate = 0.;
  415. pthread_mutex_lock(&stats_lock);
  416. for (size_t i = 0; i < opt_n_threads; i++)
  417. hashrate += thr_hashrates[i] / thr_times[i];
  418. pthread_mutex_unlock(&stats_lock);
  419. double difficulty = (((double) 0xffffffff) / target);
  420. applog(LOG_INFO, "Pool set diff to %g", difficulty);
  421. rpc2_target = target;
  422. }
  423.  
  424. if (rpc2_job_id) {
  425. free(rpc2_job_id);
  426. }
  427. rpc2_job_id = strdup(job_id);
  428. pthread_mutex_unlock(&rpc2_job_lock);
  429. }
  430. if(work) {
  431. if (!rpc2_blob) {
  432. applog(LOG_ERR, "Requested work before work was received");
  433. goto err_out;
  434. }
  435. memcpy(work->data, rpc2_blob, rpc2_bloblen);
  436. memset(work->target, 0xff, sizeof(work->target));
  437. work->target[7] = rpc2_target;
  438. if (work->job_id)
  439. free(work->job_id);
  440. work->job_id = strdup(rpc2_job_id);
  441. }
  442. return true;
  443.  
  444. err_out:
  445. return false;
  446. }
  447.  
  448. static bool work_decode(const json_t *val, struct work *work) {
  449. int i;
  450.  
  451. if(jsonrpc_2) {
  452. return rpc2_job_decode(val, work);
  453. }
  454.  
  455. if (unlikely(!jobj_binary(val, "data", work->data, sizeof(work->data)))) {
  456. applog(LOG_ERR, "JSON inval data");
  457. goto err_out;
  458. }
  459. if (unlikely(!jobj_binary(val, "target", work->target, sizeof(work->target)))) {
  460. applog(LOG_ERR, "JSON inval target");
  461. goto err_out;
  462. }
  463.  
  464. for (i = 0; i < ARRAY_SIZE(work->data); i++)
  465. work->data[i] = le32dec(work->data + i);
  466. for (i = 0; i < ARRAY_SIZE(work->target); i++)
  467. work->target[i] = le32dec(work->target + i);
  468.  
  469. return true;
  470.  
  471. err_out: return false;
  472. }
  473.  
  474. bool rpc2_login_decode(const json_t *val) {
  475. const char *id;
  476. const char *s;
  477.  
  478. json_t *res = json_object_get(val, "result");
  479. if(!res) {
  480. applog(LOG_ERR, "JSON invalid result");
  481. goto err_out;
  482. }
  483.  
  484. json_t *tmp;
  485. tmp = json_object_get(res, "id");
  486. if(!tmp) {
  487. applog(LOG_ERR, "JSON inval id");
  488. goto err_out;
  489. }
  490. id = json_string_value(tmp);
  491. if(!id) {
  492. applog(LOG_ERR, "JSON id is not a string");
  493. goto err_out;
  494. }
  495.  
  496. memcpy(&rpc2_id, id, 64);
  497.  
  498. if(opt_debug)
  499. applog(LOG_DEBUG, "Auth id: %s", id);
  500.  
  501. tmp = json_object_get(res, "status");
  502. if(!tmp) {
  503. applog(LOG_ERR, "JSON inval status");
  504. goto err_out;
  505. }
  506. s = json_string_value(tmp);
  507. if(!s) {
  508. applog(LOG_ERR, "JSON status is not a string");
  509. goto err_out;
  510. }
  511. if(strcmp(s, "OK")) {
  512. applog(LOG_ERR, "JSON returned status \"%s\"", s);
  513. return false;
  514. }
  515.  
  516. return true;
  517.  
  518. err_out: return false;
  519. }
  520.  
  521. static void share_result(int result, struct work *work, const char *reason) {
  522. char s[345];
  523. double hashrate;
  524. int i;
  525.  
  526. hashrate = 0.;
  527. pthread_mutex_lock(&stats_lock);
  528. for (i = 0; i < opt_n_threads; i++)
  529. hashrate += thr_hashrates[i] / thr_times[i];
  530. result ? accepted_count++ : rejected_count++;
  531. pthread_mutex_unlock(&stats_lock);
  532.  
  533. switch (opt_algo) {
  534. case ALGO_CRYPTONIGHT:
  535. applog(LOG_INFO, "accepted: %lu/%lu (%.2f%%), %.2f H/s at diff %g %s",
  536. accepted_count, accepted_count + rejected_count,
  537. 100. * accepted_count / (accepted_count + rejected_count), hashrate,
  538. (((double) 0xffffffff) / (work ? work->target[7] : rpc2_target)),
  539. result ? "(yay!!!)" : "(booooo)");
  540. break;
  541. default:
  542. sprintf(s, hashrate >= 1e6 ? "%.0f" : "%.2f", 1e-3 * hashrate);
  543. applog(LOG_INFO, "accepted: %lu/%lu (%.2f%%), %s khash/s %s",
  544. accepted_count, accepted_count + rejected_count,
  545. 100. * accepted_count / (accepted_count + rejected_count), s,
  546. result ? "(yay!!!)" : "(booooo)");
  547. break;
  548. }
  549.  
  550. if (opt_debug && reason)
  551. applog(LOG_DEBUG, "DEBUG: reject reason: %s", reason);
  552. }
  553.  
  554. static bool submit_upstream_work(CURL *curl, struct work *work) {
  555. char *str = NULL;
  556. json_t *val, *res, *reason;
  557. char s[JSON_BUF_LEN];
  558. int i;
  559. bool rc = false;
  560.  
  561. /* pass if the previous hash is not the current previous hash */
  562. if (!submit_old && memcmp(work->data + 1, g_work.data + 1, 32)) {
  563. if (opt_debug)
  564. applog(LOG_DEBUG, "DEBUG: stale work detected, discarding");
  565. return true;
  566. }
  567.  
  568. if (have_stratum) {
  569. uint32_t ntime, nonce;
  570. char *ntimestr, *noncestr, *xnonce2str;
  571.  
  572. if (jsonrpc_2) {
  573. noncestr = bin2hex(((const unsigned char*)work->data) + 39, 4);
  574. char hash[32];
  575. switch(opt_algo) {
  576. case ALGO_CRYPTONIGHT:
  577. default:
  578. cryptonight_hash(hash, work->data, 76);
  579. }
  580. char *hashhex = bin2hex(hash, 32);
  581. snprintf(s, JSON_BUF_LEN,
  582. "{\"method\": \"submit\", \"params\": {\"id\": \"%s\", \"job_id\": \"%s\", \"nonce\": \"%s\", \"result\": \"%s\"}, \"id\":1}\r\n",
  583. rpc2_id, work->job_id, noncestr, hashhex);
  584. free(hashhex);
  585. } else {
  586. le32enc(&ntime, work->data[17]);
  587. le32enc(&nonce, work->data[19]);
  588. ntimestr = bin2hex((const unsigned char *) (&ntime), 4);
  589. noncestr = bin2hex((const unsigned char *) (&nonce), 4);
  590. xnonce2str = bin2hex(work->xnonce2, work->xnonce2_len);
  591. snprintf(s, JSON_BUF_LEN,
  592. "{\"method\": \"mining.submit\", \"params\": [\"%s\", \"%s\", \"%s\", \"%s\", \"%s\"], \"id\":4}",
  593. rpc_user, work->job_id, xnonce2str, ntimestr, noncestr);
  594. free(ntimestr);
  595. free(xnonce2str);
  596. }
  597. free(noncestr);
  598.  
  599. if (unlikely(!stratum_send_line(&stratum, s))) {
  600. applog(LOG_ERR, "submit_upstream_work stratum_send_line failed");
  601. goto out;
  602. }
  603. } else {
  604. /* build JSON-RPC request */
  605. if(jsonrpc_2) {
  606. char *noncestr = bin2hex(((const unsigned char*)work->data) + 39, 4);
  607. char hash[32];
  608. switch(opt_algo) {
  609. case ALGO_CRYPTONIGHT:
  610. default:
  611. cryptonight_hash(hash, work->data, 76);
  612. }
  613. char *hashhex = bin2hex(hash, 32);
  614. snprintf(s, JSON_BUF_LEN,
  615. "{\"method\": \"submit\", \"params\": {\"id\": \"%s\", \"job_id\": \"%s\", \"nonce\": \"%s\", \"result\": \"%s\"}, \"id\":1}\r\n",
  616. rpc2_id, work->job_id, noncestr, hashhex);
  617. free(noncestr);
  618. free(hashhex);
  619.  
  620. /* issue JSON-RPC request */
  621. val = json_rpc2_call(curl, rpc_url, rpc_userpass, s, NULL, 0);
  622. if (unlikely(!val)) {
  623. applog(LOG_ERR, "submit_upstream_work json_rpc_call failed");
  624. goto out;
  625. }
  626. res = json_object_get(val, "result");
  627. json_t *status = json_object_get(res, "status");
  628. reason = json_object_get(res, "reject-reason");
  629. share_result(!strcmp(status ? json_string_value(status) : "", "OK"), work,
  630. reason ? json_string_value(reason) : NULL );
  631. } else {
  632. /* build hex string */
  633. for (i = 0; i < 76; i++)
  634. le32enc(((char*)work->data) + i, *((uint32_t*) (((char*)work->data) + i)));
  635. str = bin2hex((unsigned char *) work->data, 76);
  636. if (unlikely(!str)) {
  637. applog(LOG_ERR, "submit_upstream_work OOM");
  638. goto out;
  639. }
  640. snprintf(s, JSON_BUF_LEN,
  641. "{\"method\": \"getwork\", \"params\": [ \"%s\" ], \"id\":1}\r\n",
  642. str);
  643.  
  644. /* issue JSON-RPC request */
  645. val = json_rpc_call(curl, rpc_url, rpc_userpass, s, NULL, 0);
  646. if (unlikely(!val)) {
  647. applog(LOG_ERR, "submit_upstream_work json_rpc_call failed");
  648. goto out;
  649. }
  650. res = json_object_get(val, "result");
  651. reason = json_object_get(val, "reject-reason");
  652. share_result(json_is_true(res), work,
  653. reason ? json_string_value(reason) : NULL );
  654. }
  655.  
  656. json_decref(val);
  657. }
  658.  
  659. rc = true;
  660.  
  661. out: free(str);
  662. return rc;
  663. }
  664.  
  665. static const char *rpc_req =
  666. "{\"method\": \"getwork\", \"params\": [], \"id\":0}\r\n";
  667.  
  668. static bool get_upstream_work(CURL *curl, struct work *work) {
  669. json_t *val;
  670. bool rc;
  671. struct timeval tv_start, tv_end, diff;
  672.  
  673. gettimeofday(&tv_start, NULL );
  674.  
  675. if(jsonrpc_2) {
  676. char s[128];
  677. snprintf(s, 128, "{\"method\": \"getjob\", \"params\": {\"id\": \"%s\"}, \"id\":1}\r\n", rpc2_id);
  678. val = json_rpc2_call(curl, rpc_url, rpc_userpass, s, NULL, 0);
  679. } else {
  680. val = json_rpc_call(curl, rpc_url, rpc_userpass, rpc_req, NULL, 0);
  681. }
  682. gettimeofday(&tv_end, NULL );
  683.  
  684. if (have_stratum) {
  685. if (val)
  686. json_decref(val);
  687. return true;
  688. }
  689.  
  690. if (!val)
  691. return false;
  692.  
  693. rc = work_decode(json_object_get(val, "result"), work);
  694.  
  695. if (opt_debug && rc) {
  696. timeval_subtract(&diff, &tv_end, &tv_start);
  697. applog(LOG_DEBUG, "DEBUG: got new work in %d ms",
  698. diff.tv_sec * 1000 + diff.tv_usec / 1000);
  699. }
  700.  
  701. json_decref(val);
  702.  
  703. return rc;
  704. }
  705.  
  706. static bool rpc2_login(CURL *curl) {
  707. if(!jsonrpc_2) {
  708. return false;
  709. }
  710. json_t *val;
  711. bool rc;
  712. struct timeval tv_start, tv_end, diff;
  713. char s[JSON_BUF_LEN];
  714.  
  715. snprintf(s, JSON_BUF_LEN, "{\"method\": \"login\", \"params\": {\"login\": \"%s\", \"pass\": \"%s\", \"agent\": \"cpuminer-multi/0.1\"}, \"id\": 1}", rpc_user, rpc_pass);
  716.  
  717. gettimeofday(&tv_start, NULL );
  718. val = json_rpc_call(curl, rpc_url, rpc_userpass, s, NULL, 0);
  719. gettimeofday(&tv_end, NULL );
  720.  
  721. if (!val)
  722. goto end;
  723.  
  724. // applog(LOG_DEBUG, "JSON value: %s", json_dumps(val, 0));
  725.  
  726. rc = rpc2_login_decode(val);
  727.  
  728. json_t *result = json_object_get(val, "result");
  729.  
  730. if(!result) goto end;
  731.  
  732. json_t *job = json_object_get(result, "job");
  733.  
  734. if(!rpc2_job_decode(job, &g_work)) {
  735. goto end;
  736. }
  737.  
  738. if (opt_debug && rc) {
  739. timeval_subtract(&diff, &tv_end, &tv_start);
  740. applog(LOG_DEBUG, "DEBUG: authenticated in %d ms",
  741. diff.tv_sec * 1000 + diff.tv_usec / 1000);
  742. }
  743.  
  744. json_decref(val);
  745.  
  746. end:
  747. return rc;
  748. }
  749.  
  750. static void workio_cmd_free(struct workio_cmd *wc) {
  751. if (!wc)
  752. return;
  753.  
  754. switch (wc->cmd) {
  755. case WC_SUBMIT_WORK:
  756. work_free(wc->u.work);
  757. free(wc->u.work);
  758. break;
  759. default: /* do nothing */
  760. break;
  761. }
  762.  
  763. memset(wc, 0, sizeof(*wc)); /* poison */
  764. free(wc);
  765. }
  766.  
  767. static bool workio_get_work(struct workio_cmd *wc, CURL *curl) {
  768. struct work *ret_work;
  769. int failures = 0;
  770.  
  771. ret_work = calloc(1, sizeof(*ret_work));
  772. if (!ret_work)
  773. return false;
  774.  
  775. /* obtain new work from bitcoin via JSON-RPC */
  776. while (!get_upstream_work(curl, ret_work)) {
  777. if (unlikely((opt_retries >= 0) && (++failures > opt_retries))) {
  778. applog(LOG_ERR, "json_rpc_call failed, terminating workio thread");
  779. free(ret_work);
  780. return false;
  781. }
  782.  
  783. /* pause, then restart work-request loop */
  784. applog(LOG_ERR, "getwork failed, retry after %d seconds",
  785. opt_fail_pause);
  786. sleep(opt_fail_pause);
  787. }
  788.  
  789. /* send work to requesting thread */
  790. if (!tq_push(wc->thr->q, ret_work))
  791. free(ret_work);
  792.  
  793. return true;
  794. }
  795.  
  796. static bool workio_submit_work(struct workio_cmd *wc, CURL *curl) {
  797. int failures = 0;
  798.  
  799. /* submit solution to bitcoin via JSON-RPC */
  800. while (!submit_upstream_work(curl, wc->u.work)) {
  801. if (unlikely((opt_retries >= 0) && (++failures > opt_retries))) {
  802. applog(LOG_ERR, "...terminating workio thread");
  803. return false;
  804. }
  805.  
  806. /* pause, then restart work-request loop */
  807. applog(LOG_ERR, "...retry after %d seconds", opt_fail_pause);
  808. sleep(opt_fail_pause);
  809. }
  810.  
  811. return true;
  812. }
  813.  
  814. static bool workio_login(CURL *curl) {
  815. int failures = 0;
  816.  
  817. /* submit solution to bitcoin via JSON-RPC */
  818. pthread_mutex_lock(&rpc2_login_lock);
  819. while (!rpc2_login(curl)) {
  820. if (unlikely((opt_retries >= 0) && (++failures > opt_retries))) {
  821. applog(LOG_ERR, "...terminating workio thread");
  822. pthread_mutex_unlock(&rpc2_login_lock);
  823. return false;
  824. }
  825.  
  826. /* pause, then restart work-request loop */
  827. applog(LOG_ERR, "...retry after %d seconds", opt_fail_pause);
  828. sleep(opt_fail_pause);
  829. pthread_mutex_unlock(&rpc2_login_lock);
  830. pthread_mutex_lock(&rpc2_login_lock);
  831. }
  832. pthread_mutex_unlock(&rpc2_login_lock);
  833.  
  834. return true;
  835. }
  836.  
  837. static void *workio_thread(void *userdata) {
  838. struct thr_info *mythr = userdata;
  839. CURL *curl;
  840. bool ok = true;
  841.  
  842. curl = curl_easy_init();
  843. if (unlikely(!curl)) {
  844. applog(LOG_ERR, "CURL initialization failed");
  845. return NULL ;
  846. }
  847.  
  848. if(!have_stratum) {
  849. ok = workio_login(curl);
  850. }
  851.  
  852. while (ok) {
  853. struct workio_cmd *wc;
  854.  
  855. /* wait for workio_cmd sent to us, on our queue */
  856. wc = tq_pop(mythr->q, NULL );
  857. if (!wc) {
  858. ok = false;
  859. break;
  860. }
  861.  
  862. /* process workio_cmd */
  863. switch (wc->cmd) {
  864. case WC_GET_WORK:
  865. ok = workio_get_work(wc, curl);
  866. break;
  867. case WC_SUBMIT_WORK:
  868. ok = workio_submit_work(wc, curl);
  869. break;
  870.  
  871. default: /* should never happen */
  872. ok = false;
  873. break;
  874. }
  875.  
  876. workio_cmd_free(wc);
  877. }
  878.  
  879. tq_freeze(mythr->q);
  880. curl_easy_cleanup(curl);
  881.  
  882. return NULL ;
  883. }
  884.  
  885. static bool get_work(struct thr_info *thr, struct work *work) {
  886. struct workio_cmd *wc;
  887. struct work *work_heap;
  888.  
  889. if (opt_benchmark) {
  890. memset(work->data, 0x55, 76);
  891. work->data[17] = swab32(time(NULL ));
  892. memset(work->data + 19, 0x00, 52);
  893. work->data[20] = 0x80000000;
  894. work->data[31] = 0x00000280;
  895. memset(work->target, 0x00, sizeof(work->target));
  896. return true;
  897. }
  898.  
  899. /* fill out work request message */
  900. wc = calloc(1, sizeof(*wc));
  901. if (!wc)
  902. return false;
  903.  
  904. wc->cmd = WC_GET_WORK;
  905. wc->thr = thr;
  906.  
  907. /* send work request to workio thread */
  908. if (!tq_push(thr_info[work_thr_id].q, wc)) {
  909. workio_cmd_free(wc);
  910. return false;
  911. }
  912.  
  913. /* wait for response, a unit of work */
  914. work_heap = tq_pop(thr->q, NULL );
  915. if (!work_heap)
  916. return false;
  917.  
  918. /* copy returned work into storage provided by caller */
  919. memcpy(work, work_heap, sizeof(*work));
  920. free(work_heap);
  921.  
  922. return true;
  923. }
  924.  
  925. static bool submit_work(struct thr_info *thr, const struct work *work_in) {
  926. struct workio_cmd *wc;
  927.  
  928. /* fill out work request message */
  929. wc = calloc(1, sizeof(*wc));
  930. if (!wc)
  931. return false;
  932.  
  933. wc->u.work = malloc(sizeof(*work_in));
  934. if (!wc->u.work)
  935. goto err_out;
  936.  
  937. wc->cmd = WC_SUBMIT_WORK;
  938. wc->thr = thr;
  939. work_copy(wc->u.work, work_in);
  940.  
  941. /* send solution to workio thread */
  942. if (!tq_push(thr_info[work_thr_id].q, wc))
  943. goto err_out;
  944.  
  945. return true;
  946.  
  947. err_out: workio_cmd_free(wc);
  948. return false;
  949. }
  950.  
  951. static void stratum_gen_work(struct stratum_ctx *sctx, struct work *work) {
  952. unsigned char merkle_root[64];
  953. int i;
  954.  
  955. pthread_mutex_lock(&sctx->work_lock);
  956.  
  957. //if (jsonrpc_2) {
  958. free(work->job_id);
  959. memcpy(work, &sctx->work, sizeof(struct work));
  960. work->job_id = strdup(sctx->work.job_id);
  961. pthread_mutex_unlock(&sctx->work_lock);
  962. /*} else {
  963. free(work->job_id);
  964. work->job_id = strdup(sctx->job.job_id);
  965. work->xnonce2_len = sctx->xnonce2_size;
  966. work->xnonce2 = realloc(work->xnonce2, sctx->xnonce2_size);
  967. memcpy(work->xnonce2, sctx->job.xnonce2, sctx->xnonce2_size);
  968. // Generate merkle root
  969. sha256d(merkle_root, sctx->job.coinbase, sctx->job.coinbase_size);
  970. for (i = 0; i < sctx->job.merkle_count; i++) {
  971. memcpy(merkle_root + 32, sctx->job.merkle[i], 32);
  972. sha256d(merkle_root, merkle_root, 64);
  973. }
  974. // Increment extranonce2
  975. for (i = 0; i < sctx->xnonce2_size && !++sctx->job.xnonce2[i]; i++)
  976. ;
  977. // Assemble block header
  978. memset(work->data, 0, 128);
  979. work->data[0] = le32dec(sctx->job.version);
  980. for (i = 0; i < 8; i++)
  981. work->data[1 + i] = le32dec((uint32_t *) sctx->job.prevhash + i);
  982. for (i = 0; i < 8; i++)
  983. work->data[9 + i] = be32dec((uint32_t *) merkle_root + i);
  984. work->data[17] = le32dec(sctx->job.ntime);
  985. work->data[18] = le32dec(sctx->job.nbits);
  986. work->data[20] = 0x80000000;
  987. work->data[31] = 0x00000280;
  988. pthread_mutex_unlock(&sctx->work_lock);
  989. if (opt_debug) {
  990. char *xnonce2str = bin2hex(work->xnonce2, work->xnonce2_len);
  991. applog(LOG_DEBUG, "DEBUG: job_id='%s' extranonce2=%s ntime=%08x",
  992. work->job_id, xnonce2str, swab32(work->data[17]));
  993. free(xnonce2str);
  994. }
  995. if (opt_algo == ALGO_SCRYPT)
  996. diff_to_target(work->target, sctx->job.diff / 65536.0);
  997. else
  998. diff_to_target(work->target, sctx->job.diff);
  999. }*/
  1000. }
  1001.  
  1002. struct cryptonight_ctx *persistentctxs[MAX_THREADS] = { NULL };
  1003.  
  1004. static void *miner_thread(void *userdata) {
  1005. struct thr_info *mythr = userdata;
  1006. int thr_id = mythr->id;
  1007. struct work work = { { 0 } };
  1008. uint32_t max_nonce;
  1009. uint32_t end_nonce = 0xffffffffU / opt_n_threads * (thr_id + 1) - 0x20;
  1010. unsigned char *scratchbuf = NULL;
  1011. char s[16];
  1012. int i;
  1013. struct cryptonight_ctx *persistentctx;
  1014.  
  1015. /* Set worker threads to nice 19 and then preferentially to SCHED_IDLE
  1016. * and if that fails, then SCHED_BATCH. No need for this to be an
  1017. * error if it fails */
  1018. #ifdef __linux
  1019. if (!opt_benchmark) {
  1020. //setpriority(PRIO_PROCESS, 0, 19);
  1021. if(!geteuid()) setpriority(PRIO_PROCESS, 0, -14);
  1022. drop_policy();
  1023. }
  1024. #endif
  1025.  
  1026. /* Cpu affinity only makes sense if the number of threads is a multiple
  1027. * of the number of CPUs */
  1028. /*if (num_processors > 1 && opt_n_threads % num_processors == 0) {
  1029. if (!opt_quiet)
  1030. applog(LOG_INFO, "Binding thread %d to cpu %d", thr_id,
  1031. thr_id % num_processors);
  1032. affine_to_cpu(thr_id, thr_id % num_processors);
  1033. }*/
  1034.  
  1035. persistentctx = persistentctxs[thr_id];
  1036. if(!persistentctx && opt_algo == ALGO_CRYPTONIGHT)
  1037. {
  1038. #if defined __unix__ && (!defined __APPLE__) && (!defined DISABLE_LINUX_HUGEPAGES)
  1039. persistentctx = (struct cryptonight_ctx *)mmap(0, sizeof(struct cryptonight_ctx), PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS | MAP_HUGETLB | MAP_POPULATE, 0, 0);
  1040. if(persistentctx == MAP_FAILED) persistentctx = (struct cryptonight_ctx *)malloc(sizeof(struct cryptonight_ctx));
  1041. madvise(persistentctx, sizeof(struct cryptonight_ctx), MADV_RANDOM | MADV_WILLNEED | MADV_HUGEPAGE);
  1042. if(!geteuid()) mlock(persistentctx, sizeof(struct cryptonight_ctx));
  1043. #elif defined _WIN32
  1044. persistentctx = VirtualAlloc(NULL, sizeof(struct cryptonight_ctx), MEM_LARGE_PAGES, PAGE_READWRITE);
  1045. if(!persistentctx) persistentctx = (struct cryptonight_ctx *)malloc(sizeof(struct cryptonight_ctx));
  1046. #else
  1047. persistentctx = (struct cryptonight_ctx *)malloc(sizeof(struct cryptonight_ctx));
  1048. #endif
  1049. }
  1050.  
  1051. uint32_t *nonceptr = (uint32_t*) (((char*)work.data) + (jsonrpc_2 ? 39 : 76));
  1052.  
  1053. while (1) {
  1054. unsigned long hashes_done;
  1055. struct timeval tv_start, tv_end, diff;
  1056. int64_t max64;
  1057. int rc;
  1058.  
  1059. if (have_stratum) {
  1060. while (!jsonrpc_2 && time(NULL) >= g_work_time + 120)
  1061. sleep(1);
  1062. pthread_mutex_lock(&g_work_lock);
  1063. if ((*nonceptr) >= end_nonce
  1064. && !(jsonrpc_2 ? memcmp(work.data, g_work.data, 39) ||
  1065. memcmp(((uint8_t*) work.data) + 43, ((uint8_t*) g_work.data) + 43, 33)
  1066. : memcmp(work.data, g_work.data, 76)))
  1067. stratum_gen_work(&stratum, &g_work);
  1068. } else {
  1069. /* obtain new work from internal workio thread */
  1070. pthread_mutex_lock(&g_work_lock);
  1071. if ((!have_stratum
  1072. && (!have_longpoll
  1073. || time(NULL ) >= g_work_time + LP_SCANTIME * 3 / 4
  1074. || *nonceptr >= end_nonce))) {
  1075. if (unlikely(!get_work(mythr, &g_work))) {
  1076. applog(LOG_ERR, "work retrieval failed, exiting "
  1077. "mining thread %d", mythr->id);
  1078. pthread_mutex_unlock(&g_work_lock);
  1079. goto out;
  1080. }
  1081. g_work_time = have_stratum ? 0 : time(NULL );
  1082. }
  1083. if (have_stratum) {
  1084. pthread_mutex_unlock(&g_work_lock);
  1085. continue;
  1086. }
  1087. }
  1088. if (jsonrpc_2 ? memcmp(work.data, g_work.data, 39) || memcmp(((uint8_t*) work.data) + 43, ((uint8_t*) g_work.data) + 43, 33) : memcmp(work.data, g_work.data, 76)) {
  1089. work_free(&work);
  1090. work_copy(&work, &g_work);
  1091. nonceptr = (uint32_t*) (((char*)work.data) + (jsonrpc_2 ? 39 : 76));
  1092. *nonceptr = 0xffffffffU / opt_n_threads * thr_id;
  1093. } else
  1094. ++(*nonceptr);
  1095. pthread_mutex_unlock(&g_work_lock);
  1096. work_restart[thr_id].restart = 0;
  1097.  
  1098. /* adjust max_nonce to meet target scan time */
  1099. if (have_stratum)
  1100. max64 = LP_SCANTIME;
  1101. else
  1102. max64 = g_work_time + (have_longpoll ? LP_SCANTIME : opt_scantime)
  1103. - time(NULL );
  1104. //max64 *= thr_hashrates[thr_id];
  1105. if (max64 <= 0) {
  1106. switch (opt_algo) {
  1107. case ALGO_SCRYPT:
  1108. max64 = 0xfffLL;
  1109. break;
  1110. case ALGO_CRYPTONIGHT:
  1111.  
  1112. max64 = 0x40LL;
  1113. break;
  1114. default:
  1115. max64 = 0x1fffffLL;
  1116. break;
  1117. }
  1118. }
  1119. if (*nonceptr + max64 > end_nonce)
  1120. max_nonce = end_nonce;
  1121. else
  1122. max_nonce = *nonceptr + max64;
  1123.  
  1124. hashes_done = 0;
  1125. gettimeofday(&tv_start, NULL );
  1126.  
  1127. /* scan nonces for a proof-of-work hash */
  1128. rc = scanhash_cryptonight(thr_id, work.data, work.target,
  1129. max_nonce, &hashes_done, persistentctx);
  1130.  
  1131. /* record scanhash elapsed time */
  1132. gettimeofday(&tv_end, NULL );
  1133. timeval_subtract(&diff, &tv_end, &tv_start);
  1134. if (diff.tv_usec || diff.tv_sec) {
  1135. pthread_mutex_lock(&stats_lock);
  1136. thr_hashrates[thr_id] = hashes_done;
  1137. thr_times[thr_id] = (diff.tv_sec + 1e-6 * diff.tv_usec);
  1138. pthread_mutex_unlock(&stats_lock);
  1139. }
  1140. /*if (!opt_quiet) {
  1141. switch(opt_algo) {
  1142. case ALGO_CRYPTONIGHT:
  1143. applog(LOG_INFO, "thread %d: %lu hashes, %.2f H/s", thr_id,
  1144. hashes_done, thr_hashrates[thr_id]);
  1145. break;
  1146. default:
  1147. sprintf(s, thr_hashrates[thr_id] >= 1e6 ? "%.0f" : "%.2f",
  1148. 1e-3 * thr_hashrates[thr_id]);
  1149. applog(LOG_INFO, "thread %d: %lu hashes, %.2f khash/s", thr_id,
  1150. hashes_done, s);
  1151. break;
  1152. }
  1153. }
  1154. if (opt_benchmark && thr_id == opt_n_threads - 1) {
  1155. double hashrate = 0.;
  1156. for (i = 0; i < opt_n_threads && thr_hashrates[i]; i++)
  1157. hashrate += thr_hashrates[i];
  1158. if (i == opt_n_threads) {
  1159. switch(opt_algo) {
  1160. case ALGO_CRYPTONIGHT:
  1161. applog(LOG_INFO, "Total: %s H/s", hashrate);
  1162. break;
  1163. default:
  1164. sprintf(s, hashrate >= 1e6 ? "%.0f" : "%.2f", 1e-3 * hashrate);
  1165. applog(LOG_INFO, "Total: %s khash/s", s);
  1166. break;
  1167. }
  1168. }
  1169. }*/
  1170.  
  1171. /* if nonce found, submit work */
  1172. if (rc && !opt_benchmark && !submit_work(mythr, &work))
  1173. break;
  1174. }
  1175.  
  1176. out: tq_freeze(mythr->q);
  1177.  
  1178. return NULL ;
  1179. }
  1180.  
  1181. static void restart_threads(void) {
  1182. int i;
  1183.  
  1184. for (i = 0; i < opt_n_threads; i++)
  1185. work_restart[i].restart = 1;
  1186. }
  1187.  
  1188. static void *longpoll_thread(void *userdata) {
  1189. struct thr_info *mythr = userdata;
  1190. CURL *curl = NULL;
  1191. char *copy_start, *hdr_path = NULL, *lp_url = NULL;
  1192. bool need_slash = false;
  1193.  
  1194. curl = curl_easy_init();
  1195. if (unlikely(!curl)) {
  1196. applog(LOG_ERR, "CURL initialization failed");
  1197. goto out;
  1198. }
  1199.  
  1200. start: hdr_path = tq_pop(mythr->q, NULL );
  1201. if (!hdr_path)
  1202. goto out;
  1203.  
  1204. /* full URL */
  1205. if (strstr(hdr_path, "://")) {
  1206. lp_url = hdr_path;
  1207. hdr_path = NULL;
  1208. }
  1209.  
  1210. /* absolute path, on current server */
  1211. else {
  1212. copy_start = (*hdr_path == '/') ? (hdr_path + 1) : hdr_path;
  1213. if (rpc_url[strlen(rpc_url) - 1] != '/')
  1214. need_slash = true;
  1215.  
  1216. lp_url = malloc(strlen(rpc_url) + strlen(copy_start) + 2);
  1217. if (!lp_url)
  1218. goto out;
  1219.  
  1220. sprintf(lp_url, "%s%s%s", rpc_url, need_slash ? "/" : "", copy_start);
  1221. }
  1222.  
  1223. applog(LOG_INFO, "Long-polling activated for %s", lp_url);
  1224.  
  1225. while (1) {
  1226. json_t *val, *soval;
  1227. int err;
  1228.  
  1229. if(jsonrpc_2) {
  1230. pthread_mutex_lock(&rpc2_login_lock);
  1231. if(!strcmp(rpc2_id, "")) {
  1232. sleep(1);
  1233. continue;
  1234. }
  1235. char s[128];
  1236. snprintf(s, 128, "{\"method\": \"getjob\", \"params\": {\"id\": \"%s\"}, \"id\":1}\r\n", rpc2_id);
  1237. pthread_mutex_unlock(&rpc2_login_lock);
  1238. val = json_rpc2_call(curl, rpc_url, rpc_userpass, s, &err, JSON_RPC_LONGPOLL);
  1239. } else {
  1240. val = json_rpc_call(curl, rpc_url, rpc_userpass, rpc_req, &err, JSON_RPC_LONGPOLL);
  1241. }
  1242. if (have_stratum) {
  1243. if (val)
  1244. json_decref(val);
  1245. goto out;
  1246. }
  1247. if (likely(val)) {
  1248. if (!jsonrpc_2) {
  1249. soval = json_object_get(json_object_get(val, "result"),
  1250. "submitold");
  1251. submit_old = soval ? json_is_true(soval) : false;
  1252. }
  1253. pthread_mutex_lock(&g_work_lock);
  1254. char *start_job_id = strdup(g_work.job_id);
  1255. if (work_decode(json_object_get(val, "result"), &g_work)) {
  1256. if (strcmp(start_job_id, g_work.job_id)) {
  1257. applog(LOG_INFO, "LONGPOLL detected new block");
  1258. if (opt_debug)
  1259. applog(LOG_DEBUG, "DEBUG: got new work");
  1260. time(&g_work_time);
  1261. restart_threads();
  1262. }
  1263. }
  1264. free(start_job_id);
  1265. pthread_mutex_unlock(&g_work_lock);
  1266. json_decref(val);
  1267. } else {
  1268. pthread_mutex_lock(&g_work_lock);
  1269. g_work_time -= LP_SCANTIME;
  1270. pthread_mutex_unlock(&g_work_lock);
  1271. if (err == CURLE_OPERATION_TIMEDOUT) {
  1272. restart_threads();
  1273. } else {
  1274. have_longpoll = false;
  1275. restart_threads();
  1276. free(hdr_path);
  1277. free(lp_url);
  1278. lp_url = NULL;
  1279. sleep(opt_fail_pause);
  1280. goto start;
  1281. }
  1282. }
  1283. }
  1284.  
  1285. out: free(hdr_path);
  1286. free(lp_url);
  1287. tq_freeze(mythr->q);
  1288. if (curl)
  1289. curl_easy_cleanup(curl);
  1290.  
  1291. return NULL ;
  1292. }
  1293.  
  1294. static bool stratum_handle_response(char *buf) {
  1295. json_t *val, *err_val, *res_val, *id_val;
  1296. json_error_t err;
  1297. bool ret = false;
  1298. bool valid = false;
  1299.  
  1300. val = JSON_LOADS(buf, &err);
  1301. if (!val) {
  1302. applog(LOG_INFO, "JSON decode failed(%d): %s", err.line, err.text);
  1303. goto out;
  1304. }
  1305.  
  1306. res_val = json_object_get(val, "result");
  1307. err_val = json_object_get(val, "error");
  1308. id_val = json_object_get(val, "id");
  1309.  
  1310. if (!id_val || json_is_null(id_val) || !res_val)
  1311. goto out;
  1312.  
  1313. if(jsonrpc_2) {
  1314. json_t *status = json_object_get(res_val, "status");
  1315. if(status) {
  1316. const char *s = json_string_value(status);
  1317. valid = !strcmp(s, "OK") && json_is_null(err_val);
  1318. } else {
  1319. valid = json_is_null(err_val);
  1320. }
  1321. } else {
  1322. valid = json_is_true(res_val);
  1323. }
  1324.  
  1325. share_result(valid, NULL,
  1326. err_val ? (jsonrpc_2 ? json_string_value(err_val) : json_string_value(json_array_get(err_val, 1))) : NULL );
  1327.  
  1328. ret = true;
  1329. out: if (val)
  1330. json_decref(val);
  1331.  
  1332. return ret;
  1333. }
  1334.  
  1335. static void *stratum_thread(void *userdata) {
  1336. struct thr_info *mythr = userdata;
  1337. char *s;
  1338.  
  1339. stratum.url = tq_pop(mythr->q, NULL );
  1340. if (!stratum.url)
  1341. goto out;
  1342. applog(LOG_INFO, "Starting Stratum on %s", stratum.url);
  1343.  
  1344. while (1) {
  1345. int failures = 0;
  1346.  
  1347. while (!stratum.curl) {
  1348. pthread_mutex_lock(&g_work_lock);
  1349. g_work_time = 0;
  1350. pthread_mutex_unlock(&g_work_lock);
  1351. restart_threads();
  1352.  
  1353. if (!stratum_connect(&stratum, stratum.url)
  1354. || !stratum_subscribe(&stratum)
  1355. || !stratum_authorize(&stratum, rpc_user, rpc_pass)) {
  1356. stratum_disconnect(&stratum);
  1357. if (opt_retries >= 0 && ++failures > opt_retries) {
  1358. applog(LOG_ERR, "...terminating workio thread");
  1359. tq_push(thr_info[work_thr_id].q, NULL );
  1360. goto out;
  1361. }
  1362. applog(LOG_ERR, "...retry after %d seconds", opt_fail_pause);
  1363. sleep(opt_fail_pause);
  1364. }
  1365. }
  1366.  
  1367. if (jsonrpc_2) {
  1368. if (stratum.work.job_id
  1369. && (!g_work_time
  1370. || strcmp(stratum.work.job_id, g_work.job_id))) {
  1371. pthread_mutex_lock(&g_work_lock);
  1372. stratum_gen_work(&stratum, &g_work);
  1373. time(&g_work_time);
  1374. pthread_mutex_unlock(&g_work_lock);
  1375. applog(LOG_INFO, "Stratum detected new block");
  1376. restart_threads();
  1377. }
  1378. } else {
  1379. if (stratum.job.job_id
  1380. && (!g_work_time
  1381. || strcmp(stratum.job.job_id, g_work.job_id))) {
  1382. pthread_mutex_lock(&g_work_lock);
  1383. stratum_gen_work(&stratum, &g_work);
  1384. time(&g_work_time);
  1385. pthread_mutex_unlock(&g_work_lock);
  1386. if (stratum.job.clean) {
  1387. applog(LOG_INFO, "Stratum detected new block");
  1388. restart_threads();
  1389. }
  1390. }
  1391. }
  1392.  
  1393. if (!stratum_socket_full(&stratum, 600)) {
  1394. applog(LOG_ERR, "Stratum connection timed out");
  1395. s = NULL;
  1396. } else
  1397. s = stratum_recv_line(&stratum);
  1398. if (!s) {
  1399. stratum_disconnect(&stratum);
  1400. applog(LOG_ERR, "Stratum connection interrupted");
  1401. continue;
  1402. }
  1403. if (!stratum_handle_method(&stratum, s))
  1404. stratum_handle_response(s);
  1405. free(s);
  1406. }
  1407.  
  1408. out: return NULL ;
  1409. }
  1410.  
  1411. static void show_version_and_exit(void) {
  1412. printf(PACKAGE_STRING "\n built on " __DATE__ "\n features:"
  1413. #if defined(__i386__)
  1414. " i386"
  1415. #endif
  1416. #if defined(__x86_64__)
  1417. " x86_64"
  1418. #endif
  1419. #if defined(__i386__) || defined(__x86_64__)
  1420. " SSE2"
  1421. #endif
  1422. #if defined(__x86_64__) && defined(USE_AVX)
  1423. " AVX"
  1424. #endif
  1425. #if defined(__x86_64__) && defined(USE_AVX2)
  1426. " AVX2"
  1427. #endif
  1428. #if defined(__x86_64__) && defined(USE_XOP)
  1429. " XOP"
  1430. #endif
  1431. #if defined(__arm__) && defined(__APCS_32__)
  1432. " ARM"
  1433. #if defined(__ARM_ARCH_5E__) || defined(__ARM_ARCH_5TE__) || \
  1434. defined(__ARM_ARCH_5TEJ__) || defined(__ARM_ARCH_6__) || \
  1435. defined(__ARM_ARCH_6J__) || defined(__ARM_ARCH_6K__) || \
  1436. defined(__ARM_ARCH_6M__) || defined(__ARM_ARCH_6T2__) || \
  1437. defined(__ARM_ARCH_6Z__) || defined(__ARM_ARCH_6ZK__) || \
  1438. defined(__ARM_ARCH_7__) || \
  1439. defined(__ARM_ARCH_7A__) || defined(__ARM_ARCH_7R__) || \
  1440. defined(__ARM_ARCH_7M__) || defined(__ARM_ARCH_7EM__)
  1441. " ARMv5E"
  1442. #endif
  1443. #if defined(__ARM_NEON__)
  1444. " NEON"
  1445. #endif
  1446. #endif
  1447. "\n");
  1448.  
  1449. printf("%s\n", curl_version());
  1450. #ifdef JANSSON_VERSION
  1451. printf("libjansson %s\n", JANSSON_VERSION);
  1452. #endif
  1453. exit(0);
  1454. }
  1455.  
  1456. static void show_usage_and_exit(int status) {
  1457. if (status)
  1458. fprintf(stderr,
  1459. "Try `" PROGRAM_NAME " --help' for more information.\n");
  1460. else
  1461. printf(usage);
  1462. exit(status);
  1463. }
  1464.  
  1465. static void parse_arg(int key, char *arg) {
  1466. char *p;
  1467. int v, i;
  1468.  
  1469. switch (key) {
  1470. case 'a':
  1471. for (i = 0; i < ARRAY_SIZE(algo_names); i++) {
  1472. if (algo_names[i] && !strcmp(arg, algo_names[i])) {
  1473. //opt_algo = i;
  1474. break;
  1475. }
  1476. }
  1477. if (i == ARRAY_SIZE(algo_names))
  1478. show_usage_and_exit(1);
  1479. break;
  1480. case 'B':
  1481. opt_background = true;
  1482. break;
  1483. case 'c': {
  1484. json_error_t err;
  1485. if (opt_config)
  1486. json_decref(opt_config);
  1487. #if JANSSON_VERSION_HEX >= 0x020000
  1488. opt_config = json_load_file(arg, 0, &err);
  1489. #else
  1490. opt_config = json_load_file(arg, &err);
  1491. #endif
  1492. if (!json_is_object(opt_config)) {
  1493. applog(LOG_ERR, "JSON decode of %s failed", arg);
  1494. exit(1);
  1495. }
  1496. break;
  1497. }
  1498. case 'q':
  1499. opt_quiet = true;
  1500. break;
  1501. case 'D':
  1502. opt_debug = true;
  1503. break;
  1504. case 'p':
  1505. free(rpc_pass);
  1506. rpc_pass = strdup(arg);
  1507. break;
  1508. case 'P':
  1509. opt_protocol = true;
  1510. break;
  1511. case 'r':
  1512. v = atoi(arg);
  1513. if (v < -1 || v > 9999) /* sanity check */
  1514. show_usage_and_exit(1);
  1515. opt_retries = v;
  1516. break;
  1517. case 'R':
  1518. v = atoi(arg);
  1519. if (v < 1 || v > 9999) /* sanity check */
  1520. show_usage_and_exit(1);
  1521. opt_fail_pause = v;
  1522. break;
  1523. case 's':
  1524. v = atoi(arg);
  1525. if (v < 1 || v > 9999) /* sanity check */
  1526. show_usage_and_exit(1);
  1527. opt_scantime = v;
  1528. break;
  1529. case 'T':
  1530. v = atoi(arg);
  1531. if (v < 1 || v > 99999) /* sanity check */
  1532. show_usage_and_exit(1);
  1533. opt_timeout = v;
  1534. break;
  1535. case 't':
  1536. v = atoi(arg);
  1537. if (v < 1 || v > 9999) /* sanity check */
  1538. show_usage_and_exit(1);
  1539. opt_n_threads = v;
  1540. break;
  1541. case 'u':
  1542. free(rpc_user);
  1543. rpc_user = strdup(arg);
  1544. break;
  1545. case 'o': /* --url */
  1546. p = strstr(arg, "://");
  1547. if (p) {
  1548. if (strncasecmp(arg, "http://", 7)
  1549. && strncasecmp(arg, "https://", 8)
  1550. && strncasecmp(arg, "stratum+tcp://", 14))
  1551. show_usage_and_exit(1);
  1552. free(rpc_url);
  1553. rpc_url = strdup(arg);
  1554. } else {
  1555. if (!strlen(arg) || *arg == '/')
  1556. show_usage_and_exit(1);
  1557. free(rpc_url);
  1558. rpc_url = malloc(strlen(arg) + 8);
  1559. sprintf(rpc_url, "http://%s", arg);
  1560. }
  1561. p = strrchr(rpc_url, '@');
  1562. if (p) {
  1563. char *sp, *ap;
  1564. *p = '\0';
  1565. ap = strstr(rpc_url, "://") + 3;
  1566. sp = strchr(ap, ':');
  1567. if (sp) {
  1568. free(rpc_userpass);
  1569. rpc_userpass = strdup(ap);
  1570. free(rpc_user);
  1571. rpc_user = calloc(sp - ap + 1, 1);
  1572. strncpy(rpc_user, ap, sp - ap);
  1573. free(rpc_pass);
  1574. rpc_pass = strdup(sp + 1);
  1575. } else {
  1576. free(rpc_user);
  1577. rpc_user = strdup(ap);
  1578. }
  1579. memmove(ap, p + 1, strlen(p + 1) + 1);
  1580. }
  1581. have_stratum = !opt_benchmark && !strncasecmp(rpc_url, "stratum", 7);
  1582. break;
  1583. case 'O': /* --userpass */
  1584. p = strchr(arg, ':');
  1585. if (!p)
  1586. show_usage_and_exit(1);
  1587. free(rpc_userpass);
  1588. rpc_userpass = strdup(arg);
  1589. free(rpc_user);
  1590. rpc_user = calloc(p - arg + 1, 1);
  1591. strncpy(rpc_user, arg, p - arg);
  1592. free(rpc_pass);
  1593. rpc_pass = strdup(p + 1);
  1594. break;
  1595. case 'x': /* --proxy */
  1596. if (!strncasecmp(arg, "socks4://", 9))
  1597. opt_proxy_type = CURLPROXY_SOCKS4;
  1598. else if (!strncasecmp(arg, "socks5://", 9))
  1599. opt_proxy_type = CURLPROXY_SOCKS5;
  1600. #if LIBCURL_VERSION_NUM >= 0x071200
  1601. else if (!strncasecmp(arg, "socks4a://", 10))
  1602. opt_proxy_type = CURLPROXY_SOCKS4A;
  1603. else if (!strncasecmp(arg, "socks5h://", 10))
  1604. opt_proxy_type = CURLPROXY_SOCKS5_HOSTNAME;
  1605. #endif
  1606. else
  1607. opt_proxy_type = CURLPROXY_HTTP;
  1608. free(opt_proxy);
  1609. opt_proxy = strdup(arg);
  1610. break;
  1611. case 1001:
  1612. free(opt_cert);
  1613. opt_cert = strdup(arg);
  1614. break;
  1615. case 1005:
  1616. opt_benchmark = true;
  1617. want_longpoll = false;
  1618. want_stratum = false;
  1619. have_stratum = false;
  1620. break;
  1621. case 1003:
  1622. want_longpoll = false;
  1623. break;
  1624. case 1007:
  1625. want_stratum = false;
  1626. break;
  1627. case 1009:
  1628. opt_redirect = false;
  1629. break;
  1630. case 'S':
  1631. use_syslog = true;
  1632. break;
  1633. case 'V':
  1634. show_version_and_exit();
  1635. case 'h':
  1636. show_usage_and_exit(0);
  1637. default:
  1638. show_usage_and_exit(1);
  1639. }
  1640. }
  1641.  
  1642. static void parse_config(void) {
  1643. int i;
  1644. json_t *val;
  1645.  
  1646. if (!json_is_object(opt_config))
  1647. return;
  1648.  
  1649. for (i = 0; i < ARRAY_SIZE(options); i++) {
  1650. if (!options[i].name)
  1651. break;
  1652. if (!strcmp(options[i].name, "config"))
  1653. continue;
  1654.  
  1655. val = json_object_get(opt_config, options[i].name);
  1656. if (!val)
  1657. continue;
  1658.  
  1659. if (options[i].has_arg && json_is_string(val)) {
  1660. char *s = strdup(json_string_value(val));
  1661. if (!s)
  1662. break;
  1663. parse_arg(options[i].val, s);
  1664. free(s);
  1665. } else if (!options[i].has_arg && json_is_true(val))
  1666. parse_arg(options[i].val, "");
  1667. else
  1668. applog(LOG_ERR, "JSON option %s invalid", options[i].name);
  1669. }
  1670. }
  1671.  
  1672. static void parse_cmdline(int argc, char *argv[]) {
  1673. int key;
  1674.  
  1675. while (1) {
  1676. #if HAVE_GETOPT_LONG
  1677. key = getopt_long(argc, argv, short_options, options, NULL );
  1678. #else
  1679. key = getopt(argc, argv, short_options);
  1680. #endif
  1681. if (key < 0)
  1682. break;
  1683.  
  1684. parse_arg(key, optarg);
  1685. }
  1686. if (optind < argc) {
  1687. fprintf(stderr, "%s: unsupported non-option argument '%s'\n", argv[0],
  1688. argv[optind]);
  1689. show_usage_and_exit(1);
  1690. }
  1691.  
  1692. parse_config();
  1693. }
  1694.  
  1695. #ifndef WIN32
  1696. static void signal_handler(int sig) {
  1697. int i;
  1698. switch (sig) {
  1699. case SIGHUP:
  1700. applog(LOG_INFO, "SIGHUP received");
  1701. break;
  1702. case SIGINT:
  1703. applog(LOG_INFO, "SIGINT received, exiting");
  1704. #if defined __unix__ && (!defined __APPLE__)
  1705. if(opt_algo == ALGO_CRYPTONIGHT)
  1706. for(i = 0; i < opt_n_threads; i++) munmap(persistentctxs[i], sizeof(struct cryptonight_ctx));
  1707. #endif
  1708. exit(0);
  1709. break;
  1710. case SIGTERM:
  1711. applog(LOG_INFO, "SIGTERM received, exiting");
  1712. #if defined __unix__ && (!defined __APPLE__)
  1713. if(opt_algo == ALGO_CRYPTONIGHT)
  1714. for(i = 0; i < opt_n_threads; i++) munmap(persistentctxs[i], sizeof(struct cryptonight_ctx));
  1715. #endif
  1716. exit(0);
  1717. break;
  1718. }
  1719. }
  1720. #endif
  1721.  
  1722. int main(int argc, char *argv[]) {
  1723. struct thr_info *thr;
  1724. unsigned int tmp1, tmp2, tmp3, tmp4;
  1725. long flags;
  1726. int i;
  1727.  
  1728. #ifndef USE_LOBOTOMIZED_AES
  1729. // If the CPU doesn't support CPUID feature
  1730. // flags, it's WAY too old to have AES-NI
  1731. if(__get_cpuid_max(0, &tmp1) < 1)
  1732. {
  1733. applog(LOG_ERR, "CPU does not have AES-NI, which is required.");
  1734. return(0);
  1735. }
  1736.  
  1737. // We already checked the max supported
  1738. // function, so we don't need to check
  1739. // this for error.
  1740. __get_cpuid(1, &tmp1, &tmp2, &tmp3, &tmp4);
  1741.  
  1742. // Mask out all bits but bit 25; if it's
  1743. // set, we have AES-NI, if not, nope.
  1744. if(!(tmp3 & 0x2000000))
  1745. {
  1746. applog(LOG_ERR, "CPU does not have AES-NI, which is required.");
  1747. return(0);
  1748. }
  1749. #endif
  1750.  
  1751. #ifdef __unix__
  1752. if(geteuid()) applog(LOG_INFO, "I go faster as root.");
  1753. #endif
  1754.  
  1755. rpc_user = strdup("");
  1756. rpc_pass = strdup("");
  1757.  
  1758. /* parse command line */
  1759. parse_cmdline(argc, argv);
  1760.  
  1761. jsonrpc_2 = true;
  1762. applog(LOG_INFO, "Using JSON-RPC 2.0");
  1763.  
  1764.  
  1765. if (!opt_benchmark && !rpc_url) {
  1766. fprintf(stderr, "%s: no URL supplied\n", argv[0]);
  1767. show_usage_and_exit(1);
  1768. }
  1769.  
  1770. if (!rpc_userpass) {
  1771. rpc_userpass = malloc(strlen(rpc_user) + strlen(rpc_pass) + 2);
  1772. if (!rpc_userpass)
  1773. return 1;
  1774. sprintf(rpc_userpass, "%s:%s", rpc_user, rpc_pass);
  1775. }
  1776.  
  1777. pthread_mutex_init(&applog_lock, NULL );
  1778. pthread_mutex_init(&stats_lock, NULL );
  1779. pthread_mutex_init(&g_work_lock, NULL );
  1780. pthread_mutex_init(&rpc2_job_lock, NULL );
  1781. pthread_mutex_init(&stratum.sock_lock, NULL );
  1782. pthread_mutex_init(&stratum.work_lock, NULL );
  1783.  
  1784. flags = !opt_benchmark && strncmp(rpc_url, "https:", 6) ?
  1785. (CURL_GLOBAL_ALL & ~CURL_GLOBAL_SSL) : CURL_GLOBAL_ALL;
  1786. if (curl_global_init(flags)) {
  1787. applog(LOG_ERR, "CURL initialization failed");
  1788. return 1;
  1789. }
  1790.  
  1791. #ifndef WIN32
  1792. if (opt_background) {
  1793. i = fork();
  1794. if (i < 0)
  1795. exit(1);
  1796. if (i > 0)
  1797. exit(0);
  1798. i = setsid();
  1799. if (i < 0)
  1800. applog(LOG_ERR, "setsid() failed (errno = %d)", errno);
  1801. i = chdir("/");
  1802. if (i < 0)
  1803. applog(LOG_ERR, "chdir() failed (errno = %d)", errno);
  1804. signal(SIGHUP, signal_handler);
  1805. signal(SIGINT, signal_handler);
  1806. signal(SIGTERM, signal_handler);
  1807. }
  1808. #endif
  1809.  
  1810. #if defined(WIN32)
  1811. SYSTEM_INFO sysinfo;
  1812. GetSystemInfo(&sysinfo);
  1813. num_processors = sysinfo.dwNumberOfProcessors;
  1814. #elif defined(_SC_NPROCESSORS_CONF)
  1815. num_processors = sysconf(_SC_NPROCESSORS_CONF);
  1816. #elif defined(CTL_HW) && defined(HW_NCPU)
  1817. int req[] = {CTL_HW, HW_NCPU};
  1818. size_t len = sizeof(num_processors);
  1819. sysctl(req, 2, &num_processors, &len, NULL, 0);
  1820. #else
  1821. num_processors = 1;
  1822. #endif
  1823. if (num_processors < 1)
  1824. num_processors = 1;
  1825. if (!opt_n_threads)
  1826. opt_n_threads = (num_processors == 1) ? num_processors : num_processors - 1;
  1827.  
  1828. #ifdef HAVE_SYSLOG_H
  1829. if (use_syslog)
  1830. openlog("cpuminer", LOG_PID, LOG_USER);
  1831. #endif
  1832.  
  1833. work_restart = calloc(opt_n_threads, sizeof(*work_restart));
  1834. if (!work_restart)
  1835. return 1;
  1836.  
  1837. thr_info = calloc(opt_n_threads + 3, sizeof(*thr));
  1838. if (!thr_info)
  1839. return 1;
  1840.  
  1841. thr_hashrates = (double *) calloc(opt_n_threads, sizeof(double));
  1842. if (!thr_hashrates)
  1843. return 1;
  1844.  
  1845. thr_times = (double *)calloc(opt_n_threads, sizeof(double));
  1846.  
  1847. /* init workio thread info */
  1848. work_thr_id = opt_n_threads;
  1849. thr = &thr_info[work_thr_id];
  1850. thr->id = work_thr_id;
  1851. thr->q = tq_new();
  1852. if (!thr->q)
  1853. return 1;
  1854.  
  1855. /* start work I/O thread */
  1856. if (pthread_create(&thr->pth, NULL, workio_thread, thr)) {
  1857. applog(LOG_ERR, "workio thread create failed");
  1858. return 1;
  1859. }
  1860.  
  1861. if (want_longpoll && !have_stratum) {
  1862. /* init longpoll thread info */
  1863. longpoll_thr_id = opt_n_threads + 1;
  1864. thr = &thr_info[longpoll_thr_id];
  1865. thr->id = longpoll_thr_id;
  1866. thr->q = tq_new();
  1867. if (!thr->q)
  1868. return 1;
  1869.  
  1870. /* start longpoll thread */
  1871. if (unlikely(pthread_create(&thr->pth, NULL, longpoll_thread, thr))) {
  1872. applog(LOG_ERR, "longpoll thread create failed");
  1873. return 1;
  1874. }
  1875. }
  1876. if (want_stratum) {
  1877. /* init stratum thread info */
  1878. stratum_thr_id = opt_n_threads + 2;
  1879. thr = &thr_info[stratum_thr_id];
  1880. thr->id = stratum_thr_id;
  1881. thr->q = tq_new();
  1882. if (!thr->q)
  1883. return 1;
  1884.  
  1885. /* start stratum thread */
  1886. if (unlikely(pthread_create(&thr->pth, NULL, stratum_thread, thr))) {
  1887. applog(LOG_ERR, "stratum thread create failed");
  1888. return 1;
  1889. }
  1890.  
  1891. if (have_stratum)
  1892. tq_push(thr_info[stratum_thr_id].q, strdup(rpc_url));
  1893. }
  1894.  
  1895. /* start mining threads */
  1896. for (i = 0; i < opt_n_threads; i++) {
  1897. thr = &thr_info[i];
  1898.  
  1899. thr->id = i;
  1900. thr->q = tq_new();
  1901. if (!thr->q)
  1902. return 1;
  1903.  
  1904. if (unlikely(pthread_create(&thr->pth, NULL, miner_thread, thr))) {
  1905. applog(LOG_ERR, "thread %d create failed", i);
  1906. return 1;
  1907. }
  1908. }
  1909.  
  1910. applog(LOG_INFO, "%d miner threads started, "
  1911. "using '%s' algorithm.", opt_n_threads, algo_names[opt_algo]);
  1912.  
  1913. /* main loop - simply wait for workio thread to exit */
  1914. pthread_join(thr_info[work_thr_id].pth, NULL );
  1915.  
  1916. applog(LOG_INFO, "workio thread dead, exiting.");
  1917. #if defined __unix__ && (!defined __APPLE__)
  1918. if(opt_algo == ALGO_CRYPTONIGHT)
  1919. for(i = 0; i < opt_n_threads; i++) munmap(persistentctxs[i], sizeof(struct cryptonight_ctx));
  1920. #endif
  1921. return 0;
  1922. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement