Browse Source

SSM: Track proxy share difficulties

Luke Dashjr 11 years ago
parent
commit
5b072e557b
1 changed files with 43 additions and 10 deletions
  1. 43 10
      driver-stratum.c

+ 43 - 10
driver-stratum.c

@@ -36,6 +36,7 @@
 #define _ssm_client_xnonce2sz  work2d_xnonce2sz
 #define _ssm_client_xnonce2sz  work2d_xnonce2sz
 static char *_ssm_notify;
 static char *_ssm_notify;
 static int _ssm_notify_sz;
 static int _ssm_notify_sz;
+static struct stratumsrv_job *_ssm_last_ssj;
 static struct event *ev_notify;
 static struct event *ev_notify;
 static notifier_t _ssm_update_notifier;
 static notifier_t _ssm_update_notifier;
 
 
@@ -44,6 +45,7 @@ struct stratumsrv_job {
 	
 	
 	struct timeval tv_prepared;
 	struct timeval tv_prepared;
 	struct stratum_work swork;
 	struct stratum_work swork;
+	float job_pdiff[WORK2D_MAX_DIVISIONS+1];
 	
 	
 	UT_hash_handle hh;
 	UT_hash_handle hh;
 };
 };
@@ -61,12 +63,26 @@ struct stratumsrv_conn {
 	uint32_t xnonce1_le;
 	uint32_t xnonce1_le;
 	struct timeval tv_hashes_done;
 	struct timeval tv_hashes_done;
 	bool hashes_done_ext;
 	bool hashes_done_ext;
+	float current_share_pdiff;
+	float desired_share_pdiff;
 	
 	
 	struct stratumsrv_conn *next;
 	struct stratumsrv_conn *next;
 };
 };
 
 
 static struct stratumsrv_conn *_ssm_connections;
 static struct stratumsrv_conn *_ssm_connections;
 
 
+static
+void stratumsrv_send_set_difficulty(struct stratumsrv_conn * const conn, const float share_pdiff)
+{
+	struct bufferevent * const bev = conn->bev;
+	char buf[0x100];
+	const double bdiff = pdiff_to_bdiff(share_pdiff);
+	conn->current_share_pdiff = share_pdiff;
+	const int prec = double_find_precision(bdiff, 10.);
+	const size_t bufsz = snprintf(buf, sizeof(buf), "{\"params\":[%.*f],\"id\":null,\"method\":\"mining.set_difficulty\"}\n", prec, bdiff);
+	bufferevent_write(bev, buf, bufsz);
+}
+
 #define _ssm_gen_dummy_work work2d_gen_dummy_work
 #define _ssm_gen_dummy_work work2d_gen_dummy_work
 
 
 static
 static
@@ -135,11 +151,19 @@ bool stratumsrv_update_notify_str(struct pool * const pool, bool clean)
 	assert(_ssm_notify_sz <= bufsz);
 	assert(_ssm_notify_sz <= bufsz);
 	free(_ssm_notify);
 	free(_ssm_notify);
 	_ssm_notify = buf;
 	_ssm_notify = buf;
+	_ssm_last_ssj = ssj;
 	
 	
+	float pdiff = target_diff(ssj->swork.target);
 	LL_FOREACH(_ssm_connections, conn)
 	LL_FOREACH(_ssm_connections, conn)
 	{
 	{
 		if (unlikely(!conn->xnonce1_le))
 		if (unlikely(!conn->xnonce1_le))
 			continue;
 			continue;
+		float conn_pdiff = conn->desired_share_pdiff;
+		if (pdiff < conn_pdiff)
+			conn_pdiff = pdiff;
+		ssj->job_pdiff[conn->xnonce1_le] = conn_pdiff;
+		if (conn_pdiff != conn->current_share_pdiff)
+			stratumsrv_send_set_difficulty(conn, conn_pdiff);
 		bufferevent_write(conn->bev, _ssm_notify, _ssm_notify_sz);
 		bufferevent_write(conn->bev, _ssm_notify, _ssm_notify_sz);
 	}
 	}
 	
 	
@@ -203,6 +227,7 @@ void stratumsrv_boot_all_subscribed(const char * const msg)
 	
 	
 	free(_ssm_notify);
 	free(_ssm_notify);
 	_ssm_notify = NULL;
 	_ssm_notify = NULL;
+	_ssm_last_ssj = NULL;
 	
 	
 	// Boot all connections
 	// Boot all connections
 	LL_FOREACH_SAFE(_ssm_connections, conn, tmp_conn)
 	LL_FOREACH_SAFE(_ssm_connections, conn, tmp_conn)
@@ -316,8 +341,9 @@ void _stratumsrv_success(struct bufferevent * const bev, const char * const idst
 }
 }
 
 
 static
 static
