wallet: more locking in delete_address
in particular, the "Cannot delete last remaining address from wallet" check should run inside the lock - tangentially related: https://github.com/spesmilo/electrum/issues/10104#issuecomment-3151165340
This commit is contained in:
@@ -3657,11 +3657,12 @@ class Imported_Wallet(Simple_Wallet):
|
|||||||
def delete_address(self, address: str) -> None:
|
def delete_address(self, address: str) -> None:
|
||||||
if not self.db.has_imported_address(address):
|
if not self.db.has_imported_address(address):
|
||||||
return
|
return
|
||||||
if len(self.get_addresses()) <= 1:
|
|
||||||
raise UserFacingException(_('Cannot delete last remaining address from wallet'))
|
|
||||||
transactions_to_remove = set() # only referred to by this address
|
|
||||||
transactions_new = set() # txs that are not only referred to by address
|
|
||||||
with self.lock:
|
with self.lock:
|
||||||
|
if len(self.get_addresses()) <= 1: # check this inside lock
|
||||||
|
raise UserFacingException(_('Cannot delete last remaining address from wallet'))
|
||||||
|
transactions_to_remove = set() # only referred to by this address
|
||||||
|
transactions_new = set() # txs that are not only referred to by address
|
||||||
|
# rm txs from history
|
||||||
for addr in self.db.get_history():
|
for addr in self.db.get_history():
|
||||||
details = self.adb.get_address_history(addr).items()
|
details = self.adb.get_address_history(addr).items()
|
||||||
if addr == address:
|
if addr == address:
|
||||||
@@ -3674,26 +3675,30 @@ class Imported_Wallet(Simple_Wallet):
|
|||||||
self.db.remove_addr_history(address)
|
self.db.remove_addr_history(address)
|
||||||
for tx_hash in transactions_to_remove:
|
for tx_hash in transactions_to_remove:
|
||||||
self.adb._remove_transaction(tx_hash)
|
self.adb._remove_transaction(tx_hash)
|
||||||
self.set_label(address, None)
|
# rm label for addr
|
||||||
if req := self.get_request_by_addr(address):
|
# TODO rm label for txids?
|
||||||
self.delete_request(req.get_id())
|
self.set_label(address, None)
|
||||||
self.set_frozen_state_of_addresses([address], False, write_to_disk=False)
|
# rm receive requests for addr
|
||||||
pubkey = self.get_public_key(address)
|
if req := self.get_request_by_addr(address):
|
||||||
self.db.remove_imported_address(address)
|
self.delete_request(req.get_id())
|
||||||
if pubkey:
|
self.set_frozen_state_of_addresses([address], False, write_to_disk=False)
|
||||||
# delete key iff no other address uses it (e.g. p2pkh and p2wpkh for same key)
|
# rm corresponding key from keystore
|
||||||
for txin_type in bitcoin.WIF_SCRIPT_TYPES.keys():
|
pubkey = self.get_public_key(address)
|
||||||
try:
|
self.db.remove_imported_address(address)
|
||||||
addr2 = bitcoin.pubkey_to_address(txin_type, pubkey)
|
if pubkey:
|
||||||
except NotImplementedError:
|
# delete key iff no other address uses it (e.g. p2pkh and p2wpkh for same key)
|
||||||
pass
|
for txin_type in bitcoin.WIF_SCRIPT_TYPES.keys():
|
||||||
|
try:
|
||||||
|
addr2 = bitcoin.pubkey_to_address(txin_type, pubkey)
|
||||||
|
except NotImplementedError:
|
||||||
|
pass
|
||||||
|
else:
|
||||||
|
if self.db.has_imported_address(addr2):
|
||||||
|
break
|
||||||
else:
|
else:
|
||||||
if self.db.has_imported_address(addr2):
|
self.keystore.delete_imported_key(pubkey)
|
||||||
break
|
self.save_keystore()
|
||||||
else:
|
self.save_db()
|
||||||
self.keystore.delete_imported_key(pubkey)
|
|
||||||
self.save_keystore()
|
|
||||||
self.save_db()
|
|
||||||
|
|
||||||
def get_change_addresses_for_new_transaction(self, *args, **kwargs) -> List[str]:
|
def get_change_addresses_for_new_transaction(self, *args, **kwargs) -> List[str]:
|
||||||
# for an imported wallet, if all "change addresses" are already used,
|
# for an imported wallet, if all "change addresses" are already used,
|
||||||
|
|||||||
Reference in New Issue
Block a user