tw.py: new get_tw_label() function; raise exception on bad tw label

This commit is contained in:
The MMGen Project 2019-07-03 17:40:43 +00:00
commit 0ec3eb1a07
Signed by: mmgen
GPG key ID: 3F8B1861E32B7DA2
7 changed files with 68 additions and 21 deletions

View file

@ -22,9 +22,11 @@ obj.py: MMGen native classes
import sys,os,unicodedata
from decimal import *
from mmgen.color import *
from string import hexdigits,ascii_letters,digits
from mmgen.color import *
from mmgen.exception import *
def is_mmgen_seed_id(s): return SeedID(sid=s,on_fail='silent')
def is_mmgen_idx(s): return AddrIdx(s,on_fail='silent')
def is_mmgen_id(s): return MMGenID(s,on_fail='silent')
@ -169,14 +171,19 @@ class InitErrors(object):
if m2: errmsg = '{!r}\n{}'.format(m2,errmsg)
from mmgen.globalvars import g
if g.traceback: cls.on_fail == 'raise'
from mmgen.util import die,msg
if cls.on_fail == 'silent': return None # TODO: return False instead?
elif cls.on_fail == 'raise': raise ValueError(errmsg)
elif cls.on_fail == 'die': die(1,errmsg)
if cls.on_fail == 'silent':
return None # TODO: return False instead?
elif cls.on_fail == 'return':
if errmsg: msg(errmsg)
return None # TODO: here too?
return None # TODO: return False instead?
elif g.traceback or cls.on_fail == 'raise':
if hasattr(cls,'exc'):
raise cls.exc(errmsg)
else:
raise
elif cls.on_fail == 'die':
die(1,errmsg)
class Hilite(object):
@ -860,6 +867,7 @@ class MMGenWalletLabel(MMGenLabel):
class TwComment(MMGenLabel):
max_screen_width = 80
desc = 'tracking wallet comment'
exc = BadTwComment
class MMGenTXLabel(MMGenLabel):
max_len = 72

View file

@ -22,9 +22,11 @@ rpc.py: Cryptocoin RPC library for the MMGen suite
import http.client,base64,json
from mmgen.common import *
from decimal import Decimal
from mmgen.common import *
from mmgen.obj import MMGenObject
def dmsg_rpc(s):
if g.debug_rpc: msg(s)
@ -261,6 +263,8 @@ class EthereumRPCConnection(CoinDaemonRPCConnection):
def rpc_error(ret):
return type(ret) is tuple and ret and ret[0] == 'rpcfail'
def rpc_errmsg(ret): return ret[1][2]
def init_daemon_parity():
def resolve_token_arg(token_arg):
@ -362,6 +366,3 @@ def init_daemon_bitcoind():
def init_daemon(name):
return globals()['init_daemon_'+name]()
def rpc_errmsg(ret):
return ret[1][2]

View file

