stats: hashrate averages
This commit is contained in:
parent
4fbbed9523
commit
5e5c1f0dfd
220
src/pool.c
220
src/pool.c
|
@ -135,6 +135,17 @@ enum msgbin_type { BIN_PING, BIN_CONNECT, BIN_DISCONNECT, BIN_SHARE,
|
|||
BIN_BLOCK, BIN_STATS, BIN_BALANCE };
|
||||
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
|
||||
{
|
||||
char rpc_host[MAX_HOST];
|
||||
|
@ -208,23 +219,25 @@ typedef struct client_t
|
|||
char agent[256];
|
||||
bstack_t *active_jobs;
|
||||
uint64_t hashes;
|
||||
hr_stats_t hr_stats;
|
||||
time_t connected_since;
|
||||
bool is_xnp;
|
||||
uint32_t mode;
|
||||
uint8_t bad_shares;
|
||||
bool downstream;
|
||||
uint32_t downstream_miners;
|
||||
uint32_t downstream_accounts;
|
||||
UT_hash_handle hh;
|
||||
} client_t;
|
||||
|
||||
typedef struct account_stats_t
|
||||
typedef struct account_t
|
||||
{
|
||||
char address[ADDRESS_MAX];
|
||||
size_t worker_count;
|
||||
time_t connected_since;
|
||||
uint64_t hashes;
|
||||
hr_stats_t hr_stats;
|
||||
UT_hash_handle hh;
|
||||
} account_stats_t;
|
||||
} account_t;
|
||||
|
||||
typedef struct share_t
|
||||
{
|
||||
|
@ -303,8 +316,8 @@ static time_t upstream_last_time;
|
|||
static uint64_t upstream_last_height;
|
||||
static uint32_t miner_count;
|
||||
static client_t *clients_by_fd = NULL;
|
||||
static account_stats_t *account_stats = NULL;
|
||||
static gbag_t *bag_stats;
|
||||
static account_t *accounts = NULL;
|
||||
static gbag_t *bag_accounts;
|
||||
static gbag_t *bag_clients;
|
||||
|
||||
#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 *
|
||||
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;
|
||||
}
|
||||
|
||||
uint64_t
|
||||
miner_hr(const char *address)
|
||||
void
|
||||
account_hr(double *avg, const char *address)
|
||||
{
|
||||
uint64_t hr = 0;
|
||||
double d = 0.0;
|
||||
account_stats_t *stats = NULL;
|
||||
account_t *account = NULL;
|
||||
pthread_rwlock_rdlock(&rwlock_acc);
|
||||
HASH_FIND_STR(account_stats, address, stats);
|
||||
if (!stats || !stats->connected_since || !stats->hashes)
|
||||
HASH_FIND_STR(accounts, address, account);
|
||||
if (!account)
|
||||
goto bail;
|
||||
d = difftime(time(NULL), stats->connected_since);
|
||||
if (d == 0.0)
|
||||
goto bail;
|
||||
hr = stats->hashes / d;
|
||||
memcpy(avg, account->hr_stats.avg, sizeof(account->hr_stats.avg));
|
||||
bail:
|
||||
pthread_rwlock_unlock(&rwlock_acc);
|
||||
return hr;
|
||||
}
|
||||
|
||||
uint64_t
|
||||
miner_balance(const char *address)
|
||||
account_balance(const char *address)
|
||||
{
|
||||
int rc;
|
||||
char *err;
|
||||
|
@ -954,14 +992,9 @@ static void
|
|||
update_pool_hr(void)
|
||||
{
|
||||
uint64_t hr = 0;
|
||||
client_t *c = (client_t*) gbag_first(bag_clients);
|
||||
while ((c = gbag_next(bag_clients,NULL)))
|
||||
{
|
||||
double d = difftime(time(NULL), c->connected_since);
|
||||
if (d == 0.0)
|
||||
continue;
|
||||
hr += c->hashes / d;
|
||||
}
|
||||
client_t *c = (client_t*)gbag_first(bag_clients);
|
||||
while ((c = gbag_next(bag_clients, 0)))
|
||||
hr += (uint64_t) c->hr_stats.avg[0];
|
||||
log_debug("Pool hashrate: %"PRIu64, hr);
|
||||
if (upstream_event)
|
||||
return;
|
||||
|
@ -1358,14 +1391,14 @@ miner_send_job(client_t *client, bool response)
|
|||
}
|
||||
|
||||
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;
|
||||
s = (account_stats_t*) items;
|
||||
account_t *s, *e, *r;
|
||||
s = (account_t*) items;
|
||||
e = s + count;
|
||||
pthread_rwlock_wrlock(&rwlock_acc);
|
||||
while (s<e)
|
||||
HASH_REPLACE_STR(account_stats, address, s, r);
|
||||
HASH_REPLACE_STR(accounts, address, s, r);
|
||||
pthread_rwlock_unlock(&rwlock_acc);
|
||||
}
|
||||
|
||||
|
@ -1385,7 +1418,7 @@ static void
|
|||
clients_send_job(void)
|
||||
{
|
||||
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)
|
||||
continue;
|
||||
|
@ -1396,8 +1429,8 @@ clients_send_job(void)
|
|||
static void
|
||||
clients_init(void)
|
||||
{
|
||||
gbag_new(&bag_stats, CLIENTS_INIT, sizeof(account_stats_t), 0,
|
||||
account_stats_moved);
|
||||
gbag_new(&bag_accounts, CLIENTS_INIT, sizeof(account_t), 0,
|
||||
accounts_moved);
|
||||
gbag_new(&bag_clients, CLIENTS_INIT, sizeof(client_t), 0,
|
||||
clients_moved);
|
||||
}
|
||||
|
@ -1405,11 +1438,11 @@ clients_init(void)
|
|||
static void
|
||||
clients_free(void)
|
||||
{
|
||||
if (!(bag_stats && bag_clients))
|
||||
if (!(bag_accounts && bag_clients))
|
||||
return;
|
||||
|
||||
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)
|
||||
continue;
|
||||
|
@ -1421,8 +1454,8 @@ clients_free(void)
|
|||
pthread_rwlock_unlock(&rwlock_cfd);
|
||||
|
||||
pthread_rwlock_wrlock(&rwlock_acc);
|
||||
HASH_CLEAR(hh, account_stats);
|
||||
gbag_free(bag_stats);
|
||||
HASH_CLEAR(hh, accounts);
|
||||
gbag_free(bag_accounts);
|
||||
pthread_rwlock_unlock(&rwlock_acc);
|
||||
}
|
||||
|
||||
|
@ -2119,7 +2152,7 @@ send_payments(void)
|
|||
return rc;
|
||||
}
|
||||
|
||||
gbag_t *bag_pay;
|
||||
gbag_t *bag_pay = NULL;
|
||||
gbag_new(&bag_pay, 25, sizeof(payment_t), 0, 0);
|
||||
|
||||
MDB_cursor_op op = MDB_FIRST;
|
||||
|
@ -2158,7 +2191,7 @@ send_payments(void)
|
|||
"\"transfer_split\",\"params\":{"
|
||||
"\"ring_size\":11,\"destinations\":[", end);
|
||||
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, p->address, end);
|
||||
|
@ -2274,7 +2307,7 @@ trusted_send_balance(client_t *client, const char *address)
|
|||
int t = BIN_BALANCE;
|
||||
memcpy(data, msgbin, 8);
|
||||
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+sizeof(uint64_t), address, ADDRESS_MAX);
|
||||
evbuffer_add(output, data, z);
|
||||
|
@ -2293,7 +2326,7 @@ upstream_send_ping()
|
|||
}
|
||||
|
||||
static void
|
||||
upstream_send_client_connect(uint32_t count)
|
||||
upstream_send_account_connect(uint32_t count)
|
||||
{
|
||||
struct evbuffer *output = bufferevent_get_output(upstream_event);
|
||||
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+9, &count, z-9);
|
||||
evbuffer_add(output, data, z);
|
||||
log_trace("Sending message connect upstream");
|
||||
log_trace("Sending message account connect upstream");
|
||||
}
|
||||
|
||||
static void
|
||||
upstream_send_client_disconnect()
|
||||
upstream_send_account_disconnect()
|
||||
{
|
||||
struct evbuffer *output = bufferevent_get_output(upstream_event);
|
||||
char data[9];
|
||||
|
@ -2447,37 +2480,37 @@ upstream_send_backlog()
|
|||
mdb_cursor_close(curshr);
|
||||
mdb_cursor_close(curblk);
|
||||
mdb_txn_abort(txn);
|
||||
upstream_send_client_connect(pool_stats.connected_miners);
|
||||
upstream_send_account_connect(pool_stats.connected_accounts);
|
||||
}
|
||||
|
||||
static void
|
||||
trusted_on_client_connect(client_t *client)
|
||||
trusted_on_account_connect(client_t *client)
|
||||
{
|
||||
struct evbuffer *input = bufferevent_get_input(client->bev);
|
||||
uint32_t count;
|
||||
evbuffer_remove(input, &count, sizeof(uint32_t));
|
||||
pool_stats.connected_miners += count;
|
||||
client->downstream_miners += count;
|
||||
log_trace("Downstream miner connected. "
|
||||
"Miner count: %d, Pool hashrate: %"PRIu64,
|
||||
pool_stats.connected_miners, pool_stats.pool_hashrate);
|
||||
pool_stats.connected_accounts += count;
|
||||
client->downstream_accounts += count;
|
||||
log_trace("Downstream account connected. "
|
||||
"Accounts: %d, Pool hashrate: %"PRIu64,
|
||||
pool_stats.connected_accounts, pool_stats.pool_hashrate);
|
||||
trusted_send_stats(client);
|
||||
if (upstream_event)
|
||||
upstream_send_client_connect(count);
|
||||
upstream_send_account_connect(count);
|
||||
}
|
||||
|
||||
static void
|
||||
trusted_on_client_disconnect(client_t *client)
|
||||
trusted_on_account_disconnect(client_t *client)
|
||||
{
|
||||
pool_stats.connected_miners--;
|
||||
if (client->downstream_miners)
|
||||
client->downstream_miners--;
|
||||
log_trace("Downstream miner disconnected. "
|
||||
pool_stats.connected_accounts--;
|
||||
if (client->downstream_accounts)
|
||||
client->downstream_accounts--;
|
||||
log_trace("Downstream account disconnected. "
|
||||
"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);
|
||||
if (upstream_event)
|
||||
upstream_send_client_disconnect();
|
||||
upstream_send_account_disconnect();
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -2494,6 +2527,8 @@ trusted_on_client_share(client_t *client)
|
|||
s.difficulty);
|
||||
client->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);
|
||||
if (rc != 0)
|
||||
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));
|
||||
log_trace("Stats from upstream: "
|
||||
"%d, %"PRIu64", %"PRIu64", %d, %"PRIu64,
|
||||
pool_stats.connected_miners,
|
||||
pool_stats.connected_accounts,
|
||||
pool_stats.pool_hashrate,
|
||||
pool_stats.round_hashes,
|
||||
pool_stats.pool_blocks_found,
|
||||
|
@ -2633,9 +2668,9 @@ upstream_on_event(struct bufferevent *bev, short error, void *ctx)
|
|||
log_debug("Upstream timeout");
|
||||
}
|
||||
/* 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();
|
||||
}
|
||||
/* Wait and try to reconnect */
|
||||
|
@ -2767,26 +2802,26 @@ client_clear(struct bufferevent *bev)
|
|||
if (!client)
|
||||
return;
|
||||
client_clear_jobs(client);
|
||||
account_stats_t *stats = NULL;
|
||||
account_t *account = NULL;
|
||||
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);
|
||||
if (stats && stats->worker_count == 1)
|
||||
if (account && account->worker_count == 1)
|
||||
{
|
||||
if (client->downstream)
|
||||
pool_stats.connected_miners -= client->downstream_miners;
|
||||
pool_stats.connected_accounts -= client->downstream_accounts;
|
||||
else
|
||||
pool_stats.connected_miners--;
|
||||
pool_stats.connected_accounts--;
|
||||
if (upstream_event)
|
||||
upstream_send_client_disconnect();
|
||||
upstream_send_account_disconnect();
|
||||
miner_count--;
|
||||
pthread_rwlock_wrlock(&rwlock_acc);
|
||||
HASH_DEL(account_stats, stats);
|
||||
HASH_DEL(accounts, account);
|
||||
pthread_rwlock_unlock(&rwlock_acc);
|
||||
gbag_put(bag_stats, stats);
|
||||
gbag_put(bag_accounts, account);
|
||||
}
|
||||
else if (stats && stats->worker_count > 1)
|
||||
stats->worker_count--;
|
||||
else if (account && account->worker_count > 1)
|
||||
account->worker_count--;
|
||||
pthread_rwlock_wrlock(&rwlock_cfd);
|
||||
HASH_DEL(clients_by_fd, client);
|
||||
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->worker_id, worker_id, sizeof(client->worker_id)-1);
|
||||
account_stats_t *stats = NULL;
|
||||
account_t *account = NULL;
|
||||
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);
|
||||
if (!stats)
|
||||
if (!account)
|
||||
{
|
||||
miner_count++;
|
||||
if (!client->downstream)
|
||||
pool_stats.connected_miners++;
|
||||
pool_stats.connected_accounts++;
|
||||
if (upstream_event)
|
||||
upstream_send_client_connect(1);
|
||||
stats = gbag_get(bag_stats);
|
||||
strncpy(stats->address, address, sizeof(stats->address)-1);
|
||||
stats->worker_count = 1;
|
||||
stats->connected_since = time(NULL);
|
||||
stats->hashes = 0;
|
||||
upstream_send_account_connect(1);
|
||||
account = gbag_get(bag_accounts);
|
||||
strncpy(account->address, address, sizeof(account->address)-1);
|
||||
account->worker_count = 1;
|
||||
account->connected_since = time(NULL);
|
||||
account->hashes = 0;
|
||||
pthread_rwlock_wrlock(&rwlock_acc);
|
||||
HASH_ADD_STR(account_stats, address, stats);
|
||||
HASH_ADD_STR(accounts, address, account);
|
||||
pthread_rwlock_unlock(&rwlock_acc);
|
||||
}
|
||||
else
|
||||
stats->worker_count++;
|
||||
account->worker_count++;
|
||||
uuid_t cid;
|
||||
uuid_generate(cid);
|
||||
bin_to_hex((const unsigned char*)cid, sizeof(uuid_t),
|
||||
|
@ -3189,12 +3224,17 @@ post_hash:
|
|||
BN_free(rh);
|
||||
|
||||
/* Process share */
|
||||
account_stats_t *stats = NULL;
|
||||
account_t *account = NULL;
|
||||
pthread_rwlock_rdlock(&rwlock_acc);
|
||||
HASH_FIND_STR(account_stats, client->address, stats);
|
||||
pthread_rwlock_unlock(&rwlock_acc);
|
||||
stats->hashes += job->target;
|
||||
HASH_FIND_STR(accounts, client->address, account);
|
||||
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);
|
||||
bool can_store = true;
|
||||
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))
|
||||
goto unlock;
|
||||
evbuffer_drain(input, 9);
|
||||
trusted_on_client_connect(client);
|
||||
trusted_on_account_connect(client);
|
||||
break;
|
||||
case BIN_DISCONNECT:
|
||||
evbuffer_drain(input, 9);
|
||||
trusted_on_client_disconnect(client);
|
||||
trusted_on_account_disconnect(client);
|
||||
break;
|
||||
case BIN_SHARE:
|
||||
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);
|
||||
client_add(fd, bev, base == trusted_base);
|
||||
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);
|
||||
}
|
||||
|
||||
|
|
|
@ -35,7 +35,7 @@ developers.
|
|||
#ifndef POOL_H
|
||||
#define POOL_H
|
||||
|
||||
uint64_t miner_hr(const char *address);
|
||||
uint64_t miner_balance(const char *address);
|
||||
void account_hr(double *avg, const char *address);
|
||||
uint64_t account_balance(const char *address);
|
||||
|
||||
#endif
|
||||
|
|
15
src/webui.c
15
src/webui.c
|
@ -75,7 +75,7 @@ send_json_stats(struct evhttp_request *req, void *arg)
|
|||
uint32_t pbf = context->pool_stats->pool_blocks_found;
|
||||
uint64_t rh = context->pool_stats->round_hashes;
|
||||
unsigned ss = context->allow_self_select;
|
||||
uint64_t mh = 0;
|
||||
double mh[6] = {0};
|
||||
double mb = 0.0;
|
||||
|
||||
hdrs_in = evhttp_request_get_input_headers(req);
|
||||
|
@ -86,8 +86,8 @@ send_json_stats(struct evhttp_request *req, void *arg)
|
|||
if (wa)
|
||||
{
|
||||
wa += 3;
|
||||
mh = miner_hr(wa);
|
||||
uint64_t balance = miner_balance(wa);
|
||||
account_hr(mh, wa);
|
||||
uint64_t balance = account_balance(wa);
|
||||
mb = (double) balance / 1000000000000.0;
|
||||
}
|
||||
}
|
||||
|
@ -108,12 +108,17 @@ send_json_stats(struct evhttp_request *req, void *arg)
|
|||
"\"allow_self_select\":%u,"
|
||||
"\"connected_miners\":%d,"
|
||||
"\"miner_hashrate\":%"PRIu64","
|
||||
"\"miner_hashrate_stats\":["
|
||||
"%"PRIu64",%"PRIu64",%"PRIu64","
|
||||
"%"PRIu64",%"PRIu64",%"PRIu64"],"
|
||||
"\"miner_balance\":%.8f"
|
||||
"}", ph, rh, nh, nd, height, ltf, lbf, pbf,
|
||||
context->payment_threshold, context->pool_fee,
|
||||
context->pool_port, context->pool_ssl_port,
|
||||
ss, context->pool_stats->connected_miners,
|
||||
mh, mb);
|
||||
ss, context->pool_stats->connected_accounts,
|
||||
(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);
|
||||
evhttp_add_header(hdrs_out, "Content-Type", "application/json");
|
||||
evhttp_send_reply(req, HTTP_OK, "OK", buf);
|
||||
|
|
|
@ -40,7 +40,7 @@ typedef struct pool_stats_t
|
|||
uint64_t network_difficulty;
|
||||
uint64_t network_hashrate;
|
||||
uint64_t network_height;
|
||||
uint32_t connected_miners;
|
||||
uint32_t connected_accounts;
|
||||
uint64_t pool_hashrate;
|
||||
uint64_t round_hashes;
|
||||
uint32_t pool_blocks_found;
|
||||
|
|
Loading…
Reference in New Issue