Commit b3e9858c9f2e314cb430cfbc280474c81bf58694

Kano 2012-08-20T16:07:20

API new command 'coin' with mining information

diff --git a/API-README b/API-README
index 450b1aa..5ab1c72 100644
--- a/API-README
+++ b/API-README
@@ -281,6 +281,12 @@ The list of requests - a (*) means it requires privileged access - and replies a
                none           There is no reply section just the STATUS section
                               stating what failover-only was set to
 
+ coin          COIN           Coin mining information:
+                              Hash Method=sha256/scrypt,
+                              Current Block Time=N.N, <- 0 means none
+                              Current Block Hash=XXXX..., <- blank if none
+                              LP=true/false| <- LP is in use on at least 1 pool
+
 When you enable, disable or restart a GPU or PGA, you will also get Thread messages
 in the cgminer status window
 
@@ -335,6 +341,9 @@ Feature Changelog for external applications using the API:
 
 API V1.17
 
+Added API commands:
+ 'coin'
+
 Modified API commands:
  'summary' - add 'Work Utility'
  'pools' - add 'Diff1 Shares'
diff --git a/api.c b/api.c
index 2d3781c..05d7d3e 100644
--- a/api.c
+++ b/api.c
@@ -187,6 +187,11 @@ static const char *NULLSTR = "(null)";
 static const char *TRUESTR = "true";
 static const char *FALSESTR = "false";
 
+#ifdef USE_SCRYPT
+static const char *SCRYPTSTR = "scrypt";
+#endif
+static const char *SHA256STR = "sha256";
+
 static const char *DEVICECODE = ""
 #ifdef HAVE_OPENCL
 			"GPU "
@@ -232,7 +237,7 @@ static const char *OSINFO =
 #define _SUMMARY	"SUMMARY"
 #define _STATUS		"STATUS"
 #define _VERSION	"VERSION"
-#define _MINECON	"CONFIG"
+#define _MINECONFIG	"CONFIG"
 #define _GPU		"GPU"
 
 #ifdef HAVE_AN_FPGA
@@ -252,6 +257,7 @@ static const char *OSINFO =
 #define _RESTART	"RESTART"
 #define _MINESTATS	"STATS"
 #define _CHECK		"CHECK"
+#define _MINECOIN	"COIN"
 
 static const char ISJSON = '{';
 #define JSON0		"{"
@@ -267,7 +273,7 @@ static const char ISJSON = '{';
 #define JSON_SUMMARY	JSON1 _SUMMARY JSON2
 #define JSON_STATUS	JSON1 _STATUS JSON2
 #define JSON_VERSION	JSON1 _VERSION JSON2
-#define JSON_MINECON	JSON1 _MINECON JSON2
+#define JSON_MINECONFIG	JSON1 _MINECONFIG JSON2
 #define JSON_GPU	JSON1 _GPU JSON2
 
 #ifdef HAVE_AN_FPGA
@@ -288,6 +294,7 @@ static const char ISJSON = '{';
 #define JSON_CLOSE	JSON3
 #define JSON_MINESTATS	JSON1 _MINESTATS JSON2
 #define JSON_CHECK	JSON1 _CHECK JSON2
+#define JSON_MINECOIN	JSON1 _MINECOIN JSON2
 #define JSON_END	JSON4 JSON5
 
 static const char *JSON_COMMAND = "command";
@@ -329,7 +336,7 @@ static const char *JSON_PARAMETER = "parameter";
 #define MSG_NOGPUADL 30
 #define MSG_INVINT 31
 #define MSG_GPUINT 32
-#define MSG_MINECON 33
+#define MSG_MINECONFIG 33
 #define MSG_GPUMERR 34
 #define MSG_GPUMEM 35
 #define MSG_GPUEERR 36
@@ -382,6 +389,7 @@ static const char *JSON_PARAMETER = "parameter";
 #define MSG_MISBOOL 75
 #define MSG_INVBOOL 76
 #define MSG_FOO 77
