mirror of
https://github.com/bitcoin/bitcoin.git
synced 2025-01-26 19:23:26 -03:00
contrib/signet/miner: increase miner search space
The miner script will call `bitcoin-util grind` to compute PoW which will try to exhaust the block's nonce field and fail if it can't find a valid hash. This behavior does not appear for low difficulty chains, but make the miner unusable for higher difficulty settings. We capture `bitcoin-util grind` exception, build a new block header with different time and try to grind again. Fixes #30102
This commit is contained in:
parent
dd42a5ddea
commit
1cf174a295
1 changed files with 28 additions and 6 deletions
|
@ -103,8 +103,9 @@ def finish_block(block, signet_solution, grind_cmd):
|
||||||
block.solve()
|
block.solve()
|
||||||
else:
|
else:
|
||||||
headhex = CBlockHeader.serialize(block).hex()
|
headhex = CBlockHeader.serialize(block).hex()
|
||||||
|
logging.debug("grinding headhex: %s", headhex)
|
||||||
cmd = grind_cmd.split(" ") + [headhex]
|
cmd = grind_cmd.split(" ") + [headhex]
|
||||||
newheadhex = subprocess.run(cmd, stdout=subprocess.PIPE, input=b"", check=True).stdout.strip()
|
newheadhex = subprocess.run(cmd, capture_output=True, input=b"", check=True).stdout.strip()
|
||||||
newhead = from_hex(CBlockHeader(), newheadhex.decode('utf8'))
|
newhead = from_hex(CBlockHeader(), newheadhex.decode('utf8'))
|
||||||
block.nNonce = newhead.nNonce
|
block.nNonce = newhead.nNonce
|
||||||
block.rehash()
|
block.rehash()
|
||||||
|
@ -314,11 +315,12 @@ def do_generate(args):
|
||||||
|
|
||||||
ultimate_target = nbits_to_target(int(args.nbits,16))
|
ultimate_target = nbits_to_target(int(args.nbits,16))
|
||||||
|
|
||||||
|
retries = 0
|
||||||
mined_blocks = 0
|
mined_blocks = 0
|
||||||
bestheader = {"hash": None}
|
bestheader = {"hash": None}
|
||||||
lastheader = None
|
lastheader = None
|
||||||
while max_blocks is None or mined_blocks < max_blocks:
|
|
||||||
|
|
||||||
|
while max_blocks is None or mined_blocks < max_blocks:
|
||||||
# current status?
|
# current status?
|
||||||
bci = json.loads(args.bcli("getblockchaininfo"))
|
bci = json.loads(args.bcli("getblockchaininfo"))
|
||||||
|
|
||||||
|
@ -338,7 +340,7 @@ def do_generate(args):
|
||||||
now = time.time()
|
now = time.time()
|
||||||
if args.set_block_time is not None:
|
if args.set_block_time is not None:
|
||||||
logging.debug("Setting start time to %d", args.set_block_time)
|
logging.debug("Setting start time to %d", args.set_block_time)
|
||||||
mine_time = args.set_block_time
|
mine_time = args.set_block_time + retries
|
||||||
action_time = now
|
action_time = now
|
||||||
is_mine = True
|
is_mine = True
|
||||||
elif bestheader["height"] == 0:
|
elif bestheader["height"] == 0:
|
||||||
|
@ -350,7 +352,7 @@ def do_generate(args):
|
||||||
is_mine = True
|
is_mine = True
|
||||||
else:
|
else:
|
||||||
time_delta = next_block_delta(int(bestheader["bits"], 16), bci["bestblockhash"], ultimate_target, args.poisson, args.max_interval)
|
time_delta = next_block_delta(int(bestheader["bits"], 16), bci["bestblockhash"], ultimate_target, args.poisson, args.max_interval)
|
||||||
mine_time = bestheader["time"] + time_delta
|
mine_time = bestheader["time"] + time_delta + retries
|
||||||
|
|
||||||
is_mine = next_block_is_mine(bci["bestblockhash"], my_blocks)
|
is_mine = next_block_is_mine(bci["bestblockhash"], my_blocks)
|
||||||
|
|
||||||
|
@ -406,16 +408,36 @@ def do_generate(args):
|
||||||
|
|
||||||
# mine block
|
# mine block
|
||||||
logging.debug("Mining block delta=%s start=%s mine=%s", seconds_to_hms(mine_time-bestheader["time"]), mine_time, is_mine)
|
logging.debug("Mining block delta=%s start=%s mine=%s", seconds_to_hms(mine_time-bestheader["time"]), mine_time, is_mine)
|
||||||
mined_blocks += 1
|
|
||||||
psbt = generate_psbt(tmpl, reward_spk, blocktime=mine_time)
|
psbt = generate_psbt(tmpl, reward_spk, blocktime=mine_time)
|
||||||
input_stream = os.linesep.join([psbt, "true", "ALL"]).encode('utf8')
|
input_stream = os.linesep.join([psbt, "true", "ALL"]).encode('utf8')
|
||||||
psbt_signed = json.loads(args.bcli("-stdin", "walletprocesspsbt", input=input_stream))
|
psbt_signed = json.loads(args.bcli("-stdin", "walletprocesspsbt", input=input_stream))
|
||||||
|
|
||||||
if not psbt_signed.get("complete",False):
|
if not psbt_signed.get("complete",False):
|
||||||
logging.debug("Generated PSBT: %s" % (psbt,))
|
logging.debug("Generated PSBT: %s" % (psbt,))
|
||||||
sys.stderr.write("PSBT signing failed\n")
|
sys.stderr.write("PSBT signing failed\n")
|
||||||
return 1
|
return 1
|
||||||
block, signet_solution = do_decode_psbt(psbt_signed["psbt"])
|
block, signet_solution = do_decode_psbt(psbt_signed["psbt"])
|
||||||
block = finish_block(block, signet_solution, args.grind_cmd)
|
|
||||||
|
# finish_block() will call bitcoin-util to grind PoW. If the nonce field search space is exhausted,
|
||||||
|
# the subprocess will fail and thus the miner. In case of failure, increment the retries var,
|
||||||
|
# use it to create a new block header and try again.
|
||||||
|
try:
|
||||||
|
block = finish_block(block, signet_solution, args.grind_cmd)
|
||||||
|
except subprocess.CalledProcessError as e:
|
||||||
|
# Look for the return code and output message raised by bitcoin-util
|
||||||
|
if e.returncode == 1 and "Could not satisfy difficulty target" in e.stderr.decode("utf-8"):
|
||||||
|
logging.debug("grinder exhausted the nonce search space, retrying with new block header")
|
||||||
|
retries += 1
|
||||||
|
continue
|
||||||
|
else: # bitcoin-util raised another error, pass it along and let the user know
|
||||||
|
raise e
|
||||||
|
# capture keyboard interrupt so one can stop the miner with SIGINT (Ctrl-C)
|
||||||
|
except KeyboardInterrupt:
|
||||||
|
logging.debug("mining aborted by the user")
|
||||||
|
break
|
||||||
|
# Mining succeeded
|
||||||
|
mined_blocks += 1
|
||||||
|
retries = 0
|
||||||
|
|
||||||
# submit block
|
# submit block
|
||||||
r = args.bcli("-stdin", "submitblock", input=block.serialize().hex().encode('utf8'))
|
r = args.bcli("-stdin", "submitblock", input=block.serialize().hex().encode('utf8'))
|
||||||
|
|
Loading…
Add table
Reference in a new issue