Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
tpruvot
GitHub Repository: tpruvot/cpuminer-multi
Path: blob/linux/cpu-miner.c
1201 views
1
/*
2
* Copyright 2010 Jeff Garzik
3
* Copyright 2012-2014 pooler
4
* Copyright 2014 Lucas Jones
5
* Copyright 2014 Tanguy Pruvot
6
*
7
* This program is free software; you can redistribute it and/or modify it
8
* under the terms of the GNU General Public License as published by the Free
9
* Software Foundation; either version 2 of the License, or (at your option)
10
* any later version. See COPYING for more details.
11
*/
12
13
#include <cpuminer-config.h>
14
#define _GNU_SOURCE
15
16
#include <stdio.h>
17
#include <stdlib.h>
18
#include <string.h>
19
#include <stdbool.h>
20
#include <inttypes.h>
21
#include <unistd.h>
22
#include <sys/time.h>
23
#include <time.h>
24
#include <signal.h>
25
26
#include <curl/curl.h>
27
#include <jansson.h>
28
#include <openssl/sha.h>
29
30
#ifdef _MSC_VER
31
#include <windows.h>
32
#include <stdint.h>
33
#else
34
#include <errno.h>
35
#if HAVE_SYS_SYSCTL_H
36
#include <sys/types.h>
37
#if HAVE_SYS_PARAM_H
38
#include <sys/param.h>
39
#endif
40
#include <sys/sysctl.h>
41
#endif
42
#endif
43
44
#ifndef WIN32
45
#include <sys/resource.h>
46
#endif
47
48
#include "miner.h"
49
50
#ifdef WIN32
51
#include "compat/winansi.h"
52
BOOL WINAPI ConsoleHandler(DWORD);
53
#endif
54
#ifdef _MSC_VER
55
#include <Mmsystem.h>
56
#pragma comment(lib, "winmm.lib")
57
#endif
58
59
#define LP_SCANTIME 60
60
61
#ifndef min
62
#define min(a,b) (a>b ? b : a)
63
#define max(a,b) (a<b ? b : a)
64
#endif
65
66
enum workio_commands {
67
WC_GET_WORK,
68
WC_SUBMIT_WORK,
69
};
70
71
struct workio_cmd {
72
enum workio_commands cmd;
73
struct thr_info *thr;
74
union {
75
struct work *work;
76
} u;
77
};
78
79
enum algos {
80
ALGO_KECCAK, /* Keccak (old) */
81
ALGO_KECCAKC, /* Keccak */
82
ALGO_HEAVY, /* Heavy */
83
ALGO_NEOSCRYPT, /* NeoScrypt(128, 2, 1) with Salsa20/20 and ChaCha20/20 */
84
ALGO_QUARK, /* Quark */
85
ALGO_ALLIUM, /* Garlicoin double lyra2 */
86
ALGO_AXIOM, /* Shabal 256 Memohash */
87
ALGO_BASTION,
88
ALGO_BLAKE, /* Blake 256 */
89
ALGO_BLAKECOIN, /* Simplified 8 rounds Blake 256 */
90
ALGO_BLAKE2B,
91
ALGO_BLAKE2S, /* Blake2s */
92
ALGO_BMW, /* BMW 256 */
93
ALGO_C11, /* C11 Chaincoin/Flaxcoin X11 variant */
94
ALGO_CRYPTOLIGHT, /* cryptonight-light (Aeon) */
95
ALGO_CRYPTONIGHT, /* CryptoNight */
96
ALGO_DECRED, /* Decred */
97
ALGO_DMD_GR, /* Diamond */
98
ALGO_DROP, /* Dropcoin */
99
ALGO_FRESH, /* Fresh */
100
ALGO_GEEK,
101
ALGO_GROESTL, /* Groestl */
102
ALGO_JHA,
103
ALGO_LBRY, /* Lbry Sha Ripemd */
104
ALGO_LUFFA, /* Luffa (Joincoin, Doom) */
105
ALGO_LYRA2, /* Lyra2RE */
106
ALGO_LYRA2REV2, /* Lyra2REv2 */
107
ALGO_LYRA2V3, /* Lyra2REv3 (Vertcoin) */
108
ALGO_MYR_GR, /* Myriad Groestl */
109
ALGO_NIST5, /* Nist5 */
110
ALGO_PENTABLAKE, /* Pentablake */
111
ALGO_PHI1612,
112
ALGO_PHI2,
113
ALGO_PLUCK, /* Pluck (Supcoin) */
114
ALGO_QUBIT, /* Qubit */
115
ALGO_RAINFOREST, /* RainForest */
116
ALGO_SCRYPT, /* scrypt */
117
ALGO_SCRYPTJANE, /* Chacha */
118
ALGO_SHAVITE3, /* Shavite3 */
119
ALGO_SHA256D, /* SHA-256d */
120
ALGO_SIA, /* Blake2-B */
121
ALGO_SIB, /* X11 + gost (Sibcoin) */
122
ALGO_SKEIN, /* Skein */
123
ALGO_SKEIN2, /* Double skein (Woodcoin) */
124
ALGO_SONOA,
125
ALGO_S3, /* S3 */
126
ALGO_TIMETRAVEL, /* Timetravel-8 (Machinecoin) */
127
ALGO_BITCORE, /* Timetravel-10 (Bitcore) */
128
ALGO_TRIBUS, /* Denarius jh/keccak/echo */
129
ALGO_VANILLA, /* Vanilla (Blake256 8-rounds - double sha256) */
130
ALGO_VELTOR, /* Skein Shavite Shabal Streebog */
131
ALGO_X11EVO, /* Permuted X11 */
132
ALGO_X11, /* X11 */
133
ALGO_X12,
134
ALGO_X13, /* X13 */
135
ALGO_X14, /* X14 */
136
ALGO_X15, /* X15 */
137
ALGO_X16R, /* X16R */
138
ALGO_X16RV2, /* X16Rv2 */
139
ALGO_X16S,
140
ALGO_X17, /* X17 */
141
ALGO_X20R,
142
ALGO_XEVAN,
143
ALGO_YESCRYPT,
144
ALGO_YESCRYPTR8,
145
ALGO_YESCRYPTR16,
146
ALGO_YESCRYPTR32,
147
ALGO_ZR5,
148
ALGO_COUNT
149
};
150
151
static const char *algo_names[] = {
152
"keccak",
153
"keccakc",
154
"heavy",
155
"neoscrypt",
156
"quark",
157
"allium",
158
"axiom",
159
"bastion",
160
"blake",
161
"blakecoin",
162
"blake2b",
163
"blake2s",
164
"bmw",
165
"c11",
166
"cryptolight",
167
"cryptonight",
168
"decred",
169
"dmd-gr",
170
"drop",
171
"fresh",
172
"geek",
173
"groestl",
174
"jha",
175
"lbry",
176
"luffa",
177
"lyra2re",
178
"lyra2rev2",
179
"lyra2v3",
180
"myr-gr",
181
"nist5",
182
"pentablake",
183
"phi1612",
184
"phi2",
185
"pluck",
186
"qubit",
187
"rainforest",
188
"scrypt",
189
"scrypt-jane",
190
"shavite3",
191
"sha256d",
192
"sia",
193
"sib",
194
"skein",
195
"skein2",
196
"sonoa",
197
"s3",
198
"timetravel",
199
"bitcore",
200
"tribus",
201
"vanilla",
202
"veltor",
203
"x11evo",
204
"x11",
205
"x12",
206
"x13",
207
"x14",
208
"x15",
209
"x16r",
210
"x16rv2",
211
"x16s",
212
"x17",
213
"x20r",
214
"xevan",
215
"yescrypt",
216
"yescryptr8",
217
"yescryptr16",
218
"yescryptr32",
219
"zr5",
220
"\0"
221
};
222
223
bool opt_debug = false;
224
bool opt_debug_diff = false;
225
bool opt_protocol = false;
226
bool opt_benchmark = false;
227
bool opt_redirect = true;
228
bool opt_showdiff = true;
229
bool opt_extranonce = true;
230
bool want_longpoll = true;
231
bool have_longpoll = false;
232
bool have_gbt = true;
233
bool allow_getwork = true;
234
bool want_stratum = true;
235
bool have_stratum = false;
236
bool opt_stratum_stats = false;
237
bool allow_mininginfo = true;
238
bool use_syslog = false;
239
bool use_colors = true;
240
static bool opt_background = false;
241
bool opt_quiet = false;
242
int opt_maxlograte = 5;
243
bool opt_randomize = false;
244
static int opt_retries = -1;
245
static int opt_fail_pause = 10;
246
static int opt_time_limit = 0;
247
int opt_timeout = 300;
248
static int opt_scantime = 5;
249
static enum algos opt_algo = ALGO_SCRYPT;
250
static int opt_scrypt_n = 1024;
251
static int opt_pluck_n = 128;
252
static unsigned int opt_nfactor = 6;
253
int opt_n_threads = 0;
254
int64_t opt_affinity = -1L;
255
int opt_priority = 0;
256
int num_cpus;
257
char *rpc_url;
258
char *rpc_userpass;
259
char *rpc_user, *rpc_pass;
260
char *short_url = NULL;
261
static unsigned char pk_script[25] = { 0 };
262
static size_t pk_script_size = 0;
263
static char coinbase_sig[101] = { 0 };
264
char *opt_cert;
265
char *opt_proxy;
266
long opt_proxy_type;
267
struct thr_info *thr_info;
268
int work_thr_id;
269
int longpoll_thr_id = -1;
270
int stratum_thr_id = -1;
271
int api_thr_id = -1;
272
bool stratum_need_reset = false;
273
struct work_restart *work_restart = NULL;
274
struct stratum_ctx stratum;
275
bool jsonrpc_2 = false;
276
char rpc2_id[64] = "";
277
char *rpc2_blob = NULL;
278
size_t rpc2_bloblen = 0;
279
uint32_t rpc2_target = 0;
280
char *rpc2_job_id = NULL;
281
bool aes_ni_supported = false;
282
double opt_diff_factor = 1.0;
283
pthread_mutex_t rpc2_job_lock;
284
pthread_mutex_t rpc2_login_lock;
285
pthread_mutex_t applog_lock;
286
pthread_mutex_t stats_lock;
287
uint32_t zr5_pok = 0;
288
bool use_roots = false;
289
uint32_t solved_count = 0L;
290
uint32_t accepted_count = 0L;
291
uint32_t rejected_count = 0L;
292
double *thr_hashrates;
293
uint64_t global_hashrate = 0;
294
double stratum_diff = 0.;
295
double net_diff = 0.;
296
double net_hashrate = 0.;
297
uint64_t net_blocks = 0;
298
// conditional mining
299
bool conditional_state[MAX_CPUS] = { 0 };
300
double opt_max_temp = 0.0;
301
double opt_max_diff = 0.0;
302
double opt_max_rate = 0.0;
303
304
uint32_t opt_work_size = 0; /* default */
305
char *opt_api_allow = NULL;
306
int opt_api_remote = 0;
307
int opt_api_listen = 4048; /* 0 to disable */
308
309
#ifdef HAVE_GETOPT_LONG
310
#include <getopt.h>
311
#else
312
struct option {
313
const char *name;
314
int has_arg;
315
int *flag;
316
int val;
317
};
318
#endif
319
320
static char const usage[] = "\
321
Usage: " PACKAGE_NAME " [OPTIONS]\n\
322
Options:\n\
323
-a, --algo=ALGO specify the algorithm to use\n\
324
allium Garlicoin double lyra2\n\
325
axiom Shabal-256 MemoHash\n\
326
bitcore Timetravel with 10 algos\n\
327
blake Blake-256 14-rounds (SFR)\n\
328
blakecoin Blake-256 single sha256 merkle\n\
329
blake2b Blake2-B (512)\n\
330
blake2s Blake2-S (256)\n\
331
bmw BMW 256\n\
332
c11/flax C11\n\
333
cryptolight Cryptonight-light\n\
334
cryptonight Monero\n\
335
decred Blake-256 14-rounds 180 bytes\n\
336
dmd-gr Diamond-Groestl\n\
337
drop Dropcoin\n\
338
fresh Fresh\n\
339
geek GeekCash\n\
340
groestl GroestlCoin\n\
341
heavy Heavy\n\
342
jha JHA\n\
343
keccak Keccak (Old and deprecated)\n\
344
keccakc Keccak (CreativeCoin)\n\
345
luffa Luffa\n\
346
lyra2re Lyra2RE\n\
347
lyra2rev2 Lyra2REv2\n\
348
lyra2v3 Lyra2REv3 (Vertcoin)\n\
349
myr-gr Myriad-Groestl\n\
350
neoscrypt NeoScrypt(128, 2, 1)\n\
351
nist5 Nist5\n\
352
pluck Pluck:128 (Supcoin)\n\
353
pentablake Pentablake\n\
354
phi LUX initial algo\n\
355
phi2 LUX newer algo\n\
356
quark Quark\n\
357
qubit Qubit\n\
358
rainforest RainForest (256)\n\
359
scrypt scrypt(1024, 1, 1) (default)\n\
360
scrypt:N scrypt(N, 1, 1)\n\
361
scrypt-jane:N (with N factor from 4 to 30)\n\
362
shavite3 Shavite3\n\
363
sha256d SHA-256d\n\
364
sia Blake2-B\n\
365
sib X11 + gost (SibCoin)\n\
366
skein Skein+Sha (Skeincoin)\n\
367
skein2 Double Skein (Woodcoin)\n\
368
sonoa A series of 97 hashes from x17\n\
369
s3 S3\n\
370
timetravel Timetravel (Machinecoin)\n\
371
vanilla Blake-256 8-rounds\n\
372
x11evo Permuted x11\n\
373
x11 X11\n\
374
x12 X12\n\
375
x13 X13\n\
376
x14 X14\n\
377
x15 X15\n\
378
x16r X16R\n\
379
x16rv2 X16Rv2 (Raven / Trivechain)\n\
380
x16s X16S (Pigeon)\n\
381
x17 X17\n\
382
x20r X20R\n\
383
xevan Xevan (BitSend)\n\
384
yescrypt Yescrypt\n\
385
yescryptr8 Yescrypt r8\n\
386
yescryptr16 Yescrypt r16\n\
387
yescryptr32 Yescrypt r32\n\
388
zr5 ZR5\n\
389
-o, --url=URL URL of mining server\n\
390
-O, --userpass=U:P username:password pair for mining server\n\
391
-u, --user=USERNAME username for mining server\n\
392
-p, --pass=PASSWORD password for mining server\n\
393
--cert=FILE certificate for mining server using SSL\n\
394
-x, --proxy=[PROTOCOL://]HOST[:PORT] connect through a proxy\n\
395
-t, --threads=N number of miner threads (default: number of processors)\n\
396
-r, --retries=N number of times to retry if a network call fails\n\
397
(default: retry indefinitely)\n\
398
-R, --retry-pause=N time to pause between retries, in seconds (default: 30)\n\
399
--time-limit=N maximum time [s] to mine before exiting the program.\n\
400
-T, --timeout=N timeout for long poll and stratum (default: 300 seconds)\n\
401
-s, --scantime=N upper bound on time spent scanning current work when\n\
402
long polling is unavailable, in seconds (default: 5)\n\
403
--randomize Randomize scan range start to reduce duplicates\n\
404
-f, --diff-factor Divide req. difficulty by this factor (std is 1.0)\n\
405
-m, --diff-multiplier Multiply difficulty by this factor (std is 1.0)\n\
406
-n, --nfactor neoscrypt N-Factor\n\
407
--coinbase-addr=ADDR payout address for solo mining\n\
408
--coinbase-sig=TEXT data to insert in the coinbase when possible\n\
409
--max-log-rate limit per-core hashrate logs (default: 5s)\n\
410
--no-longpoll disable long polling support\n\
411
--no-getwork disable getwork support\n\
412
--no-gbt disable getblocktemplate support\n\
413
--no-stratum disable X-Stratum support\n\
414
--no-extranonce disable Stratum extranonce support\n\
415
--no-redirect ignore requests to change the URL of the mining server\n\
416
-q, --quiet disable per-thread hashmeter output\n\
417
--no-color disable colored output\n\
418
-D, --debug enable debug output\n\
419
-P, --protocol-dump verbose dump of protocol-level activities\n\
420
--hide-diff Hide submitted block and net difficulty\n"
421
#ifdef HAVE_SYSLOG_H
422
"\
423
-S, --syslog use system log for output messages\n"
424
#endif
425
"\
426
-B, --background run the miner in the background\n\
427
--benchmark run in offline benchmark mode\n\
428
--cputest debug hashes from cpu algorithms\n\
429
--cpu-affinity set process affinity to cpu core(s), mask 0x3 for cores 0 and 1\n\
430
--cpu-priority set process priority (default: 0 idle, 2 normal to 5 highest)\n\
431
-b, --api-bind IP/Port for the miner API (default: 127.0.0.1:4048)\n\
432
--api-remote Allow remote control\n\
433
--max-temp=N Only mine if cpu temp is less than specified value (linux)\n\
434
--max-rate=N[KMG] Only mine if net hashrate is less than specified value\n\
435
--max-diff=N Only mine if net difficulty is less than specified value\n\
436
-c, --config=FILE load a JSON-format configuration file\n\
437
-V, --version display version information and exit\n\
438
-h, --help display this help text and exit\n\
439
";
440
441
442
static char const short_options[] =
443
#ifdef HAVE_SYSLOG_H
444
"S"
445
#endif
446
"a:b:Bc:CDf:hm:n:p:Px:qr:R:s:t:T:o:u:O:V";
447
448
static struct option const options[] = {
449
{ "algo", 1, NULL, 'a' },
450
{ "api-bind", 1, NULL, 'b' },
451
{ "api-remote", 0, NULL, 1030 },
452
{ "background", 0, NULL, 'B' },
453
{ "benchmark", 0, NULL, 1005 },
454
{ "cputest", 0, NULL, 1006 },
455
{ "cert", 1, NULL, 1001 },
456
{ "coinbase-addr", 1, NULL, 1016 },
457
{ "coinbase-sig", 1, NULL, 1015 },
458
{ "config", 1, NULL, 'c' },
459
{ "cpu-affinity", 1, NULL, 1020 },
460
{ "cpu-priority", 1, NULL, 1021 },
461
{ "no-color", 0, NULL, 1002 },
462
{ "debug", 0, NULL, 'D' },
463
{ "diff-factor", 1, NULL, 'f' },
464
{ "diff", 1, NULL, 'f' }, // deprecated (alias)
465
{ "diff-multiplier", 1, NULL, 'm' },
466
{ "help", 0, NULL, 'h' },
467
{ "nfactor", 1, NULL, 'n' },
468
{ "no-gbt", 0, NULL, 1011 },
469
{ "no-getwork", 0, NULL, 1010 },
470
{ "no-longpoll", 0, NULL, 1003 },
471
{ "no-redirect", 0, NULL, 1009 },
472
{ "no-stratum", 0, NULL, 1007 },
473
{ "no-extranonce", 0, NULL, 1012 },
474
{ "max-temp", 1, NULL, 1060 },
475
{ "max-diff", 1, NULL, 1061 },
476
{ "max-rate", 1, NULL, 1062 },
477
{ "pass", 1, NULL, 'p' },
478
{ "protocol", 0, NULL, 'P' },
479
{ "protocol-dump", 0, NULL, 'P' },
480
{ "proxy", 1, NULL, 'x' },
481
{ "quiet", 0, NULL, 'q' },
482
{ "retries", 1, NULL, 'r' },
483
{ "retry-pause", 1, NULL, 'R' },
484
{ "randomize", 0, NULL, 1024 },
485
{ "scantime", 1, NULL, 's' },
486
{ "show-diff", 0, NULL, 1013 },
487
{ "hide-diff", 0, NULL, 1014 },
488
{ "max-log-rate", 1, NULL, 1019 },
489
#ifdef HAVE_SYSLOG_H
490
{ "syslog", 0, NULL, 'S' },
491
#endif
492
{ "time-limit", 1, NULL, 1008 },
493
{ "threads", 1, NULL, 't' },
494
{ "timeout", 1, NULL, 'T' },
495
{ "url", 1, NULL, 'o' },
496
{ "user", 1, NULL, 'u' },
497
{ "userpass", 1, NULL, 'O' },
498
{ "version", 0, NULL, 'V' },
499
{ 0, 0, 0, 0 }
500
};
501
502
static struct work g_work = {{ 0 }};
503
static time_t g_work_time = 0;
504
static pthread_mutex_t g_work_lock;
505
static bool submit_old = false;
506
static char *lp_id;
507
508
static void workio_cmd_free(struct workio_cmd *wc);
509
510
511
#ifdef __linux /* Linux specific policy and affinity management */
512
#include <sched.h>
513
514
static inline void drop_policy(void)
515
{
516
struct sched_param param;
517
param.sched_priority = 0;
518
#ifdef SCHED_IDLE
519
if (unlikely(sched_setscheduler(0, SCHED_IDLE, &param) == -1))
520
#endif
521
#ifdef SCHED_BATCH
522
sched_setscheduler(0, SCHED_BATCH, &param);
523
#endif
524
}
525
526
#ifdef __BIONIC__
527
#define pthread_setaffinity_np(tid,sz,s) {} /* only do process affinity */
528
#endif
529
530
static void affine_to_cpu_mask(int id, unsigned long mask) {
531
cpu_set_t set;
532
CPU_ZERO(&set);
533
for (uint8_t i = 0; i < num_cpus; i++) {
534
// cpu mask
535
if (mask & (1UL<<i)) { CPU_SET(i, &set); }
536
}
537
if (id == -1) {
538
// process affinity
539
sched_setaffinity(0, sizeof(&set), &set);
540
} else {
541
// thread only
542
pthread_setaffinity_np(thr_info[id].pth, sizeof(&set), &set);
543
}
544
}
545
546
#elif defined(WIN32) /* Windows */
547
static inline void drop_policy(void) { }
548
static void affine_to_cpu_mask(int id, unsigned long mask) {
549
if (id == -1)
550
SetProcessAffinityMask(GetCurrentProcess(), mask);
551
else
552
SetThreadAffinityMask(GetCurrentThread(), mask);
553
}
554
#else
555
static inline void drop_policy(void) { }
556
static void affine_to_cpu_mask(int id, unsigned long mask) { }
557
#endif
558
559
void get_currentalgo(char* buf, int sz)
560
{
561
if (opt_algo == ALGO_SCRYPTJANE)
562
snprintf(buf, sz, "%s:%d", algo_names[opt_algo], opt_scrypt_n);
563
else
564
snprintf(buf, sz, "%s", algo_names[opt_algo]);
565
}
566
567
void proper_exit(int reason)
568
{
569
#ifdef WIN32
570
if (opt_background) {
571
HWND hcon = GetConsoleWindow();
572
if (hcon) {
573
// unhide parent command line windows
574
ShowWindow(hcon, SW_SHOWMINNOACTIVE);
575
}
576
}
577
#endif
578
exit(reason);
579
}
580
581
static inline void work_free(struct work *w)
582
{
583
if (w->txs) free(w->txs);
584
if (w->workid) free(w->workid);
585
if (w->job_id) free(w->job_id);
586
if (w->xnonce2) free(w->xnonce2);
587
}
588
589
static inline void work_copy(struct work *dest, const struct work *src)
590
{
591
memcpy(dest, src, sizeof(struct work));
592
if (src->txs)
593
dest->txs = strdup(src->txs);
594
if (src->workid)
595
dest->workid = strdup(src->workid);
596
if (src->job_id)
597
dest->job_id = strdup(src->job_id);
598
if (src->xnonce2) {
599
dest->xnonce2 = (uchar*) malloc(src->xnonce2_len);
600
memcpy(dest->xnonce2, src->xnonce2, src->xnonce2_len);
601
}
602
}
603
604
/* compute nbits to get the network diff */
605
static void calc_network_diff(struct work *work)
606
{
607
// sample for diff 43.281 : 1c05ea29
608
// todo: endian reversed on longpoll could be zr5 specific...
609
uint32_t nbits = have_longpoll ? work->data[18] : swab32(work->data[18]);
610
if (opt_algo == ALGO_LBRY) nbits = swab32(work->data[26]);
611
if (opt_algo == ALGO_DECRED) nbits = work->data[29];
612
if (opt_algo == ALGO_SIA) nbits = work->data[11]; // unsure if correct
613
uint32_t bits = (nbits & 0xffffff);
614
int16_t shift = (swab32(nbits) & 0xff); // 0x1c = 28
615
616
double d = (double)0x0000ffff / (double)bits;
617
for (int m=shift; m < 29; m++) d *= 256.0;
618
for (int m=29; m < shift; m++) d /= 256.0;
619
if (opt_algo == ALGO_DECRED && shift == 28) d *= 256.0; // testnet
620
if (opt_debug_diff)
621
applog(LOG_DEBUG, "net diff: %f -> shift %u, bits %08x", d, shift, bits);
622
net_diff = d;
623
}
624
625
static bool work_decode(const json_t *val, struct work *work)
626
{
627
int i;
628
int data_size = 128, target_size = sizeof(work->target);
629
int adata_sz = 32, atarget_sz = ARRAY_SIZE(work->target);
630
631
if (opt_algo == ALGO_DROP || opt_algo == ALGO_NEOSCRYPT || opt_algo == ALGO_ZR5) {
632
data_size = 80; target_size = 32;
633
adata_sz = 20;
634
atarget_sz = target_size / sizeof(uint32_t);
635
} else if (opt_algo == ALGO_DECRED) {
636
allow_mininginfo = false;
637
data_size = 192;
638
adata_sz = 180/4;
639
} else if (use_roots) {
640
data_size = 144;
641
adata_sz = 36;
642
}
643
644
if (jsonrpc_2) {
645
return rpc2_job_decode(val, work);
646
}
647
648
if (unlikely(!jobj_binary(val, "data", work->data, data_size))) {
649
applog(LOG_ERR, "JSON invalid data");
650
goto err_out;
651
}
652
if (unlikely(!jobj_binary(val, "target", work->target, target_size))) {
653
applog(LOG_ERR, "JSON invalid target");
654
goto err_out;
655
}
656
657
for (i = 0; i < adata_sz; i++)
658
work->data[i] = le32dec(work->data + i);
659
for (i = 0; i < atarget_sz; i++)
660
work->target[i] = le32dec(work->target + i);
661
662
if ((opt_showdiff || opt_max_diff > 0.) && !allow_mininginfo)
663
calc_network_diff(work);
664
665
work->targetdiff = target_to_diff(work->target);
666
667
// for api stats, on longpoll pools
668
stratum_diff = work->targetdiff;
669
670
if (opt_algo == ALGO_DROP || opt_algo == ALGO_ZR5) {
671
#define POK_BOOL_MASK 0x00008000
672
#define POK_DATA_MASK 0xFFFF0000
673
if (work->data[0] & POK_BOOL_MASK) {
674
applog(LOG_BLUE, "POK received: %08xx", work->data[0]);
675
zr5_pok = work->data[0] & POK_DATA_MASK;
676
}
677
} else if (opt_algo == ALGO_DECRED) {
678
// some random extradata to make the work unique
679
work->data[36] = (rand()*4);
680
work->height = work->data[32];
681
// required for the getwork pools (multicoin.co)
682
if (!have_longpoll && work->height > net_blocks + 1) {
683
char netinfo[64] = { 0 };
684
if (opt_showdiff && net_diff > 0.) {
685
if (net_diff != work->targetdiff)
686
sprintf(netinfo, ", diff %.3f, target %.1f", net_diff, work->targetdiff);
687
else
688
sprintf(netinfo, ", diff %.3f", net_diff);
689
}
690
applog(LOG_BLUE, "%s block %d%s",
691
algo_names[opt_algo], work->height, netinfo);
692
net_blocks = work->height - 1;
693
}
694
} else if (opt_algo == ALGO_PHI2) {
695
if (work->data[0] & (1<<30)) use_roots = true;
696
else for (i = 20; i < 36; i++) {
697
if (work->data[i]) { use_roots = true; break; }
698
}
699
}
700
701
return true;
702
703
err_out:
704
return false;
705
}
706
707
// good alternative for wallet mining, difficulty and net hashrate
708
static const char *info_req =
709
"{\"method\": \"getmininginfo\", \"params\": [], \"id\":8}\r\n";
710
711
static bool get_mininginfo(CURL *curl, struct work *work)
712
{
713
if (have_stratum || have_longpoll || !allow_mininginfo)
714
return false;
715
716
int curl_err = 0;
717
json_t *val = json_rpc_call(curl, rpc_url, rpc_userpass, info_req, &curl_err, 0);
718
719
if (!val && curl_err == -1) {
720
allow_mininginfo = false;
721
if (opt_debug) {
722
applog(LOG_DEBUG, "getmininginfo not supported");
723
}
724
return false;
725
}
726
else {
727
json_t *res = json_object_get(val, "result");
728
// "blocks": 491493 (= current work height - 1)
729
// "difficulty": 0.99607860999999998
730
// "networkhashps": 56475980
731
if (res) {
732
json_t *key = json_object_get(res, "difficulty");
733
if (key) {
734
if (json_is_object(key))
735
key = json_object_get(key, "proof-of-work");
736
if (json_is_real(key))
737
net_diff = json_real_value(key);
738
}
739
key = json_object_get(res, "networkhashps");
740
if (key && json_is_integer(key)) {
741
net_hashrate = (double) json_integer_value(key);
742
}
743
key = json_object_get(res, "blocks");
744
if (key && json_is_integer(key)) {
745
net_blocks = json_integer_value(key);
746
}
747
if (!work->height) {
748
// complete missing data from getwork
749
work->height = (uint32_t) net_blocks + 1;
750
if (work->height > g_work.height) {
751
restart_threads();
752
if (!opt_quiet) {
753
char netinfo[64] = { 0 };
754
char srate[32] = { 0 };
755
sprintf(netinfo, "diff %.2f", net_diff);
756
if (net_hashrate) {
757
format_hashrate(net_hashrate, srate);
758
strcat(netinfo, ", net ");
759
strcat(netinfo, srate);
760
}
761
applog(LOG_BLUE, "%s block %d, %s",
762
algo_names[opt_algo], work->height, netinfo);
763
}
764
}
765
}
766
}
767
}
768
json_decref(val);
769
return true;
770
}
771
772
#define BLOCK_VERSION_CURRENT 3
773
774
static bool gbt_work_decode(const json_t *val, struct work *work)
775
{
776
int i, n;
777
uint32_t version, curtime, bits;
778
uint32_t prevhash[8];
779
uint32_t target[8];
780
int cbtx_size;
781
uchar *cbtx = NULL;
782
int tx_count, tx_size;
783
uchar txc_vi[9];
784
uchar(*merkle_tree)[32] = NULL;
785
bool coinbase_append = false;
786
bool submit_coinbase = false;
787
bool version_force = false;
788
bool version_reduce = false;
789
json_t *tmp, *txa;
790
bool rc = false;
791
792
tmp = json_object_get(val, "mutable");
793
if (tmp && json_is_array(tmp)) {
794
n = (int) json_array_size(tmp);
795
for (i = 0; i < n; i++) {
796
const char *s = json_string_value(json_array_get(tmp, i));
797
if (!s)
798
continue;
799
if (!strcmp(s, "coinbase/append"))
800
coinbase_append = true;
801
else if (!strcmp(s, "submit/coinbase"))
802
submit_coinbase = true;
803
else if (!strcmp(s, "version/force"))
804
version_force = true;
805
else if (!strcmp(s, "version/reduce"))
806
version_reduce = true;
807
}
808
}
809
810
tmp = json_object_get(val, "height");
811
if (!tmp || !json_is_integer(tmp)) {
812
applog(LOG_ERR, "JSON invalid height");
813
goto out;
814
}
815
work->height = (int) json_integer_value(tmp);
816
applog(LOG_BLUE, "Current block is %d", work->height);
817
818
tmp = json_object_get(val, "version");
819
if (!tmp || !json_is_integer(tmp)) {
820
applog(LOG_ERR, "JSON invalid version");
821
goto out;
822
}
823
version = (uint32_t) json_integer_value(tmp);
824
if ((version & 0xffU) > BLOCK_VERSION_CURRENT) {
825
if (version_reduce) {
826
version = (version & ~0xffU) | BLOCK_VERSION_CURRENT;
827
} else if (have_gbt && allow_getwork && !version_force) {
828
applog(LOG_DEBUG, "Switching to getwork, gbt version %d", version);
829
have_gbt = false;
830
goto out;
831
} else if (!version_force) {
832
applog(LOG_ERR, "Unrecognized block version: %u", version);
833
goto out;
834
}
835
}
836
837
if (unlikely(!jobj_binary(val, "previousblockhash", prevhash, sizeof(prevhash)))) {
838
applog(LOG_ERR, "JSON invalid previousblockhash");
839
goto out;
840
}
841
842
tmp = json_object_get(val, "curtime");
843
if (!tmp || !json_is_integer(tmp)) {
844
applog(LOG_ERR, "JSON invalid curtime");
845
goto out;
846
}
847
curtime = (uint32_t) json_integer_value(tmp);
848
849
if (unlikely(!jobj_binary(val, "bits", &bits, sizeof(bits)))) {
850
applog(LOG_ERR, "JSON invalid bits");
851
goto out;
852
}
853
854
/* find count and size of transactions */
855
txa = json_object_get(val, "transactions");
856
if (!txa || !json_is_array(txa)) {
857
applog(LOG_ERR, "JSON invalid transactions");
858
goto out;
859
}
860
tx_count = (int) json_array_size(txa);
861
tx_size = 0;
862
for (i = 0; i < tx_count; i++) {
863
const json_t *tx = json_array_get(txa, i);
864
const char *tx_hex = json_string_value(json_object_get(tx, "data"));
865
if (!tx_hex) {
866
applog(LOG_ERR, "JSON invalid transactions");
867
goto out;
868
}
869
tx_size += (int) (strlen(tx_hex) / 2);
870
}
871
872
/* build coinbase transaction */
873
tmp = json_object_get(val, "coinbasetxn");
874
if (tmp) {
875
const char *cbtx_hex = json_string_value(json_object_get(tmp, "data"));
876
cbtx_size = cbtx_hex ? (int) strlen(cbtx_hex) / 2 : 0;
877
cbtx = (uchar*) malloc(cbtx_size + 100);
878
if (cbtx_size < 60 || !hex2bin(cbtx, cbtx_hex, cbtx_size)) {
879
applog(LOG_ERR, "JSON invalid coinbasetxn");
880
goto out;
881
}
882
} else {
883
int64_t cbvalue;
884
if (!pk_script_size) {
885
if (allow_getwork) {
886
applog(LOG_INFO, "No payout address provided, switching to getwork");
887
have_gbt = false;
888
} else
889
applog(LOG_ERR, "No payout address provided");
890
goto out;
891
}
892
tmp = json_object_get(val, "coinbasevalue");
893
if (!tmp || !json_is_number(tmp)) {
894
applog(LOG_ERR, "JSON invalid coinbasevalue");
895
goto out;
896
}
897
cbvalue = (int64_t) (json_is_integer(tmp) ? json_integer_value(tmp) : json_number_value(tmp));
898
cbtx = (uchar*) malloc(256);
899
le32enc((uint32_t *)cbtx, 1); /* version */
900
cbtx[4] = 1; /* in-counter */
901
memset(cbtx+5, 0x00, 32); /* prev txout hash */
902
le32enc((uint32_t *)(cbtx+37), 0xffffffff); /* prev txout index */
903
cbtx_size = 43;
904
/* BIP 34: height in coinbase */
905
for (n = work->height; n; n >>= 8)
906
cbtx[cbtx_size++] = n & 0xff;
907
/* If the last byte pushed is >= 0x80, then we need to add
908
another zero byte to signal that the block height is a
909
positive number. */
910
if (cbtx[cbtx_size - 1] & 0x80)
911
cbtx[cbtx_size++] = 0;
912
cbtx[42] = cbtx_size - 43;
913
cbtx[41] = cbtx_size - 42; /* scriptsig length */
914
le32enc((uint32_t *)(cbtx+cbtx_size), 0xffffffff); /* sequence */
915
cbtx_size += 4;
916
cbtx[cbtx_size++] = 1; /* out-counter */
917
le32enc((uint32_t *)(cbtx+cbtx_size), (uint32_t)cbvalue); /* value */
918
le32enc((uint32_t *)(cbtx+cbtx_size+4), cbvalue >> 32);
919
cbtx_size += 8;
920
cbtx[cbtx_size++] = (uint8_t) pk_script_size; /* txout-script length */
921
memcpy(cbtx+cbtx_size, pk_script, pk_script_size);
922
cbtx_size += (int) pk_script_size;
923
le32enc((uint32_t *)(cbtx+cbtx_size), 0); /* lock time */
924
cbtx_size += 4;
925
coinbase_append = true;
926
}
927
if (coinbase_append) {
928
unsigned char xsig[100];
929
int xsig_len = 0;
930
if (*coinbase_sig) {
931
n = (int) strlen(coinbase_sig);
932
if (cbtx[41] + xsig_len + n <= 100) {
933
memcpy(xsig+xsig_len, coinbase_sig, n);
934
xsig_len += n;
935
} else {
936
applog(LOG_WARNING, "Signature does not fit in coinbase, skipping");
937
}
938
}
939
tmp = json_object_get(val, "coinbaseaux");
940
if (tmp && json_is_object(tmp)) {
941
void *iter = json_object_iter(tmp);
942
while (iter) {
943
unsigned char buf[100];
944
const char *s = json_string_value(json_object_iter_value(iter));
945
n = s ? (int) (strlen(s) / 2) : 0;
946
if (!s || n > 100 || !hex2bin(buf, s, n)) {
947
applog(LOG_ERR, "JSON invalid coinbaseaux");
948
break;
949
}
950
if (cbtx[41] + xsig_len + n <= 100) {
951
memcpy(xsig+xsig_len, buf, n);
952
xsig_len += n;
953
}
954
iter = json_object_iter_next(tmp, iter);
955
}
956
}
957
if (xsig_len) {
958
unsigned char *ssig_end = cbtx + 42 + cbtx[41];
959
int push_len = cbtx[41] + xsig_len < 76 ? 1 :
960
cbtx[41] + 2 + xsig_len > 100 ? 0 : 2;
961
n = xsig_len + push_len;
962
memmove(ssig_end + n, ssig_end, cbtx_size - 42 - cbtx[41]);
963
cbtx[41] += n;
964
if (push_len == 2)
965
*(ssig_end++) = 0x4c; /* OP_PUSHDATA1 */
966
if (push_len)
967
*(ssig_end++) = xsig_len;
968
memcpy(ssig_end, xsig, xsig_len);
969
cbtx_size += n;
970
}
971
}
972
973
n = varint_encode(txc_vi, 1 + tx_count);
974
work->txs = (char*) malloc(2 * (n + cbtx_size + tx_size) + 1);
975
bin2hex(work->txs, txc_vi, n);
976
bin2hex(work->txs + 2*n, cbtx, cbtx_size);
977
978
/* generate merkle root */
979
merkle_tree = (uchar(*)[32]) calloc(((1 + tx_count + 1) & ~1), 32);
980
sha256d(merkle_tree[0], cbtx, cbtx_size);
981
for (i = 0; i < tx_count; i++) {
982
tmp = json_array_get(txa, i);
983
const char *tx_hex = json_string_value(json_object_get(tmp, "data"));
984
const int tx_size = tx_hex ? (int) (strlen(tx_hex) / 2) : 0;
985
unsigned char *tx = (uchar*) malloc(tx_size);
986
if (!tx_hex || !hex2bin(tx, tx_hex, tx_size)) {
987
applog(LOG_ERR, "JSON invalid transactions");
988
free(tx);
989
goto out;
990
}
991
sha256d(merkle_tree[1 + i], tx, tx_size);
992
if (!submit_coinbase)
993
strcat(work->txs, tx_hex);
994
}
995
n = 1 + tx_count;
996
while (n > 1) {
997
if (n % 2) {
998
memcpy(merkle_tree[n], merkle_tree[n-1], 32);
999
++n;
1000
}
1001
n /= 2;
1002
for (i = 0; i < n; i++)
1003
sha256d(merkle_tree[i], merkle_tree[2*i], 64);
1004
}
1005
1006
/* assemble block header */
1007
work->data[0] = swab32(version);
1008
for (i = 0; i < 8; i++)
1009
work->data[8 - i] = le32dec(prevhash + i);
1010
for (i = 0; i < 8; i++)
1011
work->data[9 + i] = be32dec((uint32_t *)merkle_tree[0] + i);
1012
work->data[17] = swab32(curtime);
1013
work->data[18] = le32dec(&bits);
1014
memset(work->data + 19, 0x00, 52);
1015
1016
work->data[20] = 0x80000000;
1017
work->data[31] = 0x00000280;
1018
1019
if (unlikely(!jobj_binary(val, "target", target, sizeof(target)))) {
1020
applog(LOG_ERR, "JSON invalid target");
1021
goto out;
1022
}
1023
for (i = 0; i < ARRAY_SIZE(work->target); i++)
1024
work->target[7 - i] = be32dec(target + i);
1025
1026
tmp = json_object_get(val, "workid");
1027
if (tmp) {
1028
if (!json_is_string(tmp)) {
1029
applog(LOG_ERR, "JSON invalid workid");
1030
goto out;
1031
}
1032
work->workid = strdup(json_string_value(tmp));
1033
}
1034
1035
rc = true;
1036
out:
1037
/* Long polling */
1038
tmp = json_object_get(val, "longpollid");
1039
if (want_longpoll && json_is_string(tmp)) {
1040
free(lp_id);
1041
lp_id = strdup(json_string_value(tmp));
1042
if (!have_longpoll) {
1043
char *lp_uri;
1044
tmp = json_object_get(val, "longpolluri");
1045
lp_uri = json_is_string(tmp) ? strdup(json_string_value(tmp)) : rpc_url;
1046
have_longpoll = true;
1047
tq_push(thr_info[longpoll_thr_id].q, lp_uri);
1048
}
1049
}
1050
1051
free(merkle_tree);
1052
free(cbtx);
1053
return rc;
1054
}
1055
1056
#define YES "yes!"
1057
#define YAY "yay!!!"
1058
#define BOO "booooo"
1059
1060
static int share_result(int result, struct work *work, const char *reason)
1061
{
1062
const char *flag;
1063
char suppl[32] = { 0 };
1064
char s[345];
1065
double hashrate;
1066
double sharediff = work ? work->sharediff : stratum.sharediff;
1067
int i;
1068
1069
hashrate = 0.;
1070
pthread_mutex_lock(&stats_lock);
1071
for (i = 0; i < opt_n_threads; i++)
1072
hashrate += thr_hashrates[i];
1073
result ? accepted_count++ : rejected_count++;
1074
pthread_mutex_unlock(&stats_lock);
1075
1076
global_hashrate = (uint64_t) hashrate;
1077
1078
if (!net_diff || sharediff < net_diff) {
1079
flag = use_colors ?
1080
(result ? CL_GRN YES : CL_RED BOO)
1081
: (result ? "(" YES ")" : "(" BOO ")");
1082
} else {
1083
solved_count++;
1084
flag = use_colors ?
1085
(result ? CL_GRN YAY : CL_RED BOO)
1086
: (result ? "(" YAY ")" : "(" BOO ")");
1087
}
1088
1089
if (opt_showdiff)
1090
sprintf(suppl, "diff %.3f", sharediff);
1091
else // accepted percent
1092
sprintf(suppl, "%.2f%%", 100. * accepted_count / (accepted_count + rejected_count));
1093
1094
switch (opt_algo) {
1095
case ALGO_AXIOM:
1096
case ALGO_CRYPTOLIGHT:
1097
case ALGO_CRYPTONIGHT:
1098
case ALGO_PLUCK:
1099
case ALGO_SCRYPTJANE:
1100
sprintf(s, hashrate >= 1e6 ? "%.0f" : "%.2f", hashrate);
1101
applog(LOG_NOTICE, "accepted: %lu/%lu (%s), %s H/s %s",
1102
accepted_count, accepted_count + rejected_count,
1103
suppl, s, flag);
1104
break;
1105
default:
1106
sprintf(s, hashrate >= 1e6 ? "%.0f" : "%.2f", hashrate / 1000.0);
1107
applog(LOG_NOTICE, "accepted: %lu/%lu (%s), %s kH/s %s",
1108
accepted_count, accepted_count + rejected_count,
1109
suppl, s, flag);
1110
break;
1111
}
1112
1113
if (reason) {
1114
applog(LOG_WARNING, "reject reason: %s", reason);
1115
if (0 && strncmp(reason, "low difficulty share", 20) == 0) {
1116
opt_diff_factor = (opt_diff_factor * 2.0) / 3.0;
1117
applog(LOG_WARNING, "factor reduced to : %0.2f", opt_diff_factor);
1118
return 0;
1119
}
1120
}
1121
return 1;
1122
}
1123
1124
static bool submit_upstream_work(CURL *curl, struct work *work)
1125
{
1126
json_t *val, *res, *reason;
1127
char s[JSON_BUF_LEN];
1128
int i;
1129
bool rc = false;
1130
1131
/* pass if the previous hash is not the current previous hash */
1132
if (opt_algo != ALGO_SIA && !submit_old && memcmp(&work->data[1], &g_work.data[1], 32)) {
1133
if (opt_debug)
1134
applog(LOG_DEBUG, "DEBUG: stale work detected, discarding");
1135
return true;
1136
}
1137
1138
if (!have_stratum && allow_mininginfo) {
1139
struct work wheight;
1140
get_mininginfo(curl, &wheight);
1141
if (work->height && work->height <= net_blocks) {
1142
if (opt_debug)
1143
applog(LOG_WARNING, "block %u was already solved", work->height);
1144
return true;
1145
}
1146
}
1147
1148
if (have_stratum) {
1149
uint32_t ntime, nonce;
1150
char ntimestr[9], noncestr[9];
1151
1152
if (jsonrpc_2) {
1153
uchar hash[32];
1154
1155
bin2hex(noncestr, (const unsigned char *)work->data + 39, 4);
1156
switch(opt_algo) {
1157
case ALGO_CRYPTOLIGHT:
1158
cryptolight_hash(hash, work->data);
1159
break;
1160
case ALGO_CRYPTONIGHT:
1161
cryptonight_hash(hash, work->data);
1162
default:
1163
break;
1164
}
1165
char *hashhex = abin2hex(hash, 32);
1166
snprintf(s, JSON_BUF_LEN,
1167
"{\"method\": \"submit\", \"params\": {\"id\": \"%s\", \"job_id\": \"%s\", \"nonce\": \"%s\", \"result\": \"%s\"}, \"id\":4}\r\n",
1168
rpc2_id, work->job_id, noncestr, hashhex);
1169
free(hashhex);
1170
} else {
1171
char *xnonce2str;
1172
1173
switch (opt_algo) {
1174
case ALGO_DECRED:
1175
/* reversed */
1176
be32enc(&ntime, work->data[34]);
1177
be32enc(&nonce, work->data[35]);
1178
break;
1179
case ALGO_LBRY:
1180
le32enc(&ntime, work->data[25]);
1181
le32enc(&nonce, work->data[27]);
1182
break;
1183
case ALGO_DROP:
1184
case ALGO_NEOSCRYPT:
1185
case ALGO_ZR5:
1186
/* reversed */
1187
be32enc(&ntime, work->data[17]);
1188
be32enc(&nonce, work->data[19]);
1189
break;
1190
case ALGO_SIA:
1191
/* reversed */
1192
be32enc(&ntime, work->data[10]);
1193
be32enc(&nonce, work->data[8]);
1194
break;
1195
default:
1196
le32enc(&ntime, work->data[17]);
1197
le32enc(&nonce, work->data[19]);
1198
}
1199
1200
bin2hex(ntimestr, (const unsigned char *)(&ntime), 4);
1201
bin2hex(noncestr, (const unsigned char *)(&nonce), 4);
1202
if (opt_algo == ALGO_DECRED) {
1203
xnonce2str = abin2hex((unsigned char*)(&work->data[36]), stratum.xnonce1_size);
1204
} else if (opt_algo == ALGO_SIA) {
1205
uint16_t high_nonce = swab32(work->data[9]) >> 16;
1206
xnonce2str = abin2hex((unsigned char*)(&high_nonce), 2);
1207
} else {
1208
xnonce2str = abin2hex(work->xnonce2, work->xnonce2_len);
1209
}
1210
snprintf(s, JSON_BUF_LEN,
1211
"{\"method\": \"mining.submit\", \"params\": [\"%s\", \"%s\", \"%s\", \"%s\", \"%s\"], \"id\":4}",
1212
rpc_user, work->job_id, xnonce2str, ntimestr, noncestr);
1213
free(xnonce2str);
1214
}
1215
1216
// store to keep/display solved blocs (work struct not linked on accept notification)
1217
stratum.sharediff = work->sharediff;
1218
1219
if (unlikely(!stratum_send_line(&stratum, s))) {
1220
applog(LOG_ERR, "submit_upstream_work stratum_send_line failed");
1221
goto out;
1222
}
1223
1224
} else if (work->txs) { /* gbt */
1225
1226
char data_str[2 * sizeof(work->data) + 1];
1227
char *req;
1228
1229
for (i = 0; i < ARRAY_SIZE(work->data); i++)
1230
be32enc(work->data + i, work->data[i]);
1231
bin2hex(data_str, (unsigned char *)work->data, 80);
1232
if (work->workid) {
1233
char *params;
1234
val = json_object();
1235
json_object_set_new(val, "workid", json_string(work->workid));
1236
params = json_dumps(val, 0);
1237
json_decref(val);
1238
req = (char*) malloc(128 + 2 * 80 + strlen(work->txs) + strlen(params));
1239
sprintf(req,
1240
"{\"method\": \"submitblock\", \"params\": [\"%s%s\", %s], \"id\":4}\r\n",
1241
data_str, work->txs, params);
1242
free(params);
1243
} else {
1244
req = (char*) malloc(128 + 2 * 80 + strlen(work->txs));
1245
sprintf(req,
1246
"{\"method\": \"submitblock\", \"params\": [\"%s%s\"], \"id\":4}\r\n",
1247
data_str, work->txs);
1248
}
1249
1250
val = json_rpc_call(curl, rpc_url, rpc_userpass, req, NULL, 0);
1251
free(req);
1252
if (unlikely(!val)) {
1253
applog(LOG_ERR, "submit_upstream_work json_rpc_call failed");
1254
goto out;
1255
}
1256
1257
res = json_object_get(val, "result");
1258
if (json_is_object(res)) {
1259
char *res_str;
1260
bool sumres = false;
1261
void *iter = json_object_iter(res);
1262
while (iter) {
1263
if (json_is_null(json_object_iter_value(iter))) {
1264
sumres = true;
1265
break;
1266
}
1267
iter = json_object_iter_next(res, iter);
1268
}
1269
res_str = json_dumps(res, 0);
1270
share_result(sumres, work, res_str);
1271
free(res_str);
1272
} else
1273
share_result(json_is_null(res), work, json_string_value(res));
1274
1275
json_decref(val);
1276
1277
} else {
1278
1279
char* gw_str = NULL;
1280
int data_size = 128;
1281
int adata_sz;
1282
1283
if (jsonrpc_2) {
1284
char noncestr[9];
1285
uchar hash[32];
1286
char *hashhex;
1287
1288
bin2hex(noncestr, (const unsigned char *)work->data + 39, 4);
1289
1290
switch(opt_algo) {
1291
case ALGO_CRYPTOLIGHT:
1292
cryptolight_hash(hash, work->data);
1293
break;
1294
case ALGO_CRYPTONIGHT:
1295
cryptonight_hash(hash, work->data);
1296
default:
1297
break;
1298
}
1299
hashhex = abin2hex(&hash[0], 32);
1300
snprintf(s, JSON_BUF_LEN,
1301
"{\"method\": \"submit\", \"params\": "
1302
"{\"id\": \"%s\", \"job_id\": \"%s\", \"nonce\": \"%s\", \"result\": \"%s\"},"
1303
"\"id\":4}\r\n",
1304
rpc2_id, work->job_id, noncestr, hashhex);
1305
free(hashhex);
1306
1307
/* issue JSON-RPC request */
1308
val = json_rpc2_call(curl, rpc_url, rpc_userpass, s, NULL, 0);
1309
if (unlikely(!val)) {
1310
applog(LOG_ERR, "submit_upstream_work json_rpc_call failed");
1311
goto out;
1312
}
1313
res = json_object_get(val, "result");
1314
json_t *status = json_object_get(res, "status");
1315
bool valid = !strcmp(status ? json_string_value(status) : "", "OK");
1316
if (valid)
1317
share_result(valid, work, NULL);
1318
else {
1319
json_t *err = json_object_get(res, "error");
1320
const char *sreason = json_string_value(json_object_get(err, "message"));
1321
share_result(valid, work, sreason);
1322
if (!strcasecmp("Invalid job id", sreason)) {
1323
work_free(work);
1324
work_copy(work, &g_work);
1325
g_work_time = 0;
1326
restart_threads();
1327
}
1328
}
1329
json_decref(val);
1330
return true;
1331
1332
} else if (opt_algo == ALGO_DROP || opt_algo == ALGO_NEOSCRYPT || opt_algo == ALGO_ZR5) {
1333
/* different data size */
1334
data_size = 80;
1335
} else if (opt_algo == ALGO_DECRED) {
1336
/* bigger data size : 180 + terminal hash ending */
1337
data_size = 192;
1338
} else if (opt_algo == ALGO_PHI2 && use_roots) {
1339
data_size = 144;
1340
}
1341
1342
adata_sz = data_size / sizeof(uint32_t);
1343
if (opt_algo == ALGO_DECRED) adata_sz = 180 / 4; // dont touch the end tag
1344
1345
/* build hex string */
1346
for (i = 0; i < adata_sz; i++)
1347
le32enc(&work->data[i], work->data[i]);
1348
1349
gw_str = abin2hex((uchar*)work->data, data_size);
1350
1351
if (unlikely(!gw_str)) {
1352
applog(LOG_ERR, "submit_upstream_work OOM");
1353
return false;
1354
}
1355
1356
//applog(LOG_WARNING, gw_str);
1357
1358
/* build JSON-RPC request */
1359
snprintf(s, JSON_BUF_LEN,
1360
"{\"method\": \"getwork\", \"params\": [\"%s\"], \"id\":4}\r\n", gw_str);
1361
free(gw_str);
1362
1363
/* issue JSON-RPC request */
1364
val = json_rpc_call(curl, rpc_url, rpc_userpass, s, NULL, 0);
1365
if (unlikely(!val)) {
1366
applog(LOG_ERR, "submit_upstream_work json_rpc_call failed");
1367
goto out;
1368
}
1369
res = json_object_get(val, "result");
1370
reason = json_object_get(val, "reject-reason");
1371
share_result(json_is_true(res), work, reason ? json_string_value(reason) : NULL);
1372
1373
json_decref(val);
1374
}
1375
1376
rc = true;
1377
1378
out:
1379
return rc;
1380
}
1381
1382
static const char *getwork_req =
1383
"{\"method\": \"getwork\", \"params\": [], \"id\":0}\r\n";
1384
1385
#define GBT_CAPABILITIES "[\"coinbasetxn\", \"coinbasevalue\", \"longpoll\", \"workid\"]"
1386
1387
static const char *gbt_req =
1388
"{\"method\": \"getblocktemplate\", \"params\": [{\"capabilities\": "
1389
GBT_CAPABILITIES "}], \"id\":0}\r\n";
1390
static const char *gbt_lp_req =
1391
"{\"method\": \"getblocktemplate\", \"params\": [{\"capabilities\": "
1392
GBT_CAPABILITIES ", \"longpollid\": \"%s\"}], \"id\":0}\r\n";
1393
1394
static bool get_upstream_work(CURL *curl, struct work *work)
1395
{
1396
json_t *val;
1397
int err;
1398
bool rc;
1399
struct timeval tv_start, tv_end, diff;
1400
1401
start:
1402
gettimeofday(&tv_start, NULL);
1403
1404
if (jsonrpc_2) {
1405
char s[128];
1406
snprintf(s, 128, "{\"method\": \"getjob\", \"params\": {\"id\": \"%s\"}, \"id\":1}\r\n", rpc2_id);
1407
val = json_rpc2_call(curl, rpc_url, rpc_userpass, s, NULL, 0);
1408
} else {
1409
val = json_rpc_call(curl, rpc_url, rpc_userpass,
1410
have_gbt ? gbt_req : getwork_req,
1411
&err, have_gbt ? JSON_RPC_QUIET_404 : 0);
1412
}
1413
gettimeofday(&tv_end, NULL);
1414
1415
if (have_stratum) {
1416
if (val)
1417
json_decref(val);
1418
return true;
1419
}
1420
1421
if (!have_gbt && !allow_getwork) {
1422
applog(LOG_ERR, "No usable protocol");
1423
if (val)
1424
json_decref(val);
1425
return false;
1426
}
1427
1428
if (have_gbt && allow_getwork && !val && err == CURLE_OK) {
1429
applog(LOG_NOTICE, "getblocktemplate failed, falling back to getwork");
1430
have_gbt = false;
1431
goto start;
1432
}
1433
1434
if (!val)
1435
return false;
1436
1437
if (have_gbt) {
1438
rc = gbt_work_decode(json_object_get(val, "result"), work);
1439
if (!have_gbt) {
1440
json_decref(val);
1441
goto start;
1442
}
1443
} else {
1444
rc = work_decode(json_object_get(val, "result"), work);
1445
}
1446
1447
if (opt_protocol && rc) {
1448
timeval_subtract(&diff, &tv_end, &tv_start);
1449
applog(LOG_DEBUG, "got new work in %.2f ms",
1450
(1000.0 * diff.tv_sec) + (0.001 * diff.tv_usec));
1451
}
1452
1453
json_decref(val);
1454
1455
// store work height in solo
1456
get_mininginfo(curl, work);
1457
1458
return rc;
1459
}
1460
1461
static void workio_cmd_free(struct workio_cmd *wc)
1462
{
1463
if (!wc)
1464
return;
1465
1466
switch (wc->cmd) {
1467
case WC_SUBMIT_WORK:
1468
work_free(wc->u.work);
1469
free(wc->u.work);
1470
break;
1471
default: /* do nothing */
1472
break;
1473
}
1474
1475
memset(wc, 0, sizeof(*wc)); /* poison */
1476
free(wc);
1477
}
1478
1479
static bool workio_get_work(struct workio_cmd *wc, CURL *curl)
1480
{
1481
struct work *ret_work;
1482
int failures = 0;
1483
1484
ret_work = (struct work*) calloc(1, sizeof(*ret_work));
1485
if (!ret_work)
1486
return false;
1487
1488
/* obtain new work from bitcoin via JSON-RPC */
1489
while (!get_upstream_work(curl, ret_work)) {
1490
if (unlikely((opt_retries >= 0) && (++failures > opt_retries))) {
1491
applog(LOG_ERR, "json_rpc_call failed, terminating workio thread");
1492
free(ret_work);
1493
return false;
1494
}
1495
1496
/* pause, then restart work-request loop */
1497
applog(LOG_ERR, "json_rpc_call failed, retry after %d seconds",
1498
opt_fail_pause);
1499
sleep(opt_fail_pause);
1500
}
1501
1502
/* send work to requesting thread */
1503
if (!tq_push(wc->thr->q, ret_work))
1504
free(ret_work);
1505
1506
return true;
1507
}
1508
1509
static bool workio_submit_work(struct workio_cmd *wc, CURL *curl)
1510
{
1511
int failures = 0;
1512
1513
/* submit solution to bitcoin via JSON-RPC */
1514
while (!submit_upstream_work(curl, wc->u.work)) {
1515
if (unlikely((opt_retries >= 0) && (++failures > opt_retries))) {
1516
applog(LOG_ERR, "...terminating workio thread");
1517
return false;
1518
}
1519
1520
/* pause, then restart work-request loop */
1521
if (!opt_benchmark)
1522
applog(LOG_ERR, "...retry after %d seconds", opt_fail_pause);
1523
sleep(opt_fail_pause);
1524
}
1525
1526
return true;
1527
}
1528
1529
bool rpc2_login(CURL *curl)
1530
{
1531
json_t *val;
1532
bool rc = false;
1533
struct timeval tv_start, tv_end, diff;
1534
char s[JSON_BUF_LEN];
1535
1536
if (!jsonrpc_2)
1537
return false;
1538
1539
snprintf(s, JSON_BUF_LEN, "{\"method\": \"login\", \"params\": {"
1540
"\"login\": \"%s\", \"pass\": \"%s\", \"agent\": \"%s\"}, \"id\": 1}",
1541
rpc_user, rpc_pass, USER_AGENT);
1542
1543
gettimeofday(&tv_start, NULL);
1544
val = json_rpc_call(curl, rpc_url, rpc_userpass, s, NULL, 0);
1545
gettimeofday(&tv_end, NULL);
1546
1547
if (!val)
1548
goto end;
1549
1550
// applog(LOG_DEBUG, "JSON value: %s", json_dumps(val, 0));
1551
1552
rc = rpc2_login_decode(val);
1553
1554
json_t *result = json_object_get(val, "result");
1555
1556
if (!result)
1557
goto end;
1558
1559
json_t *job = json_object_get(result, "job");
1560
if (!rpc2_job_decode(job, &g_work)) {
1561
goto end;
1562
}
1563
1564
if (opt_debug && rc) {
1565
timeval_subtract(&diff, &tv_end, &tv_start);
1566
applog(LOG_DEBUG, "DEBUG: authenticated in %d ms",
1567
diff.tv_sec * 1000 + diff.tv_usec / 1000);
1568
}
1569
1570
json_decref(val);
1571
end:
1572
return rc;
1573
}
1574
1575
bool rpc2_workio_login(CURL *curl)
1576
{
1577
int failures = 0;
1578
if (opt_benchmark)
1579
return true;
1580
/* submit solution to bitcoin via JSON-RPC */
1581
pthread_mutex_lock(&rpc2_login_lock);
1582
while (!rpc2_login(curl)) {
1583
if (unlikely((opt_retries >= 0) && (++failures > opt_retries))) {
1584
applog(LOG_ERR, "...terminating workio thread");
1585
pthread_mutex_unlock(&rpc2_login_lock);
1586
return false;
1587
}
1588
1589
/* pause, then restart work-request loop */
1590
if (!opt_benchmark)
1591
applog(LOG_ERR, "...retry after %d seconds", opt_fail_pause);
1592
sleep(opt_fail_pause);
1593
pthread_mutex_unlock(&rpc2_login_lock);
1594
pthread_mutex_lock(&rpc2_login_lock);
1595
}
1596
pthread_mutex_unlock(&rpc2_login_lock);
1597
1598
return true;
1599
}
1600
1601
static void *workio_thread(void *userdata)
1602
{
1603
struct thr_info *mythr = (struct thr_info *) userdata;
1604
CURL *curl;
1605
bool ok = true;
1606
1607
curl = curl_easy_init();
1608
if (unlikely(!curl)) {
1609
applog(LOG_ERR, "CURL initialization failed");
1610
return NULL;
1611
}
1612
1613
if(jsonrpc_2 && !have_stratum) {
1614
ok = rpc2_workio_login(curl);
1615
}
1616
1617
while (ok) {
1618
struct workio_cmd *wc;
1619
1620
/* wait for workio_cmd sent to us, on our queue */
1621
wc = (struct workio_cmd *) tq_pop(mythr->q, NULL);
1622
if (!wc) {
1623
ok = false;
1624
break;
1625
}
1626
1627
/* process workio_cmd */
1628
switch (wc->cmd) {
1629
case WC_GET_WORK:
1630
ok = workio_get_work(wc, curl);
1631
break;
1632
case WC_SUBMIT_WORK:
1633
ok = workio_submit_work(wc, curl);
1634
break;
1635
1636
default: /* should never happen */
1637
ok = false;
1638
break;
1639
}
1640
1641
workio_cmd_free(wc);
1642
}
1643
1644
tq_freeze(mythr->q);
1645
curl_easy_cleanup(curl);
1646
1647
return NULL;
1648
}
1649
1650
static bool get_work(struct thr_info *thr, struct work *work)
1651
{
1652
struct workio_cmd *wc;
1653
struct work *work_heap;
1654
1655
if (opt_benchmark) {
1656
uint32_t ts = (uint32_t) time(NULL);
1657
for (int n=0; n<74; n++) ((char*)work->data)[n] = n;
1658
//memset(work->data, 0x55, 76);
1659
work->data[17] = swab32(ts);
1660
memset(work->data + 19, 0x00, 52);
1661
if (opt_algo == ALGO_DECRED) {
1662
memset(&work->data[35], 0x00, 52);
1663
} else {
1664
work->data[20] = 0x80000000;
1665
work->data[31] = 0x00000280;
1666
}
1667
memset(work->target, 0x00, sizeof(work->target));
1668
return true;
1669
}
1670
1671
/* fill out work request message */
1672
wc = (struct workio_cmd *) calloc(1, sizeof(*wc));
1673
if (!wc)
1674
return false;
1675
1676
wc->cmd = WC_GET_WORK;
1677
wc->thr = thr;
1678
1679
/* send work request to workio thread */
1680
if (!tq_push(thr_info[work_thr_id].q, wc)) {
1681
workio_cmd_free(wc);
1682
return false;
1683
}
1684
1685
/* wait for response, a unit of work */
1686
work_heap = (struct work*) tq_pop(thr->q, NULL);
1687
if (!work_heap)
1688
return false;
1689
1690
/* copy returned work into storage provided by caller */
1691
memcpy(work, work_heap, sizeof(*work));
1692
free(work_heap);
1693
1694
return true;
1695
}
1696
1697
static bool submit_work(struct thr_info *thr, const struct work *work_in)
1698
{
1699
struct workio_cmd *wc;
1700
1701
/* fill out work request message */
1702
wc = (struct workio_cmd *) calloc(1, sizeof(*wc));
1703
if (!wc)
1704
return false;
1705
1706
wc->u.work = (struct work*) malloc(sizeof(*work_in));
1707
if (!wc->u.work)
1708
goto err_out;
1709
1710
wc->cmd = WC_SUBMIT_WORK;
1711
wc->thr = thr;
1712
work_copy(wc->u.work, work_in);
1713
1714
/* send solution to workio thread */
1715
if (!tq_push(thr_info[work_thr_id].q, wc))
1716
goto err_out;
1717
1718
return true;
1719
1720
err_out:
1721
workio_cmd_free(wc);
1722
return false;
1723
}
1724
1725
static void stratum_gen_work(struct stratum_ctx *sctx, struct work *work)
1726
{
1727
uint32_t extraheader[32] = { 0 };
1728
uchar merkle_root[64] = { 0 };
1729
int i, headersize = 0;
1730
1731
pthread_mutex_lock(&sctx->work_lock);
1732
1733
if (jsonrpc_2) {
1734
work_free(work);
1735
work_copy(work, &sctx->work);
1736
pthread_mutex_unlock(&sctx->work_lock);
1737
} else {
1738
free(work->job_id);
1739
work->job_id = strdup(sctx->job.job_id);
1740
work->xnonce2_len = sctx->xnonce2_size;
1741
work->xnonce2 = (uchar*) realloc(work->xnonce2, sctx->xnonce2_size);
1742
memcpy(work->xnonce2, sctx->job.xnonce2, sctx->xnonce2_size);
1743
1744
/* Generate merkle root */
1745
switch (opt_algo) {
1746
case ALGO_DECRED:
1747
// getwork over stratum, getwork merkle + header passed in coinb1
1748
memcpy(merkle_root, sctx->job.coinbase, 32);
1749
headersize = min((int)sctx->job.coinbase_size - 32, sizeof(extraheader));
1750
memcpy(extraheader, &sctx->job.coinbase[32], headersize);
1751
break;
1752
case ALGO_HEAVY:
1753
heavyhash(merkle_root, sctx->job.coinbase, (int)sctx->job.coinbase_size);
1754
break;
1755
case ALGO_GROESTL:
1756
case ALGO_KECCAK:
1757
case ALGO_BLAKECOIN:
1758
SHA256(sctx->job.coinbase, (int) sctx->job.coinbase_size, merkle_root);
1759
break;
1760
case ALGO_SIA:
1761
// getwork over stratum, getwork merkle + header passed in coinb1
1762
memcpy(merkle_root, sctx->job.coinbase, 32);
1763
headersize = min((int)sctx->job.coinbase_size - 32, sizeof(extraheader));
1764
memcpy(extraheader, &sctx->job.coinbase[32], headersize);
1765
break;
1766
default:
1767
sha256d(merkle_root, sctx->job.coinbase, (int) sctx->job.coinbase_size);
1768
}
1769
1770
if (!headersize)
1771
for (i = 0; i < sctx->job.merkle_count; i++) {
1772
memcpy(merkle_root + 32, sctx->job.merkle[i], 32);
1773
if (opt_algo == ALGO_HEAVY)
1774
heavyhash(merkle_root, merkle_root, 64);
1775
else
1776
sha256d(merkle_root, merkle_root, 64);
1777
}
1778
1779
/* Increment extranonce2 */
1780
for (size_t t = 0; t < sctx->xnonce2_size && !(++sctx->job.xnonce2[t]); t++)
1781
;
1782
1783
/* Assemble block header */
1784
memset(work->data, 0, 128);
1785
work->data[0] = le32dec(sctx->job.version);
1786
for (i = 0; i < 8; i++)
1787
work->data[1 + i] = le32dec((uint32_t *) sctx->job.prevhash + i);
1788
for (i = 0; i < 8; i++)
1789
work->data[9 + i] = be32dec((uint32_t *) merkle_root + i);
1790
1791
if (opt_algo == ALGO_DECRED) {
1792
uint32_t* extradata = (uint32_t*) sctx->xnonce1;
1793
for (i = 0; i < 8; i++) // prevhash
1794
work->data[1 + i] = swab32(work->data[1 + i]);
1795
for (i = 0; i < 8; i++) // merkle
1796
work->data[9 + i] = swab32(work->data[9 + i]);
1797
for (i = 0; i < headersize/4; i++) // header
1798
work->data[17 + i] = extraheader[i];
1799
// extradata
1800
for (i = 0; i < sctx->xnonce1_size/4; i++)
1801
work->data[36 + i] = extradata[i];
1802
for (i = 36 + (int) sctx->xnonce1_size/4; i < 45; i++)
1803
work->data[i] = 0;
1804
work->data[37] = (rand()*4) << 8;
1805
sctx->bloc_height = work->data[32];
1806
//applog_hex(work->data, 180);
1807
//applog_hex(&work->data[36], 36);
1808
} else if (opt_algo == ALGO_LBRY) {
1809
for (i = 0; i < 8; i++)
1810
work->data[17 + i] = ((uint32_t*)sctx->job.extra)[i];
1811
work->data[25] = le32dec(sctx->job.ntime);
1812
work->data[26] = le32dec(sctx->job.nbits);
1813
work->data[28] = 0x80000000;
1814
} else if (opt_algo == ALGO_PHI2) {
1815
work->data[17] = le32dec(sctx->job.ntime);
1816
work->data[18] = le32dec(sctx->job.nbits);
1817
for (i = 0; i < 16; i++)
1818
work->data[20 + i] = ((uint32_t*)sctx->job.extra)[i];
1819
//applog_hex(&work->data[0], 144);
1820
} else if (opt_algo == ALGO_SIA) {
1821
for (i = 0; i < 8; i++) // prevhash
1822
work->data[i] = ((uint32_t*)sctx->job.prevhash)[7-i];
1823
work->data[8] = 0; // nonce
1824
work->data[9] = swab32(extraheader[0]);
1825
work->data[9] |= rand() & 0xF0;
1826
work->data[10] = be32dec(sctx->job.ntime);
1827
work->data[11] = be32dec(sctx->job.nbits);
1828
for (i = 0; i < 8; i++) // prevhash
1829
work->data[12+i] = ((uint32_t*)merkle_root)[i];
1830
//applog_hex(&work->data[0], 80);
1831
} else {
1832
work->data[17] = le32dec(sctx->job.ntime);
1833
work->data[18] = le32dec(sctx->job.nbits);
1834
// required ?
1835
work->data[20] = 0x80000000;
1836
work->data[31] = 0x00000280;
1837
}
1838
1839
if (opt_showdiff || opt_max_diff > 0.)
1840
calc_network_diff(work);
1841
1842
if (opt_algo == ALGO_DROP || opt_algo == ALGO_NEOSCRYPT || opt_algo == ALGO_ZR5) {
1843
/* reversed endian */
1844
for (i = 0; i <= 18; i++)
1845
work->data[i] = swab32(work->data[i]);
1846
}
1847
1848
pthread_mutex_unlock(&sctx->work_lock);
1849
1850
if (opt_debug && opt_algo != ALGO_DECRED && opt_algo != ALGO_SIA) {
1851
char *xnonce2str = abin2hex(work->xnonce2, work->xnonce2_len);
1852
applog(LOG_DEBUG, "DEBUG: job_id='%s' extranonce2=%s ntime=%08x",
1853
work->job_id, xnonce2str, swab32(work->data[17]));
1854
free(xnonce2str);
1855
}
1856
1857
switch (opt_algo) {
1858
case ALGO_DROP:
1859
case ALGO_JHA:
1860
case ALGO_SCRYPT:
1861
case ALGO_SCRYPTJANE:
1862
case ALGO_NEOSCRYPT:
1863
case ALGO_PLUCK:
1864
case ALGO_YESCRYPT:
1865
case ALGO_YESCRYPTR8:
1866
case ALGO_YESCRYPTR16:
1867
case ALGO_YESCRYPTR32:
1868
work_set_target(work, sctx->job.diff / (65536.0 * opt_diff_factor));
1869
break;
1870
case ALGO_ALLIUM:
1871
case ALGO_FRESH:
1872
case ALGO_DMD_GR:
1873
case ALGO_GROESTL:
1874
case ALGO_KECCAKC:
1875
case ALGO_LBRY:
1876
case ALGO_LYRA2REV2:
1877
case ALGO_LYRA2V3:
1878
case ALGO_PHI2:
1879
case ALGO_TIMETRAVEL:
1880
case ALGO_BITCORE:
1881
case ALGO_XEVAN:
1882
case ALGO_X16R:
1883
case ALGO_X16RV2:
1884
case ALGO_X16S:
1885
case ALGO_X20R:
1886
work_set_target(work, sctx->job.diff / (256.0 * opt_diff_factor));
1887
break;
1888
case ALGO_KECCAK:
1889
case ALGO_LYRA2:
1890
work_set_target(work, sctx->job.diff / (128.0 * opt_diff_factor));
1891
break;
1892
default:
1893
work_set_target(work, sctx->job.diff / opt_diff_factor);
1894
}
1895
1896
if (stratum_diff != sctx->job.diff) {
1897
char sdiff[32] = { 0 };
1898
// store for api stats
1899
stratum_diff = sctx->job.diff;
1900
if (opt_showdiff && work->targetdiff != stratum_diff)
1901
snprintf(sdiff, 32, " (%.5f)", work->targetdiff);
1902
applog(LOG_WARNING, "Stratum difficulty set to %g%s", stratum_diff, sdiff);
1903
}
1904
}
1905
}
1906
1907
bool rpc2_stratum_job(struct stratum_ctx *sctx, json_t *params)
1908
{
1909
bool ret = false;
1910
pthread_mutex_lock(&sctx->work_lock);
1911
ret = rpc2_job_decode(params, &sctx->work);
1912
1913
if (ret) {
1914
work_free(&g_work);
1915
work_copy(&g_work, &sctx->work);
1916
g_work_time = 0;
1917
}
1918
1919
pthread_mutex_unlock(&sctx->work_lock);
1920
1921
return ret;
1922
}
1923
1924
static bool wanna_mine(int thr_id)
1925
{
1926
bool state = true;
1927
1928
if (opt_max_temp > 0.0) {
1929
float temp = cpu_temp(0);
1930
if (temp > opt_max_temp) {
1931
if (!thr_id && !conditional_state[thr_id] && !opt_quiet)
1932
applog(LOG_INFO, "temperature too high (%.0fC), waiting...", temp);
1933
state = false;
1934
}
1935
}
1936
if (opt_max_diff > 0.0 && net_diff > opt_max_diff) {
1937
if (!thr_id && !conditional_state[thr_id] && !opt_quiet)
1938
applog(LOG_INFO, "network diff too high, waiting...");
1939
state = false;
1940
}
1941
if (opt_max_rate > 0.0 && net_hashrate > opt_max_rate) {
1942
if (!thr_id && !conditional_state[thr_id] && !opt_quiet) {
1943
char rate[32];
1944
format_hashrate(opt_max_rate, rate);
1945
applog(LOG_INFO, "network hashrate too high, waiting %s...", rate);
1946
}
1947
state = false;
1948
}
1949
if (thr_id < MAX_CPUS)
1950
conditional_state[thr_id] = (uint8_t) !state;
1951
return state;
1952
}
1953
1954
static void *miner_thread(void *userdata)
1955
{
1956
struct thr_info *mythr = (struct thr_info *) userdata;
1957
int thr_id = mythr->id;
1958
struct work work;
1959
uint32_t max_nonce;
1960
uint32_t end_nonce = 0xffffffffU / opt_n_threads * (thr_id + 1) - 0x20;
1961
time_t tm_rate_log = 0;
1962
time_t firstwork_time = 0;
1963
unsigned char *scratchbuf = NULL;
1964
char s[16];
1965
int i;
1966
1967
memset(&work, 0, sizeof(work));
1968
1969
/* Set worker threads to nice 19 and then preferentially to SCHED_IDLE
1970
* and if that fails, then SCHED_BATCH. No need for this to be an
1971
* error if it fails */
1972
if (!opt_benchmark && opt_priority == 0) {
1973
setpriority(PRIO_PROCESS, 0, 19);
1974
drop_policy();
1975
} else {
1976
int prio = 0;
1977
#ifndef WIN32
1978
prio = 18;
1979
// note: different behavior on linux (-19 to 19)
1980
switch (opt_priority) {
1981
case 1:
1982
prio = 5;
1983
break;
1984
case 2:
1985
prio = 0;
1986
break;
1987
case 3:
1988
prio = -5;
1989
break;
1990
case 4:
1991
prio = -10;
1992
break;
1993
case 5:
1994
prio = -15;
1995
}
1996
if (opt_debug)
1997
applog(LOG_DEBUG, "Thread %d priority %d (nice %d)",
1998
thr_id, opt_priority, prio);
1999
#endif
2000
setpriority(PRIO_PROCESS, 0, prio);
2001
if (opt_priority == 0) {
2002
drop_policy();
2003
}
2004
}
2005
2006
/* Cpu thread affinity */
2007
if (num_cpus > 1) {
2008
if (opt_affinity == -1 && opt_n_threads > 1) {
2009
if (opt_debug)
2010
applog(LOG_DEBUG, "Binding thread %d to cpu %d (mask %x)", thr_id,
2011
thr_id % num_cpus, (1 << (thr_id % num_cpus)));
2012
affine_to_cpu_mask(thr_id, 1UL << (thr_id % num_cpus));
2013
} else if (opt_affinity != -1L) {
2014
if (opt_debug)
2015
applog(LOG_DEBUG, "Binding thread %d to cpu mask %x", thr_id,
2016
opt_affinity);
2017
affine_to_cpu_mask(thr_id, (unsigned long)opt_affinity);
2018
}
2019
}
2020
2021
if (opt_algo == ALGO_SCRYPT) {
2022
scratchbuf = scrypt_buffer_alloc(opt_scrypt_n);
2023
if (!scratchbuf) {
2024
applog(LOG_ERR, "scrypt buffer allocation failed");
2025
pthread_mutex_lock(&applog_lock);
2026
exit(1);
2027
}
2028
}
2029
2030
else if (opt_algo == ALGO_PLUCK) {
2031
scratchbuf = malloc(opt_pluck_n * 1024);
2032
if (!scratchbuf) {
2033
applog(LOG_ERR, "pluck buffer allocation failed");
2034
pthread_mutex_lock(&applog_lock);
2035
exit(1);
2036
}
2037
}
2038
2039
while (1) {
2040
uint64_t hashes_done;
2041
struct timeval tv_start, tv_end, diff;
2042
int64_t max64;
2043
bool regen_work = false;
2044
int wkcmp_offset = 0;
2045
int nonce_oft = 19*sizeof(uint32_t); // 76
2046
int wkcmp_sz = nonce_oft;
2047
int rc = 0;
2048
2049
if (opt_algo == ALGO_DROP || opt_algo == ALGO_ZR5) {
2050
// Duplicates: ignore pok in data[0]
2051
wkcmp_sz -= sizeof(uint32_t);
2052
wkcmp_offset = 1;
2053
} else if (opt_algo == ALGO_DECRED) {
2054
wkcmp_sz = nonce_oft = 140; // 35 * 4
2055
regen_work = true; // ntime not changed ?
2056
} else if (opt_algo == ALGO_LBRY) {
2057
wkcmp_sz = nonce_oft = 108; // 27
2058
//regen_work = true;
2059
} else if (opt_algo == ALGO_SIA) {
2060
nonce_oft = 32;
2061
wkcmp_offset = 32 + 16;
2062
wkcmp_sz = 32; // 35 * 4
2063
}
2064
2065
if (jsonrpc_2) {
2066
wkcmp_sz = nonce_oft = 39;
2067
}
2068
2069
uint32_t *nonceptr = (uint32_t*) (((char*)work.data) + nonce_oft);
2070
2071
if (have_stratum) {
2072
while (!jsonrpc_2 && time(NULL) >= g_work_time + 120)
2073
sleep(1);
2074
2075
while (!stratum.job.diff && opt_algo == ALGO_NEOSCRYPT) {
2076
applog(LOG_DEBUG, "Waiting for Stratum to set the job difficulty");
2077
sleep(1);
2078
}
2079
2080
pthread_mutex_lock(&g_work_lock);
2081
2082
// to clean: is g_work loaded before the memcmp ?
2083
regen_work = regen_work || ( (*nonceptr) >= end_nonce
2084
&& !( memcmp(&work.data[wkcmp_offset], &g_work.data[wkcmp_offset], wkcmp_sz) ||
2085
jsonrpc_2 ? memcmp(((uint8_t*) work.data) + 43, ((uint8_t*) g_work.data) + 43, 33) : 0));
2086
if (regen_work) {
2087
stratum_gen_work(&stratum, &g_work);
2088
}
2089
2090
} else {
2091
2092
int min_scantime = have_longpoll ? LP_SCANTIME : opt_scantime;
2093
/* obtain new work from internal workio thread */
2094
pthread_mutex_lock(&g_work_lock);
2095
if (!have_stratum &&
2096
(time(NULL) - g_work_time >= min_scantime ||
2097
work.data[19] >= end_nonce)) {
2098
if (unlikely(!get_work(mythr, &g_work))) {
2099
applog(LOG_ERR, "work retrieval failed, exiting "
2100
"mining thread %d", mythr->id);
2101
pthread_mutex_unlock(&g_work_lock);
2102
goto out;
2103
}
2104
g_work_time = have_stratum ? 0 : time(NULL);
2105
}
2106
if (have_stratum) {
2107
pthread_mutex_unlock(&g_work_lock);
2108
continue;
2109
}
2110
}
2111
if (memcmp(&work.data[wkcmp_offset], &g_work.data[wkcmp_offset], wkcmp_sz) ||
2112
jsonrpc_2 ? memcmp(((uint8_t*) work.data) + 43, ((uint8_t*) g_work.data) + 43, 33) : 0)
2113
{
2114
work_free(&work);
2115
work_copy(&work, &g_work);
2116
nonceptr = (uint32_t*) (((char*)work.data) + nonce_oft);
2117
*nonceptr = 0xffffffffU / opt_n_threads * thr_id;
2118
if (opt_randomize)
2119
nonceptr[0] += ((rand()*4) & UINT32_MAX) / opt_n_threads;
2120
} else
2121
++(*nonceptr);
2122
pthread_mutex_unlock(&g_work_lock);
2123
work_restart[thr_id].restart = 0;
2124
2125
if (opt_algo == ALGO_DECRED) {
2126
if (have_stratum && strcmp(stratum.job.job_id, work.job_id))
2127
continue; // need to regen g_work..
2128
// extradata: prevent duplicates
2129
nonceptr[1] += 1;
2130
nonceptr[2] |= thr_id;
2131
} else if (opt_algo == ALGO_SIA) {
2132
if (have_stratum && strcmp(stratum.job.job_id, work.job_id))
2133
continue; // need to regen g_work..
2134
// extradata: prevent duplicates
2135
nonceptr[1] += 0x10;
2136
nonceptr[1] |= thr_id;
2137
//applog_hex(nonceptr, 8);
2138
}
2139
2140
// prevent scans before a job is received
2141
// beware, some testnet (decred) are using version 0
2142
// no version in sia draft protocol
2143
if (opt_algo != ALGO_SIA && have_stratum && !work.data[0] && !opt_benchmark) {
2144
sleep(1);
2145
continue;
2146
}
2147
2148
/* conditional mining */
2149
if (!wanna_mine(thr_id)) {
2150
sleep(5);
2151
continue;
2152
}
2153
2154
/* adjust max_nonce to meet target scan time */
2155
if (have_stratum)
2156
max64 = LP_SCANTIME;
2157
else
2158
max64 = g_work_time + (have_longpoll ? LP_SCANTIME : opt_scantime)
2159
- time(NULL);
2160
2161
/* time limit */
2162
if (opt_time_limit && firstwork_time) {
2163
int passed = (int)(time(NULL) - firstwork_time);
2164
int remain = (int)(opt_time_limit - passed);
2165
if (remain < 0) {
2166
if (thr_id != 0) {
2167
sleep(1);
2168
continue;
2169
}
2170
if (opt_benchmark) {
2171
char rate[32];
2172
format_hashrate((double)global_hashrate, rate);
2173
applog(LOG_NOTICE, "Benchmark: %s", rate);
2174
fprintf(stderr, "%llu\n", (long long unsigned int) global_hashrate);
2175
} else {
2176
applog(LOG_NOTICE,
2177
"Mining timeout of %ds reached, exiting...", opt_time_limit);
2178
}
2179
proper_exit(0);
2180
}
2181
if (remain < max64) max64 = remain;
2182
}
2183
2184
max64 *= (int64_t) thr_hashrates[thr_id];
2185
2186
if (max64 <= 0) {
2187
switch (opt_algo) {
2188
case ALGO_SCRYPT:
2189
case ALGO_NEOSCRYPT:
2190
max64 = opt_scrypt_n < 16 ? 0x3ffff : 0x3fffff / opt_scrypt_n;
2191
if (opt_nfactor > 3)
2192
max64 >>= (opt_nfactor - 3);
2193
else if (opt_nfactor > 16)
2194
max64 = 0xF;
2195
break;
2196
case ALGO_AXIOM:
2197
case ALGO_CRYPTOLIGHT:
2198
case ALGO_CRYPTONIGHT:
2199
case ALGO_SCRYPTJANE:
2200
max64 = 0x40LL;
2201
break;
2202
case ALGO_DROP:
2203
case ALGO_PLUCK:
2204
case ALGO_YESCRYPT:
2205
case ALGO_YESCRYPTR8:
2206
max64 = 0x1ff;
2207
break;
2208
case ALGO_YESCRYPTR16:
2209
case ALGO_YESCRYPTR32:
2210
max64 = 0xfff;
2211
break;
2212
case ALGO_ALLIUM:
2213
case ALGO_LYRA2:
2214
case ALGO_LYRA2REV2:
2215
case ALGO_LYRA2V3:
2216
case ALGO_PHI1612:
2217
case ALGO_PHI2:
2218
case ALGO_TIMETRAVEL:
2219
case ALGO_BITCORE:
2220
case ALGO_XEVAN:
2221
max64 = 0xffff;
2222
break;
2223
case ALGO_C11:
2224
case ALGO_DMD_GR:
2225
case ALGO_FRESH:
2226
case ALGO_GEEK:
2227
case ALGO_GROESTL:
2228
case ALGO_MYR_GR:
2229
case ALGO_SIB:
2230
case ALGO_VELTOR:
2231
case ALGO_X11EVO:
2232
case ALGO_X11:
2233
case ALGO_X12:
2234
case ALGO_X13:
2235
case ALGO_X14:
2236
max64 = 0x3ffff;
2237
break;
2238
case ALGO_LBRY:
2239
case ALGO_SONOA:
2240
case ALGO_TRIBUS:
2241
case ALGO_X15:
2242
case ALGO_X16R:
2243
case ALGO_X16RV2:
2244
case ALGO_X16S:
2245
case ALGO_X17:
2246
case ALGO_X20R:
2247
case ALGO_ZR5:
2248
max64 = 0x1ffff;
2249
break;
2250
case ALGO_BMW:
2251
case ALGO_PENTABLAKE:
2252
max64 = 0x3ffff;
2253
break;
2254
case ALGO_SKEIN:
2255
case ALGO_SKEIN2:
2256
max64 = 0x7ffffLL;
2257
break;
2258
case ALGO_BLAKE:
2259
case ALGO_BLAKECOIN:
2260
case ALGO_DECRED:
2261
case ALGO_VANILLA:
2262
max64 = 0x3fffffLL;
2263
break;
2264
case ALGO_SIA:
2265
default:
2266
max64 = 0x1fffffLL;
2267
break;
2268
}
2269
}
2270
if ((*nonceptr) + max64 > end_nonce)
2271
max_nonce = end_nonce;
2272
else
2273
max_nonce = (*nonceptr) + (uint32_t) max64;
2274
2275
hashes_done = 0;
2276
gettimeofday((struct timeval *) &tv_start, NULL);
2277
2278
if (firstwork_time == 0)
2279
firstwork_time = time(NULL);
2280
2281
/* scan nonces for a proof-of-work hash */
2282
switch (opt_algo) {
2283
2284
case ALGO_ALLIUM:
2285
rc = scanhash_allium(thr_id, &work, max_nonce, &hashes_done);
2286
break;
2287
case ALGO_AXIOM:
2288
rc = scanhash_axiom(thr_id, &work, max_nonce, &hashes_done);
2289
break;
2290
case ALGO_BASTION:
2291
rc = scanhash_bastion(thr_id, &work, max_nonce, &hashes_done);
2292
break;
2293
case ALGO_BLAKE:
2294
rc = scanhash_blake(thr_id, &work, max_nonce, &hashes_done);
2295
break;
2296
case ALGO_BLAKECOIN:
2297
rc = scanhash_blakecoin(thr_id, &work, max_nonce, &hashes_done);
2298
break;
2299
case ALGO_BLAKE2B:
2300
rc = scanhash_blake2b(thr_id, &work, max_nonce, &hashes_done);
2301
break;
2302
case ALGO_BLAKE2S:
2303
rc = scanhash_blake2s(thr_id, &work, max_nonce, &hashes_done);
2304
break;
2305
case ALGO_BMW:
2306
rc = scanhash_bmw(thr_id, &work, max_nonce, &hashes_done);
2307
break;
2308
case ALGO_C11:
2309
rc = scanhash_c11(thr_id, &work, max_nonce, &hashes_done);
2310
break;
2311
case ALGO_CRYPTOLIGHT:
2312
rc = scanhash_cryptolight(thr_id, &work, max_nonce, &hashes_done);
2313
break;
2314
case ALGO_CRYPTONIGHT:
2315
rc = scanhash_cryptonight(thr_id, &work, max_nonce, &hashes_done);
2316
break;
2317
case ALGO_DECRED:
2318
rc = scanhash_decred(thr_id, &work, max_nonce, &hashes_done);
2319
break;
2320
case ALGO_DROP:
2321
rc = scanhash_drop(thr_id, &work, max_nonce, &hashes_done);
2322
break;
2323
case ALGO_FRESH:
2324
rc = scanhash_fresh(thr_id, &work, max_nonce, &hashes_done);
2325
break;
2326
case ALGO_GEEK:
2327
rc = scanhash_geek(thr_id, &work, max_nonce, &hashes_done);
2328
break;
2329
case ALGO_DMD_GR:
2330
case ALGO_GROESTL:
2331
rc = scanhash_groestl(thr_id, &work, max_nonce, &hashes_done);
2332
break;
2333
case ALGO_KECCAK:
2334
case ALGO_KECCAKC:
2335
rc = scanhash_keccak(thr_id, &work, max_nonce, &hashes_done);
2336
break;
2337
case ALGO_HEAVY:
2338
rc = scanhash_heavy(thr_id, &work, max_nonce, &hashes_done);
2339
break;
2340
case ALGO_JHA:
2341
rc = scanhash_jha(thr_id, &work, max_nonce, &hashes_done);
2342
break;
2343
case ALGO_LBRY:
2344
rc = scanhash_lbry(thr_id, &work, max_nonce, &hashes_done);
2345
break;
2346
case ALGO_LUFFA:
2347
rc = scanhash_luffa(thr_id, &work, max_nonce, &hashes_done);
2348
break;
2349
case ALGO_LYRA2:
2350
rc = scanhash_lyra2(thr_id, &work, max_nonce, &hashes_done);
2351
break;
2352
case ALGO_LYRA2REV2:
2353
rc = scanhash_lyra2rev2(thr_id, &work, max_nonce, &hashes_done);
2354
break;
2355
case ALGO_LYRA2V3:
2356
rc = scanhash_lyra2v3(thr_id, &work, max_nonce, &hashes_done);
2357
break;
2358
case ALGO_MYR_GR:
2359
rc = scanhash_myriad(thr_id, &work, max_nonce, &hashes_done);
2360
break;
2361
case ALGO_NEOSCRYPT:
2362
rc = scanhash_neoscrypt(thr_id, &work, max_nonce, &hashes_done,
2363
0x80000020 | (opt_nfactor << 8));
2364
break;
2365
case ALGO_NIST5:
2366
rc = scanhash_nist5(thr_id, &work, max_nonce, &hashes_done);
2367
break;
2368
case ALGO_PENTABLAKE:
2369
rc = scanhash_pentablake(thr_id, &work, max_nonce, &hashes_done);
2370
break;
2371
case ALGO_PHI1612:
2372
rc = scanhash_phi1612(thr_id, &work, max_nonce, &hashes_done);
2373
break;
2374
case ALGO_PHI2:
2375
rc = scanhash_phi2(thr_id, &work, max_nonce, &hashes_done);
2376
break;
2377
case ALGO_PLUCK:
2378
rc = scanhash_pluck(thr_id, &work, max_nonce, &hashes_done, scratchbuf, opt_pluck_n);
2379
break;
2380
case ALGO_QUARK:
2381
rc = scanhash_quark(thr_id, &work, max_nonce, &hashes_done);
2382
break;
2383
case ALGO_QUBIT:
2384
rc = scanhash_qubit(thr_id, &work, max_nonce, &hashes_done);
2385
break;
2386
case ALGO_RAINFOREST:
2387
rc = scanhash_rf256(thr_id, &work, max_nonce, &hashes_done);
2388
break;
2389
case ALGO_SCRYPT:
2390
rc = scanhash_scrypt(thr_id, &work, max_nonce, &hashes_done, scratchbuf, opt_scrypt_n);
2391
break;
2392
case ALGO_SCRYPTJANE:
2393
rc = scanhash_scryptjane(opt_scrypt_n, thr_id, &work, max_nonce, &hashes_done);
2394
break;
2395
case ALGO_SHAVITE3:
2396
rc = scanhash_ink(thr_id, &work, max_nonce, &hashes_done);
2397
break;
2398
case ALGO_SHA256D:
2399
rc = scanhash_sha256d(thr_id, &work, max_nonce, &hashes_done);
2400
break;
2401
case ALGO_SIA:
2402
rc = scanhash_sia(thr_id, &work, max_nonce, &hashes_done);
2403
break;
2404
case ALGO_SIB:
2405
rc = scanhash_sib(thr_id, &work, max_nonce, &hashes_done);
2406
break;
2407
case ALGO_SKEIN:
2408
rc = scanhash_skein(thr_id, &work, max_nonce, &hashes_done);
2409
break;
2410
case ALGO_SKEIN2:
2411
rc = scanhash_skein2(thr_id, &work, max_nonce, &hashes_done);
2412
break;
2413
case ALGO_SONOA:
2414
rc = scanhash_sonoa(thr_id, &work, max_nonce, &hashes_done);
2415
break;
2416
case ALGO_S3:
2417
rc = scanhash_s3(thr_id, &work, max_nonce, &hashes_done);
2418
break;
2419
case ALGO_TIMETRAVEL:
2420
rc = scanhash_timetravel(thr_id, &work, max_nonce, &hashes_done);
2421
break;
2422
case ALGO_BITCORE:
2423
rc = scanhash_bitcore(thr_id, &work, max_nonce, &hashes_done);
2424
break;
2425
case ALGO_TRIBUS:
2426
rc = scanhash_tribus(thr_id, &work, max_nonce, &hashes_done);
2427
break;
2428
case ALGO_VANILLA:
2429
rc = scanhash_blakecoin(thr_id, &work, max_nonce, &hashes_done);
2430
break;
2431
case ALGO_VELTOR:
2432
rc = scanhash_veltor(thr_id, &work, max_nonce, &hashes_done);
2433
break;
2434
case ALGO_X11EVO:
2435
rc = scanhash_x11evo(thr_id, &work, max_nonce, &hashes_done);
2436
break;
2437
case ALGO_X11:
2438
rc = scanhash_x11(thr_id, &work, max_nonce, &hashes_done);
2439
break;
2440
case ALGO_X12:
2441
rc = scanhash_x12(thr_id, &work, max_nonce, &hashes_done);
2442
break;
2443
case ALGO_X13:
2444
rc = scanhash_x13(thr_id, &work, max_nonce, &hashes_done);
2445
break;
2446
case ALGO_X14:
2447
rc = scanhash_x14(thr_id, &work, max_nonce, &hashes_done);
2448
break;
2449
case ALGO_X15:
2450
rc = scanhash_x15(thr_id, &work, max_nonce, &hashes_done);
2451
break;
2452
case ALGO_X16R:
2453
rc = scanhash_x16r(thr_id, &work, max_nonce, &hashes_done);
2454
break;
2455
case ALGO_X16RV2:
2456
rc = scanhash_x16rv2(thr_id, &work, max_nonce, &hashes_done);
2457
break;
2458
case ALGO_X20R:
2459
rc = scanhash_x20r(thr_id, &work, max_nonce, &hashes_done);
2460
break;
2461
case ALGO_X16S:
2462
rc = scanhash_x16s(thr_id, &work, max_nonce, &hashes_done);
2463
break;
2464
case ALGO_X17:
2465
rc = scanhash_x17(thr_id, &work, max_nonce, &hashes_done);
2466
break;
2467
case ALGO_XEVAN:
2468
rc = scanhash_xevan(thr_id, &work, max_nonce, &hashes_done);
2469
break;
2470
case ALGO_YESCRYPT:
2471
rc = scanhash_yescrypt(thr_id, &work, max_nonce, &hashes_done);
2472
break;
2473
case ALGO_YESCRYPTR8:
2474
rc = scanhash_yescryptr8(thr_id, &work, max_nonce, &hashes_done);
2475
break;
2476
case ALGO_YESCRYPTR16:
2477
rc = scanhash_yescryptr16(thr_id, &work, max_nonce, &hashes_done);
2478
break;
2479
case ALGO_YESCRYPTR32:
2480
rc = scanhash_yescryptr32(thr_id, &work, max_nonce, &hashes_done);
2481
break;
2482
case ALGO_ZR5:
2483
rc = scanhash_zr5(thr_id, &work, max_nonce, &hashes_done);
2484
break;
2485
default:
2486
/* should never happen */
2487
goto out;
2488
}
2489
2490
/* record scanhash elapsed time */
2491
gettimeofday(&tv_end, NULL);
2492
timeval_subtract(&diff, &tv_end, &tv_start);
2493
if (diff.tv_usec || diff.tv_sec) {
2494
pthread_mutex_lock(&stats_lock);
2495
thr_hashrates[thr_id] =
2496
hashes_done / (diff.tv_sec + diff.tv_usec * 1e-6);
2497
pthread_mutex_unlock(&stats_lock);
2498
}
2499
if (!opt_quiet && (time(NULL) - tm_rate_log) > opt_maxlograte) {
2500
switch(opt_algo) {
2501
case ALGO_AXIOM:
2502
case ALGO_CRYPTOLIGHT:
2503
case ALGO_CRYPTONIGHT:
2504
case ALGO_PLUCK:
2505
case ALGO_SCRYPTJANE:
2506
applog(LOG_INFO, "CPU #%d: %.2f H/s", thr_id, thr_hashrates[thr_id]);
2507
break;
2508
default:
2509
sprintf(s, thr_hashrates[thr_id] >= 1e6 ? "%.0f" : "%.2f",
2510
thr_hashrates[thr_id] / 1e3);
2511
applog(LOG_INFO, "CPU #%d: %s kH/s", thr_id, s);
2512
break;
2513
}
2514
tm_rate_log = time(NULL);
2515
}
2516
if (opt_benchmark && thr_id == opt_n_threads - 1) {
2517
double hashrate = 0.;
2518
for (i = 0; i < opt_n_threads && thr_hashrates[i]; i++)
2519
hashrate += thr_hashrates[i];
2520
if (i == opt_n_threads) {
2521
switch(opt_algo) {
2522
case ALGO_CRYPTOLIGHT:
2523
case ALGO_CRYPTONIGHT:
2524
case ALGO_AXIOM:
2525
case ALGO_SCRYPTJANE:
2526
sprintf(s, "%.3f", hashrate);
2527
applog(LOG_NOTICE, "Total: %s H/s", s);
2528
break;
2529
default:
2530
sprintf(s, hashrate >= 1e6 ? "%.0f" : "%.2f", hashrate / 1000);
2531
applog(LOG_NOTICE, "Total: %s kH/s", s);
2532
break;
2533
}
2534
global_hashrate = (uint64_t) hashrate;
2535
}
2536
}
2537
2538
/* if nonce found, submit work */
2539
if (rc && !opt_benchmark) {
2540
if (!submit_work(mythr, &work))
2541
break;
2542
// prevent stale work in solo
2543
// we can't submit twice a block!
2544
if (!have_stratum && !have_longpoll) {
2545
pthread_mutex_lock(&g_work_lock);
2546
// will force getwork
2547
g_work_time = 0;
2548
pthread_mutex_unlock(&g_work_lock);
2549
continue;
2550
}
2551
}
2552
2553
}
2554
2555
out:
2556
tq_freeze(mythr->q);
2557
2558
return NULL;
2559
}
2560
2561
void restart_threads(void)
2562
{
2563
int i;
2564
2565
for (i = 0; i < opt_n_threads; i++)
2566
work_restart[i].restart = 1;
2567
}
2568
2569
static void *longpoll_thread(void *userdata)
2570
{
2571
struct thr_info *mythr = (struct thr_info*) userdata;
2572
CURL *curl = NULL;
2573
char *copy_start, *hdr_path = NULL, *lp_url = NULL;
2574
bool need_slash = false;
2575
2576
curl = curl_easy_init();
2577
if (unlikely(!curl)) {
2578
applog(LOG_ERR, "CURL init failed");
2579
goto out;
2580
}
2581
2582
start:
2583
hdr_path = (char*) tq_pop(mythr->q, NULL);
2584
if (!hdr_path)
2585
goto out;
2586
2587
/* full URL */
2588
if (strstr(hdr_path, "://")) {
2589
lp_url = hdr_path;
2590
hdr_path = NULL;
2591
}
2592
2593
/* absolute path, on current server */
2594
else {
2595
copy_start = (*hdr_path == '/') ? (hdr_path + 1) : hdr_path;
2596
if (rpc_url[strlen(rpc_url) - 1] != '/')
2597
need_slash = true;
2598
2599
lp_url = (char*) malloc(strlen(rpc_url) + strlen(copy_start) + 2);
2600
if (!lp_url)
2601
goto out;
2602
2603
sprintf(lp_url, "%s%s%s", rpc_url, need_slash ? "/" : "", copy_start);
2604
}
2605
2606
if (!opt_quiet)
2607
applog(LOG_BLUE, "Long-polling on %s", lp_url);
2608
2609
while (1) {
2610
json_t *val;
2611
char *req = NULL;
2612
int err;
2613
2614
if (jsonrpc_2) {
2615
char s[128];
2616
pthread_mutex_lock(&rpc2_login_lock);
2617
if (!strlen(rpc2_id)) {
2618
sleep(1);
2619
continue;
2620
}
2621
snprintf(s, 128, "{\"method\": \"getjob\", \"params\": {\"id\": \"%s\"}, \"id\":1}\r\n", rpc2_id);
2622
pthread_mutex_unlock(&rpc2_login_lock);
2623
val = json_rpc2_call(curl, rpc_url, rpc_userpass, s, &err, JSON_RPC_LONGPOLL);
2624
} else {
2625
if (have_gbt) {
2626
req = (char*) malloc(strlen(gbt_lp_req) + strlen(lp_id) + 1);
2627
sprintf(req, gbt_lp_req, lp_id);
2628
}
2629
val = json_rpc_call(curl, rpc_url, rpc_userpass, getwork_req, &err, JSON_RPC_LONGPOLL);
2630
val = json_rpc_call(curl, lp_url, rpc_userpass,
2631
req ? req : getwork_req, &err,
2632
JSON_RPC_LONGPOLL);
2633
free(req);
2634
}
2635
2636
if (have_stratum) {
2637
if (val)
2638
json_decref(val);
2639
goto out;
2640
}
2641
if (likely(val)) {
2642
bool rc;
2643
char *start_job_id;
2644
double start_diff = 0.0;
2645
json_t *res, *soval;
2646
res = json_object_get(val, "result");
2647
if (!jsonrpc_2) {
2648
soval = json_object_get(res, "submitold");
2649
submit_old = soval ? json_is_true(soval) : false;
2650
}
2651
pthread_mutex_lock(&g_work_lock);
2652
start_job_id = g_work.job_id ? strdup(g_work.job_id) : NULL;
2653
if (have_gbt)
2654
rc = gbt_work_decode(res, &g_work);
2655
else
2656
rc = work_decode(res, &g_work);
2657
if (rc) {
2658
bool newblock = g_work.job_id && strcmp(start_job_id, g_work.job_id);
2659
newblock |= (start_diff != net_diff); // the best is the height but... longpoll...
2660
if (newblock) {
2661
start_diff = net_diff;
2662
if (!opt_quiet) {
2663
char netinfo[64] = { 0 };
2664
if (net_diff > 0.) {
2665
sprintf(netinfo, ", diff %.3f", net_diff);
2666
}
2667
if (opt_showdiff)
2668
sprintf(&netinfo[strlen(netinfo)], ", target %.3f", g_work.targetdiff);
2669
applog(LOG_BLUE, "%s detected new block%s", short_url, netinfo);
2670
}
2671
time(&g_work_time);
2672
restart_threads();
2673
}
2674
}
2675
free(start_job_id);
2676
pthread_mutex_unlock(&g_work_lock);
2677
json_decref(val);
2678
} else {
2679
pthread_mutex_lock(&g_work_lock);
2680
g_work_time -= LP_SCANTIME;
2681
pthread_mutex_unlock(&g_work_lock);
2682
if (err == CURLE_OPERATION_TIMEDOUT) {
2683
restart_threads();
2684
} else {
2685
have_longpoll = false;
2686
restart_threads();
2687
free(hdr_path);
2688
free(lp_url);
2689
lp_url = NULL;
2690
sleep(opt_fail_pause);
2691
goto start;
2692
}
2693
}
2694
}
2695
2696
out:
2697
free(hdr_path);
2698
free(lp_url);
2699
tq_freeze(mythr->q);
2700
if (curl)
2701
curl_easy_cleanup(curl);
2702
2703
return NULL;
2704
}
2705
2706
static bool stratum_handle_response(char *buf)
2707
{
2708
json_t *val, *err_val, *res_val, *id_val;
2709
json_error_t err;
2710
bool ret = false;
2711
bool valid = false;
2712
2713
val = JSON_LOADS(buf, &err);
2714
if (!val) {
2715
applog(LOG_INFO, "JSON decode failed(%d): %s", err.line, err.text);
2716
goto out;
2717
}
2718
2719
res_val = json_object_get(val, "result");
2720
err_val = json_object_get(val, "error");
2721
id_val = json_object_get(val, "id");
2722
2723
if (!id_val || json_is_null(id_val))
2724
goto out;
2725
2726
if (jsonrpc_2)
2727
{
2728
if (!res_val && !err_val)
2729
goto out;
2730
2731
json_t *status = json_object_get(res_val, "status");
2732
if(status) {
2733
const char *s = json_string_value(status);
2734
valid = !strcmp(s, "OK") && json_is_null(err_val);
2735
} else {
2736
valid = json_is_null(err_val);
2737
}
2738
share_result(valid, NULL, err_val ? json_string_value(err_val) : NULL);
2739
2740
} else {
2741
2742
if (!res_val || json_integer_value(id_val) < 4)
2743
goto out;
2744
valid = json_is_true(res_val);
2745
share_result(valid, NULL, err_val ? json_string_value(json_array_get(err_val, 1)) : NULL);
2746
}
2747
2748
ret = true;
2749
2750
out:
2751
if (val)
2752
json_decref(val);
2753
2754
return ret;
2755
}
2756
2757
static void *stratum_thread(void *userdata)
2758
{
2759
struct thr_info *mythr = (struct thr_info *) userdata;
2760
char *s;
2761
2762
stratum.url = (char*) tq_pop(mythr->q, NULL);
2763
if (!stratum.url)
2764
goto out;
2765
applog(LOG_INFO, "Starting Stratum on %s", stratum.url);
2766
2767
while (1) {
2768
int failures = 0;
2769
2770
if (stratum_need_reset) {
2771
stratum_need_reset = false;
2772
stratum_disconnect(&stratum);
2773
if (strcmp(stratum.url, rpc_url)) {
2774
free(stratum.url);
2775
stratum.url = strdup(rpc_url);
2776
applog(LOG_BLUE, "Connection changed to %s", short_url);
2777
} else if (!opt_quiet) {
2778
applog(LOG_DEBUG, "Stratum connection reset");
2779
}
2780
}
2781
2782
while (!stratum.curl) {
2783
pthread_mutex_lock(&g_work_lock);
2784
g_work_time = 0;
2785
pthread_mutex_unlock(&g_work_lock);
2786
restart_threads();
2787
2788
if (!stratum_connect(&stratum, stratum.url)
2789
|| !stratum_subscribe(&stratum)
2790
|| !stratum_authorize(&stratum, rpc_user, rpc_pass)) {
2791
stratum_disconnect(&stratum);
2792
if (opt_retries >= 0 && ++failures > opt_retries) {
2793
applog(LOG_ERR, "...terminating workio thread");
2794
tq_push(thr_info[work_thr_id].q, NULL);
2795
goto out;
2796
}
2797
if (!opt_benchmark)
2798
applog(LOG_ERR, "...retry after %d seconds", opt_fail_pause);
2799
sleep(opt_fail_pause);
2800
}
2801
2802
if (jsonrpc_2) {
2803
work_free(&g_work);
2804
work_copy(&g_work, &stratum.work);
2805
}
2806
}
2807
2808
if (stratum.job.job_id &&
2809
(!g_work_time || strcmp(stratum.job.job_id, g_work.job_id)) )
2810
{
2811
pthread_mutex_lock(&g_work_lock);
2812
stratum_gen_work(&stratum, &g_work);
2813
time(&g_work_time);
2814
pthread_mutex_unlock(&g_work_lock);
2815
2816
if (stratum.job.clean || jsonrpc_2) {
2817
static uint32_t last_bloc_height;
2818
if (!opt_quiet && last_bloc_height != stratum.bloc_height) {
2819
last_bloc_height = stratum.bloc_height;
2820
if (net_diff > 0.)
2821
applog(LOG_BLUE, "%s block %d, diff %.3f", algo_names[opt_algo],
2822
stratum.bloc_height, net_diff);
2823
else
2824
applog(LOG_BLUE, "%s %s block %d", short_url, algo_names[opt_algo],
2825
stratum.bloc_height);
2826
}
2827
restart_threads();
2828
} else if (opt_debug && !opt_quiet) {
2829
applog(LOG_BLUE, "%s asks job %lu for block %d", short_url,
2830
strtoul(stratum.job.job_id, NULL, 16), stratum.bloc_height);
2831
}
2832
}
2833
2834
if (!stratum_socket_full(&stratum, opt_timeout)) {
2835
applog(LOG_ERR, "Stratum connection timeout");
2836
s = NULL;
2837
} else
2838
s = stratum_recv_line(&stratum);
2839
if (!s) {
2840
stratum_disconnect(&stratum);
2841
applog(LOG_ERR, "Stratum connection interrupted");
2842
continue;
2843
}
2844
if (!stratum_handle_method(&stratum, s))
2845
stratum_handle_response(s);
2846
free(s);
2847
}
2848
out:
2849
return NULL;
2850
}
2851
2852
static void show_version_and_exit(void)
2853
{
2854
printf(" built "
2855
#ifdef _MSC_VER
2856
"with VC++ %d", msver());
2857
#elif defined(__GNUC__)
2858
"with GCC ");
2859
printf("%d.%d.%d", __GNUC__, __GNUC_MINOR__, __GNUC_PATCHLEVEL__);
2860
#endif
2861
printf(" the " __DATE__ "\n");
2862
2863
// Note: if compiled with cpu opts (instruction sets),
2864
// the binary is no more compatible with older ones!
2865
printf(" compiled for"
2866
#if defined(__ARM_NEON__)
2867
" ARM NEON"
2868
#elif defined(__AVX2__)
2869
" AVX2"
2870
#elif defined(__AVX__)
2871
" AVX"
2872
#elif defined(__XOP__)
2873
" XOP"
2874
#elif defined(__SSE4_1__)
2875
" SSE4"
2876
#elif defined(_M_X64) || defined(__x86_64__)
2877
" x64"
2878
#elif defined(_M_IX86) || defined(__x86__)
2879
" x86"
2880
#else
2881
" general use"
2882
#endif
2883
"\n");
2884
2885
printf(" config features:"
2886
#if defined(USE_ASM) && defined(__i386__)
2887
" i386"
2888
#endif
2889
#if defined(USE_ASM) && defined(__x86_64__)
2890
" x86_64"
2891
#endif
2892
#if defined(USE_ASM) && (defined(__i386__) || defined(__x86_64__))
2893
" SSE2"
2894
#endif
2895
#if defined(__x86_64__) && defined(USE_XOP)
2896
" XOP"
2897
#endif
2898
#if defined(__x86_64__) && defined(USE_AVX)
2899
" AVX"
2900
#endif
2901
#if defined(__x86_64__) && defined(USE_AVX2)
2902
" AVX2"
2903
#endif
2904
#if defined(USE_ASM) && defined(__arm__) && defined(__APCS_32__)
2905
" ARM"
2906
#if defined(__ARM_ARCH_5E__) || defined(__ARM_ARCH_5TE__) || \
2907
defined(__ARM_ARCH_5TEJ__) || defined(__ARM_ARCH_6__) || \
2908
defined(__ARM_ARCH_6J__) || defined(__ARM_ARCH_6K__) || \
2909
defined(__ARM_ARCH_6M__) || defined(__ARM_ARCH_6T2__) || \
2910
defined(__ARM_ARCH_6Z__) || defined(__ARM_ARCH_6ZK__) || \
2911
defined(__ARM_ARCH_7__) || \
2912
defined(__ARM_ARCH_7A__) || defined(__ARM_ARCH_7R__) || \
2913
defined(__ARM_ARCH_7M__) || defined(__ARM_ARCH_7EM__)
2914
" ARMv5E"
2915
#endif
2916
#if defined(__ARM_NEON__)
2917
" NEON"
2918
#endif
2919
#endif
2920
"\n\n");
2921
/* dependencies versions */
2922
printf("%s\n", curl_version());
2923
#ifdef JANSSON_VERSION
2924
printf("jansson/%s ", JANSSON_VERSION);
2925
#endif
2926
#ifdef PTW32_VERSION
2927
printf("pthreads/%d.%d.%d.%d ", PTW32_VERSION);
2928
#endif
2929
printf("\n");
2930
exit(0);
2931
}
2932
2933
static void show_usage_and_exit(int status)
2934
{
2935
if (status)
2936
fprintf(stderr, "Try `" PACKAGE_NAME " --help' for more information.\n");
2937
else
2938
printf(usage);
2939
exit(status);
2940
}
2941
2942
static void strhide(char *s)
2943
{
2944
if (*s) *s++ = 'x';
2945
while (*s) *s++ = '\0';
2946
}
2947
2948
void parse_arg(int key, char *arg)
2949
{
2950
char *p;
2951
int v, i;
2952
uint64_t ul;
2953
double d;
2954
2955
switch(key) {
2956
case 'a':
2957
for (i = 0; i < ALGO_COUNT; i++) {
2958
v = (int) strlen(algo_names[i]);
2959
if (v && !strncasecmp(arg, algo_names[i], v)) {
2960
if (arg[v] == '\0') {
2961
opt_algo = (enum algos) i;
2962
break;
2963
}
2964
if (arg[v] == ':') {
2965
char *ep;
2966
v = strtol(arg+v+1, &ep, 10);
2967
if (*ep || (i == ALGO_SCRYPT && v & (v-1)) || v < 2)
2968
continue;
2969
opt_algo = (enum algos) i;
2970
opt_scrypt_n = v;
2971
break;
2972
}
2973
}
2974
}
2975
2976
if (i == ALGO_COUNT) {
2977
2978
if (strstr(arg, ":")) {
2979
// pick and strip the optional factor
2980
char *nf = strstr(arg, ":");
2981
opt_scrypt_n = strtol(&nf[1], NULL, 10);
2982
*nf = '\0';
2983
}
2984
2985
// some aliases...
2986
if (!strcasecmp("blake2", arg))
2987
i = opt_algo = ALGO_BLAKE2S;
2988
else if (!strcasecmp("cryptonight-light", arg))
2989
i = opt_algo = ALGO_CRYPTOLIGHT;
2990
else if (!strcasecmp("flax", arg))
2991
i = opt_algo = ALGO_C11;
2992
else if (!strcasecmp("diamond", arg))
2993
i = opt_algo = ALGO_DMD_GR;
2994
else if (!strcasecmp("droplp", arg))
2995
i = opt_algo = ALGO_DROP;
2996
else if (!strcasecmp("jackpot", arg))
2997
i = opt_algo = ALGO_JHA;
2998
else if (!strcasecmp("lyra2", arg))
2999
i = opt_algo = ALGO_LYRA2;
3000
else if (!strcasecmp("lyra2v2", arg))
3001
i = opt_algo = ALGO_LYRA2REV2;
3002
else if (!strcasecmp("lyra2rev3", arg))
3003
i = opt_algo = ALGO_LYRA2V3;
3004
else if (!strcasecmp("monero", arg))
3005
i = opt_algo = ALGO_CRYPTONIGHT;
3006
else if (!strcasecmp("phi", arg))
3007
i = opt_algo = ALGO_PHI1612;
3008
else if (!strcasecmp("scryptjane", arg))
3009
i = opt_algo = ALGO_SCRYPTJANE;
3010
else if (!strcasecmp("sibcoin", arg))
3011
i = opt_algo = ALGO_SIB;
3012
else if (!strcasecmp("timetravel10", arg))
3013
i = opt_algo = ALGO_BITCORE;
3014
else if (!strcasecmp("ziftr", arg))
3015
i = opt_algo = ALGO_ZR5;
3016
else
3017
applog(LOG_ERR, "Unknown algo parameter '%s'", arg);
3018
}
3019
if (i == ALGO_COUNT) {
3020
show_usage_and_exit(1);
3021
}
3022
if (!opt_nfactor && opt_algo == ALGO_SCRYPT)
3023
opt_nfactor = 9;
3024
if (opt_algo == ALGO_SCRYPTJANE && opt_scrypt_n == 0)
3025
opt_scrypt_n = 5;
3026
break;
3027
case 'b':
3028
p = strstr(arg, ":");
3029
if (p) {
3030
/* ip:port */
3031
if (p - arg > 0) {
3032
free(opt_api_allow);
3033
opt_api_allow = strdup(arg);
3034
opt_api_allow[p - arg] = '\0';
3035
}
3036
opt_api_listen = atoi(p + 1);
3037
}
3038
else if (arg && strstr(arg, ".")) {
3039
/* ip only */
3040
free(opt_api_allow);
3041
opt_api_allow = strdup(arg);
3042
}
3043
else if (arg) {
3044
/* port or 0 to disable */
3045
opt_api_listen = atoi(arg);
3046
}
3047
break;
3048
case 1030: /* --api-remote */
3049
opt_api_remote = 1;
3050
break;
3051
case 'n':
3052
if (opt_algo == ALGO_NEOSCRYPT) {
3053
v = atoi(arg);
3054
/* Nfactor = lb(N) - 1; N = (1 << (Nfactor + 1)) */
3055
if ((v < 0) || (v > 30)) {
3056
fprintf(stderr, "incorrect Nfactor %d\n", v);
3057
show_usage_and_exit(1);
3058
}
3059
opt_nfactor = v;
3060
}
3061
break;
3062
case 'B':
3063
opt_background = true;
3064
use_colors = false;
3065
break;
3066
case 'c': {
3067
json_error_t err;
3068
json_t *config;
3069
if (arg && strstr(arg, "://")) {
3070
config = json_load_url(arg, &err);
3071
} else {
3072
config = JSON_LOADF(arg, &err);
3073
}
3074
if (!json_is_object(config)) {
3075
if (err.line < 0)
3076
fprintf(stderr, "%s\n", err.text);
3077
else
3078
fprintf(stderr, "%s:%d: %s\n",
3079
arg, err.line, err.text);
3080
} else {
3081
parse_config(config, arg);
3082
json_decref(config);
3083
}
3084
break;
3085
}
3086
case 'C':
3087
break;
3088
case 'q':
3089
opt_quiet = true;
3090
break;
3091
case 'D':
3092
opt_debug = true;
3093
break;
3094
case 'p':
3095
free(rpc_pass);
3096
rpc_pass = strdup(arg);
3097
strhide(arg);
3098
break;
3099
case 'P':
3100
opt_protocol = true;
3101
break;
3102
case 'r':
3103
v = atoi(arg);
3104
if (v < -1 || v > 9999) /* sanity check */
3105
show_usage_and_exit(1);
3106
opt_retries = v;
3107
break;
3108
case 'R':
3109
v = atoi(arg);
3110
if (v < 1 || v > 9999) /* sanity check */
3111
show_usage_and_exit(1);
3112
opt_fail_pause = v;
3113
break;
3114
case 's':
3115
v = atoi(arg);
3116
if (v < 1 || v > 9999) /* sanity check */
3117
show_usage_and_exit(1);
3118
opt_scantime = v;
3119
break;
3120
case 'T':
3121
v = atoi(arg);
3122
if (v < 1 || v > 99999) /* sanity check */
3123
show_usage_and_exit(1);
3124
opt_timeout = v;
3125
break;
3126
case 't':
3127
v = atoi(arg);
3128
if (v < 0 || v > 9999) /* sanity check */
3129
show_usage_and_exit(1);
3130
opt_n_threads = v;
3131
break;
3132
case 'u':
3133
free(rpc_user);
3134
rpc_user = strdup(arg);
3135
break;
3136
case 'o': { /* --url */
3137
char *ap, *hp;
3138
ap = strstr(arg, "://");
3139
ap = ap ? ap + 3 : arg;
3140
hp = strrchr(arg, '@');
3141
if (hp) {
3142
*hp = '\0';
3143
p = strchr(ap, ':');
3144
if (p) {
3145
free(rpc_userpass);
3146
rpc_userpass = strdup(ap);
3147
free(rpc_user);
3148
rpc_user = (char*) calloc(p - ap + 1, 1);
3149
strncpy(rpc_user, ap, p - ap);
3150
free(rpc_pass);
3151
rpc_pass = strdup(++p);
3152
if (*p) *p++ = 'x';
3153
v = (int) strlen(hp + 1) + 1;
3154
memmove(p + 1, hp + 1, v);
3155
memset(p + v, 0, hp - p);
3156
hp = p;
3157
} else {
3158
free(rpc_user);
3159
rpc_user = strdup(ap);
3160
}
3161
*hp++ = '@';
3162
} else
3163
hp = ap;
3164
if (ap != arg) {
3165
if (strncasecmp(arg, "http://", 7) &&
3166
strncasecmp(arg, "https://", 8) &&
3167
strncasecmp(arg, "stratum+tcp://", 14)) {
3168
fprintf(stderr, "unknown protocol -- '%s'\n", arg);
3169
show_usage_and_exit(1);
3170
}
3171
free(rpc_url);
3172
rpc_url = strdup(arg);
3173
strcpy(rpc_url + (ap - arg), hp);
3174
short_url = &rpc_url[ap - arg];
3175
} else {
3176
if (*hp == '\0' || *hp == '/') {
3177
fprintf(stderr, "invalid URL -- '%s'\n",
3178
arg);
3179
show_usage_and_exit(1);
3180
}
3181
free(rpc_url);
3182
rpc_url = (char*) malloc(strlen(hp) + 8);
3183
sprintf(rpc_url, "http://%s", hp);
3184
short_url = &rpc_url[sizeof("http://")-1];
3185
}
3186
have_stratum = !opt_benchmark && !strncasecmp(rpc_url, "stratum", 7);
3187
break;
3188
}
3189
case 'O': /* --userpass */
3190
p = strchr(arg, ':');
3191
if (!p) {
3192
fprintf(stderr, "invalid username:password pair -- '%s'\n", arg);
3193
show_usage_and_exit(1);
3194
}
3195
free(rpc_userpass);
3196
rpc_userpass = strdup(arg);
3197
free(rpc_user);
3198
rpc_user = (char*) calloc(p - arg + 1, 1);
3199
strncpy(rpc_user, arg, p - arg);
3200
free(rpc_pass);
3201
rpc_pass = strdup(++p);
3202
strhide(p);
3203
break;
3204
case 'x': /* --proxy */
3205
if (!strncasecmp(arg, "socks4://", 9))
3206
opt_proxy_type = CURLPROXY_SOCKS4;
3207
else if (!strncasecmp(arg, "socks5://", 9))
3208
opt_proxy_type = CURLPROXY_SOCKS5;
3209
#if LIBCURL_VERSION_NUM >= 0x071200
3210
else if (!strncasecmp(arg, "socks4a://", 10))
3211
opt_proxy_type = CURLPROXY_SOCKS4A;
3212
else if (!strncasecmp(arg, "socks5h://", 10))
3213
opt_proxy_type = CURLPROXY_SOCKS5_HOSTNAME;
3214
#endif
3215
else
3216
opt_proxy_type = CURLPROXY_HTTP;
3217
free(opt_proxy);
3218
opt_proxy = strdup(arg);
3219
break;
3220
case 1001:
3221
free(opt_cert);
3222
opt_cert = strdup(arg);
3223
break;
3224
case 1002:
3225
use_colors = false;
3226
break;
3227
case 1003:
3228
want_longpoll = false;
3229
break;
3230
case 1005:
3231
opt_benchmark = true;
3232
want_longpoll = false;
3233
want_stratum = false;
3234
have_stratum = false;
3235
break;
3236
case 1006:
3237
print_hash_tests();
3238
exit(0);
3239
case 1007:
3240
want_stratum = false;
3241
opt_extranonce = false;
3242
break;
3243
case 1008:
3244
opt_time_limit = atoi(arg);
3245
break;
3246
case 1009:
3247
opt_redirect = false;
3248
break;
3249
case 1010:
3250
allow_getwork = false;
3251
break;
3252
case 1011:
3253
have_gbt = false;
3254
break;
3255
case 1012:
3256
opt_extranonce = false;
3257
break;
3258
case 1013:
3259
opt_showdiff = true;
3260
break;
3261
case 1014:
3262
opt_showdiff = false;
3263
break;
3264
case 1016: /* --coinbase-addr */
3265
pk_script_size = address_to_script(pk_script, sizeof(pk_script), arg);
3266
if (!pk_script_size) {
3267
fprintf(stderr, "invalid address -- '%s'\n", arg);
3268
show_usage_and_exit(1);
3269
}
3270
break;
3271
case 1015: /* --coinbase-sig */
3272
if (strlen(arg) + 1 > sizeof(coinbase_sig)) {
3273
fprintf(stderr, "coinbase signature too long\n");
3274
show_usage_and_exit(1);
3275
}
3276
strcpy(coinbase_sig, arg);
3277
break;
3278
case 'f':
3279
d = atof(arg);
3280
if (d == 0.) /* --diff-factor */
3281
show_usage_and_exit(1);
3282
opt_diff_factor = d;
3283
break;
3284
case 'm':
3285
d = atof(arg);
3286
if (d == 0.) /* --diff-multiplier */
3287
show_usage_and_exit(1);
3288
opt_diff_factor = 1.0/d;
3289
break;
3290
case 'S':
3291
use_syslog = true;
3292
use_colors = false;
3293
break;
3294
case 1019: // max-log-rate
3295
opt_maxlograte = atoi(arg);
3296
break;
3297
case 1020:
3298
p = strstr(arg, "0x");
3299
if (p)
3300
ul = strtoul(p, NULL, 16);
3301
else
3302
ul = atol(arg);
3303
if (ul > (1UL<<num_cpus)-1)
3304
ul = -1;
3305
opt_affinity = ul;
3306
break;
3307
case 1021:
3308
v = atoi(arg);
3309
if (v < 0 || v > 5) /* sanity check */
3310
show_usage_and_exit(1);
3311
opt_priority = v;
3312
break;
3313
case 1060: // max-temp
3314
d = atof(arg);
3315
opt_max_temp = d;
3316
break;
3317
case 1061: // max-diff
3318
d = atof(arg);
3319
opt_max_diff = d;
3320
break;
3321
case 1062: // max-rate
3322
d = atof(arg);
3323
p = strstr(arg, "K");
3324
if (p) d *= 1e3;
3325
p = strstr(arg, "M");
3326
if (p) d *= 1e6;
3327
p = strstr(arg, "G");
3328
if (p) d *= 1e9;
3329
opt_max_rate = d;
3330
break;
3331
case 1024:
3332
opt_randomize = true;
3333
break;
3334
case 'V':
3335
show_version_and_exit();
3336
case 'h':
3337
show_usage_and_exit(0);
3338
default:
3339
show_usage_and_exit(1);
3340
}
3341
}
3342
3343
void parse_config(json_t *config, char *ref)
3344
{
3345
int i;
3346
json_t *val;
3347
3348
for (i = 0; i < ARRAY_SIZE(options); i++) {
3349
if (!options[i].name)
3350
break;
3351
3352
val = json_object_get(config, options[i].name);
3353
if (!val)
3354
continue;
3355
if (options[i].has_arg && json_is_string(val)) {
3356
char *s = strdup(json_string_value(val));
3357
if (!s)
3358
break;
3359
parse_arg(options[i].val, s);
3360
free(s);
3361
}
3362
else if (options[i].has_arg && json_is_integer(val)) {
3363
char buf[16];
3364
sprintf(buf, "%d", (int)json_integer_value(val));
3365
parse_arg(options[i].val, buf);
3366
}
3367
else if (options[i].has_arg && json_is_real(val)) {
3368
char buf[16];
3369
sprintf(buf, "%f", json_real_value(val));
3370
parse_arg(options[i].val, buf);
3371
}
3372
else if (!options[i].has_arg) {
3373
if (json_is_true(val))
3374
parse_arg(options[i].val, "");
3375
}
3376
else
3377
applog(LOG_ERR, "JSON option %s invalid",
3378
options[i].name);
3379
}
3380
}
3381
3382
static void parse_cmdline(int argc, char *argv[])
3383
{
3384
int key;
3385
3386
while (1) {
3387
#if HAVE_GETOPT_LONG
3388
key = getopt_long(argc, argv, short_options, options, NULL);
3389
#else
3390
key = getopt(argc, argv, short_options);
3391
#endif
3392
if (key < 0)
3393
break;
3394
3395
parse_arg(key, optarg);
3396
}
3397
if (optind < argc) {
3398
fprintf(stderr, "%s: unsupported non-option argument -- '%s'\n",
3399
argv[0], argv[optind]);
3400
show_usage_and_exit(1);
3401
}
3402
}
3403
3404
#ifndef WIN32
3405
static void signal_handler(int sig)
3406
{
3407
switch (sig) {
3408
case SIGHUP:
3409
applog(LOG_INFO, "SIGHUP received");
3410
break;
3411
case SIGINT:
3412
applog(LOG_INFO, "SIGINT received, exiting");
3413
proper_exit(0);
3414
break;
3415
case SIGTERM:
3416
applog(LOG_INFO, "SIGTERM received, exiting");
3417
proper_exit(0);
3418
break;
3419
}
3420
}
3421
#else
3422
BOOL WINAPI ConsoleHandler(DWORD dwType)
3423
{
3424
switch (dwType) {
3425
case CTRL_C_EVENT:
3426
applog(LOG_INFO, "CTRL_C_EVENT received, exiting");
3427
proper_exit(0);
3428
break;
3429
case CTRL_BREAK_EVENT:
3430
applog(LOG_INFO, "CTRL_BREAK_EVENT received, exiting");
3431
proper_exit(0);
3432
break;
3433
default:
3434
return false;
3435
}
3436
return true;
3437
}
3438
#endif
3439
3440
static int thread_create(struct thr_info *thr, void* func)
3441
{
3442
int err = 0;
3443
pthread_attr_init(&thr->attr);
3444
err = pthread_create(&thr->pth, &thr->attr, func, thr);
3445
pthread_attr_destroy(&thr->attr);
3446
return err;
3447
}
3448
3449
static void show_credits()
3450
{
3451
printf("** " PACKAGE_NAME " " PACKAGE_VERSION " by tpruvot@github **\n");
3452
printf("BTC donation address: 1FhDPLPpw18X4srecguG3MxJYe4a1JsZnd (tpruvot)\n\n");
3453
}
3454
3455
void get_defconfig_path(char *out, size_t bufsize, char *argv0);
3456
3457
int main(int argc, char *argv[]) {
3458
struct thr_info *thr;
3459
long flags;
3460
int i, err;
3461
3462
pthread_mutex_init(&applog_lock, NULL);
3463
3464
show_credits();
3465
3466
rpc_user = strdup("");
3467
rpc_pass = strdup("");
3468
opt_api_allow = strdup("127.0.0.1"); /* 0.0.0.0 for all ips */
3469
3470
#if defined(WIN32)
3471
SYSTEM_INFO sysinfo;
3472
GetSystemInfo(&sysinfo);
3473
num_cpus = sysinfo.dwNumberOfProcessors;
3474
#elif defined(_SC_NPROCESSORS_CONF)
3475
num_cpus = sysconf(_SC_NPROCESSORS_CONF);
3476
#elif defined(CTL_HW) && defined(HW_NCPU)
3477
int req[] = { CTL_HW, HW_NCPU };
3478
size_t len = sizeof(num_cpus);
3479
sysctl(req, 2, &num_cpus, &len, NULL, 0);
3480
#else
3481
num_cpus = 1;
3482
#endif
3483
if (num_cpus < 1)
3484
num_cpus = 1;
3485
3486
/* parse command line */
3487
parse_cmdline(argc, argv);
3488
3489
if (!opt_benchmark && !rpc_url) {
3490
// try default config file in binary folder
3491
char defconfig[MAX_PATH] = { 0 };
3492
get_defconfig_path(defconfig, MAX_PATH, argv[0]);
3493
if (strlen(defconfig)) {
3494
if (opt_debug)
3495
applog(LOG_DEBUG, "Using config %s", defconfig);
3496
parse_arg('c', defconfig);
3497
parse_cmdline(argc, argv);
3498
}
3499
}
3500
3501
if (!opt_n_threads)
3502
opt_n_threads = num_cpus;
3503
if (!opt_n_threads)
3504
opt_n_threads = 1;
3505
3506
if (opt_algo == ALGO_QUARK) {
3507
init_quarkhash_contexts();
3508
} else if(opt_algo == ALGO_CRYPTONIGHT || opt_algo == ALGO_CRYPTOLIGHT) {
3509
jsonrpc_2 = true;
3510
opt_extranonce = false;
3511
aes_ni_supported = has_aes_ni();
3512
if (!opt_quiet) {
3513
applog(LOG_INFO, "Using JSON-RPC 2.0");
3514
applog(LOG_INFO, "CPU Supports AES-NI: %s", aes_ni_supported ? "YES" : "NO");
3515
}
3516
} else if(opt_algo == ALGO_DECRED || opt_algo == ALGO_SIA) {
3517
have_gbt = false;
3518
}
3519
3520
if (!opt_benchmark && !rpc_url) {
3521
fprintf(stderr, "%s: no URL supplied\n", argv[0]);
3522
show_usage_and_exit(1);
3523
}
3524
3525
if (!rpc_userpass) {
3526
rpc_userpass = (char*) malloc(strlen(rpc_user) + strlen(rpc_pass) + 2);
3527
if (!rpc_userpass)
3528
return 1;
3529
sprintf(rpc_userpass, "%s:%s", rpc_user, rpc_pass);
3530
}
3531
3532
pthread_mutex_init(&stats_lock, NULL);
3533
pthread_mutex_init(&g_work_lock, NULL);
3534
pthread_mutex_init(&rpc2_job_lock, NULL);
3535
pthread_mutex_init(&rpc2_login_lock, NULL);
3536
pthread_mutex_init(&stratum.sock_lock, NULL);
3537
pthread_mutex_init(&stratum.work_lock, NULL);
3538
3539
flags = !opt_benchmark && strncmp(rpc_url, "https:", 6)
3540
? (CURL_GLOBAL_ALL & ~CURL_GLOBAL_SSL)
3541
: CURL_GLOBAL_ALL;
3542
if (curl_global_init(flags)) {
3543
applog(LOG_ERR, "CURL initialization failed");
3544
return 1;
3545
}
3546
3547
#ifndef WIN32
3548
if (opt_background) {
3549
i = fork();
3550
if (i < 0) exit(1);
3551
if (i > 0) exit(0);
3552
i = setsid();
3553
if (i < 0)
3554
applog(LOG_ERR, "setsid() failed (errno = %d)", errno);
3555
i = chdir("/");
3556
if (i < 0)
3557
applog(LOG_ERR, "chdir() failed (errno = %d)", errno);
3558
signal(SIGHUP, signal_handler);
3559
signal(SIGTERM, signal_handler);
3560
}
3561
/* Always catch Ctrl+C */
3562
signal(SIGINT, signal_handler);
3563
#else
3564
SetConsoleCtrlHandler((PHANDLER_ROUTINE)ConsoleHandler, TRUE);
3565
if (opt_background) {
3566
HWND hcon = GetConsoleWindow();
3567
if (hcon) {
3568
// this method also hide parent command line window
3569
ShowWindow(hcon, SW_HIDE);
3570
} else {
3571
HANDLE h = GetStdHandle(STD_OUTPUT_HANDLE);
3572
CloseHandle(h);
3573
FreeConsole();
3574
}
3575
}
3576
if (opt_priority > 0) {
3577
DWORD prio = NORMAL_PRIORITY_CLASS;
3578
switch (opt_priority) {
3579
case 1:
3580
prio = BELOW_NORMAL_PRIORITY_CLASS;
3581
break;
3582
case 3:
3583
prio = ABOVE_NORMAL_PRIORITY_CLASS;
3584
break;
3585
case 4:
3586
prio = HIGH_PRIORITY_CLASS;
3587
break;
3588
case 5:
3589
prio = REALTIME_PRIORITY_CLASS;
3590
}
3591
SetPriorityClass(GetCurrentProcess(), prio);
3592
}
3593
#endif
3594
if (opt_affinity != -1) {
3595
if (!opt_quiet)
3596
applog(LOG_DEBUG, "Binding process to cpu mask %x", opt_affinity);
3597
affine_to_cpu_mask(-1, (unsigned long)opt_affinity);
3598
}
3599
3600
#ifdef HAVE_SYSLOG_H
3601
if (use_syslog)
3602
openlog("cpuminer", LOG_PID, LOG_USER);
3603
#endif
3604
3605
work_restart = (struct work_restart*) calloc(opt_n_threads, sizeof(*work_restart));
3606
if (!work_restart)
3607
return 1;
3608
3609
thr_info = (struct thr_info*) calloc(opt_n_threads + 4, sizeof(*thr));
3610
if (!thr_info)
3611
return 1;
3612
3613
thr_hashrates = (double *) calloc(opt_n_threads, sizeof(double));
3614
if (!thr_hashrates)
3615
return 1;
3616
3617
/* init workio thread info */
3618
work_thr_id = opt_n_threads;
3619
thr = &thr_info[work_thr_id];
3620
thr->id = work_thr_id;
3621
thr->q = tq_new();
3622
if (!thr->q)
3623
return 1;
3624
3625
if (rpc_pass && rpc_user)
3626
opt_stratum_stats = (strstr(rpc_pass, "stats") != NULL) || (strcmp(rpc_user, "benchmark") == 0);
3627
3628
/* start work I/O thread */
3629
if (thread_create(thr, workio_thread)) {
3630
applog(LOG_ERR, "work thread create failed");
3631
return 1;
3632
}
3633
3634
/* ESET-NOD32 Detects these 2 thread_create... */
3635
if (want_longpoll && !have_stratum) {
3636
/* init longpoll thread info */
3637
longpoll_thr_id = opt_n_threads + 1;
3638
thr = &thr_info[longpoll_thr_id];
3639
thr->id = longpoll_thr_id;
3640
thr->q = tq_new();
3641
if (!thr->q)
3642
return 1;
3643
3644
/* start longpoll thread */
3645
err = thread_create(thr, longpoll_thread);
3646
if (err) {
3647
applog(LOG_ERR, "long poll thread create failed");
3648
return 1;
3649
}
3650
}
3651
if (want_stratum) {
3652
/* init stratum thread info */
3653
stratum_thr_id = opt_n_threads + 2;
3654
thr = &thr_info[stratum_thr_id];
3655
thr->id = stratum_thr_id;
3656
thr->q = tq_new();
3657
if (!thr->q)
3658
return 1;
3659
3660
/* start stratum thread */
3661
err = thread_create(thr, stratum_thread);
3662
if (err) {
3663
applog(LOG_ERR, "stratum thread create failed");
3664
return 1;
3665
}
3666
if (have_stratum)
3667
tq_push(thr_info[stratum_thr_id].q, strdup(rpc_url));
3668
}
3669
3670
if (opt_api_listen) {
3671
/* api thread */
3672
api_thr_id = opt_n_threads + 3;
3673
thr = &thr_info[api_thr_id];
3674
thr->id = api_thr_id;
3675
thr->q = tq_new();
3676
if (!thr->q)
3677
return 1;
3678
err = thread_create(thr, api_thread);
3679
if (err) {
3680
applog(LOG_ERR, "api thread create failed");
3681
return 1;
3682
}
3683
}
3684
3685
/* start mining threads */
3686
for (i = 0; i < opt_n_threads; i++) {
3687
thr = &thr_info[i];
3688
3689
thr->id = i;
3690
thr->q = tq_new();
3691
if (!thr->q)
3692
return 1;
3693
3694
err = thread_create(thr, miner_thread);
3695
if (err) {
3696
applog(LOG_ERR, "thread %d create failed", i);
3697
return 1;
3698
}
3699
}
3700
3701
applog(LOG_INFO, "%d miner threads started, "
3702
"using '%s' algorithm.",
3703
opt_n_threads,
3704
algo_names[opt_algo]);
3705
3706
/* main loop - simply wait for workio thread to exit */
3707
pthread_join(thr_info[work_thr_id].pth, NULL);
3708
3709
applog(LOG_WARNING, "workio thread dead, exiting.");
3710
3711
return 0;
3712
}
3713
3714