-void stratumsrv_mining_subscribe(struct bufferevent *bev, json_t *params, const char *idstr, uint32_t *xnonce1_p)
+void stratumsrv_mining_subscribe(struct bufferevent * const bev, json_t * const params, const char * const idstr, struct stratumsrv_conn * const conn)
 {
 {
+	uint32_t * const xnonce1_p = &conn->xnonce1_le;
 	char buf[90 + strlen(idstr) + (_ssm_client_octets * 2 * 2) + 0x10];
 	char buf[90 + strlen(idstr) + (_ssm_client_octets * 2 * 2) + 0x10];
 	char xnonce1x[(_ssm_client_octets * 2) + 1];
 	char xnonce1x[(_ssm_client_octets * 2) + 1];
 	int bufsz;
 	int bufsz;
@@ -339,12 +365,12 @@ void stratumsrv_mining_subscribe(struct bufferevent *bev, json_t *params, const
 	bin2hex(xnonce1x, xnonce1_p, _ssm_client_octets);
 	bin2hex(xnonce1x, xnonce1_p, _ssm_client_octets);
 	bufsz = sprintf(buf, "{\"id\":%s,\"result\":[[[\"mining.set_difficulty\",\"x\"],[\"mining.notify\",\"%s\"]],\"%s\",%d],\"error\":null}\n", idstr, xnonce1x, xnonce1x, _ssm_client_xnonce2sz);
 	bufsz = sprintf(buf, "{\"id\":%s,\"result\":[[[\"mining.set_difficulty\",\"x\"],[\"mining.notify\",\"%s\"]],\"%s\",%d],\"error\":null}\n", idstr, xnonce1x, xnonce1x, _ssm_client_xnonce2sz);
 	bufferevent_write(bev, buf, bufsz);
 	bufferevent_write(bev, buf, bufsz);
-	bufferevent_write(bev, "{\"params\":[", 11);
-	if (opt_scrypt)
-		bufferevent_write(bev, "0.000015258556232", 17);
-	else
-		bufferevent_write(bev, "0.9999847412109375", 18);
-	bufferevent_write(bev, "],\"id\":null,\"method\":\"mining.set_difficulty\"}\n", 46);
+	
+	float pdiff = target_diff(_ssm_last_ssj->swork.target);
+	if (pdiff > conn->desired_share_pdiff)
+		pdiff = conn->desired_share_pdiff;
+	_ssm_last_ssj->job_pdiff[*xnonce1_p] = pdiff;
+	stratumsrv_send_set_difficulty(conn, pdiff);
 	bufferevent_write(bev, _ssm_notify, _ssm_notify_sz);
 	bufferevent_write(bev, _ssm_notify, _ssm_notify_sz);
 }
 }
 
 
@@ -373,7 +399,6 @@ void stratumsrv_mining_submit(struct bufferevent *bev, json_t *params, const cha
 	const char * const nonce = __json_array_string(params, 4);
 	const char * const nonce = __json_array_string(params, 4);
 	uint8_t xnonce2[work2d_xnonce2sz];
 	uint8_t xnonce2[work2d_xnonce2sz];
 	uint32_t ntime_n, nonce_n;
 	uint32_t ntime_n, nonce_n;
-	const float nonce_diff = opt_scrypt ? (1./0x10000) : 1.;
 	bool is_stale;
 	bool is_stale;
 	
 	
 	if (unlikely(!client))
 	if (unlikely(!client))
@@ -395,6 +420,13 @@ void stratumsrv_mining_submit(struct bufferevent *bev, json_t *params, const cha
 	if (!ssj)
 	if (!ssj)
 		return_stratumsrv_failure(21, "Job not found");
 		return_stratumsrv_failure(21, "Job not found");
 	
 	
+	float nonce_diff = ssj->job_pdiff[*xnonce1_p];
+	if (unlikely(nonce_diff <= 0))
+	{
+		applog(LOG_WARNING, "Unknown share difficulty for SSM job %s", ssj->my_job_id);
+		nonce_diff = conn->current_share_pdiff;
+	}
+	
 	hex2bin(xnonce2, extranonce2, work2d_xnonce2sz);
 	hex2bin(xnonce2, extranonce2, work2d_xnonce2sz);
 	
 	
 	// Submit nonce
 	// Submit nonce
@@ -416,7 +448,7 @@ void stratumsrv_mining_submit(struct bufferevent *bev, json_t *params, const cha
 		timer_set_now(&tv_now);
 		timer_set_now(&tv_now);
 		timersub(&tv_now, &conn->tv_hashes_done, &tv_delta);
 		timersub(&tv_now, &conn->tv_hashes_done, &tv_delta);
 		conn->tv_hashes_done = tv_now;
 		conn->tv_hashes_done = tv_now;
-		const uint64_t hashes = opt_scrypt ? 0x10000 : 0x100000000;
+		const uint64_t hashes = (float)0x100000000 * nonce_diff;
 		hashes_done(thr, hashes, &tv_delta, NULL);
 		hashes_done(thr, hashes, &tv_delta, NULL);
 	}
 	}
 }
 }
@@ -496,7 +528,7 @@ errout:
 		stratumsrv_mining_authorize(bev, params, idstr, &conn->xnonce1_le);
 		stratumsrv_mining_authorize(bev, params, idstr, &conn->xnonce1_le);
 	else
 	else
 	if (!strcasecmp(method, "mining.subscribe"))
 	if (!strcasecmp(method, "mining.subscribe"))
-		stratumsrv_mining_subscribe(bev, params, idstr, &conn->xnonce1_le);
+		stratumsrv_mining_subscribe(bev, params, idstr, conn);
 	else
 	else
 		_stratumsrv_failure(bev, idstr, -3, "Method not supported");
 		_stratumsrv_failure(bev, idstr, -3, "Method not supported");
 	
 	
@@ -557,6 +589,7 @@ void stratumlistener(struct evconnlistener *listener, evutil_socket_t sock, stru
 	conn = malloc(sizeof(*conn));
 	conn = malloc(sizeof(*conn));
 	*conn = (struct stratumsrv_conn){
 	*conn = (struct stratumsrv_conn){
 		.bev = bev,
 		.bev = bev,
+		.desired_share_pdiff = opt_scrypt ? (1./0x10000) : 1.,
 	};
 	};
 	LL_PREPEND(_ssm_connections, conn);
 	LL_PREPEND(_ssm_connections, conn);
 	bufferevent_setcb(bev, stratumsrv_read, NULL, stratumsrv_event, conn);
 	bufferevent_setcb(bev, stratumsrv_read, NULL, stratumsrv_event, conn);