From c3cd1871ef3af818776bac0b003dcf1cebd38b85 Mon Sep 17 00:00:00 2001 From: tecnovert Date: Tue, 4 Jun 2024 20:35:55 +0200 Subject: [PATCH] Add disableall option to smsgaddresses command. Ensure used addresses are active. --- basicswap/basicswap.py | 88 +++++++++++++++++++++++++++++++------ basicswap/js_server.py | 12 +++-- basicswap/ui/page_offers.py | 6 +-- tests/basicswap/test_xmr.py | 16 ++++--- 4 files changed, 95 insertions(+), 27 deletions(-) diff --git a/basicswap/basicswap.py b/basicswap/basicswap.py index c66adc3..d2c9e0a 100644 --- a/basicswap/basicswap.py +++ b/basicswap/basicswap.py @@ -1614,7 +1614,8 @@ class BasicSwap(BaseApp): try: session = self.openSession() self.checkCoinsReady(coin_from_t, coin_to_t) - offer_addr = self.newSMSGAddress(use_type=AddressTypes.OFFER, session=session)[0] if addr_send_from is None else addr_send_from + offer_addr = self.prepareSMSGAddress(addr_send_from, AddressTypes.OFFER, session) + offer_created_at = self.getTime() msg_buf = OfferMessage() @@ -2395,7 +2396,7 @@ class BasicSwap(BaseApp): bid_bytes = msg_buf.to_bytes() payload_hex = str.format('{:02x}', MessageTypes.BID) + bid_bytes.hex() - bid_addr = self.newSMSGAddress(use_type=AddressTypes.BID, session=session)[0] if addr_send_from is None else addr_send_from + bid_addr = self.prepareSMSGAddress(addr_send_from, AddressTypes.BID, session) msg_valid: int = max(self.SMSG_SECONDS_IN_HOUR, valid_for_seconds) bid_id = self.sendSmsg(bid_addr, offer.addr_from, payload_hex, msg_valid) @@ -2755,7 +2756,8 @@ class BasicSwap(BaseApp): xmr_swap = XmrSwap() xmr_swap.contract_count = self.getNewContractId(session) - bid_addr = self.newSMSGAddress(use_type=AddressTypes.BID, session=session)[0] if addr_send_from is None else addr_send_from + bid_addr = self.prepareSMSGAddress(addr_send_from, AddressTypes.BID, session) + msg_valid: int = max(self.SMSG_SECONDS_IN_HOUR, valid_for_seconds) xmr_swap.bid_id = self.sendSmsg(bid_addr, offer.addr_from, payload_hex, msg_valid) @@ -2837,7 +2839,8 @@ class BasicSwap(BaseApp): bid_bytes = msg_buf.to_bytes() payload_hex = str.format('{:02x}', MessageTypes.XMR_BID_FL) + bid_bytes.hex() - bid_addr = self.newSMSGAddress(use_type=AddressTypes.BID, session=session)[0] if addr_send_from is None else addr_send_from + bid_addr = self.prepareSMSGAddress(addr_send_from, AddressTypes.BID, session) + msg_valid: int = max(self.SMSG_SECONDS_IN_HOUR, valid_for_seconds) xmr_swap.bid_id = self.sendSmsg(bid_addr, offer.addr_from, payload_hex, msg_valid) @@ -7307,7 +7310,7 @@ class BasicSwap(BaseApp): finally: self.mxDB.release() - def listAllSMSGAddresses(self, filters={}): + def listAllSMSGAddresses(self, filters={}, session=None): query_str = 'SELECT addr_id, addr, use_type, active_ind, created_at, note, pubkey FROM smsgaddresses' query_str += ' WHERE 1 = 1 ' query_data = {} @@ -7336,9 +7339,9 @@ class BasicSwap(BaseApp): query_str += f' OFFSET {offset}' try: - session = self.openSession() + use_session = self.openSession(session) rv = [] - q = session.execute(query_str, query_data) + q = use_session.execute(query_str, query_data) for row in q: rv.append({ 'id': row[0], @@ -7351,9 +7354,10 @@ class BasicSwap(BaseApp): }) return rv finally: - self.closeSession(session, commit=False) + if session is None: + self.closeSession(use_session, commit=False) - def listSmsgAddresses(self, use_type_str): + def listSMSGAddresses(self, use_type_str: str): if use_type_str == 'offer_send_from': use_type = AddressTypes.OFFER elif use_type_str == 'offer_send_to': @@ -7471,7 +7475,11 @@ class BasicSwap(BaseApp): self.callrpc('smsgaddlocaladdress', [new_addr]) # Enable receiving smsgs self.callrpc('smsglocalkeys', ['anon', '-', new_addr]) - use_session.add(SmsgAddress(addr=new_addr, use_type=use_type, active_ind=1, created_at=now, note=addressnote, pubkey=addr_info['pubkey'])) + addr_obj = SmsgAddress(addr=new_addr, use_type=use_type, active_ind=1, created_at=now, pubkey=addr_info['pubkey']) + if addressnote is not None: + addr_obj.note = addressnote + + use_session.add(addr_obj) return new_addr, addr_info['pubkey'] finally: if session is None: @@ -7491,17 +7499,69 @@ class BasicSwap(BaseApp): finally: self.closeSession(session) - def editSMSGAddress(self, address: str, active_ind: int, addressnote: str) -> None: - session = self.openSession() + def editSMSGAddress(self, address: str, active_ind: int, addressnote: str = None, use_type=None, session=None) -> None: + use_session = self.openSession(session) try: mode = '-' if active_ind == 0 else '+' self.callrpc('smsglocalkeys', ['recv', mode, address]) + values = {'active_ind': active_ind, 'addr': address, 'use_type': use_type} - session.execute('UPDATE smsgaddresses SET active_ind = :active_ind, note = :note WHERE addr = :addr', {'active_ind': active_ind, 'note': addressnote, 'addr': address}) - session.commit() + query_str: str = 'UPDATE smsgaddresses SET active_ind = :active_ind' + if addressnote is not None: + values['note'] = addressnote + query_str += ', note = :note' + query_str += ' WHERE addr = :addr' + + rv = use_session.execute(query_str, values) + if rv.rowcount < 1: + query_str: str = 'INSERT INTO smsgaddresses (addr, active_ind, use_type) VALUES (:addr, :active_ind, :use_type)' + use_session.execute(query_str, values) + finally: + if session is None: + self.closeSession(use_session) + + def disableAllSMSGAddresses(self): + filters = { + 'exclude_inactive': True, + } + session = self.openSession() + rv = {} + num_disabled = 0 + try: + active_addresses = self.listAllSMSGAddresses(filters, session=session) + for active_address in active_addresses: + if active_address['addr'] == self.network_addr: + continue + self.editSMSGAddress(active_address['addr'], active_ind=0, session=session) + num_disabled += 1 finally: self.closeSession(session) + rv['num_disabled'] = num_disabled + + num_core_disabled = 0 + # Check localkeys + smsg_localkeys = self.callrpc('smsglocalkeys') + all_keys = smsg_localkeys['wallet_keys'] + smsg_localkeys['smsg_keys'] + for smsg_addr in all_keys: + if smsg_addr['address'] == self.network_addr: + continue + if smsg_addr['receive'] != 0: + self.log.warning('Disabling smsg key found in core and not bsx: {}'.format(smsg_addr['address'])) + self.callrpc('smsglocalkeys', ['recv', '-', smsg_addr['address']]) + num_core_disabled += 1 + + if num_core_disabled > 0: + rv['num_core_disabled'] = num_core_disabled + return rv + + def prepareSMSGAddress(self, addr_send_from, use_type, session): + if addr_send_from is None: + return self.newSMSGAddress(use_type=use_type, session=session)[0] + use_addr = addr_send_from + self.editSMSGAddress(use_addr, 1, use_type=use_type, session=session) # Ensure receive is active + return use_addr + def createCoinALockRefundSwipeTx(self, ci, bid, offer, xmr_swap, xmr_offer): self.log.debug('Creating %s lock refund swipe tx', ci.coin_name()) diff --git a/basicswap/js_server.py b/basicswap/js_server.py index 05a4626..d3ff2e4 100644 --- a/basicswap/js_server.py +++ b/basicswap/js_server.py @@ -429,27 +429,31 @@ def js_smsgaddresses(self, url_split, post_string, is_json) -> bytes: swap_client = self.server.swap_client swap_client.checkSystemStatus() post_data = {} if post_string == '' else getFormData(post_string, is_json) + if len(url_split) > 3: - if url_split[3] == 'new': + mode: str = url_split[3] + if mode == 'new': addressnote = get_data_entry_or(post_data, 'addressnote', '') new_addr, pubkey = swap_client.newSMSGAddress(addressnote=addressnote) return bytes(json.dumps({'new_address': new_addr, 'pubkey': pubkey}), 'UTF-8') - if url_split[3] == 'add': + if mode == 'add': addressnote = get_data_entry_or(post_data, 'addressnote', '') pubkey_hex = get_data_entry(post_data, 'addresspubkey') added_address = swap_client.addSMSGAddress(pubkey_hex, addressnote) return bytes(json.dumps({'added_address': added_address, 'pubkey': pubkey_hex}), 'UTF-8') - elif url_split[3] == 'edit': + elif mode == 'edit': address = get_data_entry(post_data, 'address') activeind = int(get_data_entry(post_data, 'active_ind')) addressnote = get_data_entry_or(post_data, 'addressnote', '') new_addr = swap_client.editSMSGAddress(address, activeind, addressnote) return bytes(json.dumps({'edited_address': address}), 'UTF-8') + elif mode == 'disableall': + rv = swap_client.disableAllSMSGAddresses() + return bytes(json.dumps(rv), 'UTF-8') filters = { 'exclude_inactive': post_data.get('exclude_inactive', True), } - return bytes(json.dumps(swap_client.listAllSMSGAddresses(filters)), 'UTF-8') diff --git a/basicswap/ui/page_offers.py b/basicswap/ui/page_offers.py index 51b7102..a8e2662 100644 --- a/basicswap/ui/page_offers.py +++ b/basicswap/ui/page_offers.py @@ -472,8 +472,8 @@ def page_newoffer(self, url_split, post_string): 'err_messages': err_messages, 'coins_from': coins_from, 'coins': coins_to, - 'addrs': swap_client.listSmsgAddresses('offer_send_from'), - 'addrs_to': swap_client.listSmsgAddresses('offer_send_to'), + 'addrs': swap_client.listSMSGAddresses('offer_send_from'), + 'addrs_to': swap_client.listSMSGAddresses('offer_send_to'), 'data': page_data, 'automation_strategies': automation_strategies, 'summary': summary, @@ -677,7 +677,7 @@ def page_offer(self, url_split, post_string): 'err_messages': err_messages, 'data': data, 'bids': formatted_bids, - 'addrs': None if show_bid_form is None else swap_client.listSmsgAddresses('bid'), + 'addrs': None if show_bid_form is None else swap_client.listSMSGAddresses('bid'), 'summary': summary, }) diff --git a/tests/basicswap/test_xmr.py b/tests/basicswap/test_xmr.py index 80b25f8..8967c4a 100644 --- a/tests/basicswap/test_xmr.py +++ b/tests/basicswap/test_xmr.py @@ -861,7 +861,7 @@ class Test(BaseTest): post_json = { 'addressnote': 'testing', } - json_rv = json.loads(post_json_req('http://127.0.0.1:1801/json/smsgaddresses/new', post_json)) + json_rv = read_json_api(1801, 'smsgaddresses/new', post_json) new_address = json_rv['new_address'] new_address_pk = json_rv['pubkey'] @@ -888,7 +888,7 @@ class Test(BaseTest): 'addressnote': 'testing2', 'active_ind': '0', } - json_rv = json.loads(post_json_req('http://127.0.0.1:1801/json/smsgaddresses/edit', post_json)) + json_rv = read_json_api(1801, 'smsgaddresses/edit', post_json) assert (json_rv['edited_address'] == new_address) js_3 = read_json_api(1801, 'smsgaddresses') @@ -897,7 +897,7 @@ class Test(BaseTest): post_json = { 'exclude_inactive': False, } - js_3 = json.loads(post_json_req('http://127.0.0.1:1801/json/smsgaddresses', post_json)) + js_3 = read_json_api(1801, 'smsgaddresses', post_json) found = False for addr in js_3: if addr['addr'] == new_address: @@ -918,7 +918,7 @@ class Test(BaseTest): 'address': new_address, 'active_ind': '1', } - json_rv = json.loads(post_json_req('http://127.0.0.1:1801/json/smsgaddresses/edit', post_json)) + json_rv = read_json_api(1801, 'smsgaddresses/edit', post_json) assert (json_rv['edited_address'] == new_address) found = False @@ -933,7 +933,7 @@ class Test(BaseTest): 'addresspubkey': new_address_pk, 'addressnote': 'testing_add_addr', } - json_rv = json.loads(post_json_req('http://127.0.0.1:1800/json/smsgaddresses/add', post_json)) + json_rv = read_json_api(1800, 'smsgaddresses/add', post_json) assert (json_rv['added_address'] == new_address) post_json = { @@ -944,7 +944,7 @@ class Test(BaseTest): 'amt_from': 1, 'amt_to': 1, 'lockhrs': 24} - rv = json.loads(post_json_req('http://127.0.0.1:1800/json/offers/new', post_json)) + rv = read_json_api(1800, 'offers/new', post_json) offer_id_hex = rv['offer_id'] wait_for_offer(test_delay_event, swap_clients[1], bytes.fromhex(offer_id_hex)) @@ -955,6 +955,10 @@ class Test(BaseTest): rv = read_json_api(1800, f'offers/{offer_id_hex}') assert (rv[0]['addr_to'] == new_address) + # Disable all + json_rv = read_json_api(1800, 'smsgaddresses/disableall') + assert (json_rv['num_disabled'] >= 1) + def test_02_leader_recover_a_lock_tx(self): logging.info('---------- Test PART to XMR leader recovers coin a lock tx') swap_clients = self.swap_clients