Browse Source

Stratum: Split actual work generation away from the current pool data

Luke Dashjr 12 years ago
parent
commit
a3c0318194
2 changed files with 38 additions and 26 deletions
  1. 35 26
      miner.c
  2. 3 0
      miner.h

+ 35 - 26
miner.c

@@ -7923,17 +7923,11 @@ void set_target(unsigned char *dest_target, double diff)
  * other means to detect when the pool has died in stratum_thread */
  * other means to detect when the pool has died in stratum_thread */
 static void gen_stratum_work(struct pool *pool, struct work *work)
 static void gen_stratum_work(struct pool *pool, struct work *work)
 {
 {
-	unsigned char *coinbase, merkle_root[32], merkle_sha[64];
-	uint8_t *merkle_bin;
-	uint32_t *data32, *swap32;
-	int i;
-
 	clean_work(work);
 	clean_work(work);
-
+	
 	cg_wlock(&pool->data_lock);
 	cg_wlock(&pool->data_lock);
-
-	/* Generate coinbase */
-	coinbase = bytes_buf(&pool->swork.coinbase);
+	pool->swork.data_lock_p = &pool->data_lock;
+	
 	bytes_resize(&work->nonce2, pool->n2size);
 	bytes_resize(&work->nonce2, pool->n2size);
 #ifndef __OPTIMIZE__
 #ifndef __OPTIMIZE__
 	if (pool->nonce2sz < pool->n2size)
 	if (pool->nonce2sz < pool->n2size)
@@ -7947,17 +7941,35 @@ static void gen_stratum_work(struct pool *pool, struct work *work)
 	       &pool->nonce2,
 	       &pool->nonce2,
 #endif
 #endif
 	       pool->nonce2sz);
 	       pool->nonce2sz);
-	memcpy(&coinbase[pool->swork.nonce2_offset], bytes_buf(&work->nonce2), pool->n2size);
 	pool->nonce2++;
 	pool->nonce2++;
