Create a list of solved blocks, passing the hash to and from the generator to ensure we flag the correct block and workinfo

This commit is contained in:
Con Kolivas 2014-10-15 22:28:29 +11:00
parent 46dbec0c0f
commit 71cdbfa560
2 changed files with 106 additions and 33 deletions

View File

@ -347,9 +347,14 @@ retry:
}
}
} else if (cmdmatch(buf, "submitblock:")) {
char blockmsg[80];
bool ret;
LOGNOTICE("Submitting block data!");
if (submit_block(cs, buf + 12))
send_proc(ckp->stratifier, "block");
ret = submit_block(cs, buf + 12 + 64 + 1);
memset(buf + 12 + 64, 0, 1);
sprintf(blockmsg, "%sblock:%s", ret ? "" : "no", buf + 12);
send_proc(ckp->stratifier, blockmsg);
} else if (cmdmatch(buf, "checkaddr:")) {
if (validate_address(cs, buf + 10))
send_unix_msg(sockd, "true");

View File

@ -318,6 +318,12 @@ static share_t *shares;
static cklock_t share_lock;
/* Linked list of block solves, added to during submission, removed on
* accept/reject. It is likely we only ever have one solve on here but you
* never know... */
static pthread_mutex_t block_lock;
static ckmsg_t *block_solves;
static int gen_priority;
/* Priority levels for generator messages */
@ -1149,48 +1155,96 @@ static void reconnect_clients(void)
stratum_broadcast(json_msg);
}
static void block_solve(ckpool_t *ckp)
static void block_solve(ckpool_t *ckp, const char *blockhash)
{
ckmsg_t *block, *tmp, *found = NULL;
char cdfield[64];
int height = 0;
ts_t ts_now;
json_t *val;
char *msg;
update_base(ckp, GEN_PRIORITY);
ts_realtime(&ts_now);
sprintf(cdfield, "%lu,%lu", ts_now.tv_sec, ts_now.tv_nsec);
ck_rlock(&workbase_lock);
ASPRINTF(&msg, "Block %d solved by %s!", current_workbase->height, ckp->name);
/* We send blank settings to ckdb with only the matching data from what we submitted
* to say the block has been confirmed. */
JSON_CPACK(val, "{si,ss,sI,ss,ss,si,ss,ss,ss,sI,ss,ss,ss,ss}",
"height", current_workbase->height,
"confirmed", "1",
"workinfoid", current_workbase->id,
"username", "",
"workername", "",
"clientid", 0,
"enonce1", "",
"nonce2", "",
"nonce", "",
"reward", current_workbase->coinbasevalue,
"createdate", cdfield,
"createby", "code",
"createcode", __func__,
"createinet", ckp->serverurl);
ck_runlock(&workbase_lock);
mutex_lock(&block_lock);
DL_FOREACH_SAFE(block_solves, block, tmp) {
val = block->data;
char *solvehash;
update_base(ckp, GEN_PRIORITY);
json_get_string(&solvehash, val, "blockhash");
if (unlikely(!solvehash)) {
LOGERR("Failed to find blockhash in block_solve json!");
continue;
}
if (!strcmp(solvehash, blockhash)) {
dealloc(solvehash);
found = block;
DL_DELETE(block_solves, block);
break;
}
dealloc(solvehash);
}
mutex_unlock(&block_lock);
ck_rlock(&workbase_lock);
json_set_string(val, "blockhash", current_workbase->prevhash);
ck_runlock(&workbase_lock);
if (unlikely(!found)) {
LOGERR("Failed to find blockhash %s in block_solve!", blockhash);
return;
}
val = found->data;
json_set_string(val, "confirmed", "1");
json_set_string(val, "createdate", cdfield);
json_set_string(val, "createcode", __func__);
json_get_int(&height, val, "height");
ckdbq_add(ckp, ID_BLOCK, val);
free(found);
ASPRINTF(&msg, "Block %d solved by %s!", height, ckp->name);
stratum_broadcast_message(msg);
free(msg);
LOGWARNING("Solved and confirmed block %d", height);
}
static void block_reject(const char *blockhash)
{
ckmsg_t *block, *tmp, *found = NULL;
int height = 0;
json_t *val;
mutex_lock(&block_lock);
DL_FOREACH_SAFE(block_solves, block, tmp) {
val = block->data;
char *solvehash;
json_get_string(&solvehash, val, "blockhash");
if (unlikely(!solvehash)) {
LOGERR("Failed to find blockhash in block_reject json!");
continue;
}
if (!strcmp(solvehash, blockhash)) {
dealloc(solvehash);
found = block;
DL_DELETE(block_solves, block);
break;
}
dealloc(solvehash);
}
mutex_unlock(&block_lock);
if (unlikely(!found)) {
LOGERR("Failed to find blockhash %s in block_reject!", blockhash);
return;
}
val = found->data;
json_get_int(&height, val, "height");
json_decref(val);
free(found);
LOGWARNING("Submitted, but rejected block %d", height);
}
/* Some upstream pools (like p2pool) don't update stratum often enough and
@ -1291,7 +1345,9 @@ retry:
} else if (cmdmatch(buf, "dropall")) {
drop_allclients(ckp);
} else if (cmdmatch(buf, "block")) {
block_solve(ckp);
block_solve(ckp, buf + 6);
} else if (cmdmatch(buf, "noblock")) {
block_reject(buf + 8);
} else if (cmdmatch(buf, "reconnect")) {
reconnect_clients();
} else if (cmdmatch(buf, "loglevel")) {
@ -1907,8 +1963,9 @@ test_blocksolve(stratum_instance_t *client, workbase_t *wb, const uchar *data, c
{
int transactions = wb->transactions + 1;
char hexcoinbase[1024], blockhash[68];
json_t *val = NULL, *val_copy;
char *gbt_block, varint[12];
json_t *val = NULL;
ckmsg_t *block_ckmsg;
char cdfield[64];
uchar swap[32];
ckpool_t *ckp;
@ -1927,8 +1984,12 @@ test_blocksolve(stratum_instance_t *client, workbase_t *wb, const uchar *data, c
sprintf(cdfield, "%lu,%lu", ts_now.tv_sec, ts_now.tv_nsec);
gbt_block = ckalloc(1024);
sprintf(gbt_block, "submitblock:");
__bin2hex(gbt_block + 12, data, 80);
flip_32(swap, hash);
__bin2hex(blockhash, swap, 32);
/* Message format: "submitblock:hash,data" */
sprintf(gbt_block, "submitblock:%s,", blockhash);
__bin2hex(gbt_block + 12 + 64 + 1, data, 80);
if (transactions < 0xfd) {
uint8_t val8 = transactions;
@ -1953,8 +2014,6 @@ test_blocksolve(stratum_instance_t *client, workbase_t *wb, const uchar *data, c
send_generator(ckp, gbt_block, GEN_PRIORITY);
free(gbt_block);
flip_32(swap, hash);
__bin2hex(blockhash, swap, 32);
JSON_CPACK(val, "{si,ss,ss,sI,ss,ss,sI,ss,ss,ss,sI,ss,ss,ss,ss}",
"height", wb->height,
"blockhash", blockhash,
@ -1971,6 +2030,14 @@ test_blocksolve(stratum_instance_t *client, workbase_t *wb, const uchar *data, c
"createby", "code",
"createcode", __func__,
"createinet", ckp->serverurl);
val_copy = json_deep_copy(val);
block_ckmsg = ckalloc(sizeof(ckmsg_t));
block_ckmsg->data = val_copy;
mutex_lock(&block_lock);
DL_APPEND(block_solves, block_ckmsg);
mutex_unlock(&block_lock);
ckdbq_add(ckp, ID_BLOCK, val);
}
@ -3343,6 +3410,7 @@ int stratifier(proc_instance_t *pi)
create_pthread(&pth_statsupdate, statsupdate, ckp);
cklock_init(&share_lock);
mutex_init(&block_lock);
LOGWARNING("%s stratifier ready", ckp->name);