diff --git a/mmgen/addrdata.py b/mmgen/addrdata.py
index 6abca301..000176b8 100755
--- a/mmgen/addrdata.py
+++ b/mmgen/addrdata.py
@@ -20,24 +20,22 @@
addrdata.py: MMGen AddrData and related classes
"""
-from .util import vmsg,base_proto_subclass
+from .util import vmsg,base_proto_subclass,fmt,die
from .base_obj import AsyncInit
from .obj import MMGenObject,MMGenDict,get_obj
from .addr import MMGenID,AddrListID
from .addrlist import AddrListEntry,AddrListData,AddrList
class AddrData(MMGenObject):
- msgs = {
- 'too_many_acct_addresses': """
-ERROR: More than one address found for account: '{}'.
-Your 'wallet.dat' file appears to have been altered by a non-{} program.
-Please restore your tracking wallet from a backup or create a new one and
-re-import your addresses.
-""".strip()
- }
- def __new__(cls,proto,*args,**kwargs):
- return MMGenObject.__new__(base_proto_subclass(cls,proto,'tw'))
+ msgs = {
+ 'multiple_acct_addrs': """
+ ERROR: More than one address found for account: {acct!r}.
+ Your 'wallet.dat' file appears to have been altered by a non-{proj} program.
+ Please restore your tracking wallet from a backup or create a new one and
+ re-import your addresses.
+ """
+ }
def __init__(self,proto,*args,**kwargs):
self.al_ids = {}
@@ -97,7 +95,8 @@ class TwAddrData(AddrData,metaclass=AsyncInit):
if l and l.mmid.type == 'mmgen':
obj = l.mmid.obj
if len(addr_array) != 1:
- die(2,self.msgs['too_many_acct_addresses'].format(acct,g.prog_name))
+ message = self.msgs['multiple_acct_addrs'].strip().format( acct=acct, proj=g.proj_name )
+ die(3, fmt( message, indent=' ' ))
al_id = AddrListID(SeedID(sid=obj.sid),self.proto.addr_type(obj.mmtype))
if al_id not in out:
out[al_id] = []
@@ -105,6 +104,7 @@ class TwAddrData(AddrData,metaclass=AsyncInit):
i += 1
vmsg(f'{i} {g.prog_name} addresses found, {len(twd)} accounts total')
+
for al_id in out:
self.add(AddrList(self.proto,al_id=al_id,adata=AddrListData(sorted(out[al_id],key=lambda a: a.idx))))
diff --git a/mmgen/base_proto/ethereum/tw.py b/mmgen/base_proto/ethereum/tw.py
index 9308a4b9..1e9d1289 100755
--- a/mmgen/base_proto/ethereum/tw.py
+++ b/mmgen/base_proto/ethereum/tw.py
@@ -17,10 +17,10 @@
# along with this program. If not, see .
"""
-altcoins.base_proto.ethereum.tw: Ethereum tracking wallet dependency classes
+base_proto.ethereum.tw: Ethereum tracking wallet dependency classes
"""
-from ...addrdata import AddrData,TwAddrData
+from ...addrdata import TwAddrData
class EthereumTwAddrData(TwAddrData):
@@ -32,7 +32,5 @@ class EthereumTwAddrData(TwAddrData):
# emulate the output of RPC 'listaccounts' and 'getaddressesbyaccount'
return [(mmid+' '+d['comment'],[d['addr']]) for mmid,d in list(tw.items())]
-class EthereumTokenTwAddrData(EthereumTwAddrData): pass
-
-class EthereumAddrData(AddrData): pass
-class EthereumTokenAddrData(EthereumAddrData): pass
+class EthereumTokenTwAddrData(EthereumTwAddrData):
+ pass
diff --git a/mmgen/base_proto/ethereum/twaddrs.py b/mmgen/base_proto/ethereum/twaddrs.py
index f5b29221..d8012629 100755
--- a/mmgen/base_proto/ethereum/twaddrs.py
+++ b/mmgen/base_proto/ethereum/twaddrs.py
@@ -17,7 +17,7 @@
# along with this program. If not, see .
"""
-altcoins.base_proto.ethereum.twaddrs: Ethereum tracking wallet listaddresses class
+base_proto.ethereum.twaddrs: Ethereum tracking wallet address list class
"""
from ...twaddrs import TwAddrList
diff --git a/mmgen/base_proto/ethereum/twbal.py b/mmgen/base_proto/ethereum/twbal.py
index 02f949d1..59d6f57e 100755
--- a/mmgen/base_proto/ethereum/twbal.py
+++ b/mmgen/base_proto/ethereum/twbal.py
@@ -17,7 +17,7 @@
# along with this program. If not, see .
"""
-altcoins.base_proto.ethereum.twbal: Ethereum tracking wallet getbalance class
+base_proto.ethereum.twbal: Ethereum tracking wallet getbalance class
"""
from ...twctl import TrackingWallet
@@ -29,7 +29,7 @@ class EthereumTwGetBalance(TwGetBalance):
async def __init__(self,proto,*args,**kwargs):
self.wallet = await TrackingWallet(proto,mode='w')
- await TwGetBalance.__init__(self,proto,*args,**kwargs)
+ await super().__init__(proto,*args,**kwargs)
async def create_data(self):
data = self.wallet.mmid_ordered_dict
diff --git a/mmgen/base_proto/ethereum/twctl.py b/mmgen/base_proto/ethereum/twctl.py
index 1df5f2f0..83940e56 100755
--- a/mmgen/base_proto/ethereum/twctl.py
+++ b/mmgen/base_proto/ethereum/twctl.py
@@ -17,7 +17,7 @@
# along with this program. If not, see .
"""
-altcoins.base_proto.ethereum.twctl: Ethereum tracking wallet control class
+base_proto.ethereum.twctl: Ethereum tracking wallet control class
"""
from ...util import msg,ymsg,write_mode,die
diff --git a/mmgen/base_proto/ethereum/twuo.py b/mmgen/base_proto/ethereum/twuo.py
index 470e0af1..41cdb7d1 100755
--- a/mmgen/base_proto/ethereum/twuo.py
+++ b/mmgen/base_proto/ethereum/twuo.py
@@ -17,7 +17,7 @@
# along with this program. If not, see .
"""
-altcoins.base_proto.ethereum.twuo: Ethereum tracking wallet unspent outputs class
+base_proto.ethereum.twuo: Ethereum tracking wallet unspent outputs class
"""
from ...tw import TwLabel
@@ -26,6 +26,10 @@ from ...twuo import TwUnspentOutputs
# No unspent outputs with Ethereum, but naming must be consistent
class EthereumTwUnspentOutputs(TwUnspentOutputs):
+ class MMGenTwUnspentOutput(TwUnspentOutputs.MMGenTwUnspentOutput):
+ valid_attrs = {'txid','vout','amt','amt2','label','twmmid','addr','confs','skip'}
+ invalid_attrs = {'proto'}
+
disp_type = 'eth'
can_group = False
col_adj = 29
@@ -50,7 +54,7 @@ Actions: [q]uit view, [p]rint to file, pager [v]iew, [w]ide view,
if g.cached_balances:
from ...color import yellow
self.hdr_fmt += '\n' + yellow('WARNING: Using cached balances. These may be out of date!')
- await TwUnspentOutputs.__init__(self,proto,*args,**kwargs)
+ await super().__init__(proto,*args,**kwargs)
def do_sort(self,key=None,reverse=False):
if key == 'txid': return
@@ -67,12 +71,8 @@ Actions: [q]uit view, [p]rint to file, pager [v]iew, [w]ide view,
'confirmations': 0, # TODO
} for d in wl]
- class MMGenTwUnspentOutput(TwUnspentOutputs.MMGenTwUnspentOutput):
- valid_attrs = {'txid','vout','amt','amt2','label','twmmid','addr','confs','skip'}
- invalid_attrs = {'proto'}
-
def age_disp(self,o,age_fmt): # TODO
- return None
+ pass
class EthereumTokenTwUnspentOutputs(EthereumTwUnspentOutputs):
diff --git a/mmgen/exception.py b/mmgen/exception.py
index 9d010ba3..f04b5524 100755
--- a/mmgen/exception.py
+++ b/mmgen/exception.py
@@ -28,10 +28,12 @@ class MMGenError(Exception):
super().__init__(strerror)
def __repr__(self):
- return f'{type(self).__name__}({self.mmcode}): {self}'
+ return f'{type(self).__name__}({self.mmcode}):\n{self}'
class MMGenSystemExit(MMGenError):
- pass
+
+ def __repr__(self):
+ return f'{type(self).__name__}({self.mmcode}): {self}'
# 1: no hl, message only
class UserNonConfirmation(Exception): mmcode = 1
diff --git a/mmgen/main.py b/mmgen/main.py
index 331cf787..9a887870 100755
--- a/mmgen/main.py
+++ b/mmgen/main.py
@@ -60,9 +60,9 @@ def launch(mod):
0: _o(nocolor, 1, '{message}'),
1: _o(nocolor, 1, '{message}'),
2: _o(yellow, 2, '{message}'),
- 3: _o(yellow, 3, '\nMMGen Error ({name}): {message}'),
- 4: _o(red, 4, '\nMMGen Fatal Error ({name}): {message}'),
- 'x': _o(yellow, 5, '\nMMGen Unhandled Exception ({name}): {message}'),
+ 3: _o(yellow, 3, '\nMMGen Error ({name}):\n{message}'),
+ 4: _o(red, 4, '\nMMGen Fatal Error ({name}):\n{message}'),
+ 'x': _o(yellow, 5, '\nMMGen Unhandled Exception ({name}):\n{message}'),
}[getattr(e,'mmcode','x')]
(sys.stdout if getattr(e,'stdout',None) else sys.stderr).write(
diff --git a/scripts/create-token.py b/scripts/create-token.py
index 260494d6..1ebc77cc 100755
--- a/scripts/create-token.py
+++ b/scripts/create-token.py
@@ -272,7 +272,8 @@ if __name__ == '__main__':
code = create_src( proto, solidity_code_template, token_data, cmd_args[0] )
if opt.preprocess:
- Die(0,code)
+ Msg(code)
+ sys.exit(0)
out = compile_code(code)
diff --git a/scripts/exec_wrapper.py b/scripts/exec_wrapper.py
index acb97e33..ef325541 100755
--- a/scripts/exec_wrapper.py
+++ b/scripts/exec_wrapper.py
@@ -44,6 +44,10 @@ def exec_wrapper_write_traceback(e):
if exc.startswith('SystemExit:'):
lines.pop()
+ if os.getenv('MMGEN_TEST_SUITE_DETERMINISTIC'):
+ pat = re.compile(", line [0-9]+,")
+ lines = [pat.sub(", line (scrubbed),",line) for line in lines]
+
c = exec_wrapper_get_colors()
message = ( repr(e) if type(e).__name__ in ('MMGenError','MMGenSystemExit') else exc )
sys.stdout.write('{}{}'.format(
diff --git a/test/overlay/fakemods/tw.py b/test/overlay/fakemods/tw.py
index 62547bfc..7697920a 100644
--- a/test/overlay/fakemods/tw.py
+++ b/test/overlay/fakemods/tw.py
@@ -16,5 +16,12 @@ if os.getenv('MMGEN_TEST_SUITE_DETERMINISTIC'):
}
if os.getenv('MMGEN_BOGUS_WALLET_DATA'):
+
+ async def fake_set_dates(foo,rpc,us):
+ for o in us:
+ o.date = 1831006505 - int(9.7 * 60 * (o.confs - 1))
+
+ TwCommon.set_dates = fake_set_dates
+
# 1831006505 (09 Jan 2028) = projected time of block 1000000
TwCommon.date_formatter['days'] = lambda rpc,secs: (1831006505 - secs) // 86400
diff --git a/test/overlay/fakemods/twuo.py b/test/overlay/fakemods/twuo.py
index 86b4d9d5..e17b1889 100644
--- a/test/overlay/fakemods/twuo.py
+++ b/test/overlay/fakemods/twuo.py
@@ -3,15 +3,10 @@ from .twuo_orig import *
if os.getenv('MMGEN_BOGUS_WALLET_DATA'):
- async def fake_set_dates(foo,rpc,us):
- for o in us:
- o.date = 1831006505 - int(9.7 * 60 * (o.confs - 1))
-
async def fake_get_unspent_rpc(foo):
from decimal import Decimal
import json
from mmgen.fileutil import get_data_from_file
return json.loads(get_data_from_file(os.getenv('MMGEN_BOGUS_WALLET_DATA')),parse_float=Decimal)
- TwUnspentOutputs.set_dates = fake_set_dates
TwUnspentOutputs.get_unspent_rpc = fake_get_unspent_rpc
diff --git a/test/test.py b/test/test.py
index d45e50eb..8b2bf847 100755
--- a/test/test.py
+++ b/test/test.py
@@ -608,7 +608,8 @@ class CmdGroupMgr(object):
cls.__doc__.strip() if cls.__doc__ else cls.__name__
))
- Die(0,'\n'+' '.join(e[0] for e in ginfo))
+ Msg( '\n' + ' '.join(e[0] for e in ginfo) )
+ sys.exit(0)
def find_cmd_in_groups(self,cmd,group=None):
"""