db/benchmarks: allow ccminer to report device stats

user password should contain "stats", made for ccminer 1.7.6+

will see to allow a special bench "test" account to allow devs to
easily test the stratum and fill benchmarks, for the moment, its
enabled while mining with the -p stats password option.
This commit is contained in:
Tanguy Pruvot 2016-05-15 03:39:54 +02:00
parent 035d3b3bf2
commit ed3cd5fb69
10 changed files with 200 additions and 2 deletions

View file

@ -0,0 +1,31 @@
-- Recent additions to add after db init (.gz)
-- mysql yaamp -p < file.sql
CREATE TABLE `benchmarks` (
`id` int(11) NOT NULL AUTO_INCREMENT PRIMARY KEY,
`algo` varchar(16) NOT NULL,
`type` varchar(8) NOT NULL,
`khps` double NULL,
`device` varchar(80) NULL,
`vendorid` varchar(12) NULL,
`arch` varchar(8) NULL,
`power` int(5) UNSIGNED NULL,
`freq` int(8) UNSIGNED NULL,
`memf` int(8) UNSIGNED NULL,
`client` varchar(48) NULL,
`os` varchar(8) NULL,
`driver` varchar(32) NULL,
`intensity` double NULL,
`throughput` int(11) UNSIGNED NULL,
`userid` int(11) NULL,
`time` int(10) UNSIGNED NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
-- KEYS & Indexes
ALTER TABLE `benchmarks`
ADD KEY `bench_userid` (`userid`),
ADD INDEX `ndx_type` (`type`),
ADD INDEX `ndx_algo` (`algo`),
ADD INDEX `ndx_time` (`time` DESC);

View file

@ -52,6 +52,9 @@ bool client_subscribe(YAAMP_CLIENT *client, json_value *json_params)
if(strstr(client->version, "NiceHash") || strstr(client->version, "proxy") || strstr(client->version, "/3.")) if(strstr(client->version, "NiceHash") || strstr(client->version, "proxy") || strstr(client->version, "/3."))
client->reconnectable = false; client->reconnectable = false;
if(strstr(client->version, "ccminer"))
client->stats = true;
} }
if(json_params->u.array.length>1) if(json_params->u.array.length>1)
@ -300,6 +303,38 @@ bool client_update_block(YAAMP_CLIENT *client, json_value *json_params)
/////////////////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////////////////
bool client_ask_stats(YAAMP_CLIENT *client)
{
int id;
if (!client->stats) return false;
if (!strstr(client->password, "stats")) return false;
//client_call(client, "client.get_stats", "[]");
id = client_ask(client, "client.get_version", "[\"stats\"]");
return true;
}
static bool client_store_stats(YAAMP_CLIENT *client, json_value *result)
{
if (json_typeof(result) != json_object)
return false;
json_value *val = json_get_val(result, "type");
if (val && json_is_string(val)) {
// debuglog("received stats of type %s\n", json_string_value(val));
if (!strcmp("gpu", json_string_value(val))) {
CommonLock(&g_db_mutex);
db_store_stats(g_db, client, result);
CommonUnlock(&g_db_mutex);
}
return true;
}
return false;
}
///////////////////////////////////////////////////////////////////////////////////////////
//YAAMP_SOURCE *source_init(YAAMP_CLIENT *client) //YAAMP_SOURCE *source_init(YAAMP_CLIENT *client)
//{ //{
// YAAMP_SOURCE *source = NULL; // YAAMP_SOURCE *source = NULL;
@ -414,6 +449,15 @@ void *client_thread(void *p)
client->id_str = json_get_string(json, "id"); client->id_str = json_get_string(json, "id");
const char *method = json_get_string(json, "method"); const char *method = json_get_string(json, "method");
if (!method && client->stats && client->id_int == client->reqid)
{
json_value *result = json_get_object(json, "result");
if (result) client_store_stats(client, result);
json_value_free(json);
continue;
}
if(!method) if(!method)
{ {
json_value_free(json); json_value_free(json);
@ -440,6 +484,9 @@ void *client_thread(void *p)
else if(!strcmp(method, "mining.authorize")) else if(!strcmp(method, "mining.authorize"))
b = client_authorize(client, json_params); b = client_authorize(client, json_params);
else if(!strcmp(method, "mining.ping"))
b = client_send_result(client, "\"pong\"");
else if(!strcmp(method, "mining.submit")) else if(!strcmp(method, "mining.submit"))
b = client_submit(client, json_params); b = client_submit(client, json_params);
@ -463,7 +510,7 @@ void *client_thread(void *p)
else if(!strcmp(method, "getwork")) else if(!strcmp(method, "getwork"))
{ {
clientlog(client, "using getwork"); clientlog(client, "using getwork"); // client using http:// url
break; break;
} }

View file

@ -38,6 +38,7 @@ public:
// YAAMP_SOURCE *source; // YAAMP_SOURCE *source;
char notify_id[1024]; char notify_id[1024];
int64_t reqid; // ask request id
int created; int created;
int last_best; int last_best;
@ -91,6 +92,9 @@ public:
YAAMP_CLIENT_ALGO algos_subscribed[YAAMP_MAXALGOS]; YAAMP_CLIENT_ALGO algos_subscribed[YAAMP_MAXALGOS];
int job_history[YAAMP_JOB_MAXHISTORY]; int job_history[YAAMP_JOB_MAXHISTORY];
int64_t shares;
int stats;
int donation; int donation;
}; };
@ -134,11 +138,15 @@ void client_initialize_difficulty(YAAMP_CLIENT *client);
////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////
int client_call(YAAMP_CLIENT *client, const char *method, const char *format, ...); int client_call(YAAMP_CLIENT *client, const char *method, const char *format, ...);
int client_ask(YAAMP_CLIENT *client, const char *method, const char *format, ...);
void client_dump_all(); void client_dump_all();
int client_send_result(YAAMP_CLIENT *client, const char *format, ...); int client_send_result(YAAMP_CLIENT *client, const char *format, ...);
int client_send_error(YAAMP_CLIENT *client, int error, const char *string); int client_send_error(YAAMP_CLIENT *client, int error, const char *string);
bool client_ask_stats(YAAMP_CLIENT *client);
bool client_submit(YAAMP_CLIENT *client, json_value *json_params); bool client_submit(YAAMP_CLIENT *client, json_value *json_params);
void *client_thread(void *p); void *client_thread(void *p);

