ut_msg.py 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151
  1. #!/usr/bin/env python3
  2. """
  3. test.daemontest_d.ut_msg: message signing unit tests for the MMGen suite
  4. """
  5. import os
  6. from mmgen.util import msg, pumsg, suf
  7. from mmgen.protocol import CoinProtocol
  8. from mmgen.msg import NewMsg, UnsignedMsg, SignedMsg, SignedOnlineMsg, ExportedMsgSigs
  9. from mmgen.addr import MMGenID
  10. from ..include.common import cfg, silence, end_silence, restart_test_daemons, stop_test_daemons
  11. def get_obj(coin, network, msghash_type):
  12. if coin == 'bch':
  13. addrlists = 'DEADBEEF:C:1-20 98831F3A:C:8,2 A091ABAA:L:111 A091ABAA:C:1'
  14. elif coin == 'eth':
  15. addrlists = 'DEADBEEF:E:1-20 98831F3A:E:8,2 A091ABAA:E:111'
  16. else:
  17. # A091ABAA = 98831F3A:5S
  18. addrlists = 'DEADBEEF:C:1-20 98831F3A:B:8,2 A091ABAA:S:10-11 A091ABAA:111 A091ABAA:C:1'
  19. return NewMsg(
  20. cfg = cfg,
  21. coin = coin,
  22. network = network,
  23. message = '08/Jun/2021 Bitcoin Law Enacted by El Salvador Legislative Assembly',
  24. addrlists = addrlists,
  25. msghash_type = msghash_type)
  26. def print_total(n):
  27. msg(f'{n} signature{suf(n)} verified')
  28. async def run_test(network_id, chksum, msghash_type='raw'):
  29. coin, network = CoinProtocol.Base.parse_network_id(network_id)
  30. if not cfg.verbose:
  31. silence()
  32. m = get_obj(coin, network, msghash_type)
  33. if m.proto.sign_mode == 'daemon':
  34. restart_test_daemons(network_id)
  35. pumsg('\nTesting data creation:\n')
  36. tmpdir = os.path.join('test', 'trash2')
  37. os.makedirs(tmpdir, exist_ok=True)
  38. assert m.chksum.upper() == chksum, f'{m.chksum.upper()} != {chksum}'
  39. m.write_to_file(
  40. outdir = tmpdir,
  41. ask_overwrite = False)
  42. pumsg('\nTesting signing:\n')
  43. m = UnsignedMsg(cfg, infile = os.path.join(tmpdir, get_obj(coin, network, msghash_type).filename))
  44. await m.sign(wallet_files=['test/ref/98831F3A.mmwords'])
  45. m = SignedMsg(cfg, data=m.__dict__)
  46. m.write_to_file(
  47. outdir = tmpdir,
  48. ask_overwrite = False)
  49. pumsg('\nTesting display:\n')
  50. m = SignedOnlineMsg(cfg, infile = os.path.join(tmpdir, get_obj(coin, network, msghash_type).signed_filename))
  51. msg(m.format())
  52. single_addr = 'A091ABAA:E:111' if m.proto.base_proto == 'Ethereum' else 'A091ABAA:111'
  53. single_addr_coin = m.sigs[MMGenID(m.proto, single_addr)]['addr']
  54. pumsg('\nTesting single address display:\n')
  55. msg(m.format(single_addr))
  56. pumsg('\nTesting verification:\n')
  57. print_total(await m.verify())
  58. pumsg('\nTesting single address verification:\n')
  59. print_total(await m.verify(single_addr))
  60. pumsg('\nTesting JSON dump for export:\n')
  61. msg(m.get_json_for_export())
  62. pumsg('\nTesting single address JSON dump for export:\n')
  63. msg(m.get_json_for_export(single_addr))
  64. from mmgen.fileutil import write_data_to_file
  65. exported_sigs = os.path.join(tmpdir, 'signatures.json')
  66. write_data_to_file(
  67. cfg = cfg,
  68. outfile = exported_sigs,
  69. data = m.get_json_for_export(),
  70. desc = 'signature data',
  71. ask_overwrite = False)
  72. m = ExportedMsgSigs(cfg, infile=exported_sigs)
  73. pumsg('\nTesting verification (exported data):\n')
  74. print_total(await m.verify())
  75. pumsg('\nTesting single address verification (exported data):\n')
  76. print_total(await m.verify(single_addr_coin))
  77. pumsg('\nTesting display (exported data):\n')
  78. msg(m.format())
  79. pumsg('\nTesting single address display (exported data):\n')
  80. msg(m.format(single_addr_coin))
  81. if m.proto.sign_mode == 'daemon':
  82. stop_test_daemons(network_id)
  83. msg('\n')
  84. if not cfg.verbose:
  85. end_silence()
  86. return True
  87. class unit_tests:
  88. altcoin_deps = ('ltc', 'bch', 'eth', 'eth_raw')
  89. def btc(self, name, ut, desc='Bitcoin mainnet'):
  90. return run_test('btc', 'AA0DB5')
  91. def btc_tn(self, name, ut, desc='Bitcoin testnet'):
  92. return run_test('btc_tn', 'A88E1D')
  93. def btc_rt(self, name, ut, desc='Bitcoin regtest'):
  94. return run_test('btc_rt', '578018')
  95. def ltc(self, name, ut, desc='Litecoin mainnet'):
  96. return run_test('ltc', 'BA7549')
  97. def bch(self, name, ut, desc='Bitcoin Cash mainnet'):
  98. return run_test('bch', '1B8065')
  99. def eth(self, name, ut, desc='Ethereum mainnet'):
  100. return run_test('eth', '35BAD9', msghash_type='eth_sign')
  101. def eth_raw(self, name, ut, desc='Ethereum mainnet (raw message)'):
  102. return run_test('eth', '9D900C')