diff --git a/basicswap/wallet_manager.py b/basicswap/wallet_manager.py index 3739cab..df588c5 100644 --- a/basicswap/wallet_manager.py +++ b/basicswap/wallet_manager.py @@ -38,6 +38,7 @@ class WalletManager: } GAP_LIMIT = 50 + ELECTRUM_GAP_LIMIT = 20 def __init__(self, swap_client, log): self._gap_limits: Dict[Coins, int] = {} @@ -149,6 +150,18 @@ class WalletManager: ) self._swap_client.commitDB() + def _findReusableAddress(self, coin_type: Coins, internal: bool, cursor): + query = ( + "SELECT derivation_index, address FROM wallet_addresses" + " WHERE coin_type = ? AND is_internal = ? AND is_funded = 0" + " ORDER BY derivation_index ASC LIMIT 1" + ) + cursor.execute(query, (int(coin_type), internal)) + row = cursor.fetchone() + if row: + return row[0], row[1] + return None, None + def getNewAddress( self, coin_type: Coins, internal: bool = False, label: str = "", cursor=None ) -> str: @@ -184,6 +197,19 @@ class WalletManager: else: next_index = (state.last_external_index or 0) + 1 + if next_index >= self.ELECTRUM_GAP_LIMIT: + reuse_index, reuse_addr = self._findReusableAddress( + coin_type, internal, use_cursor + ) + if reuse_addr is not None: + self._log.debug( + f"Reusing unfunded address at index {reuse_index}" + f" (next would be {next_index}," + f" electrum gap limit {self.ELECTRUM_GAP_LIMIT})" + ) + self._swap_client.commitDB() + return reuse_addr + existing = self._swap_client.queryOne( WalletAddress, use_cursor,