View file

@ -100,6 +100,25 @@ int client_call(YAAMP_CLIENT *client, const char *method, const char *format, ..
return socket_send(client->sock, "{\"id\":null,\"method\":\"%s\",\"params\":%s}\n", method, buffer); return socket_send(client->sock, "{\"id\":null,\"method\":\"%s\",\"params\":%s}\n", method, buffer);
} }
int client_ask(YAAMP_CLIENT *client, const char *method, const char *format, ...)
{
char buffer[YAAMP_SMALLBUFSIZE];
va_list args;
int64_t id = client->shares;
va_start(args, format);
vsprintf(buffer, format, args);
va_end(args);
int ret = socket_send(client->sock, "{\"id\":%d,\"method\":\"%s\",\"params\":%s}\n", id, method, buffer);
if (ret == -1) {
debuglog("unable to ask %s\n", method);
return 0; // -errno
}
client->reqid = id;
return id;
}
void client_block_ip(YAAMP_CLIENT *client, const char *reason) void client_block_ip(YAAMP_CLIENT *client, const char *reason)
{ {
char buffer[1024]; char buffer[1024];

View file

@ -463,6 +463,10 @@ bool client_submit(YAAMP_CLIENT *client, json_value *json_params)
client_send_result(client, "true"); client_send_result(client, "true");
client_record_difficulty(client); client_record_difficulty(client);
client->submit_bad = 0; client->submit_bad = 0;
client->shares++;
if ((client->shares % 50) == 0) {
if (!client_ask_stats(client)) client->stats = false;
}
double share_diff = diff_to_target(hash_int); double share_diff = diff_to_target(hash_int);

View file

@ -450,9 +450,68 @@ void db_update_renters(YAAMP_DB *db)
g_list_renter.Leave(); g_list_renter.Leave();
} }
///////////////////////////////////////////////////////////////////////
static void _json_str_safe(YAAMP_DB *db, json_value *json, const char *key, size_t maxlen, char* out)
{
json_value *val = json_get_val(json, key);
out[0] = '\0';
if (val && json_is_string(val)) {
strncpy(out, json_string_value(val), maxlen);
out[maxlen-1] = '\0';
db_clean_string(db, out);
} else {
//debuglog("stats: invalid string for field '%s'\n", key);
}
}
#define json_str_safe(stats, k, out) _json_str_safe(db, stats, k, sizeof(out), out)
static int json_int_safe(json_value *json, const char *key)
{
json_value *val = json_get_val(json, key);
return val ? (int) json_integer_value(val) : 0;
}
static double json_double_safe(json_value *json, const char *key)
{
json_value *val = json_get_val(json, key);
return val ? (int) json_double_value(val) : 0.;
}
void db_store_stats(YAAMP_DB *db, YAAMP_CLIENT *client, json_value *stats)
{
int t = time(NULL);
json_value *algo, *val;
char sdev[80], stype[8], svid[12], sarch[8];
char salgo[32], sclient[48], sdriver[32], sos[8];
double khashes, intensity, throughput;
int power, freq, memf;
json_str_safe(stats, "algo", salgo);
if (strcasecmp(g_current_algo->name, salgo) && client->submit_bad) {
// debuglog("stats: wrong algo used %s != %s", salgo, g_current_algo->name);
return;
}
json_str_safe(stats, "device", sdev);
json_str_safe(stats, "type", stype);
json_str_safe(stats, "vendorid", svid);
json_str_safe(stats, "arch", sarch);
json_str_safe(stats, "client", sclient);
json_str_safe(stats, "os", sos);
json_str_safe(stats, "driver", sdriver);
power = json_int_safe(stats, "power");
freq = json_int_safe(stats, "freq");
memf = json_int_safe(stats, "memf");
intensity = json_double_safe(stats, "intensity");
throughput = json_double_safe(stats, "throughput");
khashes = json_double_safe(stats, "khashes");
db_query(db, "INSERT INTO benchmarks("
"time, algo, type, device, arch, vendorid, os, driver,"
"client, khps, freq, memf, power, intensity, throughput, userid"
") VALUES (%d,'%s','%s','%s','%s','%s','%s','%s', '%s',%f,%d,%d,%d,%.2f,%.0f,%d)",
t, g_current_algo->name, stype, sdev, sarch, svid, sos, sdriver,
sclient, khashes, freq, memf, power, intensity, throughput, client->userid);
}

