daemon, protocol, xmrwallet: improve handling of datadirs

The default Monero wallet directory for both compat and non-compat modes is now
`altcoins/xmr/tracking-wallets` under the user’s data directory.  Formerly, this
was the default for compat mode only, while non-compat defaulted to the current
working directory.

To get the previous behavior in non-compat mode, you must specify --wallet-dir=.
on the command line.
This commit is contained in:
The MMGen Project 2026-09-21 10:30:51 +00:00
commit 5e41407b3c
Signed by: mmgen
GPG key ID: 3F8B1861E32B7DA2
11 changed files with 119 additions and 150 deletions

View file

@ -23,6 +23,7 @@ daemon: Daemon control interface for the MMGen suite
import os, time, importlib
from subprocess import run, PIPE, CompletedProcess
from collections import namedtuple
from pathlib import Path
from .cfg import gc
from .base_obj import Lockable
@ -118,8 +119,7 @@ class Daemon(Lockable):
@property
def pid(self):
if self.use_pidfile:
with open(self.pidfile) as fp:
return fp.read().strip()
return self.pidfile.read_text().strip()
match gc.platform:
case 'win32':
@ -278,7 +278,7 @@ class CoinDaemon(Daemon):
cfg_file_hdr = ''
avail_flags = ('keep_cfg_file',)
avail_opts = ('no_daemonize', 'online')
testnet_dir = None
testnet_dir = 'testnet'
test_suite_port_shift = 1237
rpc_user = None
rpc_password = None
@ -411,12 +411,22 @@ class CoinDaemon(Daemon):
getattr(self.proto.network_names, self.network),
'test suite ' if self.test_suite else '')
# user-set values take precedence
self.datadir = os.path.abspath(datadir or cfg.daemon_data_dir or self.init_datadir())
self.has_non_dfl_datadir = bool(datadir or cfg.daemon_data_dir or self.test_suite or self.network == 'regtest')
self.datadir = Path(datadir or cfg.daemon_data_dir or self.dfl_datadir).absolute()
# init_datadir() may have already initialized logdir
self.logdir = os.path.abspath(getattr(self, 'logdir', self.datadir))
if self.test_suite and cfg.test_user:
self.datadir = self.datadir / cfg.test_user
self.has_non_dfl_datadir = bool(datadir or cfg.daemon_data_dir or self.test_suite)
# location of the network's blockchain data and authentication cookie
self.network_datadir = (
self.datadir / {
'mainnet': '',
'testnet': self.testnet_dir,
'regtest': 'regtest',
}[self.network]
if self.proto.base_proto == 'Bitcoin' or not self.test_suite else
self.datadir)
ps_adj = (port_shift or 0) + (self.test_suite_port_shift if self.test_suite else 0)
@ -432,20 +442,20 @@ class CoinDaemon(Daemon):
self.private_port = getattr(self.private_ports, self.network)
# bind_port == self.private_port or self.rpc_port
self.pidfile = f'{self.logdir}/{self.id}-{self.network}-daemon-{self.bind_port}.pid'
self.logfile = f'{self.logdir}/{self.id}-{self.network}-daemon-{self.bind_port}.log'
fn_stem = f'{self.id}-{self.network}-daemon-{self.bind_port}'
self.logfile = self.network_datadir / (fn_stem + '.log')
if self.use_pidfile:
self.pidfile = self.network_datadir / (fn_stem + '.pid')
self.init_subclass()
def init_datadir(self):
if self.test_suite:
return os.path.join('test', 'daemons', self.network_id)
else:
return os.path.join(*self.datadirs[gc.platform])
@property
def network_datadir(self):
return self.datadir
def dfl_datadir(self):
return (
os.path.join('test', 'daemons', self.network_id) if self.test_suite else
os.path.join(*self.datadirs[gc.platform]))
def get_rpc_port(self):
return getattr(self.rpc_ports, self.network)
@ -484,7 +494,7 @@ class CoinDaemon(Daemon):
if self.use_pidfile and os.path.exists(self.pidfile):
# Parity overwrites the data in the existing pidfile without zeroing it first, leading
# to interesting consequences when the new PID has fewer digits than the previous one.
os.unlink(self.pidfile)
self.pidfile.unlink()
def remove_datadir(self):
"remove the network's datadir"

