Browse Source

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 <tanguy.pruvot@gmail.com>
master
Tanguy Pruvot 10 years ago
parent
commit
2d42ae6de5
  1. 1
      Makefile.am
  2. 6
      README.md
  3. 1
      ccminer.vcxproj
  4. 3
      ccminer.vcxproj.filters
  5. 29
      cpu-miner.c
  6. 84
      hashlog.cpp
  7. 6
      miner.h

1
Makefile.am

@ -17,6 +17,7 @@ ccminer_SOURCES = elist.h miner.h compat.h \
compat/inttypes.h compat/stdbool.h compat/unistd.h \ compat/inttypes.h compat/stdbool.h compat/unistd.h \
compat/sys/time.h compat/getopt/getopt.h \ compat/sys/time.h compat/getopt/getopt.h \
cpu-miner.c util.c hefty1.c scrypt.c \ cpu-miner.c util.c hefty1.c scrypt.c \
hashlog.cpp \
heavy/heavy.cu \ heavy/heavy.cu \
heavy/cuda_blake512.cu heavy/cuda_blake512.h \ heavy/cuda_blake512.cu heavy/cuda_blake512.h \
heavy/cuda_combine.cu heavy/cuda_combine.h \ heavy/cuda_combine.cu heavy/cuda_combine.h \

6
README.md

@ -3,12 +3,12 @@ ccminer
Christian Buchner's &amp; Christian H.'s CUDA miner project Christian Buchner's &amp; 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 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), 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 : You can also donate some beers (or redbulls)
XjPqpkCPoYJJYdQRrVByU7ySpVyeqJmSGU
This variant was tested and built on Linux (ubuntu server 14.04) This variant was tested and built on Linux (ubuntu server 14.04)
and VStudio 2013. and VStudio 2013.

1
ccminer.vcxproj

@ -243,6 +243,7 @@ copy "$(CudaToolkitBinDir)\cudart64*.dll" "$(OutDir)"</Command>
</ClCompile> </ClCompile>
<ClCompile Include="fuguecoin.cpp" /> <ClCompile Include="fuguecoin.cpp" />
<ClCompile Include="groestlcoin.cpp" /> <ClCompile Include="groestlcoin.cpp" />
<ClCompile Include="hashlog.cpp" />
<ClCompile Include="hefty1.c" /> <ClCompile Include="hefty1.c" />
<ClCompile Include="myriadgroestl.cpp" /> <ClCompile Include="myriadgroestl.cpp" />
<ClCompile Include="scrypt.c"> <ClCompile Include="scrypt.c">

3
ccminer.vcxproj.filters

@ -180,6 +180,9 @@
<ClCompile Include="compat\winansi.c"> <ClCompile Include="compat\winansi.c">
<Filter>Source Files</Filter> <Filter>Source Files</Filter>
</ClCompile> </ClCompile>
<ClCompile Include="hashlog.cpp">
<Filter>Source Files</Filter>
</ClCompile>
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<ClInclude Include="compat.h"> <ClInclude Include="compat.h">

29
cpu-miner.c

@ -210,7 +210,6 @@ static struct stratum_ctx stratum;
pthread_mutex_t applog_lock; pthread_mutex_t applog_lock;
static pthread_mutex_t stats_lock; static pthread_mutex_t stats_lock;
static uint8_t duplicate_shares = 0;
static unsigned long accepted_count = 0L; static unsigned long accepted_count = 0L;
static unsigned long rejected_count = 0L; static unsigned long rejected_count = 0L;
static double *thr_hashrates; static double *thr_hashrates;
@ -354,6 +353,7 @@ static pthread_mutex_t g_work_lock;
void proper_exit(int reason) void proper_exit(int reason)
{ {
cuda_devicereset(); cuda_devicereset();
hashlog_purge_all();
exit(reason); exit(reason);
} }
@ -432,14 +432,6 @@ static void share_result(int result, const char *reason)
: (result ? "(yay!!!)" : "(booooo)")); : (result ? "(yay!!!)" : "(booooo)"));
if (reason) { 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); applog(LOG_WARNING, "reject reason: %s", reason);
} }
} }
@ -460,6 +452,7 @@ static bool submit_upstream_work(CURL *curl, struct work *work)
} }
if (have_stratum) { if (have_stratum) {
uint32_t sent;
uint32_t ntime, nonce; uint32_t ntime, nonce;
uint16_t nvote; uint16_t nvote;
char *ntimestr, *noncestr, *xnonce2str, *nvotestr; 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); noncestr = bin2hex((const unsigned char *)(&nonce), 4);
xnonce2str = bin2hex(work->xnonce2, work->xnonce2_len); xnonce2str = bin2hex(work->xnonce2, work->xnonce2_len);
nvotestr = bin2hex((const unsigned char *)(&nvote), 2); 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) { if (opt_algo == ALGO_HEAVY) {
sprintf(s, sprintf(s,
"{\"method\": \"mining.submit\", \"params\": [\"%s\", \"%s\", \"%s\", \"%s\", \"%s\", \"%s\"], \"id\":4}", "{\"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"); applog(LOG_ERR, "submit_upstream_work stratum_send_line failed");
goto out; goto out;
} }
hashlog_remember_submit(work->job_id, nonce);
} else { } else {
/* build hex string */ /* 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)); 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) 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)); 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 else
diff_to_target(work->target, sctx->job.diff / opt_difficulty); 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); pthread_mutex_unlock(&g_work_lock);
if (stratum.job.clean) { if (stratum.job.clean) {
if (!opt_quiet) 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(); restart_threads();
hashlog_purge_old();
} }
} }

84
hashlog.cpp

@ -0,0 +1,84 @@
#include <inttypes.h>
#include <stdlib.h>
#include <map>
#include "miner.h"
static std::map<uint64_t, uint32_t> 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<uint64_t, uint32_t>::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<uint64_t, uint32_t>::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<uint64_t, uint32_t>::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();
}

6
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_authorize(struct stratum_ctx *sctx, const char *user, const char *pass);
bool stratum_handle_method(struct stratum_ctx *sctx, const char *s); 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; struct thread_q;
extern struct thread_q *tq_new(void); extern struct thread_q *tq_new(void);

Loading…
Cancel
Save