#!/usr/bin/env python3 # # mmgen = Multi-Mode GENerator, command-line Bitcoin cold storage solution # Copyright (C)2013-2019 The MMGen Project # # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation, either version 3 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . """ test/scrambletest.py: seed scrambling and addrlist data generation tests for all supported altcoins """ import sys,os,subprocess repo_root = os.path.normpath(os.path.abspath(os.path.join(os.path.dirname(sys.argv[0]),os.pardir))) os.chdir(repo_root) sys.path.__setitem__(0,repo_root) os.environ['MMGEN_TEST_SUITE'] = '1' # Import this _after_ local path's been added to sys.path from mmgen.common import * from test.common import init_coverage opts_data = { 'text': { 'desc': 'Test seed scrambling and addrlist data generation for all supported altcoins', 'usage':'[options] [command]', 'options': """ -h, --help Print this help message --, --longhelp Print help message for long options (common options) -C, --coverage Produce code coverage info using trace module -l, --list-cmds List and describe the tests and commands in this test suite -s, --system Test scripts and modules installed on system rather than those in the repo root -v, --verbose Produce more verbose output """, 'notes': """ If no command is given, the whole suite of tests is run. """ } } cmd_args = opts.init(opts_data) os.environ['MMGEN_DEBUG_ADDRLIST'] = '1' if not opt.system: os.environ['PYTHONPATH'] = repo_root from collections import OrderedDict test_data = OrderedDict([ # SCRAMBLED_SEED[:8] SCRAMBLE_KEY ID_STR LBL FIRST ADDR ('btc', ('456d7f5f1c4bfe3b','(none)', '', '', '1MU7EdgqYy9JX35L25hR6CmXXcSEBDAwyv')), ('btc_compressed',('bf98a4af5464a4ef','compressed', '-C', 'COMPRESSED','1F97Jd89wwmu4ELadesAdGDzg3d8Y6j5iP')), ('btc_segwit', ('b56962d829ffc678','segwit', '-S', 'SEGWIT', '36TvVzU5mxSjJ3D9qKAmYzCV7iUqtTDezF')), ('btc_bech32', ('d09eea818f9ad17f','bech32', '-B', 'BECH32', 'bc1q8snv94j6959y3gkqv4gku0cm5mersnpucsvw5z')), ('bch', ('456d7f5f1c4bfe3b','(none)', '', '', '1MU7EdgqYy9JX35L25hR6CmXXcSEBDAwyv')), ('bch_compressed',('bf98a4af5464a4ef','compressed', '-C', 'COMPRESSED','1F97Jd89wwmu4ELadesAdGDzg3d8Y6j5iP')), ('ltc', ('b11f16632e63ba92','ltc:legacy', '-LTC','LTC', 'LMxB474SVfxeYdqxNrM1WZDZMnifteSMv1')), ('ltc_compressed',('7ccf465d466ee7d3','ltc:compressed', '-LTC-C','LTC:COMPRESSED', 'LdkebBKVXSs6NNoPJWGM8KciDnL8LhXXjb')), ('ltc_segwit', ('9460f5ba15e82768','ltc:segwit', '-LTC-S','LTC:SEGWIT', 'MQrY3vEbqKMBgegXrSaR93R2HoTDE5bKrY')), ('ltc_bech32', ('dbdbff2e196e27d3','ltc:bech32', '-LTC-B','LTC:BECH32', 'ltc1qdvgqsz94ht20lr8fyk5v7n884hu9p7d8k9easu')), ('eth', ('213ed116869b19f2','eth', '-ETH', 'ETH', 'e704b6cfd9f0edb2e6cfbd0c913438d37ede7b35')), ('etc', ('909def37096f5ab8','etc', '-ETC', 'ETC', '1a6acbef8c38f52f20d04ecded2992b04d8608d7')), ('dash', ('1319d347b021f952','dash:legacy', '-DASH', 'DASH','XoK491fppGNZQUUS9uEFkT6L9u8xxVFJNJ')), ('emc', ('7e1a29853d2db875','emc:legacy', '-EMC', 'EMC', 'EU4L6x2b5QUb2gRQsBAAuB8TuPEwUxCNZU')), ('zec', ('0bf9b5b20af7b5a0','zec:legacy', '-ZEC', 'ZEC', 't1URz8BHxV38v3gsaN6oHQNKC16s35R9WkY')), ('zec_zcash_z', ('b15570d033df9b1a','zec:zcash_z', '-ZEC-Z','ZEC:ZCASH_Z','zcLMMsnzfFYZWU4avRBnuc83yh4jTtJXbtP32uWrs3ickzu1krMU4ppZCQPTwwfE9hLnRuFDSYF8VFW13aT9eeQK8aov3Ge')), ('xmr', ('c76af3b088da3364','xmr:monero', '-XMR-M','XMR:MONERO','41tmwZd2CdXEGtWqGY9fH9FVtQM8VxZASYPQ3VJQhFjtGWYzQFuidD21vJYTi2yy3tXRYXTNXBTaYVLav62rwUUpFFyicZU')), ]) cmd_base = 'python3{} cmds/mmgen-addrgen -qS'.format( ' -m trace --count --coverdir={} --file={}'.format(*init_coverage()) if opt.coverage else '') def run_tests(): for test in test_data: if test == 'zec_zcash_z' and g.platform == 'win': msg("Skipping 'zec_zcash_z' test for Windows platform") continue try: coin,mmtype = test.split('_',1) except: coin,mmtype = test,None type_arg = ' --type='+mmtype if mmtype else '' cmd = '{} --coin={}{} test/ref/98831F3A.mmwords 1'.format(cmd_base,coin,type_arg) vmsg(green('Executing: {}'.format(cmd))) msg_r('Testing: --coin {:4} {:22}'.format(coin.upper(),type_arg)) p = subprocess.Popen(cmd.split(),stdout=subprocess.PIPE,stderr=subprocess.PIPE) o = p.stdout.read().decode() vmsg(o) o = o.splitlines() d = [e for e in o if len(e) > 4 and e[:9] == 'sc_debug_'] d.append('sc_debug_addr: ' + o[-2].split()[-1]) for n,k in enumerate(['seed','str','id_str','lbl','addr']): kk = 'sc_debug_'+k a = test_data[test][n] b = [e for e in d if e[:len(kk)] == kk][0][len(kk)+2:] if b == a: vmsg('sc_{}: {}'.format(k,a)) else: rdie(1,'\nError: sc_{} value {} does not match reference value {}'.format(k,b,a)) msg('OK') start_time = int(time.time()) run_tests() t = int(time.time()) - start_time m = '\nAll requested tests finished OK, elapsed time: {:02}:{:02}' gmsg(m.format(t//60,t%60))