mmgen.tx,mmgen.tw: class, variable and function renames

Code:
    - lbl                            -> comment
    - tw.label                       -> tw.comment
    - tx.label                       -> tx.comment
    - MMGenTxLabel                   -> MMGenTxComment
    - daemon.set_label_args()        -> daemon.set_comment_args()
    - TwTransaction.get_best_label() -> TwTransaction.get_best_comment()
    - a_lbl_add()                    -> a_comment_add()
    - do_lbl_add()                   -> do_comment_add()
    - tw.add_label()                 -> tw.add_comment()
    - tw.set_label()                 -> tw.set_comment()
    - tw.remove_label()              -> tw.remove_comment()
    - AddrListEntry.label            -> AddrListEntry.comment
    - PasswordListEntry.label        -> PasswordListEntry.comment

    - TwCommon.column_params         -> TwCommon.column_widths
    - update_params_on_age_toggle    -> update_widths_on_age_toggle

Test suite:
    - tx_label_*                     -> tx_comment_*
    - tw_label_*                     -> tw_comment_*
    - get_label()                    -> get_comment()
    - *{add,edit,chk,remove}_label() -> *{add,edit,chk,remove}_comment()
This commit is contained in:
The MMGen Project 2022-11-09 13:05:07 +00:00
commit 12baa5ee9a
Signed by: mmgen
GPG key ID: 3F8B1861E32B7DA2
29 changed files with 246 additions and 234 deletions

View file

@ -91,7 +91,7 @@ class TwAddrData(AddrData,metaclass=AsyncInit):
al_id = AddrListID(SeedID(sid=obj.sid),self.proto.addr_type(obj.mmtype))
if al_id not in out:
out[al_id] = []
out[al_id].append(AddrListEntry(self.proto,idx=obj.idx,addr=addr_array[0],label=l.comment))
out[al_id].append(AddrListEntry(self.proto,idx=obj.idx,addr=addr_array[0],comment=l.comment))
i += 1
vmsg(f'{i} {g.proj_name} addresses found, {len(twd)} accounts total')

View file

@ -102,7 +102,7 @@ class AddrFile(MMGenObject):
fs = ' {:<%s} {:<34}{}' % len(str(p.data[-1].idx))
for e in p.data:
c = ' '+e.label if add_comments and e.label else ''
c = ' ' + e.comment if add_comments and e.comment else ''
if type(p) == KeyList:
out.append(fs.format( e.idx, f'{p.al_id.mmtype.wif_label}: {e.sec.wif}', c ))
elif type(p).__name__ == 'PasswordList':
@ -137,12 +137,12 @@ class AddrFile(MMGenObject):
iifs = "{!r}: invalid identifier [expected '{}:']"
while lines:
idx,addr,lbl = self.get_line(lines)
idx,addr,comment = self.get_line(lines)
assert is_addr_idx(idx), f'invalid address index {idx!r}'
p.check_format(addr)
a = le(**{ 'proto': p.proto, 'idx':int(idx), p.main_attr:addr, 'label':lbl })
a = le(**{ 'proto': p.proto, 'idx':int(idx), p.main_attr:addr, 'comment':comment })
if p.has_keys: # order: wif,(orig_hex),viewkey,wallet_passwd
d = self.get_line(lines)

View file

@ -71,7 +71,7 @@ class AddrListEntry(AddrListEntryBase):
addr = ListItemAttr(CoinAddr,include_proto=True)
addr_p2pkh = ListItemAttr(CoinAddr,include_proto=True)
idx = ListItemAttr(AddrIdx) # not present in flat addrlists
label = ListItemAttr(TwComment,reassign_ok=True)
comment = ListItemAttr(TwComment,reassign_ok=True)
sec = ListItemAttr(PrivKey,include_proto=True)
viewkey = ListItemAttr(ViewKey,include_proto=True)
wallet_passwd = ListItemAttr(WalletPassword)
@ -306,7 +306,7 @@ class AddrList(MMGenObject): # Address info for a single seed ID
return [e.addr for e in self.data]
def comments(self):
return [e.label for e in self.data]
return [e.comment for e in self.data]
def entry(self,idx):
for e in self.data:
@ -321,19 +321,19 @@ class AddrList(MMGenObject): # Address info for a single seed ID
def comment(self,idx):
for e in self.data:
if idx == e.idx:
return e.label
return e.comment
def set_comment(self,idx,comment):
for e in self.data:
if idx == e.idx:
e.label = comment
e.comment = comment
def make_reverse_dict_addrlist(self,coinaddrs):
d = MMGenDict()
b = coinaddrs
for e in self.data:
try:
d[b[b.index(e.addr)]] = ( MMGenID(self.proto, f'{self.al_id}:{e.idx}'), e.label )
d[b[b.index(e.addr)]] = ( MMGenID(self.proto, f'{self.al_id}:{e.idx}'), e.comment )
except ValueError:
pass
return d

View file

@ -169,7 +169,7 @@ async def main():
yield _d(
addr = e.addr,
twmmid = f'{al.al_id}:{e.idx}' if e.idx else f'{proto.base_coin.lower()}:{e.addr}',
comment = e.label )
comment = e.comment )
args_list = list(gen_args_list(al))

View file

@ -381,7 +381,7 @@ class TwComment(MMGenLabel):
desc = 'tracking wallet comment'
exc = 'BadTwComment'
class MMGenTxLabel(MMGenLabel):
class MMGenTxComment(MMGenLabel):
max_len = 72
desc = 'transaction label'

View file

@ -35,10 +35,10 @@ from .addrlist import (
)
class PasswordListEntry(AddrListEntryBase):
passwd = ListItemAttr(str,typeconv=False) # TODO: create Password type
idx = ImmutableAttr(AddrIdx)
label = ListItemAttr(TwComment,reassign_ok=True)
sec = ListItemAttr(PrivKey,include_proto=True)
passwd = ListItemAttr(str,typeconv=False) # TODO: create Password type
idx = ImmutableAttr(AddrIdx)
comment = ListItemAttr(TwComment,reassign_ok=True)
sec = ListItemAttr(PrivKey,include_proto=True)
class PasswordList(AddrList):
entry_type = PasswordListEntry

View file

@ -109,7 +109,7 @@ class bitcoin_core_daemon(CoinDaemon):
def stop_cmd(self):
return self.cli_cmd('stop')
def set_label_args(self,rpc,coinaddr,lbl):
def set_comment_args(self,rpc,coinaddr,lbl):
if 'label_api' in rpc.caps:
return ('setlabel',coinaddr,lbl)
else:
@ -136,7 +136,7 @@ class bitcoin_cash_node_daemon(bitcoin_core_daemon):
cfg_file_hdr = '# Bitcoin Cash Node config file\n'
nonstd_datadir = True
def set_label_args(self,rpc,coinaddr,lbl):
def set_comment_args(self,rpc,coinaddr,lbl):
# bitcoin-{abc,bchn} 'setlabel' RPC is broken, so use old 'importaddress' method to set label
# Broken behavior: new label is set OK, but old label gets attached to another address
return ('importaddress',coinaddr,lbl,False)

View file

@ -40,8 +40,8 @@ class BitcoinTrackingWallet(TrackingWallet):
raise NotImplementedError(f'address removal not implemented for coin {self.proto.coin}')
@write_mode
async def set_label(self,coinaddr,lbl):
args = self.rpc.daemon.set_label_args( self.rpc, coinaddr, lbl )
async def set_comment(self,coinaddr,lbl):
args = self.rpc.daemon.set_comment_args( self.rpc, coinaddr, lbl )
try:
return await self.rpc.call(*args)
except Exception as e:

View file

