|
|
@ -1,7 +1,7 @@ |
|
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
/*
|
|
|
|
* Copyright 2010 Jeff Garzik |
|
|
|
* Copyright 2010 Jeff Garzik |
|
|
|
* 2011 Nils Schneider |
|
|
|
* 2011 Nils Schneider |
|
|
|
|
|
|
|
* 2017 GOSTSec team |
|
|
|
* |
|
|
|
* |
|
|
|
* This program is free software; you can redistribute it and/or modify it |
|
|
|
* This program is free software; you can redistribute it and/or modify it |
|
|
|
* under the terms of the GNU General Public License as published by the Free |
|
|
|
* under the terms of the GNU General Public License as published by the Free |
|
|
@ -40,7 +40,8 @@ |
|
|
|
#define DEF_RPC_URL "http://127.0.0.1:9376/"
|
|
|
|
#define DEF_RPC_URL "http://127.0.0.1:9376/"
|
|
|
|
#define DEF_RPC_USERPASS "rpcuser:rpcpass" |
|
|
|
#define DEF_RPC_USERPASS "rpcuser:rpcpass" |
|
|
|
|
|
|
|
|
|
|
|
enum { |
|
|
|
enum |
|
|
|
|
|
|
|
{ |
|
|
|
STAT_SLEEP_INTERVAL = 1, |
|
|
|
STAT_SLEEP_INTERVAL = 1, |
|
|
|
STAT_CTR_INTERVAL = 10000000, |
|
|
|
STAT_CTR_INTERVAL = 10000000, |
|
|
|
FAILURE_INTERVAL = 30, |
|
|
|
FAILURE_INTERVAL = 30, |
|
|
@ -56,18 +57,21 @@ static const bool opt_time = true; |
|
|
|
static int opt_n_threads = 1; |
|
|
|
static int opt_n_threads = 1; |
|
|
|
static char *rpc_url = DEF_RPC_URL; |
|
|
|
static char *rpc_url = DEF_RPC_URL; |
|
|
|
static char *userpass = DEF_RPC_USERPASS; |
|
|
|
static char *userpass = DEF_RPC_USERPASS; |
|
|
|
|
|
|
|
static int opt_intensity = 16; |
|
|
|
|
|
|
|
|
|
|
|
int block = 0; |
|
|
|
int block = 0; |
|
|
|
|
|
|
|
|
|
|
|
double hashrates[16]; |
|
|
|
double hashrates[16]; |
|
|
|
_clState *clStates[16]; |
|
|
|
_clState *clStates[16]; |
|
|
|
|
|
|
|
|
|
|
|
struct option_help { |
|
|
|
struct option_help |
|
|
|
|
|
|
|
{ |
|
|
|
const char *name; |
|
|
|
const char *name; |
|
|
|
const char *helptext; |
|
|
|
const char *helptext; |
|
|
|
}; |
|
|
|
}; |
|
|
|
|
|
|
|
|
|
|
|
static struct option_help options_help[] = { |
|
|
|
static struct option_help options_help[] = |
|
|
|
|
|
|
|
{ |
|
|
|
{ "help", |
|
|
|
{ "help", |
|
|
|
"(-h) Display this help text" }, |
|
|
|
"(-h) Display this help text" }, |
|
|
|
|
|
|
|
|
|
|
@ -81,35 +85,41 @@ static struct option_help options_help[] = { |
|
|
|
"(-m) Enable pool mode (default: off)" }, |
|
|
|
"(-m) Enable pool mode (default: off)" }, |
|
|
|
|
|
|
|
|
|
|
|
{ "protocol-dump", |
|
|
|
{ "protocol-dump", |
|
|
|
"(-P) Verbose dump of protocol-level activities (default: off)" }, |
|
|
|
"(-P) Verbose dump of protocol-level activities\n" |
|
|
|
|
|
|
|
"\t(default: off)" }, |
|
|
|
|
|
|
|
|
|
|
|
{ "retries N", |
|
|
|
{ "retries N", |
|
|
|
"(-r N) Number of times to retry, if JSON-RPC call fails\n" |
|
|
|
"(-r N) Number of times to retry, if JSON-RPC call fails\n" |
|
|
|
"\t(default: 10; use -1 for \"never\")" }, |
|
|
|
"\t(default: 10; use -1 for \"never\")" }, |
|
|
|
|
|
|
|
|
|
|
|
{ "url URL", |
|
|
|
{ "url URL", |
|
|
|
"URL for bitcoin JSON-RPC server " |
|
|
|
"URL for bitcoin JSON-RPC server\n" |
|
|
|
"(default: " DEF_RPC_URL ")" }, |
|
|
|
"\t(default: " DEF_RPC_URL ")" }, |
|
|
|
|
|
|
|
|
|
|
|
{ "userpass USERNAME:PASSWORD", |
|
|
|
{ "userpass USERNAME:PASSWORD", |
|
|
|
"Username:Password pair for bitcoin JSON-RPC server " |
|
|
|
"Username:Password pair for bitcoin JSON-RPC server\n" |
|
|
|
"(default: " DEF_RPC_USERPASS ")" }, |
|
|
|
"\t(default: " DEF_RPC_USERPASS ")" }, |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
{ "intensity N", |
|
|
|
|
|
|
|
"(-i N) Intensity of mining\n" |
|
|
|
|
|
|
|
"\t(default: 16, min = 8, max = 18)" } |
|
|
|
}; |
|
|
|
}; |
|
|
|
|
|
|
|
|
|
|
|
static struct option options[] = { |
|
|
|
static struct option options[] = |
|
|
|
|
|
|
|
{ |
|
|
|
{ "help", 0, NULL, 'h' }, |
|
|
|
{ "help", 0, NULL, 'h' }, |
|
|
|
{ "debug", 0, NULL, 'D' }, |
|
|
|
{ "debug", 0, NULL, 'D' }, |
|
|
|
{ "protocol-dump", 0, NULL, 'P' }, |
|
|
|
{ "protocol-dump", 0, NULL, 'P' }, |
|
|
|
{ "retries", 1, NULL, 'r' }, |
|
|
|
{ "retries", 1, NULL, 'r' }, |
|
|
|
{ "url", 1, NULL, 1001 }, |
|
|
|
{ "url", 1, NULL, 1001 }, |
|
|
|
{ "userpass", 1, NULL, 1002 }, |
|
|
|
{ "userpass", 1, NULL, 1002 }, |
|
|
|
|
|
|
|
{ "intensity", 1, NULL, 'i' }, |
|
|
|
{ "ndevs", 0, NULL, 'n' }, |
|
|
|
{ "ndevs", 0, NULL, 'n' }, |
|
|
|
{ "pool", 0, NULL, 'm' }, |
|
|
|
{ "pool", 0, NULL, 'm' }, |
|
|
|
{ } |
|
|
|
{ } |
|
|
|
}; |
|
|
|
}; |
|
|
|
|
|
|
|
|
|
|
|
static bool jobj_binary(const json_t *obj, const char *key, |
|
|
|
static bool jobj_binary(const json_t *obj, const char *key, void *buf, size_t buflen) |
|
|
|
void *buf, size_t buflen) |
|
|
|
|
|
|
|
{ |
|
|
|
{ |
|
|
|
const char *hexstr; |
|
|
|
const char *hexstr; |
|
|
|
json_t *tmp; |
|
|
|
json_t *tmp; |
|
|
@ -195,7 +205,8 @@ out: |
|
|
|
free(hexstr); |
|
|
|
free(hexstr); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
double time2secs(struct timeval *tv_start) { |
|
|
|
double time2secs(struct timeval *tv_start) |
|
|
|
|
|
|
|
{ |
|
|
|
struct timeval tv_end, diff; |
|
|
|
struct timeval tv_end, diff; |
|
|
|
double secs; |
|
|
|
double secs; |
|
|
|
|
|
|
|
|
|
|
@ -206,25 +217,22 @@ double time2secs(struct timeval *tv_start) { |
|
|
|
return secs; |
|
|
|
return secs; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
static void hashmeter(int thr_id, struct timeval *tv_start, |
|
|
|
static void hashmeter(int thr_id, struct timeval *tv_start, unsigned long hashes_done) |
|
|
|
unsigned long hashes_done) |
|
|
|
|
|
|
|
{ |
|
|
|
{ |
|
|
|
double mhashes, secs; |
|
|
|
double mhashes, secs; |
|
|
|
|
|
|
|
|
|
|
|
secs = time2secs(tv_start); |
|
|
|
secs = time2secs(tv_start); |
|
|
|
|
|
|
|
|
|
|
|
mhashes = hashes_done / 1000.0 / 1000.0; |
|
|
|
mhashes = hashes_done / 1000.0 / 1000.0; |
|
|
|
|
|
|
|
|
|
|
|
hashrates[thr_id] = mhashes / secs; |
|
|
|
hashrates[thr_id] = mhashes / secs; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
static void print_hashmeter(double hashrate, char *rates) { |
|
|
|
static void print_hashmeter(double hashrate, char *rates) |
|
|
|
printf("\r \rHashMeter: %.2f Mhash/sec (%s)", hashrate, rates); |
|
|
|
{ |
|
|
|
|
|
|
|
printf("HashMeter: %.2f Mhash/sec (%s)\n", hashrate, rates); |
|
|
|
fflush(stdout); |
|
|
|
fflush(stdout); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
static bool getwork(struct work_t *work) |
|
|
|
static bool getwork(struct work_t *work) { |
|
|
|
{ |
|
|
|
static const char *rpc_req = "{\"method\": \"getwork\", \"params\": [], \"id\":0}\r\n"; |
|
|
|
static const char *rpc_req = "{\"method\": \"getwork\", \"params\": [], \"id\":0}\r\n"; |
|
|
|
json_t *val; |
|
|
|
json_t *val; |
|
|
|
bool rc; |
|
|
|
bool rc; |
|
|
@ -248,7 +256,8 @@ static bool getwork(struct work_t *work) { |
|
|
|
return true; |
|
|
|
return true; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
void submit_nonce(struct work_t *work, uint32_t nonce) { |
|
|
|
void submit_nonce(struct work_t *work, uint32_t nonce) |
|
|
|
|
|
|
|
{ |
|
|
|
work->data[64+12+0] = (nonce>>0) & 0xff; |
|
|
|
work->data[64+12+0] = (nonce>>0) & 0xff; |
|
|
|
work->data[64+12+1] = (nonce>>8) & 0xff; |
|
|
|
work->data[64+12+1] = (nonce>>8) & 0xff; |
|
|
|
work->data[64+12+2] = (nonce>>16) & 0xff; |
|
|
|
work->data[64+12+2] = (nonce>>16) & 0xff; |
|
|
@ -334,7 +343,7 @@ static void *miner_thread(void *thr_id_int) |
|
|
|
|
|
|
|
|
|
|
|
gettimeofday(&tv_start, NULL); |
|
|
|
gettimeofday(&tv_start, NULL); |
|
|
|
|
|
|
|
|
|
|
|
int threads = 65536; // TODO:
|
|
|
|
int threads = 1 << (opt_intensity); // TODO:
|
|
|
|
globalThreads[0] = threads; |
|
|
|
globalThreads[0] = threads; |
|
|
|
localThreads[0] = 256; |
|
|
|
localThreads[0] = 256; |
|
|
|
|
|
|
|
|
|
|
@ -382,7 +391,6 @@ static void *miner_thread(void *thr_id_int) |
|
|
|
work[res_frame].ready = false; |
|
|
|
work[res_frame].ready = false; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
status = clEnqueueReadBuffer(clState->commandQueue, clState->outputBuffer, CL_TRUE, 0, |
|
|
|
status = clEnqueueReadBuffer(clState->commandQueue, clState->outputBuffer, CL_TRUE, 0, |
|
|
|
sizeof(uint32_t) * threads, res, 0, NULL, NULL); |
|
|
|
sizeof(uint32_t) * threads, res, 0, NULL, NULL); |
|
|
|
if(status != CL_SUCCESS) { printf("Error: clEnqueueReadBuffer failed. (clEnqueueReadBuffer)\n"); return 0; } |
|
|
|
if(status != CL_SUCCESS) { printf("Error: clEnqueueReadBuffer failed. (clEnqueueReadBuffer)\n"); return 0; } |
|
|
@ -423,41 +431,51 @@ static void show_usage(void) |
|
|
|
|
|
|
|
|
|
|
|
static void parse_arg (int key, char *arg) |
|
|
|
static void parse_arg (int key, char *arg) |
|
|
|
{ |
|
|
|
{ |
|
|
|
int v, i; |
|
|
|
int v; |
|
|
|
|
|
|
|
|
|
|
|
switch(key) { |
|
|
|
switch(key) { |
|
|
|
case 'm': |
|
|
|
case 'm': |
|
|
|
opt_pool = true; |
|
|
|
opt_pool = true; |
|
|
|
break; |
|
|
|
break; |
|
|
|
|
|
|
|
|
|
|
|
case 'n': |
|
|
|
case 'n': |
|
|
|
opt_ndevs = true; |
|
|
|
opt_ndevs = true; |
|
|
|
break; |
|
|
|
break; |
|
|
|
|
|
|
|
|
|
|
|
case 'D': |
|
|
|
case 'D': |
|
|
|
opt_debug = true; |
|
|
|
opt_debug = true; |
|
|
|
break; |
|
|
|
break; |
|
|
|
|
|
|
|
|
|
|
|
case 'P': |
|
|
|
case 'P': |
|
|
|
opt_protocol = true; |
|
|
|
opt_protocol = true; |
|
|
|
break; |
|
|
|
break; |
|
|
|
|
|
|
|
|
|
|
|
case 'r': |
|
|
|
case 'r': |
|
|
|
v = atoi(arg); |
|
|
|
v = atoi(arg); |
|
|
|
if (v < -1 || v > 9999) /* sanity check */ |
|
|
|
if (v < -1 || v > 9999) |
|
|
|
show_usage(); |
|
|
|
show_usage(); |
|
|
|
|
|
|
|
|
|
|
|
opt_retries = v; |
|
|
|
opt_retries = v; |
|
|
|
break; |
|
|
|
break; |
|
|
|
case 1001: /* --url */ |
|
|
|
|
|
|
|
if (strncmp(arg, "http://", 7) && |
|
|
|
case 'i': |
|
|
|
strncmp(arg, "https://", 8)) |
|
|
|
v = atoi(arg); |
|
|
|
|
|
|
|
if (v < 8 || v > 18) |
|
|
|
show_usage(); |
|
|
|
show_usage(); |
|
|
|
|
|
|
|
opt_intensity = v; |
|
|
|
|
|
|
|
break; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
case 1001: /* --url */ |
|
|
|
|
|
|
|
if (strncmp(arg, "http://", 7) && strncmp(arg, "https://", 8)) |
|
|
|
|
|
|
|
show_usage(); |
|
|
|
rpc_url = arg; |
|
|
|
rpc_url = arg; |
|
|
|
break; |
|
|
|
break; |
|
|
|
|
|
|
|
|
|
|
|
case 1002: /* --userpass */ |
|
|
|
case 1002: /* --userpass */ |
|
|
|
if (!strchr(arg, ':')) |
|
|
|
if (!strchr(arg, ':')) |
|
|
|
show_usage(); |
|
|
|
show_usage(); |
|
|
|
|
|
|
|
|
|
|
|
userpass = arg; |
|
|
|
userpass = arg; |
|
|
|
break; |
|
|
|
break; |
|
|
|
|
|
|
|
|
|
|
|
default: |
|
|
|
default: |
|
|
|
show_usage(); |
|
|
|
show_usage(); |
|
|
|
} |
|
|
|
} |
|
|
@ -468,7 +486,7 @@ static void parse_cmdline(int argc, char *argv[]) |
|
|
|
int key; |
|
|
|
int key; |
|
|
|
|
|
|
|
|
|
|
|
while (1) { |
|
|
|
while (1) { |
|
|
|
key = getopt_long(argc, argv, "DPh?nm", options, NULL); |
|
|
|
key = getopt_long(argc, argv, "D:P:h:r:i:?:n:m", options, NULL ); |
|
|
|
if (key < 0) |
|
|
|
if (key < 0) |
|
|
|
break; |
|
|
|
break; |
|
|
|
|
|
|
|
|
|
|
@ -511,7 +529,7 @@ int main (int argc, char *argv[]) |
|
|
|
sleep(1); /* don't pound RPC server all at once */ |
|
|
|
sleep(1); /* don't pound RPC server all at once */ |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
fprintf(stderr, "%d miner threads started\n", i); |
|
|
|
fprintf(stderr, "%d miner threads with %d GPU threads started\n", i, (int) 1 << (opt_intensity)); |
|
|
|
|
|
|
|
|
|
|
|
/* main loop */ |
|
|
|
/* main loop */ |
|
|
|
struct timeval tv; |
|
|
|
struct timeval tv; |
|
|
@ -556,4 +574,3 @@ int main (int argc, char *argv[]) |
|
|
|
|
|
|
|
|
|
|
|
return 0; |
|
|
|
return 0; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|