|
|
@@ -504,6 +504,42 @@ struct cgpu_info *get_devices(int id)
|
|
|
return cgpu;
|
|
|
}
|
|
|
|
|
|
+static pthread_mutex_t noncelog_lock = PTHREAD_MUTEX_INITIALIZER;
|
|
|
+static FILE *noncelog_file = NULL;
|
|
|
+
|
|
|
+static
|
|
|
+void noncelog(const struct work * const work)
|
|
|
+{
|
|
|
+ const int thr_id = work->thr_id;
|
|
|
+ const struct cgpu_info *proc = get_thr_cgpu(thr_id);
|
|
|
+ char buf[0x200], hash[65], data[161], midstate[65];
|
|
|
+ int rv;
|
|
|
+ size_t ret;
|
|
|
+
|
|
|
+ bin2hex(hash, work->hash, 32);
|
|
|
+ bin2hex(data, work->data, 80);
|
|
|
+ bin2hex(midstate, work->midstate, 32);
|
|
|
+
|
|
|
+ // timestamp,proc,hash,data,midstate
|
|
|
+ rv = snprintf(buf, sizeof(buf), "%lu,%s,%s,%s,%s\n",
|
|
|
+ (unsigned long)time(NULL), proc->proc_repr_ns,
|
|
|
+ hash, data, midstate);
|
|
|
+
|
|
|
+ if (unlikely(rv < 1))
|
|
|
+ {
|
|
|
+ applog(LOG_ERR, "noncelog printf error");
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
+ mutex_lock(&noncelog_lock);
|
|
|
+ ret = fwrite(buf, rv, 1, noncelog_file);
|
|
|
+ fflush(noncelog_file);
|
|
|
+ mutex_unlock(&noncelog_lock);
|
|
|
+
|
|
|
+ if (ret != 1)
|
|
|
+ applog(LOG_ERR, "noncelog fwrite error");
|
|
|
+}
|
|
|
+
|
|
|
static void sharelog(const char*disposition, const struct work*work)
|
|
|
{
|
|
|
char target[(sizeof(work->target) * 2) + 1];
|
|
|
@@ -1144,28 +1180,59 @@ char *set_log_file(char *arg)
|
|
|
return NULL;
|
|
|
}
|
|
|
|
|
|
-static char* set_sharelog(char *arg)
|
|
|
+static
|
|
|
+char *_bfgopt_set_file(const char *arg, FILE **F, const char *mode, const char *purpose)
|
|
|
{
|
|
|
char *r = "";
|
|
|
long int i = strtol(arg, &r, 10);
|
|
|
+ static char *err = NULL;
|
|
|
+ const size_t errbufsz = 0x100;
|
|
|
|
|
|
+ free(err);
|
|
|
+ err = NULL;
|
|
|
+
|
|
|
if ((!*r) && i >= 0 && i <= INT_MAX) {
|
|
|
- sharelog_file = fdopen((int)i, "a");
|
|
|
- if (!sharelog_file)
|
|
|
- applog(LOG_ERR, "Failed to open fd %u for share log", (unsigned int)i);
|
|
|
+ *F = fdopen((int)i, mode);
|
|
|
+ if (!*F)
|
|
|
+ {
|
|
|
+ err = malloc(errbufsz);
|
|
|
+ snprintf(err, errbufsz, "Failed to open fd %d for %s",
|
|
|
+ (int)i, purpose);
|
|
|
+ return err;
|
|
|
+ }
|
|
|
} else if (!strcmp(arg, "-")) {
|
|
|
- sharelog_file = stdout;
|
|
|
- if (!sharelog_file)
|
|
|
- applog(LOG_ERR, "Standard output missing for share log");
|
|
|
+ *F = (mode[0] == 'a') ? stdout : stdin;
|
|
|
+ if (!*F)
|
|
|
+ {
|
|
|
+ err = malloc(errbufsz);
|
|
|
+ snprintf(err, errbufsz, "Standard %sput missing for %s",
|
|
|
+ (mode[0] == 'a') ? "out" : "in", purpose);
|
|
|
+ return err;
|
|
|
+ }
|
|
|
} else {
|
|
|
- sharelog_file = fopen(arg, "a");
|
|
|
- if (!sharelog_file)
|
|
|
- applog(LOG_ERR, "Failed to open %s for share log", arg);
|
|
|
+ *F = fopen(arg, mode);
|
|
|
+ if (!*F)
|
|
|
+ {
|
|
|
+ err = malloc(errbufsz);
|
|
|
+ snprintf(err, errbufsz, "Failed to open %s for %s",
|
|
|
+ arg, purpose);
|
|
|
+ return err;
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
return NULL;
|
|
|
}
|
|
|
|
|
|
+static char *set_noncelog(char *arg)
|
|
|
+{
|
|
|
+ return _bfgopt_set_file(arg, &noncelog_file, "a", "nonce log");
|
|
|
+}
|
|
|
+
|
|
|
+static char *set_sharelog(char *arg)
|
|
|
+{
|
|
|
+ return _bfgopt_set_file(arg, &sharelog_file, "a", "share log");
|
|
|
+}
|
|
|
+
|
|
|
static char *temp_cutoff_str = "";
|
|
|
static char *temp_target_str = "";
|
|
|
|
|
|
@@ -1631,6 +1698,9 @@ static struct opt_table opt_config_table[] = {
|
|
|
opt_hidden
|
|
|
#endif
|
|
|
),
|
|
|
+ OPT_WITH_ARG("--noncelog",
|
|
|
+ set_noncelog, NULL, NULL,
|
|
|
+ "Create log of all nonces found"),
|
|
|
OPT_WITH_ARG("--pass|-p",
|
|
|
set_pass, NULL, NULL,
|
|
|
"Password for bitcoin JSON-RPC server"),
|
|
|
@@ -8132,6 +8202,9 @@ bool submit_nonce(struct thr_info *thr, struct work *work, uint32_t nonce)
|
|
|
thr->cgpu->last_device_valid_work = time(NULL);
|
|
|
mutex_unlock(&stats_lock);
|
|
|
|
|
|
+ if (noncelog_file)
|
|
|
+ noncelog(work);
|
|
|
+
|
|
|
if (res == TNR_HIGH)
|
|
|
{
|
|
|
// Share above target, normal
|