twallet: (fix) get_receiving_address must always return an addr - electrum - Electrum Bitcoin wallet HTML git clone https://git.parazyd.org/electrum DIR Log DIR Files DIR Refs DIR Submodules --- DIR commit f8c574b6993799797e9835804bbfa3f99ced4a6e DIR parent 9657e927a7abe4e172c831f6a30c6afbc44d5687 HTML Author: SomberNight <somber.night@protonmail.com> Date: Fri, 22 May 2020 16:25:33 +0200 wallet: (fix) get_receiving_address must always return an addr - also, disallow deleting last address from an imported wallet (fixes #3254, fixes #4833) - also, set LNBackups.sweep_address lazily, as during fresh wallet creation there are no addresses in the wallet at that point yet! see trace below. Traceback (most recent call last): [...] File "...\electrum\electrum\tests\test_commands.py", line 112, in test_export_private_key_deterministic wallet = restore_wallet_from_text('bitter grass shiver impose acquire brush forget axis eager alone wine silver', File "...\electrum\electrum\wallet.py", line 2575, in restore_wallet_from_text wallet = Wallet(db, storage, config=config) File "...\electrum\electrum\wallet.py", line 2502, in __new__ wallet = WalletClass(db, storage, config=config) File "...\electrum\electrum\wallet.py", line 2346, in __init__ Deterministic_Wallet.__init__(self, db, storage, config=config) File "...\electrum\electrum\wallet.py", line 2147, in __init__ Abstract_Wallet.__init__(self, db, storage, config=config) File "...\electrum\electrum\wallet.py", line 261, in __init__ self.lnbackups = LNBackups(self) File "...\electrum\electrum\lnworker.py", line 1401, in __init__ self.sweep_address = wallet.get_receiving_address() File "...\electrum\electrum\wallet.py", line 1498, in wrapper addr = func(self, *args, **kwargs) File "...\electrum\electrum\wallet.py", line 1520, in get_receiving_address raise Exception("no receiving addresses in wallet?!") Exception: no receiving addresses in wallet?! Diffstat: M electrum/lnworker.py | 5 ++++- M electrum/wallet.py | 6 ++++-- 2 files changed, 8 insertions(+), 3 deletions(-) --- DIR diff --git a/electrum/lnworker.py b/electrum/lnworker.py t@@ -1398,11 +1398,14 @@ class LNBackups(Logger): self.lock = threading.RLock() self.wallet = wallet self.db = wallet.db - self.sweep_address = wallet.get_receiving_address() self.channel_backups = {} for channel_id, cb in self.db.get_dict("channel_backups").items(): self.channel_backups[bfh(channel_id)] = ChannelBackup(cb, sweep_address=self.sweep_address, lnworker=self) + @property + def sweep_address(self) -> str: + return self.wallet.get_receiving_address() + def channel_state_changed(self, chan): util.trigger_callback('channel', chan) DIR diff --git a/electrum/wallet.py b/electrum/wallet.py t@@ -1513,11 +1513,11 @@ class Abstract_Wallet(AddressSynchronizer, ABC): return addrs[0] @check_returned_address - def get_receiving_address(self): + def get_receiving_address(self) -> str: # always return an address domain = self.get_receiving_addresses() if not domain: - return + raise Exception("no receiving addresses in wallet?!") choice = domain[0] for addr in domain: if not self.is_used(addr): t@@ -2030,6 +2030,8 @@ class Imported_Wallet(Simple_Wallet): def delete_address(self, address: str) -> None: if not self.db.has_imported_address(address): return + if len(self.get_addresses()) <= 1: + raise Exception("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: