Browse Source

Enable --generate-to option (was --coinbase-addr) to work with non-default goals

Luke Dashjr 11 years ago
parent
commit
c873c88ed3
3 changed files with 93 additions and 35 deletions
  1. 18 7
      README
  2. 73 28
      miner.c
  3. 2 0
      miner.h

+ 18 - 7
README

@@ -255,7 +255,6 @@ Options for both config file and command line:
 --cmd-idle <arg>    Execute a command when a device is allowed to be idle (rest or wait)
 --cmd-idle <arg>    Execute a command when a device is allowed to be idle (rest or wait)
 --cmd-sick <arg>    Execute a command when a device is declared sick
 --cmd-sick <arg>    Execute a command when a device is declared sick
 --cmd-dead <arg>    Execute a command when a device is declared dead
 --cmd-dead <arg>    Execute a command when a device is declared dead
---coinbase-addr <arg> Set coinbase payout address for solo mining
 --coinbase-check-addr <arg> A list of address to check against in coinbase payout list received from the previous-defined pool, separated by ','
 --coinbase-check-addr <arg> A list of address to check against in coinbase payout list received from the previous-defined pool, separated by ','
 --coinbase-check-total <arg> The least total payout amount expected in coinbase received from the previous-defined pool
 --coinbase-check-total <arg> The least total payout amount expected in coinbase received from the previous-defined pool
 --coinbase-check-percent <arg> The least benefit percentage expected for the sum of addr(s) listed in --cbaddr argument for previous-defined pool
 --coinbase-check-percent <arg> The least benefit percentage expected for the sum of addr(s) listed in --cbaddr argument for previous-defined pool
@@ -271,6 +270,7 @@ Options for both config file and command line:
 --expiry-lp <arg>   Upper bound on how many seconds after getting work we consider a share from it stale (with longpoll active) (default: 3600)
 --expiry-lp <arg>   Upper bound on how many seconds after getting work we consider a share from it stale (with longpoll active) (default: 3600)
 --failover-only     Don't leak work to backup pools when primary pool is lagging
 --failover-only     Don't leak work to backup pools when primary pool is lagging
 --failover-switch-delay <arg> Delay in seconds before switching back to a failed pool (default: 300)
 --failover-switch-delay <arg> Delay in seconds before switching back to a failed pool (default: 300)
+--generate-to <arg> Set an address to generate to for solo mining
 --force-dev-init    Always initialize devices when possible (such as bitstream uploads to some FPGAs)
 --force-dev-init    Always initialize devices when possible (such as bitstream uploads to some FPGAs)
 --kernel-path <arg> Specify a path to where bitstream and kernel files are
 --kernel-path <arg> Specify a path to where bitstream and kernel files are
 --load-balance      Change multipool strategy from failover to quota based balance
 --load-balance      Change multipool strategy from failover to quota based balance
@@ -561,13 +561,11 @@ SOLO MINING
 
 
 BFGMiner supports solo mining with any GBT-compatible bitcoin node (such as
 BFGMiner supports solo mining with any GBT-compatible bitcoin node (such as
 bitcoind). To use this mode, you need to specify the URL of your bitcoind node
 bitcoind). To use this mode, you need to specify the URL of your bitcoind node
-using the usual pool options (--url, --userpass, etc), and the --coinbase-addr
+using the usual pool options (--url, --userpass, etc), and the --generate-to
 option to specify the Bitcoin address you wish to receive the block rewards
 option to specify the Bitcoin address you wish to receive the block rewards
 mined. When you run Bitcoin Core on the same computer as your miner, the pool
 mined. When you run Bitcoin Core on the same computer as your miner, the pool
-itself will be automatically configured for you. Please be aware that solo
-mining via GBT is at this time only supported for Bitcoin, and only on for the
-default goal - ie, if you are solo mining, don't use --pool-goal on your Bitcoin
-pool(s).
+itself will be automatically configured for you (on the default goal). Please be
+aware that solo mining via GBT is at this time only supported for Bitcoin.
 
 
 IMPORTANT: If you are solo mining with more than one instance of BFGMiner (or
 IMPORTANT: If you are solo mining with more than one instance of BFGMiner (or
 any other software) per payout address, you must also specify data using the
 any other software) per payout address, you must also specify data using the
@@ -584,7 +582,20 @@ rejected; this does not indicate that it has stopped mining.
 Example solo mining usage:
 Example solo mining usage:
 
 
 bfgminer -o http://localhost:8332 -u username -p password \
 bfgminer -o http://localhost:8332 -u username -p password \
