Browse Source

GBT: Use libblkmaker 2D work to service SSM and potentially other 2D work drivers

Luke Dashjr 12 years ago
parent
commit
d0f81e1a95
6 changed files with 86 additions and 9 deletions
  1. 1 1
      driver-stratum.c
  2. 1 1
      libblkmaker
  3. 67 7
      miner.c
  4. 3 0
      miner.h
  5. 5 0
      util.c
  6. 9 0
      util.h

+ 1 - 1
driver-stratum.c

@@ -150,7 +150,7 @@ bool stratumsrv_update_notify_str(struct pool * const pool, bool clean)
 		.pool = pool,
 		.pool = pool,
 		.work_restart_id = pool->work_restart_id,
 		.work_restart_id = pool->work_restart_id,
 		.n2size = n2size,
 		.n2size = n2size,
-		.nonce1 = strdup(pool->nonce1),
+		.nonce1 = maybe_strdup(pool->nonce1),
 	};
 	};
 	timer_set_now(&ssj->tv_prepared);
 	timer_set_now(&ssj->tv_prepared);
 	stratum_work_cpy(&ssj->swork, swork);
 	stratum_work_cpy(&ssj->swork, swork);

+ 1 - 1
libblkmaker

@@ -1 +1 @@
-Subproject commit bca8f6f5e56c547e9bbc808fb644152e44f3344d
+Subproject commit 9f5e949f7e1e0bb49bfe8eab1d99107b3114b4c7

+ 67 - 7
miner.c

@@ -2667,7 +2667,6 @@ void tmpl_incref(struct bfg_tmpl_ref * const tr)
 	mutex_unlock(&tr->mutex);
 	mutex_unlock(&tr->mutex);
 }
 }
 
 
-static
 void tmpl_decref(struct bfg_tmpl_ref * const tr)
 void tmpl_decref(struct bfg_tmpl_ref * const tr)
 {
 {
 	mutex_lock(&tr->mutex);
 	mutex_lock(&tr->mutex);
@@ -2777,11 +2776,21 @@ void pool_set_opaque(struct pool *pool, bool opaque)
 		       pool->pool_no);
 		       pool->pool_no);
 }
 }
 
 
