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-sick <arg>    Execute a command when a device is declared sick
 --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-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
@@ -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)
 --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)
+--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)
 --kernel-path <arg> Specify a path to where bitstream and kernel files are
 --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
 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
 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
 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:
 
 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!"
 
 

+ 73 - 28
miner.c

@@ -133,8 +133,6 @@ static bool want_gbt = true;
 static bool want_getwork = true;
 #if BLKMAKER_VERSION > 1
 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 template_nonce;
 #endif
@@ -1161,10 +1159,6 @@ static
 void pool_set_uri(struct pool * const pool, char * const 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 */
@@ -1263,6 +1257,37 @@ char *set_b58addr(const char * const arg, bytes_t * const b)
 	bytes_assimilate_raw(b, script, scriptsz, scriptsz);
 	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
 
 static
@@ -2180,14 +2205,6 @@ static struct opt_table opt_config_table[] = {
 	OPT_WITH_ARG("--cmd-dead",
 	             opt_set_charp, NULL, &cmd_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
 	OPT_WITH_ARG("--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,
 	        "Always initialize devices when possible (such as bitstream uploads to some FPGAs)"),
 #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
 	OPT_WITH_ARG("--gpu-dyninterval",
 		     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
 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;
 	
-	if (!have_at_least_one_getcbaddr)
+	if (!goal_has_at_least_one_getcbaddr(goal))
 		return;
 	
 	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))
 			continue;
 		if (pool->goal != goal)
-			// TODO: Multi-blockchain support
 			continue;
 		
 		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);
 			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;
 		applog(LOG_NOTICE, "Now using coinbase address %s, provided by pool %d", s, pool->pool_no);
 		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);
 #if BLKMAKER_VERSION > 1
+		struct mining_goal_info * const goal = pool->goal;
 		const uint32_t tmpl_block_id = ((uint32_t*)tmpl->prevblk)[0];
 		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;
 #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
 			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
 			if (newcb)
 			{
@@ -5623,7 +5667,8 @@ static char *prepare_rpc_req2(struct work *work, enum pool_protocol proto, const
 				goto gbtfail;
 			caps |= GBT_LONGPOLL;
 #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;
 #endif
 			json_t *req = blktmpl_request_jansson(caps, lpid);
@@ -11639,7 +11684,7 @@ err:
 	if (rpcssl == -101)
 		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;
 	char * const uri = malloc(uri_sz);

+ 2 - 0
miner.h

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