@ -26,8 +26,8 @@ class BitcoinTwTransaction(BitcoinTwCommon):
def __init__(self,parent,proto,rpc,
idx, # unique numeric identifier of this transaction in listing
unspent_info, # addrs in wallet with balances: { 'mmid': {'addr','label','amt'} }
mm_map, # all addrs in wallet: ['addr', ['twmmid','label']]
unspent_info, # addrs in wallet with balances: { 'mmid': {'addr','comment','amt'} }
mm_map, # all addrs in wallet: ['addr', ['twmmid','comment']]
tx, # the decoded transaction data
wallet_vouts, # list of ints - wallet-related vouts
prevouts, # list of (txid,vout) pairs
@ -88,12 +88,12 @@ class BitcoinTwTransaction(BitcoinTwCommon):
def total(data):
return self.proto.coin_amt( sum(d.data['value'] for d in data) )
def get_best_label():
def get_best_comment():
"""
find the most relevant label for tabular (squeezed) display
find the most relevant comment for tabular (squeezed) display
"""
def vouts_labels(src):
return [ d.twlabel.label for d in self.vouts_info[src] if d.twlabel and d.twlabel.label ]
return [ d.twlabel.comment for d in self.vouts_info[src] if d.twlabel and d.twlabel.comment ]
ret = vouts_labels('outputs') or vouts_labels('inputs')
return ret[0] if ret else TwComment('')
@ -112,7 +112,7 @@ class BitcoinTwTransaction(BitcoinTwCommon):
self.fee = self.inputs_total - self.outputs_total
self.nOutputs = len(self.tx['decoded']['vout'])
self.confirmations = self.tx['confirmations']
self.label = get_best_label()
self.comment = get_best_comment()
self.vsize = self.tx['decoded'].get('vsize') or self.tx['decoded']['size']
self.txid = CoinTxID(self.tx['txid'])
# Though 'blocktime' is flagged as an “optional” field, it’s always present for transactions
@ -172,7 +172,7 @@ class BitcoinTwTransaction(BitcoinTwCommon):
color = color,
color_override = co ),
A = self.proto.coin_amt( e.data['value'] ).fmt(color=color),
l = e.twlabel.label.hl(color=color)
l = e.twlabel.comment.hl(color=color)
).rstrip()
return f'\n{indent}'.join( gen_output() ).strip()
@ -285,7 +285,7 @@ Actions: [q]uit, r[e]draw:
l = None
o.update({
'twmmid': l.mmid if l else None,
'label': (l.comment or '') if l else None,
'comment': (l.comment or '') if l else None,
})
yield o
@ -299,11 +299,11 @@ Actions: [q]uit, r[e]draw:
for d,fn_stem in data:
open(f'/tmp/{fn_stem}-{nw}.json','w').write(json.dumps(d,cls=json_encoder))
_mmp = namedtuple('mmap_datum',['twmmid','label'])
_mmp = namedtuple('mmap_datum',['twmmid','comment'])
mm_map = {
i['address']: (
_mmp( TwMMGenID(self.proto,i['twmmid']), TwComment(i['label']) )
_mmp( TwMMGenID(self.proto,i['twmmid']), TwComment(i['comment']) )
if i['twmmid'] else _mmp(None,None)
)
for i in data }

View file

@ -19,7 +19,7 @@ class BitcoinTwUnspentOutputs(TwUnspentOutputs):
class MMGenTwUnspentOutput(TwUnspentOutputs.MMGenTwUnspentOutput):
# required by gen_unspent(); setting valid_attrs explicitly is also more efficient
valid_attrs = {'txid','vout','amt','amt2','label','twmmid','addr','confs','date','scriptPubKey','skip'}
valid_attrs = {'txid','vout','amt','amt2','comment','twmmid','addr','confs','date','scriptPubKey','skip'}
invalid_attrs = {'proto'}
has_age = True
@ -50,7 +50,7 @@ Actions: [q]uit view, [p]rint to file, pager [v]iew, [w]ide view, add [l]abel:
'p':'a_print_detail',
'v':'a_view',
'w':'a_view_detail',
'l':'a_lbl_add' }
'l':'a_comment_add' }
col_adj = 38
squeezed_fs_fs = ' {{n:{cw}}} {{t:{tw}}} {{v:2}} {{a}} {{A}} {{c:<}}'

View file

@ -94,8 +94,8 @@ class TxInfo(TxInfo):
yield ('', 'address:', f'{e.addr.hl()} {mmid_fmt}')
else:
yield (n+1, 'address:', f'{e.addr.hl()} {mmid_fmt}')
if e.label:
yield ('', 'comment:', e.label.hl())
if e.comment:
yield ('', 'comment:', e.comment.hl())
yield ('', 'amount:', f'{e.amt.hl()} {tx.dcoin}')
if is_input and blockcount:
yield ('', 'confirmations:', f'{confs} (around {days} days)')

View file

@ -127,7 +127,7 @@ class EthereumTrackingWallet(TrackingWallet):
return None
@write_mode
async def set_label(self,coinaddr,lbl):
async def set_comment(self,coinaddr,lbl):
for addr,d in list(self.data_root.items()):
if addr == coinaddr:
d['comment'] = lbl.comment

View file

@ -27,7 +27,7 @@ from ....tw.unspent import TwUnspentOutputs
class EthereumTwUnspentOutputs(TwUnspentOutputs):
class MMGenTwUnspentOutput(TwUnspentOutputs.MMGenTwUnspentOutput):
valid_attrs = {'txid','vout','amt','amt2','label','twmmid','addr','confs','skip'}
valid_attrs = {'txid','vout','amt','amt2','comment','twmmid','addr','confs','skip'}
invalid_attrs = {'proto'}
has_age = False
@ -54,7 +54,7 @@ Actions: [q]uit view, [p]rint to file, pager [v]iew, [w]ide view,
'p':'a_print_detail',
'v':'a_view',
'w':'a_view_detail',
'l':'a_lbl_add',
'l':'a_comment_add',
'D':'a_addr_delete',
'R':'a_balance_refresh' }

View file

@ -149,7 +149,7 @@ class tool_cmd(tool_cmd_base):
async def add_label(self,mmgen_or_coin_addr:str,label:str):
"add descriptive label for address in tracking wallet"
from ..tw.ctl import TrackingWallet
await (await TrackingWallet(self.proto,mode='w')).add_label( mmgen_or_coin_addr, label, on_fail='raise' )
await (await TrackingWallet(self.proto,mode='w')).add_comment( mmgen_or_coin_addr, label, on_fail='raise' )
return True
async def remove_label(self,mmgen_or_coin_addr:str):

View file

@ -177,7 +177,7 @@ class TwCommon:
if self.has_age and self.age_fmt in self.age_fmts_date_dependent:
await self.set_dates(self.rpc,data)
if not getattr(self,'column_params',None):
if not getattr(self,'column_widths',None):
self.set_column_params()
if self.group and (self.sort_key in ('addr','txid','twmmid')):
@ -194,7 +194,7 @@ class TwCommon:
+ '\nNetwork: {}'.format((nocolor,green)[color](
self.proto.coin + ' ' +
self.proto.chain_name.upper() ))
+ '\n' + '\n'.join(self.gen_squeezed_display(self.column_params,color=color))
+ '\n' + '\n'.join(self.gen_squeezed_display(self.column_widths,color=color))
+ '\n'
)
@ -272,7 +272,7 @@ class TwCommon:
def d_days(self,parent):
af = parent.age_fmts_interactive
parent.age_fmt = af[(af.index(parent.age_fmt) + 1) % len(af)]
if parent.update_params_on_age_toggle:
if parent.update_widths_on_age_toggle:
parent.set_column_params()
def d_redraw(self,parent):

View file