@ -27,6 +27,11 @@ from mmgen.tx import is_mmgen_id
CUR_HOME,ERASE_ALL = '\033[H','\033[0J'
def CUR_RIGHT(n): return '\033[{}C'.format(n)
def get_tw_label(s):
try: return TwLabel(s,on_fail='raise')
except BadTwComment: raise
except: return None
class TwUnspentOutputs(MMGenObject):
def __new__(cls,*args,**kwargs):
@ -131,8 +136,8 @@ watch-only wallet using '{}-addrimport' and then re-run this program.
tr_rpc = []
lbl_id = ('account','label')['label_api' in g.rpch.caps]
for o in us_rpc:
if not lbl_id in o: continue # coinbase outputs have no account field
l = TwLabel(o[lbl_id],on_fail='silent')
if not lbl_id in o: continue # coinbase outputs have no account field
l = get_tw_label(o[lbl_id])
if l:
o.update({
'twmmid': l.mmid,
@ -427,7 +432,7 @@ class TwAddrList(MMGenDict):
for d in g.rpch.listunspent(0):
if not lbl_id in d: continue # skip coinbase outputs with missing account
if d['confirmations'] < minconf: continue
label = TwLabel(d[lbl_id],on_fail='silent')
label = get_tw_label(d[lbl_id])
if label:
if usr_addr_list and (label.mmid not in usr_addr_list): continue
if label.mmid in self:
@ -452,7 +457,7 @@ class TwAddrList(MMGenDict):
else:
acct_list = list(g.rpch.listaccounts(0,True).keys()) # raw list, no 'L'
acct_addrs = g.rpch.getaddressesbyaccount([[a] for a in acct_list],batch=True) # use raw list here
acct_labels = MMGenList([TwLabel(a,on_fail='silent') for a in acct_list])
acct_labels = MMGenList([get_tw_label(a) for a in acct_list])
check_dup_mmid(acct_labels)
assert len(acct_list) == len(acct_addrs),(
'listaccounts() and getaddressesbyaccount() not equal in length')
@ -645,17 +650,16 @@ class TwGetBalance(MMGenObject):
# 0: unconfirmed, 1: below minconf, 2: confirmed, 3: spendable (privkey in wallet)
lbl_id = ('account','label')['label_api' in g.rpch.caps]
for d in g.rpch.listunspent(0):
try:
lbl = TwLabel(d[lbl_id],on_fail='silent')
except:
lbl,key = None,'Non-wallet'
else:
lbl = get_tw_label(d[lbl_id])
if lbl:
if lbl.mmid.type == 'mmgen':
key = lbl.mmid.obj.sid
if key not in self.data:
self.data[key] = [g.proto.coin_amt('0')] * 4
else:
key = 'Non-MMGen'
else:
lbl,key = None,'Non-wallet'
if not d['confirmations']:
self.data['TOTAL'][0] += d['amount']

View file

@ -25,6 +25,8 @@ pn = os.path.dirname(sys.argv[0])
os.chdir(os.path.join(pn,os.pardir))
sys.path.__setitem__(0,os.path.abspath(os.curdir))
os.environ['MMGEN_TEST_SUITE'] = '1'
# Import these _after_ local path's been added to sys.path
from mmgen.common import *
from mmgen.obj import *
@ -53,6 +55,7 @@ def run_test(test,arg,input_data):
arg_copy = arg
kwargs = {'on_fail':'silent'} if opt.silent else {}
ret_chk = arg
exc_type = None
if input_data == 'good' and type(arg) == tuple: arg,ret_chk = arg
if type(arg) == dict: # pass one arg + kwargs to constructor
arg_copy = arg.copy()
@ -67,6 +70,10 @@ def run_test(test,arg,input_data):
ret_chk = arg['ret']
del arg['ret']
del arg_copy['ret']
if 'ExcType' in arg:
exc_type = arg['ExcType']
del arg['ExcType']
del arg_copy['ExcType']
kwargs.update(arg)
elif type(arg) == tuple:
args = arg
@ -91,7 +98,12 @@ def run_test(test,arg,input_data):
if not opt.super_silent:
msg('==> {}'.format(ret))
if opt.verbose and issubclass(cls,MMGenObject):
ret.pmsg() if hasattr(ret,'pmsg') else pmsg(ret)
ret.ppmsg() if hasattr(ret,'ppmsg') else ppmsg(ret)
except Exception as e:
if not type(e).__name__ == exc_type:
raise
msg_r(' {}'.format(yellow(exc_type+':')))
msg(e.args[0])
except SystemExit as e:
if input_data == 'good':
raise ValueError('Error on good input data')

View file

@ -100,7 +100,10 @@ tests = OrderedDict([
}),
('TwLabel', {
'bad': ('x x','x я','я:я',1,'f00f00f','a:b','x:L:3','F00BAA12:0 x',
'F00BAA12:Z:99',tw_pfx+' x',tw_pfx+'я x'),
'F00BAA12:Z:99',tw_pfx+' x',tw_pfx+'я x',
'F00BAA12:S:1 '+ utf8_ctrl[:40],
{'s':'F00BAA12:S:1 '+ utf8_ctrl[:40],'on_fail':'raise','ExcType':'BadTwComment'},
),
'good': (
('F00BAA12:99 a comment','F00BAA12:L:99 a comment'),
'F00BAA12:L:99 comment (UTF-8) α',

View file

@ -0,0 +1,8 @@
[{'address': '153AwzcymCgiy7dBxHkpeSn8yzbfnRvVPx',
'amount': BTCAmt('34.21677044'),
'confirmations': 7528082,
'label': '96325D83:L:99 This label has a control character (tab) here: [ ]',
'scriptPubKey': '76a9142c49a3ad8d89af713197e55190a7c3bc47e0208e88ac',
'spendable': False,
'txid': '2588cbbea1f3413ee4556c0f12f825f8670771862864a44f5ad39a71e1afdb13',
'vout': 3}]

View file

@ -166,6 +166,7 @@ class TestSuiteTool(TestSuiteMain,TestSuiteBase):
('tool_rand2file', (9,"'mmgen-tool rand2file'", [])),
('tool_encrypt', (9,"'mmgen-tool encrypt' (random data)", [])),
('tool_decrypt', (9,"'mmgen-tool decrypt' (random data)", [[[enc_infn+'.mmenc'],9]])),
('tool_twview_bad_comment',(9,"'mmgen-tool twview' (with bad comment)", [])),
# ('tool_encrypt_ref', (9,"'mmgen-tool encrypt' (reference text)", [])),
)
@ -215,6 +216,16 @@ class TestSuiteTool(TestSuiteMain,TestSuiteBase):
cmp_or_die(hincog_offset,int(o))
return t
def tool_twview_bad_comment(self): # test correct operation of get_tw_label()
bw_save = os.getenv('MMGEN_BOGUS_WALLET_DATA')
os.environ['MMGEN_BOGUS_WALLET_DATA'] = joinpath(ref_dir,'bad-comment-unspent.json')
t = self.spawn('mmgen-tool',['twview'])
if bw_save:
os.environ['MMGEN_BOGUS_WALLET_DATA'] = bw_save
t.read()
t.req_exit_val = 2
return t
class TestSuiteRefTX(TestSuiteMain,TestSuiteBase):
'create a reference transaction file (administrative command)'
segwit_opts_ok = False