daemon.py 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149
  1. #!/usr/bin/env python3
  2. #
  3. # mmgen = Multi-Mode GENerator, a command-line cryptocurrency wallet
  4. # Copyright (C)2013-2023 The MMGen Project <mmgen@tuta.io>
  5. # Licensed under the GNU General Public License, Version 3:
  6. # https://www.gnu.org/licenses
  7. # Public project repositories:
  8. # https://github.com/mmgen/mmgen
  9. # https://gitlab.com/mmgen/mmgen
  10. """
  11. proto.xmr.daemon: Monero base protocol daemon classes
  12. """
  13. import os
  14. from ...globalvars import g
  15. from ...opts import opt
  16. from ...util import list_gen,die
  17. from ...daemon import CoinDaemon,RPCDaemon,_nw,_dd
  18. class monero_daemon(CoinDaemon):
  19. daemon_data = _dd('Monero', 'N/A', 'N/A')
  20. networks = ('mainnet','testnet')
  21. exec_fn = 'monerod'
  22. testnet_dir = 'stagenet'
  23. new_console_mswin = True
  24. host = 'localhost' # FIXME
  25. rpc_ports = _nw(18081, 38081, None) # testnet is stagenet
  26. cfg_file = 'bitmonero.conf'
  27. datadirs = {
  28. 'linux': [g.home_dir,'.bitmonero'],
  29. 'win': ['/','c','ProgramData','bitmonero']
  30. }
  31. def init_datadir(self):
  32. self.logdir = super().init_datadir()
  33. return os.path.join(
  34. self.logdir,
  35. self.testnet_dir if self.network == 'testnet' else '' )
  36. def get_p2p_port(self):
  37. return self.rpc_port - 1
  38. def init_subclass(self):
  39. from .rpc import MoneroRPCClient
  40. self.rpc = MoneroRPCClient(
  41. proto = self.proto,
  42. host = self.host,
  43. port = self.rpc_port,
  44. user = None,
  45. passwd = None,
  46. test_connection = False,
  47. daemon = self )
  48. self.shared_args = list_gen(
  49. [f'--no-zmq'],
  50. [f'--p2p-bind-port={self.p2p_port}', self.p2p_port],
  51. [f'--rpc-bind-port={self.rpc_port}'],
  52. ['--stagenet', self.network == 'testnet'],
  53. )
  54. self.coind_args = list_gen(
  55. ['--hide-my-port'],
  56. ['--no-igd'],
  57. [f'--data-dir={self.datadir}', self.non_dfl_datadir],
  58. [f'--pidfile={self.pidfile}', self.platform == 'linux'],
  59. ['--detach', not (self.opt.no_daemonize or self.platform=='win')],
  60. ['--offline', not self.opt.online],
  61. )
  62. @property
  63. def stop_cmd(self):
  64. return ['kill','-Wf',self.pid] if self.platform == 'win' else [self.exec_fn] + self.shared_args + ['exit']
  65. class MoneroWalletDaemon(RPCDaemon):
  66. master_daemon = 'monero_daemon'
  67. rpc_type = 'Monero wallet'
  68. exec_fn = 'monero-wallet-rpc'
  69. coin = 'XMR'
  70. new_console_mswin = True
  71. networks = ('mainnet','testnet')
  72. rpc_ports = _nw(13131, 13141, None) # testnet is non-standard
  73. def __init__(
  74. self,
  75. proto,
  76. wallet_dir,
  77. test_suite = False,
  78. host = None,
  79. user = None,
  80. passwd = None,
  81. daemon_addr = None,
  82. proxy = None,
  83. port_shift = None,
  84. datadir = None ):
  85. self.proto = proto
  86. self.test_suite = test_suite
  87. super().__init__()
  88. self.network = proto.network
  89. self.wallet_dir = wallet_dir
  90. self.rpc_port = getattr(self.rpc_ports,self.network) + (11 if test_suite else 0)
  91. if port_shift:
  92. self.rpc_port += port_shift
  93. id_str = f'{self.exec_fn}-{self.bind_port}'
  94. self.datadir = os.path.join((datadir or self.exec_fn),('','test_suite')[test_suite])
  95. self.pidfile = os.path.join(self.datadir,id_str+'.pid')
  96. self.logfile = os.path.join(self.datadir,id_str+'.log')
  97. self.proxy = proxy
  98. self.daemon_addr = daemon_addr
  99. self.daemon_port = None if daemon_addr else CoinDaemon(proto=proto,test_suite=test_suite).rpc_port
  100. self.host = host or opt.wallet_rpc_host or g.monero_wallet_rpc_host
  101. self.user = user or opt.wallet_rpc_user or g.monero_wallet_rpc_user
  102. self.passwd = passwd or opt.wallet_rpc_password or g.monero_wallet_rpc_password
  103. assert self.host
  104. assert self.user
  105. if not self.passwd:
  106. die(1,
  107. 'You must set your Monero wallet RPC password.\n' +
  108. 'This can be done on the command line with the --wallet-rpc-password option\n' +
  109. "(insecure, not recommended), or by setting 'monero_wallet_rpc_password' in\n" +
  110. "the MMGen config file." )
  111. self.daemon_args = list_gen(
  112. ['--untrusted-daemon'],
  113. [f'--rpc-bind-port={self.rpc_port}'],
  114. ['--wallet-dir='+self.wallet_dir],
  115. ['--log-file='+self.logfile],
  116. [f'--rpc-login={self.user}:{self.passwd}'],
  117. [f'--daemon-address={self.daemon_addr}', self.daemon_addr],
  118. [f'--daemon-port={self.daemon_port}', not self.daemon_addr],
  119. [f'--proxy={self.proxy}', self.proxy],
  120. [f'--pidfile={self.pidfile}', self.platform == 'linux'],
  121. ['--detach', not (self.opt.no_daemonize or self.platform=='win')],
  122. ['--stagenet', self.network == 'testnet'],
  123. ['--allow-mismatched-daemon-version', test_suite],
  124. )
  125. from .rpc import MoneroWalletRPCClient
  126. self.rpc = MoneroWalletRPCClient( daemon=self, test_connection=False )