Browse Source

Support for BIP23 BPE request target extension via new --request-diff option

Luke Dashjr 13 years ago
parent
commit
bed531938c
3 changed files with 89 additions and 11 deletions
  1. 1 0
      README
  2. 87 11
      miner.c
  3. 1 0
      util.c

+ 1 - 0
README

@@ -162,6 +162,7 @@ Options for both config file and command line:
 --quiet|-q          Disable logging output, display status and errors
 --real-quiet        Disable all output
 --remove-disabled   Remove disabled devices entirely, as if they didn't exist
+--request-diff <arg> Request a specific difficulty from pools (default: 1.0)
 --retries <arg>     Number of times to retry failed submissions before giving up (-1 means never) (default: -1)
 --rotate <arg>      Change multipool strategy from failover to regularly rotate at N minutes (default: 0)
 --round-robin       Change multipool strategy from failover to round robin on failure

+ 87 - 11
miner.c

@@ -105,6 +105,9 @@ static uint32_t template_nonce;
 const
 #endif
 char *opt_coinbase_sig;
+char *request_target_str;
+float request_pdiff = 1.0;
+double request_bdiff;
 static bool want_stratum = true;
 bool have_longpoll;
 int opt_skip_checks;
@@ -559,6 +562,22 @@ static char *set_b58addr(const char *arg, struct _cbscript_t *p)
 }
 #endif
 
+static void bdiff_target_leadzero(unsigned char *target, double diff);
+
+char *set_request_diff(const char *arg, float *p)
+{
+	unsigned char target[32];
+	char *e = opt_set_floatval(arg, p);
+	if (e)
+		return e;
+	
+	request_bdiff = (double)*p * 0.9999847412109375;
+	bdiff_target_leadzero(target, request_bdiff);
+	request_target_str = bin2hex(target, 32);
+	
+	return NULL;
+}
+
 #ifdef HAVE_LIBUDEV
 #include <libudev.h>
 #endif
@@ -1305,6 +1324,9 @@ static struct opt_table opt_config_table[] = {
 	OPT_WITHOUT_ARG("--remove-disabled",
 		     opt_set_bool, &opt_removedisabled,
 	         "Remove disabled devices entirely, as if they didn't exist"),
+	OPT_WITH_ARG("--request-diff",
+	             set_request_diff, opt_show_floatval, &request_pdiff,
+	             "Request a specific difficulty from pools"),
 	OPT_WITH_ARG("--retries",
 		     opt_set_intval, opt_show_intval, &opt_retries,
 		     "Number of times to retry failed submissions before giving up (-1 means never)"),
@@ -3055,7 +3077,50 @@ static void update_last_work(struct work *work)
 	mutex_unlock(&pool->last_work_lock);
 }
 
-static char *prepare_rpc_req(struct work *work, enum pool_protocol proto, const char *lpid)
+static
+void gbt_req_target(json_t *req)
+{
+	json_t *j;
+	json_t *n;
+	
+	if (!request_target_str)
+		return;
+	
+	j = json_object_get(req, "params");
+	if (!j)
+	{
+		n = json_array();
+		if (!n)
+			return;
+		if (json_object_set_new(req, "params", n))
+			goto erradd;
+		j = n;
+	}
+	
+	n = json_array_get(j, 0);
+	if (!n)
+	{
+		n = json_object();
+		if (!n)
+			return;
+		if (json_array_append_new(j, n))
+			goto erradd;
+	}
+	j = n;
+	
+	n = json_string(request_target_str);
+	if (!n)
+		return;
+	if (json_object_set_new(j, "target", n))
+		goto erradd;
+	
+	return;
+
+erradd:
+	json_decref(n);
+}
+
+static char *prepare_rpc_req2(struct work *work, enum pool_protocol proto, const char *lpid, bool probe)
 {
 	char *rpc_req;
 
@@ -3080,6 +3145,10 @@ static char *prepare_rpc_req(struct work *work, enum pool_protocol proto, const
 			json_t *req = blktmpl_request_jansson(caps, lpid);
 			if (!req)
 				goto gbtfail;
+			
+			if (probe)
+				gbt_req_target(req);
+			
 			rpc_req = json_dumps(req, 0);
 			if (!rpc_req)
 				goto gbtfail;
@@ -3099,6 +3168,9 @@ gbtfail2:
 	return NULL;
 }
 
+#define prepare_rpc_req(work, proto, lpid)  prepare_rpc_req2(work, proto, lpid, false)
+#define prepare_rpc_req_probe(work, proto, lpid)  prepare_rpc_req2(work, proto, lpid, true)
+
 static const char *pool_protocol_name(enum pool_protocol proto)
 {
 	switch (proto) {
@@ -6023,7 +6095,7 @@ static bool pool_active(struct pool *pool, bool pinging)
 	proto = want_gbt ? PLP_GETBLOCKTEMPLATE : PLP_GETWORK;
 
 tryagain:
-	rpc_req = prepare_rpc_req(work, proto, NULL);
+	rpc_req = prepare_rpc_req_probe(work, proto, NULL);
 	work->pool = pool;
 	if (!rpc_req)
 		return false;
@@ -6265,9 +6337,8 @@ void gen_hash(unsigned char *data, unsigned char *hash, int len)
  * 0x00000000ffff0000000000000000000000000000000000000000000000000000
  * so we use a big endian 64 bit unsigned integer centred on the 5th byte to
  * cover a huge range of difficulty targets, though not all 256 bits' worth */
-static void set_work_target(struct work *work, double diff)
+static void bdiff_target_leadzero(unsigned char *target, double diff)
 {
-	unsigned char target[32];
 	uint64_t *data64, h64;
 	double d64;
 
@@ -6278,30 +6349,35 @@ static void set_work_target(struct work *work, double diff)
 
 	memset(target, 0, 32);
 	if (d64 < 18446744073709551616.0) {
-		unsigned char rtarget[32];
-
+		unsigned char *rtarget = target;
 		memset(rtarget, 0, 32);
 		if (opt_scrypt)
 			data64 = (uint64_t *)(rtarget + 2);
 		else
 			data64 = (uint64_t *)(rtarget + 4);
 		*data64 = htobe64(h64);
-		swab256(target, rtarget);
 	} else {
 		/* Support for the classic all FFs just-below-1 diff */
 		if (opt_scrypt)
-			memset(target, 0xff, 30);
+			memset(&target[2], 0xff, 30);
 		else
-			memset(target, 0xff, 28);
+			memset(&target[4], 0xff, 28);
 	}
+}
 
+static inline
+void set_work_target(struct work *work, double diff)
+{
+	unsigned char rtarget[32];
+	bdiff_target_leadzero(rtarget, diff);
+	swab256(work->target, rtarget);
+	
 	if (opt_debug) {
-		char *htarget = bin2hex(target, 32);
+		char *htarget = bin2hex(rtarget, 32);
 
 		applog(LOG_DEBUG, "Generated target %s", htarget);
 		free(htarget);
 	}
-	memcpy(work->target, target, 32);
 }
 
 /* Generates stratum based work based on the most recent notify information

+ 1 - 0
util.c

@@ -710,6 +710,7 @@ void hash_data(unsigned char *out_hash, const unsigned char *data)
 	gen_hash(blkheader, out_hash, 80);
 }
 
+// Example output: 0000000000000000000000000000000000000000000000000000ffff00000000 (bdiff 1)
 void real_block_target(unsigned char *target, const unsigned char *data)
 {
 	uint8_t targetshift;