View file

@ -29,5 +29,7 @@ void db_update_workers(YAAMP_DB *db);
void db_init_user_coinid(YAAMP_DB *db, YAAMP_CLIENT *client); void db_init_user_coinid(YAAMP_DB *db, YAAMP_CLIENT *client);
void db_store_stats(YAAMP_DB *db, YAAMP_CLIENT *client, json_value *stats);
void db_update_renters(YAAMP_DB *db); void db_update_renters(YAAMP_DB *db);

View file

@ -1001,3 +1001,27 @@ char* json_string_value(const json_value *json)
return json->u.string.ptr; return json->u.string.ptr;
} }
double json_double_value(const json_value *json)
{
double r = 0.;
if(json_is_double(json))
r = *(json);
else if (json_is_integer(json))
r = (double) json_integer_value(json);
return r;
}
json_value* json_get_val(json_value *obj, const char *key)
{
if (obj->type != json_object)
return NULL;
for (unsigned int i = 0; i < obj->u.object.length; i++)
if (!strcmp(obj->u.object.values[i].name, key))
return obj->u.object.values[i].value;
return NULL;
}

View file

@ -261,6 +261,8 @@ void json_value_free (json_value *);
void json_value_free_ex (json_settings * settings, void json_value_free_ex (json_settings * settings,
json_value *); json_value *);
json_value* json_get_val(json_value *obj, const char *key);
// todo // todo
char* json_dumps(json_value * value, int opt); char* json_dumps(json_value * value, int opt);
@ -268,11 +270,13 @@ typedef json_value json_t;
#define json_typeof(json) ((json)->type) #define json_typeof(json) ((json)->type)
#define json_is_array(json) (json && json_typeof(json) == json_array) #define json_is_array(json) (json && json_typeof(json) == json_array)
#define json_is_integer(json) (json && json_typeof(json) == json_integer) #define json_is_integer(json) (json && json_typeof(json) == json_integer)
#define json_is_double(json) (json && json_typeof(json) == json_double)
#define json_is_string(json) (json && json_typeof(json) == json_string) #define json_is_string(json) (json && json_typeof(json) == json_string)
#define json_is_null(json) (json && json_typeof(json) == json_null) #define json_is_null(json) (json && json_typeof(json) == json_null)
int json_integer_value(const json_value *json); int json_integer_value(const json_value *json);
char* json_string_value(const json_value *json); char* json_string_value(const json_value *json);
double json_double_value(const json_value *json);
#ifdef __cplusplus #ifdef __cplusplus
} /* extern "C" */ } /* extern "C" */

View file

@ -79,7 +79,7 @@ json_value *socket_nextjson(YAAMP_SOCKET *s, YAAMP_CLIENT *client)
return NULL; return NULL;
} }
char *p = strchr(b, '}'); char *p = strrchr(b, '}');
if(!p) if(!p)
{ {
if(client) if(client)