@ -267,14 +267,14 @@ class TrackingWallet(MMGenObject,metaclass=AsyncInit):
# returns on failure
@write_mode
async def add_label(self,addrspec,label='',coinaddr=None,silent=False,on_fail='return'):
assert on_fail in ('return','raise'), 'add_label_chk1'
async def add_comment(self,addrspec,comment='',coinaddr=None,silent=False,on_fail='return'):
assert on_fail in ('return','raise'), 'add_comment_chk1'
res = await self.resolve_address(addrspec,coinaddr)
if not res:
return False
cmt = TwComment(label) if on_fail=='raise' else get_obj(TwComment,s=label)
cmt = TwComment(comment) if on_fail=='raise' else get_obj(TwComment,s=comment)
if cmt in (False,None):
return False
@ -283,29 +283,29 @@ class TrackingWallet(MMGenObject,metaclass=AsyncInit):
TwLabel(self.proto,lbl_txt) if on_fail == 'raise' else
get_obj(TwLabel,proto=self.proto,text=lbl_txt) )
if await self.set_label(res.coinaddr,lbl) == False:
if await self.set_comment(res.coinaddr,lbl) == False:
if not silent:
msg( 'Label could not be {}'.format('added' if label else 'removed') )
msg( 'Label could not be {}'.format('added' if comment else 'removed') )
return False
else:
desc = '{} address {} in tracking wallet'.format(
res.mmaddr.type.replace('mmgen','MMGen'),
res.mmaddr.replace(self.proto.base_coin.lower()+':','') )
if label:
msg(f'Added label {label!r} to {desc}')
if comment:
msg(f'Added label {comment!r} to {desc}')
else:
msg(f'Removed label from {desc}')
return True
@write_mode
async def remove_label(self,mmaddr):
await self.add_label(mmaddr,'')
async def remove_comment(self,mmaddr):
await self.add_comment(mmaddr,'')
async def import_address_common(self,data,batch=False,gather=False):
async def do_import(address,label,message):
async def do_import(address,comment,message):
try:
res = await self.import_address( address, label )
res = await self.import_address( address, comment )
qmsg(message)
return res
except Exception as e:

View file

@ -32,7 +32,7 @@ class TwTxHistory(MMGenObject,TwCommon,metaclass=AsyncInit):
show_total_amt = False
print_hdr_fs = '{a} (block #{b}, {c} UTC)\n{d}Sort order: {e}\n{f}\n'
age_fmts_interactive = ('confs','block','days','date','date_time')
update_params_on_age_toggle = True
update_widths_on_age_toggle = True
detail_display_separator = '\n\n'
print_output_types = ('squeezed','detail')
@ -57,7 +57,7 @@ class TwTxHistory(MMGenObject,TwCommon,metaclass=AsyncInit):
self.varcol_maxwidths = {
'addr1': max(len(d.vouts_disp('inputs',width=None,color=False)) for d in data),
'addr2': max(len(d.vouts_disp('outputs',width=None,color=False)) for d in data),
'lbl': max(len(d.label) for d in data),
'comment': max(len(d.comment) for d in data),
}
# var cols: addr1 addr2 comment [txid]
@ -72,7 +72,7 @@ class TwTxHistory(MMGenObject,TwCommon,metaclass=AsyncInit):
minw = {
'addr1': 15,
'addr2': 15,
'lbl': len('Comment'),
'comment': len('Comment'),
}
if show_txid:
minw.update({'txid': 8})
@ -94,8 +94,8 @@ class TwTxHistory(MMGenObject,TwCommon,metaclass=AsyncInit):
for k in maxw:
freew[k] = min( total_freew - sum(freew[k2] for k2 in varcols-{k}), varw[k] )
self.column_params = namedtuple('column_params',
['col1','txid','addr1','amt','addr2','lbl'])(
self.column_widths = namedtuple('column_params',
['col1','txid','addr1','amt','addr2','comment'])(
col1_w,
min(
# max txid was reduced by txid_adj, so stretch to fill available space, if any
@ -104,7 +104,7 @@ class TwTxHistory(MMGenObject,TwCommon,metaclass=AsyncInit):
minw['addr1'] + freew['addr1'],
amt_w,
minw['addr2'] + freew['addr2'],
minw['lbl'] + freew['lbl'] )
minw['comment'] + freew['comment'] )
def gen_squeezed_display(self,cw,color):
@ -149,7 +149,7 @@ class TwTxHistory(MMGenObject,TwCommon,metaclass=AsyncInit):
a1 = d.vouts_disp( 'inputs', width=cw.addr1, color=color ),
A = d.amt_disp(self.show_total_amt).fmt( prec=self.disp_prec, color=color ),
a2 = d.vouts_disp( 'outputs', width=cw.addr2, color=color ),
l = d.label.fmt( width=cw.lbl, color=color ) ).rstrip()
l = d.comment.fmt( width=cw.comment, color=color ) ).rstrip()
def gen_detail_display(self,color):

View file