View file

@ -33,22 +33,6 @@ class bitcoin_core_daemon(CoinDaemon):
'win32': [os.getenv('APPDATA'), 'Bitcoin']}
avail_opts = ('no_daemonize', 'online', 'bdb_wallet')
def init_datadir(self):
if self.network == 'regtest' and not self.test_suite:
return os.path.join(self.cfg.data_dir_root, 'regtest', self.cfg.coin.lower())
else:
return super().init_datadir()
@property
def network_datadir(self):
"location of the network's blockchain data and authentication cookie"
return os.path.join (
self.datadir, {
'mainnet': '',
'testnet': self.testnet_dir,
'regtest': 'regtest',
}[self.network])
@property
def auth_cookie_fn(self):
return os.path.join(self.network_datadir, '.cookie')
@ -62,7 +46,7 @@ class bitcoin_core_daemon(CoinDaemon):
self.rpc_password = MMGenRegtest.rpc_password
self.shared_args = list_gen(
[f'--datadir={self.datadir}', self.nonstd_datadir or self.has_non_dfl_datadir],
[f'--datadir={self.datadir}', self.nonstd_datadir or self.has_non_dfl_datadir],
[f'--rpcport={self.rpc_port}'],
[f'--rpcuser={self.rpc_user}', self.network == 'regtest'],
[f'--rpcpassword={self.rpc_password}', self.network == 'regtest'],

View file

@ -19,7 +19,6 @@ from ...util import list_gen, get_subclasses
from ...daemon import CoinDaemon, RPCDaemon, _nw, _dd
class ethereum_daemon(CoinDaemon):
chain_subdirs = _nw('ethereum', 'goerli', 'DevelopmentChain')
base_rpc_port = 8545 # same for all networks!
base_authrpc_port = 8551 # same for all networks!
base_p2p_port = 30303 # same for all networks!
@ -49,13 +48,6 @@ class ethereum_daemon(CoinDaemon):
def get_p2p_port(self):
return self.base_p2p_port + self.port_offset
def init_datadir(self):
self.logdir = super().init_datadir()
return os.path.join(
self.logdir,
self.id,
getattr(self.chain_subdirs, self.network))
class openethereum_daemon(ethereum_daemon):
daemon_data = _dd('OpenEthereum', 3003005, '3.3.5')
version_pat = r'OpenEthereum//v(\d+)\.(\d+)\.(\d+)'
@ -77,13 +69,13 @@ class openethereum_daemon(ethereum_daemon):
['--no-secretstore'],
[f'--jsonrpc-port={self.rpc_port}'],
[f'--port={self.p2p_port}', self.p2p_port],
[f'--base-path={self.datadir}', self.has_non_dfl_datadir],
[f'--base-path={self.network_datadir}', self.has_non_dfl_datadir],
[f'--chain={self.proto.chain_name}', self.network!='regtest'],
['--config=dev', self.network=='regtest'], # no presets for mainnet or testnet
['--mode=offline', self.test_suite or self.network=='regtest'],
[f'--log-file={self.logfile}', self.has_non_dfl_datadir],
['daemon', self.use_pidfile],
[self.pidfile, self.use_pidfile])
[str(self.pidfile), self.use_pidfile])
class parity_daemon(openethereum_daemon):
daemon_data = _dd('Parity', 2007002, '2.7.2')
@ -122,7 +114,7 @@ class geth_daemon(ethereum_daemon):
[f'--port={self.p2p_port}', self.p2p_port], # geth binds p2p port even with --maxpeers=0
[f'--discovery.port={self.p2p_port}', self.id == 'reth' and self.p2p_port],
['--maxpeers=0', self.id == 'geth' and not self.opt.online],
[f'--datadir={self.datadir}', self.has_non_dfl_datadir],
[f'--datadir={self.network_datadir}', self.has_non_dfl_datadir],
['--holesky', self.network=='testnet' and self.id == 'geth'],
['--chain=holesky', self.network=='testnet' and self.id == 'reth'],
['--dev', self.network=='regtest'])
@ -157,7 +149,7 @@ class erigon_daemon(geth_daemon):
[f'--port={self.p2p_port}', self.p2p_port],
['--maxpeers=0', not self.opt.online],
[f'--private.api.addr=127.0.0.1:{self.private_port}'],
[f'--datadir={self.datadir}', self.has_non_dfl_datadir],
[f'--datadir={self.network_datadir}', self.has_non_dfl_datadir],
['--chain=goerli', self.network=='testnet'],
[f'--torrent.port={self.torrent_ports.testnet}', self.network=='testnet'],
['--chain=dev', self.network=='regtest'],

