From 2a35148a4ba9adc81e1521e9c312a35d5291ead6 Mon Sep 17 00:00:00 2001 From: tecnovert Date: Mon, 28 Nov 2022 19:54:41 +0200 Subject: [PATCH] xmr: Support daemon rpc login details. --- basicswap/__init__.py | 2 +- basicswap/basicswap.py | 20 ++++-- basicswap/chainparams.py | 2 + basicswap/interface/xmr.py | 12 ++-- basicswap/rpc_xmr.py | 69 ++++++------------- bin/basicswap_prepare.py | 8 +++ bin/basicswap_run.py | 7 +- doc/notes.md | 56 +++++++++++++++ tests/basicswap/common_xmr.py | 24 ++++--- .../basicswap/extended/test_xmr_persistent.py | 10 +-- tests/basicswap/test_xmr.py | 15 ++-- 11 files changed, 144 insertions(+), 81 deletions(-) diff --git a/basicswap/__init__.py b/basicswap/__init__.py index 1eb8ad0..16d515c 100644 --- a/basicswap/__init__.py +++ b/basicswap/__init__.py @@ -1,3 +1,3 @@ name = "basicswap" -__version__ = "0.11.49" +__version__ = "0.11.50" diff --git a/basicswap/basicswap.py b/basicswap/basicswap.py index 8771c75..48b105e 100644 --- a/basicswap/basicswap.py +++ b/basicswap/basicswap.py @@ -467,17 +467,25 @@ class BasicSwap(BaseApp): else: raise ValueError('Missing XMR wallet rpc credentials.') + self.coin_clients[coin]['rpcuser'] = chain_client_settings.get('rpcuser', '') + self.coin_clients[coin]['rpcpassword'] = chain_client_settings.get('rpcpassword', '') + def selectXMRRemoteDaemon(self, coin): self.log.info('Selecting remote XMR daemon.') chain_client_settings = self.getChainClientSettings(coin) remote_daemon_urls = chain_client_settings.get('remote_daemon_urls', []) - rpchost = self.coin_clients[coin]['rpchost'] - rpcport = self.coin_clients[coin]['rpcport'] + + coin_settings = self.coin_clients[coin] + rpchost = coin_settings['rpchost'] + rpcport = coin_settings['rpcport'] + daemon_login = None + if coin_settings.get('rpcuser', '') != '': + daemon_login = (coin_settings.get('rpcuser', ''), coin_settings.get('rpcpassword', '')) current_daemon_url = f'{rpchost}:{rpcport}' if current_daemon_url in remote_daemon_urls: self.log.info(f'Trying last used url {rpchost}:{rpcport}.') try: - rpc_cb2 = make_xmr_rpc2_func(rpcport, rpchost) + rpc_cb2 = make_xmr_rpc2_func(rpcport, daemon_login, rpchost) test = rpc_cb2('get_height', timeout=20)['height'] return True except Exception as e: @@ -487,10 +495,10 @@ class BasicSwap(BaseApp): self.log.info(f'Trying url {url}.') try: rpchost, rpcport = url.rsplit(':', 1) - rpc_cb2 = make_xmr_rpc2_func(rpcport, rpchost) + rpc_cb2 = make_xmr_rpc2_func(rpcport, daemon_login, rpchost) test = rpc_cb2('get_height', timeout=20)['height'] - self.coin_clients[coin]['rpchost'] = rpchost - self.coin_clients[coin]['rpcport'] = rpcport + coin_settings['rpchost'] = rpchost + coin_settings['rpcport'] = rpcport data = { 'rpchost': rpchost, 'rpcport': rpcport, diff --git a/basicswap/chainparams.py b/basicswap/chainparams.py index 966a51a..0d20bb7 100644 --- a/basicswap/chainparams.py +++ b/basicswap/chainparams.py @@ -411,6 +411,8 @@ class CoinInterface: str_error = str(ex).lower() if 'not enough unlocked money' in str_error: return True + if 'No unlocked balance' in str_error: + return True if 'transaction was rejected by daemon' in str_error: return True if 'invalid unlocked_balance' in str_error: diff --git a/basicswap/interface/xmr.py b/basicswap/interface/xmr.py index f472052..dc2b9c8 100644 --- a/basicswap/interface/xmr.py +++ b/basicswap/interface/xmr.py @@ -31,8 +31,7 @@ from basicswap.util import ( TemporaryError) from basicswap.rpc_xmr import ( make_xmr_rpc_func, - make_xmr_rpc2_func, - make_xmr_wallet_rpc_func) + make_xmr_rpc2_func) from basicswap.util import ( b2i, b2h) from basicswap.chainparams import XMR_COIN, CoinInterface, Coins @@ -65,9 +64,12 @@ class XMRInterface(CoinInterface): def __init__(self, coin_settings, network, swap_client=None): super().__init__(network) - self.rpc_cb = make_xmr_rpc_func(coin_settings['rpcport'], host=coin_settings.get('rpchost', '127.0.0.1')) - self.rpc_cb2 = make_xmr_rpc2_func(coin_settings['rpcport'], host=coin_settings.get('rpchost', '127.0.0.1')) # non-json endpoint - self.rpc_wallet_cb = make_xmr_wallet_rpc_func(coin_settings['walletrpcport'], coin_settings['walletrpcauth'], host=coin_settings.get('walletrpchost', '127.0.0.1')) + daemon_login = None + if coin_settings.get('rpcuser', '') != '': + daemon_login = (coin_settings.get('rpcuser', ''), coin_settings.get('rpcpassword', '')) + self.rpc_cb = make_xmr_rpc_func(coin_settings['rpcport'], daemon_login, host=coin_settings.get('rpchost', '127.0.0.1')) + self.rpc_cb2 = make_xmr_rpc2_func(coin_settings['rpcport'], daemon_login, host=coin_settings.get('rpchost', '127.0.0.1')) # non-json endpoint + self.rpc_wallet_cb = make_xmr_rpc_func(coin_settings['walletrpcport'], coin_settings['walletrpcauth'], host=coin_settings.get('walletrpchost', '127.0.0.1')) self.blocks_confirmed = coin_settings['blocks_confirmed'] self._restore_height = coin_settings.get('restore_height', 0) diff --git a/basicswap/rpc_xmr.py b/basicswap/rpc_xmr.py index 4fe2c99..483b703 100644 --- a/basicswap/rpc_xmr.py +++ b/basicswap/rpc_xmr.py @@ -159,7 +159,7 @@ class JsonrpcDigest(): raise -def callrpc_xmr(rpc_port, auth, method, params=[], rpc_host='127.0.0.1', path='json_rpc', timeout=120): +def callrpc_xmr(rpc_port, method, params=[], rpc_host='127.0.0.1', path='json_rpc', auth=None, timeout=120): # auth is a tuple: (username, password) try: if rpc_host.count('://') > 0: @@ -168,27 +168,10 @@ def callrpc_xmr(rpc_port, auth, method, params=[], rpc_host='127.0.0.1', path='j url = 'http://{}:{}/{}'.format(rpc_host, rpc_port, path) x = JsonrpcDigest(url) - v = x.json_request(method, params, username=auth[0], password=auth[1], timeout=timeout) - x.close() - r = json.loads(v.decode('utf-8')) - except Exception as ex: - raise ValueError('RPC Server Error: {}'.format(str(ex))) - - if 'error' in r and r['error'] is not None: - raise ValueError('RPC error ' + str(r['error'])) - - return r['result'] - - -def callrpc_xmr_na(rpc_port, method, params=[], rpc_host='127.0.0.1', path='json_rpc', timeout=120): - try: - if rpc_host.count('://') > 0: - url = '{}:{}/{}'.format(rpc_host, rpc_port, path) + if auth: + v = x.json_request(method, params, username=auth[0], password=auth[1], timeout=timeout) else: - url = 'http://{}:{}/{}'.format(rpc_host, rpc_port, path) - - x = JsonrpcDigest(url) - v = x.json_request(method, params, timeout=timeout) + v = x.json_request(method, params, timeout=timeout) x.close() r = json.loads(v.decode('utf-8')) except Exception as ex: @@ -200,7 +183,7 @@ def callrpc_xmr_na(rpc_port, method, params=[], rpc_host='127.0.0.1', path='json return r['result'] -def callrpc_xmr2(rpc_port, method, params=None, rpc_host='127.0.0.1', timeout=120): +def callrpc_xmr2(rpc_port, method, params=None, auth=None, rpc_host='127.0.0.1', timeout=120): try: if rpc_host.count('://') > 0: url = '{}:{}/{}'.format(rpc_host, rpc_port, method) @@ -208,7 +191,10 @@ def callrpc_xmr2(rpc_port, method, params=None, rpc_host='127.0.0.1', timeout=12 url = 'http://{}:{}/{}'.format(rpc_host, rpc_port, method) x = JsonrpcDigest(url) - v = x.post_request(method, params, timeout=timeout) + if auth: + v = x.json_request(method, params, username=auth[0], password=auth[1], timeout=timeout) + else: + v = x.json_request(method, params, timeout=timeout) x.close() r = json.loads(v.decode('utf-8')) except Exception as ex: @@ -217,34 +203,23 @@ def callrpc_xmr2(rpc_port, method, params=None, rpc_host='127.0.0.1', timeout=12 return r -def make_xmr_rpc_func(port, host='127.0.0.1'): - port = port - host = host - - def rpc_func(method, params=None, wallet=None, timeout=120): - nonlocal port - nonlocal host - return callrpc_xmr_na(port, method, params, rpc_host=host, timeout=timeout) - return rpc_func - - -def make_xmr_rpc2_func(port, host='127.0.0.1'): - port = port - host = host - - def rpc_func(method, params=None, wallet=None, timeout=120): - nonlocal port - nonlocal host - return callrpc_xmr2(port, method, params, rpc_host=host, timeout=timeout) - return rpc_func - - -def make_xmr_wallet_rpc_func(port, auth, host='127.0.0.1'): +def make_xmr_rpc2_func(port, auth, host='127.0.0.1'): port = port auth = auth host = host def rpc_func(method, params=None, wallet=None, timeout=120): nonlocal port, auth, host - return callrpc_xmr(port, auth, method, params, rpc_host=host, timeout=timeout) + return callrpc_xmr2(port, method, params, auth=auth, rpc_host=host, timeout=timeout) + return rpc_func + + +def make_xmr_rpc_func(port, auth, host='127.0.0.1'): + port = port + auth = auth + host = host + + def rpc_func(method, params=None, wallet=None, timeout=120): + nonlocal port, auth, host + return callrpc_xmr(port, method, params, rpc_host=host, auth=auth, timeout=timeout) return rpc_func diff --git a/bin/basicswap_prepare.py b/bin/basicswap_prepare.py index c1863a0..6b2f092 100755 --- a/bin/basicswap_prepare.py +++ b/bin/basicswap_prepare.py @@ -116,6 +116,8 @@ BASE_XMR_WALLET_PORT = int(os.getenv('BASE_XMR_WALLET_PORT', 29998)) XMR_WALLET_RPC_HOST = os.getenv('XMR_WALLET_RPC_HOST', '127.0.0.1') XMR_WALLET_RPC_USER = os.getenv('XMR_WALLET_RPC_USER', 'xmr_wallet_user') XMR_WALLET_RPC_PWD = os.getenv('XMR_WALLET_RPC_PWD', 'xmr_wallet_pwd') +XMR_RPC_USER = os.getenv('XMR_RPC_USER', '') +XMR_RPC_PWD = os.getenv('XMR_RPC_PWD', '') DEFAULT_XMR_RESTORE_HEIGHT = int(os.getenv('DEFAULT_XMR_RESTORE_HEIGHT', 2245107)) LTC_RPC_HOST = os.getenv('LTC_RPC_HOST', '127.0.0.1') @@ -631,6 +633,9 @@ def prepareDataDir(coin, settings, chain, particl_mnemonic, extra_opts={}): fp.write('proxy-allow-dns-leaks=0\n') fp.write('no-igd=1\n') + if XMR_RPC_USER != '': + fp.write(f'rpc-login={XMR_RPC_USER}:{XMR_RPC_PWD}\n') + wallets_dir = core_settings.get('walletsdir', data_dir) if not os.path.exists(wallets_dir): os.makedirs(wallets_dir) @@ -1339,6 +1344,9 @@ def main(): if BTC_RPC_USER != '': chainclients['bitcoin']['rpcuser'] = BTC_RPC_USER chainclients['bitcoin']['rpcpassword'] = BTC_RPC_PWD + if XMR_RPC_USER != '': + chainclients['monero']['rpcuser'] = XMR_RPC_USER + chainclients['monero']['rpcpassword'] = XMR_RPC_PWD if PIVX_RPC_USER != '': chainclients['pivx']['rpcuser'] = PIVX_RPC_USER chainclients['pivx']['rpcpassword'] = PIVX_RPC_PWD diff --git a/bin/basicswap_run.py b/bin/basicswap_run.py index 8288fda..4606155 100755 --- a/bin/basicswap_run.py +++ b/bin/basicswap_run.py @@ -1,7 +1,7 @@ #!/usr/bin/env python3 # -*- coding: utf-8 -*- -# Copyright (c) 2019-2020 tecnovert +# Copyright (c) 2019-2022 tecnovert # Distributed under the MIT software license, see the accompanying # file LICENSE or http://www.opensource.org/licenses/mit-license.php. @@ -162,6 +162,11 @@ def runClient(fp, data_dir, chain): daemon_addr = '{}:{}'.format(v['rpchost'], v['rpcport']) swap_client.log.info('daemon-address: {}'.format(daemon_addr)) opts = ['--daemon-address', daemon_addr, ] + daemon_rpcuser = v.get('rpcuser', '') + daemon_rpcpass = v.get('rpcpassword', '') + if daemon_rpcuser != '': + opts.append('--daemon-login') + opts.append(daemon_rpcuser + ':' + daemon_rpcpass) daemons.append(startXmrWalletDaemon(v['datadir'], v['bindir'], 'monero-wallet-rpc', opts)) pid = daemons[-1].pid swap_client.log.info('Started {} {}'.format('monero-wallet-rpc', pid)) diff --git a/doc/notes.md b/doc/notes.md index 0484784..a35da73 100644 --- a/doc/notes.md +++ b/doc/notes.md @@ -1,4 +1,60 @@ +## Monero remote private node without ssh tunneling + +Example connecting a basicswap instance running on a local node to a private +remote monero node running at 192.168.1.9 with rpc username and password: +test_user:test_pwd + +Set the following in basicswap.json: + +In chainclients.monero: +- connection_type - rpc +- manage_daemon - false +- manage_wallet_daemon - true +- rpchost - ip of remote monero node (192.168.1.9) +- rpcport - rpcport that monero is listening on remote node (18081) +- rpcuser - test_user +- rpcpassword - test_pwd + + +Edit monerod.conf on the remote node: + + data-dir=PATH_TO_MONERO_DATADIR + restricted-rpc=1 + rpc-login=test_user:test_pwd + rpc-bind-port=18081 + rpc-bind-ip=192.168.1.9 + prune-blockchain=1 + +Start the remote monerod binary with `--confirm-external-bind` + +Remember to open port 18081 in the remote machine's firewall if necessary. + +You can debug the connection using curl (from the local node) + + curl http://192.168.1.9:18081/json_rpc -u test_user:test_pwd --digest -d '{"jsonrpc":"2.0","id":"0","method":"get_info"}' -H 'Content-Type: application/json' + + +## Monero remote private node with ssh tunneling + +Example connecting to a private remote monero node running at 192.168.1.9 + +Set the following in basicswap.json: + +In chainclients.monero: +- connection_type - rpc +- manage_daemon - false +- manage_wallet_daemon - true +- rpchost - localhost +- rpcport - rpcport that monero is listening on remote node (18081) + +On the remote machine open an ssh tunnel to port 18081: + + ssh -R 18081:localhost:18081 -N user@LOCAL_NODE_IP + +And start monerod + + ## Run One Test ``` diff --git a/tests/basicswap/common_xmr.py b/tests/basicswap/common_xmr.py index 681b74a..16b0063 100644 --- a/tests/basicswap/common_xmr.py +++ b/tests/basicswap/common_xmr.py @@ -19,7 +19,7 @@ from urllib.request import urlopen from unittest.mock import patch from basicswap.rpc_xmr import ( - callrpc_xmr_na, + callrpc_xmr, ) from tests.basicswap.mnemonics import mnemonics from tests.basicswap.util import ( @@ -63,10 +63,10 @@ def waitForBidState(delay_event, port, bid_id, state_str, wait_for=60): raise ValueError('waitForBidState failed') -def updateThread(xmr_addr, delay_event): +def updateThread(xmr_addr, delay_event, xmr_auth): while not delay_event.is_set(): try: - callrpc_xmr_na(XMR_BASE_RPC_PORT + 1, 'generateblocks', {'wallet_address': xmr_addr, 'amount_of_blocks': 1}) + callrpc_xmr(XMR_BASE_RPC_PORT + 1, 'generateblocks', {'wallet_address': xmr_addr, 'amount_of_blocks': 1}, auth=xmr_auth) except Exception as e: print('updateThread error', str(e)) delay_event.wait(2) @@ -85,6 +85,10 @@ def run_prepare(node_id, datadir_path, bins_path, with_coins, mnemonic_in=None, os.environ['PART_RPC_PORT'] = str(PARTICL_RPC_PORT_BASE) os.environ['BTC_RPC_PORT'] = str(BITCOIN_RPC_PORT_BASE) + + os.environ['XMR_RPC_USER'] = 'xmr_user' + os.environ['XMR_RPC_PWD'] = 'xmr_pwd' + import bin.basicswap_prepare as prepareSystem # Hack: Reload module to set env vars as the basicswap_prepare module is initialised if imported from elsewhere earlier from importlib import reload @@ -333,12 +337,16 @@ class XmrTestBase(TestBase): num_blocks = 100 - if callrpc_xmr_na(XMR_BASE_RPC_PORT + 1, 'get_block_count')['count'] < num_blocks: - logging.info('Mining {} Monero blocks to {}.'.format(num_blocks, xmr_addr1)) - callrpc_xmr_na(XMR_BASE_RPC_PORT + 1, 'generateblocks', {'wallet_address': xmr_addr1, 'amount_of_blocks': num_blocks}) - logging.info('XMR blocks: %d', callrpc_xmr_na(XMR_BASE_RPC_PORT + 1, 'get_block_count')['count']) + xmr_auth = None + if os.getenv('XMR_RPC_USER', '') != '': + xmr_auth = (os.getenv('XMR_RPC_USER', ''), os.getenv('XMR_RPC_PWD', '')) - self.update_thread = threading.Thread(target=updateThread, args=(xmr_addr1, self.delay_event)) + if callrpc_xmr(XMR_BASE_RPC_PORT + 1, 'get_block_count', auth=xmr_auth)['count'] < num_blocks: + logging.info('Mining {} Monero blocks to {}.'.format(num_blocks, xmr_addr1)) + callrpc_xmr(XMR_BASE_RPC_PORT + 1, 'generateblocks', {'wallet_address': xmr_addr1, 'amount_of_blocks': num_blocks}, auth=xmr_auth) + logging.info('XMR blocks: %d', callrpc_xmr(XMR_BASE_RPC_PORT + 1, 'get_block_count', auth=xmr_auth)['count']) + + self.update_thread = threading.Thread(target=updateThread, args=(xmr_addr1, self.delay_event, xmr_auth)) self.update_thread.start() # Wait for height, or sequencelock is thrown off by genesis blocktime diff --git a/tests/basicswap/extended/test_xmr_persistent.py b/tests/basicswap/extended/test_xmr_persistent.py index a2ac776..dc4e385 100644 --- a/tests/basicswap/extended/test_xmr_persistent.py +++ b/tests/basicswap/extended/test_xmr_persistent.py @@ -28,7 +28,7 @@ import multiprocessing from unittest.mock import patch from basicswap.rpc_xmr import ( - callrpc_xmr_na, + callrpc_xmr, ) from basicswap.rpc import ( callrpc, @@ -93,7 +93,7 @@ def updateThreadXmr(cls): while not cls.delay_event.is_set(): try: if cls.xmr_addr is not None: - callrpc_xmr_na(XMR_BASE_RPC_PORT + 1, 'generateblocks', {'wallet_address': cls.xmr_addr, 'amount_of_blocks': 1}) + callrpc_xmr(XMR_BASE_RPC_PORT + 1, 'generateblocks', {'wallet_address': cls.xmr_addr, 'amount_of_blocks': 1}) except Exception as e: print('updateThreadXmr error', str(e)) cls.delay_event.wait(random.randrange(cls.xmr_update_min, cls.xmr_update_max)) @@ -151,10 +151,10 @@ class Test(unittest.TestCase): self.xmr_addr = wallets['XMR']['main_address'] num_blocks = 100 - if callrpc_xmr_na(XMR_BASE_RPC_PORT + 1, 'get_block_count')['count'] < num_blocks: + if callrpc_xmr(XMR_BASE_RPC_PORT + 1, 'get_block_count')['count'] < num_blocks: logging.info('Mining {} Monero blocks to {}.'.format(num_blocks, self.xmr_addr)) - callrpc_xmr_na(XMR_BASE_RPC_PORT + 1, 'generateblocks', {'wallet_address': self.xmr_addr, 'amount_of_blocks': num_blocks}) - logging.info('XMR blocks: %d', callrpc_xmr_na(XMR_BASE_RPC_PORT + 1, 'get_block_count')['count']) + callrpc_xmr(XMR_BASE_RPC_PORT + 1, 'generateblocks', {'wallet_address': self.xmr_addr, 'amount_of_blocks': num_blocks}) + logging.info('XMR blocks: %d', callrpc_xmr(XMR_BASE_RPC_PORT + 1, 'get_block_count')['count']) self.btc_addr = callbtcrpc(0, 'getnewaddress', ['mining_addr', 'bech32']) num_blocks = 500 # Mine enough to activate segwit diff --git a/tests/basicswap/test_xmr.py b/tests/basicswap/test_xmr.py index fe85b5a..4812707 100644 --- a/tests/basicswap/test_xmr.py +++ b/tests/basicswap/test_xmr.py @@ -46,7 +46,6 @@ from basicswap.rpc import ( ) from basicswap.rpc_xmr import ( callrpc_xmr, - callrpc_xmr_na, ) from basicswap.interface.xmr import ( XMR_COIN, @@ -256,7 +255,7 @@ def signal_handler(sig, frame): def waitForXMRNode(rpc_offset, max_tries=7): for i in range(max_tries + 1): try: - callrpc_xmr_na(XMR_BASE_RPC_PORT + rpc_offset, 'get_block_count') + callrpc_xmr(XMR_BASE_RPC_PORT + rpc_offset, 'get_block_count') return except Exception as ex: if i < max_tries: @@ -268,7 +267,7 @@ def waitForXMRNode(rpc_offset, max_tries=7): def waitForXMRWallet(rpc_offset, auth, max_tries=7): for i in range(max_tries + 1): try: - callrpc_xmr(XMR_BASE_WALLET_RPC_PORT + rpc_offset, auth, 'get_languages') + callrpc_xmr(XMR_BASE_WALLET_RPC_PORT + rpc_offset, 'get_languages', auth=auth) return except Exception as ex: if i < max_tries: @@ -549,10 +548,10 @@ class BaseTest(unittest.TestCase): num_blocks = 100 if cls.start_xmr_nodes: cls.xmr_addr = cls.callxmrnodewallet(cls, 1, 'get_address')['address'] - if callrpc_xmr_na(XMR_BASE_RPC_PORT + 1, 'get_block_count')['count'] < num_blocks: + if callrpc_xmr(XMR_BASE_RPC_PORT + 1, 'get_block_count')['count'] < num_blocks: logging.info('Mining %d Monero blocks to %s.', num_blocks, cls.xmr_addr) - callrpc_xmr_na(XMR_BASE_RPC_PORT + 1, 'generateblocks', {'wallet_address': cls.xmr_addr, 'amount_of_blocks': num_blocks}) - logging.info('XMR blocks: %d', callrpc_xmr_na(XMR_BASE_RPC_PORT + 1, 'get_block_count')['count']) + callrpc_xmr(XMR_BASE_RPC_PORT + 1, 'generateblocks', {'wallet_address': cls.xmr_addr, 'amount_of_blocks': num_blocks}) + logging.info('XMR blocks: %d', callrpc_xmr(XMR_BASE_RPC_PORT + 1, 'get_block_count')['count']) logging.info('Adding anon outputs') outputs = [] @@ -634,7 +633,7 @@ class BaseTest(unittest.TestCase): if cls.ltc_addr is not None: ltcCli('generatetoaddress 1 {}'.format(cls.ltc_addr)) if cls.xmr_addr is not None: - callrpc_xmr_na(XMR_BASE_RPC_PORT + 1, 'generateblocks', {'wallet_address': cls.xmr_addr, 'amount_of_blocks': 1}) + callrpc_xmr(XMR_BASE_RPC_PORT + 1, 'generateblocks', {'wallet_address': cls.xmr_addr, 'amount_of_blocks': 1}) @classmethod def waitForParticlHeight(cls, num_blocks, node_id=0): @@ -651,7 +650,7 @@ class BaseTest(unittest.TestCase): assert particl_blocks >= num_blocks def callxmrnodewallet(self, node_id, method, params=None): - return callrpc_xmr(XMR_BASE_WALLET_RPC_PORT + node_id, self.xmr_wallet_auth[node_id], method, params) + return callrpc_xmr(XMR_BASE_WALLET_RPC_PORT + node_id, method, params, auth=self.xmr_wallet_auth[node_id]) def getXmrBalance(self, js_wallets): return float(js_wallets[Coins.XMR.name]['unconfirmed']) + float(js_wallets[Coins.XMR.name]['balance'])