Cache as much of the gbt coinbase as possible to avoid doing unnecessary hex2bin conversion on every work generation with gbt.
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
diff --git a/cgminer.c b/cgminer.c
index 0437005..fc259c6 100644
--- a/cgminer.c
+++ b/cgminer.c
@@ -1565,33 +1565,6 @@ void free_work(struct work *work)
free(work);
}
-/* Generate a GBT coinbase from the existing GBT variables stored. Must be
- * entered under gbt_lock */
-static void __build_gbt_coinbase(struct pool *pool)
-{
- unsigned char *coinbase;
- int cbt_len, orig_len;
- uint8_t *extra_len;
- size_t cal_len;
-
- cbt_len = strlen(pool->coinbasetxn) / 2;
- pool->coinbase_len = cbt_len + 4;
- /* We add 4 bytes of extra data corresponding to nonce2 of stratum */
- cal_len = pool->coinbase_len + 1;
- align_len(&cal_len);
- coinbase = calloc(cal_len, 1);
- hex2bin(coinbase, pool->coinbasetxn, 42);
- extra_len = (uint8_t *)(coinbase + 41);
- orig_len = *extra_len;
- hex2bin(coinbase + 42, pool->coinbasetxn + 84, orig_len);
- memcpy(coinbase + 42 + orig_len, &pool->nonce2, 4);
- *extra_len += 4;
- hex2bin(coinbase + 42 + *extra_len, pool->coinbasetxn + 84 + (orig_len * 2), cbt_len - orig_len - 42);
- pool->nonce2++;
- free(pool->gbt_coinbase);
- pool->gbt_coinbase = coinbase;
-}
-
static void gen_hash(unsigned char *data, unsigned char *hash, int len);
/* Process transactions with GBT by storing the binary value of the first
@@ -1725,7 +1698,8 @@ static void gen_gbt_work(struct pool *pool, struct work *work)
update_gbt(pool);
cg_wlock(&pool->gbt_lock);
- __build_gbt_coinbase(pool);
+ memcpy(pool->gbt_coinbase + 42 + pool->orig_len, &pool->nonce2, 4);
+ pool->nonce2++;
cg_dwlock(&pool->gbt_lock);
merkleroot = __gbt_merkleroot(pool);
@@ -1784,6 +1758,9 @@ static bool gbt_decode(struct pool *pool, json_t *res_val)
bool submitold;
const char *bits;
const char *workid;
+ int cbt_len;
+ uint8_t *extra_len;
+ size_t cal_len;
previousblockhash = json_string_value(json_object_get(res_val, "previousblockhash"));
target = json_string_value(json_object_get(res_val, "target"));
@@ -1817,6 +1794,23 @@ static bool gbt_decode(struct pool *pool, json_t *res_val)
cg_wlock(&pool->gbt_lock);
free(pool->coinbasetxn);
pool->coinbasetxn = strdup(coinbasetxn);
+ cbt_len = strlen(pool->coinbasetxn) / 2;
+ pool->coinbase_len = cbt_len + 4;
+ /* We add 4 bytes of extra data corresponding to nonce2 of stratum */
+ cal_len = pool->coinbase_len + 1;
+ align_len(&cal_len);
+ free(pool->gbt_coinbase);
+ pool->gbt_coinbase = calloc(cal_len, 1);
+ if (unlikely(!pool->gbt_coinbase))
+ quit(1, "Failed to calloc pool gbt_coinbase in gbt_decode");
+ hex2bin(pool->gbt_coinbase, pool->coinbasetxn, 42);
+ extra_len = (uint8_t *)(pool->gbt_coinbase + 41);
+ pool->orig_len = *extra_len;
+ hex2bin(pool->gbt_coinbase + 42, pool->coinbasetxn + 84, pool->orig_len);
+ *extra_len += 4;
+ hex2bin(pool->gbt_coinbase + 42 + *extra_len, pool->coinbasetxn + 84 + (pool->orig_len * 2),
+ cbt_len - pool->orig_len - 42);
+
free(pool->longpollid);
pool->longpollid = strdup(longpollid);
free(pool->gbt_workid);
diff --git a/miner.h b/miner.h
index 0ac23f8..2bc7ba7 100644
--- a/miner.h
+++ b/miner.h
@@ -1207,6 +1207,8 @@ struct pool {
unsigned char *txn_hashes;
int gbt_txns;
int coinbase_len;
+ int orig_len;
+
struct timeval tv_lastwork;
};