-    --coinbase-addr 1QATWksNFGeUJCWBrN4g6hGM178Lovm7Wh \
+    --generate-to 1QATWksNFGeUJCWBrN4g6hGM178Lovm7Wh \
+    --coinbase-sig "rig1: This is Joe's block!"
+
+If you want to solo mine on multiple GBT-compatible Bitcoin blockchains, you can
+specify --generate-to multiple times with a goal name prefix followed by a
+colon. Note that at this time, the coinbase sig is always shared across all
+goals/pools.
+
+Example multi-blockchain solo mining usage:
+
+bfgminer -o http://localhost:8332 -u username -p password \
+    --generate-to 1QATWksNFGeUJCWBrN4g6hGM178Lovm7Wh \
+    -o http://localhost:7221 -u user2 -p password --pool-goal mychain \
+    --generate-to mychain:1QATWksNFGeUJCWBrN4g6hGM178Lovm7Wh \
     --coinbase-sig "rig1: This is Joe's block!"
     --coinbase-sig "rig1: This is Joe's block!"
 
 
 
 

+ 73 - 28
miner.c

@@ -133,8 +133,6 @@ static bool want_gbt = true;
 static bool want_getwork = true;
 static bool want_getwork = true;
 #if BLKMAKER_VERSION > 1
 #if BLKMAKER_VERSION > 1
 static bool opt_load_bitcoin_conf = true;
 static bool opt_load_bitcoin_conf = true;
-static bool have_at_least_one_getcbaddr;
-static bytes_t opt_coinbase_script = BYTES_INIT;
 static uint32_t coinbase_script_block_id;
 static uint32_t coinbase_script_block_id;
 static uint32_t template_nonce;
 static uint32_t template_nonce;
 #endif
 #endif
@@ -1161,10 +1159,6 @@ static
 void pool_set_uri(struct pool * const pool, char * const uri)
 void pool_set_uri(struct pool * const pool, char * const uri)
 {
 {
 	pool->rpc_url = uri;
 	pool->rpc_url = uri;
-#if BLKMAKER_VERSION > 1
-	if (uri_get_param_bool(uri, "getcbaddr", false))
-		have_at_least_one_getcbaddr = true;
-#endif
 }
 }
 
 
 /* Pool variant of test and set */
 /* Pool variant of test and set */
@@ -1263,6 +1257,37 @@ char *set_b58addr(const char * const arg, bytes_t * const b)
 	bytes_assimilate_raw(b, script, scriptsz, scriptsz);
 	bytes_assimilate_raw(b, script, scriptsz, scriptsz);
 	return NULL;
 	return NULL;
 }
 }
+
+static
+char *set_generate_addr(char *arg)
+{
+	char * const colon = strchr(arg, ':');
+	struct mining_goal_info *goal;
+	if (colon)
+	{
+		colon[0] = '\0';
+		goal = get_mining_goal(arg);
+		arg = &colon[1];
+	}
+	else
+		goal = get_mining_goal("default");
+	
+	bytes_t newscript = BYTES_INIT;
+	char *estr = set_b58addr(arg, &newscript);
+	if (estr)
+	{
+		bytes_free(&newscript);
+		return estr;
+	}
+	if (!goal->generation_script)
+	{
+		goal->generation_script = malloc(sizeof(*goal->generation_script));
+		bytes_init(goal->generation_script);
+	}
+	bytes_assimilate(goal->generation_script, &newscript);
+	bytes_free(&newscript);
+	return NULL;
+}
 #endif
 #endif
 
 
 static
 static
