mirror of
https://github.com/GOSTSec/ccminer
synced 2025-01-08 22:07:56 +00:00
hashlog: prevent double computing on jobs already done
This commit is contained in:
parent
049e577301
commit
1a4391d7ff
@ -304,7 +304,7 @@ extern "C" int scanhash_blake32(int thr_id, uint32_t *pdata, const uint32_t *pta
|
||||
uint32_t vhashcpu[8];
|
||||
uint32_t Htarg = ptarget[7];
|
||||
|
||||
applog(LOG_WARNING, "throughput=%u, start=%x, max=%x", throughput, first_nonce, max_nonce);
|
||||
applog(LOG_WARNING, "throughput=%u, start=%x, max=%x, pdata=%x", throughput, first_nonce, max_nonce, pdata[0]);
|
||||
|
||||
for (int k=0; k < 20; k++)
|
||||
be32enc(&endiandata[k], pdata[k]);
|
||||
|
41
cpu-miner.c
41
cpu-miner.c
@ -822,9 +822,11 @@ static void stratum_gen_work(struct stratum_ctx *sctx, struct work *work)
|
||||
pthread_mutex_unlock(&sctx->work_lock);
|
||||
|
||||
if (opt_debug) {
|
||||
char *tm = atime2str(swab32(work->data[17]));
|
||||
char *xnonce2str = bin2hex(work->xnonce2, sctx->xnonce2_size);
|
||||
applog(LOG_DEBUG, "DEBUG: job_id='%s' extranonce2=%s ntime=%08x",
|
||||
work->job_id, xnonce2str, swab32(work->data[17]));
|
||||
applog(LOG_DEBUG, "DEBUG: job_id=%s xnonce2=%s time=%s",
|
||||
work->job_id, xnonce2str, tm);
|
||||
free(tm);
|
||||
free(xnonce2str);
|
||||
}
|
||||
|
||||
@ -842,10 +844,9 @@ static void *miner_thread(void *userdata)
|
||||
int thr_id = mythr->id;
|
||||
struct work work;
|
||||
uint32_t max_nonce;
|
||||
uint32_t end_nonce = 0xffffffffU / opt_n_threads * (thr_id + 1) - 2;
|
||||
uint32_t end_nonce = 0xffffffffU / opt_n_threads * (thr_id + 1) - (thr_id + 1);
|
||||
unsigned char *scratchbuf = NULL;
|
||||
char s[16];
|
||||
int i;
|
||||
|
||||
memset(&work, 0, sizeof(work)); // prevent work from being used uninitialized
|
||||
|
||||
@ -870,6 +871,7 @@ static void *miner_thread(void *userdata)
|
||||
unsigned long hashes_done;
|
||||
struct timeval tv_start, tv_end, diff;
|
||||
int64_t max64;
|
||||
uint64_t umax64;
|
||||
int rc;
|
||||
|
||||
// &work.data[19]
|
||||
@ -877,13 +879,17 @@ static void *miner_thread(void *userdata)
|
||||
uint32_t *nonceptr = (uint32_t*) (((char*)work.data) + wcmplen);
|
||||
|
||||
if (have_stratum) {
|
||||
while (time(NULL) >= g_work_time + 120)
|
||||
sleep(1);
|
||||
while (time(NULL) >= g_work_time + opt_scantime)
|
||||
usleep(500*1000);
|
||||
pthread_mutex_lock(&g_work_lock);
|
||||
nonceptr = (uint32_t*) (((char*)work.data) + wcmplen);
|
||||
if ((*nonceptr) >= end_nonce)
|
||||
stratum_gen_work(&stratum, &g_work);
|
||||
} else {
|
||||
int min_scantime = have_longpoll ? (LP_SCANTIME*3)/4 : opt_scantime;
|
||||
int min_scantime = have_longpoll ? LP_SCANTIME : opt_scantime;
|
||||
if (!opt_quiet)
|
||||
applog(LOG_DEBUG, "have_longpoll=%d, have_stratum=%d, min_scantime=%d, g_work_time=%d",
|
||||
have_longpoll, have_stratum, min_scantime, g_work_time);
|
||||
/* obtain new work from internal workio thread */
|
||||
pthread_mutex_lock(&g_work_lock);
|
||||
if (!have_stratum &&
|
||||
@ -904,7 +910,7 @@ static void *miner_thread(void *userdata)
|
||||
}
|
||||
if (memcmp(work.data, g_work.data, wcmplen)) {
|
||||
memcpy(&work, &g_work, sizeof(struct work));
|
||||
(*nonceptr) = 0xffffffffU / opt_n_threads * thr_id;
|
||||
(*nonceptr) = 0xffffffffU / opt_n_threads * thr_id; // 0 if single thr
|
||||
} else
|
||||
(*nonceptr)++;
|
||||
pthread_mutex_unlock(&g_work_lock);
|
||||
@ -932,10 +938,24 @@ static void *miner_thread(void *userdata)
|
||||
break;
|
||||
}
|
||||
}
|
||||
if ((int64_t)(*nonceptr) + max64 > end_nonce)
|
||||
|
||||
umax64 = (uint64_t) max64;
|
||||
if (end_nonce < (umax64 + (*nonceptr)))
|
||||
max_nonce = end_nonce;
|
||||
else
|
||||
max_nonce = (uint32_t)((*nonceptr) + max64);
|
||||
max_nonce = umax64 + (*nonceptr);
|
||||
|
||||
/* do not recompute something already scanned (and sent) ! */
|
||||
if (hashlog_already_submittted(work.job_id, 0)) {
|
||||
uint32_t lastnonce = hashlog_get_last_sent(work.job_id);
|
||||
if ((*nonceptr) < lastnonce && lastnonce <= max_nonce) {
|
||||
applog(LOG_WARNING, "rescan of sent job? nonce=%x, last was %x", (*nonceptr), lastnonce);
|
||||
max_nonce = lastnonce - 1;
|
||||
} else if ((*nonceptr) == lastnonce) {
|
||||
applog(LOG_WARNING, "rescan of sent job? start nonce = lastnonce");
|
||||
(*nonceptr) = lastnonce + 1;
|
||||
}
|
||||
}
|
||||
|
||||
hashes_done = 0;
|
||||
gettimeofday(&tv_start, NULL);
|
||||
@ -1051,6 +1071,7 @@ static void *miner_thread(void *userdata)
|
||||
}
|
||||
if (opt_benchmark && thr_id == opt_n_threads - 1) {
|
||||
double hashrate = 0.;
|
||||
int i;
|
||||
for (i = 0; i < opt_n_threads && thr_hashrates[i]; i++)
|
||||
hashrate += thr_hashrates[i];
|
||||
if (i == opt_n_threads) {
|
||||
|
71
hashlog.cpp
71
hashlog.cpp
@ -1,39 +1,68 @@
|
||||
#include <inttypes.h>
|
||||
//#include <inttypes.h>
|
||||
#include <stdlib.h>
|
||||
#include <map>
|
||||
|
||||
#include "miner.h"
|
||||
|
||||
#define HI_DWORD(u64) ((uint32_t) (u64 >> 32))
|
||||
#define LO_DWORD(u64) ((uint32_t) u64)
|
||||
|
||||
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
|
||||
* str hex to uint32
|
||||
*/
|
||||
extern "C" void hashlog_remember_submit(char* jobid, uint32_t nounce)
|
||||
static uint64_t hextouint(char* jobid)
|
||||
{
|
||||
char *ptr;
|
||||
uint64_t njobid = (uint64_t) strtoul(jobid, &ptr, 16);
|
||||
uint64_t key = (njobid << 32) + nounce;
|
||||
return strtoull(jobid, &ptr, 16);
|
||||
}
|
||||
|
||||
/**
|
||||
* Store submitted nonces of a job
|
||||
*/
|
||||
extern "C" void hashlog_remember_submit(char* jobid, uint32_t nonce)
|
||||
{
|
||||
uint64_t njobid = hextouint(jobid);
|
||||
uint64_t key = (njobid << 32) + nonce;
|
||||
tlastshares[key] = (uint32_t) time(NULL);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return time of submission
|
||||
* Search last submitted nonce for a job
|
||||
* @return max nonce
|
||||
*/
|
||||
extern "C" uint32_t hashlog_already_submittted(char* jobid, uint32_t nounce)
|
||||
extern "C" uint32_t hashlog_get_last_sent(char* jobid)
|
||||
{
|
||||
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())
|
||||
uint64_t njobid = hextouint(jobid);
|
||||
uint64_t keypfx = (njobid << 32);
|
||||
std::map<uint64_t, uint32_t>::iterator i = tlastshares.begin();
|
||||
while (i != tlastshares.end()) {
|
||||
if ((keypfx & i->first) == keypfx && LO_DWORD(i->first) > ret) {
|
||||
ret = LO_DWORD(i->first);
|
||||
}
|
||||
i++;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return time of a job/nonce submission (or last nonce if nonce is 0)
|
||||
*/
|
||||
extern "C" uint32_t hashlog_already_submittted(char* jobid, uint32_t nonce)
|
||||
{
|
||||
uint32_t ret = 0;
|
||||
uint64_t njobid = hextouint(jobid);
|
||||
uint64_t key = (njobid << 32) + nonce;
|
||||
if (nonce == 0) {
|
||||
// search last submitted nonce for job
|
||||
ret = hashlog_get_last_sent(jobid);
|
||||
} else if (tlastshares.find(key) != tlastshares.end()) {
|
||||
ret = (uint32_t) tlastshares[key];
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
@ -42,12 +71,11 @@ extern "C" uint32_t hashlog_already_submittted(char* jobid, uint32_t nounce)
|
||||
*/
|
||||
extern "C" void hashlog_purge_job(char* jobid)
|
||||
{
|
||||
char *ptr;
|
||||
uint64_t njobid = strtoul(jobid, &ptr, 16);
|
||||
uint64_t njobid = hextouint(jobid);
|
||||
uint64_t keypfx = (njobid << 32);
|
||||
std::map<uint64_t, uint32_t>::iterator i = tlastshares.begin();
|
||||
while (i != tlastshares.end()) {
|
||||
if ((keypfx & i->first) != 0)
|
||||
if ((keypfx & i->first) == keypfx)
|
||||
tlastshares.erase(i);
|
||||
i++;
|
||||
}
|
||||
@ -60,6 +88,7 @@ extern "C" void hashlog_purge_old(void)
|
||||
{
|
||||
int deleted = 0;
|
||||
uint32_t now = (uint32_t) time(NULL);
|
||||
uint32_t sz = tlastshares.size();
|
||||
std::map<uint64_t, uint32_t>::iterator i = tlastshares.begin();
|
||||
while (i != tlastshares.end()) {
|
||||
if ((now - i->second) > LOG_PURGE_TIMEOUT) {
|
||||
@ -69,16 +98,14 @@ extern "C" void hashlog_purge_old(void)
|
||||
i++;
|
||||
}
|
||||
if (opt_debug && deleted) {
|
||||
applog(LOG_DEBUG, "hashlog: %d/%d purged",
|
||||
deleted, tlastshares.size());
|
||||
applog(LOG_DEBUG, "hashlog: %d/%d purged", deleted, sz);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Reset the submitted nounce cache
|
||||
* Reset the submitted nonces cache
|
||||
*/
|
||||
extern "C" void hashlog_purge_all(void)
|
||||
{
|
||||
tlastshares.clear();
|
||||
}
|
||||
|
||||
|
4
miner.h
4
miner.h
@ -390,6 +390,7 @@ 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);
|
||||
uint32_t hashlog_get_last_sent(char* jobid);
|
||||
void hashlog_purge_old(void);
|
||||
void hashlog_purge_job(char* jobid);
|
||||
void hashlog_purge_all(void);
|
||||
@ -405,6 +406,9 @@ extern void tq_thaw(struct thread_q *tq);
|
||||
|
||||
void proper_exit(int reason);
|
||||
|
||||
size_t time2str(char* buf, time_t timer);
|
||||
char* atime2str(time_t timer);
|
||||
|
||||
void applog_hash(unsigned char *hash);
|
||||
|
||||
void print_hash_tests(void);
|
||||
|
26
util.c
26
util.c
@ -21,6 +21,7 @@
|
||||
#include <unistd.h>
|
||||
#include <jansson.h>
|
||||
#include <curl/curl.h>
|
||||
#include <sys/time.h>
|
||||
#include <time.h>
|
||||
#ifdef WIN32
|
||||
#include "compat/winansi.h"
|
||||
@ -1350,6 +1351,31 @@ out:
|
||||
return rval;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param buf char[9] mini
|
||||
* @param time_t timer to convert
|
||||
*/
|
||||
size_t time2str(char* buf, time_t timer)
|
||||
{
|
||||
struct tm* tm_info;
|
||||
tm_info = localtime(&timer);
|
||||
return strftime(buf, 19, "%H:%M:%S", tm_info);
|
||||
}
|
||||
|
||||
/**
|
||||
* Alloc and returns time string (to be freed)
|
||||
* @param time_t timer to convert
|
||||
*/
|
||||
char* atime2str(time_t timer)
|
||||
{
|
||||
struct tm* tm_info;
|
||||
char* buf = malloc(16);
|
||||
memset(buf, 0, 16);
|
||||
tm_info = localtime(&timer);
|
||||
strftime(buf, 19, "%H:%M:%S", tm_info);
|
||||
return buf;
|
||||
}
|
||||
|
||||
/* sprintf can be used in applog */
|
||||
static char* format_hash(char* buf, unsigned char *hash)
|
||||
{
|
||||
|
Loading…
Reference in New Issue
Block a user