From 2d42ae6de586a6ae8cbfd01806a273fd5cc4b262 Mon Sep 17 00:00:00 2001 From: Tanguy Pruvot Date: Tue, 2 Sep 2014 05:09:31 +0200 Subject: [PATCH] stratum: handle a small cache of submitted jobs Prevent to send duplicated shares on some pools like hashharder.. This cache keeps submitted job/nounces of the last 15 minutes so, remove exit on repeated duplicate shares, the submitted cache now handles this problem. Signed-off-by: Tanguy Pruvot --- Makefile.am | 1 + README.md | 6 +-- ccminer.vcxproj | 3 +- ccminer.vcxproj.filters | 5 ++- cpu-miner.c | 29 ++++++++------ hashlog.cpp | 84 +++++++++++++++++++++++++++++++++++++++++ miner.h | 6 +++ 7 files changed, 117 insertions(+), 17 deletions(-) create mode 100644 hashlog.cpp diff --git a/Makefile.am b/Makefile.am index 3935afe..c73d9d2 100644 --- a/Makefile.am +++ b/Makefile.am @@ -17,6 +17,7 @@ ccminer_SOURCES = elist.h miner.h compat.h \ compat/inttypes.h compat/stdbool.h compat/unistd.h \ compat/sys/time.h compat/getopt/getopt.h \ cpu-miner.c util.c hefty1.c scrypt.c \ + hashlog.cpp \ heavy/heavy.cu \ heavy/cuda_blake512.cu heavy/cuda_blake512.h \ heavy/cuda_combine.cu heavy/cuda_combine.h \ diff --git a/README.md b/README.md index 715b387..2a2485b 100644 --- a/README.md +++ b/README.md @@ -3,12 +3,12 @@ ccminer Christian Buchner's & Christian H.'s CUDA miner project -Fork by tpruvot@github with X14,X15,X17,WHIRL and M7 support +Fork by tpruvot@github with X14,X15,X17,WHIRL and Blake256 support BTC donation address: 1AJdfCpLWPNoAMDfHF1wD5y8VgKSSTHxPo + [![tip for next commit](https://tip4commit.com/projects/927.svg)](https://tip4commit.com/github/tpruvot/ccminer) A big part of my recent additions were wrote by [djm34](https://github.com/djm34), -You can also donate some beers (or redbulls) with these addresses : - XjPqpkCPoYJJYdQRrVByU7ySpVyeqJmSGU +You can also donate some beers (or redbulls) This variant was tested and built on Linux (ubuntu server 14.04) and VStudio 2013. diff --git a/ccminer.vcxproj b/ccminer.vcxproj index d3ec423..509715b 100644 --- a/ccminer.vcxproj +++ b/ccminer.vcxproj @@ -243,6 +243,7 @@ copy "$(CudaToolkitBinDir)\cudart64*.dll" "$(OutDir)" + @@ -560,4 +561,4 @@ copy "$(CudaToolkitBinDir)\cudart64*.dll" "$(OutDir)" - + \ No newline at end of file diff --git a/ccminer.vcxproj.filters b/ccminer.vcxproj.filters index 55c69aa..93e331c 100644 --- a/ccminer.vcxproj.filters +++ b/ccminer.vcxproj.filters @@ -180,6 +180,9 @@ Source Files + + Source Files + @@ -440,4 +443,4 @@ Source Files\CUDA - + \ No newline at end of file diff --git a/cpu-miner.c b/cpu-miner.c index 9ff8375..513d4f8 100644 --- a/cpu-miner.c +++ b/cpu-miner.c @@ -210,7 +210,6 @@ static struct stratum_ctx stratum; pthread_mutex_t applog_lock; static pthread_mutex_t stats_lock; -static uint8_t duplicate_shares = 0; static unsigned long accepted_count = 0L; static unsigned long rejected_count = 0L; static double *thr_hashrates; @@ -354,6 +353,7 @@ static pthread_mutex_t g_work_lock; void proper_exit(int reason) { cuda_devicereset(); + hashlog_purge_all(); exit(reason); } @@ -432,14 +432,6 @@ static void share_result(int result, const char *reason) : (result ? "(yay!!!)" : "(booooo)")); if (reason) { - if (!strcmp(reason, "Duplicate share")) { - duplicate_shares++; - if (duplicate_shares > 3) { - // exit from app (until auto restart) - applog(LOG_WARNING, "Auto exit to prevent stratum bans: %s", reason); - proper_exit(1); - } - } applog(LOG_WARNING, "reject reason: %s", reason); } } @@ -460,6 +452,7 @@ static bool submit_upstream_work(CURL *curl, struct work *work) } if (have_stratum) { + uint32_t sent; uint32_t ntime, nonce; uint16_t nvote; char *ntimestr, *noncestr, *xnonce2str, *nvotestr; @@ -472,6 +465,16 @@ static bool submit_upstream_work(CURL *curl, struct work *work) noncestr = bin2hex((const unsigned char *)(&nonce), 4); xnonce2str = bin2hex(work->xnonce2, work->xnonce2_len); nvotestr = bin2hex((const unsigned char *)(&nvote), 2); + + sent = hashlog_already_submittted(work->job_id, nonce); + if (sent > 0) { + sent = (uint32_t) time(NULL) - sent; + if (!opt_quiet) + applog(LOG_WARNING, "skip submit, nonce %s was already sent %u seconds ago", noncestr, sent); + rc = true; + goto out; + } + if (opt_algo == ALGO_HEAVY) { sprintf(s, "{\"method\": \"mining.submit\", \"params\": [\"%s\", \"%s\", \"%s\", \"%s\", \"%s\", \"%s\"], \"id\":4}", @@ -490,6 +493,9 @@ static bool submit_upstream_work(CURL *curl, struct work *work) applog(LOG_ERR, "submit_upstream_work stratum_send_line failed"); goto out; } + + hashlog_remember_submit(work->job_id, nonce); + } else { /* build hex string */ @@ -826,8 +832,6 @@ static void stratum_gen_work(struct stratum_ctx *sctx, struct work *work) diff_to_target(work->target, sctx->job.diff / (65536.0 * opt_difficulty)); else if (opt_algo == ALGO_FUGUE256 || opt_algo == ALGO_GROESTL || opt_algo == ALGO_DMD_GR || opt_algo == ALGO_FRESH) diff_to_target(work->target, sctx->job.diff / (256.0 * opt_difficulty)); - else if (opt_algo == ALGO_BLAKE) - diff_to_target(work->target, sctx->job.diff / (4.0 * opt_difficulty)); else diff_to_target(work->target, sctx->job.diff / opt_difficulty); } @@ -1237,8 +1241,9 @@ static void *stratum_thread(void *userdata) pthread_mutex_unlock(&g_work_lock); if (stratum.job.clean) { if (!opt_quiet) - applog(LOG_BLUE, "%s send a new %s block", short_url, algo_names[opt_algo]); + applog(LOG_BLUE, "%s send a new %s job", short_url, algo_names[opt_algo]); restart_threads(); + hashlog_purge_old(); } } diff --git a/hashlog.cpp b/hashlog.cpp new file mode 100644 index 0000000..ded566e --- /dev/null +++ b/hashlog.cpp @@ -0,0 +1,84 @@ +#include +#include +#include + +#include "miner.h" + +static std::map tlastshares; + +/** + * Purge entries after 15 minutes + */ +#define LOG_PURGE_TIMEOUT 15*60 + +/** + * Store submitted nounces of a job + */ +extern "C" void hashlog_remember_submit(char* jobid, uint32_t nounce) +{ + char *ptr; + uint64_t njobid = (uint64_t) strtoul(jobid, &ptr, 16); + uint64_t key = (njobid << 32) + nounce; + tlastshares[key] = (uint32_t) time(NULL); +} + +/** + * @return time of submission + */ +extern "C" uint32_t hashlog_already_submittted(char* jobid, uint32_t nounce) +{ + char *ptr; + uint32_t ret = 0; + uint64_t njobid = (uint64_t) strtoul(jobid, &ptr, 16); + uint64_t key = (njobid << 32) + nounce; + std::map::iterator i = tlastshares.find(key); + if (i != tlastshares.end()) + ret = (uint32_t) tlastshares[key]; + return ret; +} + +/** + * Remove entries of a job... not used yet + */ +extern "C" void hashlog_purge_job(char* jobid) +{ + char *ptr; + uint64_t njobid = strtoul(jobid, &ptr, 16); + uint64_t keypfx = (njobid << 32); + std::map::iterator i = tlastshares.begin(); + while (i != tlastshares.end()) { + if ((keypfx & i->first) != 0) + tlastshares.erase(i); + i++; + } +} + +/** + * Remove old entries to reduce memory usage + */ +extern "C" void hashlog_purge_old(void) +{ + int deleted = 0; + uint32_t now = (uint32_t) time(NULL); + std::map::iterator i = tlastshares.begin(); + while (i != tlastshares.end()) { + if ((now - i->second) > LOG_PURGE_TIMEOUT) { + deleted++; + tlastshares.erase(i); + } + i++; + } + if (opt_debug && deleted) { + applog(LOG_DEBUG, "hashlog: %d/%d purged", + deleted, tlastshares.size()); + } +} + +/** + * Reset the submitted nounce cache + */ +extern "C" void hashlog_purge_all(void) +{ + tlastshares.clear(); +} + diff --git a/miner.h b/miner.h index c9b2e44..b986197 100644 --- a/miner.h +++ b/miner.h @@ -388,6 +388,12 @@ bool stratum_subscribe(struct stratum_ctx *sctx); bool stratum_authorize(struct stratum_ctx *sctx, const char *user, const char *pass); bool stratum_handle_method(struct stratum_ctx *sctx, const char *s); +void hashlog_remember_submit(char* jobid, uint32_t nounce); +uint32_t hashlog_already_submittted(char* jobid, uint32_t nounce); +void hashlog_purge_old(void); +void hashlog_purge_job(char* jobid); +void hashlog_purge_all(void); + struct thread_q; extern struct thread_q *tq_new(void);