made local mining work with segwit, restored scrypt stuff
This commit is contained in:
parent
a4bb8de94a
commit
897f30df0f
2 changed files with 156 additions and 43 deletions
4
.gitignore
vendored
4
.gitignore
vendored
|
@ -26,3 +26,7 @@ config.sub
|
||||||
|
|
||||||
mingw32-config.cache
|
mingw32-config.cache
|
||||||
|
|
||||||
|
|
||||||
|
.idea/
|
||||||
|
|
||||||
|
compile_commands.json
|
||||||
|
|
167
cpu-miner.c
167
cpu-miner.c
|
@ -102,10 +102,14 @@ struct workio_cmd {
|
||||||
|
|
||||||
enum algos {
|
enum algos {
|
||||||
ALGO_LBRY, /* lbry */
|
ALGO_LBRY, /* lbry */
|
||||||
|
ALGO_SCRYPT, /* scrypt(1024,1,1) */
|
||||||
|
ALGO_SHA256D, /* SHA-256d */
|
||||||
};
|
};
|
||||||
|
|
||||||
static const char *algo_names[] = {
|
static const char *algo_names[] = {
|
||||||
[ALGO_LBRY] = "lbry",
|
[ALGO_LBRY] = "lbry",
|
||||||
|
[ALGO_SCRYPT] = "scrypt",
|
||||||
|
[ALGO_SHA256D] = "sha256d",
|
||||||
};
|
};
|
||||||
|
|
||||||
bool opt_debug = false;
|
bool opt_debug = false;
|
||||||
|
@ -118,6 +122,7 @@ bool have_gbt = true;
|
||||||
bool allow_getwork = false;
|
bool allow_getwork = false;
|
||||||
bool want_stratum = false;
|
bool want_stratum = false;
|
||||||
bool have_stratum = false;
|
bool have_stratum = false;
|
||||||
|
bool want_segwit = false;
|
||||||
bool use_syslog = false;
|
bool use_syslog = false;
|
||||||
static bool opt_background = false;
|
static bool opt_background = false;
|
||||||
static bool opt_quiet = false;
|
static bool opt_quiet = false;
|
||||||
|
@ -168,7 +173,7 @@ Usage: " PROGRAM_NAME " [OPTIONS]\n\
|
||||||
Options:\n\
|
Options:\n\
|
||||||
-a, --algo=ALGO specify the algorithm to use\n\
|
-a, --algo=ALGO specify the algorithm to use\n\
|
||||||
lbry (default)\n\
|
lbry (default)\n\
|
||||||
scrypt scrypt(1024, 1, 1) (default)\n\
|
scrypt scrypt(1024, 1, 1)\n\
|
||||||
scrypt:N scrypt(N, 1, 1)\n\
|
scrypt:N scrypt(N, 1, 1)\n\
|
||||||
sha256d SHA-256d\n\
|
sha256d SHA-256d\n\
|
||||||
-o, --url=URL URL of mining server\n\
|
-o, --url=URL URL of mining server\n\
|
||||||
|
@ -187,11 +192,14 @@ Options:\n\
|
||||||
--coinbase-addr=ADDR payout address for solo mining\n\
|
--coinbase-addr=ADDR payout address for solo mining\n\
|
||||||
--coinbase-sig=TEXT data to insert in the coinbase when possible\n\
|
--coinbase-sig=TEXT data to insert in the coinbase when possible\n\
|
||||||
--no-longpoll disable long polling support\n\
|
--no-longpoll disable long polling support\n\
|
||||||
|
--getwork enable getwork support\n\
|
||||||
--no-gbt disable getblocktemplate support\n\
|
--no-gbt disable getblocktemplate support\n\
|
||||||
|
--stratum enable X-Stratum support\n\
|
||||||
--no-redirect ignore requests to change the URL of the mining server\n\
|
--no-redirect ignore requests to change the URL of the mining server\n\
|
||||||
-q, --quiet disable per-thread hashmeter output\n\
|
-q, --quiet disable per-thread hashmeter output\n\
|
||||||
-D, --debug enable debug output\n\
|
-D, --debug enable debug output\n\
|
||||||
-P, --protocol-dump verbose dump of protocol-level activities\n"
|
-P, --protocol-dump verbose dump of protocol-level activities\n\
|
||||||
|
--segwit include Segwit transactions in the mined data\n"
|
||||||
#ifdef HAVE_SYSLOG_H
|
#ifdef HAVE_SYSLOG_H
|
||||||
"\
|
"\
|
||||||
-S, --syslog use system log for output messages\n"
|
-S, --syslog use system log for output messages\n"
|
||||||
|
@ -229,8 +237,10 @@ static struct option const options[] = {
|
||||||
{ "debug", 0, NULL, 'D' },
|
{ "debug", 0, NULL, 'D' },
|
||||||
{ "help", 0, NULL, 'h' },
|
{ "help", 0, NULL, 'h' },
|
||||||
{ "no-gbt", 0, NULL, 1011 },
|
{ "no-gbt", 0, NULL, 1011 },
|
||||||
|
{ "getwork", 0, NULL, 1010 },
|
||||||
{ "no-longpoll", 0, NULL, 1003 },
|
{ "no-longpoll", 0, NULL, 1003 },
|
||||||
{ "no-redirect", 0, NULL, 1009 },
|
{ "no-redirect", 0, NULL, 1009 },
|
||||||
|
{ "stratum", 0, NULL, 1007 },
|
||||||
{ "pass", 1, NULL, 'p' },
|
{ "pass", 1, NULL, 'p' },
|
||||||
{ "protocol-dump", 0, NULL, 'P' },
|
{ "protocol-dump", 0, NULL, 'P' },
|
||||||
{ "proxy", 1, NULL, 'x' },
|
{ "proxy", 1, NULL, 'x' },
|
||||||
|
@ -238,6 +248,7 @@ static struct option const options[] = {
|
||||||
{ "retries", 1, NULL, 'r' },
|
{ "retries", 1, NULL, 'r' },
|
||||||
{ "retry-pause", 1, NULL, 'R' },
|
{ "retry-pause", 1, NULL, 'R' },
|
||||||
{ "scantime", 1, NULL, 's' },
|
{ "scantime", 1, NULL, 's' },
|
||||||
|
{ "segwit", 0, NULL, 1016 },
|
||||||
#ifdef HAVE_SYSLOG_H
|
#ifdef HAVE_SYSLOG_H
|
||||||
{ "syslog", 0, NULL, 'S' },
|
{ "syslog", 0, NULL, 'S' },
|
||||||
#endif
|
#endif
|
||||||
|
@ -314,6 +325,30 @@ static bool jobj_binary(const json_t *obj, const char *key,
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static bool work_decode(const json_t *val, struct work *work)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
|
||||||
|
if (unlikely(!jobj_binary(val, "data", work->data, sizeof(work->data)))) {
|
||||||
|
applog(LOG_ERR, "JSON invalid data");
|
||||||
|
goto err_out;
|
||||||
|
}
|
||||||
|
if (unlikely(!jobj_binary(val, "target", work->target, sizeof(work->target)))) {
|
||||||
|
applog(LOG_ERR, "JSON invalid target");
|
||||||
|
goto err_out;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (i = 0; i < ARRAY_SIZE(work->data); i++)
|
||||||
|
work->data[i] = le32dec(work->data + i);
|
||||||
|
for (i = 0; i < ARRAY_SIZE(work->target); i++)
|
||||||
|
work->target[i] = le32dec(work->target + i);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
|
||||||
|
err_out:
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
static bool gbt_work_decode(const json_t *val, struct work *work)
|
static bool gbt_work_decode(const json_t *val, struct work *work)
|
||||||
{
|
{
|
||||||
int i, n;
|
int i, n;
|
||||||
|
@ -322,7 +357,7 @@ static bool gbt_work_decode(const json_t *val, struct work *work)
|
||||||
uint32_t target[8];
|
uint32_t target[8];
|
||||||
uint32_t claimtrie[8];
|
uint32_t claimtrie[8];
|
||||||
int cbtx_size;
|
int cbtx_size;
|
||||||
unsigned char *cbtx = NULL;
|
unsigned char *cbtx = NULL, *cbtx_txid = NULL;
|
||||||
unsigned char *tx = NULL;
|
unsigned char *tx = NULL;
|
||||||
int tx_count, tx_size;
|
int tx_count, tx_size;
|
||||||
unsigned char txc_vi[9];
|
unsigned char txc_vi[9];
|
||||||
|
@ -373,7 +408,7 @@ static bool gbt_work_decode(const json_t *val, struct work *work)
|
||||||
}
|
}
|
||||||
version = json_integer_value(tmp);
|
version = json_integer_value(tmp);
|
||||||
|
|
||||||
if (unlikely(!jobj_binary(val, "claimtrie", claimtrie, sizeof(claimtrie)))) {
|
if (opt_algo == ALGO_LBRY && unlikely(!jobj_binary(val, "claimtrie", claimtrie, sizeof(claimtrie)))) {
|
||||||
applog(LOG_ERR, "JSON invalid claimtrie");
|
applog(LOG_ERR, "JSON invalid claimtrie");
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
@ -424,6 +459,23 @@ static bool gbt_work_decode(const json_t *val, struct work *work)
|
||||||
applog(LOG_ERR, "JSON invalid coinbasetxn");
|
applog(LOG_ERR, "JSON invalid coinbasetxn");
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
bool hasWitness = *(uint16_t*)(cbtx + 4) == 256;
|
||||||
|
if (hasWitness && coinbase_append) {
|
||||||
|
// TODO: make this work by using index 43 instead of 41 in the coinbase_append handler below
|
||||||
|
// and then would we pass it in as one of our supported capabilities? Sure.
|
||||||
|
applog(LOG_ERR, "This tool cannot append onto segwit transactions");
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
if (hasWitness) {
|
||||||
|
cbtx_hex = json_string_value(json_object_get(tmp, "txid"));
|
||||||
|
size_t txid_size = strlen(cbtx_hex) / 2;
|
||||||
|
cbtx_txid = malloc(txid_size + 1);
|
||||||
|
if (txid_size != 32 || !hex2bin(cbtx_txid, cbtx_hex, txid_size)) {
|
||||||
|
applog(LOG_ERR, "Invalid txid on coinbase");
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
memrev(cbtx_txid, 32);
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
int64_t cbvalue;
|
int64_t cbvalue;
|
||||||
if (!pk_script_size) {
|
if (!pk_script_size) {
|
||||||
|
@ -563,6 +615,9 @@ static bool gbt_work_decode(const json_t *val, struct work *work)
|
||||||
merkle_tree = malloc(32 * ((1 + tx_count + 1) & ~1));
|
merkle_tree = malloc(32 * ((1 + tx_count + 1) & ~1));
|
||||||
size_t tx_buf_size = 32 * 1024;
|
size_t tx_buf_size = 32 * 1024;
|
||||||
tx = malloc(tx_buf_size);
|
tx = malloc(tx_buf_size);
|
||||||
|
if (cbtx_txid)
|
||||||
|
memcpy(merkle_tree[0], cbtx_txid, 32);
|
||||||
|
else
|
||||||
sha256d(merkle_tree[0], cbtx, cbtx_size);
|
sha256d(merkle_tree[0], cbtx, cbtx_size);
|
||||||
for (i = 0; i < tx_count; i++) {
|
for (i = 0; i < tx_count; i++) {
|
||||||
tmp = json_array_get(txa, i);
|
tmp = json_array_get(txa, i);
|
||||||
|
@ -606,18 +661,22 @@ static bool gbt_work_decode(const json_t *val, struct work *work)
|
||||||
}
|
}
|
||||||
|
|
||||||
/* assemble block header */
|
/* assemble block header */
|
||||||
memset(work->data, 0x00, sizeof(work->data));
|
|
||||||
work->data[0] = swab32(version);
|
work->data[0] = swab32(version);
|
||||||
for (i = 0; i < 8; i++)
|
for (i = 0; i < 8; i++)
|
||||||
work->data[8 - i] = le32dec(prevhash + i);
|
work->data[8 - i] = le32dec(prevhash + i);
|
||||||
for (i = 0; i < 8; i++)
|
for (i = 0; i < 8; i++)
|
||||||
work->data[9 + i] = be32dec((uint32_t *)merkle_tree[0] + i);
|
work->data[9 + i] = be32dec((uint32_t *)merkle_tree[0] + i);
|
||||||
|
int offset = 0;
|
||||||
|
if (opt_algo == ALGO_LBRY) {
|
||||||
for (i = 0; i < 8; i++)
|
for (i = 0; i < 8; i++)
|
||||||
work->data[24 - i] = le32dec(claimtrie + i);
|
work->data[24 - i] = le32dec(claimtrie + i);
|
||||||
work->data[25] = swab32(curtime);
|
offset = 8;
|
||||||
work->data[26] = le32dec(&bits);
|
}
|
||||||
work->data[28] = 0x80000000;
|
work->data[17 + offset] = swab32(curtime);
|
||||||
work->data[39] = 0x00000280;
|
work->data[18 + offset] = le32dec(&bits);
|
||||||
|
memset(work->data + 19 + offset, 0x00, 52);
|
||||||
|
work->data[20 + offset] = 0x80000000;
|
||||||
|
work->data[31 + offset] = 0x00000280;
|
||||||
|
|
||||||
if (unlikely(!jobj_binary(val, "target", target, sizeof(target)))) {
|
if (unlikely(!jobj_binary(val, "target", target, sizeof(target)))) {
|
||||||
applog(LOG_ERR, "JSON invalid target");
|
applog(LOG_ERR, "JSON invalid target");
|
||||||
|
@ -654,13 +713,14 @@ static bool gbt_work_decode(const json_t *val, struct work *work)
|
||||||
out:
|
out:
|
||||||
free(tx);
|
free(tx);
|
||||||
free(cbtx);
|
free(cbtx);
|
||||||
|
free(cbtx_txid);
|
||||||
free(merkle_tree);
|
free(merkle_tree);
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void share_result(int result, const char *reason)
|
static void share_result(int result, const char *reason)
|
||||||
{
|
{
|
||||||
char s[345];
|
char s[370];
|
||||||
double hashrate;
|
double hashrate;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
|
@ -687,7 +747,7 @@ static bool submit_upstream_work(CURL *curl, struct work *work)
|
||||||
{
|
{
|
||||||
json_t *val, *res, *reason;
|
json_t *val, *res, *reason;
|
||||||
char data_str[2 * sizeof(work->data) + 1];
|
char data_str[2 * sizeof(work->data) + 1];
|
||||||
char s[345];
|
char s[370];
|
||||||
int i;
|
int i;
|
||||||
bool rc = false;
|
bool rc = false;
|
||||||
|
|
||||||
|
@ -724,20 +784,21 @@ static bool submit_upstream_work(CURL *curl, struct work *work)
|
||||||
|
|
||||||
for (i = 0; i < ARRAY_SIZE(work->data); i++)
|
for (i = 0; i < ARRAY_SIZE(work->data); i++)
|
||||||
be32enc(work->data + i, work->data[i]);
|
be32enc(work->data + i, work->data[i]);
|
||||||
bin2hex(data_str, (unsigned char *)work->data, 112);
|
int offset = opt_algo == ALGO_LBRY ? 112 : 80;
|
||||||
|
bin2hex(data_str, (unsigned char *)work->data, offset);
|
||||||
if (work->workid) {
|
if (work->workid) {
|
||||||
char *params;
|
char *params;
|
||||||
val = json_object();
|
val = json_object();
|
||||||
json_object_set_new(val, "workid", json_string(work->workid));
|
json_object_set_new(val, "workid", json_string(work->workid));
|
||||||
params = json_dumps(val, 0);
|
params = json_dumps(val, 0);
|
||||||
json_decref(val);
|
json_decref(val);
|
||||||
req = malloc(160 + 2*112 + strlen(work->txs) + strlen(params));
|
req = malloc(160 + 2*offset + strlen(work->txs) + strlen(params));
|
||||||
sprintf(req,
|
sprintf(req,
|
||||||
"{\"method\": \"submitblock\", \"params\": [\"%s%s\", %s], \"id\":1}\r\n",
|
"{\"method\": \"submitblock\", \"params\": [\"%s%s\", %s], \"id\":1}\r\n",
|
||||||
data_str, work->txs, params);
|
data_str, work->txs, params);
|
||||||
free(params);
|
free(params);
|
||||||
} else {
|
} else {
|
||||||
req = malloc(160 + 2*112 + strlen(work->txs));
|
req = malloc(160 + 2*offset + strlen(work->txs));
|
||||||
sprintf(req,
|
sprintf(req,
|
||||||
"{\"method\": \"submitblock\", \"params\": [\"%s%s\"], \"id\":1}\r\n",
|
"{\"method\": \"submitblock\", \"params\": [\"%s%s\"], \"id\":1}\r\n",
|
||||||
data_str, work->txs);
|
data_str, work->txs);
|
||||||
|
@ -803,14 +864,15 @@ static const char *getwork_req =
|
||||||
"{\"method\": \"getwork\", \"params\": [], \"id\":0}\r\n";
|
"{\"method\": \"getwork\", \"params\": [], \"id\":0}\r\n";
|
||||||
|
|
||||||
#define GBT_CAPABILITIES "[\"coinbasetxn\", \"coinbasevalue\", \"longpoll\", \"workid\"]"
|
#define GBT_CAPABILITIES "[\"coinbasetxn\", \"coinbasevalue\", \"longpoll\", \"workid\"]"
|
||||||
|
#define GBT_RULES "[\"segwit\"]"
|
||||||
|
#define GBT_NO_RULES "[]"
|
||||||
|
|
||||||
static const char *gbt_req =
|
static const char *gbt_req =
|
||||||
"{\"method\": \"getblocktemplate\", \"params\": [{\"capabilities\": "
|
"{\"method\": \"getblocktemplate\", \"params\": [{\"capabilities\": "
|
||||||
GBT_CAPABILITIES "}], \"id\":0}\r\n";
|
GBT_CAPABILITIES ", \"rules\": " GBT_NO_RULES "}], \"id\":0}\r\n";
|
||||||
|
|
||||||
static const char *gbt_lp_req =
|
static const char *gbt_lp_req =
|
||||||
"{\"method\": \"getblocktemplate\", \"params\": [{\"capabilities\": "
|
"{\"method\": \"getblocktemplate\", \"params\": [{\"capabilities\": "
|
||||||
GBT_CAPABILITIES "}], \"id\":0}\r\n";
|
GBT_CAPABILITIES ", \"rules\": %s, \"longpollid\": \"%s\"}], \"id\":0}\r\n";
|
||||||
|
|
||||||
static bool get_upstream_work(CURL *curl, struct work *work)
|
static bool get_upstream_work(CURL *curl, struct work *work)
|
||||||
{
|
{
|
||||||
|
@ -848,11 +910,14 @@ start:
|
||||||
if (!val)
|
if (!val)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
|
if (have_gbt) {
|
||||||
rc = gbt_work_decode(json_object_get(val, "result"), work);
|
rc = gbt_work_decode(json_object_get(val, "result"), work);
|
||||||
if (!rc) {
|
if (!have_gbt) {
|
||||||
json_decref(val);
|
json_decref(val);
|
||||||
goto start;
|
goto start;
|
||||||
}
|
}
|
||||||
|
} else
|
||||||
|
rc = work_decode(json_object_get(val, "result"), work);
|
||||||
|
|
||||||
if (opt_debug && rc) {
|
if (opt_debug && rc) {
|
||||||
timeval_subtract(&diff, &tv_end, &tv_start);
|
timeval_subtract(&diff, &tv_end, &tv_start);
|
||||||
|
@ -1091,9 +1156,15 @@ static void stratum_gen_work(struct stratum_ctx *sctx, struct work *work)
|
||||||
free(xnonce2str);
|
free(xnonce2str);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (opt_algo == ALGO_SCRYPT)
|
||||||
|
diff_to_target(work->target, sctx->job.diff / 65536.0);
|
||||||
|
else
|
||||||
diff_to_target(work->target, sctx->job.diff);
|
diff_to_target(work->target, sctx->job.diff);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
extern int scanhash_lbry(int thr_id, uint32_t *pdata, const uint32_t *ptarget,
|
||||||
|
uint32_t max_nonce, uint64_t *hashes_done);
|
||||||
|
|
||||||
static void *miner_thread(void *userdata)
|
static void *miner_thread(void *userdata)
|
||||||
{
|
{
|
||||||
struct thr_info *mythr = userdata;
|
struct thr_info *mythr = userdata;
|
||||||
|
@ -1122,6 +1193,17 @@ static void *miner_thread(void *userdata)
|
||||||
affine_to_cpu(thr_id, thr_id % num_processors);
|
affine_to_cpu(thr_id, thr_id % num_processors);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (opt_algo == ALGO_SCRYPT) {
|
||||||
|
scratchbuf = scrypt_buffer_alloc(opt_scrypt_n);
|
||||||
|
if (!scratchbuf) {
|
||||||
|
applog(LOG_ERR, "scrypt buffer allocation failed");
|
||||||
|
pthread_mutex_lock(&applog_lock);
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int offset = opt_algo == ALGO_LBRY ? 8 : 0;
|
||||||
|
|
||||||
while (1) {
|
while (1) {
|
||||||
unsigned long hashes_done;
|
unsigned long hashes_done;
|
||||||
struct timeval tv_start, tv_end, diff;
|
struct timeval tv_start, tv_end, diff;
|
||||||
|
@ -1132,7 +1214,7 @@ static void *miner_thread(void *userdata)
|
||||||
while (time(NULL) >= g_work_time + 120)
|
while (time(NULL) >= g_work_time + 120)
|
||||||
sleep(1);
|
sleep(1);
|
||||||
pthread_mutex_lock(&g_work_lock);
|
pthread_mutex_lock(&g_work_lock);
|
||||||
if (work.data[19] >= end_nonce && !memcmp(work.data, g_work.data, 76))
|
if (work.data[19 + offset] >= end_nonce && !memcmp(work.data, g_work.data, 76 + offset * 4))
|
||||||
stratum_gen_work(&stratum, &g_work);
|
stratum_gen_work(&stratum, &g_work);
|
||||||
} else {
|
} else {
|
||||||
int min_scantime = have_longpoll ? LP_SCANTIME : opt_scantime;
|
int min_scantime = have_longpoll ? LP_SCANTIME : opt_scantime;
|
||||||
|
@ -1140,7 +1222,7 @@ static void *miner_thread(void *userdata)
|
||||||
pthread_mutex_lock(&g_work_lock);
|
pthread_mutex_lock(&g_work_lock);
|
||||||
if (!have_stratum &&
|
if (!have_stratum &&
|
||||||
(time(NULL) - g_work_time >= min_scantime ||
|
(time(NULL) - g_work_time >= min_scantime ||
|
||||||
work.data[27] >= end_nonce)) {
|
work.data[19 + offset] >= end_nonce)) {
|
||||||
work_free(&g_work);
|
work_free(&g_work);
|
||||||
if (unlikely(!get_work(mythr, &g_work))) {
|
if (unlikely(!get_work(mythr, &g_work))) {
|
||||||
applog(LOG_ERR, "work retrieval failed, exiting "
|
applog(LOG_ERR, "work retrieval failed, exiting "
|
||||||
|
@ -1155,13 +1237,12 @@ static void *miner_thread(void *userdata)
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
/* if (memcmp(work.data, g_work.data, 76)) { */
|
if (memcmp(work.data, g_work.data, 76 + offset * 4)) {
|
||||||
if (memcmp(work.data, g_work.data, 108)) {
|
|
||||||
work_free(&work);
|
work_free(&work);
|
||||||
work_copy(&work, &g_work);
|
work_copy(&work, &g_work);
|
||||||
work.data[27] = 0xffffffffU / opt_n_threads * thr_id;
|
work.data[19 + offset] = 0xffffffffU / opt_n_threads * thr_id;
|
||||||
} else
|
} else
|
||||||
work.data[27]++;
|
work.data[19 + offset]++;
|
||||||
pthread_mutex_unlock(&g_work_lock);
|
pthread_mutex_unlock(&g_work_lock);
|
||||||
work_restart[thr_id].restart = 0;
|
work_restart[thr_id].restart = 0;
|
||||||
|
|
||||||
|
@ -1177,6 +1258,12 @@ static void *miner_thread(void *userdata)
|
||||||
case ALGO_LBRY:
|
case ALGO_LBRY:
|
||||||
max64 = 0x1fffff;
|
max64 = 0x1fffff;
|
||||||
break;
|
break;
|
||||||
|
case ALGO_SCRYPT:
|
||||||
|
max64 = opt_scrypt_n < 16 ? 0x3ffff : 0x3fffff / opt_scrypt_n;
|
||||||
|
break;
|
||||||
|
case ALGO_SHA256D:
|
||||||
|
max64 = 0x1fffff;
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (work.data[19] + max64 > end_nonce)
|
if (work.data[19] + max64 > end_nonce)
|
||||||
|
@ -1193,7 +1280,15 @@ static void *miner_thread(void *userdata)
|
||||||
rc = scanhash_lbry(thr_id, work.data, work.target,
|
rc = scanhash_lbry(thr_id, work.data, work.target,
|
||||||
max_nonce, &hashes_done);
|
max_nonce, &hashes_done);
|
||||||
break;
|
break;
|
||||||
|
case ALGO_SCRYPT:
|
||||||
|
rc = scanhash_scrypt(thr_id, work.data, scratchbuf, work.target,
|
||||||
|
max_nonce, &hashes_done, opt_scrypt_n);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case ALGO_SHA256D:
|
||||||
|
rc = scanhash_sha256d(thr_id, work.data, work.target,
|
||||||
|
max_nonce, &hashes_done);
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
/* should never happen */
|
/* should never happen */
|
||||||
goto out;
|
goto out;
|
||||||
|
@ -1288,8 +1383,8 @@ start:
|
||||||
int err;
|
int err;
|
||||||
|
|
||||||
if (have_gbt) {
|
if (have_gbt) {
|
||||||
req = malloc(strlen(gbt_lp_req) + strlen(lp_id) + 1);
|
req = malloc(strlen(gbt_lp_req) + strlen(lp_id) + 1 + strlen(GBT_RULES));
|
||||||
sprintf(req, gbt_lp_req, lp_id);
|
sprintf(req, gbt_lp_req, want_segwit ? GBT_RULES : GBT_NO_RULES, lp_id);
|
||||||
}
|
}
|
||||||
val = json_rpc_call(curl, lp_url, rpc_userpass,
|
val = json_rpc_call(curl, lp_url, rpc_userpass,
|
||||||
req ? req : getwork_req, &err,
|
req ? req : getwork_req, &err,
|
||||||
|
@ -1302,13 +1397,15 @@ start:
|
||||||
}
|
}
|
||||||
if (likely(val)) {
|
if (likely(val)) {
|
||||||
bool rc;
|
bool rc;
|
||||||
//applog(LOG_INFO, "LONGPOLL pushed new work");
|
|
||||||
res = json_object_get(val, "result");
|
res = json_object_get(val, "result");
|
||||||
soval = json_object_get(res, "submitold");
|
soval = json_object_get(res, "submitold");
|
||||||
submit_old = soval ? json_is_true(soval) : false;
|
submit_old = soval ? json_is_true(soval) : false;
|
||||||
pthread_mutex_lock(&g_work_lock);
|
pthread_mutex_lock(&g_work_lock);
|
||||||
work_free(&g_work);
|
work_free(&g_work);
|
||||||
|
if (have_gbt)
|
||||||
rc = gbt_work_decode(res, &g_work);
|
rc = gbt_work_decode(res, &g_work);
|
||||||
|
else
|
||||||
|
rc = work_decode(res, &g_work);
|
||||||
if (rc) {
|
if (rc) {
|
||||||
time(&g_work_time);
|
time(&g_work_time);
|
||||||
restart_threads();
|
restart_threads();
|
||||||
|
@ -1521,6 +1618,15 @@ static void parse_arg(int key, char *arg, char *pname)
|
||||||
opt_algo = i;
|
opt_algo = i;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
if (arg[v] == ':' && i == ALGO_SCRYPT) {
|
||||||
|
char *ep;
|
||||||
|
v = strtol(arg+v+1, &ep, 10);
|
||||||
|
if (*ep || v & (v-1) || v < 2)
|
||||||
|
continue;
|
||||||
|
opt_algo = i;
|
||||||
|
opt_scrypt_n = v;
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (i == ARRAY_SIZE(algo_names)) {
|
if (i == ARRAY_SIZE(algo_names)) {
|
||||||
|
@ -1694,13 +1800,13 @@ static void parse_arg(int key, char *arg, char *pname)
|
||||||
want_longpoll = false;
|
want_longpoll = false;
|
||||||
break;
|
break;
|
||||||
case 1007:
|
case 1007:
|
||||||
want_stratum = false;
|
want_stratum = true;
|
||||||
break;
|
break;
|
||||||
case 1009:
|
case 1009:
|
||||||
opt_redirect = false;
|
opt_redirect = false;
|
||||||
break;
|
break;
|
||||||
case 1010:
|
case 1010:
|
||||||
allow_getwork = false;
|
allow_getwork = true;
|
||||||
break;
|
break;
|
||||||
case 1011:
|
case 1011:
|
||||||
have_gbt = false;
|
have_gbt = false;
|
||||||
|
@ -1720,6 +1826,9 @@ static void parse_arg(int key, char *arg, char *pname)
|
||||||
}
|
}
|
||||||
strcpy(coinbase_sig, arg);
|
strcpy(coinbase_sig, arg);
|
||||||
break;
|
break;
|
||||||
|
case 1016:
|
||||||
|
want_segwit = true;
|
||||||
|
break;
|
||||||
case 'S':
|
case 'S':
|
||||||
use_syslog = true;
|
use_syslog = true;
|
||||||
break;
|
break;
|
||||||
|
|
Loading…
Reference in a new issue