stratum: improve and add new methods for pool benchmark/stats
will allow to submit some device benchmark data to compute algo power usage and profitability. Introduce two new methods mining.get_algo and mining_get_stats These methods will be used with yiimp stratum with a special benchmark option Note: only the first card is handled for the moment. also add stratum mining.ping support (like cgminer 4.7.1+) and prevent disconnect on unknown methods, reply it is unsupported.
This commit is contained in:
parent
81051dd75f
commit
dcbcf6ba7e
@ -1,5 +1,5 @@
|
||||
|
||||
ccMiner release 1.7.6 (May 2016) "Under dev..."
|
||||
ccMiner release 1.7.6 (May 2016) "DCR vote & pool device stats"
|
||||
---------------------------------------------------------------
|
||||
|
||||
***************************************************************
|
||||
@ -238,10 +238,11 @@ features.
|
||||
|
||||
>>> RELEASE HISTORY <<<
|
||||
|
||||
May XXth 2016 v1.7.6
|
||||
May 15th 2016 v1.7.6
|
||||
Decred vote support
|
||||
X17 cleanup and improvement
|
||||
...
|
||||
Add mining.ping stratum method and handle unknown methods
|
||||
Implement a pool stats/benchmark mode (-p stats on yiimp)
|
||||
|
||||
Mar. 13th 2016 v1.7.5
|
||||
Blake2S Algo (NEVA/OXEN)
|
||||
|
2
api.cpp
2
api.cpp
@ -101,8 +101,6 @@ extern struct stratum_ctx stratum;
|
||||
extern int num_cpus;
|
||||
extern float cpu_temp(int);
|
||||
extern uint32_t cpu_clock(int);
|
||||
// cuda.cpp
|
||||
extern int cuda_gpu_clocks(struct cgpu_info *gpu);
|
||||
|
||||
char driver_version[32] = { 0 };
|
||||
|
||||
|
@ -204,6 +204,8 @@ char *opt_api_allow = strdup("127.0.0.1"); /* 0.0.0.0 for all ips */
|
||||
int opt_api_remote = 0;
|
||||
int opt_api_listen = 4068; /* 0 to disable */
|
||||
|
||||
bool opt_stratum_stats = false;
|
||||
|
||||
static char const usage[] = "\
|
||||
Usage: " PROGRAM_NAME " [OPTIONS]\n\
|
||||
Options:\n\
|
||||
|
5
cuda.cpp
5
cuda.cpp
@ -52,6 +52,11 @@ int cuda_num_devices()
|
||||
return GPU_N;
|
||||
}
|
||||
|
||||
int cuda_version()
|
||||
{
|
||||
return (int) CUDART_VERSION;
|
||||
}
|
||||
|
||||
void cuda_devicenames()
|
||||
{
|
||||
cudaError_t err;
|
||||
|
3
miner.h
3
miner.h
@ -459,6 +459,7 @@ extern bool want_longpoll;
|
||||
extern bool have_longpoll;
|
||||
extern bool want_stratum;
|
||||
extern bool have_stratum;
|
||||
extern bool opt_stratum_stats;
|
||||
extern char *opt_cert;
|
||||
extern char *opt_proxy;
|
||||
extern long opt_proxy_type;
|
||||
@ -493,7 +494,9 @@ void cuda_devicenames();
|
||||
void cuda_reset_device(int thr_id, bool *init);
|
||||
void cuda_shutdown();
|
||||
int cuda_finddevice(char *name);
|
||||
int cuda_version();
|
||||
void cuda_print_devices();
|
||||
int cuda_gpu_clocks(struct cgpu_info *gpu);
|
||||
int cuda_available_memory(int thr_id);
|
||||
|
||||
uint32_t cuda_default_throughput(int thr_id, uint32_t defcount);
|
||||
|
@ -196,6 +196,9 @@ bool pool_switch(int thr_id, int pooln)
|
||||
|
||||
want_stratum = have_stratum = (p->type & POOL_STRATUM) != 0;
|
||||
|
||||
// yiimp stats reporting
|
||||
opt_stratum_stats = (strstr(p->pass, "stats") != NULL) || (strcmp(p->user, "test") == 0);
|
||||
|
||||
pthread_mutex_unlock(&stratum_work_lock);
|
||||
|
||||
// algo "blind" switch without free, not proper
|
||||
|
205
util.cpp
205
util.cpp
@ -104,10 +104,10 @@ void applog(int prio, const char *fmt, ...)
|
||||
#endif
|
||||
else {
|
||||
const char* color = "";
|
||||
const time_t now = time(NULL);
|
||||
char *f;
|
||||
int len;
|
||||
struct tm tm;
|
||||
time_t now = time(NULL);
|
||||
|
||||
localtime_r(&now, &tm);
|
||||
|
||||
@ -1561,19 +1561,134 @@ static bool stratum_reconnect(struct stratum_ctx *sctx, json_t *params)
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool stratum_get_version(struct stratum_ctx *sctx, json_t *id)
|
||||
static bool stratum_pong(struct stratum_ctx *sctx, json_t *id)
|
||||
{
|
||||
char buf[64];
|
||||
bool ret = false;
|
||||
|
||||
if (!id || json_is_null(id))
|
||||
return ret;
|
||||
|
||||
sprintf(buf, "{\"id\":%d,\"result\":\"pong\",\"error\":null}",
|
||||
(int) json_integer_value(id));
|
||||
ret = stratum_send_line(sctx, buf);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static bool stratum_get_algo(struct stratum_ctx *sctx, json_t *id, json_t *params)
|
||||
{
|
||||
char algo[64] = { 0 };
|
||||
char *s;
|
||||
json_t *val;
|
||||
bool ret = true;
|
||||
|
||||
if (!id || json_is_null(id))
|
||||
return false;
|
||||
|
||||
get_currentalgo(algo, sizeof(algo));
|
||||
|
||||
val = json_object();
|
||||
json_object_set(val, "id", id);
|
||||
json_object_set_new(val, "error", json_null());
|
||||
json_object_set_new(val, "result", json_string(algo));
|
||||
|
||||
s = json_dumps(val, 0);
|
||||
ret = stratum_send_line(sctx, s);
|
||||
json_decref(val);
|
||||
free(s);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
#include "nvml.h"
|
||||
extern char driver_version[32];
|
||||
|
||||
static bool json_object_set_error(json_t *result, int code, const char *msg)
|
||||
{
|
||||
json_t *val = json_object();
|
||||
json_object_set_new(val, "code", json_integer(code));
|
||||
json_object_set_new(val, "message", json_string(msg));
|
||||
return json_object_set_new(result, "error", val) != -1;
|
||||
}
|
||||
|
||||
/* allow to report algo/device perf to the pool for algo stats */
|
||||
static bool stratum_benchdata(json_t *result, json_t *params, int thr_id)
|
||||
{
|
||||
char algo[64] = { 0 };
|
||||
char vid[32], arch[8], driver[32];
|
||||
char *card;
|
||||
char os[8];
|
||||
int dev_id = device_map[thr_id];
|
||||
int cuda_ver = cuda_version();
|
||||
struct cgpu_info *cgpu = &thr_info[thr_id].gpu;
|
||||
json_t *val;
|
||||
|
||||
if (!cgpu) return false;
|
||||
|
||||
#if defined(WIN32) && (defined(_M_X64) || defined(__x86_64__))
|
||||
strcpy(os, "win64");
|
||||
#else
|
||||
strcpy(os, is_windows() ? "win32" : "linux");
|
||||
#endif
|
||||
|
||||
#ifdef USE_WRAPNVML
|
||||
cgpu->has_monitoring = true;
|
||||
cgpu->gpu_power = gpu_power(cgpu); // Watts
|
||||
gpu_info(cgpu);
|
||||
#endif
|
||||
cuda_gpu_clocks(cgpu);
|
||||
get_currentalgo(algo, sizeof(algo));
|
||||
|
||||
card = device_name[dev_id];
|
||||
cgpu->khashes = stats_get_speed(thr_id, 0.0) / 1000.0;
|
||||
|
||||
sprintf(vid, "%04hx:%04hx", cgpu->gpu_vid, cgpu->gpu_pid);
|
||||
sprintf(arch, "%d", (int) cgpu->gpu_arch);
|
||||
snprintf(driver, 32, "CUDA %d.%d %s", cuda_ver/1000, (cuda_ver%1000) / 10, driver_version);
|
||||
driver[31] = '\0';
|
||||
|
||||
val = json_object();
|
||||
json_object_set_new(val, "algo", json_string(algo));
|
||||
json_object_set_new(val, "type", json_string("gpu"));
|
||||
json_object_set_new(val, "device", json_string(card));
|
||||
json_object_set_new(val, "vendorid", json_string(vid));
|
||||
json_object_set_new(val, "arch", json_string(arch));
|
||||
json_object_set_new(val, "freq", json_integer(cgpu->gpu_clock/1000));
|
||||
json_object_set_new(val, "memf", json_integer(cgpu->gpu_memclock/1000));
|
||||
json_object_set_new(val, "power", json_integer(cgpu->gpu_power/1000));
|
||||
json_object_set_new(val, "khashes", json_real(cgpu->khashes));
|
||||
json_object_set_new(val, "intensity", json_integer(cgpu->intensity));
|
||||
json_object_set_new(val, "throughput", json_integer(cgpu->throughput));
|
||||
json_object_set_new(val, "client", json_string(PACKAGE_NAME "/" PACKAGE_VERSION));
|
||||
json_object_set_new(val, "os", json_string(os));
|
||||
json_object_set_new(val, "driver", json_string(driver));
|
||||
|
||||
json_object_set_new(result, "result", val);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool stratum_get_stats(struct stratum_ctx *sctx, json_t *id, json_t *params)
|
||||
{
|
||||
char *s;
|
||||
json_t *val;
|
||||
bool ret;
|
||||
|
||||
|
||||
if (!id || json_is_null(id))
|
||||
return false;
|
||||
|
||||
val = json_object();
|
||||
json_object_set(val, "id", id);
|
||||
json_object_set_new(val, "error", json_null());
|
||||
json_object_set_new(val, "result", json_string(USER_AGENT));
|
||||
|
||||
ret = stratum_benchdata(val, params, 0);
|
||||
|
||||
if (!opt_stratum_stats || !ret) {
|
||||
json_object_set_error(val, 1, "disabled"); //EPERM
|
||||
} else {
|
||||
json_object_set_new(val, "error", json_null());
|
||||
}
|
||||
|
||||
s = json_dumps(val, 0);
|
||||
ret = stratum_send_line(sctx, s);
|
||||
json_decref(val);
|
||||
@ -1582,6 +1697,36 @@ static bool stratum_get_version(struct stratum_ctx *sctx, json_t *id)
|
||||
return ret;
|
||||
}
|
||||
|
||||
static bool stratum_get_version(struct stratum_ctx *sctx, json_t *id, json_t *params)
|
||||
{
|
||||
char *s;
|
||||
json_t *val;
|
||||
bool ret = true;
|
||||
|
||||
if (!id || json_is_null(id))
|
||||
return false;
|
||||
|
||||
val = json_object();
|
||||
json_object_set(val, "id", id);
|
||||
|
||||
if (opt_stratum_stats && params) {
|
||||
// linked here as transition, miners without get_stats method could fail
|
||||
ret = stratum_benchdata(val, params, 0);
|
||||
if (!ret) json_object_set_error(val, 1, "disabled"); // EPERM
|
||||
} else {
|
||||
json_object_set_new(val, "result", json_string(USER_AGENT));
|
||||
}
|
||||
if (ret) json_object_set_new(val, "error", json_null());
|
||||
|
||||
s = json_dumps(val, 0);
|
||||
ret = stratum_send_line(sctx, s);
|
||||
|
||||
json_decref(val);
|
||||
free(s);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static bool stratum_show_message(struct stratum_ctx *sctx, json_t *id, json_t *params)
|
||||
{
|
||||
char *s;
|
||||
@ -1607,6 +1752,28 @@ static bool stratum_show_message(struct stratum_ctx *sctx, json_t *id, json_t *p
|
||||
return ret;
|
||||
}
|
||||
|
||||
static bool stratum_unknown_method(struct stratum_ctx *sctx, json_t *id)
|
||||
{
|
||||
char *s;
|
||||
json_t *val;
|
||||
bool ret = false;
|
||||
|
||||
if (!id || json_is_null(id))
|
||||
return ret;
|
||||
|
||||
val = json_object();
|
||||
json_object_set(val, "id", id);
|
||||
json_object_set_new(val, "result", json_false());
|
||||
json_object_set_error(val, 38, "unknown method"); // ENOSYS
|
||||
|
||||
s = json_dumps(val, 0);
|
||||
ret = stratum_send_line(sctx, s);
|
||||
json_decref(val);
|
||||
free(s);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
bool stratum_handle_method(struct stratum_ctx *sctx, const char *s)
|
||||
{
|
||||
json_t *val, *id, *params;
|
||||
@ -1630,6 +1797,11 @@ bool stratum_handle_method(struct stratum_ctx *sctx, const char *s)
|
||||
ret = stratum_notify(sctx, params);
|
||||
goto out;
|
||||
}
|
||||
if (!strcasecmp(method, "mining.ping")) { // cgminer 4.7.1+
|
||||
if (opt_debug) applog(LOG_DEBUG, "Pool ping");
|
||||
ret = stratum_pong(sctx, id);
|
||||
goto out;
|
||||
}
|
||||
if (!strcasecmp(method, "mining.set_difficulty")) {
|
||||
ret = stratum_set_difficulty(sctx, params);
|
||||
goto out;
|
||||
@ -1642,15 +1814,32 @@ bool stratum_handle_method(struct stratum_ctx *sctx, const char *s)
|
||||
ret = stratum_reconnect(sctx, params);
|
||||
goto out;
|
||||
}
|
||||
if (!strcasecmp(method, "client.get_version")) {
|
||||
ret = stratum_get_version(sctx, id);
|
||||
if (!strcasecmp(method, "client.get_algo")) { // ccminer only yet!
|
||||
// will prevent wrong algo parameters on a pool, will be used as test on rejects
|
||||
if (!opt_quiet) applog(LOG_NOTICE, "Pool asked your algo parameter");
|
||||
ret = stratum_get_algo(sctx, id, params);
|
||||
goto out;
|
||||
}
|
||||
if (!strcasecmp(method, "client.show_message")) {
|
||||
if (!strcasecmp(method, "client.get_stats")) { // ccminer/yiimp only yet!
|
||||
// optional to fill device benchmarks
|
||||
ret = stratum_get_stats(sctx, id, params);
|
||||
goto out;
|
||||
}
|
||||
if (!strcasecmp(method, "client.get_version")) { // common
|
||||
ret = stratum_get_version(sctx, id, params);
|
||||
goto out;
|
||||
}
|
||||
if (!strcasecmp(method, "client.show_message")) { // common
|
||||
ret = stratum_show_message(sctx, id, params);
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (!ret) {
|
||||
// don't fail = disconnect stratum on unknown (and optional?) methods
|
||||
if (opt_debug) applog(LOG_WARNING, "unknown stratum method %s!", method);
|
||||
ret = stratum_unknown_method(sctx, id);
|
||||
}
|
||||
|
||||
out:
|
||||
if (val)
|
||||
json_decref(val);
|
||||
|
Loading…
x
Reference in New Issue
Block a user