diff --git a/basicswap/basicswap.py b/basicswap/basicswap.py index c0ed320..dc126d7 100644 --- a/basicswap/basicswap.py +++ b/basicswap/basicswap.py @@ -571,6 +571,7 @@ class BasicSwap(BaseApp): 'explorers': [], 'chain_lookups': chain_client_settings.get('chain_lookups', 'local'), 'restore_height': chain_client_settings.get('restore_height', 0), + 'fee_priority': chain_client_settings.get('fee_priority', 0), } if self.coin_clients[coin]['connection_type'] == 'rpc': @@ -2713,9 +2714,10 @@ class BasicSwap(BaseApp): # Have to use findTxB instead of relying on the first seen height to detect chain reorgs found_tx = ci_to.findTxB(xmr_swap.vkbv, xmr_swap.pkbs, bid.amount_to, ci_to.blocks_confirmed, xmr_swap.b_restore_height) if found_tx is not None: + if bid.xmr_b_lock_tx is None or not bid.xmr_b_lock_tx.chain_height: + self.logBidEvent(bid, EventLogTypes.LOCK_TX_B_SEEN, '', session) if bid.xmr_b_lock_tx is None: self.log.debug('Found {} lock tx in chain'.format(ci_to.coin_name())) - self.logBidEvent(bid, EventLogTypes.LOCK_TX_B_SEEN, '', session) b_lock_tx_id = bytes.fromhex(found_tx['txid']) bid.xmr_b_lock_tx = SwapTx( bid_id=bid_id, @@ -4509,21 +4511,36 @@ class BasicSwap(BaseApp): def editSettings(self, coin_name, data): self.log.info('Updating settings %s', coin_name) - self.mxDB.acquire() - try: + with self.mxDB: + settings_changed = False if 'lookups' in data: - self.settings['chainclients'][coin_name]['chain_lookups'] = data['lookups'] + if self.settings['chainclients'][coin_name].get('chain_lookups', 'local') != data['lookups']: + settings_changed = True + self.settings['chainclients'][coin_name]['chain_lookups'] = data['lookups'] + for coin, cc in self.coin_clients.items(): + if cc['name'] == coin_name: + cc['chain_lookups'] = data['lookups'] + break + + if 'fee_priority' in data: + new_fee_priority = data['fee_priority'] + assert(new_fee_priority >= 0 and new_fee_priority < 4), 'Invalid priority' + + if self.settings['chainclients'][coin_name].get('fee_priority', 0) != data['fee_priority']: + settings_changed = True + self.settings['chainclients'][coin_name]['fee_priority'] = data['fee_priority'] + for coin, cc in self.coin_clients.items(): + if cc['name'] == coin_name: + cc['fee_priority'] = data['fee_priority'] + break + self.ci(Coins.XMR).setFeePriority(data['fee_priority']) + + if settings_changed: settings_path = os.path.join(self.data_dir, cfg.CONFIG_FILENAME) shutil.copyfile(settings_path, settings_path + '.last') with open(settings_path, 'w') as fp: json.dump(self.settings, fp, indent=4) - for c in self.coin_clients: - if c['name'] == coin_name: - c['chain_lookups'] = data['lookups'] - finally: - self.mxDB.release() - def getSummary(self, opts=None): num_watched_outputs = 0 for c, v in self.coin_clients.items(): diff --git a/basicswap/rfc6979.py b/basicswap/contrib/rfc6979.py similarity index 100% rename from basicswap/rfc6979.py rename to basicswap/contrib/rfc6979.py diff --git a/basicswap/http_server.py b/basicswap/http_server.py index ccf9dc9..6715ff1 100644 --- a/basicswap/http_server.py +++ b/basicswap/http_server.py @@ -284,6 +284,9 @@ class HttpHandler(BaseHTTPRequestHandler): 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 name == 'monero': + data['fee_priority'] = int(form_data[bytes('fee_priority_' + name, 'utf-8')][0]) + swap_client.editSettings(name, data) chains_formatted = [] @@ -292,6 +295,8 @@ class HttpHandler(BaseHTTPRequestHandler): 'name': name, 'lookups': c.get('chain_lookups', 'local') }) + if name == 'monero': + chains_formatted[-1]['fee_priority'] = c.get('fee_priority', 0) template = env.get_template('settings.html') return bytes(template.render( diff --git a/basicswap/interface_xmr.py b/basicswap/interface_xmr.py index d1180e9..3f80acc 100644 --- a/basicswap/interface_xmr.py +++ b/basicswap/interface_xmr.py @@ -64,6 +64,10 @@ class XMRInterface(CoinInterface): self._network = network self.blocks_confirmed = coin_settings['blocks_confirmed'] self._restore_height = coin_settings.get('restore_height', 0) + self._fee_priority = coin_settings.get('fee_priority', 0) + + def setFeePriority(self, new_priority): + self._fee_priority = new_priority def setWalletFilename(self, wallet_filename): self._wallet_filename = wallet_filename @@ -191,8 +195,9 @@ class XMRInterface(CoinInterface): shared_addr = xmr_util.encode_address(Kbv, Kbs) - # TODO: How to set feerate? params = {'destinations': [{'amount': output_amount, 'address': shared_addr}]} + if self._fee_priority > 0: + params['priority'] = self._fee_priority rv = self.rpc_wallet_cb('transfer', params) logging.info('publishBLockTx %s to address_b58 %s', rv['tx_hash'], shared_addr) tx_hash = bytes.fromhex(rv['tx_hash']) @@ -382,38 +387,19 @@ class XMRInterface(CoinInterface): raise ValueError('Invalid unlocked_balance') params = {'address': address_to} + if self._fee_priority > 0: + params['priority'] = self._fee_priority rv = self.rpc_wallet_cb('sweep_all', params) print('sweep_all', rv) return bytes.fromhex(rv['tx_hash_list'][0]) - """ - # TODO: need a subfee from output option - # b_fee = b_fee_rate * 10 # Guess - b_fee = b_fee_rate - - num_tries = 20 - for i in range(1 + num_tries): - try: - params = {'destinations': [{'amount': cb_swap_value - b_fee, 'address': address_to}]} - logging.debug('params', dumpj(params)) - rv = self.rpc_wallet_cb('transfer', params) - print('transfer', rv) - break - except Exception as e: - print('str(e)', str(e)) - if i >= num_tries: - raise ValueError('transfer failed.') - b_fee += b_fee_rate - logging.info('Raising fee to %d', b_fee) - - return bytes.fromhex(rv['tx_hash']) - """ - def withdrawCoin(self, value, addr_to, subfee): self.rpc_wallet_cb('open_wallet', {'filename': self._wallet_filename}) value_sats = make_int(value, self.exp()) params = {'destinations': [{'amount': value_sats, 'address': addr_to}]} + if self._fee_priority > 0: + params['priority'] = self._fee_priority rv = self.rpc_wallet_cb('transfer', params) return rv['tx_hash'] diff --git a/basicswap/network.py b/basicswap/network.py index 0370b0a..a22b580 100644 --- a/basicswap/network.py +++ b/basicswap/network.py @@ -15,6 +15,8 @@ node1 send_ping - With a version field node0 recv_ping Both nodes are initialised + + XChaCha20_Poly1305 mac is 16bytes ''' import time @@ -33,7 +35,7 @@ from enum import IntEnum, auto from collections import OrderedDict from Crypto.Cipher import ChaCha20_Poly1305 # TODO: Add to libsecp256k1/coincurve fork from coincurve.keys import PrivateKey, PublicKey -from basicswap.rfc6979 import ( +from basicswap.contrib.rfc6979 import ( rfc6979_hmac_sha256_initialize, rfc6979_hmac_sha256_generate) @@ -55,6 +57,7 @@ class NetMessageTypes(IntEnum): PING = auto() PONG = auto() DATA = auto() + ONION_PACKET = auto() @classmethod def has_value(cls, value): @@ -580,8 +583,6 @@ class Network: def test_onion(self, path): self._sc.log.debug('test_onion packet') - plaintext = 'test' - def get_info(self): rv = {} diff --git a/basicswap/templates/settings.html b/basicswap/templates/settings.html index 5cfa437..38da7ad 100644 --- a/basicswap/templates/settings.html +++ b/basicswap/templates/settings.html @@ -9,13 +9,22 @@
{% for c in chains %} -

