stats: hashrate averages

This commit is contained in:
Jethro Grassie 2020-09-01 20:40:14 -04:00
parent 4fbbed9523
commit 5e5c1f0dfd
No known key found for this signature in database
GPG Key ID: DE8ED755616565BB
4 changed files with 143 additions and 98 deletions

View File

@ -135,6 +135,17 @@ enum msgbin_type { BIN_PING, BIN_CONNECT, BIN_DISCONNECT, BIN_SHARE,
BIN_BLOCK, BIN_STATS, BIN_BALANCE }; BIN_BLOCK, BIN_STATS, BIN_BALANCE };
const unsigned char msgbin[] = {0x4D,0x4E,0x52,0x4F,0x50,0x4F,0x4F,0x4C}; const unsigned char msgbin[] = {0x4D,0x4E,0x52,0x4F,0x50,0x4F,0x4F,0x4C};
/* 2m, 10m, 30m, 1h, 1d, 1w */
const unsigned hr_intervals[] = {120,600,1800,3600,86400,604800};
typedef struct hr_stats_t
{
time_t last_calc;
uint64_t diff_since;
/* 2m, 10m, 30m, 1h, 1d, 1w */
double avg[6];
} hr_stats_t;
typedef struct config_t typedef struct config_t
{ {
char rpc_host[MAX_HOST]; char rpc_host[MAX_HOST];
@ -208,23 +219,25 @@ typedef struct client_t
char agent[256]; char agent[256];
bstack_t *active_jobs; bstack_t *active_jobs;
uint64_t hashes; uint64_t hashes;
hr_stats_t hr_stats;
time_t connected_since; time_t connected_since;
bool is_xnp; bool is_xnp;
uint32_t mode; uint32_t mode;
uint8_t bad_shares; uint8_t bad_shares;
bool downstream; bool downstream;
uint32_t downstream_miners; uint32_t downstream_accounts;
UT_hash_handle hh; UT_hash_handle hh;
} client_t; } client_t;
typedef struct account_stats_t typedef struct account_t
{ {
char address[ADDRESS_MAX]; char address[ADDRESS_MAX];
size_t worker_count; size_t worker_count;
time_t connected_since; time_t connected_since;
uint64_t hashes; uint64_t hashes;
hr_stats_t hr_stats;
UT_hash_handle hh; UT_hash_handle hh;
} account_stats_t; } account_t;
typedef struct share_t typedef struct share_t
{ {
@ -303,8 +316,8 @@ static time_t upstream_last_time;
static uint64_t upstream_last_height; static uint64_t upstream_last_height;
static uint32_t miner_count; static uint32_t miner_count;
static client_t *clients_by_fd = NULL; static client_t *clients_by_fd = NULL;
static account_stats_t *account_stats = NULL; static account_t *accounts = NULL;
static gbag_t *bag_stats; static gbag_t *bag_accounts;
static gbag_t *bag_clients; static gbag_t *bag_clients;
#ifdef HAVE_RX #ifdef HAVE_RX
@ -336,6 +349,37 @@ void rx_slow_hash_free_state(){}
} \ } \
} }
static void
hr_update(hr_stats_t *stats)
{
/*
Update some time decayed EMA hashrates.
*/
time_t now = time(NULL);
double t = difftime(now, stats->last_calc);
if (t <= 0)
return;
double h = stats->diff_since;
double d, p, z;
unsigned i = sizeof(hr_intervals)/sizeof(hr_intervals[0]);
while (i--)
{
unsigned inter = hr_intervals[i];
double *f = &stats->avg[i];
d = t/inter;
if (d > 32)
d = 32;
p = 1 - 1.0 / exp(d);
z = 1 + p;
*f += (h / t * p);
*f /= z;
if (*f < 2e-16)
*f = 0;
}
stats->diff_since = 0;
stats->last_calc = now;
}
static inline rpc_callback_t * static inline rpc_callback_t *
rpc_callback_new(rpc_callback_fun cf, void *data, rpc_datafree_fun df) rpc_callback_new(rpc_callback_fun cf, void *data, rpc_datafree_fun df)
{ {
@ -628,27 +672,21 @@ store_block(uint64_t height, block_t *block)
return rc; return rc;
} }
uint64_t void
miner_hr(const char *address) account_hr(double *avg, const char *address)
{ {
uint64_t hr = 0; account_t *account = NULL;
double d = 0.0;
account_stats_t *stats = NULL;
pthread_rwlock_rdlock(&rwlock_acc); pthread_rwlock_rdlock(&rwlock_acc);
HASH_FIND_STR(account_stats, address, stats); HASH_FIND_STR(accounts, address, account);
if (!stats || !stats->connected_since || !stats->hashes) if (!account)
goto bail; goto bail;
d = difftime(time(NULL), stats->connected_since); memcpy(avg, account->hr_stats.avg, sizeof(account->hr_stats.avg));
if (d == 0.0)
goto bail;
hr = stats->hashes / d;
bail: bail:
pthread_rwlock_unlock(&rwlock_acc); pthread_rwlock_unlock(&rwlock_acc);
return hr;
} }
uint64_t uint64_t
miner_balance(const char *address) account_balance(const char *address)
{ {
int rc; int rc;
char *err; char *err;
@ -954,14 +992,9 @@ static void
update_pool_hr(void) update_pool_hr(void)
{ {
uint64_t hr = 0; uint64_t hr = 0;
client_t *c = (client_t*) gbag_first(bag_clients); client_t *c = (client_t*)gbag_first(bag_clients);
while ((c = gbag_next(bag_clients,NULL))) while ((c = gbag_next(bag_clients, 0)))
{ hr += (uint64_t) c->hr_stats.avg[0];
double d = difftime(time(NULL), c->connected_since);
if (d == 0.0)
continue;
hr += c->hashes / d;
}
log_debug("Pool hashrate: %"PRIu64, hr); log_debug("Pool hashrate: %"PRIu64, hr);
if (upstream_event) if (upstream_event)
return; return;
@ -1358,14 +1391,14 @@ miner_send_job(client_t *client, bool response)
} }
static void static void
account_stats_moved(const void *items, size_t count) accounts_moved(const void *items, size_t count)
{ {
account_stats_t *s, *e, *r; account_t *s, *e, *r;
s = (account_stats_t*) items; s = (account_t*) items;
e = s + count; e = s + count;
pthread_rwlock_wrlock(&rwlock_acc); pthread_rwlock_wrlock(&rwlock_acc);
while (s<e) while (s<e)
HASH_REPLACE_STR(account_stats, address, s, r); HASH_REPLACE_STR(accounts, address, s, r);
pthread_rwlock_unlock(&rwlock_acc); pthread_rwlock_unlock(&rwlock_acc);
} }
@ -1385,7 +1418,7 @@ static void
clients_send_job(void) clients_send_job(void)
{ {
client_t *c = (client_t*) gbag_first(bag_clients); client_t *c = (client_t*) gbag_first(bag_clients);
while ((c = gbag_next(bag_clients,NULL))) while ((c = gbag_next(bag_clients, 0)))
{ {
if (c->fd == 0 || c->address[0] == 0 || c->downstream) if (c->fd == 0 || c->address[0] == 0 || c->downstream)
continue; continue;
@ -1396,8 +1429,8 @@ clients_send_job(void)
static void static void
clients_init(void) clients_init(void)
{ {
gbag_new(&bag_stats, CLIENTS_INIT, sizeof(account_stats_t), 0, gbag_new(&bag_accounts, CLIENTS_INIT, sizeof(account_t), 0,
account_stats_moved); accounts_moved);
gbag_new(&bag_clients, CLIENTS_INIT, sizeof(client_t), 0, gbag_new(&bag_clients, CLIENTS_INIT, sizeof(client_t), 0,
clients_moved); clients_moved);
} }
@ -1405,11 +1438,11 @@ clients_init(void)
static void static void
clients_free(void) clients_free(void)
{ {
if (!(bag_stats && bag_clients)) if (!(bag_accounts && bag_clients))
return; return;
client_t *c = (client_t*) gbag_first(bag_clients); client_t *c = (client_t*) gbag_first(bag_clients);
while ((c = gbag_next(bag_clients,NULL))) while ((c = gbag_next(bag_clients, 0)))
{ {
if (!c->active_jobs) if (!c->active_jobs)
continue; continue;
@ -1421,8 +1454,8 @@ clients_free(void)
pthread_rwlock_unlock(&rwlock_cfd); pthread_rwlock_unlock(&rwlock_cfd);
pthread_rwlock_wrlock(&rwlock_acc); pthread_rwlock_wrlock(&rwlock_acc);
HASH_CLEAR(hh, account_stats); HASH_CLEAR(hh, accounts);
gbag_free(bag_stats); gbag_free(bag_accounts);
pthread_rwlock_unlock(&rwlock_acc); pthread_rwlock_unlock(&rwlock_acc);
} }
@ -2119,7 +2152,7 @@ send_payments(void)
return rc; return rc;
} }
gbag_t *bag_pay; gbag_t *bag_pay = NULL;
gbag_new(&bag_pay, 25, sizeof(payment_t), 0, 0); gbag_new(&bag_pay, 25, sizeof(payment_t), 0, 0);
MDB_cursor_op op = MDB_FIRST; MDB_cursor_op op = MDB_FIRST;
@ -2158,7 +2191,7 @@ send_payments(void)
"\"transfer_split\",\"params\":{" "\"transfer_split\",\"params\":{"
"\"ring_size\":11,\"destinations\":[", end); "\"ring_size\":11,\"destinations\":[", end);
payment_t *p = (payment_t*) gbag_first(bag_pay); payment_t *p = (payment_t*) gbag_first(bag_pay);
while ((p = gbag_next(bag_pay, NULL))) while ((p = gbag_next(bag_pay, 0)))
{ {
start = stecpy(start, "{\"address\":\"", end); start = stecpy(start, "{\"address\":\"", end);
start = stecpy(start, p->address, end); start = stecpy(start, p->address, end);
@ -2274,7 +2307,7 @@ trusted_send_balance(client_t *client, const char *address)
int t = BIN_BALANCE; int t = BIN_BALANCE;
memcpy(data, msgbin, 8); memcpy(data, msgbin, 8);
memcpy(data+8, &t, 1); memcpy(data+8, &t, 1);
uint64_t balance = miner_balance(address); uint64_t balance = account_balance(address);
memcpy(data+9, &balance, sizeof(uint64_t)); memcpy(data+9, &balance, sizeof(uint64_t));
memcpy(data+9+sizeof(uint64_t), address, ADDRESS_MAX); memcpy(data+9+sizeof(uint64_t), address, ADDRESS_MAX);
evbuffer_add(output, data, z); evbuffer_add(output, data, z);
@ -2293,7 +2326,7 @@ upstream_send_ping()
} }
static void static void
upstream_send_client_connect(uint32_t count) upstream_send_account_connect(uint32_t count)
{ {
struct evbuffer *output = bufferevent_get_output(upstream_event); struct evbuffer *output = bufferevent_get_output(upstream_event);
size_t z = 9 + sizeof(uint32_t); size_t z = 9 + sizeof(uint32_t);
@ -2303,11 +2336,11 @@ upstream_send_client_connect(uint32_t count)
memcpy(data+8, &t, 1); memcpy(data+8, &t, 1);
memcpy(data+9, &count, z-9); memcpy(data+9, &count, z-9);
evbuffer_add(output, data, z); evbuffer_add(output, data, z);
log_trace("Sending message connect upstream"); log_trace("Sending message account connect upstream");
} }
static void static void
upstream_send_client_disconnect() upstream_send_account_disconnect()
{ {
struct evbuffer *output = bufferevent_get_output(upstream_event); struct evbuffer *output = bufferevent_get_output(upstream_event);
char data[9]; char data[9];
@ -2447,37 +2480,37 @@ upstream_send_backlog()
mdb_cursor_close(curshr); mdb_cursor_close(curshr);
mdb_cursor_close(curblk); mdb_cursor_close(curblk);
mdb_txn_abort(txn); mdb_txn_abort(txn);
upstream_send_client_connect(pool_stats.connected_miners); upstream_send_account_connect(pool_stats.connected_accounts);
} }
static void static void
trusted_on_client_connect(client_t *client) trusted_on_account_connect(client_t *client)
{ {
struct evbuffer *input = bufferevent_get_input(client->bev); struct evbuffer *input = bufferevent_get_input(client->bev);
uint32_t count; uint32_t count;
evbuffer_remove(input, &count, sizeof(uint32_t)); evbuffer_remove(input, &count, sizeof(uint32_t));
pool_stats.connected_miners += count; pool_stats.connected_accounts += count;
client->downstream_miners += count; client->downstream_accounts += count;
log_trace("Downstream miner connected. " log_trace("Downstream account connected. "
"Miner count: %d, Pool hashrate: %"PRIu64, "Accounts: %d, Pool hashrate: %"PRIu64,
pool_stats.connected_miners, pool_stats.pool_hashrate); pool_stats.connected_accounts, pool_stats.pool_hashrate);
trusted_send_stats(client); trusted_send_stats(client);
if (upstream_event) if (upstream_event)
upstream_send_client_connect(count); upstream_send_account_connect(count);
} }
static void static void
trusted_on_client_disconnect(client_t *client) trusted_on_account_disconnect(client_t *client)
{ {
pool_stats.connected_miners--; pool_stats.connected_accounts--;
if (client->downstream_miners) if (client->downstream_accounts)
client->downstream_miners--; client->downstream_accounts--;
log_trace("Downstream miner disconnected. " log_trace("Downstream account disconnected. "
"Miner count: %d, Pool hashrate: %"PRIu64, "Miner count: %d, Pool hashrate: %"PRIu64,
pool_stats.connected_miners, pool_stats.pool_hashrate); pool_stats.connected_accounts, pool_stats.pool_hashrate);
trusted_send_stats(client); trusted_send_stats(client);
if (upstream_event) if (upstream_event)
upstream_send_client_disconnect(); upstream_send_account_disconnect();
} }
static void static void
@ -2494,6 +2527,8 @@ trusted_on_client_share(client_t *client)
s.difficulty); s.difficulty);
client->hashes += s.difficulty; client->hashes += s.difficulty;
pool_stats.round_hashes += s.difficulty; pool_stats.round_hashes += s.difficulty;
client->hr_stats.diff_since += s.difficulty;
hr_update(&client->hr_stats);
rc = store_share(s.height, &s); rc = store_share(s.height, &s);
if (rc != 0) if (rc != 0)
log_warn("Failed to store share: %s", mdb_strerror(rc)); log_warn("Failed to store share: %s", mdb_strerror(rc));
@ -2529,7 +2564,7 @@ upstream_on_stats(struct bufferevent *bev)
evbuffer_remove(input, &pool_stats, sizeof(pool_stats_t)); evbuffer_remove(input, &pool_stats, sizeof(pool_stats_t));
log_trace("Stats from upstream: " log_trace("Stats from upstream: "
"%d, %"PRIu64", %"PRIu64", %d, %"PRIu64, "%d, %"PRIu64", %"PRIu64", %d, %"PRIu64,
pool_stats.connected_miners, pool_stats.connected_accounts,
pool_stats.pool_hashrate, pool_stats.pool_hashrate,
pool_stats.round_hashes, pool_stats.round_hashes,
pool_stats.pool_blocks_found, pool_stats.pool_blocks_found,
@ -2633,9 +2668,9 @@ upstream_on_event(struct bufferevent *bev, short error, void *ctx)
log_debug("Upstream timeout"); log_debug("Upstream timeout");
} }
/* Update stats due to upstream disconnect */ /* Update stats due to upstream disconnect */
if (pool_stats.connected_miners != miner_count) if (pool_stats.connected_accounts != miner_count)
{ {
pool_stats.connected_miners = miner_count; pool_stats.connected_accounts = miner_count;
update_pool_hr(); update_pool_hr();
} }
/* Wait and try to reconnect */ /* Wait and try to reconnect */
@ -2767,26 +2802,26 @@ client_clear(struct bufferevent *bev)
if (!client) if (!client)
return; return;
client_clear_jobs(client); client_clear_jobs(client);
account_stats_t *stats = NULL; account_t *account = NULL;
pthread_rwlock_rdlock(&rwlock_acc); pthread_rwlock_rdlock(&rwlock_acc);
HASH_FIND_STR(account_stats, client->address, stats); HASH_FIND_STR(accounts, client->address, account);
pthread_rwlock_unlock(&rwlock_acc); pthread_rwlock_unlock(&rwlock_acc);
if (stats && stats->worker_count == 1) if (account && account->worker_count == 1)
{ {
if (client->downstream) if (client->downstream)
pool_stats.connected_miners -= client->downstream_miners; pool_stats.connected_accounts -= client->downstream_accounts;
else else
pool_stats.connected_miners--; pool_stats.connected_accounts--;
if (upstream_event) if (upstream_event)
upstream_send_client_disconnect(); upstream_send_account_disconnect();
miner_count--; miner_count--;
pthread_rwlock_wrlock(&rwlock_acc); pthread_rwlock_wrlock(&rwlock_acc);
HASH_DEL(account_stats, stats); HASH_DEL(accounts, account);
pthread_rwlock_unlock(&rwlock_acc); pthread_rwlock_unlock(&rwlock_acc);
gbag_put(bag_stats, stats); gbag_put(bag_accounts, account);
} }
else if (stats && stats->worker_count > 1) else if (account && account->worker_count > 1)
stats->worker_count--; account->worker_count--;
pthread_rwlock_wrlock(&rwlock_cfd); pthread_rwlock_wrlock(&rwlock_cfd);
HASH_DEL(clients_by_fd, client); HASH_DEL(clients_by_fd, client);
pthread_rwlock_unlock(&rwlock_cfd); pthread_rwlock_unlock(&rwlock_cfd);
@ -2861,28 +2896,28 @@ miner_on_login(json_object *message, client_t *client)
strncpy(client->address, address, sizeof(client->address)-1); strncpy(client->address, address, sizeof(client->address)-1);
strncpy(client->worker_id, worker_id, sizeof(client->worker_id)-1); strncpy(client->worker_id, worker_id, sizeof(client->worker_id)-1);
account_stats_t *stats = NULL; account_t *account = NULL;
pthread_rwlock_rdlock(&rwlock_acc); pthread_rwlock_rdlock(&rwlock_acc);
HASH_FIND_STR(account_stats, client->address, stats); HASH_FIND_STR(accounts, client->address, account);
pthread_rwlock_unlock(&rwlock_acc); pthread_rwlock_unlock(&rwlock_acc);
if (!stats) if (!account)
{ {
miner_count++; miner_count++;
if (!client->downstream) if (!client->downstream)
pool_stats.connected_miners++; pool_stats.connected_accounts++;
if (upstream_event) if (upstream_event)
upstream_send_client_connect(1); upstream_send_account_connect(1);
stats = gbag_get(bag_stats); account = gbag_get(bag_accounts);
strncpy(stats->address, address, sizeof(stats->address)-1); strncpy(account->address, address, sizeof(account->address)-1);
stats->worker_count = 1; account->worker_count = 1;
stats->connected_since = time(NULL); account->connected_since = time(NULL);
stats->hashes = 0; account->hashes = 0;
pthread_rwlock_wrlock(&rwlock_acc); pthread_rwlock_wrlock(&rwlock_acc);
HASH_ADD_STR(account_stats, address, stats); HASH_ADD_STR(accounts, address, account);
pthread_rwlock_unlock(&rwlock_acc); pthread_rwlock_unlock(&rwlock_acc);
} }
else else
stats->worker_count++; account->worker_count++;
uuid_t cid; uuid_t cid;
uuid_generate(cid); uuid_generate(cid);
bin_to_hex((const unsigned char*)cid, sizeof(uuid_t), bin_to_hex((const unsigned char*)cid, sizeof(uuid_t),
@ -3189,12 +3224,17 @@ post_hash:
BN_free(rh); BN_free(rh);
/* Process share */ /* Process share */
account_stats_t *stats = NULL; account_t *account = NULL;
pthread_rwlock_rdlock(&rwlock_acc); pthread_rwlock_rdlock(&rwlock_acc);
HASH_FIND_STR(account_stats, client->address, stats); HASH_FIND_STR(accounts, client->address, account);
pthread_rwlock_unlock(&rwlock_acc);
stats->hashes += job->target;
client->hashes += job->target; client->hashes += job->target;
client->hr_stats.diff_since += job->target;
account->hashes += job->target;
account->hr_stats.diff_since += job->target;
hr_update(&client->hr_stats);
/* TODO: account hr should be called less freq */
hr_update(&account->hr_stats);
pthread_rwlock_unlock(&rwlock_acc);
time_t now = time(NULL); time_t now = time(NULL);
bool can_store = true; bool can_store = true;
log_trace("Checking hash against block difficulty: " log_trace("Checking hash against block difficulty: "
@ -3442,11 +3482,11 @@ trusted_on_read(struct bufferevent *bev, void *ctx)
if (len - 9 < sizeof(uint32_t)) if (len - 9 < sizeof(uint32_t))
goto unlock; goto unlock;
evbuffer_drain(input, 9); evbuffer_drain(input, 9);
trusted_on_client_connect(client); trusted_on_account_connect(client);
break; break;
case BIN_DISCONNECT: case BIN_DISCONNECT:
evbuffer_drain(input, 9); evbuffer_drain(input, 9);
trusted_on_client_disconnect(client); trusted_on_account_disconnect(client);
break; break;
case BIN_SHARE: case BIN_SHARE:
if (len - 9 < sizeof(share_t)) if (len - 9 < sizeof(share_t))
@ -3549,7 +3589,7 @@ listener_on_accept(evutil_socket_t listener, short event, void *arg)
bufferevent_setwatermark(bev, EV_READ, 0, MAX_LINE); bufferevent_setwatermark(bev, EV_READ, 0, MAX_LINE);
client_add(fd, bev, base == trusted_base); client_add(fd, bev, base == trusted_base);
log_info("New %s connected. Miner count: %d, Pool hashrate: %"PRIu64, log_info("New %s connected. Miner count: %d, Pool hashrate: %"PRIu64,
type, pool_stats.connected_miners, pool_stats.pool_hashrate); type, pool_stats.connected_accounts, pool_stats.pool_hashrate);
bufferevent_enable(bev, EV_READ|EV_WRITE); bufferevent_enable(bev, EV_READ|EV_WRITE);
} }

View File

@ -35,7 +35,7 @@ developers.
#ifndef POOL_H #ifndef POOL_H
#define POOL_H #define POOL_H
uint64_t miner_hr(const char *address); void account_hr(double *avg, const char *address);
uint64_t miner_balance(const char *address); uint64_t account_balance(const char *address);
#endif #endif

View File

@ -75,7 +75,7 @@ send_json_stats(struct evhttp_request *req, void *arg)
uint32_t pbf = context->pool_stats->pool_blocks_found; uint32_t pbf = context->pool_stats->pool_blocks_found;
uint64_t rh = context->pool_stats->round_hashes; uint64_t rh = context->pool_stats->round_hashes;
unsigned ss = context->allow_self_select; unsigned ss = context->allow_self_select;
uint64_t mh = 0; double mh[6] = {0};
double mb = 0.0; double mb = 0.0;
hdrs_in = evhttp_request_get_input_headers(req); hdrs_in = evhttp_request_get_input_headers(req);
@ -86,8 +86,8 @@ send_json_stats(struct evhttp_request *req, void *arg)
if (wa) if (wa)
{ {
wa += 3; wa += 3;
mh = miner_hr(wa); account_hr(mh, wa);
uint64_t balance = miner_balance(wa); uint64_t balance = account_balance(wa);
mb = (double) balance / 1000000000000.0; mb = (double) balance / 1000000000000.0;
} }
} }
@ -108,12 +108,17 @@ send_json_stats(struct evhttp_request *req, void *arg)
"\"allow_self_select\":%u," "\"allow_self_select\":%u,"
"\"connected_miners\":%d," "\"connected_miners\":%d,"
"\"miner_hashrate\":%"PRIu64"," "\"miner_hashrate\":%"PRIu64","
"\"miner_hashrate_stats\":["
"%"PRIu64",%"PRIu64",%"PRIu64","
"%"PRIu64",%"PRIu64",%"PRIu64"],"
"\"miner_balance\":%.8f" "\"miner_balance\":%.8f"
"}", ph, rh, nh, nd, height, ltf, lbf, pbf, "}", ph, rh, nh, nd, height, ltf, lbf, pbf,
context->payment_threshold, context->pool_fee, context->payment_threshold, context->pool_fee,
context->pool_port, context->pool_ssl_port, context->pool_port, context->pool_ssl_port,
ss, context->pool_stats->connected_miners, ss, context->pool_stats->connected_accounts,
mh, mb); (uint64_t)mh[0],
(uint64_t)mh[0], (uint64_t)mh[1], (uint64_t)mh[2],
(uint64_t)mh[3], (uint64_t)mh[4], (uint64_t)mh[5], mb);
hdrs_out = evhttp_request_get_output_headers(req); hdrs_out = evhttp_request_get_output_headers(req);
evhttp_add_header(hdrs_out, "Content-Type", "application/json"); evhttp_add_header(hdrs_out, "Content-Type", "application/json");
evhttp_send_reply(req, HTTP_OK, "OK", buf); evhttp_send_reply(req, HTTP_OK, "OK", buf);

View File

@ -40,7 +40,7 @@ typedef struct pool_stats_t
uint64_t network_difficulty; uint64_t network_difficulty;
uint64_t network_hashrate; uint64_t network_hashrate;
uint64_t network_height; uint64_t network_height;
uint32_t connected_miners; uint32_t connected_accounts;
uint64_t pool_hashrate; uint64_t pool_hashrate;
uint64_t round_hashes; uint64_t round_hashes;
uint32_t pool_blocks_found; uint32_t pool_blocks_found;