|
|
|
@ -80,80 +80,7 @@ struct pool_stats {
|
|
|
|
|
|
|
|
|
|
typedef struct pool_stats pool_stats_t; |
|
|
|
|
|
|
|
|
|
struct workbase { |
|
|
|
|
/* Hash table data */ |
|
|
|
|
UT_hash_handle hh; |
|
|
|
|
|
|
|
|
|
/* The next two fields need to be consecutive as both of them are
|
|
|
|
|
* used as the key for their hashtable entry in remote_workbases */ |
|
|
|
|
int64_t id; |
|
|
|
|
/* The client id this workinfo came from if remote */ |
|
|
|
|
int64_t client_id; |
|
|
|
|
|
|
|
|
|
char idstring[20]; |
|
|
|
|
|
|
|
|
|
/* How many readers we currently have of this workbase, set
|
|
|
|
|
* under write workbase_lock */ |
|
|
|
|
int readcount; |
|
|
|
|
|
|
|
|
|
/* The id a remote workinfo is mapped to locally */ |
|
|
|
|
int64_t mapped_id; |
|
|
|
|
|
|
|
|
|
ts_t gentime; |
|
|
|
|
tv_t retired; |
|
|
|
|
|
|
|
|
|
/* GBT/shared variables */ |
|
|
|
|
char target[68]; |
|
|
|
|
double diff; |
|
|
|
|
double network_diff; |
|
|
|
|
uint32_t version; |
|
|
|
|
uint32_t curtime; |
|
|
|
|
char prevhash[68]; |
|
|
|
|
char ntime[12]; |
|
|
|
|
uint32_t ntime32; |
|
|
|
|
char bbversion[12]; |
|
|
|
|
char nbit[12]; |
|
|
|
|
uint64_t coinbasevalue; |
|
|
|
|
int height; |
|
|
|
|
char *flags; |
|
|
|
|
int txns; |
|
|
|
|
char *txn_data; |
|
|
|
|
char *txn_hashes; |
|
|
|
|
char witnessdata[80]; //null-terminated ascii
|
|
|
|
|
bool insert_witness; |
|
|
|
|
int merkles; |
|
|
|
|
char merklehash[16][68]; |
|
|
|
|
char merklebin[16][32]; |
|
|
|
|
json_t *merkle_array; |
|
|
|
|
|
|
|
|
|
/* Template variables, lengths are binary lengths! */ |
|
|
|
|
char *coinb1; // coinbase1
|
|
|
|
|
uchar *coinb1bin; |
|
|
|
|
int coinb1len; // length of above
|
|
|
|
|
|
|
|
|
|
char enonce1const[32]; // extranonce1 section that is constant
|
|
|
|
|
uchar enonce1constbin[16]; |
|
|
|
|
int enonce1constlen; // length of above - usually zero unless proxying
|
|
|
|
|
int enonce1varlen; // length of unique extranonce1 string for each worker - usually 8
|
|
|
|
|
|
|
|
|
|
int enonce2varlen; // length of space left for extranonce2 - usually 8 unless proxying
|
|
|
|
|
|
|
|
|
|
char *coinb2; // coinbase2
|
|
|
|
|
uchar *coinb2bin; |
|
|
|
|
int coinb2len; // length of above
|
|
|
|
|
|
|
|
|
|
/* Cached header binary */ |
|
|
|
|
char headerbin[112]; |
|
|
|
|
|
|
|
|
|
char *logdir; |
|
|
|
|
|
|
|
|
|
ckpool_t *ckp; |
|
|
|
|
bool proxy; /* This workbase is proxied work */ |
|
|
|
|
|
|
|
|
|
bool incomplete; /* This is a remote workinfo without all the txn data */ |
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
typedef struct workbase workbase_t; |
|
|
|
|
typedef struct genwork workbase_t; |
|
|
|
|
|
|
|
|
|
struct json_params { |
|
|
|
|
json_t *method; |
|
|
|
@ -729,6 +656,8 @@ static void clear_workbase(workbase_t *wb)
|
|
|
|
|
free(wb->coinb2bin); |
|
|
|
|
free(wb->coinb2); |
|
|
|
|
json_decref(wb->merkle_array); |
|
|
|
|
if (wb->json) |
|
|
|
|
json_decref(wb->json); |
|
|
|
|
free(wb); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
@ -1468,8 +1397,8 @@ static void gbt_witness_data(workbase_t *wb, json_t *txn_array)
|
|
|
|
|
* are serialised. */ |
|
|
|
|
static void block_update(ckpool_t *ckp, int *prio) |
|
|
|
|
{ |
|
|
|
|
json_t *val, *txn_array, *rules_array; |
|
|
|
|
const char* witnessdata_check, *rule; |
|
|
|
|
json_t *txn_array, *rules_array; |
|
|
|
|
sdata_t *sdata = ckp->sdata; |
|
|
|
|
bool new_block = false; |
|
|
|
|
int i, retries = 0; |
|
|
|
@ -1479,8 +1408,8 @@ static void block_update(ckpool_t *ckp, int *prio)
|
|
|
|
|
time_t now_t; |
|
|
|
|
|
|
|
|
|
retry: |
|
|
|
|
val = generator_genbase(ckp); |
|
|
|
|
if (unlikely(!val)) { |
|
|
|
|
wb = generator_getbase(ckp); |
|
|
|
|
if (unlikely(!wb)) { |
|
|
|
|
if (retries++ < 5 || *prio == GEN_PRIORITY) { |
|
|
|
|
LOGWARNING("Generator returned failure in update_base, retry #%d", retries); |
|
|
|
|
goto retry; |
|
|
|
@ -1491,27 +1420,13 @@ retry:
|
|
|
|
|
if (unlikely(retries)) |
|
|
|
|
LOGWARNING("Generator succeeded in update_base after retrying"); |
|
|
|
|
|
|
|
|
|
wb = ckzalloc(sizeof(workbase_t)); |
|
|
|
|
wb->ckp = ckp; |
|
|
|
|
|
|
|
|
|
json_strcpy(wb->target, val, "target"); |
|
|
|
|
json_dblcpy(&wb->diff, val, "diff"); |
|
|
|
|
json_uintcpy(&wb->version, val, "version"); |
|
|
|
|
json_uintcpy(&wb->curtime, val, "curtime"); |
|
|
|
|
json_strcpy(wb->prevhash, val, "prevhash"); |
|
|
|
|
json_strcpy(wb->ntime, val, "ntime"); |
|
|
|
|
sscanf(wb->ntime, "%x", &wb->ntime32); |
|
|
|
|
json_strcpy(wb->bbversion, val, "bbversion"); |
|
|
|
|
json_strcpy(wb->nbit, val, "nbit"); |
|
|
|
|
json_uint64cpy(&wb->coinbasevalue, val, "coinbasevalue"); |
|
|
|
|
json_intcpy(&wb->height, val, "height"); |
|
|
|
|
json_strdup(&wb->flags, val, "flags"); |
|
|
|
|
txn_array = json_object_get(val, "transactions"); |
|
|
|
|
txn_array = json_object_get(wb->json, "transactions"); |
|
|
|
|
txns = wb_merkle_bin_txns(ckp, sdata, wb, txn_array, true); |
|
|
|
|
|
|
|
|
|
wb->insert_witness = false; |
|
|
|
|
memset(wb->witnessdata, 0, sizeof(wb->witnessdata)); |
|
|
|
|
rules_array = json_object_get(val, "rules"); |
|
|
|
|
rules_array = json_object_get(wb->json, "rules"); |
|
|
|
|
|
|
|
|
|
if (rules_array) { |
|
|
|
|
int rule_count = json_array_size(rules_array); |
|
|
|
@ -1523,7 +1438,7 @@ retry:
|
|
|
|
|
if (*rule == '!') |
|
|
|
|
rule++; |
|
|
|
|
if (safecmp(rule, "segwit")) { |
|
|
|
|
witnessdata_check = json_string_value(json_object_get(val, "default_witness_commitment")); |
|
|
|
|
witnessdata_check = json_string_value(json_object_get(wb->json, "default_witness_commitment")); |
|
|
|
|
gbt_witness_data(wb, txn_array); |
|
|
|
|
// Verify against the pre-calculated value if it exists. Skip the size/OP_RETURN bytes.
|
|
|
|
|
if (wb->insert_witness && witnessdata_check[0] && safecmp(witnessdata_check + 4, wb->witnessdata) != 0) |
|
|
|
@ -1533,7 +1448,6 @@ retry:
|
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
json_decref(val); |
|
|
|
|
generate_coinbase(ckp, wb); |
|
|
|
|
|
|
|
|
|
add_base(ckp, sdata, wb, &new_block); |
|
|
|
|