+static double target_diff(const unsigned char *);
+
+#define GBT_XNONCESZ (sizeof(uint32_t))
+
+#if 1 // FIXME BLKMAKER_VERSION > 4
+#define blkmk_append_coinbase_safe(tmpl, append, appendsz)  \
+       blkmk_append_coinbase_safe2(tmpl, append, appendsz, GBT_XNONCESZ, false)
+#endif
+
 static bool work_decode(struct pool *pool, struct work *work, json_t *val)
 static bool work_decode(struct pool *pool, struct work *work, json_t *val)
 {
 {
 	json_t *res_val = json_object_get(val, "result");
 	json_t *res_val = json_object_get(val, "result");
 	json_t *tmp_val;
 	json_t *tmp_val;
 	bool ret = false;
 	bool ret = false;
+	struct timeval tv_now;
 
 
 	if (unlikely(detect_algo == 1)) {
 	if (unlikely(detect_algo == 1)) {
 		json_t *tmp = json_object_get(res_val, "algorithm");
 		json_t *tmp = json_object_get(res_val, "algorithm");
@@ -2790,11 +2799,11 @@ static bool work_decode(struct pool *pool, struct work *work, json_t *val)
 			detect_algo = 2;
 			detect_algo = 2;
 	}
 	}
 	
 	
+	timer_set_now(&tv_now);
+	
 	if (work->tr)
 	if (work->tr)
 	{
 	{
 		blktemplate_t * const tmpl = work->tr->tmpl;
 		blktemplate_t * const tmpl = work->tr->tmpl;
-		struct timeval tv_now;
-		cgtime(&tv_now);
 		const char *err = blktmpl_add_jansson(tmpl, res_val, tv_now.tv_sec);
 		const char *err = blktmpl_add_jansson(tmpl, res_val, tv_now.tv_sec);
 		if (err) {
 		if (err) {
 			applog(LOG_ERR, "blktmpl error: %s", err);
 			applog(LOG_ERR, "blktmpl error: %s", err);
@@ -2922,8 +2931,48 @@ static bool work_decode(struct pool *pool, struct work *work, json_t *val)
 
 
 	memset(work->hash, 0, sizeof(work->hash));
 	memset(work->hash, 0, sizeof(work->hash));
 
 
-	cgtime(&work->tv_staged);
+	work->tv_staged = tv_now;
 	
 	
+#if 1 // FIXME BLKMAKER_VERSION > 4
+	if (work->tr)
+	{
+		blktemplate_t * const tmpl = work->tr->tmpl;
+		uint8_t buf[80];
+		int16_t expire;
+		uint8_t *cbtxn;
+		size_t cbtxnsz;
+		size_t cbextranonceoffset;
+		int branchcount;
+		libblkmaker_hash_t *branches;
+		
+		if (blkmk_get_mdata(tmpl, buf, sizeof(buf), tv_now.tv_sec, &expire, &cbtxn, &cbtxnsz, &cbextranonceoffset, &branchcount, &branches, GBT_XNONCESZ))
+		{
+			struct stratum_work * const swork = &pool->swork;
+			const size_t branchdatasz = branchcount * 0x20;
+			
+			cg_wlock(&pool->data_lock);
+			swork->tr = work->tr;
+			bytes_assimilate_raw(&swork->coinbase, cbtxn, cbtxnsz, cbtxnsz);
+			swork->nonce2_offset = cbextranonceoffset;
+			bytes_assimilate_raw(&swork->merkle_bin, branches, branchdatasz, branchdatasz);
+			swork->merkles = branchcount;
+			memcpy(swork->header1, &buf[0], 36);
+			swork->ntime = le32toh(*(uint32_t *)(&buf[68]));
+			swork->tv_received = tv_now;
+			memcpy(swork->diffbits, &buf[72], 4);
+			swork->diff = target_diff(work->target);
+			free(swork->job_id);
+			swork->job_id = NULL;
+			swork->clean = true;
+			// FIXME: Do something with expire
+			pool->nonce2sz = pool->n2size = GBT_XNONCESZ;
+			pool->nonce2 = 0;
+			cg_wunlock(&pool->data_lock);
+		}
+		else
+			applog(LOG_DEBUG, "blkmk_get_mdata failed for pool %u", pool->pool_no);
+	}
+#endif  // BLKMAKER_VERSION > 4
 	pool_set_opaque(pool, !work->tr);
 	pool_set_opaque(pool, !work->tr);
 
 
 	ret = true;
 	ret = true;
@@ -8655,13 +8704,17 @@ void set_target(unsigned char *dest_target, double diff)
 void stratum_work_cpy(struct stratum_work * const dst, const struct stratum_work * const src)
 void stratum_work_cpy(struct stratum_work * const dst, const struct stratum_work * const src)
 {
 {
 	*dst = *src;
 	*dst = *src;
-	dst->job_id = strdup(src->job_id);
+	if (dst->tr)
+		tmpl_incref(dst->tr);
+	dst->job_id = maybe_strdup(src->job_id);
 	bytes_cpy(&dst->coinbase, &src->coinbase);
 	bytes_cpy(&dst->coinbase, &src->coinbase);
 	bytes_cpy(&dst->merkle_bin, &src->merkle_bin);
 	bytes_cpy(&dst->merkle_bin, &src->merkle_bin);
 }
 }
 
 
 void stratum_work_clean(struct stratum_work * const swork)
 void stratum_work_clean(struct stratum_work * const swork)
 {
 {
+	if (swork->tr)
+		tmpl_decref(swork->tr);
 	free(swork->job_id);
 	free(swork->job_id);
 	bytes_free(&swork->coinbase);
 	bytes_free(&swork->coinbase);
 	bytes_free(&swork->merkle_bin);
 	bytes_free(&swork->merkle_bin);
@@ -8669,6 +8722,13 @@ void stratum_work_clean(struct stratum_work * const swork)
 
 
 bool pool_has_usable_swork(const struct pool * const pool)
 bool pool_has_usable_swork(const struct pool * const pool)
 {
 {
+	if (pool->swork.tr)
+	{
+		// GBT
+		struct timeval tv_now;
+		timer_set_now(&tv_now);
+		return blkmk_time_left(pool->swork.tr->tmpl, tv_now.tv_sec);
+	}
 	return pool->stratum_notify;
 	return pool->stratum_notify;
 }
 }
 
 
@@ -8742,8 +8802,8 @@ void gen_stratum_work2(struct work *work, struct stratum_work *swork, const char
 	work->sdiff = swork->diff;
 	work->sdiff = swork->diff;
 
 
 	/* Copy parameters required for share submission */
 	/* Copy parameters required for share submission */
-	work->job_id = strdup(swork->job_id);
-	work->nonce1 = strdup(nonce1);
+	work->job_id = maybe_strdup(swork->job_id);
+	work->nonce1 = maybe_strdup(nonce1);
 	if (swork->data_lock_p)
 	if (swork->data_lock_p)
 		cg_runlock(swork->data_lock_p);
 		cg_runlock(swork->data_lock_p);
 
 

+ 3 - 0
miner.h

@@ -1133,6 +1133,7 @@ struct bfg_tmpl_ref {
 };
 };
 
 
 struct stratum_work {
 struct stratum_work {
+	struct bfg_tmpl_ref *tr;
 	char *job_id;
 	char *job_id;
 	bool clean;
 	bool clean;
 	
 	
@@ -1146,6 +1147,7 @@ struct stratum_work {
 	uint8_t diffbits[4];
 	uint8_t diffbits[4];
 	uint32_t ntime;
 	uint32_t ntime;
 	struct timeval tv_received;
 	struct timeval tv_received;
+	struct timeval tv_expire;
 
 
 	double diff;
 	double diff;
 
 
@@ -1418,6 +1420,7 @@ extern void tq_freeze(struct thread_q *tq);
 extern void tq_thaw(struct thread_q *tq);
 extern void tq_thaw(struct thread_q *tq);
 extern bool successful_connect;
 extern bool successful_connect;
 extern void adl(void);
 extern void adl(void);
+extern void tmpl_decref(struct bfg_tmpl_ref *);
 extern void clean_work(struct work *work);
 extern void clean_work(struct work *work);
 extern void free_work(struct work *work);
 extern void free_work(struct work *work);
 extern void __copy_work(struct work *work, const struct work *base_work);
 extern void __copy_work(struct work *work, const struct work *base_work);

+ 5 - 0
util.c

@@ -1907,6 +1907,11 @@ static bool parse_notify(struct pool *pool, json_t *val)
 	cgtime(&pool->swork.tv_received);
 	cgtime(&pool->swork.tv_received);
 	free(pool->swork.job_id);
 	free(pool->swork.job_id);
 	pool->swork.job_id = job_id;
 	pool->swork.job_id = job_id;
+	if (pool->swork.tr)
+	{
+		tmpl_decref(pool->swork.tr);
+		pool->swork.tr = NULL;
+	}
 	pool->submit_old = !clean;
 	pool->submit_old = !clean;
 	pool->swork.clean = true;
 	pool->swork.clean = true;
 	
 	

+ 9 - 0
util.h

@@ -303,6 +303,15 @@ void bytes_cpy(bytes_t *dst, const bytes_t *src)
 	memcpy(dst->buf, src->buf, dst->sz);
 	memcpy(dst->buf, src->buf, dst->sz);
 }
 }
 
 
+static inline
+void bytes_assimilate_raw(bytes_t * const b, void * const buf, const size_t bufsz, const size_t buflen)
+{
+	free(b->buf);
+	b->buf = buf;
+	b->allocsz = bufsz;
+	b->sz = buflen;
+}
+
 static inline
 static inline
 void bytes_shift(bytes_t *b, size_t shift)
 void bytes_shift(bytes_t *b, size_t shift)
 {
 {