Browse Source

Prevent transaction refcount from falling inappropriately rapidly causing early removal from the txn table.

master
Con Kolivas 8 years ago
parent
commit
7bc783111b
  1. 35
      src/stratifier.c

35
src/stratifier.c

@ -392,6 +392,7 @@ struct txntable {
char hash[68];
char *data;
int refcount;
bool seen;
};
#define ID_AUTH 0
@ -1165,7 +1166,7 @@ static bool add_txn(ckpool_t *ckp, sdata_t *sdata, txntable_t **txns, const char
txn->refcount = 100;
else if (txn->refcount < 20)
txn->refcount = 20;
found = true;
txn->seen = found = true;
}
ck_runlock(&sdata->workbase_lock);
@ -1175,7 +1176,7 @@ static bool add_txn(ckpool_t *ckp, sdata_t *sdata, txntable_t **txns, const char
txn = ckzalloc(sizeof(txntable_t));
memcpy(txn->hash, hash, 65);
txn->data = strdup(data);
if (ckp->node)
if (!local || ckp->node)
txn->refcount = 100;
else
txn->refcount = 20;
@ -1237,6 +1238,10 @@ static void update_txns(ckpool_t *ckp, sdata_t *sdata, txntable_t *txns, bool lo
* and remove them. */
ck_wlock(&sdata->workbase_lock);
HASH_ITER(hh, sdata->txns, tmp, tmpa) {
if (tmp->seen) {
tmp->seen = false;
continue;
}
if (tmp->refcount-- > 0)
continue;
HASH_DEL(sdata->txns, tmp);
@ -1270,7 +1275,8 @@ static void update_txns(ckpool_t *ckp, sdata_t *sdata, txntable_t *txns, bool lo
/* Distill down a set of transactions into an efficient tree arrangement for
* stratum messages and fast work assembly. */
static void wb_merkle_bins(ckpool_t *ckp, 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,
bool local)
{
int i, j, binleft, binlen;
txntable_t *txns = NULL;
@ -1317,7 +1323,7 @@ static void wb_merkle_bins(ckpool_t *ckp, sdata_t *sdata, workbase_t *wb, json_t
return;
}
txn = json_string_value(json_object_get(arr_val, "data"));
add_txn(ckp, sdata, &txns, hash, txn, true);
add_txn(ckp, sdata, &txns, hash, txn, local);
len = strlen(txn);
memcpy(wb->txn_data + ofs, txn, len);
ofs += len;
@ -1452,7 +1458,7 @@ retry:
json_intcpy(&wb->height, val, "height");
json_strdup(&wb->flags, val, "flags");
txn_array = json_object_get(val, "transactions");
wb_merkle_bins(ckp, sdata, wb, txn_array);
wb_merkle_bins(ckp, sdata, wb, txn_array, true);
wb->insert_witness = false;
memset(wb->witnessdata, 0, sizeof(wb->witnessdata));
@ -1506,12 +1512,13 @@ out:
free(prio);
}
/* Rebuilds transactions from txnhashes to be able to construct wb_merkle_bins */
static bool rebuild_txns(ckpool_t *ckp, sdata_t *sdata, workbase_t *wb, json_t *txnhashes)
{
const char *hashes = json_string_value(txnhashes);
json_t *txn_array;
bool ret = false;
txntable_t *txn;
bool ret = true;
int i, len;
if (likely(hashes))
@ -1523,8 +1530,9 @@ static bool rebuild_txns(ckpool_t *ckp, sdata_t *sdata, workbase_t *wb, json_t *
if (unlikely(len < wb->txns * 65)) {
LOGERR("Truncated transactions in rebuild_txns only %d long", len);
return false;
return ret;
}
ret = true;
txn_array = json_array();
ck_rlock(&sdata->workbase_lock);
@ -1536,22 +1544,25 @@ static bool rebuild_txns(ckpool_t *ckp, sdata_t *sdata, workbase_t *wb, json_t *
hash[64] = '\0';
HASH_FIND_STR(sdata->txns, hash, txn);
if (unlikely(!txn)) {
LOGNOTICE("Failed to find txn in rebuild_txns");
ret = false;
goto out_unlock;
continue;
}
/* This is unnecessary most of the time since it will be set
* in rebuild_txns as well but helps in the case we can't call
* rebuild_txns due to missing some txns */
txn->refcount = 100;
txn->seen = true;
JSON_CPACK(txn_val, "{ss,ss}",
"hash", hash, "data", txn->data);
json_array_append_new(txn_array, txn_val);
}
out_unlock:
ck_runlock(&sdata->workbase_lock);
if (ret) {
LOGINFO("Rebuilt txns into workbase with %d transactions", (int)i);
wb_merkle_bins(ckp, sdata, wb, txn_array);
}
wb_merkle_bins(ckp, sdata, wb, txn_array, false);
} else
LOGNOTICE("Failed to find all txns in rebuild_txns");
json_decref(txn_array);
return ret;

Loading…
Cancel
Save