dep.py 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159
  1. #!/usr/bin/env python3
  2. """
  3. test.modtest_d.dep: dependency unit tests for the MMGen suite
  4. Test whether dependencies are installed and functional.
  5. No data verification is performed.
  6. """
  7. import sys
  8. from subprocess import run, PIPE
  9. from mmgen.util import msg, rmsg, ymsg, gmsg
  10. from mmgen.exception import NoLEDSupport
  11. from ..include.common import cfg, vmsg, check_solc_ver
  12. class unit_tests:
  13. altcoin_deps = ('solc', 'keccak', 'pysocks', 'semantic_version')
  14. win_skip = ('led', 'semantic_version')
  15. def secp256k1(self, name, ut):
  16. try:
  17. from mmgen.proto.secp256k1.secp256k1 import pubkey_gen
  18. pubkey_gen(bytes.fromhex('deadbeef'*8), 1)
  19. return True
  20. except ModuleNotFoundError as e:
  21. ymsg(f'{type(e).__name__}: {e}')
  22. msg('Installing secp256k1 module locally...')
  23. run(['python3', './setup.py', 'build_ext', '--inplace'], stdout=PIPE, stderr=PIPE, check=True)
  24. ymsg('The module has been installed. Try re-running the test')
  25. sys.exit(1)
  26. return False
  27. def led(self, name, ut):
  28. from mmgen.led import LEDControl
  29. try:
  30. LEDControl(enabled=True)
  31. except NoLEDSupport:
  32. ymsg('Warning: no LED support on this platform')
  33. else:
  34. gmsg('LED support found!')
  35. return True
  36. def keccak(self, name, ut): # used by ETH, ETC, XMR
  37. from mmgen.util2 import get_keccak, get_hashlib_keccak
  38. if not (keccak_256 := get_hashlib_keccak()):
  39. ymsg('Hashlib keccak_256() not available, falling back on cryptodome(x) package')
  40. try:
  41. keccak_256 = get_keccak()
  42. except Exception as e:
  43. rmsg(str(e))
  44. return False
  45. chk = 'c5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470'
  46. assert keccak_256(b'').hexdigest() == chk, 'hash mismatch!'
  47. return True
  48. def pysocks(self, name, ut):
  49. import requests, urllib3
  50. urllib3.disable_warnings()
  51. session = requests.Session()
  52. session.trust_env = False
  53. session.proxies.update({'https':'socks5h://127.243.172.8:20677'})
  54. try:
  55. session.get('https://127.188.29.17', timeout=1)
  56. except Exception as e:
  57. if type(e).__name__ in ('ConnectionError', 'ConnectTimeout'):
  58. return True
  59. else:
  60. ymsg('{}: {}'.format(type(e).__name__, e))
  61. msg('Is the ‘pysocks’ package installed?')
  62. return False
  63. def cryptography(self, name, ut):
  64. from cryptography.hazmat.primitives.ciphers import Cipher, algorithms, modes
  65. from cryptography.hazmat.backends import default_backend
  66. c = Cipher(algorithms.AES(b'deadbeef'*4), modes.CTR(b'deadbeef'*2), backend=default_backend())
  67. encryptor = c.encryptor()
  68. encryptor.update(b'foo') + encryptor.finalize()
  69. return True
  70. def ecdsa(self, name, ut):
  71. import ecdsa
  72. pko = ecdsa.SigningKey.from_secret_exponent(12345678901234, curve=ecdsa.SECP256k1)
  73. pko.get_verifying_key().to_string().hex()
  74. return True
  75. def ripemd160(self, name, ut):
  76. import hashlib
  77. if hashlib.new.__name__ == 'hashlib_new_wrapper':
  78. ymsg('Warning: RIPEMD160 missing in hashlib, falling back on pure-Python implementation')
  79. hashlib.new('ripemd160')
  80. return True
  81. def gmpy(self, name, ut):
  82. from gmpy2 import context, set_context, sqrt, cbrt
  83. # context() parameters are platform-dependent!
  84. set_context(context(precision=75, round=1)) # OK for gmp 6.1.2 / gmpy 2.1.0
  85. return True
  86. def aiohttp(self, name, ut):
  87. import asyncio, aiohttp
  88. async def do():
  89. async with aiohttp.ClientSession(
  90. headers = {'Content-Type': 'application/json'},
  91. connector = aiohttp.TCPConnector(),
  92. ):
  93. pass
  94. asyncio.run(do())
  95. return True
  96. def pexpect(self, name, ut):
  97. import pexpect
  98. from pexpect.popen_spawn import PopenSpawn
  99. return True
  100. def scrypt(self, name, ut):
  101. passwd, salt = b'foo', b'bar'
  102. N, r, p = 4, 8, 16
  103. buflen = 64
  104. vmsg('Testing builtin scrypt module (hashlib)')
  105. from hashlib import scrypt # max N == 14!!
  106. scrypt(password=passwd, salt=salt, n=2**N, r=r, p=p, maxmem=0, dklen=buflen)
  107. vmsg('Testing standalone scrypt module')
  108. import scrypt
  109. scrypt.hash(passwd, salt, N=2**N, r=r, p=p, buflen=buflen)
  110. return True
  111. def semantic_version(self, name, ut):
  112. from semantic_version import Version, NpmSpec
  113. return True
  114. def solc(self, name, ut):
  115. from mmgen.protocol import init_proto
  116. solc_ok = check_solc_ver()
  117. if solc_ok:
  118. cmd = [
  119. 'python3',
  120. 'scripts/create-token.py',
  121. '--coin=ETH',
  122. '--name=My Fake Token',
  123. '--symbol=FAKE',
  124. '--supply=100000000000000000000000000',
  125. '--decimals=18',
  126. '--stdout',
  127. init_proto(cfg, 'eth').checksummed_addr('deadbeef'*5),
  128. ]
  129. cp = run(cmd, stdout=PIPE, stderr=PIPE, text=True)
  130. vmsg(cp.stderr)
  131. if cp.returncode:
  132. msg(cp.stderr)
  133. return False
  134. return True