View file

@ -12,7 +12,7 @@
proto.xmr.daemon: Monero base protocol daemon classes
"""
import os
from pathlib import Path
from ...cfg import gc
from ...util import list_gen, die, contains_any
@ -31,12 +31,6 @@ class monero_daemon(CoinDaemon):
'darwin': [gc.home_dir, '.bitmonero'],
'win32': ['/', 'c', 'ProgramData', 'bitmonero']}
def init_datadir(self):
self.logdir = super().init_datadir()
return os.path.join(
self.logdir,
self.testnet_dir if self.network == 'testnet' else '')
def get_p2p_port(self):
return self.rpc_port - 1
@ -64,7 +58,7 @@ class monero_daemon(CoinDaemon):
self.coind_args = list_gen(
['--hide-my-port'],
['--no-igd'],
[f'--data-dir={self.datadir}', self.has_non_dfl_datadir],
[f'--data-dir={self.network_datadir}', self.has_non_dfl_datadir],
[f'--pidfile={self.pidfile}', self.use_pidfile],
['--detach', not (self.opt.no_daemonize or gc.platform=='win32')],
['--offline', not self.opt.online])
@ -88,7 +82,10 @@ class MoneroWalletDaemon(RPCDaemon):
networks = ('mainnet', 'testnet')
rpc_ports = _nw(13131, 13141, None) # testnet is non-standard
_reset_ok = ('debug', 'wait', 'pids', 'force_kill')
test_suite_datadir = os.path.join('test', 'daemons', 'xmrtest', 'wallet_rpc')
test_user_port_shifts = {
'bob': 10,
'alice': 20,
'miner': 30}
def __init__(
self,
@ -112,17 +109,23 @@ class MoneroWalletDaemon(RPCDaemon):
super().__init__(cfg, **kwargs)
self.network = proto.network
self.wallet_dir = wallet_dir or (self.test_suite_datadir if self.test_suite else None)
self.rpc_port = getattr(self.rpc_ports, self.network) + (11 if self.test_suite else 0)
self.disable_authentication = disable_authentication
if port_shift:
self.rpc_port += port_shift
elif cfg.test_user:
self.rpc_port += self.test_user_port_shifts[cfg.test_user]
id_str = f'{self.exec_fn}-{self.bind_port}'
self.datadir = datadir or (self.test_suite_datadir if self.test_suite else self.exec_fn + '.d')
self.pidfile = os.path.join(self.datadir, id_str+'.pid')
self.logfile = os.path.join(self.datadir, id_str+'.log')
if wallet_dir or cfg.wallet_dir:
self.wallet_dir = Path(wallet_dir or cfg.wallet_dir)
else:
from .tw.ctl import MoneroTwCtl
self.wallet_dir = MoneroTwCtl.get_tw_dir(self.proto)
fn_stem = f'{self.exec_fn}-{self.bind_port}'
self.pidfile = self.proto.network_datadir / (fn_stem + '.pid')
self.logfile = self.proto.network_datadir / (fn_stem + '.log')
self.use_pidfile = gc.platform == 'linux'
@ -176,7 +179,7 @@ class MoneroWalletDaemon(RPCDaemon):
def start(self, *args, **kwargs):
try: # NB: required due to bug in v18.3.1: PID file not deleted on shutdown
os.unlink(self.pidfile)
self.pidfile.unlink()
except FileNotFoundError:
pass
super().start(*args, **kwargs)

View file

@ -128,12 +128,18 @@ class CoinProtocol(MMGenObject):
@property
def network_datadir(self):
from pathlib import Path
return Path(
self.cfg.data_dir_root,
self.cfg.test_user,
'altcoins',
self.coin.lower(),
('' if self.network == 'mainnet' else self.network))
if self.coin == 'BTC':
return Path(
self.cfg.data_dir_root,
('' if self.network == 'mainnet' else self.network),
self.cfg.test_user).absolute()
else:
return Path(
self.cfg.data_dir_root,
'altcoins',
self.coin.lower(),
('' if self.network == 'mainnet' else self.network),
self.cfg.test_user).absolute()
@property
def dcoin(self):

View file

@ -119,9 +119,7 @@ def op(op, cfg, infile, wallets, *, spec=None, compat_call=False):
if compat_call or (cfg.compat if cfg.compat is not None else cfg.xmrwallet_compat):
if cfg.wallet_dir and not cfg.offline:
die(1, '--wallet-dir cannot be specified in xmrwallet compatibility mode')
from ..tw.ctl import TwCtl
from ..cfg import Config
twctl_cls = cfg._proto.base_proto_subclass(TwCtl, 'tw.ctl')
cfg = Config({
'_clone': cfg,
'compat': True,
@ -129,6 +127,5 @@ def op(op, cfg, infile, wallets, *, spec=None, compat_call=False):
'xmrwallet_compat': True} | ({} if cfg.offline else {
'no_start_wallet_daemon': cfg.no_start_wallet_daemon or compat_call,
'daemon': cfg.daemon or cfg.monero_daemon,
'watch_only': cfg.watch_only or cfg.autosign or bool(cfg.autosign_mountpoint),
'wallet_dir': twctl_cls.get_tw_dir(cfg._proto)}))
'watch_only': cfg.watch_only or cfg.autosign or bool(cfg.autosign_mountpoint)}))
return op_cls(op)(cfg, uargs(infile, wallets, spec, compat_call))

View file

@ -62,7 +62,6 @@ class OpSubmit(OpWallet):
wd = MoneroWalletDaemon(
cfg = self.cfg,
proto = self.proto,
wallet_dir = self.cfg.wallet_dir or '.',
monerod_addr = relay_opt[1])
u = wd.usr_daemon_args = []

View file

@ -51,7 +51,6 @@ class OpSweep(OpMixinSpec, OpWallet):
wd2 = MoneroWalletDaemon(
cfg = self.cfg,
proto = self.proto,
wallet_dir = self.cfg.wallet_dir or '.',
monerod_addr = m[1],
proxy = m[2])

View file

@ -13,7 +13,6 @@ xmrwallet.ops.wallet: xmrwallet wallet op for the MMGen Suite
"""
import asyncio, re, atexit
from pathlib import Path
from ...color import orange, cyan
from ...util import msg, gmsg, ymsg, die, suf
@ -66,7 +65,6 @@ class OpWallet(OpBase):
self.wd = MoneroWalletDaemon(
cfg = self.cfg,
proto = self.proto,
wallet_dir = self.cfg.wallet_dir or '.',
monerod_addr = self.cfg.daemon or None,
disable_authentication = self.disable_authentication,
trust_monerod = self.trust_monerod,
@ -204,13 +202,11 @@ class OpWallet(OpBase):
def get_wallet_fn(self, data, *, watch_only=None):
if watch_only is None:
watch_only = self.cfg.watch_only
return Path(
(self.cfg.wallet_dir or '.'),
'{a}-{b}-Monero{c}Wallet{d}'.format(
a = self.kal.al_id.sid,
b = data.idx,
c = 'WatchOnly' if watch_only else '',
d = f'.{self.cfg.network}' if self.cfg.network != 'mainnet' else ''))
return self.wd.wallet_dir / '{a}-{b}-Monero{c}Wallet{d}'.format(
a = self.kal.al_id.sid,
b = data.idx,
c = 'WatchOnly' if watch_only else '',
d = f'.{self.cfg.network}' if self.cfg.network != 'mainnet' else '')
@property
def add_wallet_desc(self):

View file

@ -113,17 +113,8 @@ class CmdTestXMRAutosign(CmdTestXMRWallet, CmdTestAutosignThreaded):
if trunner is None:
return
from mmgen.cfg import Config
self.alice_cfg = Config({
'coin': 'XMR',
'outdir': self.users['alice'].udir,
'wallet_rpc_password': 'passwOrd',
} | ({
'alice': True,
'compat': True
} if self.compat else {
'wallet_dir': self.users['alice'].udir
}))
self.alice_cfg = self.users['alice'].cfg
self.alice_datadir = self.users['alice'].cfg._proto.network_datadir
self.burn_addr = make_burn_addr(cfg)
@ -144,8 +135,8 @@ class CmdTestXMRAutosign(CmdTestXMRWallet, CmdTestAutosignThreaded):
seed = Wallet(self.alice_cfg, fn=data.mmwords).seed,
skip_chksum_msg = True,
key_address_validity_check = False)
kal.file.write(ask_overwrite=False)
fn = get_file_with_ext(data.udir, 'akeys')
kal.file.write(outdir=self.alice_datadir, ask_overwrite=False)
fn = get_file_with_ext(self.alice_datadir, 'akeys')
m = op('create', self.alice_cfg, fn, '1-2')
asyncio.run(m.main())
asyncio.run(m.stop_wallet_daemon())
@ -194,7 +185,7 @@ class CmdTestXMRAutosign(CmdTestXMRWallet, CmdTestAutosignThreaded):
t = self.spawn(
'mmgen-xmrwallet',
self.extra_opts
+ (['--alice', '--compat'] if self.compat else [f'--wallet-dir={data.udir}'])
+ (['--alice', '--compat'] if self.compat else [])
+ [f'--daemon=localhost:{data.md.rpc_port}']
+ (self.autosign_opts if autosign else [])
+ [op]
@ -347,7 +338,7 @@ class CmdTestXMRAutosign(CmdTestXMRWallet, CmdTestAutosignThreaded):
args = (
self.extra_opts
+ self.autosign_opts
+ (['--alice', '--compat'] if self.compat else [f'--wallet-dir={data.udir}'])
+ (['--alice', '--compat'] if self.compat else [])
+ [f'--daemon=localhost:{data.md.rpc_port}']
+ add_opts
+ [op]
@ -598,13 +589,13 @@ class CmdTestXMRCompat(CmdTestXMRAutosign):
super().__init__(cfg, trunner, cfgs, spawn)
if trunner is None:
return
self.alice_tw_dir = os.path.join(self.tr.data_dir, 'alice', 'altcoins', 'xmr', 'tracking-wallets')
data = self.users['alice']
self.alice_dump_file = os.path.join(
self.alice_tw_dir,
'{}-2-MoneroWatchOnlyWallet.dump'.format(self.users['alice'].sid))
data.wd.wallet_dir,
f'{data.sid}-2-MoneroWatchOnlyWallet.dump')
self.alice_daemon_opts = [
f'--monero-daemon=localhost:{self.users["alice"].md.rpc_port}',
'--monero-wallet-rpc-password=passwOrd']
f'--monero-daemon=localhost:{data.md.rpc_port}',
'--monero-wallet-rpc-password=abc']
self.alice_opts = ['--alice', '--coin=xmr'] + self.alice_daemon_opts
def addrimport_alice(self):

