wallet: refactor get_change_addresses_for_new_transaction
What changed, and why it matters
This commit is a straightforward code cleanup: it extracts a repeated block of address-selection logic into a new helper method and reuses it in two places. There is no indication of a security fix, behavior change, or vulnerability being patched.
No security action required; treat as a normal refactoring review.
Security signals we found
No strong security signals were identified.
Evidence from the diff
The change refactors get_change_addresses_for_new_transaction and get_new_sweep_address_for_channel in electrum/wallet.py. It moves the logic for choosing unused change addresses (or reusing a recent one) into a new private method _get_change_addresses_we_can_use_now. The original behavior is preserved: unused addresses are returned if available; otherwise a random recent change address is chosen when reuse is allowed. The @check_returned_address_for_corruption decorator is removed from get_new_sweep_address_for_channel because the new helper performs the corruption check inline on each returned address.
Changed components
electrum/wallet.pyAbstract_Wallet.get_change_addresses_for_new_transactionAbstract_Wallet.get_new_sweep_address_for_channelnew helper _get_change_addresses_we_can_use_nowInspect captured patch +25 / −21
diff --git a/electrum/wallet.py b/electrum/wallet.py
index 1682cb4..20a3f8f 100644
--- a/electrum/wallet.py
+++ b/electrum/wallet.py
@@ -1840,19 +1840,7 @@ class Abstract_Wallet(ABC, Logger, EventListener):
else:
change_addrs = [preferred_change_addr]
elif self.use_change:
- # Recalc and get unused change addresses
- addrs = self.calc_unused_change_addresses()
- # New change addresses are created only after a few
- # confirmations.
- if addrs:
- # if there are any unused, select all
- change_addrs = addrs
- else:
- # if there are none, take one randomly from the last few
- if not allow_reusing_used_change_addrs:
- return []
- addrs = self.get_change_addresses(slice_start=-self.gap_limit_for_change)
- change_addrs = [random.choice(addrs)] if addrs else []
+ change_addrs = self._get_change_addresses_we_can_use_now(allow_reuse=allow_reusing_used_change_addrs)
for addr in change_addrs:
assert is_address(addr), f"not valid bitcoin address: {addr}"
# note that change addresses are not necessarily ismine
@@ -1872,21 +1860,37 @@ class Abstract_Wallet(ABC, Logger, EventListener):
return addrs[0]
return None
- @check_returned_address_for_corruption
def get_new_sweep_address_for_channel(self) -> str:
+ addrs = self._get_change_addresses_we_can_use_now(allow_reuse=True)
+ if addrs:
+ return addrs[0]
+ # fallback for e.g. imported wallets
+ return self.get_receiving_address()
+
+ def _get_change_addresses_we_can_use_now(
+ self,
+ *,
+ allow_reuse: bool = True,
+ ) -> Sequence[str]:
# Recalc and get unused change addresses
addrs = self.calc_unused_change_addresses()
+ # New change addresses are created only after a few
+ # confirmations.
if addrs:
- selected_addr = addrs[0]
+ # if there are any unused, select all
+ change_addrs = addrs
else:
# if there are none, take one randomly from the last few
+ if not allow_reuse:
+ return []
addrs = self.get_change_addresses(slice_start=-self.gap_limit_for_change)
- if addrs:
- selected_addr = random.choice(addrs)
- else: # fallback for e.g. imported wallets
- selected_addr = self.get_receiving_address()
- assert is_address(selected_addr), f"not valid bitcoin address: {selected_addr}"
- return selected_addr
+ change_addrs = [random.choice(addrs)] if addrs else []
+ for addr in change_addrs:
+ assert is_address(addr), f"not valid bitcoin address: {addr}"
+ # note that change addresses are not necessarily ismine
+ # in which case this is a no-op
+ self.check_address_for_corruption(addr)
+ return change_addrs
def should_keep_reserve_utxo(
self,
Why this scored 12/100
Community notes
Notes can correct, qualify, or add evidence to the AI analysis. Every note shown here has been validated by a human moderator.
The AI analysis stands alone for now. Submit a note if you can add evidence or important context.