Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

contrib: add OP_RETURN message capability to signet miner #6

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
41 changes: 36 additions & 5 deletions contrib/signet/miner
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import struct
import sys
import time
import subprocess
from io import BytesIO

PATH_BASE_CONTRIB_SIGNET = os.path.abspath(os.path.dirname(os.path.realpath(__file__)))
PATH_BASE_TEST_FUNCTIONAL = os.path.abspath(os.path.join(PATH_BASE_CONTRIB_SIGNET, "..", "..", "test", "functional"))
Expand Down Expand Up @@ -93,7 +94,7 @@ def finish_block(block, signet_solution, grind_cmd):
block.rehash()
return block

def generate_psbt(tmpl, reward_spk, *, blocktime=None, poolid=None):
def generate_psbt(tmpl, reward_spk, *, blocktime=None, poolid=None, extra_vouts=[]):
signet_spk = tmpl["signet_challenge"]
signet_spk_bin = bytes.fromhex(signet_spk)

Expand All @@ -104,6 +105,9 @@ def generate_psbt(tmpl, reward_spk, *, blocktime=None, poolid=None):
cbtx = CTransaction()
cbtx.vin = [CTxIn(COutPoint(0, 0xffffffff), scriptSig, 0xffffffff)]
cbtx.vout = [CTxOut(tmpl["coinbasevalue"], reward_spk)]
if extra_vouts is not None:
cbtx.vout.extend(extra_vouts)

cbtx.vin[0].nSequence = 2**32-2
cbtx.rehash()

Expand Down Expand Up @@ -136,6 +140,25 @@ def generate_psbt(tmpl, reward_spk, *, blocktime=None, poolid=None):
psbt.o = [ PSBTMap() ]
return psbt.to_base64()

def get_extra_vouts(args):
vouts = []

for message in args.extra_vout:
if message is None:
continue

try:
decoded_message = bytes.fromhex(message)
except ValueError:
raise Exception("message must be hex-encoded bytes")

tx_out = CTxOut()
tx_out.deserialize(BytesIO(decoded_message))

vouts.append(tx_out)

return vouts

def get_poolid(args):
if args.poolid is not None:
return args.poolid.encode('utf8')
Expand Down Expand Up @@ -172,10 +195,11 @@ def get_reward_addr_spk(args, height):
return reward_addr, reward_spk

def do_genpsbt(args):
extra_vouts = get_extra_vouts(args)
poolid = get_poolid(args)
tmpl = json.load(sys.stdin)
_, reward_spk = get_reward_addr_spk(args, tmpl["height"])
psbt = generate_psbt(tmpl, reward_spk, poolid=poolid)
psbt = generate_psbt(tmpl, reward_spk, poolid=poolid, extra_vouts=extra_vouts)
print(psbt)

def do_solvepsbt(args):
Expand Down Expand Up @@ -229,7 +253,7 @@ class Generate:
standby_delay=0, backup_delay=0, set_block_time=None,
# 10 minutes, adjusted for the off-by-one bug
block_interval=600.0*2016/2015,
poolid=None):
poolid=None, extra_vouts=[]):
if multiminer is None:
multiminer = (0, 1, 1)
(self.multi_low, self.multi_high, self.multi_period) = multiminer
Expand All @@ -241,6 +265,8 @@ class Generate:
self.set_block_time = set_block_time
self.poolid = poolid
self.block_interval = block_interval
self.extra_vouts = extra_vouts


def next_block_delta(self, last_nbits, last_hash):
# strategy:
Expand Down Expand Up @@ -324,7 +350,10 @@ class Generate:
return tmpl

def mine(self, bcli, grind_cmd, tmpl, reward_spk):
psbt = generate_psbt(tmpl, reward_spk, blocktime=self.mine_time, poolid=self.poolid)
psbt = generate_psbt(
tmpl, reward_spk, blocktime=self.mine_time,
poolid=self.poolid, extra_vouts=self.extra_vouts,
)
input_stream = os.linesep.join([psbt, "true", "ALL"]).encode('utf8')
psbt_signed = json.loads(bcli("-stdin", "walletprocesspsbt", input=input_stream))
if not psbt_signed.get("complete",False):
Expand Down Expand Up @@ -392,7 +421,8 @@ def do_generate(args):

gen = Generate(multiminer=my_blocks, ultimate_target=ultimate_target, poisson=args.poisson, max_interval=args.max_interval,
standby_delay=args.standby_delay, backup_delay=args.backup_delay, set_block_time=args.set_block_time, poolid=poolid,
block_interval=args.block_interval)
block_interval=args.block_interval,
extra_vouts=get_extra_vouts(args))

mined_blocks = 0
bestheader = {"hash": None}
Expand Down Expand Up @@ -550,6 +580,7 @@ def main():
pool = sp.add_mutually_exclusive_group()
pool.add_argument("--poolnum", default=None, type=int, help="Identify blocks that you mine")
pool.add_argument("--poolid", default=None, type=str, help="Identify blocks that you mine (eg: /signet:1/)")
pool.add_argument("--extra-vout", default=None, action="append", type=str, help="Extra raw vout to add to the coinbase")

for sp in [solvepsbt, generate, calibrate]:
sp.add_argument("--grind-cmd", default=None, type=str, required=(sp==calibrate), help="Command to grind a block header for proof-of-work")
Expand Down
Loading