From 30650c524cefd979963f60cef7b5da3e81ab67bc Mon Sep 17 00:00:00 2001 From: SomberNight Date: Mon, 4 Apr 2022 19:24:29 +0200 Subject: [PATCH] address_sync: "up_to_date" now waits for SPV --- electrum/address_synchronizer.py | 7 ++++--- electrum/gui/stdio.py | 4 +++- electrum/gui/text.py | 6 +++--- electrum/synchronizer.py | 10 ++++++++-- electrum/wallet.py | 12 +++++++++--- 5 files changed, 27 insertions(+), 12 deletions(-) diff --git a/electrum/address_synchronizer.py b/electrum/address_synchronizer.py index 8782557f9..04cff9dfe 100644 --- a/electrum/address_synchronizer.py +++ b/electrum/address_synchronizer.py @@ -90,7 +90,7 @@ class AddressSynchronizer(Logger): # Txs the server claims are in the mempool: self.unconfirmed_tx = defaultdict(int) # type: Dict[str, int] # txid -> height. Access with self.lock. # true when synchronized - self._up_to_date = False + self._up_to_date = False # considers both Synchronizer and Verifier # thread local storage for caching stuff self.threadlocal_cache = threading.local() @@ -922,5 +922,6 @@ class AddressSynchronizer(Logger): c, u, x = self.get_addr_balance(address) return c+u+x == 0 - def synchronize(self): - pass + def synchronize(self) -> int: + """Returns the number of new addresses we generated.""" + return 0 diff --git a/electrum/gui/stdio.py b/electrum/gui/stdio.py index 80990da47..5b0030ce6 100644 --- a/electrum/gui/stdio.py +++ b/electrum/gui/stdio.py @@ -2,10 +2,12 @@ from decimal import Decimal import getpass import datetime import logging +from typing import Optional from electrum.gui import BaseElectrumGui from electrum import util from electrum import WalletStorage, Wallet +from electrum.wallet import Abstract_Wallet from electrum.wallet_db import WalletDB from electrum.util import format_satoshis from electrum.bitcoin import is_address, COIN @@ -41,7 +43,7 @@ class ElectrumGui(BaseElectrumGui): self.str_amount = "" self.str_fee = "" - self.wallet = Wallet(db, storage, config=config) + self.wallet = Wallet(db, storage, config=config) # type: Optional[Abstract_Wallet] self.wallet.start_network(self.network) self.contacts = self.wallet.contacts diff --git a/electrum/gui/text.py b/electrum/gui/text.py index 5814b8ef5..749661074 100644 --- a/electrum/gui/text.py +++ b/electrum/gui/text.py @@ -6,7 +6,7 @@ import locale from decimal import Decimal import getpass import logging -from typing import TYPE_CHECKING +from typing import TYPE_CHECKING, Optional import electrum from electrum.gui import BaseElectrumGui @@ -14,7 +14,7 @@ from electrum import util from electrum.util import format_satoshis from electrum.bitcoin import is_address, COIN from electrum.transaction import PartialTxOutput -from electrum.wallet import Wallet +from electrum.wallet import Wallet, Abstract_Wallet from electrum.wallet_db import WalletDB from electrum.storage import WalletStorage from electrum.network import NetworkParameters, TxBroadcastError, BestEffortRequestFailed @@ -42,7 +42,7 @@ class ElectrumGui(BaseElectrumGui): password = getpass.getpass('Password:', stream=None) storage.decrypt(password) db = WalletDB(storage.read(), manual_upgrades=False) - self.wallet = Wallet(db, storage, config=config) + self.wallet = Wallet(db, storage, config=config) # type: Optional[Abstract_Wallet] self.wallet.start_network(self.network) self.contacts = self.wallet.contacts diff --git a/electrum/synchronizer.py b/electrum/synchronizer.py index dacfed265..14945a718 100644 --- a/electrum/synchronizer.py +++ b/electrum/synchronizer.py @@ -260,8 +260,14 @@ class Synchronizer(SynchronizerBase): # main loop while True: await asyncio.sleep(0.1) - await run_in_thread(self.wallet.synchronize) - up_to_date = self.is_up_to_date() + # note: we only generate new HD addresses if the existing ones + # have history that are mined and SPV-verified. This inherently couples + # the Sychronizer and the Verifier. + hist_done = self.is_up_to_date() + spv_done = self.wallet.verifier.is_up_to_date() if self.wallet.verifier else True + num_new_addrs = await run_in_thread(self.wallet.synchronize) + up_to_date = hist_done and spv_done and num_new_addrs == 0 + # see if status changed if (up_to_date != self.wallet.is_up_to_date() or up_to_date and self._processed_some_notifications): self._processed_some_notifications = False diff --git a/electrum/wallet.py b/electrum/wallet.py index 5a8edf2e8..aafdfa35e 100644 --- a/electrum/wallet.py +++ b/electrum/wallet.py @@ -3043,11 +3043,13 @@ class Deterministic_Wallet(Abstract_Wallet): self._not_old_change_addresses.append(address) return address - def synchronize_sequence(self, for_change): + def synchronize_sequence(self, for_change: bool) -> int: + count = 0 # num new addresses we generated limit = self.gap_limit_for_change if for_change else self.gap_limit while True: num_addr = self.db.num_change_addresses() if for_change else self.db.num_receiving_addresses() if num_addr < limit: + count += 1 self.create_new_address(for_change) continue if for_change: @@ -3055,15 +3057,19 @@ class Deterministic_Wallet(Abstract_Wallet): else: last_few_addresses = self.get_receiving_addresses(slice_start=-limit) if any(map(self.address_is_old, last_few_addresses)): + count += 1 self.create_new_address(for_change) else: break + return count @AddressSynchronizer.with_local_height_cached def synchronize(self): + count = 0 with self.lock: - self.synchronize_sequence(False) - self.synchronize_sequence(True) + count += self.synchronize_sequence(False) + count += self.synchronize_sequence(True) + return count def get_all_known_addresses_beyond_gap_limit(self): # note that we don't stop at first large gap