Reuse just the one pool coinbase variable in stratum, avoiding more string functions and storage in gen_stratum_work on each work generation.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151
diff --git a/cgminer.c b/cgminer.c
index 37e393b..fa0d174 100644
--- a/cgminer.c
+++ b/cgminer.c
@@ -5586,33 +5586,23 @@ void set_target(unsigned char *dest_target, double diff)
* other means to detect when the pool has died in stratum_thread */
static void gen_stratum_work(struct pool *pool, struct work *work)
{
- unsigned char *coinbase, merkle_root[32], merkle_sha[64];
+ unsigned char merkle_root[32], merkle_sha[64];
char *header, *merkle_hash;
uint32_t *data32, *swap32;
- size_t alloc_len;
int i;
cg_wlock(&pool->data_lock);
/* Generate coinbase */
work->nonce2 = bin2hex((const unsigned char *)&pool->nonce2, pool->n2size);
+ hex2bin(pool->coinbase + pool->nonce2_offset, work->nonce2, pool->n2size);
pool->nonce2++;
/* Downgrade to a read lock to read off the pool variables */
cg_dwlock(&pool->data_lock);
- alloc_len = pool->swork.cb_len;
- align_len(&alloc_len);
- coinbase = calloc(alloc_len, 1);
- if (unlikely(!coinbase))
- quit(1, "Failed to calloc coinbase in gen_stratum_work");
- memcpy(coinbase, pool->swork.cb1, pool->swork.cb1_len);
- memcpy(coinbase + pool->swork.cb1_len, pool->nonce1bin, pool->n1_len);
- hex2bin(coinbase + pool->nonce2_offset, work->nonce2, pool->n2size);
- memcpy(coinbase + pool->swork.cb1_len + pool->n1_len + pool->n2size, pool->swork.cb2, pool->swork.cb2_len);
/* Generate merkle root */
- gen_hash(coinbase, merkle_root, pool->swork.cb_len);
- free(coinbase);
+ gen_hash(pool->coinbase, merkle_root, pool->swork.cb_len);
memcpy(merkle_sha, merkle_root, 32);
for (i = 0; i < pool->swork.merkles; i++) {
unsigned char merkle_bin[32];
diff --git a/miner.h b/miner.h
index 915b244..fd15e20 100644
--- a/miner.h
+++ b/miner.h
@@ -1088,20 +1088,13 @@ enum pool_enable {
struct stratum_work {
char *job_id;
char *prev_hash;
- char *coinbase1;
- char *coinbase2;
char **merkle;
char *bbversion;
char *nbit;
char *ntime;
bool clean;
- unsigned char *cb1;
- unsigned char *cb2;
- size_t cb1_len;
- size_t cb2_len;
size_t cb_len;
-
size_t header_len;
int merkles;
double diff;
diff --git a/util.c b/util.c
index 1f7fbe6..93c2054 100644
--- a/util.c
+++ b/util.c
@@ -1200,6 +1200,8 @@ static char *json_array_string(json_t *val, unsigned int entry)
static bool parse_notify(struct pool *pool, json_t *val)
{
char *job_id, *prev_hash, *coinbase1, *coinbase2, *bbversion, *nbit, *ntime;
+ size_t cb1_len, cb2_len, alloc_len;
+ unsigned char *cb1, *cb2;
bool clean, ret = false;
int merkles, i;
json_t *arr;
@@ -1241,23 +1243,19 @@ static bool parse_notify(struct pool *pool, json_t *val)
cg_wlock(&pool->data_lock);
free(pool->swork.job_id);
free(pool->swork.prev_hash);
- free(pool->swork.coinbase1);
- free(pool->swork.coinbase2);
free(pool->swork.bbversion);
free(pool->swork.nbit);
free(pool->swork.ntime);
pool->swork.job_id = job_id;
pool->swork.prev_hash = prev_hash;
- pool->swork.coinbase1 = coinbase1;
- pool->swork.cb1_len = strlen(coinbase1) / 2;
- pool->swork.coinbase2 = coinbase2;
- pool->swork.cb2_len = strlen(coinbase2) / 2;
+ cb1_len = strlen(coinbase1) / 2;
+ cb2_len = strlen(coinbase2) / 2;
pool->swork.bbversion = bbversion;
pool->swork.nbit = nbit;
pool->swork.ntime = ntime;
pool->swork.clean = clean;
- pool->swork.cb_len = pool->swork.cb1_len + pool->n1_len + pool->n2size + pool->swork.cb2_len;
- pool->nonce2_offset = pool->swork.cb1_len + pool->n1_len;
+ alloc_len = pool->swork.cb_len = cb1_len + pool->n1_len + pool->n2size + cb2_len;
+ pool->nonce2_offset = cb1_len + pool->n1_len;
for (i = 0; i < pool->swork.merkles; i++)
free(pool->swork.merkle[i]);
@@ -1279,16 +1277,22 @@ static bool parse_notify(struct pool *pool, json_t *val)
pool->swork.header_len = pool->swork.header_len * 2 + 1;
align_len(&pool->swork.header_len);
- free(pool->swork.cb1);
- free(pool->swork.cb2);
- pool->swork.cb1 = calloc(pool->swork.cb1_len, 1);
- if (unlikely(!pool->swork.cb1))
- quithere(1, "Failed to calloc swork cb1");
- hex2bin(pool->swork.cb1, pool->swork.coinbase1, pool->swork.cb1_len);
- pool->swork.cb2 = calloc(pool->swork.cb2_len, 1);
- if (unlikely(!pool->swork.cb2))
- quithere(1, "Failed to calloc swork cb2");
- hex2bin(pool->swork.cb2, pool->swork.coinbase2, pool->swork.cb2_len);
+ cb1 = calloc(cb1_len, 1);
+ if (unlikely(!cb1))
+ quithere(1, "Failed to calloc cb1 in parse_notify");
+ hex2bin(cb1, coinbase1, cb1_len);
+ cb2 = calloc(cb2_len, 1);
+ if (unlikely(!cb2))
+ quithere(1, "Failed to calloc cb2 in parse_notify");
+ hex2bin(cb2, coinbase2, cb2_len);
+ free(pool->coinbase);
+ align_len(&alloc_len);
+ pool->coinbase = calloc(alloc_len, 1);
+ if (unlikely(!pool->coinbase))
+ quit(1, "Failed to calloc pool coinbase in parse_notify");
+ memcpy(pool->coinbase, cb1, cb1_len);
+ memcpy(pool->coinbase + cb1_len, pool->nonce1bin, pool->n1_len);
+ memcpy(pool->coinbase + cb1_len + pool->n1_len + pool->n2size, cb2, cb2_len);
cg_wunlock(&pool->data_lock);
if (opt_protocol) {
@@ -1303,6 +1307,10 @@ static bool parse_notify(struct pool *pool, json_t *val)
applog(LOG_DEBUG, "ntime: %s", ntime);
applog(LOG_DEBUG, "clean: %s", clean ? "yes" : "no");
}
+ free(coinbase1);
+ free(coinbase2);
+ free(cb1);
+ free(cb2);
/* A notify message is the closest stratum gets to a getwork */
pool->getwork_requested++;