{{ c.name }}

+

{{ c.name|capitalize }}

+{% if c.name == 'monero' %} + +{% endif %}
Chain Lookups
Transaction Fee Priority +
{% endfor %} @@ -24,4 +33,4 @@

home

- \ No newline at end of file + diff --git a/tests/basicswap/test_network.py b/tests/basicswap/test_network.py index 50887a3..b834bc1 100644 --- a/tests/basicswap/test_network.py +++ b/tests/basicswap/test_network.py @@ -326,7 +326,7 @@ class Test(unittest.TestCase): print(dumpj(js_n0)) path = [swap_clients[0]._network._network_pubkey, swap_clients[2]._network._network_pubkey] - swap_clients[1].test_onion(path) + swap_clients[1]._network.test_onion(path) delay_for(delay_event, 1000) diff --git a/tests/basicswap/test_xmr.py b/tests/basicswap/test_xmr.py index 5a2797c..86154ee 100644 --- a/tests/basicswap/test_xmr.py +++ b/tests/basicswap/test_xmr.py @@ -548,6 +548,8 @@ class Test(unittest.TestCase): offers = swap_clients[1].listOffers(filters={'offer_id': offer_id}) offer = offers[0] + swap_clients[1].ci(Coins.XMR).setFeePriority(3) + bid_id = swap_clients[1].postXmrBid(offer_id, offer.amount_from) wait_for_bid(delay_event, swap_clients[0], bid_id, BidStates.BID_RECEIVED) @@ -560,6 +562,8 @@ class Test(unittest.TestCase): wait_for_bid(delay_event, swap_clients[0], bid_id, BidStates.SWAP_COMPLETED, wait_for=180) wait_for_bid(delay_event, swap_clients[1], bid_id, BidStates.SWAP_COMPLETED, sent=True) + swap_clients[1].ci(Coins.XMR).setFeePriority(0) + def test_06_multiple_swaps(self): logging.info('---------- Test Multiple concurrent swaps') swap_clients = self.swap_clients