|
|
@ -469,6 +469,9 @@ struct stratifier_data { |
|
|
|
|
|
|
|
|
|
|
|
uint64_t enonce1_64; |
|
|
|
uint64_t enonce1_64; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/* For protecting the txntable data */ |
|
|
|
|
|
|
|
cklock_t txn_lock; |
|
|
|
|
|
|
|
|
|
|
|
/* For protecting the hashtable data */ |
|
|
|
/* For protecting the hashtable data */ |
|
|
|
cklock_t workbase_lock; |
|
|
|
cklock_t workbase_lock; |
|
|
|
|
|
|
|
|
|
|
@ -1175,7 +1178,7 @@ static bool add_txn(ckpool_t *ckp, sdata_t *sdata, txntable_t **txns, const char |
|
|
|
|
|
|
|
|
|
|
|
/* Look for transactions we already know about and increment their
|
|
|
|
/* Look for transactions we already know about and increment their
|
|
|
|
* refcount if we're still using them. */ |
|
|
|
* refcount if we're still using them. */ |
|
|
|
ck_rlock(&sdata->workbase_lock); |
|
|
|
ck_wlock(&sdata->txn_lock); |
|
|
|
HASH_FIND_STR(sdata->txns, hash, txn); |
|
|
|
HASH_FIND_STR(sdata->txns, hash, txn); |
|
|
|
if (txn) { |
|
|
|
if (txn) { |
|
|
|
if (!local) |
|
|
|
if (!local) |
|
|
@ -1184,7 +1187,7 @@ static bool add_txn(ckpool_t *ckp, sdata_t *sdata, txntable_t **txns, const char |
|
|
|
txn->refcount = REFCOUNT_LOCAL; |
|
|
|
txn->refcount = REFCOUNT_LOCAL; |
|
|
|
txn->seen = found = true; |
|
|
|
txn->seen = found = true; |
|
|
|
} |
|
|
|
} |
|
|
|
ck_runlock(&sdata->workbase_lock); |
|
|
|
ck_wunlock(&sdata->txn_lock); |
|
|
|
|
|
|
|
|
|
|
|
if (found) |
|
|
|
if (found) |
|
|
|
return false; |
|
|
|
return false; |
|
|
@ -1283,7 +1286,7 @@ static void update_txns(ckpool_t *ckp, sdata_t *sdata, txntable_t *txns, bool lo |
|
|
|
|
|
|
|
|
|
|
|
/* Find which transactions have their refcount decremented to zero
|
|
|
|
/* Find which transactions have their refcount decremented to zero
|
|
|
|
* and remove them. */ |
|
|
|
* and remove them. */ |
|
|
|
ck_wlock(&sdata->workbase_lock); |
|
|
|
ck_wlock(&sdata->txn_lock); |
|
|
|
HASH_ITER(hh, sdata->txns, tmp, tmpa) { |
|
|
|
HASH_ITER(hh, sdata->txns, tmp, tmpa) { |
|
|
|
json_t *txn_val; |
|
|
|
json_t *txn_val; |
|
|
|
|
|
|
|
|
|
|
@ -1319,7 +1322,7 @@ static void update_txns(ckpool_t *ckp, sdata_t *sdata, txntable_t *txns, bool lo |
|
|
|
HASH_ADD_STR(sdata->txns, hash, tmp); |
|
|
|
HASH_ADD_STR(sdata->txns, hash, tmp); |
|
|
|
added++; |
|
|
|
added++; |
|
|
|
} |
|
|
|
} |
|
|
|
ck_wunlock(&sdata->workbase_lock); |
|
|
|
ck_wunlock(&sdata->txn_lock); |
|
|
|
|
|
|
|
|
|
|
|
if (added) { |
|
|
|
if (added) { |
|
|
|
JSON_CPACK(val, "{so}", "transaction", txn_array); |
|
|
|
JSON_CPACK(val, "{so}", "transaction", txn_array); |
|
|
@ -1681,7 +1684,7 @@ static bool rebuild_txns(ckpool_t *ckp, sdata_t *sdata, workbase_t *wb) |
|
|
|
|
|
|
|
|
|
|
|
memcpy(hash, hashes + i * 65, 64); |
|
|
|
memcpy(hash, hashes + i * 65, 64); |
|
|
|
|
|
|
|
|
|
|
|
ck_wlock(&sdata->workbase_lock); |
|
|
|
ck_wlock(&sdata->txn_lock); |
|
|
|
HASH_FIND_STR(sdata->txns, hash, txn); |
|
|
|
HASH_FIND_STR(sdata->txns, hash, txn); |
|
|
|
if (likely(txn)) { |
|
|
|
if (likely(txn)) { |
|
|
|
txn->refcount = REFCOUNT_REMOTE; |
|
|
|
txn->refcount = REFCOUNT_REMOTE; |
|
|
@ -1690,7 +1693,7 @@ static bool rebuild_txns(ckpool_t *ckp, sdata_t *sdata, workbase_t *wb) |
|
|
|
"hash", hash, "data", txn->data); |
|
|
|
"hash", hash, "data", txn->data); |
|
|
|
json_array_append_new(txn_array, txn_val); |
|
|
|
json_array_append_new(txn_array, txn_val); |
|
|
|
} |
|
|
|
} |
|
|
|
ck_wunlock(&sdata->workbase_lock); |
|
|
|
ck_wunlock(&sdata->txn_lock); |
|
|
|
|
|
|
|
|
|
|
|
if (likely(txn_val)) |
|
|
|
if (likely(txn_val)) |
|
|
|
continue; |
|
|
|
continue; |
|
|
@ -1704,7 +1707,7 @@ static bool rebuild_txns(ckpool_t *ckp, sdata_t *sdata, workbase_t *wb) |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
/* We've found it, let's add it to the table */ |
|
|
|
/* We've found it, let's add it to the table */ |
|
|
|
ck_wlock(&sdata->workbase_lock); |
|
|
|
ck_wlock(&sdata->txn_lock); |
|
|
|
/* One last check in case it got added while we dropped the lock */ |
|
|
|
/* One last check in case it got added while we dropped the lock */ |
|
|
|
HASH_FIND_STR(sdata->txns, hash, txn); |
|
|
|
HASH_FIND_STR(sdata->txns, hash, txn); |
|
|
|
if (likely(!txn)) { |
|
|
|
if (likely(!txn)) { |
|
|
@ -1720,7 +1723,7 @@ static bool rebuild_txns(ckpool_t *ckp, sdata_t *sdata, workbase_t *wb) |
|
|
|
"hash", hash, "data", txn->data); |
|
|
|
"hash", hash, "data", txn->data); |
|
|
|
json_array_append_new(txn_array, txn_val); |
|
|
|
json_array_append_new(txn_array, txn_val); |
|
|
|
} |
|
|
|
} |
|
|
|
ck_wunlock(&sdata->workbase_lock); |
|
|
|
ck_wunlock(&sdata->txn_lock); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
if (ret) { |
|
|
|
if (ret) { |
|
|
@ -3128,6 +3131,7 @@ static void free_proxy(proxy_t *proxy) |
|
|
|
} |
|
|
|
} |
|
|
|
mutex_unlock(&dsdata->share_lock); |
|
|
|
mutex_unlock(&dsdata->share_lock); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/* Do we need to check readcount here if freeing the proxy? */ |
|
|
|
ck_wlock(&dsdata->workbase_lock); |
|
|
|
ck_wlock(&dsdata->workbase_lock); |
|
|
|
HASH_ITER(hh, dsdata->workbases, wb, tmpwb) { |
|
|
|
HASH_ITER(hh, dsdata->workbases, wb, tmpwb) { |
|
|
|
HASH_DEL(dsdata->workbases, wb); |
|
|
|
HASH_DEL(dsdata->workbases, wb); |
|
|
@ -6431,12 +6435,12 @@ static void send_node_all_txns(sdata_t *sdata, const stratum_instance_t *client) |
|
|
|
|
|
|
|
|
|
|
|
txn_array = json_array(); |
|
|
|
txn_array = json_array(); |
|
|
|
|
|
|
|
|
|
|
|
ck_rlock(&sdata->workbase_lock); |
|
|
|
ck_rlock(&sdata->txn_lock); |
|
|
|
HASH_ITER(hh, sdata->txns, txn, tmp) { |
|
|
|
HASH_ITER(hh, sdata->txns, txn, tmp) { |
|
|
|
JSON_CPACK(txn_val, "{ss,ss}", "hash", txn->hash, "data", txn->data); |
|
|
|
JSON_CPACK(txn_val, "{ss,ss}", "hash", txn->hash, "data", txn->data); |
|
|
|
json_array_append_new(txn_array, txn_val); |
|
|
|
json_array_append_new(txn_array, txn_val); |
|
|
|
} |
|
|
|
} |
|
|
|
ck_runlock(&sdata->workbase_lock); |
|
|
|
ck_runlock(&sdata->txn_lock); |
|
|
|
|
|
|
|
|
|
|
|
if (client->trusted) { |
|
|
|
if (client->trusted) { |
|
|
|
JSON_CPACK(val, "{ss,so}", "method", stratum_msgs[SM_TRANSACTIONS], |
|
|
|
JSON_CPACK(val, "{ss,so}", "method", stratum_msgs[SM_TRANSACTIONS], |
|
|
@ -7127,7 +7131,7 @@ static json_t *get_hash_transactions(sdata_t *sdata, const json_t *hashes) |
|
|
|
int found = 0; |
|
|
|
int found = 0; |
|
|
|
size_t index; |
|
|
|
size_t index; |
|
|
|
|
|
|
|
|
|
|
|
ck_rlock(&sdata->workbase_lock); |
|
|
|
ck_rlock(&sdata->txn_lock); |
|
|
|
json_array_foreach(hashes, index, arr_val) { |
|
|
|
json_array_foreach(hashes, index, arr_val) { |
|
|
|
const char *hash = json_string_value(arr_val); |
|
|
|
const char *hash = json_string_value(arr_val); |
|
|
|
json_t *txn_val; |
|
|
|
json_t *txn_val; |
|
|
@ -7141,7 +7145,7 @@ static json_t *get_hash_transactions(sdata_t *sdata, const json_t *hashes) |
|
|
|
json_array_append_new(txn_array, txn_val); |
|
|
|
json_array_append_new(txn_array, txn_val); |
|
|
|
found++; |
|
|
|
found++; |
|
|
|
} |
|
|
|
} |
|
|
|
ck_runlock(&sdata->workbase_lock); |
|
|
|
ck_runlock(&sdata->txn_lock); |
|
|
|
|
|
|
|
|
|
|
|
return txn_array; |
|
|
|
return txn_array; |
|
|
|
} |
|
|
|
} |
|
|
@ -8574,6 +8578,7 @@ void *stratifier(void *arg) |
|
|
|
create_pthread(&pth_heartbeat, ckdb_heartbeat, ckp); |
|
|
|
create_pthread(&pth_heartbeat, ckdb_heartbeat, ckp); |
|
|
|
read_poolstats(ckp); |
|
|
|
read_poolstats(ckp); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
cklock_init(&sdata->txn_lock); |
|
|
|
cklock_init(&sdata->workbase_lock); |
|
|
|
cklock_init(&sdata->workbase_lock); |
|
|
|
if (!ckp->proxy) |
|
|
|
if (!ckp->proxy) |
|
|
|
create_pthread(&pth_blockupdate, blockupdate, ckp); |
|
|
|
create_pthread(&pth_blockupdate, blockupdate, ckp); |
|
|
|