@@ -2180,14 +2205,6 @@ static struct opt_table opt_config_table[] = {
 	OPT_WITH_ARG("--cmd-dead",
 	OPT_WITH_ARG("--cmd-dead",
 	             opt_set_charp, NULL, &cmd_dead,
 	             opt_set_charp, NULL, &cmd_dead,
 	             "Execute a command when a device is declared dead"),
 	             "Execute a command when a device is declared dead"),
-#if BLKMAKER_VERSION > 1
-	OPT_WITH_ARG("--coinbase-addr",
-		     set_b58addr, NULL, &opt_coinbase_script,
-		     "Set coinbase payout address for solo mining"),
-	OPT_WITH_ARG("--coinbase-address|--coinbase-payout|--cbaddress|--cbaddr|--cb-address|--cb-addr|--payout",
-		     set_b58addr, NULL, &opt_coinbase_script,
-		     opt_hidden),
-#endif
 #if BLKMAKER_VERSION > 0
 #if BLKMAKER_VERSION > 0
 	OPT_WITH_ARG("--coinbase-sig",
 	OPT_WITH_ARG("--coinbase-sig",
 		     set_strdup, NULL, &opt_coinbase_sig,
 		     set_strdup, NULL, &opt_coinbase_sig,
@@ -2249,6 +2266,14 @@ static struct opt_table opt_config_table[] = {
 	        opt_set_bool, &opt_force_dev_init,
 	        opt_set_bool, &opt_force_dev_init,
 	        "Always initialize devices when possible (such as bitstream uploads to some FPGAs)"),
 	        "Always initialize devices when possible (such as bitstream uploads to some FPGAs)"),
 #endif
 #endif
+#if BLKMAKER_VERSION > 1
+	OPT_WITH_ARG("--generate-to",
+	             set_generate_addr, NULL, NULL,
+	             "Set an address to generate to for solo mining"),
+	OPT_WITH_ARG("--generate-to-addr|--generate-to-address|--genaddress|--genaddr|--gen-address|--gen-addr|--generate-address|--generate-addr|--coinbase-addr|--coinbase-address|--coinbase-payout|--cbaddress|--cbaddr|--cb-address|--cb-addr|--payout",
+	             set_generate_addr, NULL, NULL,
+	             opt_hidden),
+#endif
 #ifdef HAVE_OPENCL
 #ifdef HAVE_OPENCL
 	OPT_WITH_ARG("--gpu-dyninterval",
 	OPT_WITH_ARG("--gpu-dyninterval",
 		     set_int_1_to_65535, opt_show_intval, &opt_dynamic_interval,
 		     set_int_1_to_65535, opt_show_intval, &opt_dynamic_interval,
@@ -3112,12 +3137,23 @@ int work_ntime_range(struct work * const work, const struct timeval * const tvp_
 
 
 #if BLKMAKER_VERSION > 1
 #if BLKMAKER_VERSION > 1
 static
 static
-void refresh_bitcoind_address(const bool fresh)
+bool goal_has_at_least_one_getcbaddr(const struct mining_goal_info * const goal)
+{
+	for (int i = 0; i < total_pools; ++i)
+	{
+		struct pool * const pool = pools[i];
+		if (uri_get_param_bool(pool->rpc_url, "getcbaddr", false))
+			return true;
+	}
+	return false;
+}
+
+static
+void refresh_bitcoind_address(struct mining_goal_info * const goal, const bool fresh)
 {
 {
-	struct mining_goal_info * const goal = get_mining_goal("default");
 	struct blockchain_info * const blkchain = goal->blkchain;
 	struct blockchain_info * const blkchain = goal->blkchain;
 	
 	
-	if (!have_at_least_one_getcbaddr)
+	if (!goal_has_at_least_one_getcbaddr(goal))
 		return;
 		return;
 	
 	
 	char getcbaddr_req[60];
 	char getcbaddr_req[60];
@@ -3134,7 +3170,6 @@ void refresh_bitcoind_address(const bool fresh)
 		if (!uri_get_param_bool(pool->rpc_url, "getcbaddr", false))
 		if (!uri_get_param_bool(pool->rpc_url, "getcbaddr", false))
 			continue;
 			continue;
 		if (pool->goal != goal)
 		if (pool->goal != goal)
-			// TODO: Multi-blockchain support
 			continue;
 			continue;
 		
 		
 		applog(LOG_DEBUG, "Refreshing coinbase address from pool %d", pool->pool_no);
 		applog(LOG_DEBUG, "Refreshing coinbase address from pool %d", pool->pool_no);
@@ -3176,12 +3211,20 @@ void refresh_bitcoind_address(const bool fresh)
 			applog(LOG_WARNING, "Error %cetting coinbase address from pool %d: %s", 's', pool->pool_no, s2);
 			applog(LOG_WARNING, "Error %cetting coinbase address from pool %d: %s", 's', pool->pool_no, s2);
 			continue;
 			continue;
 		}
 		}
-		if (bytes_eq(&newscript, &opt_coinbase_script))
+		if (goal->generation_script)
 		{
 		{
-			applog(LOG_DEBUG, "Pool %d returned coinbase address already in use (%s)", pool->pool_no, s2);
-			break;
+			if (bytes_eq(&newscript, goal->generation_script))
+			{
+				applog(LOG_DEBUG, "Pool %d returned coinbase address already in use (%s)", pool->pool_no, s2);
+				break;
+			}
 		}
 		}
-		bytes_assimilate(&opt_coinbase_script, &newscript);
+		else
+		{
+			goal->generation_script = malloc(sizeof(*goal->generation_script));
+			bytes_init(goal->generation_script);
+		}
+		bytes_assimilate(goal->generation_script, &newscript);
 		coinbase_script_block_id = blkchain->currentblk->block_id;
 		coinbase_script_block_id = blkchain->currentblk->block_id;
 		applog(LOG_NOTICE, "Now using coinbase address %s, provided by pool %d", s, pool->pool_no);
 		applog(LOG_NOTICE, "Now using coinbase address %s, provided by pool %d", s, pool->pool_no);
 		break;
 		break;
@@ -3226,17 +3269,18 @@ static bool work_decode(struct pool *pool, struct work *work, json_t *val)
 		}
 		}
 		work->rolltime = blkmk_time_left(tmpl, tv_now.tv_sec);
 		work->rolltime = blkmk_time_left(tmpl, tv_now.tv_sec);
 #if BLKMAKER_VERSION > 1
 #if BLKMAKER_VERSION > 1
+		struct mining_goal_info * const goal = pool->goal;
 		const uint32_t tmpl_block_id = ((uint32_t*)tmpl->prevblk)[0];
 		const uint32_t tmpl_block_id = ((uint32_t*)tmpl->prevblk)[0];
 		if ((!tmpl->cbtxn) && coinbase_script_block_id != tmpl_block_id)
 		if ((!tmpl->cbtxn) && coinbase_script_block_id != tmpl_block_id)
-			refresh_bitcoind_address(false);
-		if (bytes_len(&opt_coinbase_script) && get_mining_goal("default") == pool->goal)
+			refresh_bitcoind_address(goal, false);
+		if (goal->generation_script)
 		{
 		{
 			bool newcb;
 			bool newcb;
 #if BLKMAKER_VERSION > 2
 #if BLKMAKER_VERSION > 2
-			blkmk_init_generation2(tmpl, bytes_buf(&opt_coinbase_script), bytes_len(&opt_coinbase_script), &newcb);
+			blkmk_init_generation2(tmpl, bytes_buf(goal->generation_script), bytes_len(goal->generation_script), &newcb);
 #else
 #else
 			newcb = !tmpl->cbtxn;
 			newcb = !tmpl->cbtxn;
-			blkmk_init_generation(tmpl, bytes_buf(&opt_coinbase_script), bytes_len(&opt_coinbase_script));
+			blkmk_init_generation(tmpl, bytes_buf(goal->generation_script), bytes_len(goal->generation_script));
 #endif
 #endif
 			if (newcb)
 			if (newcb)
 			{
 			{
@@ -5623,7 +5667,8 @@ static char *prepare_rpc_req2(struct work *work, enum pool_protocol proto, const
 				goto gbtfail;
 				goto gbtfail;
 			caps |= GBT_LONGPOLL;
 			caps |= GBT_LONGPOLL;
 #if BLKMAKER_VERSION > 1
 #if BLKMAKER_VERSION > 1
-			if ((bytes_len(&opt_coinbase_script) || have_at_least_one_getcbaddr) && get_mining_goal("default") == pool->goal)
+			const struct mining_goal_info * const goal = pool->goal;
+			if (goal->generation_script || goal_has_at_least_one_getcbaddr(goal))
 				caps |= GBT_CBVALUE;
 				caps |= GBT_CBVALUE;
 #endif
 #endif
 			json_t *req = blktmpl_request_jansson(caps, lpid);
 			json_t *req = blktmpl_request_jansson(caps, lpid);
@@ -11639,7 +11684,7 @@ err:
 	if (rpcssl == -101)
 	if (rpcssl == -101)
 		rpcssl = 0;
 		rpcssl = 0;
 	
 	
-	const bool have_cbaddr = bytes_len(&opt_coinbase_script);
+	const bool have_cbaddr = get_mining_goal("default")->generation_script;
 	
 	
 	const int uri_sz = 0x30;
 	const int uri_sz = 0x30;
 	char * const uri = malloc(uri_sz);
 	char * const uri = malloc(uri_sz);

+ 2 - 0
miner.h

@@ -1149,6 +1149,8 @@ struct mining_goal_info {
 	
 	
 	struct blockchain_info *blkchain;
 	struct blockchain_info *blkchain;
 	
 	
+	bytes_t *generation_script;  // was opt_coinbase_script
+	
 	double current_diff;
 	double current_diff;
 	char current_diff_str[ALLOC_H2B_SHORTV];  // was global block_diff
 	char current_diff_str[ALLOC_H2B_SHORTV];  // was global block_diff
 	char net_hashrate[ALLOC_H2B_SHORT];
 	char net_hashrate[ALLOC_H2B_SHORT];