+	
+	work->pool = pool;
+	work->work_restart_id = work->pool->work_restart_id;
+	gen_stratum_work2(work, &pool->swork, pool->nonce1);
+	
+	cgtime(&work->tv_staged);
+}
+
+void gen_stratum_work2(struct work *work, struct stratum_work *swork, const char *nonce1)
+{
+	unsigned char *coinbase, merkle_root[32], merkle_sha[64];
+	uint8_t *merkle_bin;
+	uint32_t *data32, *swap32;
+	int i;
 
 
-	/* Downgrade to a read lock to read off the pool variables */
-	cg_dwlock(&pool->data_lock);
+	/* Generate coinbase */
+	coinbase = bytes_buf(&swork->coinbase);
+	memcpy(&coinbase[swork->nonce2_offset], bytes_buf(&work->nonce2), bytes_len(&work->nonce2));
+
+	/* Downgrade to a read lock to read off the variables */
+	if (swork->data_lock_p)
+		cg_dwlock(swork->data_lock_p);
 
 
 	/* Generate merkle root */
 	/* Generate merkle root */
-	gen_hash(coinbase, merkle_root, bytes_len(&pool->swork.coinbase));
+	gen_hash(coinbase, merkle_root, bytes_len(&swork->coinbase));
 	memcpy(merkle_sha, merkle_root, 32);
 	memcpy(merkle_sha, merkle_root, 32);
-	merkle_bin = bytes_buf(&pool->swork.merkle_bin);
-	for (i = 0; i < pool->swork.merkles; ++i, merkle_bin += 32) {
+	merkle_bin = bytes_buf(&swork->merkle_bin);
+	for (i = 0; i < swork->merkles; ++i, merkle_bin += 32) {
 		memcpy(merkle_sha + 32, merkle_bin, 32);
 		memcpy(merkle_sha + 32, merkle_bin, 32);
 		gen_hash(merkle_sha, merkle_root, 64);
 		gen_hash(merkle_sha, merkle_root, 64);
 		memcpy(merkle_sha, merkle_root, 32);
 		memcpy(merkle_sha, merkle_root, 32);
@@ -7966,21 +7978,22 @@ static void gen_stratum_work(struct pool *pool, struct work *work)
 	swap32 = (uint32_t *)merkle_root;
 	swap32 = (uint32_t *)merkle_root;
 	flip32(swap32, data32);
 	flip32(swap32, data32);
 	
 	
-	memcpy(&work->data[0], pool->swork.header1, 36);
+	memcpy(&work->data[0], swork->header1, 36);
 	memcpy(&work->data[36], merkle_root, 32);
 	memcpy(&work->data[36], merkle_root, 32);
-	*((uint32_t*)&work->data[68]) = htobe32(pool->swork.ntime + timer_elapsed(&pool->swork.tv_received, NULL));
-	memcpy(&work->data[72], pool->swork.diffbits, 4);
+	*((uint32_t*)&work->data[68]) = htobe32(swork->ntime + timer_elapsed(&swork->tv_received, NULL));
+	memcpy(&work->data[72], swork->diffbits, 4);
 	memset(&work->data[76], 0, 4);  // nonce
 	memset(&work->data[76], 0, 4);  // nonce
 	memcpy(&work->data[80], workpadding_bin, 48);
 	memcpy(&work->data[80], workpadding_bin, 48);
 
 
 	/* Store the stratum work diff to check it still matches the pool's
 	/* Store the stratum work diff to check it still matches the pool's
 	 * stratum diff when submitting shares */
 	 * stratum diff when submitting shares */
-	work->sdiff = pool->swork.diff;
+	work->sdiff = swork->diff;
 
 
 	/* Copy parameters required for share submission */
 	/* Copy parameters required for share submission */
-	work->job_id = strdup(pool->swork.job_id);
-	work->nonce1 = strdup(pool->nonce1);
-	cg_runlock(&pool->data_lock);
+	work->job_id = strdup(swork->job_id);
+	work->nonce1 = strdup(nonce1);
+	if (swork->data_lock_p)
+		cg_runlock(swork->data_lock_p);
 
 
 	if (opt_debug)
 	if (opt_debug)
 	{
 	{
@@ -7997,16 +8010,12 @@ static void gen_stratum_work(struct pool *pool, struct work *work)
 	set_target(work->target, work->sdiff);
 	set_target(work->target, work->sdiff);
 
 
 	local_work++;
 	local_work++;
-	work->pool = pool;
 	work->stratum = true;
 	work->stratum = true;
 	work->blk.nonce = 0;
 	work->blk.nonce = 0;
 	work->id = total_work++;
 	work->id = total_work++;
 	work->longpoll = false;
 	work->longpoll = false;
 	work->getwork_mode = GETWORK_MODE_STRATUM;
 	work->getwork_mode = GETWORK_MODE_STRATUM;
-	work->work_restart_id = work->pool->work_restart_id;
 	calc_diff(work, 0);
 	calc_diff(work, 0);
-
-	cgtime(&work->tv_staged);
 }
 }
 
 
 void request_work(struct thr_info *thr)
 void request_work(struct thr_info *thr)

+ 3 - 0
miner.h

@@ -1151,6 +1151,8 @@ struct stratum_work {
 	bool transparency_probed;
 	bool transparency_probed;
 	struct timeval tv_transparency;
 	struct timeval tv_transparency;
 	bool opaque;
 	bool opaque;
+	
+	cglock_t *data_lock_p;
 };
 };
 
 
 #define RBUFSIZE 8192
 #define RBUFSIZE 8192
@@ -1329,6 +1331,7 @@ struct work {
 
 
 extern void get_datestamp(char *, size_t, time_t);
 extern void get_datestamp(char *, size_t, time_t);
 #define get_now_datestamp(buf, bufsz)  get_datestamp(buf, bufsz, INVALID_TIMESTAMP)
 #define get_now_datestamp(buf, bufsz)  get_datestamp(buf, bufsz, INVALID_TIMESTAMP)
+extern void gen_stratum_work2(struct work *, struct stratum_work *, const char *nonce1);
 extern void inc_hw_errors2(struct thr_info *thr, const struct work *work, const uint32_t *bad_nonce_p);
 extern void inc_hw_errors2(struct thr_info *thr, const struct work *work, const uint32_t *bad_nonce_p);
 extern void inc_hw_errors(struct thr_info *, const struct work *, const uint32_t bad_nonce);
 extern void inc_hw_errors(struct thr_info *, const struct work *, const uint32_t bad_nonce);
 #define inc_hw_errors_only(thr)  inc_hw_errors(thr, NULL, 0)
 #define inc_hw_errors_only(thr)  inc_hw_errors(thr, NULL, 0)