@ -44,7 +44,7 @@ class TwUnspentOutputs(MMGenObject,TwCommon,metaclass=AsyncInit):
No spendable outputs found! Import addresses with balances into your
watch-only wallet using 'mmgen-addrimport' and then re-run this program.
"""
update_params_on_age_toggle = False
update_widths_on_age_toggle = False
detail_display_separator = '\n'
print_output_types = ('detail',)
@ -53,7 +53,7 @@ class TwUnspentOutputs(MMGenObject,TwCommon,metaclass=AsyncInit):
vout = ListItemAttr(int,typeconv=False)
amt = ImmutableAttr(None)
amt2 = ListItemAttr(None) # the ETH balance for token account
label = ListItemAttr(TwComment,reassign_ok=True)
comment = ListItemAttr(TwComment,reassign_ok=True)
twmmid = ImmutableAttr(TwMMGenID,include_proto=True)
addr = ImmutableAttr(CoinAddr,include_proto=True)
confs = ImmutableAttr(int,typeconv=False)
@ -94,11 +94,11 @@ class TwUnspentOutputs(MMGenObject,TwCommon,metaclass=AsyncInit):
l = get_tw_label(self.proto,o[lbl_id])
if l:
o.update({
'twmmid': l.mmid,
'label': l.comment or '',
'amt': self.proto.coin_amt(o['amount']),
'addr': CoinAddr(self.proto,o['address']),
'confs': o['confirmations']
'twmmid': l.mmid,
'comment': l.comment or '',
'amt': self.proto.coin_amt(o['amount']),
'addr': CoinAddr(self.proto,o['address']),
'confs': o['confirmations']
})
yield self.MMGenTwUnspentOutput(
self.proto,
@ -114,20 +114,20 @@ class TwUnspentOutputs(MMGenObject,TwCommon,metaclass=AsyncInit):
# allow for 7-digit confirmation nums
col1_w = max(3,len(str(len(data)))+1) # num + ')'
mmid_w = max(len(('',i.twmmid)[i.twmmid.type=='mmgen']) for i in data) or 12 # DEADBEEF:S:1
max_acct_w = max(i.label.screen_width for i in data) + mmid_w + 1
max_acct_w = max(i.comment.screen_width for i in data) + mmid_w + 1
max_btcaddr_w = max(len(i.addr) for i in data)
min_addr_w = self.cols - self.col_adj
addr_w = min(max_btcaddr_w + (0,1+max_acct_w)[self.show_mmid],min_addr_w)
acct_w = min(max_acct_w, max(24,addr_w-10))
btaddr_w = addr_w - acct_w - 1
label_w = acct_w - mmid_w - 1
comment_w = acct_w - mmid_w - 1
tx_w = min(self.txid_w,self.cols-addr_w-29-col1_w) # min=6 TODO
txdots = ('','..')[tx_w < self.txid_w]
self.column_params = namedtuple(
'column_params',
['col1_w','mmid_w','addr_w','btaddr_w','label_w','tx_w','txdots']
)(col1_w, mmid_w, addr_w, btaddr_w, label_w, tx_w, txdots)
self.column_widths = namedtuple(
'column_widths',
['col1_w','mmid_w','addr_w','btaddr_w','comment_w','tx_w','txdots']
)(col1_w, mmid_w, addr_w, btaddr_w, comment_w, tx_w, txdots)
def gen_squeezed_display(self,c,color):
fs = self.squeezed_fs_fs.format( cw=c.col1_w, tw=c.tx_w )
@ -157,7 +157,7 @@ class TwUnspentOutputs(MMGenObject,TwCommon,metaclass=AsyncInit):
i.addr.fmt(width=c.btaddr_w,color=color)
),
mmid_disp,
(' ' + i.label.fmt(width=c.label_w,color=color)) if c.label_w > 0 else ''
(' ' + i.comment.fmt(width=c.comment_w,color=color)) if c.comment_w > 0 else ''
)
else:
addr_out = (
@ -199,7 +199,7 @@ class TwUnspentOutputs(MMGenObject,TwCommon,metaclass=AsyncInit):
D = 'Date',
l = 'Label' )
max_lbl_len = max([len(i.label) for i in self.data if i.label] or [2])
max_comment_len = max([len(i.comment) for i in self.data if i.comment] or [2])
for n,i in enumerate(self.data):
yield fs.format(
@ -219,12 +219,12 @@ class TwUnspentOutputs(MMGenObject,TwCommon,metaclass=AsyncInit):
c = i.confs,
b = self.rpc.blockcount - (i.confs - 1),
D = self.age_disp(i,'date_time'),
l = i.label.hl(color=color) if i.label else
l = i.comment.hl(color=color) if i.comment else
TwComment.fmtc(
s = '',
color = color,
nullrepl = '-',
width = max_lbl_len )
width = max_comment_len )
).rstrip()
def display_total(self):
@ -270,37 +270,37 @@ class TwUnspentOutputs(MMGenObject,TwCommon,metaclass=AsyncInit):
await asyncio.sleep(3)
uo.oneshot_msg = red('Address could not be removed\n\n')
async def a_lbl_add(self,uo,idx):
async def a_comment_add(self,uo,idx):
async def do_lbl_add(lbl):
async def do_comment_add(comment):
e = uo.data[idx-1]
if await uo.wallet.add_label( e.twmmid, lbl, coinaddr=e.addr ):
if await uo.wallet.add_comment( e.twmmid, comment, coinaddr=e.addr ):
await uo.get_data()
uo.oneshot_msg = yellow('Label {a} {b}{c}\n\n'.format(
a = 'to' if cur_lbl and lbl else 'added to' if lbl else 'removed from',
a = 'to' if cur_comment and comment else 'added to' if comment else 'removed from',
b = desc,
c = ' edited' if cur_lbl and lbl else '' ))
c = ' edited' if cur_comment and comment else '' ))
else:
await asyncio.sleep(3)
uo.oneshot_msg = red('Label could not be {}\n\n'.format(
'edited' if cur_lbl and lbl else
'added' if lbl else
'edited' if cur_comment and comment else
'added' if comment else
'removed' ))
desc = f'{uo.item_desc} #{idx}'
cur_lbl = uo.data[idx-1].label
msg('Current label: {}'.format(cur_lbl.hl() if cur_lbl else '(none)'))
cur_comment = uo.data[idx-1].comment
msg('Current label: {}'.format(cur_comment.hl() if cur_comment else '(none)'))
from ..ui import line_input
res = line_input(
"Enter label text (or ENTER to return to main menu): ",
insert_txt = cur_lbl )
insert_txt = cur_comment )
if res == cur_lbl:
if res == cur_comment:
return None
elif res == '':
from ..ui import keypress_confirm
return (await do_lbl_add('')) if keypress_confirm(
return (await do_comment_add('')) if keypress_confirm(
f'Removing label for {desc}. Is this what you want?') else 'redo'
else:
return (await do_lbl_add(res)) if get_obj(TwComment,s=res) else 'redo'
return (await do_comment_add(res)) if get_obj(TwComment,s=res) else 'redo'

View file

@ -14,7 +14,7 @@ tx.base: base transaction class
from ..globalvars import *
from ..objmethods import MMGenObject
from ..obj import ImmutableAttr,ListItemAttr,MMGenListItem,MMGenTxLabel,TwComment,CoinTxID,HexStr
from ..obj import ImmutableAttr,ListItemAttr,MMGenListItem,MMGenTxComment,TwComment,CoinTxID,HexStr
from ..addr import MMGenID,CoinAddr
from ..util import msg,ymsg,fmt,remove_dups,make_timestamp,die
from ..opts import opt
@ -22,7 +22,7 @@ from ..opts import opt
class MMGenTxIO(MMGenListItem):
vout = ListItemAttr(int,typeconv=False)
amt = ImmutableAttr(None)
label = ListItemAttr(TwComment,reassign_ok=True)
comment = ListItemAttr(TwComment,reassign_ok=True)
mmid = ListItemAttr(MMGenID,include_proto=True)
addr = ImmutableAttr(CoinAddr,include_proto=True)
confs = ListItemAttr(int) # confs of type long exist in the wild, so convert
@ -65,7 +65,7 @@ class MMGenTxIOList(list,MMGenObject):
class Base(MMGenObject):
desc = 'transaction'
label = None
comment = None
txid = None
coin_txid = None
timestamp = None
@ -89,7 +89,7 @@ class Base(MMGenObject):
class Input(MMGenTxIO):
scriptPubKey = ListItemAttr(HexStr)
sequence = ListItemAttr(int,typeconv=False)
tw_copy_attrs = { 'scriptPubKey','vout','amt','label','mmid','addr','confs','txid' }
tw_copy_attrs = { 'scriptPubKey','vout','amt','comment','mmid','addr','confs','txid' }
class Output(MMGenTxIO):
is_chg = ListItemAttr(bool,typeconv=False)
@ -150,18 +150,18 @@ class Base(MMGenObject):
def add_comment(self,infile=None):
if infile:
from ..fileutil import get_data_from_file
self.label = MMGenTxLabel(get_data_from_file(infile,'transaction comment'))
self.comment = MMGenTxComment(get_data_from_file(infile,'transaction comment'))
else: # get comment from user, or edit existing comment
m = ('Add a comment to transaction?','Edit transaction comment?')[bool(self.label)]
m = ('Add a comment to transaction?','Edit transaction comment?')[bool(self.comment)]
from ..ui import keypress_confirm,line_input
if keypress_confirm(m,default_yes=False):
while True:
s = MMGenTxLabel(line_input('Comment: ',insert_txt=self.label))
s = MMGenTxComment(line_input('Comment: ',insert_txt=self.comment))
if not s:
ymsg('Warning: comment is empty')
lbl_save = self.label
self.label = s
return (True,False)[lbl_save == self.label]
save = self.comment
self.comment = s
return (True,False)[save == self.comment]
return False
def get_non_mmaddrs(self,desc):

View file

@ -21,7 +21,7 @@ tx.file: Transaction file operations for the MMGen suite
"""
from ..common import *
from ..obj import MMGenObject,HexStr,MMGenTxID,CoinTxID,MMGenTxLabel
from ..obj import MMGenObject,HexStr,MMGenTxID,CoinTxID,MMGenTxComment
class MMGenTxFile(MMGenObject):
@ -48,6 +48,9 @@ class MMGenTxFile(MMGenObject):
assert len(d), f'no {desc}!'
for e in d:
e['amt'] = tx.proto.coin_amt(e['amt'])
if 'label' in e:
e['comment'] = e['label']
del e['label']
io,io_list = {
'inputs': ( tx.Input, tx.InputList ),
'outputs': ( tx.Output, tx.OutputList ),
@ -74,7 +77,7 @@ class MMGenTxFile(MMGenObject):
if len(tx_data) == 5:
# rough check: allow for 4-byte utf8 characters + base58 (4 * 11 / 8 = 6 (rounded up))
assert len(tx_data[-1]) < MMGenTxLabel.max_len*6,'invalid comment length'
assert len(tx_data[-1]) < MMGenTxComment.max_len*6,'invalid comment length'
c = tx_data.pop(-1)
if c != '-':
desc = 'encoded comment (not base58)'
@ -82,7 +85,7 @@ class MMGenTxFile(MMGenObject):
comment = baseconv('b58').tobytes(c).decode()
assert comment != False,'invalid comment'
desc = 'comment'
tx.label = MMGenTxLabel(comment)
tx.comment = MMGenTxComment(comment)
desc = 'number of lines' # four required lines
( metadata, tx.serialized, inputs_data, outputs_data ) = tx_data
@ -174,12 +177,12 @@ class MMGenTxFile(MMGenObject):
ascii([amt_to_str(e._asdict()) for e in tx.outputs])
]
if tx.label:
if tx.comment:
from ..baseconv import baseconv
lines.append(baseconv('b58').frombytes(tx.label.encode(),tostr=True))
lines.append(baseconv('b58').frombytes(tx.comment.encode(),tostr=True))
if tx.coin_txid:
if not tx.label:
if not tx.comment:
lines.append('-') # keep old tx files backwards compatible
lines.append(tx.coin_txid)

