Browse Source

Create a work data template when receiving stratum notification, allowing a simple memcpy of the merkle root avoiding more hex2bin conversions on each work generation.

nfactor-troky
Con Kolivas 11 years ago
parent
commit
87ae66c7e6
  1. 30
      cgminer.c
  2. 2
      miner.h
  3. 25
      util.c

30
cgminer.c

@ -5588,7 +5588,6 @@ static void gen_stratum_work(struct pool *pool, struct work *work)
{ {
unsigned char merkle_root[32], merkle_sha[64]; unsigned char merkle_root[32], merkle_sha[64];
uint32_t *data32, *swap32, nonce2; uint32_t *data32, *swap32, nonce2;
char *header, *merkle_hash;
size_t nonce2_len; size_t nonce2_len;
int i; int i;
@ -5613,20 +5612,10 @@ static void gen_stratum_work(struct pool *pool, struct work *work)
data32 = (uint32_t *)merkle_sha; data32 = (uint32_t *)merkle_sha;
swap32 = (uint32_t *)merkle_root; swap32 = (uint32_t *)merkle_root;
flip32(swap32, data32); flip32(swap32, data32);
merkle_hash = bin2hex((const unsigned char *)merkle_root, 32);
header = calloc(pool->swork.header_len, 1); /* Copy the data template from header_bin */
if (unlikely(!header)) memcpy(work->data, pool->header_bin, 128);
quit(1, "Failed to calloc header in gen_stratum_work"); memcpy(work->data + pool->merkle_offset, merkle_root, 32);
snprintf(header, pool->swork.header_len,
"%s%s%s%s%s%s%s",
pool->swork.bbversion,
pool->swork.prev_hash,
merkle_hash,
pool->swork.ntime,
pool->swork.nbit,
"00000000", /* nonce */
workpadding);
/* Store the stratum work diff to check it still matches the pool's /* Store the stratum work diff to check it still matches the pool's
* stratum diff when submitting shares */ * stratum diff when submitting shares */
@ -5646,18 +5635,19 @@ static void gen_stratum_work(struct pool *pool, struct work *work)
quit(1, "Failed to calloc work nonce2 in gen_stratum_work"); quit(1, "Failed to calloc work nonce2 in gen_stratum_work");
__bin2hex(work->nonce2, (const unsigned char *)&nonce2, sizeof(uint32_t)); __bin2hex(work->nonce2, (const unsigned char *)&nonce2, sizeof(uint32_t));
if (opt_debug) {
char *header, *merkle_hash;
header = bin2hex(work->data, 128);
merkle_hash = bin2hex((const unsigned char *)merkle_root, 32);
applog(LOG_DEBUG, "Generated stratum merkle %s", merkle_hash); applog(LOG_DEBUG, "Generated stratum merkle %s", merkle_hash);
applog(LOG_DEBUG, "Generated stratum header %s", header); applog(LOG_DEBUG, "Generated stratum header %s", header);
applog(LOG_DEBUG, "Work job_id %s nonce2 %s ntime %s", work->job_id, work->nonce2, work->ntime); applog(LOG_DEBUG, "Work job_id %s nonce2 %s ntime %s", work->job_id, work->nonce2, work->ntime);
free(header);
free(merkle_hash); free(merkle_hash);
}
/* Convert hex data to binary data for work */
if (unlikely(!hex2bin(work->data, header, 128)))
quit(1, "Failed to convert header to data in gen_stratum_work");
free(header);
calc_midstate(work); calc_midstate(work);
set_target(work->target, work->sdiff); set_target(work->target, work->sdiff);
local_work++; local_work++;

2
miner.h

@ -1212,6 +1212,8 @@ struct pool {
/* Shared by both stratum & GBT */ /* Shared by both stratum & GBT */
unsigned char *coinbase; unsigned char *coinbase;
int nonce2_offset; int nonce2_offset;
unsigned char header_bin[128];
int merkle_offset;
struct timeval tv_lastwork; struct timeval tv_lastwork;
}; };

25
util.c

@ -1203,9 +1203,12 @@ static char *json_array_string(json_t *val, unsigned int entry)
return NULL; return NULL;
} }
static char *blank_merkel = "0000000000000000000000000000000000000000000000000000000000000000";
static bool parse_notify(struct pool *pool, json_t *val) static bool parse_notify(struct pool *pool, json_t *val)
{ {
char *job_id, *prev_hash, *coinbase1, *coinbase2, *bbversion, *nbit, *ntime; char *job_id, *prev_hash, *coinbase1, *coinbase2, *bbversion, *nbit,
*ntime, *header;
size_t cb1_len, cb2_len, alloc_len; size_t cb1_len, cb2_len, alloc_len;
unsigned char *cb1, *cb2; unsigned char *cb1, *cb2;
bool clean, ret = false; bool clean, ret = false;
@ -1281,15 +1284,29 @@ static bool parse_notify(struct pool *pool, json_t *val)
pool->swork.merkles = merkles; pool->swork.merkles = merkles;
if (clean) if (clean)
pool->nonce2 = 0; pool->nonce2 = 0;
pool->swork.header_len = strlen(pool->swork.bbversion) + pool->merkle_offset = strlen(pool->swork.bbversion) +
strlen(pool->swork.prev_hash) + strlen(pool->swork.prev_hash);
pool->swork.header_len = pool->merkle_offset +
/* merkle_hash */ 32 +
strlen(pool->swork.ntime) + strlen(pool->swork.ntime) +
strlen(pool->swork.nbit) + strlen(pool->swork.nbit) +
/* merkle_hash */ 32 +
/* nonce */ 8 + /* nonce */ 8 +
/* workpadding */ 96; /* workpadding */ 96;
pool->merkle_offset /= 2;
pool->swork.header_len = pool->swork.header_len * 2 + 1; pool->swork.header_len = pool->swork.header_len * 2 + 1;
align_len(&pool->swork.header_len); align_len(&pool->swork.header_len);
header = alloca(pool->swork.header_len);
snprintf(header, pool->swork.header_len,
"%s%s%s%s%s%s%s",
pool->swork.bbversion,
pool->swork.prev_hash,
blank_merkel,
pool->swork.ntime,
pool->swork.nbit,
"00000000", /* nonce */
workpadding);
if (unlikely(!hex2bin(pool->header_bin, header, 128)))
quit(1, "Failed to convert header to header_bin in parse_notify");
cb1 = calloc(cb1_len, 1); cb1 = calloc(cb1_len, 1);
if (unlikely(!cb1)) if (unlikely(!cb1))

Loading…
Cancel
Save