Browse Source

Add --show-diff parameter and fix pool net diff

which display submitted block and net difficulty and is able
to detect shares above net diff (solved blocs)

Note: only made on lyra2v2 and zr5 algos

TODO: compute the found diff on all algos...
require changes in all scan hash "kernel" function parameters

to be continued...
master
Tanguy Pruvot 9 years ago
parent
commit
4babf37256
  1. 33
      bignum.cpp
  2. 108
      ccminer.cpp
  3. 11
      lyra2/lyra2REv2.cu
  4. 13
      miner.h
  5. 10
      util.cpp
  6. 3
      zr5.cu

33
bignum.cpp

@ -24,3 +24,36 @@ extern "C" void bn_nbits_to_uchar(const uint32_t nBits, unsigned char *target) @@ -24,3 +24,36 @@ extern "C" void bn_nbits_to_uchar(const uint32_t nBits, unsigned char *target)
snprintf(buff, 65, "%s\n", bn.ToString().c_str()); buff[64] = '\0';
hex2bin(target, buff, 32);
}
extern "C" double bn_hash_target_ratio(uint32_t* hash, uint32_t* target)
{
unsigned char* uc;
double dhash;
if (!opt_showdiff)
return 0.0;
CBigNum h(0), t(0);
std::vector<unsigned char> vch(32);
memcpy(&vch[0], (void*) target, 32);
t.setvch(vch);
memcpy(&vch[0], (void*) hash, 32);
h.setvch(vch);
dhash = h.getuint256().getdouble();
if (dhash > 0.)
return t.getuint256().getdouble() / dhash;
else
return dhash;
}
// store ratio in work struct
extern "C" void bn_store_hash_target_ratio(uint32_t* hash, uint32_t* target, struct work* work)
{
// only if the option is enabled (to reduce cpu usage)
if (opt_showdiff) {
work->shareratio = bn_hash_target_ratio(hash, target);
work->sharediff = work->targetdiff * work->shareratio;
}
}

108
ccminer.cpp