View file

@ -24,7 +24,7 @@ import os, time, re, atexit, asyncio, shutil
from subprocess import run
from collections import namedtuple
from mmgen.cfg import gc
from mmgen.cfg import Config, gc
from mmgen.util import capfirst, is_int, die, suf, list_gen
from mmgen.obj import MMGenRange
from mmgen.amt import XMRAmt
@ -156,14 +156,14 @@ class CmdTestXMRWallet(CmdTestBase):
from mmgen.proto.xmr.daemon import MoneroWalletDaemon
from mmgen.proto.xmr.rpc import MoneroRPCClient, MoneroWalletRPCClient
self.users = {}
tmpdir_num = self.tmpdir_nums[0]
ud = namedtuple('user_data', [
'cfg',
'sid',
'udir',
'twdir',
'mmwords',
'autosign',
'udir',
'daemon_datadir',
'kal_range',
'kafile',
'walletfile_fs',
@ -183,27 +183,18 @@ class CmdTestXMRWallet(CmdTestBase):
kal_range,
add_coind_args) in self.user_data:
tmpdir = os.path.join('test', 'tmp', str(tmpdir_num))
udir = os.path.join(tmpdir, user)
daemon_datadir = os.path.join(self.daemon_datadir_base, user)
if self.compat:
from mmgen.tw.ctl import TwCtl
twctl_cls = self.proto.base_proto_subclass(TwCtl, 'tw.ctl')
wallet_dir = os.path.join(self.tr.data_dir, user, 'altcoins', 'xmr', twctl_cls.tw_subdir)
else:
wallet_dir = udir
usr_cfg = Config({'_clone': self.cfg, user: True, 'wallet_rpc_password': 'abc'})
udir = usr_cfg._proto.network_datadir
md = CoinDaemon(
cfg = self.cfg,
proto = self.proto,
cfg = usr_cfg,
proto = usr_cfg._proto,
port_shift = shift,
opts = ['online'],
datadir = daemon_datadir)
opts = ['online'])
md_rpc = MoneroRPCClient(
cfg = self.cfg,
proto = self.proto,
cfg = usr_cfg,
proto = usr_cfg._proto,
host = 'localhost',
port = md.rpc_port,
user = None,
@ -212,37 +203,35 @@ class CmdTestXMRWallet(CmdTestBase):
daemon = md)
wd = MoneroWalletDaemon(
cfg = self.cfg,
proto = self.proto,
wallet_dir = wallet_dir,
cfg = usr_cfg,
proto = usr_cfg._proto,
wallet_dir = None if autosign else
(usr_cfg._proto.network_datadir / 'tracking-wallets'),
user = 'foo',
passwd = 'bar',
port_shift = shift,
monerod_addr = f'127.0.0.1:{md.rpc_port}')
wd_rpc = MoneroWalletRPCClient(
cfg = self.cfg,
cfg = usr_cfg,
daemon = wd,
test_connection = False)
if autosign:
kafile_suf = 'vkeys'
fn_stem = 'MoneroWatchOnlyWallet'
kafile_dir = self.asi_online.xmr_dir
else:
kafile_suf = 'akeys'
fn_stem = 'MoneroWallet'
kafile_dir = udir
kafile_suf, fn_stem = (
('vkeys', 'MoneroWatchOnlyWallet') if autosign else
('akeys', 'MoneroWallet'))
self.users[user] = ud(
cfg = usr_cfg,
sid = sid,
mmwords = f'test/ref/{sid}.mmwords',
autosign = autosign,
udir = udir,
daemon_datadir = daemon_datadir,
twdir = wd.wallet_dir,
kal_range = kal_range,
kafile = f'{kafile_dir}/{sid}-XMR-M[{kal_range}].{kafile_suf}',
walletfile_fs = f'{udir}/{sid}-{{}}-{fn_stem}',
addrfile_fs = f'{udir}/{sid}-{{}}-{fn_stem}.address.txt',
kafile = str(udir / f'{sid}-XMR-M[{kal_range}].{kafile_suf}'),
walletfile_fs = str(wd.wallet_dir / f'{sid}-{{}}-{fn_stem}'),
addrfile_fs = str(wd.wallet_dir / f'{sid}-{{}}-{fn_stem}.address.txt'),
md = md,
md_rpc = md_rpc,
wd = wd,
@ -272,8 +261,7 @@ class CmdTestXMRWallet(CmdTestBase):
for user, data in self.users.items():
if not user in users:
continue
run(['mkdir', '-p', data.udir])
run(f'rm -f {data.kafile}', shell=True)
run(['mkdir', '-p', str(data.udir)])
t = self.spawn(
'mmgen-keygen',
['--quiet', '--accept-defaults', '--coin=xmr', f'--outdir={data.udir}']
@ -313,7 +301,8 @@ class CmdTestXMRWallet(CmdTestBase):
t = self.spawn(
'mmgen-xmrwallet',
self.extra_opts
+ ([f'--{user}', '--compat'] if self.compat else [f'--wallet-dir={data.udir}'])
+ [f'--{user}']
+ (['--compat'] if self.compat else [])
+ (self.autosign_opts if data.autosign else [])
+ add_opts
+ [op]
@ -330,7 +319,8 @@ class CmdTestXMRWallet(CmdTestBase):
'mmgen-xmrwallet',
self.extra_opts
+ (self.autosign_opts if do_autosign else [])
+ (['--alice', '--compat'] if self.compat else [f'--wallet-dir={data.udir}'])
+ ['--alice']
+ (['--compat'] if self.compat else [])
+ [f'--daemon=localhost:{data.md.rpc_port}']
+ (['--no-start-wallet-daemon'] if cfg in ('continue', 'stop') else [])
+ (['--no-stop-wallet-daemon'] if cfg in ('start', 'continue') else [])
@ -413,10 +403,11 @@ class CmdTestXMRWallet(CmdTestBase):
def set_label_user(self, user, label_spec, add_timestr_resp, expect, add_opts=[]):
data = self.users[user]
cmd_opts = [f'--wallet-dir={data.udir}', f'--daemon=localhost:{data.md.rpc_port}']
cmd_opts = [f'--daemon=localhost:{data.md.rpc_port}']
t = self.spawn(
'mmgen-xmrwallet',
self.extra_opts
+ [f'--{user}']
+ add_opts
+ cmd_opts
+ ['label', data.kafile, label_spec])
@ -451,7 +442,8 @@ class CmdTestXMRWallet(CmdTestBase):
t = self.spawn(
'mmgen-xmrwallet',
self.extra_opts
+ ([f'--{user}', '--compat'] if self.compat else [f'--wallet-dir={data.udir}'])
+ [f'--{user}']
+ (['--compat'] if self.compat else [f'--wallet-dir={data.twdir}']) # test --wallet-dir option
+ [f'--daemon=localhost:{data.md.rpc_port}']
+ (self.autosign_opts if data.autosign else [])
+ add_opts
@ -502,7 +494,8 @@ class CmdTestXMRWallet(CmdTestBase):
t = self.spawn(
'mmgen-xmrwallet',
self.extra_opts
+ ([f'--{user}', '--compat'] if self.compat else [f'--wallet-dir={data.udir}'])
+ [f'--{user}']
+ (['--compat'] if self.compat else [])
+ cmd_opts
+ add_opts
+ (self.autosign_opts if data.autosign else [])
@ -631,8 +624,8 @@ class CmdTestXMRWallet(CmdTestBase):
self.do_mount_online()
silence()
kal = (ViewKeyAddrList if data.autosign else KeyAddrList)(
cfg = self.cfg,
proto = self.proto,
cfg = data.cfg,
proto = data.cfg._proto,
infile = data.kafile,
skip_chksum_msg = True,
key_address_validity_check = False)
@ -853,7 +846,6 @@ class CmdTestXMRWallet(CmdTestBase):
def start_daemons(self):
for v in self.users.values():
run(['mkdir', '-p', v.daemon_datadir])
v.md.start()
if self.extra_daemons:
start_test_daemons(*self.extra_daemons, verbose=True)