Generate header from correct hashing generation of the merkle root for 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 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
diff --git a/cgminer.c b/cgminer.c
index 0f5e977..6834af1 100644
--- a/cgminer.c
+++ b/cgminer.c
@@ -1362,13 +1362,16 @@ static void calc_midstate(struct work *work)
static void __build_gbt_coinbase(struct pool *pool)
{
unsigned char *coinbase;
+ int cbt_len, cal_len;
uint8_t *extra_len;
- int cbt_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 */
- coinbase = calloc(pool->coinbase_len, 1);
+ cal_len = pool->coinbase_len + 1;
+ if (cal_len % 4)
+ cal_len += 4 - (cal_len % 4);
+ coinbase = calloc(cal_len, 1);
hex2bin(coinbase, pool->coinbasetxn, 42);
extra_len = (uint8_t *)(coinbase + 41);
*extra_len += 4;
@@ -1390,7 +1393,7 @@ static bool __build_gbt_txns(struct pool *pool, json_t *res_val)
json_t *txn_array;
const char *txn0;
bool ret = false;
- int i;
+ int i, cal_len;
free(pool->txn0);
pool->txn0 = NULL;
@@ -1409,7 +1412,10 @@ static bool __build_gbt_txns(struct pool *pool, json_t *res_val)
txn0 = json_string_value(json_object_get(json_array_get(txn_array, 0), "data"));
pool->txn0_len = strlen(txn0) / 2;
- pool->txn0 = calloc(pool->txn0_len , 1);;
+ cal_len = pool->txn0_len;
+ if (cal_len % 4)
+ cal_len += 4 - (cal_len % 4);
+ pool->txn0 = calloc(cal_len , 1);
if (unlikely(!pool->txn0))
quit(1, "Failed to calloc pool->txn0");
if (!hex2bin(pool->txn0, txn0, pool->txn0_len))
@@ -1421,11 +1427,13 @@ static bool __build_gbt_txns(struct pool *pool, json_t *res_val)
for (i = 1; i < pool->gbt_txns; i++) {
json_t *txn_val = json_object_get(json_array_get(txn_array, i), "data");
const char *txn = json_string_value(txn_val);
- int txn_len = strlen(txn), binlen;
+ int txn_len = strlen(txn);
unsigned char *txn_bin;
- binlen = txn_len % 4 ? txn_len + 4 - (txn_len % 4) : txn_len;
- txn_bin = calloc(binlen, 1);
+ cal_len = txn_len;
+ if (cal_len % 4)
+ cal_len += 4 - (cal_len % 4);
+ txn_bin = calloc(cal_len, 1);
if (unlikely(!txn_bin))
quit(1, "Failed to calloc txn_bin in __build_gbt_txns");
if (unlikely(!hex2bin(txn_bin, txn, txn_len / 2)))
@@ -1441,21 +1449,25 @@ out:
static unsigned char *__gbt_merkleroot(struct pool *pool)
{
unsigned char *merkles, *txn0, *merkle_hash;
- int i, txns;
+ int i, txns, cal_len;
if (!pool->gbt_txns) {
pool->txn0 = (unsigned char *)strdup((const char *)pool->gbt_coinbase);
pool->txn0_len = pool->coinbase_len;
}
- txn0 = calloc(pool->coinbase_len + pool->txn0_len, 1);
+ cal_len = pool->coinbase_len + pool->txn0_len;
+ if (cal_len % 4)
+ cal_len += 4 - (cal_len % 4);
+ txn0 = calloc(cal_len, 1);
if (unlikely(!txn0))
quit(1, "Failed to calloc txn0hash");
memcpy(txn0, pool->gbt_coinbase, pool->coinbase_len);
memcpy(txn0 + pool->coinbase_len, pool->txn0, pool->txn0_len);
- merkles = calloc(32 + (32 * pool->gbt_txns), 1);
+ cal_len = 32 + (32 * pool->gbt_txns);
+ merkles = calloc(cal_len, 1);
if (unlikely(!merkles))
quit(1, "Failed to calloc merkles in __gbt_merkleroot");
@@ -1465,20 +1477,24 @@ static unsigned char *__gbt_merkleroot(struct pool *pool)
if (pool->gbt_txns > 1)
memcpy(merkles + 32, pool->txn_hashes, (pool->gbt_txns - 1) * 32);
- merkle_hash = calloc((pool->gbt_txns + 1) * 32, 1);
+ cal_len = (pool->gbt_txns + 1) * 32;
+ merkle_hash = calloc(cal_len, 1);
if (unlikely(!merkle_hash))
quit(1, "Failed to calloc merkle_hash in __gbt_merkleroot");
txns = pool->gbt_txns + 1;
- for (i = 0; i < txns; i++){
- unsigned char tohash[64];
+ while (txns > 1) {
+ if (txns % 2) {
+ memcpy(&merkles[txns * 32], &merkles[(txns - 1) * 32], 32);
+ txns++;
+ }
+ for (i = 0; i < txns; i += 2){
+ unsigned char hashout[32];
- memcpy(tohash, &merkles[i * 32], 32);
- if (i + 1 < txns)
- memcpy(tohash + 32, &merkles[(i + 1) * 32], 32);
- else
- memcpy(tohash + 32, &merkles[i * 32], 32);
- gen_hash(tohash, merkle_hash + (i * 32), 64);
+ gen_hash(merkle_hash + (i * 32), hashout, 64);
+ memcpy(merkle_hash + (i / 2 * 32), hashout, 32);
+ }
+ txns /= 2;
}
return merkle_hash;
}
@@ -1490,8 +1506,21 @@ static void gen_gbt_work(struct pool *pool, struct work *work)
mutex_lock(&pool->gbt_lock);
__build_gbt_coinbase(pool);
merkleroot = __gbt_merkleroot(pool);
+ memcpy(work->data, &pool->gbt_version, 4);
+ hex2bin(work->data + 4, pool->previousblockhash, 32);
+ memcpy(work->data + 4 + 32, merkleroot, 32);
+ memcpy(work->data + 4 + 32 + 32, &pool->curtime, 4);
+ hex2bin(work->data + 4 + 32 + 32 + 4, pool->gbt_bits, 4);
+ memset(work->data + 4 + 32 + 32 + 4 + 4, 0, 4); /* nonce */
mutex_unlock(&pool->gbt_lock);
+ if (opt_debug) {
+ char *header = bin2hex(work->data, 4 + 32 + 32 + 4 + 4 + 4);
+
+ applog(LOG_DEBUG, "Generated GBT header %s", header);
+ free(header);
+ }
+
free(merkleroot);
}