Browse Source

comments, whitespace, minor cleanups

The MMGen Project 2 months ago
parent
commit
1f1e0a1186

+ 5 - 3
mmgen/devinit.py

@@ -43,14 +43,15 @@ class MMGenObjectDevTools:
 	pexit = lambda *args, **kwargs: MMGenObject_call('pexit', *args, **kwargs)
 	pfmt  = lambda *args, **kwargs: MMGenObject_call('pfmt', *args, **kwargs)
 
-	# Check that all immutables have been initialized.  Expensive, so do only when testing.
+	# Check that all immutable attrs in ‘valid_attrs’ exist and have been initialized.
+	# Expensive, so do only when testing.
 	def immutable_attr_init_check(self):
 
 		cls = type(self)
 
 		for attrname in self.valid_attrs:
-
-			for o in (cls, cls.__bases__[0]): # assume there's only one base class
+			# existence check:
+			for o in cls.__mro__[:3]: # allow for 2 levels of subclassing
 				if attrname in o.__dict__:
 					attr = o.__dict__[attrname]
 					break
@@ -58,6 +59,7 @@ class MMGenObjectDevTools:
 				from .util import die
 				die(4, f'unable to find descriptor {cls.__name__}.{attrname}')
 
+			# initialization check:
 			if type(attr).__name__ == 'ImmutableAttr' and attrname not in self.__dict__:
 				from .util import die
 				die(4, f'attribute {attrname!r} of {cls.__name__} has not been initialized in constructor!')

+ 51 - 38
mmgen/help/help_notes.py

@@ -22,11 +22,12 @@ class help_notes:
 
 	def txcreate_args(self):
 		return (
-			'<addr,amt>' if self.proto.base_coin == 'ETH' else
-			'[<addr,amt> ...] <change addr, addrlist ID or addr type>')
+			'[ADDR,AMT ...] ADDR <change addr, addrlist ID or addr type>'
+				if self.proto.base_proto == 'Bitcoin' else
+			'ADDR,AMT')
 
 	def account_info_desc(self):
-		return 'account info' if self.proto.base_coin == 'ETH' else 'unspent outputs'
+		return 'unspent outputs' if self.proto.base_proto == 'Bitcoin' else 'account info'
 
 	def fee_spec_letters(self, use_quotes=False):
 		cu = self.proto.coin_amt.units
@@ -77,14 +78,20 @@ class help_notes:
 
 	def address_types(self):
 		from ..addr import MMGenAddrType
-		return '\n  '.join([
-			"'{}','{:<12} - {}".format(k, v.name + "'", v.desc)
-				for k, v in MMGenAddrType.mmtypes.items()
-		])
+		return """
+ADDRESS TYPES:
+
+  Code Type           Description
+  ---- ----           -----------
+  """ + format('\n  '.join(['‘{}’  {:<12} - {}'.format(k, v.name, v.desc)
+				for k, v in MMGenAddrType.mmtypes.items()]))
 
 	def fmt_codes(self):
 		from ..wallet import format_fmt_codes
-		return '\n  '.join(format_fmt_codes().splitlines())
+		return """
+FMT CODES:
+
+  """ + '\n  '.join(format_fmt_codes().splitlines())
 
 	def coin_id(self):
 		return self.proto.coin_id
@@ -147,20 +154,7 @@ seed, the same seed length and hash preset parameters must always be used.
 		addr = t.privhex2addr('bead' * 16)
 		sample_addr = addr.views[addr.view_pref]
 
-		if self.proto.base_coin == 'ETH':
-			return f"""
-EXAMPLES:
-
-  Send 0.123 {self.proto.coin} to an external {self.proto.name} address:
-
-    $ {gc.prog_name} {sample_addr},0.123
-
-  Send 0.123 {self.proto.coin} to another account in wallet 01ABCDEF:
-
-    $ {gc.prog_name} 01ABCDEF:{mmtype}:7,0.123
-"""
-		else:
-			return f"""
+		return f"""
 EXAMPLES:
 
   Send 0.123 {self.proto.coin} to an external {self.proto.name} address, returning the change to a
@@ -190,23 +184,47 @@ EXAMPLES:
   address of specified type:
 
     $ {gc.prog_name} {mmtype}
+""" if self.proto.base_proto == 'Bitcoin' else f"""
+EXAMPLES:
+
+  Send 0.123 {self.proto.coin} to an external {self.proto.name} address:
+
+    $ {gc.prog_name} {sample_addr},0.123
+
+  Send 0.123 {self.proto.coin} to another account in wallet 01ABCDEF:
+
+    $ {gc.prog_name} 01ABCDEF:{mmtype}:7,0.123
 """
 
 	def txcreate(self):
-		return f"""
+		outputs_info = (
+			"""
+Outputs are specified in the form ADDRESS,AMOUNT or ADDRESS.  The first form
+creates an output sending the given amount to the given address.  The bare
+address form designates the given address as either the change output or the
+sole output of the transaction (excluding any data output).  Exactly one bare
+address argument is required.
+
+For convenience, the bare address argument may be given as ADDRTYPE_CODE or
+SEED_ID:ADDRTYPE_CODE (see ADDRESS TYPES below). In the first form, the first
+unused address of type ADDRTYPE_CODE for each Seed ID in the tracking wallet
+will be displayed in a menu, with the user prompted to select one.  In the
+second form, the user specifies the Seed ID as well, allowing the script to
+select the transaction’s change output or single output without prompting.
+See EXAMPLES below.
+"""
+		if self.proto.base_proto == 'Bitcoin' else """
+The transaction output is specified in the form ADDRESS,AMOUNT.
+""")
+
+		return """
 The transaction’s outputs are listed on the command line, while its inputs
 are chosen from a list of the wallet’s unspent outputs via an interactive
 menu.  Alternatively, inputs may be specified using the --inputs option.
 
-All addresses on the command line can be either {self.proto.name} addresses or MMGen
-IDs in the form <seed ID>:<address type letter>:<index>.
-
-Outputs are specified in the form <address>,<amount>, with the change output
-specified by address only.  Alternatively, the change output may be an
-addrlist ID in the form <seed ID>:<address type letter>, in which case the
-first unused address in the tracking wallet matching the requested ID will
-be automatically selected as the change output.
-
+Addresses on the command line can be either native coin addresses or MMGen
+IDs in the form SEED_ID:ADDRTYPE_CODE:INDEX.
+{oinfo}
 If the transaction fee is not specified on the command line (see FEE
 SPECIFICATION below), it will be calculated dynamically using network fee
 estimation for the default (or user-specified) number of confirmations.
@@ -214,12 +232,7 @@ If network fee estimation fails, the user will be prompted for a fee.
 
 Network-estimated fees will be multiplied by the value of --fee-adjust, if
 specified.
-
-To send the value of all inputs (minus TX fee) to a single output, specify
-a single address with no amount on the command line.  Alternatively, an
-addrlist ID may be specified, and the address will be chosen automatically
-as described above for the change output.
-"""
+""".format(oinfo=outputs_info)
 
 	def txsign(self):
 		from ..proto.btc.params import mainnet

+ 2 - 5
mmgen/main_addrgen.py

@@ -90,17 +90,14 @@ range(s).
 
 {n_addrkey}If available, the libsecp256k1 library will be used for address generation.
 
-ADDRESS TYPES:
-  {n_at}
-
 
                       NOTES FOR ALL GENERATOR COMMANDS
 
 {n_sw}{n_pw}{n_bw}
 
-FMT CODES:
+{n_at}
 
-  {n_fmt}
+{n_fmt}
 """
 	},
 	'code': {

+ 5 - 8
mmgen/main_msg.py

@@ -126,16 +126,13 @@ export - dump signed MMGen message file to ‘signatures.json’, including only
 The `create` operation takes one or more ADDRESS_SPEC arguments with the
 following format:
 
-    SEED_ID:ADDR_TYPE:ADDR_IDX_SPEC
+    SEED_ID:ADDRTYPE_CODE:ADDR_IDX_SPEC
 
-where ADDR_TYPE is an address type letter from the list below, and
-ADDR_IDX_SPEC is a comma-separated list of address indexes or hyphen-
-separated address index ranges.
+where ADDRTYPE_CODE is a one-letter address type code from the list below, and
+ADDR_IDX_SPEC is a comma-separated list of address indexes or hyphen-separated
+address index ranges.
 
-
-                                ADDRESS TYPES
-
-  {n_at}
+{n_at}
 
 
                                     NOTES

+ 1 - 3
mmgen/main_passgen.py

@@ -110,9 +110,7 @@ EXAMPLES:
 
 {n_bw}
 
-FMT CODES:
-
-  {n_fmt}
+{n_fmt}
 """
 	},
 	'code': {

+ 1 - 3
mmgen/main_seedjoin.py

@@ -73,9 +73,7 @@ For usage examples, see the help screen for the 'mmgen-seedsplit' command.
 
 {n_pw}
 
-FMT CODES:
-
-  {f}
+{f}
 """
 	},
 	'code': {

+ 1 - 3
mmgen/main_txbump.py

@@ -84,9 +84,7 @@ opts_data = {
 Seed source files must have the canonical extensions listed in the 'FileExt'
 column below:
 
-FMT CODES:
-
-  {f}
+{f}
 """
 	},
 	'code': {

+ 3 - 2
mmgen/main_txcreate.py

@@ -66,7 +66,7 @@ opts_data = {
 			-- -y, --yes             Answer 'yes' to prompts, suppress non-essential output
 			e- -X, --cached-balances Use cached balances
 		""",
-		'notes': '\n{c}\n{F}\n{x}',
+		'notes': '\n{c}\n{n_at}\n\n{F}\n{x}',
 	},
 	'code': {
 		'usage': lambda cfg, proto, help_notes, s: s.format(
@@ -82,7 +82,8 @@ opts_data = {
 		'notes': lambda cfg, help_notes, s: s.format(
 			c      = help_notes('txcreate'),
 			F      = help_notes('fee'),
-			x      = help_notes('txcreate_examples'))
+			x      = help_notes('txcreate_examples'),
+			n_at   = help_notes('address_types'))
 	}
 }
 

+ 3 - 2
mmgen/main_txdo.py

@@ -95,9 +95,9 @@ opts_data = {
 Seed source files must have the canonical extensions listed in the 'FileExt'
 column below:
 
-FMT CODES:
+{n_at}
 
-  {f}
+{f}
 
 {x}"""
 	},
@@ -124,6 +124,7 @@ FMT CODES:
 			c       = help_notes('txcreate'),
 			F       = help_notes('fee'),
 			s       = help_notes('txsign'),
+			n_at    = help_notes('address_types'),
 			f       = help_notes('fmt_codes'),
 			x       = help_notes('txcreate_examples')),
 	}

+ 1 - 3
mmgen/main_txsign.py

@@ -74,9 +74,7 @@ opts_data = {
 Seed source files must have the canonical extensions listed in the 'FileExt'
 column below:
 
-FMT CODES:
-
-  {f}
+{f}
 """
 	},
 	'code': {

+ 1 - 3
mmgen/main_wallet.py

@@ -122,9 +122,7 @@ opts_data = {
 
 {n_ss}{n_sw}{n_pw}{n_bw}
 
-FMT CODES:
-
-  {f}
+{f}
 """
 	},
 	'code': {

+ 2 - 3
mmgen/obj.py

@@ -107,10 +107,9 @@ class ImmutableAttr: # Descriptor
 		self.typeconv = typeconv
 
 		assert isinstance(dtype, self.ok_dtypes), 'ImmutableAttr_check1'
-		if include_proto:
-			assert typeconv, 'ImmutableAttr_check2'
+
 		if set_none_ok:
-			assert typeconv and not isinstance(dtype, str), 'ImmutableAttr_check3'
+			assert typeconv and not isinstance(dtype, str), 'ImmutableAttr_check2'
 
 		if typeconv:
 			# convert this attribute's type

+ 1 - 2
mmgen/rpc.py

@@ -21,7 +21,6 @@ rpc: Cryptocoin RPC library for the MMGen suite
 """
 
 import sys, re, base64, json, asyncio, importlib
-from decimal import Decimal
 from collections import namedtuple
 
 from .util import msg, ymsg, die, fmt, fmt_list, pp_fmt, oneshot_warning
@@ -75,7 +74,7 @@ class IPPort(HiliteStr, InitErrors):
 
 class json_encoder(json.JSONEncoder):
 	def default(self, o):
-		if isinstance(o, Decimal):
+		if type(o).__name__.endswith('Amt'):
 			return str(o)
 		else:
 			return json.JSONEncoder.default(self, o)

+ 2 - 1
test/cmdtest_d/ct_regtest.py

@@ -63,7 +63,8 @@ pat_date_time = r'\b\d\d\d\d-\d\d-\d\d\s+\d\d:\d\d\b'
 
 dfl_wcls = get_wallet_cls('mmgen')
 
-tx_fee = rtFundAmt = rtFee = rtBals = rtBals_gb = rtBobOp3 = rtAmts = {} # ruff
+tx_fee = rtFundAmt = rtFee = rtBals = rtBals_gb = rtBobOp3 = rtAmts = None # ruff
+
 rt_pw = 'abc-α'
 rt_data = {
 	'tx_fee': {'btc':'0.0001', 'bch':'0.001', 'ltc':'0.01'},

+ 1 - 1
test/include/pexpect.py

@@ -82,7 +82,7 @@ class MMGenPexpect:
 
 	def view_tx(self, view):
 		self.expect(r'View.* transaction.*\? .*: ', view, regex=True)
-		if view not in 'n\n':
+		if view not in 'vn\n':
 			self.expect('to continue: ', '\n')
 
 	def do_comment(self, add_comment, has_label=False):