@ -160,9 +160,11 @@ static const char *algo_names[] = { @@ -160,9 +160,11 @@ static const char *algo_names[] = {
};
bool opt_debug = false;
bool opt_debug_diff = false;
bool opt_debug_threads = false;
bool opt_protocol = false;
bool opt_benchmark = false;
bool opt_showdiff = false;
// todo: limit use of these flags,
// prefer the pools[] attributes
@ -370,6 +372,7 @@ Options:\n\ @@ -370,6 +372,7 @@ Options:\n\
--syslog-prefix=... allow to change syslog tool name\n"
#endif
"\
--show-diff display submitted block and net difficulty\n\
-B, --background run the miner in the background\n\
--benchmark run in offline benchmark mode\n\
--cputest debug hashes from cpu algorithms\n\
@ -425,6 +428,7 @@ struct option options[] = { @@ -425,6 +428,7 @@ struct option options[] = {
{ "retries", 1, NULL, 'r' },
{ "retry-pause", 1, NULL, 'R' },
{ "scantime", 1, NULL, 's' },
{ "show-diff", 0, NULL, 1013 },
{ "statsavg", 1, NULL, 'N' },
{ "gpu-clock", 1, NULL, 1070 },
{ "mem-clock", 1, NULL, 1071 },
@ -601,7 +605,6 @@ static void calc_network_diff(struct work *work) @@ -601,7 +605,6 @@ static void calc_network_diff(struct work *work)
{
// sample for diff 43.281 : 1c05ea29
uchar rtarget[48] = { 0 };
uint64_t diffone = 0xFFFF000000000000ull; //swab64(0xFFFFull);
uint64_t *data64, d64;
// todo: endian reversed on longpoll could be zr5 specific...
uint32_t nbits = have_longpoll ? work->data[18] : swab32(work->data[18]);
@ -609,6 +612,18 @@ static void calc_network_diff(struct work *work) @@ -609,6 +612,18 @@ static void calc_network_diff(struct work *work)
uint32_t bits = (nbits & 0xffffff);
int shfb = 8 * (26 - (shift - 3));
#if 1
uint64_t diffone = 0x0000FFFF00000000ull;
double d = (double)0x0000ffff / (double)bits;
for (int m=shift; m < 29; m++) d *= 256.0;
for (int m=29; m < shift; m++) d /= 256.0;
if (opt_debug_diff)
applog(LOG_DEBUG, "diff: %f -> shift %u, bits %08x, shfb %d", d, shift, bits, shfb);
net_diff = d;
return;
#else
uint64_t diffone = 0xFFFF000000000000ull; //swab64(0xFFFFull);
switch (opt_algo) {
case ALGO_QUARK:
diffone = 0xFFFFFF0000000000ull;
@ -643,10 +658,11 @@ static void calc_network_diff(struct work *work) @@ -643,10 +658,11 @@ static void calc_network_diff(struct work *work)
d64 = swab64(*data64);
if (!d64)
d64 = 1;
net_diff = (double)diffone / d64; // 43.281
if (opt_debug)
net_diff = (double)(diffone) / d64; // 43.281
if (opt_debug_diff)
applog(LOG_DEBUG, "diff: %08x -> shift %u, bits %08x, shfb %d -> %.5f (pool %u)",
nbits, shift, bits, shfb, net_diff, work->pooln);
#endif
}
static bool work_decode(const json_t *val, struct work *work)
@ -679,10 +695,9 @@ static bool work_decode(const json_t *val, struct work *work) @@ -679,10 +695,9 @@ static bool work_decode(const json_t *val, struct work *work)
for (i = 0; i < atarget_sz; i++)
work->target[i] = le32dec(work->target + i);
if (opt_max_diff > 0. && !allow_mininginfo)
if ((opt_showdiff || opt_max_diff > 0.) && !allow_mininginfo)
calc_network_diff(work);
work->tx_count = use_pok = 0;
if (work->data[0] & POK_BOOL_MASK) {
use_pok = 1;
@ -697,10 +712,10 @@ static bool work_decode(const json_t *val, struct work *work) @@ -697,10 +712,10 @@ static bool work_decode(const json_t *val, struct work *work)
size_t txlen = strlen(hexstr)/2;
work->tx_count++;
if (work->tx_count > POK_MAX_TXS || txlen >= POK_MAX_TX_SZ) {
// when tx is too big, just reset use_pok for the bloc
// when tx is too big, just reset use_pok for the block
use_pok = 0;
if (opt_debug) applog(LOG_WARNING,
"pok: large bloc ignored, tx len: %u", txlen);
"pok: large block ignored, tx len: %u", txlen);
work->tx_count = 0;
break;
}
@ -709,7 +724,7 @@ static bool work_decode(const json_t *val, struct work *work) @@ -709,7 +724,7 @@ static bool work_decode(const json_t *val, struct work *work)
totlen += txlen;
}
if (opt_debug)
applog(LOG_DEBUG, "bloc txs: %u, total len: %u", work->tx_count, totlen);
applog(LOG_DEBUG, "block txs: %u, total len: %u", work->tx_count, totlen);
}
}
@ -749,7 +764,7 @@ static void calc_target_diff(struct work *work) @@ -749,7 +764,7 @@ static void calc_target_diff(struct work *work)
//case ALGO_SCRYPT:
//case ALGO_SCRYPT_JANE:
// todo/check...
work->difficulty = 0.;
work->difficulty = work->targetdiff;
return;
case ALGO_HEAVY:
data64 = (uint64_t*)(rtarget + 2);
@ -764,8 +779,14 @@ static void calc_target_diff(struct work *work) @@ -764,8 +779,14 @@ static void calc_target_diff(struct work *work)
work->difficulty /= opt_difficulty;
}
static int share_result(int result, int pooln, const char *reason)
#define YES "yes!"
#define YAY "yay!!!"
#define BOO "booooo"
static int share_result(int result, int pooln, double sharediff, const char *reason)
{
const char *flag;
char suppl[32] = { 0 };
char s[32] = { 0 };
double hashrate = 0.;
struct pool_infos *p = &pools[pooln];
@ -782,15 +803,25 @@ static int share_result(int result, int pooln, const char *reason) @@ -782,15 +803,25 @@ static int share_result(int result, int pooln, const char *reason)
global_hashrate = llround(hashrate);
format_hashrate(hashrate, s);
applog(LOG_NOTICE, "accepted: %lu/%lu (%.2f%%), %s %s",
if (opt_showdiff)
sprintf(suppl, "diff %.3f", sharediff);
else // accepted percent
sprintf(suppl, "%.2f%%", 100. * p->accepted_count / (p->accepted_count + p->rejected_count));
if (!net_diff || sharediff < net_diff) {
flag = use_colors ?
(result ? CL_GRN YES : CL_RED BOO)
: (result ? "(" YES ")" : "(" BOO ")");
} else {
flag = use_colors ?
(result ? CL_GRN YAY : CL_RED BOO)
: (result ? "(" YAY ")" : "(" BOO ")");
}
applog(LOG_NOTICE, "accepted: %lu/%lu (%s), %s %s",
p->accepted_count,
p->accepted_count + p->rejected_count,
100. * p->accepted_count / (p->accepted_count + p->rejected_count),
s,
use_colors ?
(result ? CL_GRN "yay!!!" : CL_RED "booooo")
: (result ? "(yay!!!)" : "(booooo)"));
suppl, s, flag);
if (reason) {
applog(LOG_WARNING, "reject reason: %s", reason);
/* if (strncasecmp(reason, "low difficulty", 14) == 0) {
@ -814,7 +845,7 @@ static bool submit_upstream_work(CURL *curl, struct work *work) @@ -814,7 +845,7 @@ static bool submit_upstream_work(CURL *curl, struct work *work)
bool stale_work = false;
char s[384];
/* discard if a newer bloc was received */
/* discard if a newer block was received */
stale_work = work->height && work->height < g_work.height;
if (have_stratum && !stale_work && opt_algo != ALGO_ZR5 && opt_algo != ALGO_SCRYPT_JANE) {
pthread_mutex_lock(&g_work_lock);
@ -828,7 +859,7 @@ static bool submit_upstream_work(CURL *curl, struct work *work) @@ -828,7 +859,7 @@ static bool submit_upstream_work(CURL *curl, struct work *work)
if (get_blocktemplate(curl, &wheight)) {
if (work->height && work->height < wheight.height) {
if (opt_debug)
applog(LOG_WARNING, "bloc %u was already solved", work->height);
applog(LOG_WARNING, "block %u was already solved", work->height);
return true;
}
}
@ -886,6 +917,16 @@ static bool submit_upstream_work(CURL *curl, struct work *work) @@ -886,6 +917,16 @@ static bool submit_upstream_work(CURL *curl, struct work *work)
ntimestr = bin2hex((const uchar*)(&ntime), 4);
xnonce2str = bin2hex(work->xnonce2, work->xnonce2_len);
// store to keep/display the solved ratio/diff
stratum.sharediff = work->sharediff;
if (net_diff && stratum.sharediff > net_diff && (!opt_quiet || opt_debug_diff))
applog(LOG_INFO, "share diff: %.5f, possible block found!!!",
stratum.sharediff);
else if (opt_debug_diff)
applog(LOG_DEBUG, "share diff: %.5f (x %.1f)",
stratum.sharediff, work->shareratio);
if (opt_algo == ALGO_HEAVY) {
be16enc(&nvote, *((uint16_t*)&work->data[20]));
nvotestr = bin2hex((const uchar*)(&nvote), 2);
@ -947,8 +988,7 @@ static bool submit_upstream_work(CURL *curl, struct work *work) @@ -947,8 +988,7 @@ static bool submit_upstream_work(CURL *curl, struct work *work)
res = json_object_get(val, "result");
reason = json_object_get(val, "reject-reason");
if (!share_result(json_is_true(res),
work->pooln,
if (!share_result(json_is_true(res), work->pooln, work->sharediff,
reason ? json_string_value(reason) : NULL))
{
if (check_dups)
@ -969,7 +1009,7 @@ static bool gbt_work_decode(const json_t *val, struct work *work) @@ -969,7 +1009,7 @@ static bool gbt_work_decode(const json_t *val, struct work *work)
json_t *err = json_object_get(val, "error");
if (err && !json_is_null(err)) {
allow_gbt = false;
applog(LOG_INFO, "GBT not supported, bloc height unavailable");
applog(LOG_INFO, "GBT not supported, block height unavailable");
return false;
}
@ -1373,7 +1413,7 @@ static bool stratum_gen_work(struct stratum_ctx *sctx, struct work *work) @@ -1373,7 +1413,7 @@ static bool stratum_gen_work(struct stratum_ctx *sctx, struct work *work)
work->xnonce2_len = sctx->xnonce2_size;
memcpy(work->xnonce2, sctx->job.xnonce2, sctx->xnonce2_size);
// also store the bloc number
// also store the block number
work->height = sctx->job.height;
// and the pool of the current stratum
work->pooln = sctx->pooln;
@ -1415,7 +1455,7 @@ static bool stratum_gen_work(struct stratum_ctx *sctx, struct work *work) @@ -1415,7 +1455,7 @@ static bool stratum_gen_work(struct stratum_ctx *sctx, struct work *work)
work->data[17] = le32dec(sctx->job.ntime);
work->data[18] = le32dec(sctx->job.nbits);
if (opt_max_diff > 0.)
if (opt_showdiff || opt_max_diff > 0.)
calc_network_diff(work);
switch (opt_algo) {
@ -1460,21 +1500,21 @@ static bool stratum_gen_work(struct stratum_ctx *sctx, struct work *work) @@ -1460,21 +1500,21 @@ static bool stratum_gen_work(struct stratum_ctx *sctx, struct work *work)
case ALGO_NEOSCRYPT:
case ALGO_SCRYPT:
case ALGO_SCRYPT_JANE:
diff_to_target(work->target, sctx->job.diff / (65536.0 * opt_difficulty));
diff_to_target(work, sctx->job.diff / (65536.0 * opt_difficulty));
break;
case ALGO_DMD_GR:
case ALGO_FRESH:
case ALGO_FUGUE256:
case ALGO_GROESTL:
case ALGO_LYRA2v2:
diff_to_target(work->target, sctx->job.diff / (256.0 * opt_difficulty));
diff_to_target(work, sctx->job.diff / (256.0 * opt_difficulty));
break;
case ALGO_KECCAK:
case ALGO_LYRA2:
diff_to_target(work->target, sctx->job.diff / (128.0 * opt_difficulty));
diff_to_target(work, sctx->job.diff / (128.0 * opt_difficulty));
break;
default:
diff_to_target(work->target, sctx->job.diff / opt_difficulty);
diff_to_target(work, sctx->job.diff / opt_difficulty);
}
return true;
}
@ -1919,8 +1959,7 @@ static void *miner_thread(void *userdata) @@ -1919,8 +1959,7 @@ static void *miner_thread(void *userdata)
break;
case ALGO_LYRA2v2:
rc = scanhash_lyra2v2(thr_id, work.data, work.target,
max_nonce, &hashes_done);
rc = scanhash_lyra2v2(thr_id, &work, max_nonce, &hashes_done);
break;
case ALGO_NEOSCRYPT:
@ -2208,7 +2247,7 @@ longpoll_retry: @@ -2208,7 +2247,7 @@ longpoll_retry:
if (!opt_quiet) {
char netinfo[64] = { 0 };
if (net_diff > 0.) {
sprintf(netinfo, ", diff %.2f", net_diff);
sprintf(netinfo, ", diff %.3f", net_diff);
}
applog(LOG_BLUE, "%s detected new block%s", short_url, netinfo);
}
@ -2280,7 +2319,7 @@ static bool stratum_handle_response(char *buf) @@ -2280,7 +2319,7 @@ static bool stratum_handle_response(char *buf)
// store time required to the pool to answer to a submit
stratum.answer_msec = (1000 * diff.tv_sec) + (uint32_t) (0.001 * diff.tv_usec);
share_result(json_is_true(res_val), stratum.pooln,
share_result(json_is_true(res_val), stratum.pooln, stratum.sharediff,
err_val ? json_string_value(json_array_get(err_val, 1)) : NULL);
ret = true;
@ -2366,7 +2405,7 @@ wait_stratum_url: @@ -2366,7 +2405,7 @@ wait_stratum_url:
if (stratum.job.clean) {
if (!opt_quiet) {
if (net_diff > 0.)
applog(LOG_BLUE, "%s block %d, diff %.2f", algo_names[opt_algo],
applog(LOG_BLUE, "%s block %d, diff %.3f", algo_names[opt_algo],
stratum.job.height, net_diff);
else
applog(LOG_BLUE, "%s %s block %d", pool->short_url, algo_names[opt_algo],
@ -2841,6 +2880,9 @@ void parse_arg(int key, char *arg) @@ -2841,6 +2880,9 @@ void parse_arg(int key, char *arg)
case 1012:
opt_extranonce = false;
break;
case 1013:
opt_showdiff = true;
break;
case 'S':
case 1018:
applog(LOG_INFO, "Now logging to syslog...");

11
lyra2/lyra2REv2.cu

@ -71,10 +71,10 @@ void lyra2v2_hash(void *state, const void *input) @@ -71,10 +71,10 @@ void lyra2v2_hash(void *state, const void *input)
static bool init[MAX_GPUS] = { 0 };
extern "C" int scanhash_lyra2v2(int thr_id, uint32_t *pdata,
const uint32_t *ptarget, uint32_t max_nonce,
unsigned long *hashes_done)
extern "C" int scanhash_lyra2v2(int thr_id, struct work* work, uint32_t max_nonce, unsigned long *hashes_done)
{
uint32_t *pdata = work->data;
uint32_t *ptarget = work->target;
const uint32_t first_nonce = pdata[19];
int intensity = (device_sm[device_map[thr_id]] > 500 && !is_windows()) ? 18 : 17;
unsigned int defthr = 1U << intensity;
@ -138,10 +138,15 @@ extern "C" int scanhash_lyra2v2(int thr_id, uint32_t *pdata, @@ -138,10 +138,15 @@ extern "C" int scanhash_lyra2v2(int thr_id, uint32_t *pdata,
if (vhash64[7] <= Htarg && fulltest(vhash64, ptarget))
{
int res = 1;
bn_store_hash_target_ratio(vhash64, ptarget, work);
// check if there was another one...
*hashes_done = pdata[19] - first_nonce + throughput;
if (foundNonces[1] != 0)
{
be32enc(&endiandata[19], foundNonces[1]);
lyra2v2_hash(vhash64, endiandata);
if (bn_hash_target_ratio(vhash64, ptarget) > work->shareratio)
bn_store_hash_target_ratio(vhash64, ptarget, work);
pdata[21] = foundNonces[1];
res++;
}

13
miner.h

@ -322,8 +322,8 @@ extern int scanhash_fresh(int thr_id, uint32_t *pdata, @@ -322,8 +322,8 @@ extern int scanhash_fresh(int thr_id, uint32_t *pdata,
extern int scanhash_lyra2(int thr_id, uint32_t *pdata,
const uint32_t *ptarget, uint32_t max_nonce, unsigned long *hashes_done);
extern int scanhash_lyra2v2(int thr_id, uint32_t *pdata,
const uint32_t *ptarget, uint32_t max_nonce, unsigned long *hashes_done);
extern int scanhash_lyra2v2(int thr_id, struct work *work,
uint32_t max_nonce, unsigned long *hashes_done);
extern int scanhash_neoscrypt(int thr_id, uint32_t *pdata,
const uint32_t *ptarget, uint32_t max_nonce, unsigned long *hashes_done);
@ -495,6 +495,7 @@ extern bool opt_benchmark; @@ -495,6 +495,7 @@ extern bool opt_benchmark;
extern bool opt_debug;
extern bool opt_quiet;
extern bool opt_protocol;
extern bool opt_showdiff;
extern bool opt_tracegpu;
extern int opt_n_threads;
extern int active_gpus;
@ -571,13 +572,15 @@ extern bool hex2bin(unsigned char *p, const char *hexstr, size_t len); @@ -571,13 +572,15 @@ extern bool hex2bin(unsigned char *p, const char *hexstr, size_t len);
extern int timeval_subtract(struct timeval *result, struct timeval *x,
struct timeval *y);
extern bool fulltest(const uint32_t *hash, const uint32_t *target);
extern void diff_to_target(uint32_t *target, double diff);
extern void diff_to_target(struct work* work, double diff);
extern void get_currentalgo(char* buf, int sz);
extern uint32_t device_intensity(int thr_id, const char *func, uint32_t defcount);
// bignum
double bn_convert_nbits(const uint32_t nbits);
void bn_nbits_to_uchar(const uint32_t nBits, uchar *target);
double bn_hash_target_ratio(uint32_t* hash, uint32_t* target);
void bn_store_hash_target_ratio(uint32_t* hash, uint32_t* target, struct work* work);
struct stratum_job {
char *job_id;
@ -607,6 +610,7 @@ struct stratum_ctx { @@ -607,6 +610,7 @@ struct stratum_ctx {
char *sockbuf;
double next_diff;
double sharediff;
char *session_id;
size_t xnonce1_size;
@ -643,7 +647,10 @@ struct work { @@ -643,7 +647,10 @@ struct work {
uint64_t u64[1];
} noncerange;
double targetdiff;
double difficulty;
double shareratio;
double sharediff;
uint32_t height;
uint8_t pooln;

10
util.cpp

@ -38,6 +38,7 @@ @@ -38,6 +38,7 @@
extern pthread_mutex_t stratum_sock_lock;
extern pthread_mutex_t stratum_work_lock;
extern bool opt_debug_diff;
bool opt_tracegpu = false;
@ -765,7 +766,7 @@ bool fulltest(const uint32_t *hash, const uint32_t *target) @@ -765,7 +766,7 @@ bool fulltest(const uint32_t *hash, const uint32_t *target)
}
}
if (!rc && opt_debug) {
if ((!rc && opt_debug) || opt_debug_diff) {
uint32_t hash_be[8], target_be[8];
char *hash_str, *target_str;
@ -789,11 +790,14 @@ bool fulltest(const uint32_t *hash, const uint32_t *target) @@ -789,11 +790,14 @@ bool fulltest(const uint32_t *hash, const uint32_t *target)
return rc;
}
void diff_to_target(uint32_t *target, double diff)
void diff_to_target(struct work* work, double diff)
{
uint32_t *target = work->target;
uint64_t m;
int k;
work->targetdiff = diff;
for (k = 6; k > 0 && diff > 1.0; k--)
diff /= 4294967296.0;
m = (uint64_t)(4294901760.0 / diff);

3
zr5.cu

@ -435,6 +435,7 @@ extern "C" int scanhash_zr5(int thr_id, struct work *work, @@ -435,6 +435,7 @@ extern "C" int scanhash_zr5(int thr_id, struct work *work,
zr5hash(vhash64, pdata);
if (vhash64[7] <= ptarget[7] && fulltest(vhash64, ptarget)) {
int res = 1;
bn_store_hash_target_ratio(vhash64, ptarget, work);
uint32_t secNonce = cuda_check_hash_suppl(thr_id, throughput, oldp19, d_hash[thr_id], 1);
if (secNonce != 0) {
offset = secNonce - oldp19;
@ -444,6 +445,8 @@ extern "C" int scanhash_zr5(int thr_id, struct work *work, @@ -444,6 +445,8 @@ extern "C" int scanhash_zr5(int thr_id, struct work *work,
tmpdata[0] = pok; tmpdata[19] = secNonce;
zr5hash(vhash64, tmpdata);
if (vhash64[7] <= ptarget[7] && fulltest(vhash64, ptarget)) {
if (bn_hash_target_ratio(vhash64, ptarget) > work->shareratio)
bn_store_hash_target_ratio(vhash64, ptarget, work);
pdata[21] = secNonce;
pdata[22] = pok;
res++;

Loading…
Cancel
Save