kanoi 9 years ago
parent
commit
e87c451f5c
  1. 50
      src/stratifier.c

50
src/stratifier.c

@ -459,6 +459,9 @@ struct stratifier_data {
int workbases_generated; int workbases_generated;
txntable_t *txns; txntable_t *txns;
/* Is this a node and unable to rebuild workinfos due to lack of txns */
bool wbincomplete;
/* Semaphore to serialise calls to add_base */ /* Semaphore to serialise calls to add_base */
sem_t update_sem; sem_t update_sem;
/* Time we last sent out a stratum update */ /* Time we last sent out a stratum update */
@ -955,7 +958,8 @@ static void send_workinfo(ckpool_t *ckp, sdata_t *sdata, const workbase_t *wb)
"createcode", __func__, "createcode", __func__,
"createinet", ckp->serverurl[0]); "createinet", ckp->serverurl[0]);
ckdbq_add(ckp, ID_WORKINFO, val); ckdbq_add(ckp, ID_WORKINFO, val);
send_node_workinfo(sdata, wb); if (!ckp->proxy)
send_node_workinfo(sdata, wb);
} }
static void send_ageworkinfo(ckpool_t *ckp, const int64_t id) static void send_ageworkinfo(ckpool_t *ckp, const int64_t id)
@ -1117,7 +1121,8 @@ static void broadcast_ping(sdata_t *sdata);
/* Build a hashlist of all transactions, allowing us to compare with the list of /* Build a hashlist of all transactions, allowing us to compare with the list of
* existing transactions to determine which need to be propagated */ * existing transactions to determine which need to be propagated */
static void add_txn(sdata_t *sdata, txntable_t **txns, const char *hash, const char *data) static void add_txn(ckpool_t *ckp, sdata_t *sdata, txntable_t **txns, const char *hash,
const char *data)
{ {
bool found = false; bool found = false;
txntable_t *txn; txntable_t *txn;
@ -1127,7 +1132,10 @@ static void add_txn(sdata_t *sdata, txntable_t **txns, const char *hash, const c
ck_rlock(&sdata->workbase_lock); ck_rlock(&sdata->workbase_lock);
HASH_FIND_STR(sdata->txns, hash, txn); HASH_FIND_STR(sdata->txns, hash, txn);
if (txn) { if (txn) {
txn->refcount++; if (ckp->node)
txn->refcount = 100;
else
txn->refcount = 20;
found = true; found = true;
} }
ck_runlock(&sdata->workbase_lock); ck_runlock(&sdata->workbase_lock);
@ -1138,7 +1146,10 @@ static void add_txn(sdata_t *sdata, txntable_t **txns, const char *hash, const c
txn = ckzalloc(sizeof(txntable_t)); txn = ckzalloc(sizeof(txntable_t));
memcpy(txn->hash, hash, 65); memcpy(txn->hash, hash, 65);
txn->data = strdup(data); txn->data = strdup(data);
txn->refcount = 10; if (ckp->node)
txn->refcount = 100;
else
txn->refcount = 20;
HASH_ADD_STR(*txns, hash, txn); HASH_ADD_STR(*txns, hash, txn);
} }
@ -1173,7 +1184,7 @@ static void send_node_transactions(sdata_t *sdata, const json_t *txn_val)
/* Distill down a set of transactions into an efficient tree arrangement for /* Distill down a set of transactions into an efficient tree arrangement for
* stratum messages and fast work assembly. */ * stratum messages and fast work assembly. */
static void wb_merkle_bins(sdata_t *sdata, workbase_t *wb, json_t *txn_array) static void wb_merkle_bins(ckpool_t *ckp, sdata_t *sdata, workbase_t *wb, json_t *txn_array)
{ {
int i, j, binleft, binlen, added = 0, purged = 0; int i, j, binleft, binlen, added = 0, purged = 0;
txntable_t *txns = NULL, *tmp, *tmpa; txntable_t *txns = NULL, *tmp, *tmpa;
@ -1211,7 +1222,7 @@ static void wb_merkle_bins(sdata_t *sdata, workbase_t *wb, json_t *txn_array)
arr_val = json_array_get(txn_array, i); arr_val = json_array_get(txn_array, i);
hash = json_string_value(json_object_get(arr_val, "hash")); hash = json_string_value(json_object_get(arr_val, "hash"));
txn = json_string_value(json_object_get(arr_val, "data")); txn = json_string_value(json_object_get(arr_val, "data"));
add_txn(sdata, &txns, hash, txn); add_txn(ckp, sdata, &txns, hash, txn);
len = strlen(txn); len = strlen(txn);
memcpy(wb->txn_data + ofs, txn, len); memcpy(wb->txn_data + ofs, txn, len);
ofs += len; ofs += len;
@ -1268,7 +1279,7 @@ static void wb_merkle_bins(sdata_t *sdata, workbase_t *wb, json_t *txn_array)
* and remove them. */ * and remove them. */
ck_wlock(&sdata->workbase_lock); ck_wlock(&sdata->workbase_lock);
HASH_ITER(hh, sdata->txns, tmp, tmpa) { HASH_ITER(hh, sdata->txns, tmp, tmpa) {
if (tmp->refcount--) if (tmp->refcount-- > 0)
continue; continue;
HASH_DEL(sdata->txns, tmp); HASH_DEL(sdata->txns, tmp);
dealloc(tmp->data); dealloc(tmp->data);
@ -1360,7 +1371,7 @@ retry:
json_intcpy(&wb->height, val, "height"); json_intcpy(&wb->height, val, "height");
json_strdup(&wb->flags, val, "flags"); json_strdup(&wb->flags, val, "flags");
txn_array = json_object_get(val, "transactions"); txn_array = json_object_get(val, "transactions");
wb_merkle_bins(sdata, wb, txn_array); wb_merkle_bins(ckp, sdata, wb, txn_array);
json_decref(val); json_decref(val);
generate_coinbase(ckp, wb); generate_coinbase(ckp, wb);
@ -1393,7 +1404,7 @@ out_free:
return NULL; return NULL;
} }
static bool rebuild_txns(sdata_t *sdata, workbase_t *wb, json_t *txnhashes) static bool rebuild_txns(ckpool_t *ckp, sdata_t *sdata, workbase_t *wb, json_t *txnhashes)
{ {
const char *hashes = json_string_value(txnhashes); const char *hashes = json_string_value(txnhashes);
json_t *txn_array; json_t *txn_array;
@ -1427,7 +1438,7 @@ static bool rebuild_txns(sdata_t *sdata, workbase_t *wb, json_t *txnhashes)
ret = false; ret = false;
goto out_unlock; goto out_unlock;
} }
txn->refcount += 2; txn->refcount = 100;
JSON_CPACK(txn_val, "{ss,ss}", JSON_CPACK(txn_val, "{ss,ss}",
"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);
@ -1437,7 +1448,7 @@ out_unlock:
if (ret) { if (ret) {
LOGINFO("Rebuilt txns into workbase with %d transactions", (int)i); LOGINFO("Rebuilt txns into workbase with %d transactions", (int)i);
wb_merkle_bins(sdata, wb, txn_array); wb_merkle_bins(ckp, sdata, wb, txn_array);
} }
json_decref(txn_array); json_decref(txn_array);
@ -1481,11 +1492,18 @@ static void add_node_base(ckpool_t *ckp, json_t *val)
} else { } else {
json_intcpy(&wb->txns, val, "txns"); json_intcpy(&wb->txns, val, "txns");
txnhashes = json_object_get(val, "txn_hashes"); txnhashes = json_object_get(val, "txn_hashes");
if (!rebuild_txns(sdata, wb, txnhashes)) { if (!rebuild_txns(ckp, sdata, wb, txnhashes)) {
LOGWARNING("Unable to rebuild transactions from hashes to create workinfo"); if (!sdata->wbincomplete) {
sdata->wbincomplete = true;
LOGWARNING("Unable to rebuild transactions to create workinfo, ignore displayed hashrate");
}
free(wb); free(wb);
return; return;
} }
if (sdata->wbincomplete) {
LOGWARNING("Successfully resumed rebuilding transactions into workinfo");
sdata->wbincomplete = false;
}
} }
json_strdup(&wb->coinb1, val, "coinb1"); json_strdup(&wb->coinb1, val, "coinb1");
json_intcpy(&wb->coinb1len, val, "coinb1len"); json_intcpy(&wb->coinb1len, val, "coinb1len");
@ -5589,7 +5607,7 @@ out_unlock:
} }
ckdbq_add(ckp, ID_SHARES, val); ckdbq_add(ckp, ID_SHARES, val);
out: out:
if ((!result && !submit) || !share) { if (!sdata->wbincomplete && ((!result && !submit) || !share)) {
/* Is this the first in a run of invalids? */ /* Is this the first in a run of invalids? */
if (client->first_invalid < client->last_share.tv_sec || !client->first_invalid) if (client->first_invalid < client->last_share.tv_sec || !client->first_invalid)
client->first_invalid = now_t; client->first_invalid = now_t;
@ -6320,7 +6338,7 @@ static void add_node_txns(sdata_t *sdata, const json_t *val)
} }
HASH_FIND_STR(sdata->txns, hash, txn); HASH_FIND_STR(sdata->txns, hash, txn);
if (txn) { if (txn) {
txn->refcount++; txn->refcount = 100;
continue; continue;
} }
txn = ckzalloc(sizeof(txntable_t)); txn = ckzalloc(sizeof(txntable_t));
@ -6329,7 +6347,7 @@ static void add_node_txns(sdata_t *sdata, const json_t *val)
/* Set the refcount for node transactions greater than the /* Set the refcount for node transactions greater than the
* upstream pool to ensure we never age them faster than the * upstream pool to ensure we never age them faster than the
* pool does. */ * pool does. */
txn->refcount = 50; txn->refcount = 100;
HASH_ADD_STR(sdata->txns, hash, txn); HASH_ADD_STR(sdata->txns, hash, txn);
added++; added++;
} }

Loading…
Cancel
Save