View file

@ -67,8 +67,8 @@ class TxInfo:
enl = ('\n','')[bool(terse)]
yield enl
if tx.label:
yield f'Comment: {tx.label.hl()}\n{enl}'
if tx.comment:
yield f'Comment: {tx.comment.hl()}\n{enl}'
yield self.format_body(blockcount,nonmm_str,max_mmwid,enl,terse=terse,sort=sort)

View file

@ -84,7 +84,7 @@ class New(Base):
if e.addr and e.addr in d:
e.mmid,f = d[e.addr]
if f:
e.label = f
e.comment = f
def check_dup_addrs(self,io_str):
assert io_str in ('inputs','outputs')

View file

@ -28,7 +28,7 @@ tests = {
'AddrListEntry': atd({
'addr': (0b001, CoinAddr),
'idx': (0b001, AddrIdx),
'label': (0b101, TwComment),
'comment': (0b101, TwComment),
'sec': (0b001, PrivKey),
# 'viewkey': (0b001, ViewKey), # TODO
# 'wallet_passwd': (0b001, WalletPassword), # TODO
@ -39,7 +39,7 @@ tests = {
'PasswordListEntry': atd({
'passwd': (0b001, str),
'idx': (0b001, AddrIdx),
'label': (0b101, TwComment),
'comment':(0b101, TwComment),
'sec': (0b001, PrivKey),
},
(proto,),
@ -115,7 +115,7 @@ tests = {
'vout': (0b001, int),
'amt': (0b001, BTCAmt),
'amt2': (0b001, BTCAmt),
'label': (0b101, TwComment),
'comment': (0b101, TwComment),
'twmmid': (0b001, TwMMGenID),
'addr': (0b001, CoinAddr),
'confs': (0b001, int),
@ -135,7 +135,7 @@ tests = {
'Base.Input': atd({
'vout': (0b001, int),
'amt': (0b001, BTCAmt),
'label': (0b101, TwComment),
'comment': (0b101, TwComment),
'mmid': (0b001, MMGenID),
'addr': (0b001, CoinAddr),
'confs': (0b001, int),
@ -150,7 +150,7 @@ tests = {
'Base.Output': atd({
'vout': (0b001, int),
'amt': (0b001, BTCAmt),
'label': (0b101, TwComment),
'comment': (0b101, TwComment),
'mmid': (0b001, MMGenID),
'addr': (0b001, CoinAddr),
'confs': (0b001, int),

View file

@ -289,7 +289,7 @@ tests = {
text_jp[:40],
text_zh[:40] )
},
'MMGenTxLabel':{
'MMGenTxComment':{
'arg1': 's',
'bad': (utf8_text[:73],utf8_combining[:72],utf8_ctrl[:72],gr_uc_w_ctrl),
'good': (utf8_text[:72],)

View file

@ -48,16 +48,16 @@ ref_dir = os.path.join('test','ref')
dfl_words_file = os.path.join(ref_dir,'98831F3A.mmwords')
dfl_bip39_file = os.path.join(ref_dir,'98831F3A.bip39')
from mmgen.obj import MMGenTxLabel,TwComment
from mmgen.obj import MMGenTxComment,TwComment
tx_label_jp = text_jp
tx_label_zh = text_zh
tx_comment_jp = text_jp
tx_comment_zh = text_zh
lcg = ascii_cyr_gr if g.platform == 'win' else lat_cyr_gr # MSYS2 popen_spawn issue
tx_label_lat_cyr_gr = lcg[:MMGenTxLabel.max_len] # 72 chars
tx_comment_lat_cyr_gr = lcg[:MMGenTxComment.max_len] # 72 chars
tw_label_zh = text_zh[:TwComment.max_screen_width // 2]
tw_label_lat_cyr_gr = lcg[:TwComment.max_screen_width] # 80 chars
tw_comment_zh = text_zh[:TwComment.max_screen_width // 2]
tw_comment_lat_cyr_gr = lcg[:TwComment.max_screen_width] # 80 chars
ref_bw_hash_preset = '1'
ref_bw_file = 'wallet.mmbrain'
@ -120,13 +120,13 @@ def get_file_with_ext(tdir,ext,delete=True,no_dot=False,return_list=False,delete
else:
return flist[0]
def get_label(do_shuffle=False):
def get_comment(do_shuffle=False):
labels = [
"Automotive",
"Travel expenses",
"Healthcare",
tx_label_jp[:40],
tx_label_zh[:40],
tx_comment_jp[:40],
tx_comment_zh[:40],
"Alice's allowance",
"Bob's bequest",
"House purchase",

View file

@ -213,11 +213,11 @@ class TestSuiteEthdev(TestSuiteBase,TestSuiteShared):
('addrimport_burn_addr', 'importing burn address'),
('bal5', f'the {coin} balance'),
('add_label1', 'adding a UTF-8 label (zh)'),
('chk_label1', 'checking the label'),
('add_label2', 'adding a UTF-8 label (lat+cyr+gr)'),
('chk_label2', 'checking the label'),
('remove_label', 'removing the label'),
('add_comment1', 'adding a UTF-8 label (zh)'),
('chk_comment1', 'checking the label'),
('add_comment2', 'adding a UTF-8 label (lat+cyr+gr)'),
('chk_comment2', 'checking the label'),
('remove_comment', 'removing the label'),
),
'contract': (
'creating and deploying ERC20 tokens',
@ -346,11 +346,11 @@ class TestSuiteEthdev(TestSuiteBase,TestSuiteShared):
),
'label': (
'creating, editing and removing labels',
('edit_label1', f'adding label to addr #{del_addrs[0]} in {coin} tracking wallet (zh)'),
('edit_label2', f'editing label for addr #{del_addrs[0]} in {coin} tracking wallet (zh)'),
('edit_label3', f'adding label to addr #{del_addrs[1]} in {coin} tracking wallet (lat+cyr+gr)'),
('edit_label4', f'removing label from addr #{del_addrs[0]} in {coin} tracking wallet'),
('token_edit_label1', f'adding label to addr #{del_addrs[0]} in {coin} token tracking wallet'),
('edit_comment1', f'adding label to addr #{del_addrs[0]} in {coin} tracking wallet (zh)'),
('edit_comment2', f'editing label for addr #{del_addrs[0]} in {coin} tracking wallet (zh)'),
('edit_comment3', f'adding label to addr #{del_addrs[1]} in {coin} tracking wallet (lat+cyr+gr)'),
('edit_comment4', f'removing label from addr #{del_addrs[0]} in {coin} tracking wallet'),
('token_edit_comment1', f'adding label to addr #{del_addrs[0]} in {coin} token tracking wallet'),
),
'remove': (
'removing addresses from tracking wallet',
@ -599,7 +599,7 @@ class TestSuiteEthdev(TestSuiteBase,TestSuiteShared):
fee_res = fee_res,
fee_desc = fee_desc,
eth_fee_res = eth_fee_res,
add_comment = tx_label_jp,
add_comment = tx_comment_jp,
tweaks = tweaks )
if not no_read:
t.read()
@ -850,22 +850,22 @@ class TestSuiteEthdev(TestSuiteBase,TestSuiteShared):
assert Decimal(bal1) + Decimal(bal2) == Decimal(total)
return t
def add_label(self,lbl,addr='98831F3A:E:3'):
t = self.spawn('mmgen-tool', self.eth_args + ['add_label',addr,lbl])
def add_comment(self,comment,addr='98831F3A:E:3'):
t = self.spawn('mmgen-tool', self.eth_args + ['add_label',addr,comment])
t.expect('Added label.*in tracking wallet',regex=True)
return t
def chk_label(self,lbl_pat,addr='98831F3A:E:3'):
def chk_comment(self,comment_pat,addr='98831F3A:E:3'):
t = self.spawn('mmgen-tool', self.eth_args + ['listaddresses','all_labels=1'])
t.expect(fr'{addr}\b.*\S{{30}}\b.*{lbl_pat}\b',regex=True)
t.expect(fr'{addr}\b.*\S{{30}}\b.*{comment_pat}\b',regex=True)
return t
def add_label1(self): return self.add_label(lbl=tw_label_zh)
def chk_label1(self): return self.chk_label(lbl_pat=tw_label_zh)
def add_label2(self): return self.add_label(lbl=tw_label_lat_cyr_gr)
def chk_label2(self): return self.chk_label(lbl_pat=tw_label_lat_cyr_gr)
def add_comment1(self): return self.add_comment(comment=tw_comment_zh)
def chk_comment1(self): return self.chk_comment(comment_pat=tw_comment_zh)
def add_comment2(self): return self.add_comment(comment=tw_comment_lat_cyr_gr)
def chk_comment2(self): return self.chk_comment(comment_pat=tw_comment_lat_cyr_gr)
def remove_label(self,addr='98831F3A:E:3'):
def remove_comment(self,addr='98831F3A:E:3'):
t = self.spawn('mmgen-tool', self.eth_args + ['remove_label',addr])
t.expect('Removed label.*in tracking wallet',regex=True)
return t
@ -1070,7 +1070,7 @@ class TestSuiteEthdev(TestSuiteBase,TestSuiteShared):
menu = [],
inputs = inputs,
input_sels_prompt = 'to spend from',
add_comment = tx_label_lat_cyr_gr )
add_comment = tx_comment_lat_cyr_gr )
def token_txsign(self,ext='',token=''):
return self.txsign(ni=True,ext=ext,add_args=['--token='+token])
def token_txsend(self,ext='',token=''):
@ -1257,17 +1257,17 @@ class TestSuiteEthdev(TestSuiteBase,TestSuiteShared):
def token_twview3(self):
return self.twview(args=['--token=mm1'],tool_args=['wide=1','sort=age'])
def edit_label(self,out_num,args=[],action='l',label_text=None,changed=False,pexpect_spawn=None):
def edit_comment(self,out_num,args=[],action='l',comment_text=None,changed=False,pexpect_spawn=None):
t = self.spawn('mmgen-txcreate', self.eth_args + args + ['-B','-i'],pexpect_spawn=pexpect_spawn)
p1,p2 = ('efresh balance:\b','return to main menu): ')
p3,r3 = (p2,label_text+'\n') if label_text is not None else ('(y/N): ','y')
p4,r4 = (('(y/N): ',),('y',)) if label_text == Ctrl_U else ((),())
p3,r3 = (p2,comment_text+'\n') if comment_text is not None else ('(y/N): ','y')
p4,r4 = (('(y/N): ',),('y',)) if comment_text == Ctrl_U else ((),())
for p,r in zip((p1,p1,p2,p3)+p4,('M',action,out_num+'\n',r3)+r4):
t.expect(p,r)
m = (
'Label to account #{} edited' if changed else
'Account #{} removed' if action == 'D' else
'Label added to account #{}' if label_text and label_text != Ctrl_U else
'Label added to account #{}' if comment_text and comment_text != Ctrl_U else
'Label removed from account #{}' )
t.expect(m.format(out_num))
for p,r in zip((p1,p1),('M','q')):
@ -1275,29 +1275,29 @@ class TestSuiteEthdev(TestSuiteBase,TestSuiteShared):
t.expect('Total unspent:')
return t
def edit_label1(self):
return self.edit_label(out_num=del_addrs[0],label_text=tw_label_zh[:3])
def edit_label2(self):
def edit_comment1(self):
return self.edit_comment(out_num=del_addrs[0],comment_text=tw_comment_zh[:3])
def edit_comment2(self):
spawn = False if g.platform == 'win' else True
return self.edit_label(out_num=del_addrs[0],label_text=tw_label_zh[3:],changed=True,pexpect_spawn=spawn)
def edit_label3(self):
return self.edit_label(out_num=del_addrs[1],label_text=tw_label_lat_cyr_gr)
def edit_label4(self):
return self.edit_comment(out_num=del_addrs[0],comment_text=tw_comment_zh[3:],changed=True,pexpect_spawn=spawn)
def edit_comment3(self):
return self.edit_comment(out_num=del_addrs[1],comment_text=tw_comment_lat_cyr_gr)
def edit_comment4(self):
if self.skip_for_win():
return 'skip'
return self.edit_label(out_num=del_addrs[0],label_text=Ctrl_U,pexpect_spawn=True)
return self.edit_comment(out_num=del_addrs[0],comment_text=Ctrl_U,pexpect_spawn=True)
def token_edit_label1(self):
return self.edit_label(out_num='1',label_text='Token label #1',args=['--token=mm1'])
def token_edit_comment1(self):
return self.edit_comment(out_num='1',comment_text='Token label #1',args=['--token=mm1'])
def remove_addr1(self):
return self.edit_label(out_num=del_addrs[0],action='D')
return self.edit_comment(out_num=del_addrs[0],action='D')
def remove_addr2(self):
return self.edit_label(out_num=del_addrs[1],action='D')
return self.edit_comment(out_num=del_addrs[1],action='D')
def token_remove_addr1(self):
return self.edit_label(out_num=del_addrs[0],args=['--token=mm1'],action='D')
return self.edit_comment(out_num=del_addrs[0],args=['--token=mm1'],action='D')
def token_remove_addr2(self):
return self.edit_label(out_num=del_addrs[1],args=['--token=mm1'],action='D')
return self.edit_comment(out_num=del_addrs[1],args=['--token=mm1'],action='D')
def twexport_noamt(self):
return self.twexport(add_args=['include_amts=0'])

View file

@ -339,9 +339,11 @@ class TestSuiteMain(TestSuiteBase,TestSuiteShared):
if opt.verbose or opt.exact_output:
sys.stderr.write(f'Fake transaction wallet data written to file {self.unspent_data_file!r}\n')
def _create_fake_unspent_entry(self,coinaddr,al_id=None,idx=None,lbl=None,non_mmgen=False,segwit=False):
if 'S' not in self.proto.mmtypes: segwit = False
if lbl: lbl = ' ' + lbl
def _create_fake_unspent_entry(self,coinaddr,al_id=None,idx=None,comment=None,non_mmgen=False,segwit=False):
if 'S' not in self.proto.mmtypes:
segwit = False
if comment:
comment = ' ' + comment
k = coinaddr.addr_fmt
if not segwit and k == 'p2sh': k = 'p2pkh'
s_beg,s_end = { 'p2pkh': ('76a914','88ac'),
@ -351,7 +353,7 @@ class TestSuiteMain(TestSuiteBase,TestSuiteShared):
ret = {
self.lbl_id: (
f'{self.proto.base_coin.lower()}:{coinaddr}' if non_mmgen
else f'{al_id}:{idx}{lbl}' ),
else f'{al_id}:{idx}{comment}' ),
'vout': int(getrandnum(4) % 8),
'txid': getrandhex(32),
'amount': self.proto.coin_amt('{}.{}'.format(
@ -370,10 +372,10 @@ class TestSuiteMain(TestSuiteBase,TestSuiteShared):
for d in tx_data.values():
al = adata.addrlist(al_id=d['al_id'])
for n,(idx,coinaddr) in enumerate(al.addrpairs()):
lbl = get_label(do_shuffle=not g.test_suite_deterministic)
out.append(self._create_fake_unspent_entry(coinaddr,d['al_id'],idx,lbl,segwit=d['segwit']))
comment = get_comment(do_shuffle=not g.test_suite_deterministic)
out.append(self._create_fake_unspent_entry(coinaddr,d['al_id'],idx,comment,segwit=d['segwit']))
if n == 0: # create a duplicate address. This means addrs_per_wallet += 1
out.append(self._create_fake_unspent_entry(coinaddr,d['al_id'],idx,lbl,segwit=d['segwit']))
out.append(self._create_fake_unspent_entry(coinaddr,d['al_id'],idx,comment,segwit=d['segwit']))
if non_mmgen_input:
from mmgen.key import PrivKey
@ -526,7 +528,7 @@ class TestSuiteMain(TestSuiteBase,TestSuiteShared):
self.txcreate_ui_common(t,
menu = (['M'],['M','D','D','D','D','m','g'])[self.test_name=='txcreate'],
inputs = ' '.join(map(str,outputs_list)),
add_comment = ('',tx_label_lat_cyr_gr)[do_label],
add_comment = ('',tx_comment_lat_cyr_gr)[do_label],
view = view,
tweaks = tweaks )

View file

@ -240,7 +240,7 @@ class TestSuiteRegtest(TestSuiteBase,TestSuiteShared):
),
'main': (
'creating, signing, sending and bumping transactions',
('bob_add_label', "adding an 80-screen-width label (lat+cyr+gr)"),
('bob_add_comment', "adding an 80-screen-width label (lat+cyr+gr)"),
('bob_twview1', "viewing Bob's tracking wallet"),
('bob_split1', "splitting Bob's funds"),
('generate', 'mining a block'),
@ -316,22 +316,22 @@ class TestSuiteRegtest(TestSuiteBase,TestSuiteShared):
),
'label': (
'adding, removing and editing labels',
('alice_bal2', "Alice's balance"),
('alice_add_label1', 'adding a label'),
('alice_chk_label1', 'the label'),
('alice_add_label2', 'adding a label'),
('alice_chk_label2', 'the label'),
('alice_edit_label1', 'editing a label (zh)'),
('alice_edit_label2', 'editing a label (lat+cyr+gr)'),
('alice_chk_label3', 'the label'),
('alice_remove_label1', 'removing a label'),
('alice_chk_label4', 'the label'),
('alice_add_label_coinaddr', 'adding a label using the coin address'),
('alice_chk_label_coinaddr', 'the label'),
('alice_add_label_badaddr1', 'adding a label with invalid address'),
('alice_add_label_badaddr2', 'adding a label with invalid address for this chain'),
('alice_add_label_badaddr3', 'adding a label with wrong MMGen address'),
('alice_add_label_badaddr4', 'adding a label with wrong coin address'),
('alice_bal2', "Alice's balance"),
('alice_add_comment1', 'adding a label'),
('alice_chk_comment1', 'the label'),
('alice_add_comment2', 'adding a label'),
('alice_chk_comment2', 'the label'),
('alice_edit_comment1', 'editing a label (zh)'),
('alice_edit_comment2', 'editing a label (lat+cyr+gr)'),
('alice_chk_comment3', 'the label'),
('alice_remove_comment1', 'removing a label'),
('alice_chk_comment4', 'the label'),
('alice_add_comment_coinaddr', 'adding a label using the coin address'),
('alice_chk_comment_coinaddr', 'the label'),
('alice_add_comment_badaddr1', 'adding a label with invalid address'),
('alice_add_comment_badaddr2', 'adding a label with invalid address for this chain'),
('alice_add_comment_badaddr3', 'adding a label with wrong MMGen address'),
('alice_add_comment_badaddr4', 'adding a label with wrong coin address'),
),
'view': (
'viewing addresses and unspent outputs',
@ -376,13 +376,13 @@ class TestSuiteRegtest(TestSuiteBase,TestSuiteShared):
def __del__(self):
os.environ['MMGEN_BOGUS_SEND'] = '1'
def _add_comments_to_addr_file(self,addrfile,outfile,use_labels=False):
def _add_comments_to_addr_file(self,addrfile,outfile,use_comments=False):
silence()
gmsg(f'Adding comments to address file {addrfile!r}')
a = AddrList(self.proto,addrfile)
for n,idx in enumerate(a.idxs(),1):
if use_labels:
a.set_comment(idx,get_label())
if use_comments:
a.set_comment(idx,get_comment())
else:
if n % 2: a.set_comment(idx,f'Test address {n}')
af = a.get_file()
@ -464,7 +464,7 @@ class TestSuiteRegtest(TestSuiteBase,TestSuiteShared):
sid,self.altcoin_pfx,id_strs[desc],addr_range,
x='' if g.debug_utf8 else ''))
if mmtype == self.proto.mmtypes[0] and user == 'bob':
self._add_comments_to_addr_file(addrfile,addrfile,use_labels=True)
self._add_comments_to_addr_file(addrfile,addrfile,use_comments=True)
t = self.spawn(
'mmgen-addrimport',
args = (
@ -787,7 +787,7 @@ class TestSuiteRegtest(TestSuiteBase,TestSuiteShared):
inputs = outputs_list,
file_desc = 'Signed transaction',
interactive_fee = (tx_fee,'')[bool(fee)],
add_comment = tx_label_jp,
add_comment = tx_comment_jp,
view = 't',save=True)
if not skip_passphrase:
@ -1109,45 +1109,45 @@ class TestSuiteRegtest(TestSuiteBase,TestSuiteShared):
outputs2 = [sid+':C:2,6.333', sid+':L:3,6.667',sid+l1+':4,0.123',sid+l2+':5']
return self.user_txdo('bob',rtFee[5],outputs1+outputs2,'1-2')
def user_add_label(self,user,addr,label):
t = self.spawn('mmgen-tool',['--'+user,'add_label',addr,label])
def user_add_comment(self,user,addr,comment):
t = self.spawn('mmgen-tool',['--'+user,'add_label',addr,comment])
t.expect('Added label.*in tracking wallet',regex=True)
return t
def user_remove_label(self,user,addr):
def user_remove_comment(self,user,addr):
t = self.spawn('mmgen-tool',['--'+user,'remove_label',addr])
t.expect('Removed label.*in tracking wallet',regex=True)
return t
def bob_add_label(self):
def bob_add_comment(self):
sid = self._user_sid('bob')
return self.user_add_label('bob',sid+':C:1',tw_label_lat_cyr_gr)
return self.user_add_comment('bob',sid+':C:1',tw_comment_lat_cyr_gr)
def alice_add_label1(self):
def alice_add_comment1(self):
sid = self._user_sid('alice')
return self.user_add_label('alice',sid+':C:1','Original Label - 月へ')
return self.user_add_comment('alice',sid+':C:1','Original Label - 月へ')
def alice_add_label2(self):
def alice_add_comment2(self):
sid = self._user_sid('alice')
return self.user_add_label('alice',sid+':C:1','Replacement Label')
return self.user_add_comment('alice',sid+':C:1','Replacement Label')
def _user_chk_label(self,user,addr,label):
def _user_chk_comment(self,user,addr,comment):
t = self.spawn('mmgen-tool',['--'+user,'listaddresses','all_labels=1'])
ret = strip_ansi_escapes(t.expect_getend(addr)).strip().split(None,1)[1]
cmp_or_die(ret[:len(label)],label)
cmp_or_die(ret[:len(comment)],comment)
return t
def alice_add_label_coinaddr(self):
def alice_add_comment_coinaddr(self):
mmid = self._user_sid('alice') + (':S:1',':L:1')[self.proto.coin=='BCH']
t = self.spawn('mmgen-tool',['--alice','listaddress',mmid],no_msg=True)
addr = [i for i in strip_ansi_escapes(t.read()).splitlines() if i.startswith(mmid)][0].split()[1]
return self.user_add_label('alice',addr,'Label added using coin address of MMGen address')
return self.user_add_comment('alice',addr,'Label added using coin address of MMGen address')
def alice_chk_label_coinaddr(self):
def alice_chk_comment_coinaddr(self):
mmid = self._user_sid('alice') + (':S:1',':L:1')[self.proto.coin=='BCH']
return self._user_chk_label('alice',mmid,'Label added using coin address of MMGen address')
return self._user_chk_comment('alice',mmid,'Label added using coin address of MMGen address')
def alice_add_label_badaddr(self,addr,reply):
def alice_add_comment_badaddr(self,addr,reply):
if os.getenv('PYTHONOPTIMIZE'):
omsg(yellow(f'PYTHONOPTIMIZE set, skipping test {self.test_name!r}'))
return 'skip'
@ -1155,53 +1155,53 @@ class TestSuiteRegtest(TestSuiteBase,TestSuiteShared):
t.expect(reply,regex=True)
return t
def alice_add_label_badaddr1(self):
return self.alice_add_label_badaddr( rt_pw,'Invalid coin address for this chain: ')
def alice_add_comment_badaddr1(self):
return self.alice_add_comment_badaddr( rt_pw,'Invalid coin address for this chain: ')
def alice_add_label_badaddr2(self):
def alice_add_comment_badaddr2(self):
addr = init_proto(self.proto.coin,network='mainnet').pubhash2addr(bytes(20),False) # mainnet zero address
return self.alice_add_label_badaddr( addr, f'Invalid coin address for this chain: {addr}' )
return self.alice_add_comment_badaddr( addr, f'Invalid coin address for this chain: {addr}' )
def alice_add_label_badaddr3(self):
def alice_add_comment_badaddr3(self):
addr = self._user_sid('alice') + ':C:123'
return self.alice_add_label_badaddr( addr, f'MMGen address {addr!r} not found in tracking wallet' )
return self.alice_add_comment_badaddr( addr, f'MMGen address {addr!r} not found in tracking wallet' )
def alice_add_label_badaddr4(self):
def alice_add_comment_badaddr4(self):
addr = self.proto.pubhash2addr(bytes(20),False) # regtest (testnet) zero address
return self.alice_add_label_badaddr( addr, f'Address {addr!r} not found in tracking wallet' )
return self.alice_add_comment_badaddr( addr, f'Address {addr!r} not found in tracking wallet' )
def alice_remove_label1(self):
def alice_remove_comment1(self):
sid = self._user_sid('alice')
mmid = sid + (':S:3',':L:3')[self.proto.coin=='BCH']
return self.user_remove_label('alice',mmid)
return self.user_remove_comment('alice',mmid)
def alice_chk_label1(self):
def alice_chk_comment1(self):
sid = self._user_sid('alice')
return self._user_chk_label('alice',sid+':C:1','Original Label - 月へ')
return self._user_chk_comment('alice',sid+':C:1','Original Label - 月へ')
def alice_chk_label2(self):
def alice_chk_comment2(self):
sid = self._user_sid('alice')
return self._user_chk_label('alice',sid+':C:1','Replacement Label')
return self._user_chk_comment('alice',sid+':C:1','Replacement Label')
def alice_edit_label1(self): return self.user_edit_label('alice','4',tw_label_lat_cyr_gr)
def alice_edit_label2(self): return self.user_edit_label('alice','3',tw_label_zh)
def alice_edit_comment1(self): return self.user_edit_comment('alice','4',tw_comment_lat_cyr_gr)
def alice_edit_comment2(self): return self.user_edit_comment('alice','3',tw_comment_zh)
def alice_chk_label3(self):
def alice_chk_comment3(self):
sid = self._user_sid('alice')
mmid = sid + (':S:3',':L:3')[self.proto.coin=='BCH']
return self._user_chk_label('alice',mmid,tw_label_lat_cyr_gr)
return self._user_chk_comment('alice',mmid,tw_comment_lat_cyr_gr)
def alice_chk_label4(self):
def alice_chk_comment4(self):
sid = self._user_sid('alice')
mmid = sid + (':S:3',':L:3')[self.proto.coin=='BCH']
return self._user_chk_label('alice',mmid,'-')
return self._user_chk_comment('alice',mmid,'-')
def user_edit_label(self,user,output,label):
def user_edit_comment(self,user,output,comment):
t = self.spawn('mmgen-txcreate',['-B','--'+user,'-i'])
t.expect(r'add \[l\]abel:.','M',regex=True)
t.expect(r'add \[l\]abel:.','l',regex=True)
t.expect(r"Enter unspent.*return to main menu\):.",output+'\n',regex=True)
t.expect(r"Enter label text.*return to main menu\):.",label+'\n',regex=True)
t.expect(r"Enter label text.*return to main menu\):.",comment+'\n',regex=True)
t.expect(r'\[q\]uit view, .*?:.','q',regex=True)
return t

View file

@ -25,18 +25,25 @@ async def do_txfile_test(desc,fns):
if g.debug_utf8:
fn_gen = fn_gen.replace('','')
assert fn_gen == os.path.basename(fn), f'{fn_gen} != {fn}'
text = f.format()
continue # TODO: check disabled after label -> comment patch
with open(fpath) as fp:
# remove Python2 'u' string prefixes from ref files:
# New in version 3.3: Support for the unicode legacy literal (u'value') was
# reintroduced to simplify the maintenance of dual Python 2.x and 3.x codebases.
# See PEP 414 for more information.
chk = re.subn( r"\bu(['\"])", r'\1', fp.read() )[0]
chk = fp.read()
# remove Python2 'u' string prefixes from ref files:
# New in version 3.3: Support for the unicode legacy literal (u'value') was
# reintroduced to simplify the maintenance of dual Python 2.x and 3.x codebases.
# See PEP 414 for more information.
chk = chk.replace("'label':","'comment':") # TODO
chk = re.subn( r"\bu(['\"])", r'\1', chk )[0]
diff = get_ndiff(chk,text)
print(get_diff(chk,text,from_json=False))
nLines = len([i for i in diff if i.startswith('-')])
assert nLines in (0,1), f'{nLines} lines differ: only checksum line may differ'