From 5cc4a20724c905334be391e3a0c946d7d77b4ed0 Mon Sep 17 00:00:00 2001 From: The MMGen Project Date: Tue, 8 Oct 2024 12:56:00 +0000 Subject: [PATCH] cfg.py: add `cmd_caps` attr --- mmgen/altcoin/params.py | 2 +- mmgen/cfg.py | 29 ++++++++++++++++++++++++++++- mmgen/proto/btc/params.py | 2 +- mmgen/proto/eth/params.py | 2 +- mmgen/proto/xmr/params.py | 2 +- mmgen/proto/zec/params.py | 2 +- mmgen/protocol.py | 8 +++++--- test/cmdtest_py_d/ct_help.py | 30 +++++++++++++++++------------- 8 files changed, 55 insertions(+), 22 deletions(-) diff --git a/mmgen/altcoin/params.py b/mmgen/altcoin/params.py index 94287b0c..faffe72a 100755 --- a/mmgen/altcoin/params.py +++ b/mmgen/altcoin/params.py @@ -292,7 +292,7 @@ def make_proto(e,testnet=False): 'wif_ver_num': { 'std': num2hexstr(e.wif_ver_num) }, 'mmtypes': ('L','C','S') if e.has_segwit else ('L','C'), 'dfl_mmtype': 'L', - 'mmcaps': ('key','addr'), + 'mmcaps': (), }, ) ) diff --git a/mmgen/cfg.py b/mmgen/cfg.py index c4215093..23a961ab 100755 --- a/mmgen/cfg.py +++ b/mmgen/cfg.py @@ -40,6 +40,7 @@ class GlobalConstants(Lockable): _autolock = True proj_name = 'MMGen' + proj_id = 'mmgen' proj_url = 'https://github.com/mmgen/mmgen-wallet' author = 'The MMGen Project' email = '' @@ -52,8 +53,34 @@ class GlobalConstants(Lockable): # must match CoinProtocol.coins core_coins = ('btc','bch','ltc','eth','etc','zec','xmr') + _cc = namedtuple('cmd_cap', ['proto', 'rpc', 'coin', 'caps', 'platforms']) + cmd_caps_data = { + 'addrgen': _cc(True, False, None, [], 'lmw'), + 'addrimport': _cc(True, True, 'R', ['tw'], 'lmw'), + 'autosign': _cc(True, True, 'r', ['rpc'], 'lm'), + 'keygen': _cc(True, False, None, [], 'lmw'), + 'msg': _cc(True, True, 'R', ['msg'], 'lmw'), + 'passchg': _cc(False, False, None, [], 'lmw'), + 'passgen': _cc(False, False, None, [], 'lmw'), + 'regtest': _cc(True, True, 'b', ['tw'], 'lmw'), + 'seedjoin': _cc(False, False, None, [], 'lmw'), + 'seedsplit': _cc(False, False, None, [], 'lmw'), + 'subwalletgen': _cc(False, False, None, [], 'lmw'), + 'tool': _cc(True, True, None, [], 'lmw'), + 'txbump': _cc(True, True, 'R', ['tw'], 'lmw'), + 'txcreate': _cc(True, True, 'R', ['tw'], 'lmw'), + 'txdo': _cc(True, True, 'R', ['tw'], 'lmw'), + 'txsend': _cc(True, True, 'R', ['tw'], 'lmw'), + 'txsign': _cc(True, True, 'R', ['tw'], 'lmw'), + 'walletchk': _cc(False, False, None, [], 'lmw'), + 'walletconv': _cc(False, False, None, [], 'lmw'), + 'walletgen': _cc(False, False, None, [], 'lmw'), + 'xmrwallet': _cc(True, True, 'xmr', ['rpc'], 'lmw'), + } + prog_name = os.path.basename(sys.argv[0]) - is_txprog = prog_name == 'mmgen-regtest' or prog_name.startswith('mmgen-tx') + prog_id = prog_name.removeprefix(f'{proj_id}-') + cmd_caps = cmd_caps_data.get(prog_id) if sys.platform not in ('linux', 'win32', 'darwin'): die2(1,f'{sys.platform!r}: platform not supported by {proj_name}') diff --git a/mmgen/proto/btc/params.py b/mmgen/proto/btc/params.py index f9eaa888..999f7366 100755 --- a/mmgen/proto/btc/params.py +++ b/mmgen/proto/btc/params.py @@ -35,7 +35,7 @@ class mainnet(CoinProtocol.Secp256k1): # chainparams.cpp _finfo(478559,'00000000000000000019f112ec0a9982926f1258cdcc558dd7c3b7e5dc7fa148','BCH',False), ] caps = ('rbf','segwit') - mmcaps = ('key','addr','rpc_init','tx') + mmcaps = ('rpc', 'rpc_init', 'tw', 'msg') base_proto = 'Bitcoin' base_proto_coin = 'BTC' base_coin = 'BTC' diff --git a/mmgen/proto/eth/params.py b/mmgen/proto/eth/params.py index ccefa576..c79d8e78 100755 --- a/mmgen/proto/eth/params.py +++ b/mmgen/proto/eth/params.py @@ -30,7 +30,7 @@ class mainnet(CoinProtocol.DummyWIF,CoinProtocol.Secp256k1): chain_names = ['ethereum','foundation'] sign_mode = 'standalone' caps = ('token',) - mmcaps = ('key','addr','rpc_init','tx') + mmcaps = ('rpc', 'rpc_init', 'tw', 'msg') base_proto = 'Ethereum' base_proto_coin = 'ETH' base_coin = 'ETH' diff --git a/mmgen/proto/xmr/params.py b/mmgen/proto/xmr/params.py index 30c479b5..01298303 100755 --- a/mmgen/proto/xmr/params.py +++ b/mmgen/proto/xmr/params.py @@ -36,7 +36,7 @@ class mainnet(CoinProtocol.DummyWIF,CoinProtocol.Base): pubkey_type = 'monero' # required by DummyWIF avg_bdi = 120 privkey_len = 32 - mmcaps = ('key','addr') + mmcaps = ('rpc',) ignore_daemon_version = False coin_amt = 'XMRAmt' sign_mode = 'standalone' diff --git a/mmgen/proto/zec/params.py b/mmgen/proto/zec/params.py index f155fdc0..64dbd583 100755 --- a/mmgen/proto/zec/params.py +++ b/mmgen/proto/zec/params.py @@ -25,7 +25,7 @@ class mainnet(mainnet): wif_ver_num = { 'std': '80', 'zcash_z': 'ab36' } pubkey_types = ('std','zcash_z') mmtypes = ('L','C','Z') - mmcaps = ('key','addr') + mmcaps = () dfl_mmtype = 'L' avg_bdi = 75 diff --git a/mmgen/protocol.py b/mmgen/protocol.py index ded7ac47..0c56f258 100755 --- a/mmgen/protocol.py +++ b/mmgen/protocol.py @@ -84,9 +84,11 @@ class CoinProtocol(MMGenObject): self.addr_fmt_to_ver_bytes = {v:k for k,v in self.addr_ver_bytes.items()} self.addr_ver_bytes_len = len(list(self.addr_ver_bytes)[0]) - if 'tx' not in self.mmcaps and gc.is_txprog: - from .util import die - die(2,f'Command {gc.prog_name!r} not supported for coin {self.coin}') + if gc.cmd_caps: + for cap in gc.cmd_caps.caps: + if cap not in self.mmcaps: + from .util import die + die(2, f'Command {gc.prog_name!r} not supported for coin {self.coin}') if self.chain_names: self.chain_name = self.chain_names[0] # first chain name is default diff --git a/test/cmdtest_py_d/ct_help.py b/test/cmdtest_py_d/ct_help.py index a70d6401..9baf4c99 100755 --- a/test/cmdtest_py_d/ct_help.py +++ b/test/cmdtest_py_d/ct_help.py @@ -17,7 +17,7 @@ import sys, os, time from mmgen.util import ymsg from mmgen.cfg import gc -from ..include.common import cfg, proto_cmds +from ..include.common import cfg from .ct_base import CmdTestBase class CmdTestHelp(CmdTestBase): @@ -83,25 +83,29 @@ class CmdTestHelp(CmdTestBase): t.skip_ok = True return t - def helpscreens(self,arg='--help',scripts=(),expect='USAGE:.*OPTIONS:',pager=True): + def helpscreens(self, arg='--help', scripts=(), expect='USAGE:.*OPTIONS:', pager=True): - scripts = list(scripts) or [s.replace('mmgen-','') for s in os.listdir('cmds')] + scripts = list(scripts or gc.cmd_caps_data) - if 'tx' not in self.proto.mmcaps: - scripts = [s for s in scripts if not (s == 'regtest' or s.startswith('tx'))] + def gen_skiplist(): + for script in scripts: + d = gc.cmd_caps_data[script] + for cap in d.caps: + if cap not in self.proto.mmcaps: + yield script + break + else: + if sys.platform == 'win32' and 'w' not in d.platforms: + yield script + elif d.coin and len(d.coin) > 1 and self.proto.coin.lower() not in (d.coin, 'btc'): + yield script - if 'xmrwallet' in scripts and (cfg.no_altcoin or not self.proto.coin in ('BTC','XMR')): - scripts.remove('xmrwallet') - - if 'autosign' in scripts and sys.platform == 'win32': - scripts.remove('autosign') - - for cmdname in sorted(scripts): + for cmdname in sorted(set(scripts) - set(list(gen_skiplist()))): t = self.spawn( f'mmgen-{cmdname}', [arg], extra_desc = f'(mmgen-{cmdname})', - no_passthru_opts = not cmdname in proto_cmds) + no_passthru_opts = not gc.cmd_caps_data[cmdname].proto) t.expect(expect,regex=True) if pager and t.pexpect_spawn: time.sleep(0.2)