Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
litecoincash-project
GitHub Repository: litecoincash-project/cpuminer-multi
Path: blob/master/util.c
548 views
1
/*
2
* Copyright 2010 Jeff Garzik
3
* Copyright 2012 Luke Dashjr
4
* Copyright 2012-2014 pooler
5
* Copyright 2017 Pieter Wuille
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
#define _GNU_SOURCE
14
#include <cpuminer-config.h>
15
16
#include <stdio.h>
17
#include <stdlib.h>
18
#include <ctype.h>
19
#include <stdarg.h>
20
#include <string.h>
21
#include <stdbool.h>
22
#include <inttypes.h>
23
#include <limits.h>
24
#include <errno.h>
25
#include <unistd.h>
26
#include <jansson.h>
27
#include <curl/curl.h>
28
#include <time.h>
29
#include <sys/stat.h>
30
#if defined(WIN32)
31
#include <winsock2.h>
32
#include <mstcpip.h>
33
#include "compat/winansi.h"
34
#else
35
#include <sys/socket.h>
36
#include <netinet/in.h>
37
#include <netinet/tcp.h>
38
#endif
39
40
#ifndef _MSC_VER
41
/* dirname() linux/mingw, else in compat.h */
42
#include <libgen.h>
43
#endif
44
45
#include "miner.h"
46
#include "elist.h"
47
48
extern pthread_mutex_t stats_lock;
49
50
struct data_buffer {
51
void *buf;
52
size_t len;
53
};
54
55
struct upload_buffer {
56
const void *buf;
57
size_t len;
58
size_t pos;
59
};
60
61
struct header_info {
62
char *lp_path;
63
char *reason;
64
char *stratum_url;
65
};
66
67
struct tq_ent {
68
void *data;
69
struct list_head q_node;
70
};
71
72
struct thread_q {
73
struct list_head q;
74
75
bool frozen;
76
77
pthread_mutex_t mutex;
78
pthread_cond_t cond;
79
};
80
81
void applog(int prio, const char *fmt, ...)
82
{
83
va_list ap;
84
85
va_start(ap, fmt);
86
87
#ifdef HAVE_SYSLOG_H
88
if (use_syslog) {
89
va_list ap2;
90
char *buf;
91
int len;
92
93
/* custom colors to syslog prio */
94
if (prio > LOG_DEBUG) {
95
switch (prio) {
96
case LOG_BLUE: prio = LOG_NOTICE; break;
97
}
98
}
99
100
va_copy(ap2, ap);
101
len = vsnprintf(NULL, 0, fmt, ap2) + 1;
102
va_end(ap2);
103
buf = alloca(len);
104
if (vsnprintf(buf, len, fmt, ap) >= 0)
105
syslog(prio, "%s", buf);
106
}
107
#else
108
if (0) {}
109
#endif
110
else {
111
const char* color = "";
112
char *f;
113
int len;
114
struct tm tm;
115
time_t now = time(NULL);
116
117
localtime_r(&now, &tm);
118
119
switch (prio) {
120
case LOG_ERR: color = CL_RED; break;
121
case LOG_WARNING: color = CL_YLW; break;
122
case LOG_NOTICE: color = CL_WHT; break;
123
case LOG_INFO: color = ""; break;
124
case LOG_DEBUG: color = CL_GRY; break;
125
126
case LOG_BLUE:
127
prio = LOG_NOTICE;
128
color = CL_CYN;
129
break;
130
}
131
if (!use_colors)
132
color = "";
133
134
len = 64 + (int) strlen(fmt) + 2;
135
f = (char*) malloc(len);
136
sprintf(f, "[%d-%02d-%02d %02d:%02d:%02d]%s %s%s\n",
137
tm.tm_year + 1900,
138
tm.tm_mon + 1,
139
tm.tm_mday,
140
tm.tm_hour,
141
tm.tm_min,
142
tm.tm_sec,
143
color,
144
fmt,
145
use_colors ? CL_N : ""
146
);
147
pthread_mutex_lock(&applog_lock);
148
vfprintf(stdout, f, ap); /* atomic write to stdout */
149
fflush(stdout);
150
free(f);
151
pthread_mutex_unlock(&applog_lock);
152
}
153
va_end(ap);
154
}
155
156
/* Get default config.json path (will be system specific) */
157
void get_defconfig_path(char *out, size_t bufsize, char *argv0)
158
{
159
char *cmd = strdup(argv0);
160
char *dir = dirname(cmd);
161
const char *sep = strstr(dir, "\\") ? "\\" : "/";
162
struct stat info = { 0 };
163
#ifdef WIN32
164
snprintf(out, bufsize, "%s\\cpuminer\\cpuminer-conf.json", getenv("APPDATA"));
165
#else
166
snprintf(out, bufsize, "%s\\.cpuminer\\cpuminer-conf.json", getenv("HOME"));
167
#endif
168
if (dir && stat(out, &info) != 0) {
169
snprintf(out, bufsize, "%s%scpuminer-conf.json", dir, sep);
170
}
171
if (stat(out, &info) != 0) {
172
out[0] = '\0';
173
return;
174
}
175
out[bufsize - 1] = '\0';
176
free(cmd);
177
}
178
179
180
void format_hashrate(double hashrate, char *output)
181
{
182
char prefix = '\0';
183
184
if (hashrate < 10000) {
185
// nop
186
}
187
else if (hashrate < 1e7) {
188
prefix = 'k';
189
hashrate *= 1e-3;
190
}
191
else if (hashrate < 1e10) {
192
prefix = 'M';
193
hashrate *= 1e-6;
194
}
195
else if (hashrate < 1e13) {
196
prefix = 'G';
197
hashrate *= 1e-9;
198
}
199
else {
200
prefix = 'T';
201
hashrate *= 1e-12;
202
}
203
204
sprintf(
205
output,
206
prefix ? "%.2f %cH/s" : "%.2f H/s%c",
207
hashrate, prefix
208
);
209
}
210
211
/* Modify the representation of integer numbers which would cause an overflow
212
* so that they are treated as floating-point numbers.
213
* This is a hack to overcome the limitations of some versions of Jansson. */
214
static char *hack_json_numbers(const char *in)
215
{
216
char *out;
217
int i, off, intoff;
218
bool in_str, in_int;
219
220
out = (char*) calloc(2 * strlen(in) + 1, 1);
221
if (!out)
222
return NULL;
223
off = intoff = 0;
224
in_str = in_int = false;
225
for (i = 0; in[i]; i++) {
226
char c = in[i];
227
if (c == '"') {
228
in_str = !in_str;
229
} else if (c == '\\') {
230
out[off++] = c;
231
if (!in[++i])
232
break;
233
} else if (!in_str && !in_int && isdigit(c)) {
234
intoff = off;
235
in_int = true;
236
} else if (in_int && !isdigit(c)) {
237
if (c != '.' && c != 'e' && c != 'E' && c != '+' && c != '-') {
238
in_int = false;
239
if (off - intoff > 4) {
240
char *end;
241
#if JSON_INTEGER_IS_LONG_LONG
242
errno = 0;
243
strtoll(out + intoff, &end, 10);
244
if (!*end && errno == ERANGE) {
245
#else
246
long l;
247
errno = 0;
248
l = strtol(out + intoff, &end, 10);
249
if (!*end && (errno == ERANGE || l > INT_MAX)) {
250
#endif
251
out[off++] = '.';
252
out[off++] = '0';
253
}
254
}
255
}
256
}
257
out[off++] = in[i];
258
}
259
return out;
260
}
261
262
static void databuf_free(struct data_buffer *db)
263
{
264
if (!db)
265
return;
266
267
free(db->buf);
268
269
memset(db, 0, sizeof(*db));
270
}
271
272
static size_t all_data_cb(const void *ptr, size_t size, size_t nmemb,
273
void *user_data)
274
{
275
struct data_buffer *db = (struct data_buffer *) user_data;
276
size_t len = size * nmemb;
277
size_t oldlen, newlen;
278
void *newmem;
279
static const unsigned char zero = 0;
280
281
oldlen = db->len;
282
newlen = oldlen + len;
283
284
newmem = realloc(db->buf, newlen + 1);
285
if (!newmem)
286
return 0;
287
288
db->buf = newmem;
289
db->len = newlen;
290
memcpy((uchar*) db->buf + oldlen, ptr, len);
291
memcpy((uchar*) db->buf + newlen, &zero, 1); /* null terminate */
292
293
return len;
294
}
295
296
static size_t upload_data_cb(void *ptr, size_t size, size_t nmemb,
297
void *user_data)
298
{
299
struct upload_buffer *ub = (struct upload_buffer *) user_data;
300
size_t len = size * nmemb;
301
302
if (len > ub->len - ub->pos)
303
len = ub->len - ub->pos;
304
305
if (len) {
306
memcpy(ptr, ((uchar*)ub->buf) + ub->pos, len);
307
ub->pos += len;
308
}
309
310
return len;
311
}
312
313
#if LIBCURL_VERSION_NUM >= 0x071200
314
static int seek_data_cb(void *user_data, curl_off_t offset, int origin)
315
{
316
struct upload_buffer *ub = (struct upload_buffer *) user_data;
317
318
switch (origin) {
319
case SEEK_SET:
320
ub->pos = (size_t) offset;
321
break;
322
case SEEK_CUR:
323
ub->pos += (size_t) offset;
324
break;
325
case SEEK_END:
326
ub->pos = ub->len + (size_t) offset;
327
break;
328
default:
329
return 1; /* CURL_SEEKFUNC_FAIL */
330
}
331
332
return 0; /* CURL_SEEKFUNC_OK */
333
}
334
#endif
335
336
static size_t resp_hdr_cb(void *ptr, size_t size, size_t nmemb, void *user_data)
337
{
338
struct header_info *hi = (struct header_info *) user_data;
339
size_t remlen, slen, ptrlen = size * nmemb;
340
char *rem, *val = NULL, *key = NULL;
341
void *tmp;
342
343
val = (char*) calloc(1, ptrlen);
344
key = (char*) calloc(1, ptrlen);
345
if (!key || !val)
346
goto out;
347
348
tmp = memchr(ptr, ':', ptrlen);
349
if (!tmp || (tmp == ptr)) /* skip empty keys / blanks */
350
goto out;
351
slen = (char*)tmp - (char*)ptr;
352
if ((slen + 1) == ptrlen) /* skip key w/ no value */
353
goto out;
354
memcpy(key, ptr, slen); /* store & nul term key */
355
key[slen] = 0;
356
357
rem = (char*)ptr + slen + 1; /* trim value's leading whitespace */
358
remlen = ptrlen - slen - 1;
359
while ((remlen > 0) && (isspace(*rem))) {
360
remlen--;
361
rem++;
362
}
363
364
memcpy(val, rem, remlen); /* store value, trim trailing ws */
365
val[remlen] = 0;
366
while ((*val) && (isspace(val[strlen(val) - 1]))) {
367
val[strlen(val) - 1] = 0;
368
}
369
370
if (!strcasecmp("X-Long-Polling", key)) {
371
hi->lp_path = val; /* steal memory reference */
372
val = NULL;
373
}
374
375
if (!strcasecmp("X-Reject-Reason", key)) {
376
hi->reason = val; /* steal memory reference */
377
val = NULL;
378
}
379
380
if (!strcasecmp("X-Stratum", key)) {
381
hi->stratum_url = val; /* steal memory reference */
382
val = NULL;
383
}
384
385
out:
386
free(key);
387
free(val);
388
return ptrlen;
389
}
390
391
#if LIBCURL_VERSION_NUM >= 0x070f06
392
static int sockopt_keepalive_cb(void *userdata, curl_socket_t fd,
393
curlsocktype purpose)
394
{
395
#ifdef __linux
396
int tcp_keepcnt = 3;
397
#endif
398
int tcp_keepintvl = 50;
399
int tcp_keepidle = 50;
400
#ifndef WIN32
401
int keepalive = 1;
402
if (unlikely(setsockopt(fd, SOL_SOCKET, SO_KEEPALIVE, &keepalive,
403
sizeof(keepalive))))
404
return 1;
405
#ifdef __linux
406
if (unlikely(setsockopt(fd, SOL_TCP, TCP_KEEPCNT,
407
&tcp_keepcnt, sizeof(tcp_keepcnt))))
408
return 1;
409
if (unlikely(setsockopt(fd, SOL_TCP, TCP_KEEPIDLE,
410
&tcp_keepidle, sizeof(tcp_keepidle))))
411
return 1;
412
if (unlikely(setsockopt(fd, SOL_TCP, TCP_KEEPINTVL,
413
&tcp_keepintvl, sizeof(tcp_keepintvl))))
414
return 1;
415
#endif /* __linux */
416
#ifdef __APPLE_CC__
417
if (unlikely(setsockopt(fd, IPPROTO_TCP, TCP_KEEPALIVE,
418
&tcp_keepintvl, sizeof(tcp_keepintvl))))
419
return 1;
420
#endif /* __APPLE_CC__ */
421
#else /* WIN32 */
422
struct tcp_keepalive vals;
423
vals.onoff = 1;
424
vals.keepalivetime = tcp_keepidle * 1000;
425
vals.keepaliveinterval = tcp_keepintvl * 1000;
426
DWORD outputBytes;
427
if (unlikely(WSAIoctl(fd, SIO_KEEPALIVE_VALS, &vals, sizeof(vals),
428
NULL, 0, &outputBytes, NULL, NULL)))
429
return 1;
430
#endif /* WIN32 */
431
432
return 0;
433
}
434
#endif
435
436
json_t *json_rpc_call(CURL *curl, const char *url,
437
const char *userpass, const char *rpc_req,
438
int *curl_err, int flags)
439
{
440
json_t *val, *err_val, *res_val;
441
int rc;
442
long http_rc;
443
struct data_buffer all_data = {0};
444
struct upload_buffer upload_data;
445
char *json_buf;
446
json_error_t err;
447
struct curl_slist *headers = NULL;
448
char len_hdr[64];
449
char curl_err_str[CURL_ERROR_SIZE] = { 0 };
450
long timeout = (flags & JSON_RPC_LONGPOLL) ? opt_timeout : 30;
451
struct header_info hi = {0};
452
453
/* it is assumed that 'curl' is freshly [re]initialized at this pt */
454
455
if (opt_protocol)
456
curl_easy_setopt(curl, CURLOPT_VERBOSE, 1);
457
curl_easy_setopt(curl, CURLOPT_URL, url);
458
if (opt_cert)
459
curl_easy_setopt(curl, CURLOPT_CAINFO, opt_cert);
460
curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, false);
461
curl_easy_setopt(curl, CURLOPT_ENCODING, "");
462
curl_easy_setopt(curl, CURLOPT_FAILONERROR, 0);
463
curl_easy_setopt(curl, CURLOPT_NOSIGNAL, 1);
464
curl_easy_setopt(curl, CURLOPT_TCP_NODELAY, 1);
465
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, all_data_cb);
466
curl_easy_setopt(curl, CURLOPT_WRITEDATA, &all_data);
467
curl_easy_setopt(curl, CURLOPT_READFUNCTION, upload_data_cb);
468
curl_easy_setopt(curl, CURLOPT_READDATA, &upload_data);
469
#if LIBCURL_VERSION_NUM >= 0x071200
470
curl_easy_setopt(curl, CURLOPT_SEEKFUNCTION, &seek_data_cb);
471
curl_easy_setopt(curl, CURLOPT_SEEKDATA, &upload_data);
472
#endif
473
curl_easy_setopt(curl, CURLOPT_ERRORBUFFER, curl_err_str);
474
if (opt_redirect)
475
curl_easy_setopt(curl, CURLOPT_FOLLOWLOCATION, 1);
476
curl_easy_setopt(curl, CURLOPT_TIMEOUT, timeout);
477
curl_easy_setopt(curl, CURLOPT_HEADERFUNCTION, resp_hdr_cb);
478
curl_easy_setopt(curl, CURLOPT_HEADERDATA, &hi);
479
if (opt_proxy) {
480
curl_easy_setopt(curl, CURLOPT_PROXY, opt_proxy);
481
curl_easy_setopt(curl, CURLOPT_PROXYTYPE, opt_proxy_type);
482
}
483
if (userpass) {
484
curl_easy_setopt(curl, CURLOPT_USERPWD, userpass);
485
curl_easy_setopt(curl, CURLOPT_HTTPAUTH, CURLAUTH_BASIC);
486
}
487
#if LIBCURL_VERSION_NUM >= 0x070f06
488
if (flags & JSON_RPC_LONGPOLL)
489
curl_easy_setopt(curl, CURLOPT_SOCKOPTFUNCTION, sockopt_keepalive_cb);
490
#endif
491
curl_easy_setopt(curl, CURLOPT_POST, 1);
492
493
if (opt_protocol)
494
applog(LOG_DEBUG, "JSON protocol request:\n%s\n", rpc_req);
495
496
upload_data.buf = rpc_req;
497
upload_data.len = strlen(rpc_req);
498
upload_data.pos = 0;
499
sprintf(len_hdr, "Content-Length: %lu",
500
(unsigned long) upload_data.len);
501
502
headers = curl_slist_append(headers, "Content-Type: application/json");
503
headers = curl_slist_append(headers, len_hdr);
504
headers = curl_slist_append(headers, "User-Agent: " USER_AGENT);
505
headers = curl_slist_append(headers, "X-Mining-Extensions: longpoll reject-reason");
506
//headers = curl_slist_append(headers, "Accept:"); /* disable Accept hdr*/
507
//headers = curl_slist_append(headers, "Expect:"); /* disable Expect hdr*/
508
509
curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headers);
510
511
rc = curl_easy_perform(curl);
512
if (curl_err != NULL)
513
*curl_err = rc;
514
if (rc) {
515
curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE, &http_rc);
516
if (!((flags & JSON_RPC_LONGPOLL) && rc == CURLE_OPERATION_TIMEDOUT) &&
517
!((flags & JSON_RPC_QUIET_404) && http_rc == 404))
518
applog(LOG_ERR, "HTTP request failed: %s", curl_err_str);
519
if (curl_err && (flags & JSON_RPC_QUIET_404) && http_rc == 404)
520
*curl_err = CURLE_OK;
521
goto err_out;
522
}
523
524
/* If X-Stratum was found, activate Stratum */
525
if (want_stratum && hi.stratum_url &&
526
!strncasecmp(hi.stratum_url, "stratum+tcp://", 14)) {
527
have_stratum = true;
528
tq_push(thr_info[stratum_thr_id].q, hi.stratum_url);
529
hi.stratum_url = NULL;
530
}
531
532
/* If X-Long-Polling was found, activate long polling */
533
if (!have_longpoll && want_longpoll && hi.lp_path && !have_gbt &&
534
allow_getwork && !have_stratum) {
535
have_longpoll = true;
536
tq_push(thr_info[longpoll_thr_id].q, hi.lp_path);
537
hi.lp_path = NULL;
538
}
539
540
if (!all_data.buf) {
541
applog(LOG_ERR, "Empty data received in json_rpc_call.");
542
goto err_out;
543
}
544
545
json_buf = hack_json_numbers((char*) all_data.buf);
546
errno = 0; /* needed for Jansson < 2.1 */
547
val = JSON_LOADS(json_buf, &err);
548
free(json_buf);
549
if (!val) {
550
applog(LOG_ERR, "JSON decode failed(%d): %s", err.line, err.text);
551
goto err_out;
552
}
553
554
if (opt_protocol) {
555
char *s = json_dumps(val, JSON_INDENT(3));
556
applog(LOG_DEBUG, "JSON protocol response:\n%s", s);
557
free(s);
558
}
559
560
/* JSON-RPC valid response returns a 'result' and a null 'error'. */
561
res_val = json_object_get(val, "result");
562
err_val = json_object_get(val, "error");
563
564
if (!res_val || (err_val && !json_is_null(err_val)
565
&& !(flags & JSON_RPC_IGNOREERR))) {
566
567
char *s = NULL;
568
569
if (err_val) {
570
s = json_dumps(err_val, 0);
571
json_t *msg = json_object_get(err_val, "message");
572
json_t *err_code = json_object_get(err_val, "code");
573
if (curl_err && json_integer_value(err_code))
574
*curl_err = (int)json_integer_value(err_code);
575
576
if (msg && json_is_string(msg)) {
577
free(s);
578
s = strdup(json_string_value(msg));
579
if (have_longpoll && s && !strcmp(s, "method not getwork")) {
580
json_decref(err_val);
581
free(s);
582
goto err_out;
583
}
584
}
585
json_decref(err_val);
586
}
587
else
588
s = strdup("(unknown reason)");
589
590
if (!curl_err || opt_debug)
591
applog(LOG_ERR, "JSON-RPC call failed: %s", s);
592
593
free(s);
594
595
goto err_out;
596
}
597
598
if (hi.reason)
599
json_object_set_new(val, "reject-reason", json_string(hi.reason));
600
601
databuf_free(&all_data);
602
curl_slist_free_all(headers);
603
curl_easy_reset(curl);
604
return val;
605
606
err_out:
607
free(hi.lp_path);
608
free(hi.reason);
609
free(hi.stratum_url);
610
databuf_free(&all_data);
611
curl_slist_free_all(headers);
612
curl_easy_reset(curl);
613
return NULL;
614
}
615
616
/* used to load a remote config */
617
json_t* json_load_url(char* cfg_url, json_error_t *err)
618
{
619
char err_str[CURL_ERROR_SIZE] = { 0 };
620
struct data_buffer all_data = { 0 };
621
int rc = 0; json_t *cfg = NULL;
622
CURL *curl = curl_easy_init();
623
if (unlikely(!curl)) {
624
applog(LOG_ERR, "Remote config init failed!");
625
return NULL;
626
}
627
curl_easy_setopt(curl, CURLOPT_URL, cfg_url);
628
curl_easy_setopt(curl, CURLOPT_FRESH_CONNECT, 1);
629
curl_easy_setopt(curl, CURLOPT_CONNECTTIMEOUT, 15);
630
curl_easy_setopt(curl, CURLOPT_ERRORBUFFER, err_str);
631
curl_easy_setopt(curl, CURLOPT_NOSIGNAL, 1);
632
curl_easy_setopt(curl, CURLOPT_TCP_NODELAY, 1);
633
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, all_data_cb);
634
curl_easy_setopt(curl, CURLOPT_WRITEDATA, &all_data);
635
if (opt_proxy) {
636
curl_easy_setopt(curl, CURLOPT_PROXY, opt_proxy);
637
curl_easy_setopt(curl, CURLOPT_PROXYTYPE, opt_proxy_type);
638
} else if (getenv("http_proxy")) {
639
if (getenv("all_proxy"))
640
curl_easy_setopt(curl, CURLOPT_PROXY, getenv("all_proxy"));
641
else if (getenv("ALL_PROXY"))
642
curl_easy_setopt(curl, CURLOPT_PROXY, getenv("ALL_PROXY"));
643
else
644
curl_easy_setopt(curl, CURLOPT_PROXY, "");
645
}
646
rc = curl_easy_perform(curl);
647
if (rc) {
648
applog(LOG_ERR, "Remote config read failed: %s", err_str);
649
goto err_out;
650
}
651
if (!all_data.buf || !all_data.len) {
652
applog(LOG_ERR, "Empty data received for config");
653
goto err_out;
654
}
655
656
cfg = JSON_LOADS((char*)all_data.buf, err);
657
err_out:
658
curl_easy_cleanup(curl);
659
return cfg;
660
}
661
662
// Segwit BEGIN
663
void memrev(unsigned char *p, size_t len)
664
{
665
unsigned char c, *q;
666
for (q = p + len - 1; p < q; p++, q--) {
667
c = *p;
668
*p = *q;
669
*q = c;
670
}
671
}
672
// Segwit END
673
674
void bin2hex(char *s, const unsigned char *p, size_t len)
675
{
676
for (size_t i = 0; i < len; i++)
677
sprintf(s + (i * 2), "%02x", (unsigned int) p[i]);
678
}
679
680
char *abin2hex(const unsigned char *p, size_t len)
681
{
682
char *s = (char*) malloc((len * 2) + 1);
683
if (!s)
684
return NULL;
685
bin2hex(s, p, len);
686
return s;
687
}
688
689
bool hex2bin(unsigned char *p, const char *hexstr, size_t len)
690
{
691
if(hexstr == NULL)
692
return false;
693
694
size_t hexstr_len = strlen(hexstr);
695
if((hexstr_len % 2) != 0) {
696
applog(LOG_ERR, "hex2bin str truncated");
697
return false;
698
}
699
700
size_t bin_len = hexstr_len / 2;
701
if (bin_len > len) {
702
applog(LOG_ERR, "hex2bin buffer too small");
703
return false;
704
}
705
706
memset(p, 0, len);
707
708
size_t i = 0;
709
while (i < hexstr_len) {
710
char c = hexstr[i];
711
unsigned char nibble;
712
if(c >= '0' && c <= '9') {
713
nibble = (c - '0');
714
} else if (c >= 'A' && c <= 'F') {
715
nibble = (10 + (c - 'A'));
716
} else if (c >= 'a' && c <= 'f') {
717
nibble = (10 + (c - 'a'));
718
} else {
719
applog(LOG_ERR, "hex2bin invalid hex");
720
return false;
721
}
722
p[(i / 2)] |= (nibble << ((1 - (i % 2)) * 4));
723
i++;
724
}
725
726
return true;
727
}
728
729
int varint_encode(unsigned char *p, uint64_t n)
730
{
731
int i;
732
if (n < 0xfd) {
733
p[0] = (uchar) n;
734
return 1;
735
}
736
if (n <= 0xffff) {
737
p[0] = 0xfd;
738
p[1] = n & 0xff;
739
p[2] = (uchar) (n >> 8);
740
return 3;
741
}
742
if (n <= 0xffffffff) {
743
p[0] = 0xfe;
744
for (i = 1; i < 5; i++) {
745
p[i] = n & 0xff;
746
n >>= 8;
747
}
748
return 5;
749
}
750
p[0] = 0xff;
751
for (i = 1; i < 9; i++) {
752
p[i] = n & 0xff;
753
n >>= 8;
754
}
755
return 9;
756
}
757
758
static const char b58digits[] = "123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz";
759
760
static bool b58dec(unsigned char *bin, size_t binsz, const char *b58)
761
{
762
size_t i, j;
763
uint64_t t;
764
uint32_t c;
765
uint32_t *outi;
766
size_t outisz = (binsz + 3) / 4;
767
int rem = binsz % 4;
768
uint32_t remmask = 0xffffffff << (8 * rem);
769
size_t b58sz = strlen(b58);
770
bool rc = false;
771
772
outi = (uint32_t *) calloc(outisz, sizeof(*outi));
773
774
for (i = 0; i < b58sz; ++i) {
775
for (c = 0; b58digits[c] != b58[i]; c++)
776
if (!b58digits[c])
777
goto out;
778
for (j = outisz; j--; ) {
779
t = (uint64_t)outi[j] * 58 + c;
780
c = t >> 32;
781
outi[j] = t & 0xffffffff;
782
}
783
if (c || outi[0] & remmask)
784
goto out;
785
}
786
787
j = 0;
788
switch (rem) {
789
case 3:
790
*(bin++) = (outi[0] >> 16) & 0xff;
791
case 2:
792
*(bin++) = (outi[0] >> 8) & 0xff;
793
case 1:
794
*(bin++) = outi[0] & 0xff;
795
++j;
796
default:
797
break;
798
}
799
for (; j < outisz; ++j) {
800
be32enc((uint32_t *)bin, outi[j]);
801
bin += sizeof(uint32_t);
802
}
803
804
rc = true;
805
out:
806
free(outi);
807
return rc;
808
}
809
810
static int b58check(unsigned char *bin, size_t binsz, const char *b58)
811
{
812
unsigned char buf[32];
813
int i;
814
815
sha256d(buf, bin, (int) (binsz - 4));
816
if (memcmp(&bin[binsz - 4], buf, 4))
817
return -1;
818
819
/* Check number of zeros is correct AFTER verifying checksum
820
* (to avoid possibility of accessing the string beyond the end) */
821
for (i = 0; bin[i] == '\0' && b58[i] == '1'; ++i);
822
if (bin[i] == '\0' || b58[i] == '1')
823
return -3;
824
825
return bin[0];
826
}
827
828
bool jobj_binary(const json_t *obj, const char *key, void *buf, size_t buflen)
829
{
830
const char *hexstr;
831
json_t *tmp;
832
833
tmp = json_object_get(obj, key);
834
if (unlikely(!tmp)) {
835
applog(LOG_ERR, "JSON key '%s' not found", key);
836
return false;
837
}
838
hexstr = json_string_value(tmp);
839
if (unlikely(!hexstr)) {
840
applog(LOG_ERR, "JSON key '%s' is not a string", key);
841
return false;
842
}
843
if (!hex2bin((uchar*) buf, hexstr, buflen))
844
return false;
845
846
return true;
847
}
848
849
static uint32_t bech32_polymod_step(uint32_t pre) {
850
uint8_t b = pre >> 25;
851
return ((pre & 0x1FFFFFF) << 5) ^
852
(-((b >> 0) & 1) & 0x3b6a57b2UL) ^
853
(-((b >> 1) & 1) & 0x26508e6dUL) ^
854
(-((b >> 2) & 1) & 0x1ea119faUL) ^
855
(-((b >> 3) & 1) & 0x3d4233ddUL) ^
856
(-((b >> 4) & 1) & 0x2a1462b3UL);
857
}
858
859
static const int8_t bech32_charset_rev[128] = {
860
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
861
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
862
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
863
15, -1, 10, 17, 21, 20, 26, 30, 7, 5, -1, -1, -1, -1, -1, -1,
864
-1, 29, -1, 24, 13, 25, 9, 8, 23, -1, 18, 22, 31, 27, 19, -1,
865
1, 0, 3, 16, 11, 28, 12, 14, 6, 4, 2, -1, -1, -1, -1, -1,
866
-1, 29, -1, 24, 13, 25, 9, 8, 23, -1, 18, 22, 31, 27, 19, -1,
867
1, 0, 3, 16, 11, 28, 12, 14, 6, 4, 2, -1, -1, -1, -1, -1
868
};
869
870
static bool bech32_decode(char *hrp, uint8_t *data, size_t *data_len, const char *input) {
871
uint32_t chk = 1;
872
size_t i;
873
size_t input_len = strlen(input);
874
size_t hrp_len;
875
int have_lower = 0, have_upper = 0;
876
if (input_len < 8 || input_len > 90) {
877
return false;
878
}
879
*data_len = 0;
880
while (*data_len < input_len && input[(input_len - 1) - *data_len] != '1') {
881
++(*data_len);
882
}
883
hrp_len = input_len - (1 + *data_len);
884
if (1 + *data_len >= input_len || *data_len < 6) {
885
return false;
886
}
887
*(data_len) -= 6;
888
for (i = 0; i < hrp_len; ++i) {
889
int ch = input[i];
890
if (ch < 33 || ch > 126) {
891
return false;
892
}
893
if (ch >= 'a' && ch <= 'z') {
894
have_lower = 1;
895
} else if (ch >= 'A' && ch <= 'Z') {
896
have_upper = 1;
897
ch = (ch - 'A') + 'a';
898
}
899
hrp[i] = ch;
900
chk = bech32_polymod_step(chk) ^ (ch >> 5);
901
}
902
hrp[i] = 0;
903
chk = bech32_polymod_step(chk);
904
for (i = 0; i < hrp_len; ++i) {
905
chk = bech32_polymod_step(chk) ^ (input[i] & 0x1f);
906
}
907
++i;
908
while (i < input_len) {
909
int v = (input[i] & 0x80) ? -1 : bech32_charset_rev[(int)input[i]];
910
if (input[i] >= 'a' && input[i] <= 'z') have_lower = 1;
911
if (input[i] >= 'A' && input[i] <= 'Z') have_upper = 1;
912
if (v == -1) {
913
return false;
914
}
915
chk = bech32_polymod_step(chk) ^ v;
916
if (i + 6 < input_len) {
917
data[i - (1 + hrp_len)] = v;
918
}
919
++i;
920
}
921
if (have_lower && have_upper) {
922
return false;
923
}
924
return chk == 1;
925
}
926
927
static bool convert_bits(uint8_t *out, size_t *outlen, int outbits, const uint8_t *in, size_t inlen, int inbits, int pad) {
928
uint32_t val = 0;
929
int bits = 0;
930
uint32_t maxv = (((uint32_t)1) << outbits) - 1;
931
while (inlen--) {
932
val = (val << inbits) | *(in++);
933
bits += inbits;
934
while (bits >= outbits) {
935
bits -= outbits;
936
out[(*outlen)++] = (val >> bits) & maxv;
937
}
938
}
939
if (pad) {
940
if (bits) {
941
out[(*outlen)++] = (val << (outbits - bits)) & maxv;
942
}
943
} else if (((val << (outbits - bits)) & maxv) || bits >= inbits) {
944
return false;
945
}
946
return true;
947
}
948
949
static bool segwit_addr_decode(int *witver, uint8_t *witdata, size_t *witdata_len, const char *addr) {
950
uint8_t data[84];
951
char hrp_actual[84];
952
size_t data_len;
953
if (!bech32_decode(hrp_actual, data, &data_len, addr)) return false;
954
if (data_len == 0 || data_len > 65) return false;
955
if (data[0] > 16) return false;
956
*witdata_len = 0;
957
if (!convert_bits(witdata, witdata_len, 8, data + 1, data_len - 1, 5, 0)) return false;
958
if (*witdata_len < 2 || *witdata_len > 40) return false;
959
if (data[0] == 0 && *witdata_len != 20 && *witdata_len != 32) return false;
960
*witver = data[0];
961
return true;
962
}
963
964
static size_t bech32_to_script(uint8_t *out, size_t outsz, const char *addr) {
965
uint8_t witprog[40];
966
size_t witprog_len;
967
int witver;
968
969
if (!segwit_addr_decode(&witver, witprog, &witprog_len, addr))
970
return 0;
971
if (outsz < witprog_len + 2)
972
return 0;
973
out[0] = witver ? (0x50 + witver) : 0;
974
out[1] = witprog_len;
975
memcpy(out + 2, witprog, witprog_len);
976
return witprog_len + 2;
977
}
978
979
size_t address_to_script(unsigned char *out, size_t outsz, const char *addr)
980
{
981
unsigned char addrbin[25];
982
int addrver;
983
size_t rv;
984
985
if (!b58dec(addrbin, sizeof(addrbin), addr))
986
return bech32_to_script(out, outsz, addr);
987
addrver = b58check(addrbin, sizeof(addrbin), addr);
988
if (addrver < 0)
989
return 0;
990
switch (addrver) {
991
case 5: /* LCC mainnet script hash */
992
case 50: /* LCC mainnet alt script hash */
993
case 196: /* LCC testnet script hash */
994
case 58: /* LCC testnet alt script hash */
995
case 81: /* RNG mainnet script hash */
996
case 78: /* RNG mainnet script hash */
997
if (outsz < (rv = 23))
998
return rv;
999
out[ 0] = 0xa9; /* OP_HASH160 */
1000
out[ 1] = 0x14; /* push 20 bytes */
1001
memcpy(&out[2], &addrbin[1], 20);
1002
out[22] = 0x87; /* OP_EQUAL */
1003
return rv;
1004
default:
1005
if (outsz < (rv = 25))
1006
return rv;
1007
out[ 0] = 0x76; /* OP_DUP */
1008
out[ 1] = 0xa9; /* OP_HASH160 */
1009
out[ 2] = 0x14; /* push 20 bytes */
1010
memcpy(&out[3], &addrbin[1], 20);
1011
out[23] = 0x88; /* OP_EQUALVERIFY */
1012
out[24] = 0xac; /* OP_CHECKSIG */
1013
return rv;
1014
}
1015
}
1016
1017
/* Subtract the `struct timeval' values X and Y,
1018
storing the result in RESULT.
1019
Return 1 if the difference is negative, otherwise 0. */
1020
int timeval_subtract(struct timeval *result, struct timeval *x,
1021
struct timeval *y)
1022
{
1023
/* Perform the carry for the later subtraction by updating Y. */
1024
if (x->tv_usec < y->tv_usec) {
1025
int nsec = (y->tv_usec - x->tv_usec) / 1000000 + 1;
1026
y->tv_usec -= 1000000 * nsec;
1027
y->tv_sec += nsec;
1028
}
1029
if (x->tv_usec - y->tv_usec > 1000000) {
1030
int nsec = (x->tv_usec - y->tv_usec) / 1000000;
1031
y->tv_usec += 1000000 * nsec;
1032
y->tv_sec -= nsec;
1033
}
1034
1035
/* Compute the time remaining to wait.
1036
* `tv_usec' is certainly positive. */
1037
result->tv_sec = x->tv_sec - y->tv_sec;
1038
result->tv_usec = x->tv_usec - y->tv_usec;
1039
1040
/* Return 1 if result is negative. */
1041
return x->tv_sec < y->tv_sec;
1042
}
1043
1044
bool fulltest(const uint32_t *hash, const uint32_t *target)
1045
{
1046
int i;
1047
bool rc = true;
1048
1049
for (i = 7; i >= 0; i--) {
1050
if (hash[i] > target[i]) {
1051
rc = false;
1052
break;
1053
}
1054
if (hash[i] < target[i]) {
1055
rc = true;
1056
break;
1057
}
1058
}
1059
1060
if (opt_debug) {
1061
uint32_t hash_be[8], target_be[8];
1062
char hash_str[65], target_str[65];
1063
1064
for (i = 0; i < 8; i++) {
1065
be32enc(hash_be + i, hash[7 - i]);
1066
be32enc(target_be + i, target[7 - i]);
1067
}
1068
bin2hex(hash_str, (unsigned char *)hash_be, 32);
1069
bin2hex(target_str, (unsigned char *)target_be, 32);
1070
1071
applog(LOG_DEBUG, "DEBUG: %s\nHash: %s\nTarget: %s",
1072
rc ? "hash <= target"
1073
: "hash > target (false positive)",
1074
hash_str,
1075
target_str);
1076
}
1077
1078
return rc;
1079
}
1080
1081
void diff_to_target(uint32_t *target, double diff)
1082
{
1083
uint64_t m;
1084
int k;
1085
1086
for (k = 6; k > 0 && diff > 1.0; k--)
1087
diff /= 4294967296.0;
1088
m = (uint64_t)(4294901760.0 / diff);
1089
if (m == 0 && k == 6)
1090
memset(target, 0xff, 32);
1091
else {
1092
memset(target, 0, 32);
1093
target[k] = (uint32_t)m;
1094
target[k + 1] = (uint32_t)(m >> 32);
1095
}
1096
}
1097
1098
// Only used by stratum pools
1099
void work_set_target(struct work* work, double diff)
1100
{
1101
diff_to_target(work->target, diff);
1102
work->targetdiff = diff;
1103
}
1104
1105
// Only used by longpoll pools
1106
double target_to_diff(uint32_t* target)
1107
{
1108
uchar* tgt = (uchar*) target;
1109
uint64_t m =
1110
(uint64_t)tgt[29] << 56 |
1111
(uint64_t)tgt[28] << 48 |
1112
(uint64_t)tgt[27] << 40 |
1113
(uint64_t)tgt[26] << 32 |
1114
(uint64_t)tgt[25] << 24 |
1115
(uint64_t)tgt[24] << 16 |
1116
(uint64_t)tgt[23] << 8 |
1117
(uint64_t)tgt[22] << 0;
1118
1119
if (!m)
1120
return 0.;
1121
else
1122
return (double)0x0000ffff00000000/m;
1123
}
1124
1125
#ifdef WIN32
1126
#define socket_blocks() (WSAGetLastError() == WSAEWOULDBLOCK)
1127
#else
1128
#define socket_blocks() (errno == EAGAIN || errno == EWOULDBLOCK)
1129
#endif
1130
1131
static bool send_line(curl_socket_t sock, char *s)
1132
{
1133
size_t sent = 0;
1134
int len;
1135
1136
len = (int) strlen(s);
1137
s[len++] = '\n';
1138
1139
while (len > 0) {
1140
struct timeval timeout = {0, 0};
1141
int n;
1142
fd_set wd;
1143
1144
FD_ZERO(&wd);
1145
FD_SET(sock, &wd);
1146
if (select((int) (sock + 1), NULL, &wd, NULL, &timeout) < 1)
1147
return false;
1148
n = send(sock, s + sent, len, 0);
1149
if (n < 0) {
1150
if (!socket_blocks())
1151
return false;
1152
n = 0;
1153
}
1154
sent += n;
1155
len -= n;
1156
}
1157
1158
return true;
1159
}
1160
1161
bool stratum_send_line(struct stratum_ctx *sctx, char *s)
1162
{
1163
bool ret = false;
1164
1165
if (opt_protocol)
1166
applog(LOG_DEBUG, "> %s", s);
1167
1168
pthread_mutex_lock(&sctx->sock_lock);
1169
ret = send_line(sctx->sock, s);
1170
pthread_mutex_unlock(&sctx->sock_lock);
1171
1172
return ret;
1173
}
1174
1175
static bool socket_full(curl_socket_t sock, int timeout)
1176
{
1177
struct timeval tv;
1178
fd_set rd;
1179
1180
FD_ZERO(&rd);
1181
FD_SET(sock, &rd);
1182
tv.tv_sec = timeout;
1183
tv.tv_usec = 0;
1184
if (select((int)(sock + 1), &rd, NULL, NULL, &tv) > 0)
1185
return true;
1186
return false;
1187
}
1188
1189
bool stratum_socket_full(struct stratum_ctx *sctx, int timeout)
1190
{
1191
return strlen(sctx->sockbuf) || socket_full(sctx->sock, timeout);
1192
}
1193
1194
#define RBUFSIZE 2048
1195
#define RECVSIZE (RBUFSIZE - 4)
1196
1197
static void stratum_buffer_append(struct stratum_ctx *sctx, const char *s)
1198
{
1199
size_t old, n;
1200
1201
old = strlen(sctx->sockbuf);
1202
n = old + strlen(s) + 1;
1203
if (n >= sctx->sockbuf_size) {
1204
sctx->sockbuf_size = n + (RBUFSIZE - (n % RBUFSIZE));
1205
sctx->sockbuf = (char*) realloc(sctx->sockbuf, sctx->sockbuf_size);
1206
}
1207
strcpy(sctx->sockbuf + old, s);
1208
}
1209
1210
char *stratum_recv_line(struct stratum_ctx *sctx)
1211
{
1212
ssize_t len, buflen;
1213
char *tok, *sret = NULL;
1214
1215
if (!strstr(sctx->sockbuf, "\n")) {
1216
bool ret = true;
1217
time_t rstart;
1218
1219
time(&rstart);
1220
if (!socket_full(sctx->sock, 60)) {
1221
applog(LOG_ERR, "stratum_recv_line timed out");
1222
goto out;
1223
}
1224
do {
1225
char s[RBUFSIZE];
1226
ssize_t n;
1227
1228
memset(s, 0, RBUFSIZE);
1229
n = recv(sctx->sock, s, RECVSIZE, 0);
1230
if (!n) {
1231
ret = false;
1232
break;
1233
}
1234
if (n < 0) {
1235
if (!socket_blocks() || !socket_full(sctx->sock, 1)) {
1236
ret = false;
1237
break;
1238
}
1239
} else
1240
stratum_buffer_append(sctx, s);
1241
} while (time(NULL) - rstart < 60 && !strstr(sctx->sockbuf, "\n"));
1242
1243
if (!ret) {
1244
applog(LOG_ERR, "stratum_recv_line failed");
1245
goto out;
1246
}
1247
}
1248
1249
buflen = (ssize_t) strlen(sctx->sockbuf);
1250
tok = strtok(sctx->sockbuf, "\n");
1251
if (!tok) {
1252
applog(LOG_ERR, "stratum_recv_line failed to parse a newline-terminated string");
1253
goto out;
1254
}
1255
sret = strdup(tok);
1256
len = (ssize_t) strlen(sret);
1257
1258
if (buflen > len + 1)
1259
memmove(sctx->sockbuf, sctx->sockbuf + len + 1, buflen - len + 1);
1260
else
1261
sctx->sockbuf[0] = '\0';
1262
1263
out:
1264
if (sret && opt_protocol)
1265
applog(LOG_DEBUG, "< %s", sret);
1266
return sret;
1267
}
1268
1269
#if LIBCURL_VERSION_NUM >= 0x071101
1270
static curl_socket_t opensocket_grab_cb(void *clientp, curlsocktype purpose,
1271
struct curl_sockaddr *addr)
1272
{
1273
curl_socket_t *sock = (curl_socket_t*) clientp;
1274
*sock = socket(addr->family, addr->socktype, addr->protocol);
1275
return *sock;
1276
}
1277
#endif
1278
1279
bool stratum_connect(struct stratum_ctx *sctx, const char *url)
1280
{
1281
CURL *curl;
1282
int rc;
1283
1284
pthread_mutex_lock(&sctx->sock_lock);
1285
if (sctx->curl)
1286
curl_easy_cleanup(sctx->curl);
1287
sctx->curl = curl_easy_init();
1288
if (!sctx->curl) {
1289
applog(LOG_ERR, "CURL initialization failed");
1290
pthread_mutex_unlock(&sctx->sock_lock);
1291
return false;
1292
}
1293
curl = sctx->curl;
1294
if (!sctx->sockbuf) {
1295
sctx->sockbuf = (char*) calloc(RBUFSIZE, 1);
1296
sctx->sockbuf_size = RBUFSIZE;
1297
}
1298
sctx->sockbuf[0] = '\0';
1299
pthread_mutex_unlock(&sctx->sock_lock);
1300
1301
if (url != sctx->url) {
1302
free(sctx->url);
1303
sctx->url = strdup(url);
1304
}
1305
free(sctx->curl_url);
1306
sctx->curl_url = (char*) malloc(strlen(url));
1307
sprintf(sctx->curl_url, "http%s", strstr(url, "://"));
1308
1309
if (opt_protocol)
1310
curl_easy_setopt(curl, CURLOPT_VERBOSE, 1);
1311
curl_easy_setopt(curl, CURLOPT_URL, sctx->curl_url);
1312
curl_easy_setopt(curl, CURLOPT_FRESH_CONNECT, 1);
1313
curl_easy_setopt(curl, CURLOPT_CONNECTTIMEOUT, 30);
1314
curl_easy_setopt(curl, CURLOPT_ERRORBUFFER, sctx->curl_err_str);
1315
curl_easy_setopt(curl, CURLOPT_NOSIGNAL, 1);
1316
curl_easy_setopt(curl, CURLOPT_TCP_NODELAY, 1);
1317
if (opt_proxy) {
1318
curl_easy_setopt(curl, CURLOPT_PROXY, opt_proxy);
1319
curl_easy_setopt(curl, CURLOPT_PROXYTYPE, opt_proxy_type);
1320
}
1321
curl_easy_setopt(curl, CURLOPT_HTTPPROXYTUNNEL, 1);
1322
#if LIBCURL_VERSION_NUM >= 0x070f06
1323
curl_easy_setopt(curl, CURLOPT_SOCKOPTFUNCTION, sockopt_keepalive_cb);
1324
#endif
1325
#if LIBCURL_VERSION_NUM >= 0x071101
1326
curl_easy_setopt(curl, CURLOPT_OPENSOCKETFUNCTION, opensocket_grab_cb);
1327
curl_easy_setopt(curl, CURLOPT_OPENSOCKETDATA, &sctx->sock);
1328
#endif
1329
curl_easy_setopt(curl, CURLOPT_CONNECT_ONLY, 1);
1330
1331
rc = curl_easy_perform(curl);
1332
if (rc) {
1333
applog(LOG_ERR, "Stratum connection failed: %s", sctx->curl_err_str);
1334
curl_easy_cleanup(curl);
1335
sctx->curl = NULL;
1336
return false;
1337
}
1338
1339
#if LIBCURL_VERSION_NUM < 0x071101
1340
/* CURLINFO_LASTSOCKET is broken on Win64; only use it as a last resort */
1341
curl_easy_getinfo(curl, CURLINFO_LASTSOCKET, (long *)&sctx->sock);
1342
#endif
1343
1344
return true;
1345
}
1346
1347
void stratum_disconnect(struct stratum_ctx *sctx)
1348
{
1349
pthread_mutex_lock(&sctx->sock_lock);
1350
if (sctx->curl) {
1351
curl_easy_cleanup(sctx->curl);
1352
sctx->curl = NULL;
1353
sctx->sockbuf[0] = '\0';
1354
}
1355
pthread_mutex_unlock(&sctx->sock_lock);
1356
}
1357
1358
static const char *get_stratum_session_id(json_t *val)
1359
{
1360
json_t *arr_val;
1361
int i, n;
1362
1363
arr_val = json_array_get(val, 0);
1364
if (!arr_val || !json_is_array(arr_val))
1365
return NULL;
1366
n = (int) json_array_size(arr_val);
1367
for (i = 0; i < n; i++) {
1368
const char *notify;
1369
json_t *arr = json_array_get(arr_val, i);
1370
1371
if (!arr || !json_is_array(arr))
1372
break;
1373
notify = json_string_value(json_array_get(arr, 0));
1374
if (!notify)
1375
continue;
1376
if (!strcasecmp(notify, "mining.notify"))
1377
return json_string_value(json_array_get(arr, 1));
1378
}
1379
return NULL;
1380
}
1381
1382
static bool stratum_parse_extranonce(struct stratum_ctx *sctx, json_t *params, int pndx)
1383
{
1384
const char* xnonce1;
1385
int xn2_size;
1386
1387
xnonce1 = json_string_value(json_array_get(params, pndx));
1388
if (!xnonce1) {
1389
applog(LOG_ERR, "Failed to get extranonce1");
1390
goto out;
1391
}
1392
xn2_size = (int) json_integer_value(json_array_get(params, pndx+1));
1393
if (!xn2_size) {
1394
applog(LOG_ERR, "Failed to get extranonce2_size");
1395
goto out;
1396
}
1397
if (xn2_size < 2 || xn2_size > 16) {
1398
applog(LOG_INFO, "Failed to get valid n2size in parse_extranonce");
1399
goto out;
1400
}
1401
1402
pthread_mutex_lock(&sctx->work_lock);
1403
if (sctx->xnonce1)
1404
free(sctx->xnonce1);
1405
sctx->xnonce1_size = strlen(xnonce1) / 2;
1406
sctx->xnonce1 = (uchar*) calloc(1, sctx->xnonce1_size);
1407
if (unlikely(!sctx->xnonce1)) {
1408
applog(LOG_ERR, "Failed to alloc xnonce1");
1409
pthread_mutex_unlock(&sctx->work_lock);
1410
goto out;
1411
}
1412
hex2bin(sctx->xnonce1, xnonce1, sctx->xnonce1_size);
1413
sctx->xnonce2_size = xn2_size;
1414
pthread_mutex_unlock(&sctx->work_lock);
1415
1416
if (pndx == 0 && opt_debug) /* pool dynamic change */
1417
applog(LOG_DEBUG, "Stratum set nonce %s with extranonce2 size=%d",
1418
xnonce1, xn2_size);
1419
1420
return true;
1421
out:
1422
return false;
1423
}
1424
1425
bool stratum_subscribe(struct stratum_ctx *sctx)
1426
{
1427
char *s, *sret = NULL;
1428
const char *sid;
1429
json_t *val = NULL, *res_val, *err_val;
1430
json_error_t err;
1431
bool ret = false, retry = false;
1432
1433
if (jsonrpc_2)
1434
return true;
1435
1436
start:
1437
s = (char*) malloc(128 + (sctx->session_id ? strlen(sctx->session_id) : 0));
1438
if (retry)
1439
sprintf(s, "{\"id\": 1, \"method\": \"mining.subscribe\", \"params\": []}");
1440
else if (sctx->session_id)
1441
sprintf(s, "{\"id\": 1, \"method\": \"mining.subscribe\", \"params\": [\"" USER_AGENT "\", \"%s\"]}", sctx->session_id);
1442
else
1443
sprintf(s, "{\"id\": 1, \"method\": \"mining.subscribe\", \"params\": [\"" USER_AGENT "\"]}");
1444
1445
if (!stratum_send_line(sctx, s)) {
1446
applog(LOG_ERR, "stratum_subscribe send failed");
1447
goto out;
1448
}
1449
1450
if (!socket_full(sctx->sock, 30)) {
1451
applog(LOG_ERR, "stratum_subscribe timed out");
1452
goto out;
1453
}
1454
1455
sret = stratum_recv_line(sctx);
1456
if (!sret)
1457
goto out;
1458
1459
val = JSON_LOADS(sret, &err);
1460
free(sret);
1461
if (!val) {
1462
applog(LOG_ERR, "JSON decode failed(%d): %s", err.line, err.text);
1463
goto out;
1464
}
1465
1466
res_val = json_object_get(val, "result");
1467
err_val = json_object_get(val, "error");
1468
1469
if (!res_val || json_is_null(res_val) ||
1470
(err_val && !json_is_null(err_val))) {
1471
if (opt_debug || retry) {
1472
free(s);
1473
if (err_val)
1474
s = json_dumps(err_val, JSON_INDENT(3));
1475
else
1476
s = strdup("(unknown reason)");
1477
applog(LOG_ERR, "JSON-RPC call failed: %s", s);
1478
}
1479
goto out;
1480
}
1481
1482
sid = get_stratum_session_id(res_val);
1483
if (opt_debug && sid)
1484
applog(LOG_DEBUG, "Stratum session id: %s", sid);
1485
1486
pthread_mutex_lock(&sctx->work_lock);
1487
if (sctx->session_id)
1488
free(sctx->session_id);
1489
sctx->session_id = sid ? strdup(sid) : NULL;
1490
sctx->next_diff = 1.0;
1491
pthread_mutex_unlock(&sctx->work_lock);
1492
1493
// sid is param 1, extranonce params are 2 and 3
1494
if (!stratum_parse_extranonce(sctx, res_val, 1)) {
1495
goto out;
1496
}
1497
1498
ret = true;
1499
1500
out:
1501
free(s);
1502
if (val)
1503
json_decref(val);
1504
1505
if (!ret) {
1506
if (sret && !retry) {
1507
retry = true;
1508
goto start;
1509
}
1510
}
1511
1512
return ret;
1513
}
1514
1515
extern bool opt_extranonce;
1516
1517
bool stratum_authorize(struct stratum_ctx *sctx, const char *user, const char *pass)
1518
{
1519
json_t *val = NULL, *res_val, *err_val;
1520
char *s, *sret;
1521
json_error_t err;
1522
bool ret = false;
1523
int req_id = 0;
1524
1525
if (jsonrpc_2) {
1526
s = (char*) malloc(300 + strlen(user) + strlen(pass));
1527
sprintf(s, "{\"method\": \"login\", \"params\": {"
1528
"\"login\": \"%s\", \"pass\": \"%s\", \"agent\": \"%s\"}, \"id\": 1}",
1529
user, pass, USER_AGENT);
1530
} else {
1531
s = (char*) malloc(80 + strlen(user) + strlen(pass));
1532
sprintf(s, "{\"id\": 2, \"method\": \"mining.authorize\", \"params\": [\"%s\", \"%s\"]}",
1533
user, pass);
1534
}
1535
1536
if (!stratum_send_line(sctx, s))
1537
goto out;
1538
1539
while (1) {
1540
sret = stratum_recv_line(sctx);
1541
if (!sret)
1542
goto out;
1543
if (!stratum_handle_method(sctx, sret))
1544
break;
1545
free(sret);
1546
}
1547
1548
val = JSON_LOADS(sret, &err);
1549
free(sret);
1550
if (!val) {
1551
applog(LOG_ERR, "JSON decode failed(%d): %s", err.line, err.text);
1552
goto out;
1553
}
1554
1555
res_val = json_object_get(val, "result");
1556
err_val = json_object_get(val, "error");
1557
req_id = (int) json_integer_value(json_object_get(val, "id"));
1558
1559
if (req_id == 2
1560
&& (!res_val || json_is_false(res_val) || (err_val && !json_is_null(err_val)))) {
1561
applog(LOG_ERR, "Stratum authentication failed");
1562
goto out;
1563
}
1564
1565
if (jsonrpc_2) {
1566
rpc2_login_decode(val);
1567
json_t *job_val = json_object_get(res_val, "job");
1568
pthread_mutex_lock(&sctx->work_lock);
1569
if(job_val) rpc2_job_decode(job_val, &sctx->work);
1570
pthread_mutex_unlock(&sctx->work_lock);
1571
}
1572
1573
ret = true;
1574
1575
if (!opt_extranonce)
1576
goto out;
1577
1578
// subscribe to extranonce (optional)
1579
sprintf(s, "{\"id\": 3, \"method\": \"mining.extranonce.subscribe\", \"params\": []}");
1580
1581
if (!stratum_send_line(sctx, s))
1582
goto out;
1583
1584
if (!socket_full(sctx->sock, 3)) {
1585
if (opt_debug)
1586
applog(LOG_DEBUG, "stratum extranonce subscribe timed out");
1587
goto out;
1588
}
1589
1590
sret = stratum_recv_line(sctx);
1591
if (sret) {
1592
json_t *extra = JSON_LOADS(sret, &err);
1593
if (!extra) {
1594
applog(LOG_WARNING, "JSON decode failed(%d): %s", err.line, err.text);
1595
} else {
1596
if (json_integer_value(json_object_get(extra, "id")) != 3) {
1597
// we receive a standard method if extranonce is ignored
1598
if (!stratum_handle_method(sctx, sret))
1599
applog(LOG_WARNING, "Stratum answer id is not correct!");
1600
}
1601
json_decref(extra);
1602
}
1603
free(sret);
1604
}
1605
1606
out:
1607
free(s);
1608
if (val)
1609
json_decref(val);
1610
1611
return ret;
1612
}
1613
1614
// -------------------- RPC 2.0 (XMR/AEON) -------------------------
1615
1616
extern pthread_mutex_t rpc2_login_lock;
1617
extern pthread_mutex_t rpc2_job_lock;
1618
1619
bool rpc2_login_decode(const json_t *val)
1620
{
1621
const char *id;
1622
const char *s;
1623
1624
json_t *res = json_object_get(val, "result");
1625
if(!res) {
1626
applog(LOG_ERR, "JSON invalid result");
1627
goto err_out;
1628
}
1629
1630
json_t *tmp;
1631
tmp = json_object_get(res, "id");
1632
if(!tmp) {
1633
applog(LOG_ERR, "JSON inval id");
1634
goto err_out;
1635
}
1636
id = json_string_value(tmp);
1637
if(!id) {
1638
applog(LOG_ERR, "JSON id is not a string");
1639
goto err_out;
1640
}
1641
1642
memcpy(&rpc2_id, id, 64);
1643
1644
if(opt_debug)
1645
applog(LOG_DEBUG, "Auth id: %s", id);
1646
1647
tmp = json_object_get(res, "status");
1648
if(!tmp) {
1649
applog(LOG_ERR, "JSON inval status");
1650
goto err_out;
1651
}
1652
s = json_string_value(tmp);
1653
if(!s) {
1654
applog(LOG_ERR, "JSON status is not a string");
1655
goto err_out;
1656
}
1657
if(strcmp(s, "OK")) {
1658
applog(LOG_ERR, "JSON returned status \"%s\"", s);
1659
return false;
1660
}
1661
1662
return true;
1663
1664
err_out:
1665
applog(LOG_WARNING,"%s: fail", __func__);
1666
return false;
1667
}
1668
1669
json_t* json_rpc2_call_recur(CURL *curl, const char *url, const char *userpass,
1670
json_t *rpc_req, int *curl_err, int flags, int recur)
1671
{
1672
if(recur >= 5) {
1673
if(opt_debug)
1674
applog(LOG_DEBUG, "Failed to call rpc command after %i tries", recur);
1675
return NULL;
1676
}
1677
if(!strcmp(rpc2_id, "")) {
1678
if(opt_debug)
1679
applog(LOG_DEBUG, "Tried to call rpc2 command before authentication");
1680
return NULL;
1681
}
1682
json_t *params = json_object_get(rpc_req, "params");
1683
if (params) {
1684
json_t *auth_id = json_object_get(params, "id");
1685
if (auth_id) {
1686
json_string_set(auth_id, rpc2_id);
1687
}
1688
}
1689
json_t *res = json_rpc_call(curl, url, userpass, json_dumps(rpc_req, 0),
1690
curl_err, flags | JSON_RPC_IGNOREERR);
1691
if(!res) goto end;
1692
json_t *error = json_object_get(res, "error");
1693
if(!error) goto end;
1694
json_t *message;
1695
if(json_is_string(error))
1696
message = error;
1697
else
1698
message = json_object_get(error, "message");
1699
if(!message || !json_is_string(message)) goto end;
1700
const char *mes = json_string_value(message);
1701
if(!strcmp(mes, "Unauthenticated")) {
1702
pthread_mutex_lock(&rpc2_login_lock);
1703
rpc2_login(curl);
1704
sleep(1);
1705
pthread_mutex_unlock(&rpc2_login_lock);
1706
return json_rpc2_call_recur(curl, url, userpass, rpc_req,
1707
curl_err, flags, recur + 1);
1708
} else if(!strcmp(mes, "Low difficulty share") || !strcmp(mes, "Block expired") || !strcmp(mes, "Invalid job id") || !strcmp(mes, "Duplicate share")) {
1709
json_t *result = json_object_get(res, "result");
1710
if(!result) {
1711
goto end;
1712
}
1713
json_object_set(result, "reject-reason", json_string(mes));
1714
} else {
1715
applog(LOG_ERR, "json_rpc2.0 error: %s", mes);
1716
return NULL;
1717
}
1718
end:
1719
return res;
1720
}
1721
1722
json_t *json_rpc2_call(CURL *curl, const char *url, const char *userpass, const char *rpc_req, int *curl_err, int flags)
1723
{
1724
json_t* req_json = JSON_LOADS(rpc_req, NULL);
1725
json_t* res = json_rpc2_call_recur(curl, url, userpass, req_json, curl_err, flags, 0);
1726
json_decref(req_json);
1727
return res;
1728
}
1729
1730
bool rpc2_job_decode(const json_t *job, struct work *work)
1731
{
1732
if (!jsonrpc_2) {
1733
applog(LOG_ERR, "Tried to decode job without JSON-RPC 2.0");
1734
return false;
1735
}
1736
json_t *tmp;
1737
tmp = json_object_get(job, "job_id");
1738
if (!tmp) {
1739
applog(LOG_ERR, "JSON invalid job id");
1740
goto err_out;
1741
}
1742
const char *job_id = json_string_value(tmp);
1743
tmp = json_object_get(job, "blob");
1744
if (!tmp) {
1745
applog(LOG_ERR, "JSON invalid blob");
1746
goto err_out;
1747
}
1748
const char *hexblob = json_string_value(tmp);
1749
size_t blobLen = strlen(hexblob);
1750
if (blobLen % 2 != 0 || ((blobLen / 2) < 40 && blobLen != 0) || (blobLen / 2) > 128) {
1751
applog(LOG_ERR, "JSON invalid blob length");
1752
goto err_out;
1753
}
1754
if (blobLen != 0) {
1755
uint32_t target = 0;
1756
pthread_mutex_lock(&rpc2_job_lock);
1757
uchar *blob = (uchar*) malloc(blobLen / 2);
1758
if (!hex2bin(blob, hexblob, blobLen / 2)) {
1759
applog(LOG_ERR, "JSON invalid blob");
1760
pthread_mutex_unlock(&rpc2_job_lock);
1761
goto err_out;
1762
}
1763
rpc2_bloblen = blobLen / 2;
1764
if (rpc2_blob) free(rpc2_blob);
1765
rpc2_blob = (char*) malloc(rpc2_bloblen);
1766
if (!rpc2_blob) {
1767
applog(LOG_ERR, "RPC2 OOM!");
1768
goto err_out;
1769
}
1770
memcpy(rpc2_blob, blob, blobLen / 2);
1771
free(blob);
1772
1773
jobj_binary(job, "target", &target, 4);
1774
if(rpc2_target != target) {
1775
double hashrate = 0.0;
1776
pthread_mutex_lock(&stats_lock);
1777
for (int i = 0; i < opt_n_threads; i++)
1778
hashrate += thr_hashrates[i];
1779
pthread_mutex_unlock(&stats_lock);
1780
double difficulty = (((double) 0xffffffff) / target);
1781
if (!opt_quiet) {
1782
// xmr pool diff can change a lot...
1783
applog(LOG_WARNING, "Stratum difficulty set to %g", difficulty);
1784
}
1785
stratum_diff = difficulty;
1786
rpc2_target = target;
1787
}
1788
1789
if (rpc2_job_id) free(rpc2_job_id);
1790
rpc2_job_id = strdup(job_id);
1791
pthread_mutex_unlock(&rpc2_job_lock);
1792
}
1793
if(work) {
1794
if (!rpc2_blob) {
1795
applog(LOG_WARNING, "Work requested before it was received");
1796
goto err_out;
1797
}
1798
memcpy(work->data, rpc2_blob, rpc2_bloblen);
1799
memset(work->target, 0xff, sizeof(work->target));
1800
work->target[7] = rpc2_target;
1801
if (work->job_id) free(work->job_id);
1802
work->job_id = strdup(rpc2_job_id);
1803
}
1804
return true;
1805
1806
err_out:
1807
applog(LOG_WARNING, "%s", __func__);
1808
return false;
1809
}
1810
1811
/**
1812
* Extract bloc height L H... here len=3, height=0x1333e8
1813
* "...0000000000ffffffff2703e83313062f503253482f043d61105408"
1814
*/
1815
static uint32_t getblocheight(struct stratum_ctx *sctx)
1816
{
1817
uint32_t height = 0;
1818
uint8_t hlen = 0, *p, *m;
1819
1820
// find 0xffff tag
1821
p = (uint8_t*) sctx->job.coinbase + 32;
1822
m = p + 128;
1823
while (*p != 0xff && p < m) p++;
1824
while (*p == 0xff && p < m) p++;
1825
if (*(p-1) == 0xff && *(p-2) == 0xff) {
1826
p++; hlen = *p;
1827
p++; height = le16dec(p);
1828
p += 2;
1829
switch (hlen) {
1830
case 4:
1831
height += 0x10000UL * le16dec(p);
1832
break;
1833
case 3:
1834
height += 0x10000UL * (*p);
1835
break;
1836
}
1837
}
1838
return height;
1839
}
1840
1841
static bool stratum_notify(struct stratum_ctx *sctx, json_t *params)
1842
{
1843
char algo[64] = { 0 };
1844
const char *job_id, *prevhash, *coinb1, *coinb2, *version, *nbits, *ntime;
1845
const char *extradata = NULL;
1846
size_t coinb1_size, coinb2_size;
1847
bool clean, ret = false;
1848
int merkle_count, i, p=0;
1849
bool has_claim, has_roots;
1850
json_t *merkle_arr;
1851
uchar **merkle;
1852
1853
get_currentalgo(algo, sizeof(algo));
1854
has_claim = strcmp(algo, "lbry") == 0 && json_array_size(params) == 10;
1855
has_roots = strcmp(algo, "phi2") == 0 && json_array_size(params) == 10;
1856
1857
job_id = json_string_value(json_array_get(params, p++));
1858
prevhash = json_string_value(json_array_get(params, p++));
1859
if (has_claim) {
1860
extradata = json_string_value(json_array_get(params, p++));
1861
if (!extradata || strlen(extradata) != 64) {
1862
applog(LOG_ERR, "Stratum notify: invalid claim parameter");
1863
goto out;
1864
}
1865
}
1866
else if (has_roots) {
1867
extradata = json_string_value(json_array_get(params, p++));
1868
if (!extradata || strlen(extradata) != 128) {
1869
applog(LOG_ERR, "Stratum notify: invalid UTXO root parameter");
1870
goto out;
1871
}
1872
}
1873
coinb1 = json_string_value(json_array_get(params, p++));
1874
coinb2 = json_string_value(json_array_get(params, p++));
1875
merkle_arr = json_array_get(params, p++);
1876
if (!merkle_arr || !json_is_array(merkle_arr))
1877
goto out;
1878
merkle_count = (int) json_array_size(merkle_arr);
1879
version = json_string_value(json_array_get(params, p++));
1880
nbits = json_string_value(json_array_get(params, p++));
1881
ntime = json_string_value(json_array_get(params, p++));
1882
clean = json_is_true(json_array_get(params, p));
1883
1884
if (!job_id || !prevhash || !coinb1 || !coinb2 || !version || !nbits || !ntime ||
1885
strlen(prevhash) != 64 || strlen(version) != 8 ||
1886
strlen(nbits) != 8 || strlen(ntime) != 8) {
1887
applog(LOG_ERR, "Stratum notify: invalid parameters");
1888
goto out;
1889
}
1890
merkle = (uchar**) malloc(merkle_count * sizeof(char *));
1891
for (i = 0; i < merkle_count; i++) {
1892
const char *s = json_string_value(json_array_get(merkle_arr, i));
1893
if (!s || strlen(s) != 64) {
1894
while (i--)
1895
free(merkle[i]);
1896
free(merkle);
1897
applog(LOG_ERR, "Stratum notify: invalid Merkle branch");
1898
goto out;
1899
}
1900
merkle[i] = (uchar*) malloc(32);
1901
hex2bin(merkle[i], s, 32);
1902
}
1903
1904
pthread_mutex_lock(&sctx->work_lock);
1905
1906
coinb1_size = strlen(coinb1) / 2;
1907
coinb2_size = strlen(coinb2) / 2;
1908
sctx->job.coinbase_size = coinb1_size + sctx->xnonce1_size +
1909
sctx->xnonce2_size + coinb2_size;
1910
sctx->job.coinbase = (uchar*) realloc(sctx->job.coinbase, sctx->job.coinbase_size);
1911
sctx->job.xnonce2 = sctx->job.coinbase + coinb1_size + sctx->xnonce1_size;
1912
hex2bin(sctx->job.coinbase, coinb1, coinb1_size);
1913
memcpy(sctx->job.coinbase + coinb1_size, sctx->xnonce1, sctx->xnonce1_size);
1914
if (!sctx->job.job_id || strcmp(sctx->job.job_id, job_id))
1915
memset(sctx->job.xnonce2, 0, sctx->xnonce2_size);
1916
hex2bin(sctx->job.xnonce2 + sctx->xnonce2_size, coinb2, coinb2_size);
1917
1918
free(sctx->job.job_id);
1919
sctx->job.job_id = strdup(job_id);
1920
hex2bin(sctx->job.prevhash, prevhash, 32);
1921
1922
if (has_claim) hex2bin(sctx->job.extra, extradata, 32);
1923
if (has_roots) hex2bin(sctx->job.extra, extradata, 64);
1924
1925
sctx->bloc_height = getblocheight(sctx);
1926
1927
for (i = 0; i < sctx->job.merkle_count; i++)
1928
free(sctx->job.merkle[i]);
1929
free(sctx->job.merkle);
1930
sctx->job.merkle = merkle;
1931
sctx->job.merkle_count = merkle_count;
1932
1933
hex2bin(sctx->job.version, version, 4);
1934
hex2bin(sctx->job.nbits, nbits, 4);
1935
hex2bin(sctx->job.ntime, ntime, 4);
1936
sctx->job.clean = clean;
1937
1938
sctx->job.diff = sctx->next_diff;
1939
1940
pthread_mutex_unlock(&sctx->work_lock);
1941
1942
ret = true;
1943
1944
out:
1945
return ret;
1946
}
1947
1948
static bool stratum_set_difficulty(struct stratum_ctx *sctx, json_t *params)
1949
{
1950
double diff;
1951
1952
diff = json_number_value(json_array_get(params, 0));
1953
if (diff == 0)
1954
return false;
1955
1956
pthread_mutex_lock(&sctx->work_lock);
1957
sctx->next_diff = diff;
1958
pthread_mutex_unlock(&sctx->work_lock);
1959
1960
return true;
1961
}
1962
1963
static bool stratum_reconnect(struct stratum_ctx *sctx, json_t *params)
1964
{
1965
json_t *port_val;
1966
char *url;
1967
const char *host;
1968
int port;
1969
1970
host = json_string_value(json_array_get(params, 0));
1971
port_val = json_array_get(params, 1);
1972
if (json_is_string(port_val))
1973
port = atoi(json_string_value(port_val));
1974
else
1975
port = (int) json_integer_value(port_val);
1976
if (!host || !port)
1977
return false;
1978
1979
url = (char*) malloc(32 + strlen(host));
1980
sprintf(url, "stratum+tcp://%s:%d", host, port);
1981
1982
if (!opt_redirect) {
1983
applog(LOG_INFO, "Ignoring request to reconnect to %s", url);
1984
free(url);
1985
return true;
1986
}
1987
1988
applog(LOG_NOTICE, "Server requested reconnection to %s", url);
1989
1990
free(sctx->url);
1991
sctx->url = url;
1992
stratum_disconnect(sctx);
1993
1994
return true;
1995
}
1996
1997
static bool json_object_set_error(json_t *result, int code, const char *msg)
1998
{
1999
json_t *val = json_object();
2000
json_object_set_new(val, "code", json_integer(code));
2001
json_object_set_new(val, "message", json_string(msg));
2002
return json_object_set_new(result, "error", val) != -1;
2003
}
2004
2005
/* allow to report algo perf to the pool for algo stats */
2006
static bool stratum_benchdata(json_t *result, json_t *params, int thr_id)
2007
{
2008
char algo[64] = { 0 };
2009
char cpuname[80] = { 0 };
2010
char vendorid[32] = { 0 };
2011
char compiler[32] = { 0 };
2012
char arch[16] = { 0 };
2013
char os[8];
2014
char *p;
2015
double cpufreq = 0;
2016
json_t *val;
2017
2018
if (!opt_stratum_stats) return false;
2019
2020
get_currentalgo(algo, sizeof(algo));
2021
2022
#if defined(WIN32) && (defined(_M_X64) || defined(__x86_64__))
2023
strcpy(os, "win64");
2024
#else
2025
strcpy(os, is_windows() ? "win32" : "linux");
2026
#endif
2027
2028
#ifdef _MSC_VER
2029
sprintf(compiler, "MSVC %d\n", msver());
2030
#elif defined(__clang__)
2031
sprintf(compiler, "clang %s\n", __clang_version__);
2032
#elif defined(__GNUC__)
2033
sprintf(compiler, "GCC %d.%d.%d\n", __GNUC__, __GNUC_MINOR__, __GNUC_PATCHLEVEL__);
2034
#endif
2035
2036
#ifdef __AVX2__
2037
strcat(compiler, " AVX2");
2038
#elif defined(__AVX__)
2039
strcat(compiler, " AVX");
2040
#elif defined(__FMA4__)
2041
strcat(compiler, " FMA4");
2042
#elif defined(__FMA3__)
2043
strcat(compiler, " FMA3");
2044
#elif defined(__SSE4_2__)
2045
strcat(compiler, " SSE4.2");
2046
#elif defined(__SSE4_1__)
2047
strcat(compiler, " SSE4");
2048
#elif defined(__SSE3__)
2049
strcat(compiler, " SSE3");
2050
#elif defined(__SSE2__)
2051
strcat(compiler, " SSE2");
2052
#elif defined(__SSE__)
2053
strcat(compiler, " SSE");
2054
#endif
2055
2056
cpu_bestfeature(arch, 16);
2057
if (has_aes_ni()) strcat(arch, " NI");
2058
2059
cpu_getmodelid(vendorid, 32);
2060
cpu_getname(cpuname, 80);
2061
p = strstr(cpuname, " @ ");
2062
if (p) {
2063
char freq[32] = { 0 };
2064
*p = '\0'; p += 3;
2065
snprintf(freq, 32, "%s", p);
2066
cpufreq = atof(freq);
2067
p = strstr(freq, "GHz"); if (p) cpufreq *= 1000;
2068
applog(LOG_NOTICE, "sharing CPU stats with freq %s", freq);
2069
}
2070
2071
compiler[31] = '\0';
2072
2073
val = json_object();
2074
json_object_set_new(val, "algo", json_string(algo));
2075
json_object_set_new(val, "type", json_string("cpu"));
2076
json_object_set_new(val, "device", json_string(cpuname));
2077
json_object_set_new(val, "vendorid", json_string(vendorid));
2078
json_object_set_new(val, "arch", json_string(arch));
2079
json_object_set_new(val, "freq", json_integer((uint64_t)cpufreq));
2080
json_object_set_new(val, "memf", json_integer(0));
2081
json_object_set_new(val, "power", json_integer(0));
2082
json_object_set_new(val, "khashes", json_real((double)global_hashrate / 1000.0));
2083
json_object_set_new(val, "intensity", json_real(opt_priority));
2084
json_object_set_new(val, "throughput", json_integer(opt_n_threads));
2085
json_object_set_new(val, "client", json_string(PACKAGE_NAME "/" PACKAGE_VERSION));
2086
json_object_set_new(val, "os", json_string(os));
2087
json_object_set_new(val, "driver", json_string(compiler));
2088
2089
json_object_set_new(result, "result", val);
2090
2091
return true;
2092
}
2093
2094
static bool stratum_get_stats(struct stratum_ctx *sctx, json_t *id, json_t *params)
2095
{
2096
char *s;
2097
json_t *val;
2098
bool ret;
2099
2100
if (!id || json_is_null(id))
2101
return false;
2102
2103
val = json_object();
2104
json_object_set(val, "id", id);
2105
2106
ret = stratum_benchdata(val, params, 0);
2107
2108
if (!ret) {
2109
json_object_set_error(val, 1, "disabled"); //EPERM
2110
} else {
2111
json_object_set_new(val, "error", json_null());
2112
}
2113
2114
s = json_dumps(val, 0);
2115
ret = stratum_send_line(sctx, s);
2116
json_decref(val);
2117
free(s);
2118
2119
return ret;
2120
}
2121
2122
static bool stratum_unknown_method(struct stratum_ctx *sctx, json_t *id)
2123
{
2124
char *s;
2125
json_t *val;
2126
bool ret = false;
2127
2128
if (!id || json_is_null(id))
2129
return ret;
2130
2131
val = json_object();
2132
json_object_set(val, "id", id);
2133
json_object_set_new(val, "result", json_false());
2134
json_object_set_error(val, 38, "unknown method"); // ENOSYS
2135
2136
s = json_dumps(val, 0);
2137
ret = stratum_send_line(sctx, s);
2138
json_decref(val);
2139
free(s);
2140
2141
return ret;
2142
}
2143
2144
static bool stratum_pong(struct stratum_ctx *sctx, json_t *id)
2145
{
2146
char buf[64];
2147
bool ret = false;
2148
2149
if (!id || json_is_null(id))
2150
return ret;
2151
2152
sprintf(buf, "{\"id\":%d,\"result\":\"pong\",\"error\":null}",
2153
(int) json_integer_value(id));
2154
ret = stratum_send_line(sctx, buf);
2155
2156
return ret;
2157
}
2158
2159
static bool stratum_get_algo(struct stratum_ctx *sctx, json_t *id, json_t *params)
2160
{
2161
char algo[64] = { 0 };
2162
char *s;
2163
json_t *val;
2164
bool ret = true;
2165
2166
if (!id || json_is_null(id))
2167
return false;
2168
2169
get_currentalgo(algo, sizeof(algo));
2170
2171
val = json_object();
2172
json_object_set(val, "id", id);
2173
json_object_set_new(val, "error", json_null());
2174
json_object_set_new(val, "result", json_string(algo));
2175
2176
s = json_dumps(val, 0);
2177
ret = stratum_send_line(sctx, s);
2178
json_decref(val);
2179
free(s);
2180
2181
return ret;
2182
}
2183
2184
static bool stratum_get_version(struct stratum_ctx *sctx, json_t *id)
2185
{
2186
char *s;
2187
json_t *val;
2188
bool ret;
2189
2190
if (!id || json_is_null(id))
2191
return false;
2192
2193
val = json_object();
2194
json_object_set(val, "id", id);
2195
json_object_set_new(val, "error", json_null());
2196
json_object_set_new(val, "result", json_string(USER_AGENT));
2197
s = json_dumps(val, 0);
2198
ret = stratum_send_line(sctx, s);
2199
json_decref(val);
2200
free(s);
2201
2202
return ret;
2203
}
2204
2205
static bool stratum_show_message(struct stratum_ctx *sctx, json_t *id, json_t *params)
2206
{
2207
char *s;
2208
json_t *val;
2209
bool ret;
2210
2211
val = json_array_get(params, 0);
2212
if (val)
2213
applog(LOG_NOTICE, "MESSAGE FROM SERVER: %s", json_string_value(val));
2214
2215
if (!id || json_is_null(id))
2216
return true;
2217
2218
val = json_object();
2219
json_object_set(val, "id", id);
2220
json_object_set_new(val, "error", json_null());
2221
json_object_set_new(val, "result", json_true());
2222
s = json_dumps(val, 0);
2223
ret = stratum_send_line(sctx, s);
2224
json_decref(val);
2225
free(s);
2226
2227
return ret;
2228
}
2229
2230
bool stratum_handle_method(struct stratum_ctx *sctx, const char *s)
2231
{
2232
json_t *val, *id, *params;
2233
json_error_t err;
2234
const char *method;
2235
bool ret = false;
2236
2237
val = JSON_LOADS(s, &err);
2238
if (!val) {
2239
applog(LOG_ERR, "JSON decode failed(%d): %s", err.line, err.text);
2240
goto out;
2241
}
2242
2243
method = json_string_value(json_object_get(val, "method"));
2244
if (!method)
2245
goto out;
2246
2247
params = json_object_get(val, "params");
2248
2249
if (jsonrpc_2) {
2250
if (!strcasecmp(method, "job")) {
2251
ret = rpc2_stratum_job(sctx, params);
2252
}
2253
goto out;
2254
}
2255
2256
id = json_object_get(val, "id");
2257
2258
if (!strcasecmp(method, "mining.notify")) {
2259
ret = stratum_notify(sctx, params);
2260
goto out;
2261
}
2262
if (!strcasecmp(method, "mining.ping")) { // cgminer 4.7.1+
2263
if (opt_debug) applog(LOG_DEBUG, "Pool ping");
2264
ret = stratum_pong(sctx, id);
2265
goto out;
2266
}
2267
if (!strcasecmp(method, "mining.set_difficulty")) {
2268
ret = stratum_set_difficulty(sctx, params);
2269
goto out;
2270
}
2271
if (!strcasecmp(method, "mining.set_extranonce")) {
2272
ret = stratum_parse_extranonce(sctx, params, 0);
2273
goto out;
2274
}
2275
if (!strcasecmp(method, "client.reconnect")) {
2276
ret = stratum_reconnect(sctx, params);
2277
goto out;
2278
}
2279
if (!strcasecmp(method, "client.get_algo")) {
2280
// will prevent wrong algo parameters on a pool, will be used as test on rejects
2281
if (!opt_quiet) applog(LOG_NOTICE, "Pool asked your algo parameter");
2282
ret = stratum_get_algo(sctx, id, params);
2283
goto out;
2284
}
2285
if (!strcasecmp(method, "client.get_stats")) {
2286
// optional to fill device benchmarks
2287
ret = stratum_get_stats(sctx, id, params);
2288
goto out;
2289
}
2290
if (!strcasecmp(method, "client.get_version")) {
2291
ret = stratum_get_version(sctx, id);
2292
goto out;
2293
}
2294
if (!strcasecmp(method, "client.show_message")) {
2295
ret = stratum_show_message(sctx, id, params);
2296
goto out;
2297
}
2298
2299
if (!ret) {
2300
// don't fail = disconnect stratum on unknown (and optional?) methods
2301
if (opt_debug) applog(LOG_WARNING, "unknown stratum method %s!", method);
2302
ret = stratum_unknown_method(sctx, id);
2303
}
2304
2305
out:
2306
if (val)
2307
json_decref(val);
2308
2309
return ret;
2310
}
2311
2312
struct thread_q *tq_new(void)
2313
{
2314
struct thread_q *tq;
2315
2316
tq = (struct thread_q*) calloc(1, sizeof(*tq));
2317
if (!tq)
2318
return NULL;
2319
2320
INIT_LIST_HEAD(&tq->q);
2321
pthread_mutex_init(&tq->mutex, NULL);
2322
pthread_cond_init(&tq->cond, NULL);
2323
2324
return tq;
2325
}
2326
2327
void tq_free(struct thread_q *tq)
2328
{
2329
struct tq_ent *ent, *iter;
2330
2331
if (!tq)
2332
return;
2333
2334
list_for_each_entry_safe(ent, iter, &tq->q, q_node, struct tq_ent) {
2335
list_del(&ent->q_node);
2336
free(ent);
2337
}
2338
2339
pthread_cond_destroy(&tq->cond);
2340
pthread_mutex_destroy(&tq->mutex);
2341
2342
memset(tq, 0, sizeof(*tq)); /* poison */
2343
free(tq);
2344
}
2345
2346
static void tq_freezethaw(struct thread_q *tq, bool frozen)
2347
{
2348
pthread_mutex_lock(&tq->mutex);
2349
2350
tq->frozen = frozen;
2351
2352
pthread_cond_signal(&tq->cond);
2353
pthread_mutex_unlock(&tq->mutex);
2354
}
2355
2356
void tq_freeze(struct thread_q *tq)
2357
{
2358
tq_freezethaw(tq, true);
2359
}
2360
2361
void tq_thaw(struct thread_q *tq)
2362
{
2363
tq_freezethaw(tq, false);
2364
}
2365
2366
bool tq_push(struct thread_q *tq, void *data)
2367
{
2368
struct tq_ent *ent;
2369
bool rc = true;
2370
2371
ent = (struct tq_ent*) calloc(1, sizeof(*ent));
2372
if (!ent)
2373
return false;
2374
2375
ent->data = data;
2376
INIT_LIST_HEAD(&ent->q_node);
2377
2378
pthread_mutex_lock(&tq->mutex);
2379
2380
if (!tq->frozen) {
2381
list_add_tail(&ent->q_node, &tq->q);
2382
} else {
2383
free(ent);
2384
rc = false;
2385
}
2386
2387
pthread_cond_signal(&tq->cond);
2388
pthread_mutex_unlock(&tq->mutex);
2389
2390
return rc;
2391
}
2392
2393
void *tq_pop(struct thread_q *tq, const struct timespec *abstime)
2394
{
2395
struct tq_ent *ent;
2396
void *rval = NULL;
2397
int rc;
2398
2399
pthread_mutex_lock(&tq->mutex);
2400
2401
if (!list_empty(&tq->q))
2402
goto pop;
2403
2404
if (abstime)
2405
rc = pthread_cond_timedwait(&tq->cond, &tq->mutex, abstime);
2406
else
2407
rc = pthread_cond_wait(&tq->cond, &tq->mutex);
2408
if (rc)
2409
goto out;
2410
if (list_empty(&tq->q))
2411
goto out;
2412
2413
pop:
2414
ent = list_entry(tq->q.next, struct tq_ent, q_node);
2415
rval = ent->data;
2416
2417
list_del(&ent->q_node);
2418
free(ent);
2419
2420
out:
2421
pthread_mutex_unlock(&tq->mutex);
2422
return rval;
2423
}
2424
2425
/* sprintf can be used in applog */
2426
static char* format_hash(char* buf, uint8_t *hash)
2427
{
2428
int len = 0;
2429
for (int i=0; i < 32; i += 4) {
2430
len += sprintf(buf+len, "%02x%02x%02x%02x ",
2431
hash[i], hash[i+1], hash[i+2], hash[i+3]);
2432
}
2433
return buf;
2434
}
2435
2436
void applog_compare_hash(void *hash, void *hash_ref)
2437
{
2438
char s[256] = "";
2439
int len = 0;
2440
uchar* hash1 = (uchar*)hash;
2441
uchar* hash2 = (uchar*)hash_ref;
2442
for (int i=0; i < 32; i += 4) {
2443
const char *color = memcmp(hash1+i, hash2+i, 4) ? CL_WHT : CL_GRY;
2444
len += sprintf(s+len, "%s%02x%02x%02x%02x " CL_GRY, color,
2445
hash1[i], hash1[i+1], hash1[i+2], hash1[i+3]);
2446
s[len] = '\0';
2447
}
2448
applog(LOG_DEBUG, "%s", s);
2449
}
2450
2451
void applog_hash(void *hash)
2452
{
2453
char s[128] = {'\0'};
2454
applog(LOG_DEBUG, "%s", format_hash(s, (uchar*) hash));
2455
}
2456
2457
void applog_hex(void *data, int len)
2458
{
2459
char* hex = abin2hex((uchar*)data, len);
2460
applog(LOG_DEBUG, "%s", hex);
2461
free(hex);
2462
}
2463
2464
void applog_hash64(void *hash)
2465
{
2466
char s[128] = {'\0'};
2467
char t[128] = {'\0'};
2468
applog(LOG_DEBUG, "%s %s", format_hash(s, (uchar*)hash), format_hash(t, &((uchar*)hash)[32]));
2469
}
2470
2471
2472
#define printpfx(n,h) \
2473
printf("%s%11s%s: %s\n", CL_CYN, n, CL_N, format_hash(s, (uint8_t*) h))
2474
2475
void print_hash_tests(void)
2476
{
2477
uchar *scratchbuf = NULL;
2478
char hash[128], s[80];
2479
char buf[192] = { 0 };
2480
2481
scratchbuf = (uchar*) calloc(128, 1024);
2482
2483
printf(CL_WHT "CPU HASH ON EMPTY BUFFER RESULTS:" CL_N "\n\n");
2484
2485
memset(buf, 0, sizeof(buf));
2486
//buf[0] = 1; buf[64] = 2; // for endian tests
2487
2488
allium_hash(&hash[0], &buf[0]);
2489
printpfx("allium", hash);
2490
2491
axiomhash(&hash[0], &buf[0]);
2492
printpfx("axiom", hash);
2493
2494
bastionhash(&hash[0], &buf[0]);
2495
printpfx("bastion", hash);
2496
2497
blakehash(&hash[0], &buf[0]);
2498
printpfx("blake", hash);
2499
2500
blakecoinhash(&hash[0], &buf[0]);
2501
printpfx("blakecoin", hash);
2502
2503
blake2b_hash(&hash[0], &buf[0]);
2504
printpfx("blake2b", hash);
2505
2506
blake2s_hash(&hash[0], &buf[0]);
2507
printpfx("blake2s", hash);
2508
2509
bmwhash(&hash[0], &buf[0]);
2510
printpfx("bmw", hash);
2511
2512
c11hash(&hash[0], &buf[0]);
2513
printpfx("c11", hash);
2514
2515
cryptolight_hash(&hash[0], &buf[0]);
2516
printpfx("cryptolight", hash);
2517
2518
cryptonight_hash_v1(&hash[0], &buf[0]);
2519
printpfx("cryptonight", hash);
2520
2521
decred_hash(&hash[0], &buf[0]);
2522
printpfx("decred", hash);
2523
2524
droplp_hash(&hash[0], &buf[0]);
2525
printpfx("drop", hash);
2526
2527
freshhash(&hash[0], &buf[0], 80);
2528
printpfx("fresh", hash);
2529
2530
geekhash(&hash[0], &buf[0]);
2531
printpfx("geek", hash);
2532
2533
groestlhash(&hash[0], &buf[0]);
2534
printpfx("groestl", hash);
2535
2536
heavyhash((uint8_t*) &hash[0], (uint8_t*) &buf[0], 32);
2537
printpfx("heavy", hash);
2538
2539
keccakhash(&hash[0], &buf[0]);
2540
printpfx("keccak", hash);
2541
2542
jha_hash(&hash[0], &buf[0]);
2543
printpfx("jha", hash);
2544
2545
lbry_hash(&hash[0], &buf[0]);
2546
printpfx("lbry", hash);
2547
2548
luffahash(&hash[0], &buf[0]);
2549
printpfx("luffa", hash);
2550
2551
lyra2_hash(&hash[0], &buf[0]);
2552
printpfx("lyra2", hash);
2553
2554
lyra2rev2_hash(&hash[0], &buf[0]);
2555
printpfx("lyra2v2", hash);
2556
2557
lyra2v3_hash(&hash[0], &buf[0]);
2558
printpfx("lyra2v3", hash);
2559
2560
minotaurhash(&hash[0], &buf[0], false);
2561
printpfx("minotaur", hash);
2562
2563
minotaurhash(&hash[0], &buf[0], true);
2564
printpfx("minotaurx", hash);
2565
2566
cryptonight_hash(&hash[0], &buf[0]);
2567
printpfx("monero", hash);
2568
2569
myriadhash(&hash[0], &buf[0]);
2570
printpfx("myr-gr", hash);
2571
2572
neoscrypt((uchar*) &hash[0], (uchar*)&buf[0], 80000620);
2573
printpfx("neoscrypt", hash);
2574
2575
nist5hash(&hash[0], &buf[0]);
2576
printpfx("nist5", hash);
2577
2578
pentablakehash(&hash[0], &buf[0]);
2579
printpfx("pentablake", hash);
2580
2581
phi1612_hash(&hash[0], &buf[0]);
2582
printpfx("phi1612", hash);
2583
2584
phi2_hash(&hash[0], &buf[0]);
2585
printpfx("phi2", hash);
2586
2587
pluck_hash((uint32_t*)&hash[0], (uint32_t*)&buf[0], scratchbuf, 128);
2588
memset(&buf[0], 0, sizeof(buf));
2589
printpfx("pluck", hash);
2590
2591
init_quarkhash_contexts();
2592
quarkhash(&hash[0], &buf[0]);
2593
printpfx("quark", hash);
2594
2595
qubithash(&hash[0], &buf[0]);
2596
printpfx("qubit", hash);
2597
2598
rf256_hash(&hash[0], &buf[0], 80);
2599
printpfx("rainforest", hash);
2600
2601
scrypthash(&hash[0], &buf[0], 1024);
2602
printpfx("scrypt", hash);
2603
2604
scrypthash(&hash[0], &buf[0], 2048);
2605
printpfx("scrypt:2048", hash);
2606
2607
scryptjanehash(&hash[0], &buf[0], 9);
2608
printpfx("scrypt-jane", hash);
2609
2610
inkhash(&hash[0], &buf[0]);
2611
printpfx("shavite3", hash);
2612
2613
sha256d((uint8_t*) &hash[0], (uint8_t*)&buf[0], 64);
2614
printpfx("sha256d", hash);
2615
2616
blake2b_hash(&hash[0], &buf[0]);
2617
printpfx("sia", hash);
2618
2619
sibhash(&hash[0], &buf[0]);
2620
printpfx("sib", hash);
2621
2622
skeinhash(&hash[0], &buf[0]);
2623
printpfx("skein", hash);
2624
2625
skein2hash(&hash[0], &buf[0]);
2626
printpfx("skein2", hash);
2627
2628
sonoa_hash(&hash[0], &buf[0]);
2629
printpfx("sonoa", hash);
2630
2631
s3hash(&hash[0], &buf[0]);
2632
printpfx("s3", hash);
2633
2634
timetravel_hash(&hash[0], &buf[0]);
2635
printpfx("timetravel", hash);
2636
2637
bitcore_hash(&hash[0], &buf[0]);
2638
printpfx("bitcore", hash);
2639
2640
tribus_hash(&hash[0], &buf[0]);
2641
printpfx("tribus", hash);
2642
2643
veltor_hash(&hash[0], &buf[0]);
2644
printpfx("veltor", hash);
2645
2646
xevan_hash(&hash[0], &buf[0]);
2647
printpfx("xevan", hash);
2648
2649
x11evo_hash(&hash[0], &buf[0]);
2650
printpfx("x11evo", hash);
2651
2652
x11hash(&hash[0], &buf[0]);
2653
printpfx("x11", hash);
2654
2655
x12hash(&hash[0], &buf[0]);
2656
printpfx("x12", hash);
2657
2658
x13hash(&hash[0], &buf[0]);
2659
printpfx("x13", hash);
2660
2661
x14hash(&hash[0], &buf[0]);
2662
printpfx("x14", hash);
2663
2664
x15hash(&hash[0], &buf[0]);
2665
printpfx("x15", hash);
2666
2667
x16r_hash(&hash[0], &buf[0]);
2668
printpfx("x16r", hash);
2669
2670
x16s_hash(&hash[0], &buf[0]);
2671
printpfx("x16s", hash);
2672
2673
x17hash(&hash[0], &buf[0]);
2674
printpfx("x17", hash);
2675
2676
x20r_hash(&hash[0], &buf[0]);
2677
printpfx("x20r", hash);
2678
2679
//zr5hash(&hash[0], &buf[0]);
2680
zr5hash(&hash[0], (uint32_t*) &buf[0]);
2681
memset(buf, 0, sizeof(buf));
2682
printpfx("zr5", hash);
2683
2684
printf("\n");
2685
2686
free(scratchbuf);
2687
}
2688
2689
2690