globalvars.py 8.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278
  1. #!/usr/bin/env python3
  2. #
  3. # mmgen = Multi-Mode GENerator, command-line Bitcoin cold storage solution
  4. # Copyright (C)2013-2020 The MMGen Project <mmgen@tuta.io>
  5. #
  6. # This program is free software: you can redistribute it and/or modify
  7. # it under the terms of the GNU General Public License as published by
  8. # the Free Software Foundation, either version 3 of the License, or
  9. # (at your option) any later version.
  10. #
  11. # This program is distributed in the hope that it will be useful,
  12. # but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  14. # GNU General Public License for more details.
  15. #
  16. # You should have received a copy of the GNU General Public License
  17. # along with this program. If not, see <http://www.gnu.org/licenses/>.
  18. """
  19. globalvars.py: Constants and configuration options for the MMGen suite
  20. """
  21. import sys,os
  22. from decimal import Decimal
  23. from collections import namedtuple
  24. from .devtools import *
  25. # Global vars are set to dfl values in class g.
  26. # They're overridden in this order:
  27. # 1 - config file
  28. # 2 - environmental vars
  29. # 3 - command line
  30. class g(object):
  31. def die(ev=0,s=''):
  32. if s: sys.stderr.write(s+'\n')
  33. sys.exit(ev)
  34. # Constants:
  35. version = '0.12.099'
  36. release_date = 'March 2020'
  37. proj_name = 'MMGen'
  38. proj_url = 'https://github.com/mmgen/mmgen'
  39. prog_name = os.path.basename(sys.argv[0])
  40. author = 'The MMGen Project'
  41. email = '<mmgen@tuta.io>'
  42. Cdates = '2013-2020'
  43. keywords = 'Bitcoin, BTC, Ethereum, ETH, Monero, XMR, ERC20, cryptocurrency, wallet, BIP32, cold storage, offline, online, spending, open-source, command-line, Python, Linux, Bitcoin Core, bitcoind, hd, deterministic, hierarchical, secure, anonymous, Electrum, seed, mnemonic, brainwallet, Scrypt, utility, script, scriptable, blockchain, raw, transaction, permissionless, console, terminal, curses, ansi, color, tmux, remote, client, daemon, RPC, json, entropy, xterm, rxvt, PowerShell, MSYS, MSYS2, MinGW, MinGW64, MSWin, Armbian, Raspbian, Raspberry Pi, Orange Pi, BCash, BCH, Litecoin, LTC, altcoin, ZEC, Zcash, DASH, Dashpay, SHA256Compress, monerod, EMC, Emercoin, token, deploy, contract, gas, fee, smart contract, solidity, Parity, testnet, devmode, Kovan'
  44. max_int = 0xffffffff
  45. stdin_tty = sys.stdin.isatty()
  46. stdout = sys.stdout
  47. stderr = sys.stderr
  48. http_timeout = 60
  49. err_disp_timeout = 0.7
  50. short_disp_timeout = 0.3
  51. min_time_precision = 18
  52. # Variables - these might be altered at runtime:
  53. user_entropy = ''
  54. hash_preset = '3'
  55. usr_randchars = 30
  56. tx_fee_adj = Decimal('1.0')
  57. tx_confs = 3
  58. seed_len = 256
  59. # Constant vars - some of these might be overridden in opts.py, but they don't change thereafter
  60. coin = 'BTC'
  61. dcoin = None # the display coin unit
  62. token = ''
  63. debug = False
  64. debug_opts = False
  65. debug_rpc = False
  66. debug_addrlist = False
  67. debug_subseed = False
  68. quiet = False
  69. no_license = False
  70. force_256_color = False
  71. testnet = False
  72. regtest = False
  73. accept_defaults = False
  74. use_internal_keccak_module = False
  75. chain = None # set by first call to rpc_init()
  76. chains = 'mainnet','testnet','regtest'
  77. # rpc:
  78. rpc_host = ''
  79. rpc_port = 0
  80. rpc_user = ''
  81. rpc_password = ''
  82. monero_wallet_rpc_host = 'localhost'
  83. monero_wallet_rpc_user = 'monero'
  84. monero_wallet_rpc_password = ''
  85. rpc_fail_on_command = ''
  86. rpch = None # global RPC handle
  87. use_cached_balances = False
  88. # regtest:
  89. bob = False
  90. alice = False
  91. # test suite:
  92. bogus_wallet_data = ''
  93. bogus_send = False
  94. debug_utf8 = False
  95. traceback = False
  96. test_suite = False
  97. test_suite_popen_spawn = False
  98. terminal_width = 0
  99. mnemonic_entry_modes = {}
  100. for k in ('linux','win','msys'):
  101. if sys.platform[:len(k)] == k:
  102. platform = { 'linux':'linux', 'win':'win', 'msys':'win' }[k]
  103. break
  104. else:
  105. die(1,"'{}': platform not supported by {}\n".format(sys.platform,proj_name))
  106. color = sys.stdout.isatty()
  107. if os.getenv('HOME'): # Linux or MSYS
  108. home_dir = os.getenv('HOME')
  109. elif platform == 'win': # non-MSYS Windows - not supported
  110. die(1,'$HOME not set! {} for Windows must be run in MSYS environment'.format(proj_name))
  111. else:
  112. die(2,'$HOME is not set! Unable to determine home directory')
  113. # https://wiki.debian.org/Python:
  114. # Debian (Ubuntu) sys.prefix is '/usr' rather than '/usr/local, so add 'local'
  115. # This must match the configuration in setup.py
  116. shared_data_path = os.path.join(
  117. sys.prefix,
  118. *(['local','share'] if platform == 'linux' else ['share']),
  119. proj_name.lower()
  120. )
  121. data_dir_root,data_dir,cfg_file = None,None,None
  122. daemon_data_dir = '' # set by user or protocol
  123. # global var sets user opt:
  124. global_sets_opt = ( 'minconf','seed_len','hash_preset','usr_randchars','debug',
  125. 'quiet','tx_confs','tx_fee_adj','key_generator' )
  126. # user opt sets global var:
  127. opt_sets_global = ( 'use_internal_keccak_module','subseeds' )
  128. # 'long' opts - opt sets global var
  129. common_opts = (
  130. 'color','no_license','rpc_host','rpc_port','testnet','rpc_user','rpc_password',
  131. 'monero_wallet_rpc_host','monero_wallet_rpc_user','monero_wallet_rpc_password',
  132. 'daemon_data_dir','force_256_color','regtest','coin','bob','alice',
  133. 'accept_defaults','token'
  134. )
  135. # opts initialized to None by opts.init() if not set by user
  136. required_opts = (
  137. 'quiet','verbose','debug','outdir','echo_passphrase','passwd_file','stdout',
  138. 'show_hash_presets','label','keep_passphrase','keep_hash_preset','yes',
  139. 'brain_params','b16','usr_randchars','coin','bob','alice','key_generator',
  140. 'hidden_incog_input_params','in_fmt'
  141. )
  142. incompatible_opts = (
  143. ('help','longhelp'),
  144. ('bob','alice'),
  145. ('label','keep_label'),
  146. ('tx_id','info'),
  147. ('tx_id','terse_info'),
  148. ('batch','rescan'), # TODO: still incompatible?
  149. )
  150. cfg_file_opts = (
  151. 'color','debug','hash_preset','http_timeout','no_license','rpc_host','rpc_port',
  152. 'quiet','tx_fee_adj','usr_randchars','testnet','rpc_user','rpc_password',
  153. 'monero_wallet_rpc_host','monero_wallet_rpc_user','monero_wallet_rpc_password',
  154. 'daemon_data_dir','force_256_color','regtest','subseeds','mnemonic_entry_modes',
  155. 'btc_max_tx_fee','ltc_max_tx_fee','bch_max_tx_fee','eth_max_tx_fee',
  156. 'eth_mainnet_chain_name','eth_testnet_chain_name',
  157. 'max_tx_file_size','max_input_size'
  158. )
  159. # Supported environmental vars
  160. # The corresponding vars (lowercase, minus 'mmgen_') must be initialized in g
  161. # 'DISABLE_' env vars disable the corresponding var in g
  162. env_opts = (
  163. 'MMGEN_DEBUG_ALL', # special: there is no g.debug_all var
  164. 'MMGEN_TEST_SUITE',
  165. 'MMGEN_TEST_SUITE_POPEN_SPAWN',
  166. 'MMGEN_TERMINAL_WIDTH',
  167. 'MMGEN_BOGUS_WALLET_DATA',
  168. 'MMGEN_BOGUS_SEND',
  169. 'MMGEN_DEBUG',
  170. 'MMGEN_DEBUG_OPTS',
  171. 'MMGEN_DEBUG_RPC',
  172. 'MMGEN_DEBUG_ADDRLIST',
  173. 'MMGEN_DEBUG_UTF8',
  174. 'MMGEN_DEBUG_SUBSEED',
  175. 'MMGEN_QUIET',
  176. 'MMGEN_FORCE_256_COLOR',
  177. 'MMGEN_MIN_URANDCHARS',
  178. 'MMGEN_NO_LICENSE',
  179. 'MMGEN_RPC_HOST',
  180. 'MMGEN_RPC_FAIL_ON_COMMAND',
  181. 'MMGEN_TESTNET',
  182. 'MMGEN_REGTEST',
  183. 'MMGEN_TRACEBACK',
  184. 'MMGEN_USE_STANDALONE_SCRYPT_MODULE',
  185. 'MMGEN_DISABLE_COLOR',
  186. 'MMGEN_DISABLE_MSWIN_PW_WARNING',
  187. )
  188. infile_opts = (
  189. 'keys_from_file',
  190. 'mmgen_keys_from_file',
  191. 'passwd_file',
  192. 'keysforaddrs',
  193. 'comment_file',
  194. 'contract_data',
  195. )
  196. # Auto-typechecked and auto-set opts - incompatible with global_sets_opt and opt_sets_global
  197. # First value in list is the default
  198. ov = namedtuple('autoset_opt_info',['type','choices'])
  199. autoset_opts = {
  200. 'fee_estimate_mode': ov('nocase_pfx', ('conservative','economical')),
  201. }
  202. min_screen_width = 80
  203. minconf = 1
  204. max_tx_file_size = 100000
  205. max_input_size = 1024 * 1024
  206. passwd_max_tries = 5
  207. max_urandchars = 80
  208. min_urandchars = 10
  209. seed_lens = 128,192,256
  210. scramble_hash_rounds = 10
  211. subseeds = 100
  212. mmenc_ext = 'mmenc'
  213. salt_len = 16
  214. aesctr_iv_len = 16
  215. aesctr_dfl_iv = int.to_bytes(1,aesctr_iv_len,'big')
  216. hincog_chk_len = 8
  217. key_generators = ('python-ecdsa','libsecp256k1') # '1','2'
  218. key_generator = 2 # libsecp256k1 is default
  219. force_standalone_scrypt_module = False
  220. # Scrypt params: 'id_num': [N, p, r] (N is an exponent of two)
  221. # NB: hashlib.scrypt in Python (>=v3.6) supports max N value of 14. This means that
  222. # for hash presets > 3 the standalone scrypt library must be used!
  223. hash_presets = {
  224. '1': [12, 8, 1],
  225. '2': [13, 8, 4],
  226. '3': [14, 8, 8],
  227. '4': [15, 8, 12],
  228. '5': [16, 8, 16],
  229. '6': [17, 8, 20],
  230. '7': [18, 8, 24],
  231. }
  232. if os.getenv('MMGEN_TEST_SUITE'):
  233. err_disp_timeout = 0.1
  234. short_disp_timeout = 0.1
  235. if os.getenv('MMGEN_TEST_SUITE_POPEN_SPAWN'):
  236. stdin_tty = True
  237. if os.getenv('MMGEN_DEBUG_ALL'):
  238. for name in env_opts:
  239. if name[:11] == 'MMGEN_DEBUG':
  240. os.environ[name] = '1'