+#define MSG_MINECOIN 78
 
 enum code_severity {
 	SEVERITY_ERR,
@@ -496,7 +504,7 @@ struct CODES {
  { SEVERITY_ERR,   MSG_NOGPUADL,PARAM_GPU,	"GPU %d does not have ADL" },
  { SEVERITY_ERR,   MSG_INVINT,	PARAM_STR,	"Invalid intensity (%s) - must be '" _DYNAMIC  "' or range " _MIN_INTENSITY_STR " - " _MAX_INTENSITY_STR },
  { SEVERITY_INFO,  MSG_GPUINT,	PARAM_BOTH,	"GPU %d set new intensity to %s" },
- { SEVERITY_SUCC,  MSG_MINECON, PARAM_NONE,	"CGMiner config" },
+ { SEVERITY_SUCC,  MSG_MINECONFIG,PARAM_NONE,	"CGMiner config" },
 #ifdef HAVE_OPENCL
  { SEVERITY_ERR,   MSG_GPUMERR,	PARAM_BOTH,	"Setting GPU %d memoryclock to (%s) reported failure" },
  { SEVERITY_SUCC,  MSG_GPUMEM,	PARAM_BOTH,	"Setting GPU %d memoryclock to (%s) reported success" },
@@ -534,6 +542,7 @@ struct CODES {
  { SEVERITY_ERR,   MSG_MISBOOL,	PARAM_NONE,	"Missing parameter: true/false" },
  { SEVERITY_ERR,   MSG_INVBOOL,	PARAM_NONE,	"Invalid parameter should be true or false" },
  { SEVERITY_SUCC,  MSG_FOO,	PARAM_BOOL,	"Failover-Only set to %s" },
+ { SEVERITY_SUCC,  MSG_MINECOIN,PARAM_NONE,	"CGMiner coin" },
  { SEVERITY_FAIL, 0, 0, NULL }
 };
 
@@ -1232,9 +1241,9 @@ static void minerconfig(__maybe_unused SOCKETTYPE c, __maybe_unused char *param,
 #endif
 
 	sprintf(io_buffer, isjson
-		? "%s," JSON_MINECON
-		: "%s" _MINECON ",",
-		message(MSG_MINECON, 0, NULL, isjson));
+		? "%s," JSON_MINECONFIG
+		: "%s" _MINECONFIG ",",
+		message(MSG_MINECONFIG, 0, NULL, isjson));
 
 	root = api_add_int(root, "GPU Count", &gpucount, false);
 	root = api_add_int(root, "PGA Count", &pgacount, false);
@@ -2741,6 +2750,42 @@ static void failoveronly(__maybe_unused SOCKETTYPE c, char *param, bool isjson, 
 	strcpy(io_buffer, message(MSG_FOO, tf, NULL, isjson));
 }
 
+static void minecoin(__maybe_unused SOCKETTYPE c, __maybe_unused char *param, bool isjson, __maybe_unused char group)
+{
+	struct api_data *root = NULL;
+	char buf[TMPBUFSIZ];
+
+	sprintf(io_buffer, isjson
+		? "%s," JSON_MINECOIN
+		: "%s" _MINECOIN ",",
+		message(MSG_MINECOIN, 0, NULL, isjson));
+
+#ifdef USE_SCRYPT
+	if (opt_scrypt)
+		root = api_add_const(root, "Hash Method", SCRYPTSTR, false);
+	else
+#endif
+		root = api_add_const(root, "Hash Method", SHA256STR, false);
+
+        mutex_lock(&ch_lock);
+	if (current_fullhash && *current_fullhash) {
+		root = api_add_timeval(root, "Current Block Time", &block_timeval, true);
+		root = api_add_string(root, "Current Block Hash", current_fullhash, true);
+	} else {
+		struct timeval t = {0,0};
+		root = api_add_timeval(root, "Current Block Time", &t, true);
+		root = api_add_const(root, "Current Block Hash", BLANK, false);
+	}
+        mutex_unlock(&ch_lock);
+
+	root = api_add_bool(root, "LP", &have_longpoll, false);
+
+	root = print_data(root, buf, isjson);
+	if (isjson)
+		strcat(buf, JSON_CLOSE);
+	strcat(io_buffer, buf);
+}
+
 static void checkcommand(__maybe_unused SOCKETTYPE c, char *param, bool isjson, char group);
 
 struct CMDS {
@@ -2792,6 +2837,7 @@ struct CMDS {
 	{ "stats",		minerstats,	false },
 	{ "check",		checkcommand,	false },
 	{ "failover-only",	failoveronly,	true },
+	{ "coin",		minecoin,	false },
 	{ NULL,			NULL,		false }
 };
 
diff --git a/cgminer.c b/cgminer.c
index aa2fb42..2123d41 100644
--- a/cgminer.c
+++ b/cgminer.c
@@ -85,7 +85,7 @@ static char packagename[255];
 
 bool opt_protocol;
 static bool opt_benchmark;
-static bool have_longpoll;
+bool have_longpoll;
 static bool want_per_device_stats;
 bool use_syslog;
 bool opt_quiet;
@@ -167,7 +167,7 @@ static pthread_mutex_t hash_lock;
 static pthread_mutex_t qd_lock;
 static pthread_mutex_t *stgd_lock;
 pthread_mutex_t console_lock;
-static pthread_mutex_t ch_lock;
+pthread_mutex_t ch_lock;
 static pthread_rwlock_t blk_lock;
 
 pthread_rwlock_t netacc_lock;
@@ -210,8 +210,10 @@ bool curses_active;
 
 static char current_block[37];
 static char *current_hash;
+char *current_fullhash;
 static char datestamp[40];
 static char blocktime[30];
+struct timeval block_timeval;
 
 struct block {
 	char hash[37];
@@ -2769,22 +2771,27 @@ static void restart_threads(void)
 static void set_curblock(char *hexstr, unsigned char *hash)
 {
 	unsigned char hash_swap[32];
-	struct timeval tv_now;
+	unsigned char block_hash_swap[32];
 	char *old_hash;
 
 	strcpy(current_block, hexstr);
-	gettimeofday(&tv_now, NULL);
-	get_timestamp(blocktime, &tv_now);
 	swap256(hash_swap, hash);
+	swap256(block_hash_swap, hash+4);
 
 	/* Don't free current_hash directly to avoid dereferencing when read
-	 * elsewhere */
+	 * elsewhere - and update block_timeval inside the same lock */
 	mutex_lock(&ch_lock);
+	gettimeofday(&block_timeval, NULL);
 	old_hash = current_hash;
 	current_hash = bin2hex(hash_swap, 16);
 	free(old_hash);
+	old_hash = current_fullhash;
+	current_fullhash = bin2hex(block_hash_swap, 32);
+	free(old_hash);
 	mutex_unlock(&ch_lock);
 
+	get_timestamp(blocktime, &block_timeval);
+
 	if (unlikely(!current_hash))
 		quit (1, "set_curblock OOM");
 	applog(LOG_INFO, "New block: %s...", current_hash);
diff --git a/miner.h b/miner.h
index cb090e4..a671992 100644
--- a/miner.h
+++ b/miner.h
@@ -552,6 +552,7 @@ static inline void rwlock_init(pthread_rwlock_t *lock)
 struct pool;
 
 extern bool opt_protocol;
+extern bool have_longpoll;
 extern char *opt_kernel_path;
 extern char *opt_socks_proxy;
 extern char *cgminer_path;
@@ -595,6 +596,7 @@ extern bool fulltest(const unsigned char *hash, const unsigned char *target);
 extern int opt_scantime;
 
 extern pthread_mutex_t console_lock;
+extern pthread_mutex_t ch_lock;
 
 extern pthread_mutex_t restart_lock;
 extern pthread_cond_t restart_cond;
@@ -669,6 +671,8 @@ extern unsigned int total_go, total_ro;
 extern const int opt_cutofftemp;
 extern int opt_log_interval;
 extern unsigned long long global_hashrate;
+extern char *current_fullhash;
+extern struct timeval block_timeval;
 
 #ifdef HAVE_OPENCL
 typedef struct {