ui, xmr: List of candidate remote XMR daemon urls can be set through the http ui
This commit is contained in:
		
							parent
							
								
									eff5235205
								
							
						
					
					
						commit
						b152150932
					
				@ -34,6 +34,7 @@ from .interface_xmr import XMRInterface
 | 
			
		||||
from .interface_passthrough_btc import PassthroughBTCInterface
 | 
			
		||||
 | 
			
		||||
from . import __version__
 | 
			
		||||
from .rpc_xmr import make_xmr_rpc2_func
 | 
			
		||||
from .util import (
 | 
			
		||||
    TemporaryError,
 | 
			
		||||
    pubkeyToAddress,
 | 
			
		||||
@ -377,6 +378,9 @@ class BasicSwap(BaseApp):
 | 
			
		||||
 | 
			
		||||
        if self.coin_clients[coin]['connection_type'] == 'rpc':
 | 
			
		||||
            if coin == Coins.XMR:
 | 
			
		||||
                if chain_client_settings.get('automatically_select_daemon', False):
 | 
			
		||||
                    self.selectXMRRemoteDaemon(coin)
 | 
			
		||||
 | 
			
		||||
                self.coin_clients[coin]['walletrpchost'] = chain_client_settings.get('walletrpchost', '127.0.0.1')
 | 
			
		||||
                self.coin_clients[coin]['walletrpcport'] = chain_client_settings.get('walletrpcport', chainparams[coin][self.chain]['walletrpcport'])
 | 
			
		||||
                if 'walletrpcpassword' in chain_client_settings:
 | 
			
		||||
@ -384,6 +388,41 @@ class BasicSwap(BaseApp):
 | 
			
		||||
                else:
 | 
			
		||||
                    raise ValueError('Missing XMR wallet rpc credentials.')
 | 
			
		||||
 | 
			
		||||
    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']
 | 
			
		||||
        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)
 | 
			
		||||
                test = rpc_cb2('get_height', timeout=20)['height']
 | 
			
		||||
                return True
 | 
			
		||||
            except Exception as e:
 | 
			
		||||
                self.log.warning(f'Failed to set XMR remote daemon to {rpchost}:{rpcport}, {e}')
 | 
			
		||||
        random.shuffle(remote_daemon_urls)
 | 
			
		||||
        for url in remote_daemon_urls:
 | 
			
		||||
            self.log.info(f'Trying url {url}.')
 | 
			
		||||
            try:
 | 
			
		||||
                rpchost, rpcport = url.rsplit(':', 1)
 | 
			
		||||
                rpc_cb2 = make_xmr_rpc2_func(rpcport, rpchost)
 | 
			
		||||
                test = rpc_cb2('get_height', timeout=20)['height']
 | 
			
		||||
                self.coin_clients[coin]['rpchost'] = rpchost
 | 
			
		||||
                self.coin_clients[coin]['rpcport'] = rpcport
 | 
			
		||||
                data = {
 | 
			
		||||
                    'rpchost': rpchost,
 | 
			
		||||
                    'rpcport': rpcport,
 | 
			
		||||
                }
 | 
			
		||||
                self.editSettings(self.coin_clients[coin]['name'], data)
 | 
			
		||||
                return True
 | 
			
		||||
            except Exception as e:
 | 
			
		||||
                self.log.warning(f'Failed to set XMR remote daemon to {url}, {e}')
 | 
			
		||||
 | 
			
		||||
        raise ValueError('Failed to select a working XMR daemon url.')
 | 
			
		||||
 | 
			
		||||
    def ci(self, coin):  # Coin interface
 | 
			
		||||
        if coin == Coins.PART_ANON:
 | 
			
		||||
            return self.coin_clients[Coins.PART]['interface_anon']
 | 
			
		||||
@ -4818,6 +4857,7 @@ class BasicSwap(BaseApp):
 | 
			
		||||
        with self.mxDB:
 | 
			
		||||
            settings_cc = self.settings['chainclients'][coin_name]
 | 
			
		||||
            settings_changed = False
 | 
			
		||||
            suggest_reboot = False
 | 
			
		||||
            if 'lookups' in data:
 | 
			
		||||
                if settings_cc.get('chain_lookups', 'local') != data['lookups']:
 | 
			
		||||
                    settings_changed = True
 | 
			
		||||
@ -4827,6 +4867,26 @@ class BasicSwap(BaseApp):
 | 
			
		||||
                            cc['chain_lookups'] = data['lookups']
 | 
			
		||||
                            break
 | 
			
		||||
 | 
			
		||||
            for setting in ('manage_daemon', 'rpchost', 'rpcport', 'automatically_select_daemon'):
 | 
			
		||||
                if setting not in data:
 | 
			
		||||
                    continue
 | 
			
		||||
                if settings_cc.get(setting) != data[setting]:
 | 
			
		||||
                    settings_changed = True
 | 
			
		||||
                    suggest_reboot = True
 | 
			
		||||
                    settings_cc[setting] = data[setting]
 | 
			
		||||
 | 
			
		||||
            if 'remotedaemonurls' in data:
 | 
			
		||||
                remotedaemonurls_in = data['remotedaemonurls'].split('\n')
 | 
			
		||||
                remotedaemonurls = set()
 | 
			
		||||
                for url in remotedaemonurls_in:
 | 
			
		||||
                    if url.count(':') > 0:
 | 
			
		||||
                        remotedaemonurls.add(url.strip())
 | 
			
		||||
 | 
			
		||||
                if set(settings_cc.get('remote_daemon_urls', [])) != remotedaemonurls:
 | 
			
		||||
                    settings_cc['remote_daemon_urls'] = list(remotedaemonurls)
 | 
			
		||||
                    settings_changed = True
 | 
			
		||||
                    suggest_reboot = True
 | 
			
		||||
 | 
			
		||||
            if 'fee_priority' in data:
 | 
			
		||||
                new_fee_priority = data['fee_priority']
 | 
			
		||||
                ensure(new_fee_priority >= 0 and new_fee_priority < 4, 'Invalid priority')
 | 
			
		||||
@ -4858,7 +4918,7 @@ class BasicSwap(BaseApp):
 | 
			
		||||
                shutil.copyfile(settings_path, settings_path + '.last')
 | 
			
		||||
                with open(settings_path, 'w') as fp:
 | 
			
		||||
                    json.dump(self.settings, fp, indent=4)
 | 
			
		||||
        return settings_changed
 | 
			
		||||
        return settings_changed, suggest_reboot
 | 
			
		||||
 | 
			
		||||
    def enableCoin(self, coin_name):
 | 
			
		||||
        self.log.info('Enabling coin %s', coin_name)
 | 
			
		||||
 | 
			
		||||
