From af115b656ba843d314db4ab33e919dd3c2fe4d41 Mon Sep 17 00:00:00 2001 From: Kyle Altendorf Date: Thu, 15 Apr 2021 23:10:06 -0400 Subject: [PATCH 01/19] Use chia's own 'chia plots create' argument parser --- setup.cfg | 2 ++ src/plotman/job.py | 62 +++++++++++++--------------------------------- tox.ini | 1 + 3 files changed, 20 insertions(+), 45 deletions(-) diff --git a/setup.cfg b/setup.cfg index caebb8b0..df00d2d2 100644 --- a/setup.cfg +++ b/setup.cfg @@ -46,6 +46,8 @@ console_scripts = plotman = plotman.plotman:main [options.extras_require] +chia = + chia-blockchain >= 1.0.4 dev = %(test)s isort diff --git a/src/plotman/job.py b/src/plotman/job.py index 64cdb5d1..4083fb53 100644 --- a/src/plotman/job.py +++ b/src/plotman/job.py @@ -12,6 +12,7 @@ from enum import Enum, auto from subprocess import call +import chia.cmds.plots import pendulum import psutil @@ -57,15 +58,6 @@ def parse_chia_plot_time(s): class Job: 'Represents a plotter job' - # These are constants, not updated during a run. - k = 0 - r = 0 - u = 0 - b = 0 - n = 0 # probably not used - tmpdir = '' - tmp2dir = '' - dstdir = '' logfile = '' jobfile = '' job_id = 0 @@ -110,34 +102,14 @@ def __init__(self, proc, logroot): assert 'chia' in args[1] assert 'plots' == args[2] assert 'create' == args[3] - args_iter = iter(cmdline_argfix(args[4:])) - for arg in args_iter: - val = None if arg in {'-e', '--nobitfield', '-h', '--help', '--override-k'} else next(args_iter) - if arg in {'-k', '--size'}: - self.k = val - elif arg in {'-r', '--num_threads'}: - self.r = val - elif arg in {'-b', '--buffer'}: - self.b = val - elif arg in {'-u', '--buckets'}: - self.u = val - elif arg in {'-t', '--tmp_dir'}: - self.tmpdir = val - elif arg in {'-2', '--tmp2_dir'}: - self.tmp2dir = val - elif arg in {'-d', '--final_dir'}: - self.dstdir = val - elif arg in {'-n', '--num'}: - self.n = val - elif arg in {'-h', '--help'}: - self.help = True - elif arg in {'-e', '--nobitfield', '-f', '--farmer_public_key', '-p', '--pool_public_key'}: - pass - # TODO: keep track of these - elif arg == '--override-k': - pass - else: - print('Warning: unrecognized args: %s %s' % (arg, val)) + + self.args = chia.cmds.plots.create_cmd.make_context(info_name='', args=args[4:]) + + plot_cwd = self.proc.cwd() + self.args['tmpdir'] = os.path.join(plot_cwd, self.args['tmpdir']) + if self.args['tmp2dir'] is not None: + self.args['tmp2dir'] = os.path.join(plot_cwd, args['tmp2dir']) + self.args['dstdir'] = os.path.join(plot_cwd, self.args['dstdir']) # Find logfile (whatever file is open under the log root). The # file may be open more than once, e.g. for STDOUT and STDERR. @@ -262,14 +234,14 @@ def plot_id_prefix(self): def status_str_long(self): return '{plot_id}\nk={k} r={r} b={b} u={u}\npid:{pid}\ntmp:{tmp}\ntmp2:{tmp2}\ndst:{dst}\nlogfile:{logfile}'.format( plot_id = self.plot_id, - k = self.k, - r = self.r, - b = self.b, - u = self.u, + k = self.args['size'], + r = self.args['num_threads'], + b = self.args['buffer'], + u = self.args['buckets'], pid = self.proc.pid, - tmp = self.tmpdir, - tmp2 = self.tmp2dir, - dst = self.dstdir, + tmp = self.args['tmpdir'], + tmp2 = self.args['tmp2dir'], + dst = self.args['dstdir'], plotid = self.plot_id, logfile = self.logfile ) @@ -332,7 +304,7 @@ def get_temp_files(self): # Prevent duplicate file paths by using set. temp_files = set([]) for f in self.proc.open_files(): - if self.tmpdir in f.path or self.tmp2dir in f.path or self.dstdir in f.path: + if self.args['tmpdir'] in f.path or self.args['tmp2dir'] in f.path or self.args['dstdir'] in f.path: temp_files.add(f.path) return temp_files diff --git a/tox.ini b/tox.ini index 81081aaa..bf228508 100644 --- a/tox.ini +++ b/tox.ini @@ -6,6 +6,7 @@ changedir = {envtmpdir} [testenv:test-py{36,37,38,39,py36,py37}] extras = + chia test commands = pytest --capture=no --verbose --pyargs plotman From 83349319dc845b6ff0696bfb91dfd688ea606550 Mon Sep 17 00:00:00 2001 From: Kyle Altendorf Date: Thu, 15 Apr 2021 23:16:57 -0400 Subject: [PATCH 02/19] Manually handle --help --- src/plotman/job.py | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/plotman/job.py b/src/plotman/job.py index 4083fb53..f10a51f4 100644 --- a/src/plotman/job.py +++ b/src/plotman/job.py @@ -63,7 +63,6 @@ class Job: job_id = 0 plot_id = '--------' proc = None # will get a psutil.Process - help = False # These are dynamic, cached, and need to be udpated periodically phase = (None, None) # Phase/subphase @@ -103,6 +102,12 @@ def __init__(self, proc, logroot): assert 'plots' == args[2] assert 'create' == args[3] + if '--help' in args: + args = [arg for arg in args if arg != '--help'] + self.help = True + else: + self.help = False + self.args = chia.cmds.plots.create_cmd.make_context(info_name='', args=args[4:]) plot_cwd = self.proc.cwd() From be7c4e5a21c33ca714421368d8731ef37c24c233 Mon Sep 17 00:00:00 2001 From: Kyle Altendorf Date: Thu, 15 Apr 2021 23:40:32 -0400 Subject: [PATCH 03/19] Change less --- src/plotman/job.py | 54 +++++++++++++++++++++++++++++++++++----------- 1 file changed, 42 insertions(+), 12 deletions(-) diff --git a/src/plotman/job.py b/src/plotman/job.py index f10a51f4..3bfc668c 100644 --- a/src/plotman/job.py +++ b/src/plotman/job.py @@ -110,11 +110,41 @@ def __init__(self, proc, logroot): self.args = chia.cmds.plots.create_cmd.make_context(info_name='', args=args[4:]) + # an example as of 1.0.5 + # { + # 'size': 32, + # 'num_threads': 4, + # 'buckets': 128, + # 'buffer': 6000, + # 'tmp_dir': '/farm/yards/901', + # 'final_dir': '/farm/wagons/801', + # 'override_k': False, + # 'num': 1, + # 'alt_fingerprint': None, + # 'pool_contract_address': None, + # 'farmer_public_key': None, + # 'pool_public_key': None, + # 'tmp2_dir': None, + # 'plotid': None, + # 'memo': None, + # 'nobitfield': False, + # 'exclude_final_dir': False, + # } + + self.k = self.args['size'] + self.r = self.args['num_threads'] + self.u = self.args['buckets'] + self.b = self.args['buffer'] + self.n = self.args['num'] + self.tmpdir = self.args['tmp_dir'] + self.tmp2dir = self.args['tmp2_dir'] + self.dstdir = self.args['final_dir'] + plot_cwd = self.proc.cwd() - self.args['tmpdir'] = os.path.join(plot_cwd, self.args['tmpdir']) - if self.args['tmp2dir'] is not None: - self.args['tmp2dir'] = os.path.join(plot_cwd, args['tmp2dir']) - self.args['dstdir'] = os.path.join(plot_cwd, self.args['dstdir']) + self.tmpdir = os.path.join(plot_cwd, self.tmpdir) + if self.tmp2dir != '': + self.tmp2dir = os.path.join(plot_cwd, self.tmp2dir) + self.dstdir = os.path.join(plot_cwd, self.dstdir) # Find logfile (whatever file is open under the log root). The # file may be open more than once, e.g. for STDOUT and STDERR. @@ -239,14 +269,14 @@ def plot_id_prefix(self): def status_str_long(self): return '{plot_id}\nk={k} r={r} b={b} u={u}\npid:{pid}\ntmp:{tmp}\ntmp2:{tmp2}\ndst:{dst}\nlogfile:{logfile}'.format( plot_id = self.plot_id, - k = self.args['size'], - r = self.args['num_threads'], - b = self.args['buffer'], - u = self.args['buckets'], + k = self.k, + r = self.r, + b = self.b, + u = self.u, pid = self.proc.pid, - tmp = self.args['tmpdir'], - tmp2 = self.args['tmp2dir'], - dst = self.args['dstdir'], + tmp = self.tmpdir, + tmp2 = self.tmp2dir, + dst = self.dstdir, plotid = self.plot_id, logfile = self.logfile ) @@ -309,7 +339,7 @@ def get_temp_files(self): # Prevent duplicate file paths by using set. temp_files = set([]) for f in self.proc.open_files(): - if self.args['tmpdir'] in f.path or self.args['tmp2dir'] in f.path or self.args['dstdir'] in f.path: + if self.tmpdir in f.path or self.tmp2dir in f.path or self.dstdir in f.path: temp_files.add(f.path) return temp_files From 17a2b83285ce0db7f4e32c40875ead515ef58100 Mon Sep 17 00:00:00 2001 From: Kyle Altendorf Date: Thu, 15 Apr 2021 23:41:14 -0400 Subject: [PATCH 04/19] fix: use .params --- src/plotman/job.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/plotman/job.py b/src/plotman/job.py index 3bfc668c..05620927 100644 --- a/src/plotman/job.py +++ b/src/plotman/job.py @@ -108,7 +108,7 @@ def __init__(self, proc, logroot): else: self.help = False - self.args = chia.cmds.plots.create_cmd.make_context(info_name='', args=args[4:]) + self.args = chia.cmds.plots.create_cmd.make_context(info_name='', args=args[4:]).params # an example as of 1.0.5 # { From 30ad3f67614fce29d20a3c3eae18df99e11ca5c2 Mon Sep 17 00:00:00 2001 From: Kyle Altendorf Date: Fri, 16 Apr 2021 03:42:51 +0000 Subject: [PATCH 05/19] fix: tmp2dir is optionally None now --- src/plotman/job.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/plotman/job.py b/src/plotman/job.py index 05620927..68a871ff 100644 --- a/src/plotman/job.py +++ b/src/plotman/job.py @@ -142,7 +142,7 @@ def __init__(self, proc, logroot): plot_cwd = self.proc.cwd() self.tmpdir = os.path.join(plot_cwd, self.tmpdir) - if self.tmp2dir != '': + if self.tmp2dir is not None: self.tmp2dir = os.path.join(plot_cwd, self.tmp2dir) self.dstdir = os.path.join(plot_cwd, self.dstdir) From 4c8f2007e655f2aaba0cef1966bb4be4dadce1a9 Mon Sep 17 00:00:00 2001 From: Kyle Altendorf Date: Sat, 17 Apr 2021 00:05:21 -0400 Subject: [PATCH 06/19] fix: handle -h as well --- src/plotman/job.py | 36 +++++++++++++++++++++++------------- 1 file changed, 23 insertions(+), 13 deletions(-) diff --git a/src/plotman/job.py b/src/plotman/job.py index 68a871ff..18d116f0 100644 --- a/src/plotman/job.py +++ b/src/plotman/job.py @@ -95,20 +95,30 @@ def __init__(self, proc, logroot): with self.proc.oneshot(): # Parse command line args - args = self.proc.cmdline() - assert len(args) > 4 - assert 'python' in args[0] - assert 'chia' in args[1] - assert 'plots' == args[2] - assert 'create' == args[3] - - if '--help' in args: - args = [arg for arg in args if arg != '--help'] - self.help = True - else: - self.help = False + command_line = self.proc.cmdline() + assert len(command_line) > 4 + assert 'python' in command_line[0] + assert 'chia' in command_line[1] + assert 'plots' == command_line[2] + assert 'create' == command_line[3] + + command_arguments = command_line[4:] + command = chia.cmds.plots.create_cmd + context = command.make_context( + info_name='', + args=command_arguments, + resilient_parsing=True, + ) + + # nice idea, but this doesn't include -h + # help_option_names = command.get_help_option_names(ctx=context) + help_option_names = {'--help', '-h'} + + self.help = any( + argument in help_option_names for argument in command_arguments + ) - self.args = chia.cmds.plots.create_cmd.make_context(info_name='', args=args[4:]).params + self.args = context.params # an example as of 1.0.5 # { From f3114a5edfb4962a00771845036b5dd289726f68 Mon Sep 17 00:00:00 2001 From: Kyle Altendorf Date: Sat, 17 Apr 2021 04:25:17 +0000 Subject: [PATCH 07/19] fix: get defaults back --- src/plotman/job.py | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/src/plotman/job.py b/src/plotman/job.py index 18d116f0..75392667 100644 --- a/src/plotman/job.py +++ b/src/plotman/job.py @@ -102,21 +102,21 @@ def __init__(self, proc, logroot): assert 'plots' == command_line[2] assert 'create' == command_line[3] - command_arguments = command_line[4:] - command = chia.cmds.plots.create_cmd - context = command.make_context( - info_name='', - args=command_arguments, - resilient_parsing=True, - ) - # nice idea, but this doesn't include -h # help_option_names = command.get_help_option_names(ctx=context) help_option_names = {'--help', '-h'} - self.help = any( - argument in help_option_names for argument in command_arguments - ) + all_command_arguments = command_line[4:] + command_arguments = [ + argument + for argument in all_command_arguments + if argument not in help_option_names + ] + + self.help = len(all_command_arguments) > len(command_arguments) + + command = chia.cmds.plots.create_cmd + context = command.make_context(info_name='', args=command_arguments) self.args = context.params From 8dde509c6c6fd4c44326eb004f2b57492149cc04 Mon Sep 17 00:00:00 2001 From: Kyle Altendorf Date: Sat, 17 Apr 2021 10:38:34 -0400 Subject: [PATCH 08/19] refactor: isolate chia cli parsing and test it --- src/plotman/_tests/job_test.py | 62 +++++++++++++++++++++++++++++++++ src/plotman/job.py | 63 ++++++++++++++++++++-------------- 2 files changed, 100 insertions(+), 25 deletions(-) diff --git a/src/plotman/_tests/job_test.py b/src/plotman/_tests/job_test.py index 46a28cda..e1052f26 100644 --- a/src/plotman/_tests/job_test.py +++ b/src/plotman/_tests/job_test.py @@ -54,3 +54,65 @@ def test_job_parses_time_with_non_english_locale(logfile_path, locale_name): job.Job.init_from_logfile(self=faux_job_with_logfile) assert faux_job_with_logfile.start_time == log_file_time + + +@pytest.mark.parametrize( + argnames=['arguments'], + argvalues=[ + [['-h']], + [['--help']], + [['-k', '32']], + [['-k32']], + [['-k', '32', '--help']], + ], +) +def test_chia_plots_create_parsing_does_not_fail(arguments): + job.parse_chia_plots_create_command_line( + command_line=['python', 'chia', 'plots', 'create', *arguments], + ) + + +@pytest.mark.parametrize( + argnames=['arguments'], + argvalues=[ + [['-h']], + [['--help']], + [['-k', '32', '--help']], + ], +) +def test_chia_plots_create_parsing_does_not_fail(arguments): + job.parse_chia_plots_create_command_line( + command_line=['python', 'chia', 'plots', 'create', *arguments], + ) + + +@pytest.mark.parametrize( + argnames=['arguments'], + argvalues=[ + [['-h']], + [['--help']], + [['-k', '32', '--help']], + ], +) +def test_chia_plots_create_parsing_detects_help(arguments): + parsed = job.parse_chia_plots_create_command_line( + command_line=['python', 'chia', 'plots', 'create', *arguments], + ) + + assert parsed.help + + +@pytest.mark.parametrize( + argnames=['arguments'], + argvalues=[ + [[]], + [['-k32']], + [['-k', '32']], + ], +) +def test_chia_plots_create_parsing_detects_not_help(arguments): + parsed = job.parse_chia_plots_create_command_line( + command_line=['python', 'chia', 'plots', 'create', *arguments], + ) + + assert not parsed.help diff --git a/src/plotman/job.py b/src/plotman/job.py index 75392667..48e48a48 100644 --- a/src/plotman/job.py +++ b/src/plotman/job.py @@ -53,6 +53,39 @@ def parse_chia_plot_time(s): # This will grow to try ISO8601 as well for when Chia logs that way return pendulum.from_format(s, 'ddd MMM DD HH:mm:ss YYYY', locale='en', tz=None) +class ParsedChiaPlotsCreateCommand: + def __init__(self, help, parameters): + self.help = help + self.parameters = parameters + +def parse_chia_plots_create_command_line(command_line): + # Parse command line args + assert len(command_line) >= 4 + assert 'python' in command_line[0] + assert 'chia' in command_line[1] + assert 'plots' == command_line[2] + assert 'create' == command_line[3] + + all_command_arguments = command_line[4:] + + # nice idea, but this doesn't include -h + # help_option_names = command.get_help_option_names(ctx=context) + help_option_names = {'--help', '-h'} + + command_arguments = [ + argument + for argument in all_command_arguments + if argument not in help_option_names + ] + + command = chia.cmds.plots.create_cmd + context = command.make_context(info_name='', args=list(command_arguments)) + + return ParsedChiaPlotsCreateCommand( + help=len(all_command_arguments) > len(command_arguments), + parameters=context.params, + ) + # TODO: be more principled and explicit about what we cache vs. what we look up # dynamically from the logfile class Job: @@ -94,31 +127,11 @@ def __init__(self, proc, logroot): self.proc = proc with self.proc.oneshot(): - # Parse command line args - command_line = self.proc.cmdline() - assert len(command_line) > 4 - assert 'python' in command_line[0] - assert 'chia' in command_line[1] - assert 'plots' == command_line[2] - assert 'create' == command_line[3] - - # nice idea, but this doesn't include -h - # help_option_names = command.get_help_option_names(ctx=context) - help_option_names = {'--help', '-h'} - - all_command_arguments = command_line[4:] - command_arguments = [ - argument - for argument in all_command_arguments - if argument not in help_option_names - ] - - self.help = len(all_command_arguments) > len(command_arguments) - - command = chia.cmds.plots.create_cmd - context = command.make_context(info_name='', args=command_arguments) - - self.args = context.params + parsed_command = parse_chia_plots_create_command_line( + command_line=self.proc.cmdline(), + ) + self.help = parsed_command.help + self.args = parsed_command.parameters # an example as of 1.0.5 # { From ef87c2b4b541984d2db73707dc968d5ccb21e9a1 Mon Sep 17 00:00:00 2001 From: Kyle Altendorf Date: Sat, 17 Apr 2021 21:15:14 -0400 Subject: [PATCH 09/19] refactor: some more testing and adjusting --- src/plotman/_tests/job_test.py | 22 ++++++++++++++++++++++ src/plotman/job.py | 10 +++++----- 2 files changed, 27 insertions(+), 5 deletions(-) diff --git a/src/plotman/_tests/job_test.py b/src/plotman/_tests/job_test.py index e1052f26..3ce250d1 100644 --- a/src/plotman/_tests/job_test.py +++ b/src/plotman/_tests/job_test.py @@ -65,6 +65,7 @@ def test_job_parses_time_with_non_english_locale(logfile_path, locale_name): [['-k32']], [['-k', '32', '--help']], ], + ids=str, ) def test_chia_plots_create_parsing_does_not_fail(arguments): job.parse_chia_plots_create_command_line( @@ -79,6 +80,7 @@ def test_chia_plots_create_parsing_does_not_fail(arguments): [['--help']], [['-k', '32', '--help']], ], + ids=str, ) def test_chia_plots_create_parsing_does_not_fail(arguments): job.parse_chia_plots_create_command_line( @@ -93,6 +95,7 @@ def test_chia_plots_create_parsing_does_not_fail(arguments): [['--help']], [['-k', '32', '--help']], ], + ids=str, ) def test_chia_plots_create_parsing_detects_help(arguments): parsed = job.parse_chia_plots_create_command_line( @@ -109,6 +112,7 @@ def test_chia_plots_create_parsing_detects_help(arguments): [['-k32']], [['-k', '32']], ], + ids=str, ) def test_chia_plots_create_parsing_detects_not_help(arguments): parsed = job.parse_chia_plots_create_command_line( @@ -116,3 +120,21 @@ def test_chia_plots_create_parsing_detects_not_help(arguments): ) assert not parsed.help + + +@pytest.mark.parametrize( + argnames=['arguments'], + argvalues=[ + [[]], + [['-k32']], + [['-k', '32']], + [['--size', '32']], + ], + ids=str, +) +def test_chia_plots_create_parsing_handles_argument_forms(arguments): + parsed = job.parse_chia_plots_create_command_line( + command_line=['python', 'chia', 'plots', 'create', *arguments], + ) + + assert parsed.parameters['size'] == 32 diff --git a/src/plotman/job.py b/src/plotman/job.py index 48e48a48..8dc393d0 100644 --- a/src/plotman/job.py +++ b/src/plotman/job.py @@ -53,11 +53,6 @@ def parse_chia_plot_time(s): # This will grow to try ISO8601 as well for when Chia logs that way return pendulum.from_format(s, 'ddd MMM DD HH:mm:ss YYYY', locale='en', tz=None) -class ParsedChiaPlotsCreateCommand: - def __init__(self, help, parameters): - self.help = help - self.parameters = parameters - def parse_chia_plots_create_command_line(command_line): # Parse command line args assert len(command_line) >= 4 @@ -86,6 +81,11 @@ def parse_chia_plots_create_command_line(command_line): parameters=context.params, ) +class ParsedChiaPlotsCreateCommand: + def __init__(self, help, parameters): + self.help = help + self.parameters = parameters + # TODO: be more principled and explicit about what we cache vs. what we look up # dynamically from the logfile class Job: From a4737c0bbe12936fceb084d0c4b2e78bd9f55104 Mon Sep 17 00:00:00 2001 From: Kyle Altendorf Date: Sat, 17 Apr 2021 21:28:53 -0400 Subject: [PATCH 10/19] fix: skip jobs whose arguments fail to be parsed --- setup.cfg | 1 + src/plotman/_tests/job_test.py | 29 +++---- src/plotman/job.py | 149 ++++++++++++++++++--------------- 3 files changed, 99 insertions(+), 80 deletions(-) diff --git a/setup.cfg b/setup.cfg index a8b9e4f5..bc8fb59c 100644 --- a/setup.cfg +++ b/setup.cfg @@ -34,6 +34,7 @@ package_dir= packages=find: install_requires = appdirs + click desert marshmallow pendulum diff --git a/src/plotman/_tests/job_test.py b/src/plotman/_tests/job_test.py index 3ce250d1..ecac7a88 100644 --- a/src/plotman/_tests/job_test.py +++ b/src/plotman/_tests/job_test.py @@ -82,27 +82,29 @@ def test_chia_plots_create_parsing_does_not_fail(arguments): ], ids=str, ) -def test_chia_plots_create_parsing_does_not_fail(arguments): - job.parse_chia_plots_create_command_line( +def test_chia_plots_create_parsing_detects_help(arguments): + parsed = job.parse_chia_plots_create_command_line( command_line=['python', 'chia', 'plots', 'create', *arguments], ) + assert parsed.help + @pytest.mark.parametrize( argnames=['arguments'], argvalues=[ - [['-h']], - [['--help']], - [['-k', '32', '--help']], + [[]], + [['-k32']], + [['-k', '32']], ], ids=str, ) -def test_chia_plots_create_parsing_detects_help(arguments): +def test_chia_plots_create_parsing_detects_not_help(arguments): parsed = job.parse_chia_plots_create_command_line( command_line=['python', 'chia', 'plots', 'create', *arguments], ) - assert parsed.help + assert not parsed.help @pytest.mark.parametrize( @@ -111,24 +113,23 @@ def test_chia_plots_create_parsing_detects_help(arguments): [[]], [['-k32']], [['-k', '32']], + [['--size', '32']], ], ids=str, ) -def test_chia_plots_create_parsing_detects_not_help(arguments): +def test_chia_plots_create_parsing_handles_argument_forms(arguments): parsed = job.parse_chia_plots_create_command_line( command_line=['python', 'chia', 'plots', 'create', *arguments], ) - assert not parsed.help + assert parsed.parameters['size'] == 32 @pytest.mark.parametrize( argnames=['arguments'], argvalues=[ - [[]], - [['-k32']], - [['-k', '32']], - [['--size', '32']], + [['--size32']], + [['--not-an-actual-option']], ], ids=str, ) @@ -137,4 +138,4 @@ def test_chia_plots_create_parsing_handles_argument_forms(arguments): command_line=['python', 'chia', 'plots', 'create', *arguments], ) - assert parsed.parameters['size'] == 32 + assert parsed.error is not None diff --git a/src/plotman/job.py b/src/plotman/job.py index 8dc393d0..0ae3af27 100644 --- a/src/plotman/job.py +++ b/src/plotman/job.py @@ -13,6 +13,7 @@ from subprocess import call import chia.cmds.plots +import click import pendulum import psutil @@ -74,15 +75,24 @@ def parse_chia_plots_create_command_line(command_line): ] command = chia.cmds.plots.create_cmd - context = command.make_context(info_name='', args=list(command_arguments)) + try: + context = command.make_context(info_name='', args=list(command_arguments)) + except click.ClickException as e: + error = e + params = {} + else: + error = None + params = context.params return ParsedChiaPlotsCreateCommand( + error=error, help=len(all_command_arguments) > len(command_arguments), - parameters=context.params, + parameters=params, ) class ParsedChiaPlotsCreateCommand: - def __init__(self, help, parameters): + def __init__(self, error, help, parameters): + self.error = error self.help = help self.parameters = parameters @@ -115,78 +125,85 @@ def get_running_jobs(logroot, cached_jobs=()): if proc.pid in cached_jobs_by_pid.keys(): jobs.append(cached_jobs_by_pid[proc.pid]) # Copy from cache else: - job = Job(proc, logroot) - if not job.help: + with proc.oneshot(): + parsed_command = parse_chia_plots_create_command_line( + command_line=proc.cmdline(), + ) + if parsed_command.error is not None: + continue + if job.help: + continue + job = Job( + proc=proc, + parsed_command=parsed_command, + logroot=logroot, + ) jobs.append(job) return jobs - def __init__(self, proc, logroot): + def __init__(self, proc, parsed_command, logroot): '''Initialize from an existing psutil.Process object. must know logroot in order to understand open files''' self.proc = proc - with self.proc.oneshot(): - parsed_command = parse_chia_plots_create_command_line( - command_line=self.proc.cmdline(), - ) - self.help = parsed_command.help - self.args = parsed_command.parameters - - # an example as of 1.0.5 - # { - # 'size': 32, - # 'num_threads': 4, - # 'buckets': 128, - # 'buffer': 6000, - # 'tmp_dir': '/farm/yards/901', - # 'final_dir': '/farm/wagons/801', - # 'override_k': False, - # 'num': 1, - # 'alt_fingerprint': None, - # 'pool_contract_address': None, - # 'farmer_public_key': None, - # 'pool_public_key': None, - # 'tmp2_dir': None, - # 'plotid': None, - # 'memo': None, - # 'nobitfield': False, - # 'exclude_final_dir': False, - # } - - self.k = self.args['size'] - self.r = self.args['num_threads'] - self.u = self.args['buckets'] - self.b = self.args['buffer'] - self.n = self.args['num'] - self.tmpdir = self.args['tmp_dir'] - self.tmp2dir = self.args['tmp2_dir'] - self.dstdir = self.args['final_dir'] - - plot_cwd = self.proc.cwd() - self.tmpdir = os.path.join(plot_cwd, self.tmpdir) - if self.tmp2dir is not None: - self.tmp2dir = os.path.join(plot_cwd, self.tmp2dir) - self.dstdir = os.path.join(plot_cwd, self.dstdir) - - # Find logfile (whatever file is open under the log root). The - # file may be open more than once, e.g. for STDOUT and STDERR. + self.help = parsed_command.help + self.args = parsed_command.parameters + + # an example as of 1.0.5 + # { + # 'size': 32, + # 'num_threads': 4, + # 'buckets': 128, + # 'buffer': 6000, + # 'tmp_dir': '/farm/yards/901', + # 'final_dir': '/farm/wagons/801', + # 'override_k': False, + # 'num': 1, + # 'alt_fingerprint': None, + # 'pool_contract_address': None, + # 'farmer_public_key': None, + # 'pool_public_key': None, + # 'tmp2_dir': None, + # 'plotid': None, + # 'memo': None, + # 'nobitfield': False, + # 'exclude_final_dir': False, + # } + + self.k = self.args['size'] + self.r = self.args['num_threads'] + self.u = self.args['buckets'] + self.b = self.args['buffer'] + self.n = self.args['num'] + self.tmpdir = self.args['tmp_dir'] + self.tmp2dir = self.args['tmp2_dir'] + self.dstdir = self.args['final_dir'] + + plot_cwd = self.proc.cwd() + self.tmpdir = os.path.join(plot_cwd, self.tmpdir) + if self.tmp2dir is not None: + self.tmp2dir = os.path.join(plot_cwd, self.tmp2dir) + self.dstdir = os.path.join(plot_cwd, self.dstdir) + + # Find logfile (whatever file is open under the log root). The + # file may be open more than once, e.g. for STDOUT and STDERR. + for f in self.proc.open_files(): + if logroot in f.path: + if self.logfile: + assert self.logfile == f.path + else: + self.logfile = f.path + break + + if self.logfile: + # Initialize data that needs to be loaded from the logfile + self.init_from_logfile() + else: + print('Found plotting process PID {pid}, but could not find ' + 'logfile in its open files:'.format(pid = self.proc.pid)) for f in self.proc.open_files(): - if logroot in f.path: - if self.logfile: - assert self.logfile == f.path - else: - self.logfile = f.path - break - - if self.logfile: - # Initialize data that needs to be loaded from the logfile - self.init_from_logfile() - else: - print('Found plotting process PID {pid}, but could not find ' - 'logfile in its open files:'.format(pid = self.proc.pid)) - for f in self.proc.open_files(): - print(f.path) + print(f.path) From 2b4fcc5a2600161b7852a71cdc27940f26af81d3 Mon Sep 17 00:00:00 2001 From: Kyle Altendorf Date: Wed, 21 Apr 2021 23:03:41 -0400 Subject: [PATCH 11/19] chore: remove unused code --- src/plotman/job.py | 15 --------------- 1 file changed, 15 deletions(-) diff --git a/src/plotman/job.py b/src/plotman/job.py index 3f1fd1fb..4e0926b2 100644 --- a/src/plotman/job.py +++ b/src/plotman/job.py @@ -34,21 +34,6 @@ def is_plotting_cmdline(cmdline): and 'create' == cmdline[3] ) -# This is a cmdline argument fix for https://github.com/ericaltendorf/plotman/issues/41 -def cmdline_argfix(cmdline): - known_keys = 'krbut2dne' - for i in cmdline: - # If the argument starts with dash and a known key and is longer than 2, - # then an argument is passed with no space between its key and value. - # This is POSIX compliant but the arg parser was tripping over it. - # In these cases, splitting that item up in separate key and value - # elements results in a `cmdline` list that is correctly formatted. - if i[0]=='-' and i[1] in known_keys and len(i)>2: - yield i[0:2] # key - yield i[2:] # value - else: - yield i - def parse_chia_plot_time(s): # This will grow to try ISO8601 as well for when Chia logs that way return pendulum.from_format(s, 'ddd MMM DD HH:mm:ss YYYY', locale='en', tz=None) From 242a8346acc6c6626bb0e13f5f96fa47b94a404a Mon Sep 17 00:00:00 2001 From: Kyle Altendorf Date: Fri, 23 Apr 2021 23:45:07 +0000 Subject: [PATCH 12/19] chore: fix mismerge --- src/plotman/job.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/plotman/job.py b/src/plotman/job.py index 60d7697c..f26d3920 100644 --- a/src/plotman/job.py +++ b/src/plotman/job.py @@ -118,13 +118,13 @@ def get_running_jobs(logroot, cached_jobs=()): ) if parsed_command.error is not None: continue - if job.help: - continue job = Job( proc=proc, parsed_command=parsed_command, logroot=logroot, ) + if job.help: + continue jobs.append(job) return jobs From c0fa13a69e8a7a35a3be4ae0012c397275031338 Mon Sep 17 00:00:00 2001 From: Kyle Altendorf Date: Thu, 29 Apr 2021 22:06:10 -0400 Subject: [PATCH 13/19] refactor: copy in chia plots create click options --- LICENSE-chia-blockchain | 201 +++++++++++++++++++++++++++++++++ setup.cfg | 2 - src/plotman/_tests/job_test.py | 2 +- src/plotman/chia.py | 83 ++++++++++++++ src/plotman/job.py | 8 +- tox.ini | 1 - 6 files changed, 291 insertions(+), 6 deletions(-) create mode 100644 LICENSE-chia-blockchain create mode 100644 src/plotman/chia.py diff --git a/LICENSE-chia-blockchain b/LICENSE-chia-blockchain new file mode 100644 index 00000000..261eeb9e --- /dev/null +++ b/LICENSE-chia-blockchain @@ -0,0 +1,201 @@ + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. diff --git a/setup.cfg b/setup.cfg index 9e9720d6..ed151143 100644 --- a/setup.cfg +++ b/setup.cfg @@ -53,8 +53,6 @@ console_scripts = plotman = plotman.plotman:main [options.extras_require] -chia = - chia-blockchain >= 1.0.4 dev = %(test)s isort diff --git a/src/plotman/_tests/job_test.py b/src/plotman/_tests/job_test.py index 6e607050..25840723 100644 --- a/src/plotman/_tests/job_test.py +++ b/src/plotman/_tests/job_test.py @@ -133,7 +133,7 @@ def test_chia_plots_create_parsing_handles_argument_forms(arguments): ], ids=str, ) -def test_chia_plots_create_parsing_handles_argument_forms(arguments): +def test_chia_plots_create_parsing_identifies_errors(arguments): parsed = job.parse_chia_plots_create_command_line( command_line=['python', 'chia', 'plots', 'create', *arguments], ) diff --git a/src/plotman/chia.py b/src/plotman/chia.py new file mode 100644 index 00000000..283594d9 --- /dev/null +++ b/src/plotman/chia.py @@ -0,0 +1,83 @@ +import functools + +import click +from pathlib import Path + + +class Commands: + def __init__(self): + self.by_version = {} + + def register(self, version): + if version in self.by_version: + raise Exception(f'Version already registered: {version!r}') + if not isinstance(version, tuple): + raise Exception(f'Version must be a tuple: {version!r}') + + return functools.partial(self._decorator, version=version) + + def _decorator(self, command, *, version): + self.by_version[version] = command + # self.by_version = dict(sorted(self.by_version.items())) + + def __getitem__(self, item): + return self.by_version[item] + + def latest_command(self): + return max(self.by_version.items())[1] + + +commands = Commands() + + +@commands.register(version=(1, 1, 2)) +@click.command() +# https://github.com/Chia-Network/chia-blockchain/blob/v1.1.2/LICENSE +# https://github.com/Chia-Network/chia-blockchain/blob/v1.1.2/chia/cmds/plots.py#L39-L83 +@click.option("-k", "--size", help="Plot size", type=int, default=32, show_default=True) +@click.option("--override-k", help="Force size smaller than 32", default=False, show_default=True, is_flag=True) +@click.option("-n", "--num", help="Number of plots or challenges", type=int, default=1, show_default=True) +@click.option("-b", "--buffer", help="Megabytes for sort/plot buffer", type=int, default=4608, show_default=True) +@click.option("-r", "--num_threads", help="Number of threads to use", type=int, default=2, show_default=True) +@click.option("-u", "--buckets", help="Number of buckets", type=int, default=128, show_default=True) +@click.option( + "-a", + "--alt_fingerprint", + type=int, + default=None, + help="Enter the alternative fingerprint of the key you want to use", +) +@click.option( + "-c", + "--pool_contract_address", + type=str, + default=None, + help="Address of where the pool reward will be sent to. Only used if alt_fingerprint and pool public key are None", +) +@click.option("-f", "--farmer_public_key", help="Hex farmer public key", type=str, default=None) +@click.option("-p", "--pool_public_key", help="Hex public key of pool", type=str, default=None) +@click.option( + "-t", + "--tmp_dir", + help="Temporary directory for plotting files", + type=click.Path(), + default=Path("."), + show_default=True, +) +@click.option("-2", "--tmp2_dir", help="Second temporary directory for plotting files", type=click.Path(), default=None) +@click.option( + "-d", + "--final_dir", + help="Final directory for plots (relative or absolute)", + type=click.Path(), + default=Path("."), + show_default=True, +) +@click.option("-i", "--plotid", help="PlotID in hex for reproducing plots (debugging only)", type=str, default=None) +@click.option("-m", "--memo", help="Memo in hex for reproducing plots (debugging only)", type=str, default=None) +@click.option("-e", "--nobitfield", help="Disable bitfield", default=False, is_flag=True) +@click.option( + "-x", "--exclude_final_dir", help="Skips adding [final dir] to harvester for farming", default=False, is_flag=True +) +def _cli(): + pass diff --git a/src/plotman/job.py b/src/plotman/job.py index 065bc10b..8150d400 100644 --- a/src/plotman/job.py +++ b/src/plotman/job.py @@ -11,11 +11,12 @@ from enum import Enum, auto from subprocess import call -import chia.cmds.plots import click import pendulum import psutil +from plotman import chia + def job_phases_for_tmpdir(d, all_jobs): '''Return phase 2-tuples for jobs running on tmpdir d''' @@ -61,7 +62,10 @@ def parse_chia_plots_create_command_line(command_line): if argument not in help_option_names ] - command = chia.cmds.plots.create_cmd + # TODO: We could at some point do chia version detection and pick the + # associated command. For now we'll just use the latest one we have + # copied. + command = chia.commands.latest_command() try: context = command.make_context(info_name='', args=list(command_arguments)) except click.ClickException as e: diff --git a/tox.ini b/tox.ini index 3d35c407..bd7e875e 100644 --- a/tox.ini +++ b/tox.ini @@ -6,7 +6,6 @@ changedir = {envtmpdir} [testenv:test-py{37,38,39}] extras = - chia test commands = pytest --capture=no --verbose --pyargs plotman From 1561c6fc38ded2c813d7bb3669dd7cd07011ab5e Mon Sep 17 00:00:00 2001 From: Kyle Altendorf Date: Thu, 29 Apr 2021 22:14:32 -0400 Subject: [PATCH 14/19] chore: add chia-blockchain license file to manifest --- MANIFEST.in | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/MANIFEST.in b/MANIFEST.in index c6146883..8a034f2d 100644 --- a/MANIFEST.in +++ b/MANIFEST.in @@ -1,5 +1,5 @@ include CHANGELOG.md -include LICENSE +include LICENSE* include README.md include *.md include VERSION From 2b2d6f41e85f7beae3a054435871e3dae05edb93 Mon Sep 17 00:00:00 2001 From: Kyle Altendorf Date: Fri, 30 Apr 2021 13:09:15 -0400 Subject: [PATCH 15/19] Update LICENSE-chia-blockchain --- LICENSE-chia-blockchain | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/LICENSE-chia-blockchain b/LICENSE-chia-blockchain index 261eeb9e..ee81ae2a 100644 --- a/LICENSE-chia-blockchain +++ b/LICENSE-chia-blockchain @@ -186,7 +186,7 @@ same "printed page" as the copyright notice for easier identification within third-party archives. - Copyright [yyyy] [name of copyright owner] + Copyright 2021 Chia Network Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. From 3921ab93299c1990a55c1e8a3c7cf4b28bf3adc3 Mon Sep 17 00:00:00 2001 From: Kyle Altendorf Date: Sat, 1 May 2021 23:38:27 -0400 Subject: [PATCH 16/19] doc: add markers for start and end of copied code --- src/plotman/chia.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/plotman/chia.py b/src/plotman/chia.py index 283594d9..0c90501f 100644 --- a/src/plotman/chia.py +++ b/src/plotman/chia.py @@ -34,6 +34,7 @@ def latest_command(self): @click.command() # https://github.com/Chia-Network/chia-blockchain/blob/v1.1.2/LICENSE # https://github.com/Chia-Network/chia-blockchain/blob/v1.1.2/chia/cmds/plots.py#L39-L83 +# start copied code @click.option("-k", "--size", help="Plot size", type=int, default=32, show_default=True) @click.option("--override-k", help="Force size smaller than 32", default=False, show_default=True, is_flag=True) @click.option("-n", "--num", help="Number of plots or challenges", type=int, default=1, show_default=True) @@ -79,5 +80,6 @@ def latest_command(self): @click.option( "-x", "--exclude_final_dir", help="Skips adding [final dir] to harvester for farming", default=False, is_flag=True ) +# end copied code def _cli(): pass From 1b5db4e342b9ec1f7910663a453aec3a97ba51a6 Mon Sep 17 00:00:00 2001 From: Kyle Altendorf Date: Sat, 1 May 2021 23:39:10 -0400 Subject: [PATCH 17/19] chore: copy in chia plots create cli parser for 1.1.3 --- src/plotman/chia.py | 55 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 55 insertions(+) diff --git a/src/plotman/chia.py b/src/plotman/chia.py index 0c90501f..a9e4f9ef 100644 --- a/src/plotman/chia.py +++ b/src/plotman/chia.py @@ -83,3 +83,58 @@ def latest_command(self): # end copied code def _cli(): pass + + +@commands.register(version=(1, 1, 3)) +@click.command() +# https://github.com/Chia-Network/chia-blockchain/blob/v1.1.3/LICENSE +# https://github.com/Chia-Network/chia-blockchain/blob/v1.1.3/chia/cmds/plots.py#L39-L83 +# start copied code +@click.option("-k", "--size", help="Plot size", type=int, default=32, show_default=True) +@click.option("--override-k", help="Force size smaller than 32", default=False, show_default=True, is_flag=True) +@click.option("-n", "--num", help="Number of plots or challenges", type=int, default=1, show_default=True) +@click.option("-b", "--buffer", help="Megabytes for sort/plot buffer", type=int, default=4608, show_default=True) +@click.option("-r", "--num_threads", help="Number of threads to use", type=int, default=2, show_default=True) +@click.option("-u", "--buckets", help="Number of buckets", type=int, default=128, show_default=True) +@click.option( + "-a", + "--alt_fingerprint", + type=int, + default=None, + help="Enter the alternative fingerprint of the key you want to use", +) +@click.option( + "-c", + "--pool_contract_address", + type=str, + default=None, + help="Address of where the pool reward will be sent to. Only used if alt_fingerprint and pool public key are None", +) +@click.option("-f", "--farmer_public_key", help="Hex farmer public key", type=str, default=None) +@click.option("-p", "--pool_public_key", help="Hex public key of pool", type=str, default=None) +@click.option( + "-t", + "--tmp_dir", + help="Temporary directory for plotting files", + type=click.Path(), + default=Path("."), + show_default=True, +) +@click.option("-2", "--tmp2_dir", help="Second temporary directory for plotting files", type=click.Path(), default=None) +@click.option( + "-d", + "--final_dir", + help="Final directory for plots (relative or absolute)", + type=click.Path(), + default=Path("."), + show_default=True, +) +@click.option("-i", "--plotid", help="PlotID in hex for reproducing plots (debugging only)", type=str, default=None) +@click.option("-m", "--memo", help="Memo in hex for reproducing plots (debugging only)", type=str, default=None) +@click.option("-e", "--nobitfield", help="Disable bitfield", default=False, is_flag=True) +@click.option( + "-x", "--exclude_final_dir", help="Skips adding [final dir] to harvester for farming", default=False, is_flag=True +) +# end copied code +def _cli(): + pass From e784731b798eaaa9de3998d1fed4d62eb6713c15 Mon Sep 17 00:00:00 2001 From: Kyle Altendorf Date: Sat, 1 May 2021 23:50:37 -0400 Subject: [PATCH 18/19] doc: add MAINTENANCE.md and a description fo the chia code copying --- MAINTENANCE.md | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) create mode 100644 MAINTENANCE.md diff --git a/MAINTENANCE.md b/MAINTENANCE.md new file mode 100644 index 00000000..825c273e --- /dev/null +++ b/MAINTENANCE.md @@ -0,0 +1,19 @@ +# Maintenance + +## Overview + +This document holds guidance on maintaining aspects of plotman. + +## The `chia plots create` CLI parsing code + +In [src/plotman/chia.py](src/plotman/chia.py) there is code copied from the `chia plots create` subcommand's CLI parser definition. +When new versions of `chia-blockchain` are released, their interface code should be added to plotman. +plotman commit [1b5db4e](https://github.com/altendky/plotman/commit/1b5db4e342b9ec1f7910663a453aec3a97ba51a6) provides an example of adding a new version. + +In many cases, copying code is a poor choice. +It is believed that in this case it is appropriate since the chia code that plotman could import is not necessarily the code that is parsing the plotting process command lines anyways. +The chia command could come from another Python environment, a system package, a `.dmg`, etc. +This approach also offers future potential of using the proper version of parsing for the specific plot process being inspected. +Finally, this alleviates dealing with the dependency on the `chia-blockchain` package. +In generally, using dependencies is good. +This seems to be an exceptional case. From 28f5b41229caea8160197570201ca26ab591c059 Mon Sep 17 00:00:00 2001 From: Kyle Altendorf Date: Sat, 1 May 2021 23:52:01 -0400 Subject: [PATCH 19/19] doc: change code copying example link to use ericaltendorf repo --- MAINTENANCE.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/MAINTENANCE.md b/MAINTENANCE.md index 825c273e..b8b17c2d 100644 --- a/MAINTENANCE.md +++ b/MAINTENANCE.md @@ -8,7 +8,7 @@ This document holds guidance on maintaining aspects of plotman. In [src/plotman/chia.py](src/plotman/chia.py) there is code copied from the `chia plots create` subcommand's CLI parser definition. When new versions of `chia-blockchain` are released, their interface code should be added to plotman. -plotman commit [1b5db4e](https://github.com/altendky/plotman/commit/1b5db4e342b9ec1f7910663a453aec3a97ba51a6) provides an example of adding a new version. +plotman commit [1b5db4e](https://github.com/ericaltendorf/plotman/commit/1b5db4e342b9ec1f7910663a453aec3a97ba51a6) provides an example of adding a new version. In many cases, copying code is a poor choice. It is believed that in this case it is appropriate since the chia code that plotman could import is not necessarily the code that is parsing the plotting process command lines anyways.