Diff cpuminer for Koto Sapling
diff --git a/configure.ac b/configure.ac | |
index eb48278..32c2f1e 100644 | |
--- a/configure.ac | |
+++ b/configure.ac | |
@@ -1,4 +1,4 @@ | |
-AC_INIT([cpuminer], [2.5]) | |
+AC_INIT([cpuminer], [3.0]) | |
AC_PREREQ([2.59c]) | |
AC_CANONICAL_SYSTEM | |
diff --git a/cpu-miner.c b/cpu-miner.c | |
index b84fd0d..a1c4a87 100644 | |
--- a/cpu-miner.c | |
+++ b/cpu-miner.c | |
@@ -259,7 +259,7 @@ static struct option const options[] = { | |
}; | |
struct work { | |
- uint32_t data[32]; | |
+ uint32_t data[40]; | |
uint32_t target[8]; | |
int height; | |
@@ -269,6 +269,8 @@ struct work { | |
char *job_id; | |
size_t xnonce2_len; | |
unsigned char *xnonce2; | |
+ | |
+ bool sapling; | |
}; | |
static struct work g_work; | |
@@ -357,12 +359,14 @@ static bool gbt_work_decode(const json_t *val, struct work *work) | |
int tx_count, tx_size; | |
unsigned char txc_vi[9]; | |
unsigned char (*merkle_tree)[32] = NULL; | |
+ uint32_t final_sapling_hash[8]; | |
bool coinbase_append = false; | |
bool submit_coinbase = false; | |
bool version_force = false; | |
bool version_reduce = false; | |
json_t *tmp, *txa; | |
bool rc = false; | |
+ bool sapling = false; | |
tmp = json_object_get(val, "mutable"); | |
if (tmp && json_is_array(tmp)) { | |
@@ -395,7 +399,9 @@ static bool gbt_work_decode(const json_t *val, struct work *work) | |
goto out; | |
} | |
version = json_integer_value(tmp); | |
- if (version > 4) { | |
+ if (version == 5) { | |
+ sapling = true; | |
+ } else if (version > 4) { | |
if (version_reduce) { | |
version = 4; | |
} else if (!version_force) { | |
@@ -421,6 +427,13 @@ static bool gbt_work_decode(const json_t *val, struct work *work) | |
goto out; | |
} | |
+ if (sapling) { | |
+ if (unlikely(!jobj_binary(val, "finalsaplingroothash", final_sapling_hash, sizeof(final_sapling_hash)))) { | |
+ applog(LOG_ERR, "JSON invalid finalsaplingroothash"); | |
+ goto out; | |
+ } | |
+ } | |
+ | |
/* find count and size of transactions */ | |
txa = json_object_get(val, "transactions"); | |
if (!txa || !json_is_array(txa)) { | |
@@ -576,9 +589,20 @@ static bool gbt_work_decode(const json_t *val, struct work *work) | |
work->data[9 + i] = be32dec((uint32_t *)merkle_tree[0] + i); | |
work->data[17] = swab32(curtime); | |
work->data[18] = le32dec(&bits); | |
- memset(work->data + 19, 0x00, 52); | |
- work->data[20] = 0x80000000; | |
- work->data[31] = 0x00000280; | |
+ if (sapling) { | |
+ work->sapling = true; | |
+ memset(work->data + 28, 0x00, 48); | |
+ for (i = 0; i < 8; i++) | |
+ work->data[27 - i] = le32dec(final_sapling_hash + i); | |
+ work->data[19] = 0; | |
+ work->data[28] = 0x80000000; | |
+ work->data[39] = 0x00000280; | |
+ } else { | |
+ work->sapling = false; | |
+ memset(work->data + 19, 0x00, 52); | |
+ work->data[20] = 0x80000000; | |
+ work->data[31] = 0x00000280; | |
+ } | |
if (unlikely(!jobj_binary(val, "target", target, sizeof(target)))) { | |
applog(LOG_ERR, "JSON invalid target"); | |
@@ -692,23 +716,27 @@ static bool submit_upstream_work(CURL *curl, struct work *work) | |
} | |
} else if (work->txs) { | |
char *req; | |
+ int datasize = 80; | |
+ if (work->sapling) { | |
+ datasize = 112; | |
+ } | |
for (i = 0; i < ARRAY_SIZE(work->data); i++) | |
be32enc(work->data + i, work->data[i]); | |
- bin2hex(data_str, (unsigned char *)work->data, 80); | |
+ bin2hex(data_str, (unsigned char *)work->data, datasize); | |
if (work->workid) { | |
char *params; | |
val = json_object(); | |
json_object_set_new(val, "workid", json_string(work->workid)); | |
params = json_dumps(val, 0); | |
json_decref(val); | |
- req = malloc(128 + 2*80 + strlen(work->txs) + strlen(params)); | |
+ req = malloc(128 + 2*datasize + strlen(work->txs) + strlen(params)); | |
sprintf(req, | |
"{\"method\": \"submitblock\", \"params\": [\"%s%s\", %s], \"id\":1}\r\n", | |
data_str, work->txs, params); | |
free(params); | |
} else { | |
- req = malloc(128 + 2*80 + strlen(work->txs)); | |
+ req = malloc(128 + 2*datasize + strlen(work->txs)); | |
sprintf(req, | |
"{\"method\": \"submitblock\", \"params\": [\"%s%s\"], \"id\":1}\r\n", | |
data_str, work->txs); | |
@@ -959,9 +987,9 @@ static bool get_work(struct thr_info *thr, struct work *work) | |
if (opt_benchmark) { | |
memset(work->data, 0x55, 76); | |
work->data[17] = swab32(time(NULL)); | |
- memset(work->data + 19, 0x00, 52); | |
- work->data[20] = 0x80000000; | |
- work->data[31] = 0x00000280; | |
+ memset(work->data + 27, 0x00, 52); | |
+ work->data[28] = 0x80000000; | |
+ work->data[39] = 0x00000280; | |
memset(work->target, 0x00, sizeof(work->target)); | |
return true; | |
} | |
@@ -1044,7 +1072,8 @@ static void stratum_gen_work(struct stratum_ctx *sctx, struct work *work) | |
for (i = 0; i < sctx->xnonce2_size && !++sctx->job.xnonce2[i]; i++); | |
/* Assemble block header */ | |
- memset(work->data, 0, 128); | |
+ memset(work->data, 0, 160); | |
+ work->sapling = be32dec(sctx->job.version) == 5 ? true : false; | |
work->data[0] = le32dec(sctx->job.version); | |
for (i = 0; i < 8; i++) | |
work->data[1 + i] = le32dec((uint32_t *)sctx->job.prevhash + i); | |
@@ -1052,8 +1081,15 @@ static void stratum_gen_work(struct stratum_ctx *sctx, struct work *work) | |
work->data[9 + i] = be32dec((uint32_t *)merkle_root + i); | |
work->data[17] = le32dec(sctx->job.ntime); | |
work->data[18] = le32dec(sctx->job.nbits); | |
- work->data[20] = 0x80000000; | |
- work->data[31] = 0x00000280; | |
+ if (work->sapling) { | |
+ for (i = 0; i < 8; i++) | |
+ work->data[20 + i] = le32dec((uint32_t *)sctx->job.finalsaplinghash + i); | |
+ work->data[28] = 0x80000000; | |
+ work->data[39] = 0x00000280; | |
+ } else { | |
+ work->data[20] = 0x80000000; | |
+ work->data[31] = 0x00000280; | |
+ } | |
pthread_mutex_unlock(&sctx->work_lock); | |
@@ -1103,6 +1139,7 @@ static void *miner_thread(void *userdata) | |
unsigned long hashes_done; | |
struct timeval tv_start, tv_end, diff; | |
int64_t max64; | |
+ int perslen = 80; | |
int rc; | |
if (have_stratum) { | |
@@ -1164,14 +1201,16 @@ static void *miner_thread(void *userdata) | |
gettimeofday(&tv_start, NULL); | |
/* scan nonces for a proof-of-work hash */ | |
+ if (work.sapling) | |
+ perslen = 112; | |
switch (opt_algo) { | |
case ALGO_YESCRYPT: | |
rc = scanhash_yescrypt(thr_id, work.data, work.target, | |
- max_nonce, &hashes_done); | |
+ max_nonce, &hashes_done, perslen); | |
break; | |
case ALGO_YESPOWER: | |
rc = scanhash_yespower(thr_id, work.data, work.target, | |
- max_nonce, &hashes_done); | |
+ max_nonce, &hashes_done, perslen); | |
break; | |
default: | |
/* should never happen */ | |
diff --git a/miner.h b/miner.h | |
index 440bc9a..3d867bc 100644 | |
--- a/miner.h | |
+++ b/miner.h | |
@@ -155,10 +155,10 @@ extern int scanhash_sha256d(int thr_id, uint32_t *pdata, | |
const uint32_t *ptarget, uint32_t max_nonce, unsigned long *hashes_done); | |
extern int scanhash_yescrypt(int thr_id, uint32_t *pdata, | |
- const uint32_t *ptarget, uint32_t max_nonce, unsigned long *hashes_done); | |
+ const uint32_t *ptarget, uint32_t max_nonce, unsigned long *hashes_done, int perslen); | |
extern int scanhash_yespower(int thr_id, uint32_t *pdata, | |
- const uint32_t *ptarget, uint32_t max_nonce, unsigned long *hashes_done); | |
+ const uint32_t *ptarget, uint32_t max_nonce, unsigned long *hashes_done, int perslen); | |
extern unsigned char *scrypt_buffer_alloc(int N); | |
extern int scanhash_scrypt(int thr_id, uint32_t *pdata, | |
@@ -216,6 +216,7 @@ extern void diff_to_target(uint32_t *target, double diff); | |
struct stratum_job { | |
char *job_id; | |
unsigned char prevhash[32]; | |
+ unsigned char finalsaplinghash[32]; | |
size_t coinbase_size; | |
unsigned char *coinbase; | |
unsigned char *xnonce2; | |
diff --git a/util.c b/util.c | |
index 32a79e6..24e31c4 100644 | |
--- a/util.c | |
+++ b/util.c | |
@@ -1175,12 +1175,13 @@ out: | |
static bool stratum_notify(struct stratum_ctx *sctx, json_t *params) | |
{ | |
- const char *job_id, *prevhash, *coinb1, *coinb2, *version, *nbits, *ntime; | |
+ const char *job_id, *prevhash, *coinb1, *coinb2, *version, *nbits, *ntime, *finalsaplinghash; | |
size_t coinb1_size, coinb2_size; | |
bool clean, ret = false; | |
int merkle_count, i; | |
json_t *merkle_arr; | |
unsigned char **merkle; | |
+ int ver; | |
job_id = json_string_value(json_array_get(params, 0)); | |
prevhash = json_string_value(json_array_get(params, 1)); | |
@@ -1201,6 +1202,15 @@ static bool stratum_notify(struct stratum_ctx *sctx, json_t *params) | |
applog(LOG_ERR, "Stratum notify: invalid parameters"); | |
goto out; | |
} | |
+ hex2bin(sctx->job.version, version, 4); | |
+ ver = be32dec(sctx->job.version); | |
+ if (ver == 5) { | |
+ finalsaplinghash = json_string_value(json_array_get(params, 9)); | |
+ if (!finalsaplinghash || strlen(finalsaplinghash) != 64) { | |
+ applog(LOG_ERR, "Stratum notify: invalid parameters"); | |
+ goto out; | |
+ } | |
+ } | |
merkle = malloc(merkle_count * sizeof(char *)); | |
for (i = 0; i < merkle_count; i++) { | |
const char *s = json_string_value(json_array_get(merkle_arr, i)); | |
@@ -1232,6 +1242,9 @@ static bool stratum_notify(struct stratum_ctx *sctx, json_t *params) | |
free(sctx->job.job_id); | |
sctx->job.job_id = strdup(job_id); | |
hex2bin(sctx->job.prevhash, prevhash, 32); | |
+ if (ver == 5) { | |
+ hex2bin(sctx->job.finalsaplinghash, finalsaplinghash, 32); | |
+ } | |
for (i = 0; i < sctx->job.merkle_count; i++) | |
free(sctx->job.merkle[i]); | |
@@ -1239,7 +1252,6 @@ static bool stratum_notify(struct stratum_ctx *sctx, json_t *params) | |
sctx->job.merkle = merkle; | |
sctx->job.merkle_count = merkle_count; | |
- hex2bin(sctx->job.version, version, 4); | |
hex2bin(sctx->job.nbits, nbits, 4); | |
hex2bin(sctx->job.ntime, ntime, 4); | |
sctx->job.clean = clean; | |
diff --git a/winbuild-cross.sh b/winbuild-cross.sh | |
index fac9c76..33257eb 100755 | |
--- a/winbuild-cross.sh | |
+++ b/winbuild-cross.sh | |
@@ -19,6 +19,7 @@ CFLAGS="-Wall -O3 -fomit-frame-pointer" | |
mkdir release | |
cp README.txt release/ | |
#cp /usr/i686-w64-mingw32/lib/libwinpthread-1.dll release/ | |
+#cp /usr/lib/gcc/i686-w64-mingw32/5.3-win32/libgcc_s_sjlj-1.dll release/ | |
cp /usr/x86_64-w64-mingw32/lib/libwinpthread-1.dll release/ | |
cp curl/lib/.libs/libcurl-4.dll release/ | |
diff --git a/yescrypt.c b/yescrypt.c | |
index 35e3277..19392f9 100644 | |
--- a/yescrypt.c | |
+++ b/yescrypt.c | |
@@ -12,7 +12,7 @@ | |
#include "sha256_Y.c" | |
int scanhash_yescrypt(int thr_id, uint32_t *pdata, const uint32_t *ptarget, | |
- uint32_t max_nonce, unsigned long *hashes_done) | |
+ uint32_t max_nonce, unsigned long *hashes_done, int perslen) | |
{ | |
uint32_t n = pdata[19] - 1; | |
const uint32_t first_nonce = pdata[19]; | |
@@ -38,7 +38,7 @@ int scanhash_yescrypt(int thr_id, uint32_t *pdata, const uint32_t *ptarget, | |
if (opt_debug) { | |
bin2hex(hash_str, (unsigned char *)hash64, 32); | |
bin2hex(target_str, (unsigned char *)ptarget, 32); | |
- bin2hex(data_str, (unsigned char *)endiandata, 80); | |
+ bin2hex(data_str, (unsigned char *)endiandata, perslen); | |
applog(LOG_DEBUG, "DEBUG: [%d thread] Found share!\ndata %s\nhash %s\ntarget %s", thr_id, | |
data_str, | |
hash_str, | |
diff --git a/yespower.c b/yespower.c | |
index f0f06f4..b4fd427 100644 | |
--- a/yespower.c | |
+++ b/yespower.c | |
@@ -28,7 +28,7 @@ | |
#include "yespower.h" | |
int scanhash_yespower(int thr_id, uint32_t *pdata, const uint32_t *ptarget, | |
- uint32_t max_nonce, unsigned long *hashes_done) | |
+ uint32_t max_nonce, unsigned long *hashes_done, int perslen) | |
{ | |
uint32_t n = pdata[19] - 1; | |
const uint32_t first_nonce = pdata[19]; | |
@@ -40,7 +40,7 @@ int scanhash_yespower(int thr_id, uint32_t *pdata, const uint32_t *ptarget, | |
.N = 2048, | |
.r = 8, | |
.pers = (const uint8_t *)endiandata, | |
- .perslen = 80 | |
+ .perslen = perslen | |
}; | |
//we need bigendian data... | |
int kk=0; | |
@@ -52,7 +52,7 @@ int scanhash_yespower(int thr_id, uint32_t *pdata, const uint32_t *ptarget, | |
do { | |
pdata[19] = ++n; | |
be32enc(&endiandata[19], n); | |
- if (yespower_tls((unsigned char *)endiandata, 80, ¶ms, (yespower_binary_t *)hash64)) { | |
+ if (yespower_tls((unsigned char *)endiandata, perslen, ¶ms, (yespower_binary_t *)hash64)) { | |
puts("FAILED"); | |
return -1; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment