minor fixes and cleanups
This commit is contained in:
parent
92ab29a138
commit
ede7353ea2
6 changed files with 76 additions and 34 deletions
|
|
@ -44,7 +44,7 @@ def launch(*, mod=None, func=None, fqmod=None, package='mmgen'):
|
|||
try:
|
||||
errmsg = str(e.args[0])
|
||||
except:
|
||||
errmsg = repr(e.args[0])
|
||||
errmsg = repr(e.args[0]) if e.args else repr(e)
|
||||
|
||||
from collections import namedtuple
|
||||
from .color import nocolor,yellow,red
|
||||
|
|
|
|||
31
mmgen/obj.py
31
mmgen/obj.py
|
|
@ -347,6 +347,7 @@ class MMGenLabel(HiliteStr,InitErrors):
|
|||
color = 'pink'
|
||||
allowed = []
|
||||
forbidden = []
|
||||
first_char = []
|
||||
max_len = 0
|
||||
min_len = 0
|
||||
max_screen_width = 0 # if != 0, overrides max_len
|
||||
|
|
@ -354,21 +355,18 @@ class MMGenLabel(HiliteStr,InitErrors):
|
|||
def __new__(cls,s):
|
||||
if isinstance(s,cls):
|
||||
return s
|
||||
for k in ( cls.forbidden, cls.allowed ):
|
||||
assert isinstance(k,list)
|
||||
for ch in k:
|
||||
assert isinstance(ch,str) and len(ch) == 1
|
||||
try:
|
||||
s = s.strip()
|
||||
for ch in s:
|
||||
# Allow: (L)etter,(N)umber,(P)unctuation,(S)ymbol,(Z)space
|
||||
# Disallow: (C)ontrol,(M)combining
|
||||
# Combining characters create width formatting issues, so disallow them for now
|
||||
if unicodedata.category(ch)[0] in ('C','M'):
|
||||
raise ValueError(
|
||||
'{!a}: {} characters not allowed'.format(
|
||||
ch,
|
||||
{ 'C':'control', 'M':'combining' }[unicodedata.category(ch)[0]] ))
|
||||
if not cls.allowed:
|
||||
for ch in s:
|
||||
# Allow: (L)etter,(N)umber,(P)unctuation,(S)ymbol,(Z)space
|
||||
# Disallow: (C)ontrol,(M)combining
|
||||
# Combining characters create width formatting issues, so disallow them for now
|
||||
if unicodedata.category(ch)[0] in ('C','M'):
|
||||
raise ValueError(
|
||||
'{!a}: {} characters not allowed'.format(
|
||||
ch,
|
||||
{ 'C':'control', 'M':'combining' }[unicodedata.category(ch)[0]] ))
|
||||
|
||||
me = str.__new__(cls,s)
|
||||
|
||||
|
|
@ -380,11 +378,14 @@ class MMGenLabel(HiliteStr,InitErrors):
|
|||
|
||||
assert len(s) >= cls.min_len, f'too short (<{cls.min_len} symbols)'
|
||||
|
||||
if cls.first_char and s and not s[0] in cls.first_char:
|
||||
raise ValueError('first character not in set ' + ' '.join(cls.first_char))
|
||||
|
||||
if cls.allowed and not set(list(s)).issubset(set(cls.allowed)):
|
||||
raise ValueError('contains non-allowed symbols: ' + ' '.join(set(list(s)) - set(cls.allowed)) )
|
||||
raise ValueError('contains symbols not in set: ' + ' '.join(cls.allowed))
|
||||
|
||||
if cls.forbidden and any(ch in s for ch in cls.forbidden):
|
||||
raise ValueError('contains one of these forbidden symbols: ' + ' '.join(cls.forbidden) )
|
||||
raise ValueError('contains one of these forbidden symbols: ' + ' '.join(cls.forbidden))
|
||||
|
||||
return me
|
||||
except Exception as e:
|
||||
|
|
|
|||
|
|
@ -79,14 +79,16 @@ class New(Base,TxBase.New):
|
|||
self.txid = MMGenTxID(make_chksum_6(self.serialized).upper())
|
||||
|
||||
async def process_cmd_args(self,cmd_args,ad_f,ad_w):
|
||||
|
||||
lc = len(cmd_args)
|
||||
|
||||
if lc == 0 and self.usr_contract_data and 'Token' not in self.name:
|
||||
return
|
||||
if lc != 1:
|
||||
die(1,f'{lc} output{suf(lc)} specified, but Ethereum transactions must have exactly one')
|
||||
|
||||
for a in cmd_args:
|
||||
await self.process_cmd_arg(a,ad_f,ad_w)
|
||||
if lc != 1:
|
||||
die(1, f'{lc} output{suf(lc)} specified, but Ethereum transactions must have exactly one')
|
||||
|
||||
await self.process_cmd_arg(cmd_args[0],ad_f,ad_w)
|
||||
|
||||
def select_unspent(self,unspent):
|
||||
from ....ui import line_input
|
||||
|
|
|
|||
|
|
@ -323,7 +323,10 @@ class TwAddresses(TwView):
|
|||
if start is not None:
|
||||
for d in data[start:]:
|
||||
if d.al_id == al_id:
|
||||
if not d.recvd and (self.cfg.autochg_ignore_labels or not d.comment):
|
||||
if (
|
||||
not d.recvd
|
||||
and (self.cfg.autochg_ignore_labels or not d.comment)
|
||||
):
|
||||
if d.comment:
|
||||
msg('{} {} {} {}{}'.format(
|
||||
yellow('WARNING: address'),
|
||||
|
|
@ -369,7 +372,8 @@ class TwAddresses(TwView):
|
|||
|
||||
assert isinstance(mmtype,MMGenAddrType)
|
||||
|
||||
res = [self.get_change_address( f'{sid}:{mmtype}', r.bot, r.top ) for sid,r in self.sid_ranges.items()]
|
||||
res = [self.get_change_address(f'{sid}:{mmtype}', r.bot, r.top)
|
||||
for sid,r in self.sid_ranges.items()]
|
||||
|
||||
if any(res):
|
||||
res = list(filter(None,res))
|
||||
|
|
|
|||
|
|
@ -221,17 +221,18 @@ class New(Base):
|
|||
await self.process_cmd_arg(a,ad_f,ad_w)
|
||||
|
||||
if self.chg_idx is None:
|
||||
die(2,(
|
||||
fmt( self.msg_no_change_output.format(self.dcoin) ).strip()
|
||||
die(2,
|
||||
fmt(self.msg_no_change_output.format(self.dcoin)).strip()
|
||||
if len(self.outputs) == 1 else
|
||||
'ERROR: No change output specified' ))
|
||||
'ERROR: No change output specified')
|
||||
|
||||
if self.has_segwit_outputs() and not self.rpc.info('segwit_is_active'):
|
||||
die(2,f'{gc.proj_name} Segwit address requested on the command line, '
|
||||
+ 'but Segwit is not active on this chain')
|
||||
die(2,
|
||||
f'{gc.proj_name} Segwit address requested on the command line, '
|
||||
'but Segwit is not active on this chain')
|
||||
|
||||
if not self.outputs:
|
||||
die(2,'At least one output must be specified on the command line')
|
||||
die(2, 'At least one output must be specified on the command line')
|
||||
|
||||
async def get_outputs_from_cmdline(self,cmd_args):
|
||||
from ..addrdata import AddrData,TwAddrData
|
||||
|
|
|
|||
|
|
@ -438,6 +438,11 @@ class CmdTestRegtest(CmdTestBase,CmdTestShared):
|
|||
('bob_auto_chg_bad3', 'error handling for auto change address transaction (no unused addresses)'),
|
||||
('bob_auto_chg_bad4', 'error handling for auto change address transaction by addrtype '
|
||||
'(no unused addresses)'),
|
||||
('bob_auto_chg_bad5', 'error handling (more than one chg address listed)'),
|
||||
('bob_auto_chg_bad6', 'error handling for auto change address transaction '
|
||||
'(more than one chg address, mixed)'),
|
||||
('bob_auto_chg_bad7', 'error handling for auto change address transaction '
|
||||
'(more than one chg address requested)'),
|
||||
('carol_twimport2', 'recreating Carol’s tracking wallet from JSON dump'),
|
||||
('carol_rescan_blockchain', 'rescanning the blockchain (full rescan)'),
|
||||
('carol_auto_chg1', 'creating an automatic change address transaction (C)'),
|
||||
|
|
@ -1882,16 +1887,19 @@ class CmdTestRegtest(CmdTestBase,CmdTestShared):
|
|||
idx,
|
||||
by_mmtype = False,
|
||||
include_dest = True,
|
||||
ignore_labels = False):
|
||||
ignore_labels = False,
|
||||
add_args = []):
|
||||
|
||||
if mmtype in ('S','B') and not self.proto.cap('segwit'):
|
||||
return 'skip'
|
||||
sid = self._user_sid('bob')
|
||||
t = self.spawn(
|
||||
'mmgen-txcreate',
|
||||
[f'--outdir={self.tr.trash_dir}', '--no-blank', f'--{user}'] +
|
||||
(['--autochg-ignore-labels'] if ignore_labels else []) +
|
||||
[mmtype if by_mmtype else f'{sid}:{mmtype}'] +
|
||||
([self.burn_addr+',0.01'] if include_dest else [])
|
||||
[f'--outdir={self.tr.trash_dir}', '--no-blank', f'--{user}']
|
||||
+ (['--autochg-ignore-labels'] if ignore_labels else [])
|
||||
+ [mmtype if by_mmtype else f'{sid}:{mmtype}']
|
||||
+ ([self.burn_addr+',0.01'] if include_dest else [])
|
||||
+ add_args
|
||||
)
|
||||
return self.txcreate_ui_common(t,
|
||||
menu = [],
|
||||
|
|
@ -1949,10 +1957,13 @@ class CmdTestRegtest(CmdTestBase,CmdTestShared):
|
|||
def bob_remove_comment_uua1(self):
|
||||
return self._bob_remove_comment_uua(':C:3')
|
||||
|
||||
def _usr_auto_chg_bad(self,user,al_id,expect):
|
||||
def _usr_auto_chg_bad(self, user, al_id, expect, add_args=[]):
|
||||
t = self.spawn(
|
||||
'mmgen-txcreate',
|
||||
['-d', self.tr.trash_dir, '-B', f'--{user}', self.burn_addr+', 0.01', al_id],
|
||||
['-d', self.tr.trash_dir, '-B', f'--{user}']
|
||||
+ [f'{self.burn_addr},0.01']
|
||||
+ ([al_id] if al_id else [])
|
||||
+ add_args,
|
||||
exit_val = 2)
|
||||
t.expect(expect)
|
||||
return t
|
||||
|
|
@ -1981,6 +1992,29 @@ class CmdTestRegtest(CmdTestBase,CmdTestShared):
|
|||
'L',
|
||||
'contains no unused addresses of address type' )
|
||||
|
||||
def bob_auto_chg_bad5(self):
|
||||
sid = self._user_sid('bob')
|
||||
return self._usr_auto_chg_bad(
|
||||
'bob',
|
||||
None,
|
||||
'More than one change address listed',
|
||||
add_args = [f'{sid}:C:4', f'{sid}:C:5'])
|
||||
|
||||
def bob_auto_chg_bad6(self):
|
||||
sid = self._user_sid('bob')
|
||||
return self._usr_auto_chg_bad(
|
||||
'bob',
|
||||
'L',
|
||||
'More than one',
|
||||
add_args = [f'{sid}:C:4'])
|
||||
|
||||
def bob_auto_chg_bad7(self):
|
||||
return self._usr_auto_chg_bad(
|
||||
'bob',
|
||||
'L',
|
||||
'More than one change address requested',
|
||||
add_args = ['B'])
|
||||
|
||||
def carol_twimport2(self):
|
||||
u,b = (4,3) if self.proto.cap('segwit') else (3,2)
|
||||
return self.carol_twimport(
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue