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 .interface_passthrough_btc import PassthroughBTCInterface
|
||||||
|
|
||||||
from . import __version__
|
from . import __version__
|
||||||
|
from .rpc_xmr import make_xmr_rpc2_func
|
||||||
from .util import (
|
from .util import (
|
||||||
TemporaryError,
|
TemporaryError,
|
||||||
pubkeyToAddress,
|
pubkeyToAddress,
|
||||||
@ -377,6 +378,9 @@ class BasicSwap(BaseApp):
|
|||||||
|
|
||||||
if self.coin_clients[coin]['connection_type'] == 'rpc':
|
if self.coin_clients[coin]['connection_type'] == 'rpc':
|
||||||
if coin == Coins.XMR:
|
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]['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'])
|
self.coin_clients[coin]['walletrpcport'] = chain_client_settings.get('walletrpcport', chainparams[coin][self.chain]['walletrpcport'])
|
||||||
if 'walletrpcpassword' in chain_client_settings:
|
if 'walletrpcpassword' in chain_client_settings:
|
||||||
@ -384,6 +388,41 @@ class BasicSwap(BaseApp):
|
|||||||
else:
|
else:
|
||||||
raise ValueError('Missing XMR wallet rpc credentials.')
|
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
|
def ci(self, coin): # Coin interface
|
||||||
if coin == Coins.PART_ANON:
|
if coin == Coins.PART_ANON:
|
||||||
return self.coin_clients[Coins.PART]['interface_anon']
|
return self.coin_clients[Coins.PART]['interface_anon']
|
||||||
@ -4818,6 +4857,7 @@ class BasicSwap(BaseApp):
|
|||||||
with self.mxDB:
|
with self.mxDB:
|
||||||
settings_cc = self.settings['chainclients'][coin_name]
|
settings_cc = self.settings['chainclients'][coin_name]
|
||||||
settings_changed = False
|
settings_changed = False
|
||||||
|
suggest_reboot = False
|
||||||
if 'lookups' in data:
|
if 'lookups' in data:
|
||||||
if settings_cc.get('chain_lookups', 'local') != data['lookups']:
|
if settings_cc.get('chain_lookups', 'local') != data['lookups']:
|
||||||
settings_changed = True
|
settings_changed = True
|
||||||
@ -4827,6 +4867,26 @@ class BasicSwap(BaseApp):
|
|||||||
cc['chain_lookups'] = data['lookups']
|
cc['chain_lookups'] = data['lookups']
|
||||||
break
|
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:
|
if 'fee_priority' in data:
|
||||||
new_fee_priority = data['fee_priority']
|
new_fee_priority = data['fee_priority']
|
||||||
ensure(new_fee_priority >= 0 and new_fee_priority < 4, 'Invalid 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')
|
shutil.copyfile(settings_path, settings_path + '.last')
|
||||||
with open(settings_path, 'w') as fp:
|
with open(settings_path, 'w') as fp:
|
||||||
json.dump(self.settings, fp, indent=4)
|
json.dump(self.settings, fp, indent=4)
|
||||||
return settings_changed
|
return settings_changed, suggest_reboot
|
||||||
|
|
||||||
def enableCoin(self, coin_name):
|
def enableCoin(self, coin_name):
|
||||||
self.log.info('Enabling coin %s', 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)
|
form_data = self.checkForm(post_string, 'settings', messages)
|
||||||
if form_data:
|
if form_data:
|
||||||
for name, c in swap_client.settings['chainclients'].items():
|
for name, c in swap_client.settings['chainclients'].items():
|
||||||
if bytes('apply_' + name, 'utf-8') in form_data:
|
if have_data_entry(form_data, 'apply_' + name):
|
||||||
data = {'lookups': form_data[bytes('lookups_' + name, 'utf-8')][0].decode('utf-8')}
|
data = {'lookups': get_data_entry(form_data, 'lookups_' + name)}
|
||||||
if name == 'monero':
|
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:
|
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.')
|
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)
|
swap_client.enableCoin(name)
|
||||||
messages.append(name.capitalize() + ' enabled, shutting down.')
|
messages.append(name.capitalize() + ' enabled, shutting down.')
|
||||||
swap_client.stopRunning()
|
swap_client.stopRunning()
|
||||||
elif bytes('disable_' + name, 'utf-8') in form_data:
|
elif have_data_entry(form_data, 'disable_' + name):
|
||||||
swap_client.disableCoin(name)
|
swap_client.disableCoin(name)
|
||||||
messages.append(name.capitalize() + ' disabled, shutting down.')
|
messages.append(name.capitalize() + ' disabled, shutting down.')
|
||||||
swap_client.stopRunning()
|
swap_client.stopRunning()
|
||||||
chains_formatted = []
|
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({
|
chains_formatted.append({
|
||||||
'name': name,
|
'name': name,
|
||||||
'lookups': c.get('chain_lookups', 'local'),
|
'lookups': c.get('chain_lookups', 'local'),
|
||||||
@ -417,6 +427,10 @@ class HttpHandler(BaseHTTPRequestHandler):
|
|||||||
if name == 'monero':
|
if name == 'monero':
|
||||||
chains_formatted[-1]['fee_priority'] = c.get('fee_priority', 0)
|
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]['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:
|
else:
|
||||||
chains_formatted[-1]['conf_target'] = c.get('conf_target', 2)
|
chains_formatted[-1]['conf_target'] = c.get('conf_target', 2)
|
||||||
if name != 'particl':
|
if name != 'particl':
|
||||||
|
@ -7,6 +7,9 @@ import requests
|
|||||||
def callrpc_xmr(rpc_port, auth, method, params=[], rpc_host='127.0.0.1', path='json_rpc', timeout=120):
|
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)
|
# auth is a tuple: (username, password)
|
||||||
try:
|
try:
|
||||||
|
if rpc_host.count('://') > 0:
|
||||||
|
url = '{}:{}/{}'.format(rpc_host, rpc_port, path)
|
||||||
|
else:
|
||||||
url = 'http://{}:{}/{}'.format(rpc_host, rpc_port, path)
|
url = 'http://{}:{}/{}'.format(rpc_host, rpc_port, path)
|
||||||
request_body = {
|
request_body = {
|
||||||
'method': method,
|
'method': method,
|
||||||
@ -30,6 +33,9 @@ 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):
|
def callrpc_xmr_na(rpc_port, method, params=[], rpc_host='127.0.0.1', path='json_rpc', timeout=120):
|
||||||
try:
|
try:
|
||||||
|
if rpc_host.count('://') > 0:
|
||||||
|
url = '{}:{}/{}'.format(rpc_host, rpc_port, path)
|
||||||
|
else:
|
||||||
url = 'http://{}:{}/{}'.format(rpc_host, rpc_port, path)
|
url = 'http://{}:{}/{}'.format(rpc_host, rpc_port, path)
|
||||||
request_body = {
|
request_body = {
|
||||||
'method': method,
|
'method': method,
|
||||||
@ -53,6 +59,9 @@ 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):
|
def callrpc_xmr2(rpc_port, method, params=None, rpc_host='127.0.0.1', timeout=120):
|
||||||
try:
|
try:
|
||||||
|
if rpc_host.count('://') > 0:
|
||||||
|
url = '{}:{}/{}'.format(rpc_host, rpc_port, method)
|
||||||
|
else:
|
||||||
url = 'http://{}:{}/{}'.format(rpc_host, rpc_port, method)
|
url = 'http://{}:{}/{}'.format(rpc_host, rpc_port, method)
|
||||||
headers = {
|
headers = {
|
||||||
'Content-Type': 'application/json'
|
'Content-Type': 'application/json'
|
||||||
|
@ -15,8 +15,31 @@
|
|||||||
<tr><td>Connection Type</td><td>{{ c.connection_type }}</td></tr>
|
<tr><td>Connection Type</td><td>{{ c.connection_type }}</td></tr>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
{% if c.manage_daemon is defined %}
|
{% 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>
|
<tr><td>Manage Daemon</td><td>{{ c.manage_daemon }}</td></tr>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
{% endif %}
|
||||||
{% if c.manage_wallet_daemon is defined %}
|
{% if c.manage_wallet_daemon is defined %}
|
||||||
<tr><td>Manage Wallet Daemon</td><td>{{ c.manage_wallet_daemon }}</td></tr>
|
<tr><td>Manage Wallet Daemon</td><td>{{ c.manage_wallet_daemon }}</td></tr>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
@ -9,6 +9,8 @@
|
|||||||
- xmrswaps:
|
- xmrswaps:
|
||||||
- Setting state to 'Script tx redeemed' will trigger an attempt to redeem the scriptless lock tx.
|
- 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.
|
- 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
|
0.0.25
|
||||||
|
Loading…
Reference in New Issue
Block a user