@ -388,26 +388,36 @@ class HttpHandler(BaseHTTPRequestHandler):
 | 
			
		||||
        form_data = self.checkForm(post_string, 'settings', messages)
 | 
			
		||||
        if form_data:
 | 
			
		||||
            for name, c in swap_client.settings['chainclients'].items():
 | 
			
		||||
                if bytes('apply_' + name, 'utf-8') in form_data:
 | 
			
		||||
                    data = {'lookups': form_data[bytes('lookups_' + name, 'utf-8')][0].decode('utf-8')}
 | 
			
		||||
                if have_data_entry(form_data, 'apply_' + name):
 | 
			
		||||
                    data = {'lookups': get_data_entry(form_data, 'lookups_' + name)}
 | 
			
		||||
                    if name == 'monero':
 | 
			
		||||
                        data['fee_priority'] = int(form_data[bytes('fee_priority_' + name, 'utf-8')][0])
 | 
			
		||||
                        data['fee_priority'] = int(get_data_entry(form_data, 'fee_priority_' + name))
 | 
			
		||||
                        data['manage_daemon'] = True if get_data_entry(form_data, 'managedaemon_' + name) == 'true' else False
 | 
			
		||||
                        data['rpchost'] = get_data_entry(form_data, 'rpchost_' + name)
 | 
			
		||||
                        data['rpcport'] = int(get_data_entry(form_data, 'rpcport_' + name))
 | 
			
		||||
                        data['remotedaemonurls'] = get_data_entry(form_data, 'remotedaemonurls_' + name)
 | 
			
		||||
                        data['automatically_select_daemon'] = True if get_data_entry(form_data, 'autosetdaemon_' + name) == 'true' else False
 | 
			
		||||
                    else:
 | 
			
		||||
                        data['conf_target'] = int(form_data[bytes('conf_target_' + name, 'utf-8')][0])
 | 
			
		||||
                        data['conf_target'] = int(get_data_entry(form_data, 'conf_target_' + name))
 | 
			
		||||
 | 
			
		||||
                    if swap_client.editSettings(name, data) is True:
 | 
			
		||||
                    settings_changed, suggest_reboot = swap_client.editSettings(name, data)
 | 
			
		||||
                    if settings_changed is True:
 | 
			
		||||
                        messages.append('Settings applied.')
 | 
			
		||||
                elif bytes('enable_' + name, 'utf-8') in form_data:
 | 
			
		||||
                    if suggest_reboot is True:
 | 
			
		||||
                        messages.append('Please restart BasicSwap.')
 | 
			
		||||
                elif have_data_entry(form_data, 'enable_' + name):
 | 
			
		||||
                    swap_client.enableCoin(name)
 | 
			
		||||
                    messages.append(name.capitalize() + ' enabled, shutting down.')
 | 
			
		||||
                    swap_client.stopRunning()
 | 
			
		||||
                elif bytes('disable_' + name, 'utf-8') in form_data:
 | 
			
		||||
                elif have_data_entry(form_data, 'disable_' + name):
 | 
			
		||||
                    swap_client.disableCoin(name)
 | 
			
		||||
                    messages.append(name.capitalize() + ' disabled, shutting down.')
 | 
			
		||||
                    swap_client.stopRunning()
 | 
			
		||||
        chains_formatted = []
 | 
			
		||||
 | 
			
		||||
        for name, c in swap_client.settings['chainclients'].items():
 | 
			
		||||
        sorted_names = sorted(swap_client.settings['chainclients'].keys())
 | 
			
		||||
        for name in sorted_names:
 | 
			
		||||
            c = swap_client.settings['chainclients'][name]
 | 
			
		||||
            chains_formatted.append({
 | 
			
		||||
                'name': name,
 | 
			
		||||
                'lookups': c.get('chain_lookups', 'local'),
 | 
			
		||||
@ -417,6 +427,10 @@ class HttpHandler(BaseHTTPRequestHandler):
 | 
			
		||||
            if name == 'monero':
 | 
			
		||||
                chains_formatted[-1]['fee_priority'] = c.get('fee_priority', 0)
 | 
			
		||||
                chains_formatted[-1]['manage_wallet_daemon'] = c.get('manage_wallet_daemon', 'Unknown')
 | 
			
		||||
                chains_formatted[-1]['rpchost'] = c.get('rpchost', 'localhost')
 | 
			
		||||
                chains_formatted[-1]['rpcport'] = int(c.get('rpcport', 18081))
 | 
			
		||||
                chains_formatted[-1]['remotedaemonurls'] = '\n'.join(c.get('remote_daemon_urls', []))
 | 
			
		||||
                chains_formatted[-1]['autosetdaemon'] = c.get('automatically_select_daemon', False)
 | 
			
		||||
            else:
 | 
			
		||||
                chains_formatted[-1]['conf_target'] = c.get('conf_target', 2)
 | 
			
		||||
            if name != 'particl':
 | 
			
		||||
 | 
			
		||||
@ -7,7 +7,10 @@ import requests
 | 
			
		||||
def callrpc_xmr(rpc_port, auth, method, params=[], rpc_host='127.0.0.1', path='json_rpc', timeout=120):
 | 
			
		||||
    # auth is a tuple: (username, password)
 | 
			
		||||
    try:
 | 
			
		||||
        url = 'http://{}:{}/{}'.format(rpc_host, rpc_port, path)
 | 
			
		||||
        if rpc_host.count('://') > 0:
 | 
			
		||||
            url = '{}:{}/{}'.format(rpc_host, rpc_port, path)
 | 
			
		||||
        else:
 | 
			
		||||
            url = 'http://{}:{}/{}'.format(rpc_host, rpc_port, path)
 | 
			
		||||
        request_body = {
 | 
			
		||||
            'method': method,
 | 
			
		||||
            'params': params,
 | 
			
		||||
@ -30,7 +33,10 @@ def callrpc_xmr(rpc_port, auth, method, params=[], rpc_host='127.0.0.1', path='j
 | 
			
		||||
 | 
			
		||||
def callrpc_xmr_na(rpc_port, method, params=[], rpc_host='127.0.0.1', path='json_rpc', timeout=120):
 | 
			
		||||
    try:
 | 
			
		||||
        url = 'http://{}:{}/{}'.format(rpc_host, rpc_port, path)
 | 
			
		||||
        if rpc_host.count('://') > 0:
 | 
			
		||||
            url = '{}:{}/{}'.format(rpc_host, rpc_port, path)
 | 
			
		||||
        else:
 | 
			
		||||
            url = 'http://{}:{}/{}'.format(rpc_host, rpc_port, path)
 | 
			
		||||
        request_body = {
 | 
			
		||||
            'method': method,
 | 
			
		||||
            'params': params,
 | 
			
		||||
@ -53,7 +59,10 @@ def callrpc_xmr_na(rpc_port, method, params=[], rpc_host='127.0.0.1', path='json
 | 
			
		||||
 | 
			
		||||
def callrpc_xmr2(rpc_port, method, params=None, rpc_host='127.0.0.1', timeout=120):
 | 
			
		||||
    try:
 | 
			
		||||
        url = 'http://{}:{}/{}'.format(rpc_host, rpc_port, method)
 | 
			
		||||
        if rpc_host.count('://') > 0:
 | 
			
		||||
            url = '{}:{}/{}'.format(rpc_host, rpc_port, method)
 | 
			
		||||
        else:
 | 
			
		||||
            url = 'http://{}:{}/{}'.format(rpc_host, rpc_port, method)
 | 
			
		||||
        headers = {
 | 
			
		||||
            'Content-Type': 'application/json'
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
@ -15,8 +15,31 @@
 | 
			
		||||
<tr><td>Connection Type</td><td>{{ c.connection_type }}</td></tr>
 | 
			
		||||
{% endif %}
 | 
			
		||||
{% if c.manage_daemon is defined %}
 | 
			
		||||
{% if c.name == 'monero' %}
 | 
			
		||||
<tr><td>Manage Daemon</td><td>
 | 
			
		||||
<select name="managedaemon_{{ c.name }}">
 | 
			
		||||
<option value="true"{% if c.manage_daemon==true %} selected{% endif %}>True</option>
 | 
			
		||||
<option value="false"{% if c.manage_daemon==false %} selected{% endif %}>False</option>
 | 
			
		||||
</select></td></tr>
 | 
			
		||||
<tr><td>Daemon RPC Host</td><td><input type="text" name="rpchost_{{ c.name }}" value="{{ c.rpchost }}"></td></tr>
 | 
			
		||||
<tr><td>Daemon RPC Port</td><td><input type="text" name="rpcport_{{ c.name }}" value="{{ c.rpcport }}"></td></tr>
 | 
			
		||||
<tr><td colspan=2>Remote Daemon Urls<br/>
 | 
			
		||||
List of public nodes to use if "Automatically Select Daemon" is true.<br/>
 | 
			
		||||
Add one entry per line, eg:<br/>
 | 
			
		||||
node.xmr.to:18081<br/>
 | 
			
		||||
<textarea class="monospace" name="remotedaemonurls_{{ c.name }}" rows="10" cols="100">
 | 
			
		||||
{{ c.remotedaemonurls }}
 | 
			
		||||
</textarea>
 | 
			
		||||
</td></tr>
 | 
			
		||||
<tr><td>Automatically Select Daemon</td><td>
 | 
			
		||||
<select name="autosetdaemon_{{ c.name }}">
 | 
			
		||||
<option value="true"{% if c.autosetdaemon==true %} selected{% endif %}>True</option>
 | 
			
		||||
<option value="false"{% if c.autosetdaemon==false %} selected{% endif %}>False</option>
 | 
			
		||||
</select></td></tr>
 | 
			
		||||
{% else %}
 | 
			
		||||
<tr><td>Manage Daemon</td><td>{{ c.manage_daemon }}</td></tr>
 | 
			
		||||
{% endif %}
 | 
			
		||||
{% endif %}
 | 
			
		||||
{% if c.manage_wallet_daemon is defined %}
 | 
			
		||||
<tr><td>Manage Wallet Daemon</td><td>{{ c.manage_wallet_daemon }}</td></tr>
 | 
			
		||||
{% endif %}
 | 
			
		||||
 | 
			
		||||
@ -9,6 +9,8 @@
 | 
			
		||||
- xmrswaps:
 | 
			
		||||
  - Setting state to 'Script tx redeemed' will trigger an attempt to redeem the scriptless lock tx.
 | 
			
		||||
  - Node will wait for the chain B lock tx to reach a spendable depth before attempting to spend.
 | 
			
		||||
- ui: Sort settings page by coin name.
 | 
			
		||||
- ui, xmr: List of candidate remote XMR daemon urls can be set through the http ui
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
0.0.25
 | 
			
		||||
 | 
			
		||||
		Loading…
	
		Reference in New Issue
	
	Block a user