swap.py 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134
  1. #!/usr/bin/env python3
  2. """
  3. test.modtest_d.swap: swap unit tests for the MMGen suite
  4. """
  5. from mmgen.color import cyan
  6. from ..include.common import cfg, vmsg, make_burn_addr
  7. from mmgen.swap.proto.thorchain import SwapAsset
  8. class unit_tests:
  9. def asset(self, name, ut, desc='SwapAsset class'):
  10. for name, full_name, memo_name, chain, asset, direction in (
  11. ('BTC', 'BTC.BTC', 'b', 'BTC', None, 'recv'),
  12. ('LTC', 'LTC.LTC', 'l', 'LTC', None, 'recv'),
  13. ('BCH', 'BCH.BCH', 'c', 'BCH', None, 'recv'),
  14. ('ETH.USDT', 'ETH.USDT', 'ETH.USDT', 'ETH', 'USDT', 'recv'),
  15. ):
  16. a = SwapAsset(name, direction)
  17. vmsg(f' {a.name}')
  18. assert a.name == name
  19. assert a.full_name == full_name
  20. assert a.direction == direction
  21. assert a.asset == asset
  22. assert a.chain == chain
  23. assert a.memo_asset_name == memo_name
  24. return True
  25. def memo(self, name, ut, desc='Swap transaction memo'):
  26. from mmgen.protocol import init_proto
  27. from mmgen.amt import UniAmt
  28. from mmgen.swap.proto.thorchain import Memo
  29. for coin, addrtype, asset_name, token in (
  30. ('ltc', 'bech32', 'LTC', None),
  31. ('bch', 'compressed', 'BCH', None),
  32. ('eth', None, 'ETH', None),
  33. ('eth', None, 'ETH.USDT', 'USDT'),
  34. ):
  35. proto = init_proto(cfg, coin, tokensym=token, need_amt=True)
  36. addr = make_burn_addr(proto, addrtype)
  37. asset = SwapAsset(asset_name, 'recv')
  38. vmsg(f'\nTesting asset {cyan(asset_name)}:')
  39. for limit, limit_chk in (
  40. ('123.4567', 12340000000),
  41. ('1.234567', 123400000),
  42. ('0.01234567', 1234000),
  43. ('0.00012345', 12345),
  44. (None, 0),
  45. ):
  46. vmsg('\nTesting memo initialization:')
  47. m = Memo(proto, asset, addr, trade_limit=UniAmt(limit) if limit else None)
  48. vmsg(f'str(memo): {m}')
  49. vmsg(f'repr(memo): {m!r}')
  50. vmsg(f'limit: {limit}')
  51. p = Memo.parse(m)
  52. limit_dec = UniAmt(p.trade_limit, from_unit='satoshi')
  53. vmsg(f'limit_dec: {limit_dec.hl()}')
  54. vmsg('\nTesting memo parsing:')
  55. from pprint import pformat
  56. vmsg(pformat(p._asdict()))
  57. assert p.proto == 'THORChain'
  58. assert p.function == 'SWAP'
  59. assert p.chain == coin.upper()
  60. assert p.asset == token or coin.upper()
  61. assert p.address == addr.views[addr.view_pref]
  62. assert p.trade_limit == limit_chk
  63. assert p.stream_interval == 3
  64. assert p.stream_quantity == 0 # auto
  65. vmsg('\nTesting is_partial_memo():')
  66. for vec in (
  67. str(m),
  68. 'SWAP:xyz',
  69. '=:xyz',
  70. 's:xyz',
  71. 'a:xz',
  72. '+:xz',
  73. 'WITHDRAW:xz',
  74. 'LOAN+:xz:x:x',
  75. 'TRADE-:xz:x:x',
  76. 'BOND:xz',
  77. ):
  78. vmsg(f' pass: {vec}')
  79. assert Memo.is_partial_memo(vec.encode('ascii')), vec
  80. for vec in (
  81. '=',
  82. 'swap',
  83. 'swap:',
  84. 'swap:abc',
  85. 'SWAP:a',
  86. ):
  87. vmsg(f' fail: {vec}')
  88. assert not Memo.is_partial_memo(vec.encode('ascii')), vec
  89. vmsg('\nTesting error handling:')
  90. def bad(s):
  91. return lambda: Memo.parse(s)
  92. def bad10():
  93. coin = 'BTC'
  94. proto = init_proto(cfg, coin, need_amt=True)
  95. addr = make_burn_addr(proto, 'C')
  96. asset = SwapAsset(coin, 'send')
  97. Memo(proto, asset, addr)
  98. def bad11():
  99. SwapAsset('XYZ', 'send')
  100. def bad12():
  101. SwapAsset('DOGE', 'send')
  102. ut.process_bad_data((
  103. ('bad1', 'SwapMemoParseError', 'must contain', bad('x')),
  104. ('bad2', 'SwapMemoParseError', 'must contain', bad('y:z:x')),
  105. ('bad3', 'SwapMemoParseError', 'function abbrev', bad('z:l:foobar:0/3/0')),
  106. ('bad4', 'SwapAssetError', 'unrecognized', bad('=:x:foobar:0/3/0')),
  107. ('bad5', 'SwapMemoParseError', 'failed to parse', bad('=:l:foobar:n')),
  108. ('bad6', 'SwapMemoParseError', 'invalid specifier', bad('=:l:foobar:x/3/0')),
  109. ('bad7', 'SwapMemoParseError', 'extra', bad('=:l:foobar:0/3/0:x')),
  110. ('bad10', 'AssertionError', 'recv', bad10),
  111. ('bad11', 'SwapAssetError', 'unrecognized', bad11),
  112. ('bad12', 'SwapAssetError', 'unsupported', bad12),
  113. ), pfx='')
  114. return True