diff --git a/src/ckdb.h b/src/ckdb.h index a45dc0be..94ac6fbc 100644 --- a/src/ckdb.h +++ b/src/ckdb.h @@ -55,7 +55,7 @@ #define DB_VLOCK "1" #define DB_VERSION "1.0.3" -#define CKDB_VERSION DB_VERSION"-1.400" +#define CKDB_VERSION DB_VERSION"-1.401" #define WHERE_FFL " - from %s %s() line %d" #define WHERE_FFL_HERE __FILE__, __func__, __LINE__ @@ -2353,6 +2353,7 @@ extern cmp_t cmp_payouts(K_ITEM *a, K_ITEM *b); extern cmp_t cmp_payouts_id(K_ITEM *a, K_ITEM *b); extern cmp_t cmp_payouts_wid(K_ITEM *a, K_ITEM *b); extern K_ITEM *find_payouts(int32_t height, char *blockhash); +extern K_ITEM *first_payouts(int32_t height, K_TREE_CTX *ctx); extern K_ITEM *find_last_payouts(); extern K_ITEM *find_payoutid(int64_t payoutid); extern K_ITEM *find_payouts_wid(int64_t workinfoidend, K_TREE_CTX *ctx); diff --git a/src/ckdb_cmd.c b/src/ckdb_cmd.c index d7bed90e..2a6fd845 100644 --- a/src/ckdb_cmd.c +++ b/src/ckdb_cmd.c @@ -7036,6 +7036,127 @@ static char *cmd_query(__maybe_unused PGconn *conn, char *cmd, char *id, "WorkinfoRange", FLDSEP, "", FLDSEP); APPEND_REALLOC(buf, off, len, tmp); + ok = true; + } else if (strcasecmp(request, "payout") == 0) { + /* return the details of the payouts for block height=height + * if expired= is present, also return expired records */ + K_ITEM *i_height, *i_expired, *p_item; + PAYOUTS *payouts = NULL; + bool expired = false; + int32_t height; + char *stats = NULL, *ptr; + + i_height = require_name(trf_root, "height", + 1, (char *)intpatt, + reply, siz); + if (!i_height) + return strdup(reply); + TXT_TO_INT("height", transfer_data(i_height), height); + + int_to_buf(height, reply, sizeof(reply)); + snprintf(msg, sizeof(msg), "height=%s", reply); + + i_expired = optional_name(trf_root, "expired", + 0, NULL, reply, siz); + if (i_expired) + expired = true; + + K_RLOCK(payouts_free); + p_item = first_payouts(height, ctx); + DATA_PAYOUTS_NULL(payouts, p_item); + while (p_item && payouts->height == height) { + if (expired || CURRENT(&(payouts->expirydate))) { + int_to_buf(payouts->height, + reply, sizeof(reply)); + snprintf(tmp, sizeof(tmp), + "height:%d=%s%c", + rows, reply, FLDSEP); + APPEND_REALLOC(buf, off, len, tmp); + bigint_to_buf(payouts->payoutid, + reply, sizeof(reply)); + snprintf(tmp, sizeof(tmp), + "payoutid:%d=%s%c", + rows, reply, FLDSEP); + APPEND_REALLOC(buf, off, len, tmp); + bigint_to_buf(payouts->minerreward, + reply, sizeof(reply)); + snprintf(tmp, sizeof(tmp), + "minerreward:%d=%s%c", + rows, reply, FLDSEP); + APPEND_REALLOC(buf, off, len, tmp); + bigint_to_buf(payouts->workinfoidstart, + reply, sizeof(reply)); + snprintf(tmp, sizeof(tmp), + "workinfoidstart:%d=%s%c", + rows, reply, FLDSEP); + APPEND_REALLOC(buf, off, len, tmp); + bigint_to_buf(payouts->workinfoidend, + reply, sizeof(reply)); + snprintf(tmp, sizeof(tmp), + "workinfoidend:%d=%s%c", + rows, reply, FLDSEP); + APPEND_REALLOC(buf, off, len, tmp); + bigint_to_buf(payouts->elapsed, + reply, sizeof(reply)); + snprintf(tmp, sizeof(tmp), + "elapsed:%d=%s%c", + rows, reply, FLDSEP); + APPEND_REALLOC(buf, off, len, tmp); + snprintf(tmp, sizeof(tmp), + "status:%d=%s%c", + rows, payouts->status, FLDSEP); + APPEND_REALLOC(buf, off, len, tmp); + snprintf(tmp, sizeof(tmp), + "diffwanted:%d=%f%c", + rows, payouts->diffwanted, FLDSEP); + APPEND_REALLOC(buf, off, len, tmp); + snprintf(tmp, sizeof(tmp), + "diffused:%d=%f%c", + rows, payouts->diffused, FLDSEP); + APPEND_REALLOC(buf, off, len, tmp); + ptr = stats = strdup(payouts->stats); + if (!stats) { + quithere(1, "strdup (%"PRId64") OOM", + payouts->payoutid); + } + while (*ptr) { + if (*ptr == FLDSEP) + *ptr = ' '; + ptr++; + } + snprintf(tmp, sizeof(tmp), + "stats:%d=%s%c", + rows, stats, FLDSEP); + APPEND_REALLOC(buf, off, len, tmp); + FREENULL(stats); + tv_to_buf(&(payouts->expirydate), cd_buf, + sizeof(cd_buf)); + snprintf(tmp, sizeof(tmp), + EDDB"_str:%d=%s%c", + rows, cd_buf, FLDSEP); + APPEND_REALLOC(buf, off, len, tmp); + tv_to_buf(&(payouts->createdate), cd_buf, + sizeof(cd_buf)); + snprintf(tmp, sizeof(tmp), + CDDB"_str:%d=%s%c", + rows, cd_buf, FLDSEP); + APPEND_REALLOC(buf, off, len, tmp); + rows++; + } + p_item = next_in_ktree(ctx); + DATA_PAYOUTS_NULL(payouts, p_item); + } + + snprintf(tmp, sizeof(tmp), "flds=%s%c", + "height,payoutid,minerreward,workinfoidstart," + "workinfoidend,elapsed,status,diffwanted,diffused," + "stats,"EDDB"_str,"CDDB"_str", + FLDSEP); + APPEND_REALLOC(buf, off, len, tmp); + snprintf(tmp, sizeof(tmp), "arn=%s%carp=%s%c", + "Payouts", FLDSEP, "", FLDSEP); + APPEND_REALLOC(buf, off, len, tmp); + ok = true; } else { free(buf); diff --git a/src/ckdb_data.c b/src/ckdb_data.c index 95d38469..5a98946e 100644 --- a/src/ckdb_data.c +++ b/src/ckdb_data.c @@ -3405,6 +3405,25 @@ K_ITEM *find_payouts(int32_t height, char *blockhash) return find_in_ktree(payouts_root, &look, ctx); } +// The first (any state) payouts record with the given height +K_ITEM *first_payouts(int32_t height, K_TREE_CTX *ctx) +{ + PAYOUTS payouts; + K_TREE_CTX ctx0[1]; + K_ITEM look; + + if (ctx == NULL) + ctx = ctx0; + + payouts.height = height; + payouts.blockhash[0] = '\0'; + DATE_ZERO(&(payouts.expirydate)); + + INIT_PAYOUTS(&look); + look.data = (void *)(&payouts); + return find_after_in_ktree(payouts_root, &look, ctx); +} + // Last block payout calculated K_ITEM *find_last_payouts() {