From 8a53a3201c169d0d21b5eaac3b4c9e7c726b1bb2 Mon Sep 17 00:00:00 2001 From: SomberNight Date: Wed, 8 Feb 2023 23:30:48 +0000 Subject: [PATCH] wallet.try_detecting_internal_addresses_corruption: check more addrs related https://github.com/spesmilo/electrum/issues/8202 For a HD wallet, instead of checking the first 10 addrs + 10 additional random ones, we now check the first 10 addrs + 10 random used addrs + 10 random unused addrs. Checking unused addresses is useful to prevent getting money sent there, and checking used addresses is useful to inform people of already lost money. --- electrum/wallet.py | 27 ++++++++++++++++++--------- 1 file changed, 18 insertions(+), 9 deletions(-) diff --git a/electrum/wallet.py b/electrum/wallet.py index f6ef08580..c90ace5b0 100644 --- a/electrum/wallet.py +++ b/electrum/wallet.py @@ -3085,9 +3085,14 @@ class Imported_Wallet(Simple_Wallet): @profiler def try_detecting_internal_addresses_corruption(self): # we check only a random sample, for performance - addresses = self.get_addresses() - addresses = random.sample(addresses, min(len(addresses), 10)) - for addr_found in addresses: + addresses_all = self.get_addresses() + # some random *used* addresses (note: we likely have not synced yet) + addresses_used = [addr for addr in addresses_all if self.adb.is_used(addr)] + sample1 = random.sample(addresses_used, min(len(addresses_used), 10)) + # some random *unused* addresses + addresses_unused = [addr for addr in addresses_all if not self.adb.is_used(addr)] + sample2 = random.sample(addresses_unused, min(len(addresses_unused), 10)) + for addr_found in itertools.chain(sample1, sample2): self.check_address_for_corruption(addr_found) def check_address_for_corruption(self, addr): @@ -3167,12 +3172,16 @@ class Deterministic_Wallet(Abstract_Wallet): @profiler def try_detecting_internal_addresses_corruption(self): addresses_all = self.get_addresses() - # sample 1: first few - addresses_sample1 = addresses_all[:10] - # sample2: a few more randomly selected - addresses_rand = addresses_all[10:] - addresses_sample2 = random.sample(addresses_rand, min(len(addresses_rand), 10)) - for addr_found in itertools.chain(addresses_sample1, addresses_sample2): + # first few addresses + nfirst_few = 10 + sample1 = addresses_all[:nfirst_few] + # some random *used* addresses (note: we likely have not synced yet) + addresses_used = [addr for addr in addresses_all[nfirst_few:] if self.adb.is_used(addr)] + sample2 = random.sample(addresses_used, min(len(addresses_used), 10)) + # some random *unused* addresses + addresses_unused = [addr for addr in addresses_all[nfirst_few:] if not self.adb.is_used(addr)] + sample3 = random.sample(addresses_unused, min(len(addresses_unused), 10)) + for addr_found in itertools.chain(sample1, sample2, sample3): self.check_address_for_corruption(addr_found) def check_address_for_corruption(self, addr):