diff --git a/algorithm.c b/algorithm.c index 2cc8cbd7..6d762a5f 100644 --- a/algorithm.c +++ b/algorithm.c @@ -41,7 +41,6 @@ #include "algorithm/blakecoin.h" #include "algorithm/ethash.h" #include "algorithm/equihash.h" -#include "kernel/equihash-param.h" #include "compat.h" @@ -1084,21 +1083,6 @@ static cl_int queue_equihash_kernel(_clState *clState, dev_blk_ctx *blk, __maybe cl_int status = 0; size_t work_items = threads; size_t worksize = clState->wsize; - struct pool *pool = blk->work->pool; - - //do this for stratum only, don't want to mess with GBT implementation... - if (blk->work->getwork_mode == GETWORK_MODE_STRATUM) { - //get next nonce to check - cg_wlock(&pool->data_lock); - blk->work->nonce2 = pool->nonce2++; - cg_wunlock(&pool->data_lock); - - //set new nonce in equihash_data - *(uint64_t*)(blk->work->equihash_data+108+(strlen(blk->work->nonce1) / 2)) = blk->work->nonce2; -/* char *n = bin2hex(blk->work->equihash_data+108, 32); - applog(LOG_DEBUG, "[THR%d] nonce: %s", blk->work->thr->id, n); - free(n);*/ - } uint64_t mid_hash[8]; equihash_calc_mid_hash(mid_hash, blk->work->equihash_data); diff --git a/algorithm/equihash.c b/algorithm/equihash.c index bf339739..1f6a6b4b 100644 --- a/algorithm/equihash.c +++ b/algorithm/equihash.c @@ -135,24 +135,6 @@ void equihash_calc_hash(uint8_t hash[25], uint64_t mid_hash[8], uint32_t bday) { memcpy(hash, tmp + (bday & 1 ? 25 : 0), 25); } -void equihash_sort_indices(uint32_t* indices) { - for (int i = 0; i < 512; i++) - indices[i] = htobe32(indices[i]); - uint32_t tmp[256]; - for (int len = 1; len <= 256; len *= 2){ - for (int i = 0; i < 512; i += 2*len) { - bool is_before = (memcmp(indices + i, indices + i + len, 4*len) < 0); - if (is_before) - continue; - for (int j = i; j < i + len; j++) { - uint32_t tmp = indices[j + len]; - indices[j + len] = indices[j]; - indices[j] = tmp; - } - } - } -} - // These two copied from the ref impl, for now. void ExpandArray(const unsigned char* in, size_t in_len, @@ -231,71 +213,6 @@ void CompressArray(const unsigned char* in, size_t in_len, } -bool submit_tested_work(struct thr_info *, struct work *); -int equihash_check_solutions(struct work *work, uint32_t* indices, uint64_t *mid_hash) { - int count = 0; - uint8_t hash[10][512][25]; - uint32_t found_idx = work->pool->algorithm.found_idx; - /* - for (int i = 0; i < MIN(indices[found_idx], found_idx / 512); i++) { - for (int j = 0; j < 512; j++) { - equihash_calc_hash(hash[0][j], mid_hash, indices[512*i + j]); - } - for (int depth = 1; depth < 10; depth++) { - for (int j = 0; j < (1 << (9 - depth)); j++) { - for (int u = 0; u < 25; u++) - hash[depth][j][u] = hash[depth-1][2*j][u] ^ hash[depth-1][2*j+1][u]; - - int k = 0; - for (; k < (depth + (depth == 9 ? 1 : 0)) * 20 / 8; k++) - if (hash[depth][j][k] != 0) - goto out; - if ((depth * 20 % 8) && (hash[depth][j][k] & 0xf0)) - goto out; - } - } - count++; - equihash_sort_indices(indices + 512*i); - CompressArray((unsigned char*) (indices + 512*i), 512*4, work->equihash_data + 143, 1344, 21, 1); - gen_hash(work->equihash_data, 1344 + 143, work->hash); - if (*(uint64_t*) (work->hash + 24) < *(uint64_t*) (work->target + 24)) - submit_tested_work(work->thr, work); -out: - continue; - } - return count; */ - - for (int i = 0; i < MIN(indices[found_idx], found_idx / 512); i++) { - equihash_sort_indices(indices + 512*i); - CompressArray((unsigned char*) (indices + 512*i), 512*4, work->equihash_data + 143, 1344, 21, 1); - gen_hash(work->equihash_data, 1344 + 143, work->hash); - if (*(uint64_t*) (work->hash + 24) >= *(uint64_t*) (work->target + 24)) - continue; - for (int j = 0; j < 512; j++) { - equihash_calc_hash(hash[0][j], mid_hash, be32toh(indices[512*i + j])); - } - for (int depth = 1; depth < 10; depth++) { - for (int j = 0; j < (1 << (9 - depth)); j++) { - for (int u = 0; u < 25; u++) - hash[depth][j][u] = hash[depth-1][2*j][u] ^ hash[depth-1][2*j+1][u]; - - int k = 0; - for (; k < (depth + (depth == 9 ? 1 : 0)) * 20 / 8; k++) - if (hash[depth][j][k] != 0) - goto out; - if ((depth * 20 % 8) && (hash[depth][j][k] & 0xf0)) - goto out; - } - } - submit_tested_work(work->thr, work); -out: - continue; - } - return 1; -} - - - static inline void sort_pair(uint32_t *a, uint32_t len) { uint32_t *b = a + len; @@ -313,8 +230,9 @@ static inline void sort_pair(uint32_t *a, uint32_t len) } -#include "kernel/equihash-param.h" -uint32_t verify_sol(struct work *work, sols_t *sols, int sol_i) +bool submit_tested_work(struct thr_info *, struct work *); + +uint32_t equihash_verify_sol(struct work *work, sols_t *sols, int sol_i) { uint32_t thr_id = work->thr->id; uint32_t *inputs = sols->values[sol_i]; @@ -355,30 +273,8 @@ uint32_t verify_sol(struct work *work, sols_t *sols, int sol_i) gen_hash(work->equihash_data, 1344 + 143, work->hash); - if (work->getwork_mode == GETWORK_MODE_STRATUM) { - -/* char *eqdata = bin2hex(work->equihash_data, 1487); - applog(LOG_DEBUG, "[THR%d] %s: got solution... %s", thr_id, __func__, eqdata); - free(eqdata); - char *whash = bin2hex(work->hash, 32); - applog(LOG_DEBUG, "[THR%d] %s: hash: %s", thr_id, __func__, whash); - free(whash); - char *targ = bin2hex(work->target, 32); - applog(LOG_DEBUG, "[THR%d] %s: target: %s", thr_id, __func__, targ); - free(targ); - applog(LOG_DEBUG, "[THR%d] %s: %08lx <= %08lx?", thr_id, __func__, ((uint32_t *)work->hash)[7], ((uint32_t *)work->target)[7]);*/ - if (((uint32_t *)work->hash)[7] <= ((uint32_t *)work->target)[7]) { - // applog(LOG_DEBUG, "[THR%d] %s: valid!", thr_id, __func__); - submit_nonce(work->thr, work, 0); - } - /*else { - applog(LOG_DEBUG, "[THR%d] %s: invalid...", thr_id, __func__); - }*/ - } - else { - if (*(uint64_t*) (work->hash + 24) < *(uint64_t*) (work->target + 24)) { - submit_tested_work(work->thr, work); - } + if (*(uint64_t*) (work->hash + 24) < *(uint64_t*) (work->target + 24)) { + submit_tested_work(work->thr, work); } return 1; } diff --git a/algorithm/equihash.h b/algorithm/equihash.h index 79ed5505..330daeca 100644 --- a/algorithm/equihash.h +++ b/algorithm/equihash.h @@ -3,9 +3,10 @@ #include #include "miner.h" +#include "kernel/equihash-param.h" +uint32_t equihash_verify_sol(struct work *work, sols_t *sols, int sol_i); void equihash_calc_mid_hash(uint64_t[8], uint8_t*); -int equihash_check_solutions(struct work*, uint32_t*, uint64_t*); void equihash_regenhash(struct work *work); int64_t equihash_scanhash(struct thr_info *thr, struct work *work, int64_t *last_nonce, int64_t __maybe_unused max_nonce); diff --git a/driver-opencl.c b/driver-opencl.c index 4d74a5dc..47847624 100644 --- a/driver-opencl.c +++ b/driver-opencl.c @@ -36,7 +36,6 @@ #include "util.h" #include "algorithm/equihash.h" -#include "kernel/equihash-param.h" /* TODO: cleanup externals ********************/ @@ -1334,7 +1333,6 @@ static bool opencl_thread_init(struct thr_info *thr) cl_int status = 0; thrdata = (struct opencl_thread_data *)calloc(1, sizeof(*thrdata)); thr->cgpu_data = thrdata; - int buffersize = (gpu->algorithm.type == ALGO_EQUIHASH) ? sizeof(sols_t) : BUFFERSIZE; //MAX(BUFFERSIZE, sizeof(sols_t)); if (!thrdata) { applog(LOG_ERR, "Failed to calloc in opencl_thread_init"); @@ -1342,7 +1340,7 @@ static bool opencl_thread_init(struct thr_info *thr) } thrdata->queue_kernel_parameters = gpu->algorithm.queue_kernel; - thrdata->res = (uint32_t *)calloc(buffersize, 1); + thrdata->res = (uint32_t *)calloc(BUFFERSIZE, 1); if (!thrdata->res) { free(thrdata); @@ -1351,7 +1349,7 @@ static bool opencl_thread_init(struct thr_info *thr) } status |= clEnqueueWriteBuffer(clState->commandQueue, clState->outputBuffer, CL_TRUE, 0, - buffersize, blank_res, 0, NULL, NULL); + BUFFERSIZE, blank_res, 0, NULL, NULL); if (unlikely(status != CL_SUCCESS)) { free(thrdata->res); free(thrdata); @@ -1369,7 +1367,8 @@ static bool opencl_thread_init(struct thr_info *thr) static bool opencl_prepare_work(struct thr_info __maybe_unused *thr, struct work *work) { work->blk.work = work; - if (work->pool->algorithm.precalc_hash) work->pool->algorithm.precalc_hash(&work->blk, 0, (uint32_t *)(work->data)); + if (work->pool->algorithm.precalc_hash) + work->pool->algorithm.precalc_hash(&work->blk, 0, (uint32_t *)(work->data)); thr->pool_no = work->pool->pool_no; return true; @@ -1377,7 +1376,6 @@ static bool opencl_prepare_work(struct thr_info __maybe_unused *thr, struct work extern int opt_dynamic_interval; -uint32_t verify_sol(struct work *, sols_t *, int); static int64_t opencl_scanhash(struct thr_info *thr, struct work *work, int64_t __maybe_unused max_nonce) @@ -1427,7 +1425,7 @@ static int64_t opencl_scanhash(struct thr_info *thr, struct work *work, uint64_t t0 = time(NULL); uint8_t prev_hash[32]; size_t txns; - bool stale = false; + bool stale = true; if (work->getwork_mode != GETWORK_MODE_STRATUM) { cg_rlock(&work->pool->gbt_lock); @@ -1448,22 +1446,25 @@ static int64_t opencl_scanhash(struct thr_info *thr, struct work *work, sols->nr = MAX_SOLS; } for (int sol_i = 0; sol_i < sols->nr; sol_i++) - ret += verify_sol(work, sols, sol_i); + ret += equihash_verify_sol(work, sols, sol_i); } else { applog(LOG_ERR, "Error %d: Reading result buffer for ALGO_EQUIHASH failed. (clEnqueueReadBuffer)", status); return -1; } + // increase nonce work->blk.nonce++; - if (work->getwork_mode != GETWORK_MODE_STRATUM) { - *(uint64_t*)(work->equihash_data + 108) += 1; // increase nonce + if (work->getwork_mode == GETWORK_MODE_STRATUM) + *(uint16_t*)(work->equihash_data + 108 + strlen(work->nonce1) / 2) += 1; + else { + *(uint64_t*)(work->equihash_data + 108) += 1; cg_rlock(&work->pool->gbt_lock); stale = (work->pool->gbt_txns != txns) || (memcmp(prev_hash, work->pool->previousblockhash, 32) != 0); cg_runlock(&work->pool->gbt_lock); } - } while ((time(NULL) - t0) <= 3 && !stale); + } while (!stale && (time(NULL) - t0) < 2); return ret; } diff --git a/ocl.c b/ocl.c index 1b755d03..3f5e60cf 100644 --- a/ocl.c +++ b/ocl.c @@ -38,7 +38,7 @@ #include "algorithm/pluck.h" #include "algorithm/yescrypt.h" #include "algorithm/lyra2rev2.h" -#include "kernel/equihash-param.h" +#include "algorithm/equihash.h" /* FIXME: only here for global config vars, replace with configuration.h * or similar as soon as config is in a struct instead of littered all diff --git a/sgminer.c b/sgminer.c index 20e38271..d80ef066 100644 --- a/sgminer.c +++ b/sgminer.c @@ -6507,29 +6507,23 @@ static void gen_stratum_work_eth(struct pool *pool, struct work *work) static void gen_stratum_work_equihash(struct pool *pool, struct work *work) { - unsigned char merkle_root[32], merkle_sha[64]; - uint32_t *data32, *swap32; - uint64_t nonce2le; - int i, j; - cg_wlock(&pool->data_lock); + work->nonce2 = pool->nonce2++; + work->nonce2_len = 2; + /* Downgrade to a read lock to read off the pool variables */ cg_dwlock(&pool->data_lock); /* equihash already has the merkle root in the header no need to change it */ -// memset(work->data, 0, 168); -// memcpy(work->data, pool->header_bin, 128); memset(work->equihash_data, 0, 1487); memcpy(work->equihash_data, pool->header_bin, 128); //add pool extra nonce - hex2bin(work->equihash_data+108, pool->nonce1, (strlen(pool->nonce1) / 2)); - *(uint64_t *)(work->equihash_data+108+(strlen(pool->nonce1) / 2)) = 1; - + hex2bin(work->equihash_data + 108, pool->nonce1, strlen(pool->nonce1) / 2); + memcpy(work->equihash_data + 108 + 20 - work->nonce2_len, &work->nonce2, work->nonce2_len); + //add solutionsize - //uint32_t solution_size = 0x540fd; //compact size 1344 (0x540) - make/use a function to calculate the encoding in the future - //memcpy(work->data+140, &solution_size, 3); - add_var_int(work->equihash_data+140, 1344); + add_var_int(work->equihash_data + 140, 1344); /* Store the stratum work diff to check it still matches the pool's * stratum diff when submitting shares */ @@ -6545,10 +6539,8 @@ static void gen_stratum_work_equihash(struct pool *pool, struct work *work) char *header, *merkle_hash; header = bin2hex(work->equihash_data, 143); - merkle_hash = bin2hex((const unsigned char *)merkle_root, 32); - applog(LOG_DEBUG, "[THR%d] Generated stratum merkle %s", work->thr_id, merkle_hash); applog(LOG_DEBUG, "[THR%d] Generated stratum header %s", work->thr_id, header); - applog(LOG_DEBUG, "[THR%d] Work job_id %s nonce2 %"PRIu64" ntime %s", work->thr_id, work->job_id, work->nonce2, work->ntime); + applog(LOG_DEBUG, "[THR%d] job_id %s, nonce1 %s, nonce2 %"PRIu64", ntime %s", work->thr_id, work->job_id, work->nonce1, work->nonce2, work->ntime); free(header); free(merkle_hash); } @@ -7678,8 +7670,9 @@ bool submit_tested_work(struct thr_info *thr, struct work *work) else if (work->pool->algorithm.type == ALGO_EQUIHASH) { applog(LOG_DEBUG, "equihash target: %.16llx", *(uint64_t*) (work->target + 24)); if (*(uint64_t*) (work->hash + 24) > *(uint64_t*) (work->target + 24)) - return false; - applog(LOG_WARNING, "Found zcash block!"); + return false; + if (work->getwork_mode == GETWORK_MODE_GBT) + applog(LOG_WARNING, "Found zcash block!"); } else if (!fulltest(work->hash, work->target)) { applog(LOG_INFO, "%s %d: Share above target", thr->cgpu->drv->name, @@ -8093,7 +8086,6 @@ static void *longpoll_thread(void *userdata) } while (42) { - applog(LOG_WARNING, "longpoll..."); json_t *val, *soval; wait_lpcurrent(cp); @@ -9493,7 +9485,15 @@ int main(int argc, char *argv[]) pool->rpc_userpass = (char *)malloc(siz); if (!pool->rpc_userpass) quit(1, "Failed to malloc userpass"); - snprintf(pool->rpc_userpass, siz, "%s:%s", pool->rpc_user, pool->rpc_pass); + + char *point_chr = strchr(pool->rpc_user, '.'); + if (pool->algorithm.type == ALGO_EQUIHASH && point_chr != NULL) { + *point_chr = '\0'; + snprintf(pool->rpc_userpass, siz, "%s:%s", pool->rpc_user, pool->rpc_pass); + *point_chr = '.'; + } + else + snprintf(pool->rpc_userpass, siz, "%s:%s", pool->rpc_user, pool->rpc_pass); } } /* Set the currentpool to pool 0 */