Browse Source

address_sync: "up_to_date" now waits for SPV

master
SomberNight 4 years ago
parent
commit
30650c524c
No known key found for this signature in database
GPG Key ID: B33B5F232C6271E9
  1. 7
      electrum/address_synchronizer.py
  2. 4
      electrum/gui/stdio.py
  3. 6
      electrum/gui/text.py
  4. 10
      electrum/synchronizer.py
  5. 12
      electrum/wallet.py

7
electrum/address_synchronizer.py

@ -90,7 +90,7 @@ class AddressSynchronizer(Logger):
# Txs the server claims are in the mempool: # Txs the server claims are in the mempool:
self.unconfirmed_tx = defaultdict(int) # type: Dict[str, int] # txid -> height. Access with self.lock. self.unconfirmed_tx = defaultdict(int) # type: Dict[str, int] # txid -> height. Access with self.lock.
# true when synchronized # true when synchronized
self._up_to_date = False self._up_to_date = False # considers both Synchronizer and Verifier
# thread local storage for caching stuff # thread local storage for caching stuff
self.threadlocal_cache = threading.local() self.threadlocal_cache = threading.local()
@ -922,5 +922,6 @@ class AddressSynchronizer(Logger):
c, u, x = self.get_addr_balance(address) c, u, x = self.get_addr_balance(address)
return c+u+x == 0 return c+u+x == 0
def synchronize(self): def synchronize(self) -> int:
pass """Returns the number of new addresses we generated."""
return 0

4
electrum/gui/stdio.py

@ -2,10 +2,12 @@ from decimal import Decimal
import getpass import getpass
import datetime import datetime
import logging import logging
from typing import Optional
from electrum.gui import BaseElectrumGui from electrum.gui import BaseElectrumGui
from electrum import util from electrum import util
from electrum import WalletStorage, Wallet from electrum import WalletStorage, Wallet
from electrum.wallet import Abstract_Wallet
from electrum.wallet_db import WalletDB from electrum.wallet_db import WalletDB
from electrum.util import format_satoshis from electrum.util import format_satoshis
from electrum.bitcoin import is_address, COIN from electrum.bitcoin import is_address, COIN
@ -41,7 +43,7 @@ class ElectrumGui(BaseElectrumGui):
self.str_amount = "" self.str_amount = ""
self.str_fee = "" 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.wallet.start_network(self.network)
self.contacts = self.wallet.contacts self.contacts = self.wallet.contacts

6
electrum/gui/text.py

@ -6,7 +6,7 @@ import locale
from decimal import Decimal from decimal import Decimal
import getpass import getpass
import logging import logging
from typing import TYPE_CHECKING from typing import TYPE_CHECKING, Optional
import electrum import electrum
from electrum.gui import BaseElectrumGui from electrum.gui import BaseElectrumGui
@ -14,7 +14,7 @@ from electrum import util
from electrum.util import format_satoshis from electrum.util import format_satoshis
from electrum.bitcoin import is_address, COIN from electrum.bitcoin import is_address, COIN
from electrum.transaction import PartialTxOutput 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.wallet_db import WalletDB
from electrum.storage import WalletStorage from electrum.storage import WalletStorage
from electrum.network import NetworkParameters, TxBroadcastError, BestEffortRequestFailed from electrum.network import NetworkParameters, TxBroadcastError, BestEffortRequestFailed
@ -42,7 +42,7 @@ class ElectrumGui(BaseElectrumGui):
password = getpass.getpass('Password:', stream=None) password = getpass.getpass('Password:', stream=None)
storage.decrypt(password) storage.decrypt(password)
db = WalletDB(storage.read(), manual_upgrades=False) 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.wallet.start_network(self.network)
self.contacts = self.wallet.contacts self.contacts = self.wallet.contacts

10
electrum/synchronizer.py

@ -260,8 +260,14 @@ class Synchronizer(SynchronizerBase):
# main loop # main loop
while True: while True:
await asyncio.sleep(0.1) await asyncio.sleep(0.1)
await run_in_thread(self.wallet.synchronize) # note: we only generate new HD addresses if the existing ones
up_to_date = self.is_up_to_date() # 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() if (up_to_date != self.wallet.is_up_to_date()
or up_to_date and self._processed_some_notifications): or up_to_date and self._processed_some_notifications):
self._processed_some_notifications = False self._processed_some_notifications = False

12
electrum/wallet.py

@ -3043,11 +3043,13 @@ class Deterministic_Wallet(Abstract_Wallet):
self._not_old_change_addresses.append(address) self._not_old_change_addresses.append(address)
return 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 limit = self.gap_limit_for_change if for_change else self.gap_limit
while True: while True:
num_addr = self.db.num_change_addresses() if for_change else self.db.num_receiving_addresses() num_addr = self.db.num_change_addresses() if for_change else self.db.num_receiving_addresses()
if num_addr < limit: if num_addr < limit:
count += 1
self.create_new_address(for_change) self.create_new_address(for_change)
continue continue
if for_change: if for_change:
@ -3055,15 +3057,19 @@ class Deterministic_Wallet(Abstract_Wallet):
else: else:
last_few_addresses = self.get_receiving_addresses(slice_start=-limit) last_few_addresses = self.get_receiving_addresses(slice_start=-limit)
if any(map(self.address_is_old, last_few_addresses)): if any(map(self.address_is_old, last_few_addresses)):
count += 1
self.create_new_address(for_change) self.create_new_address(for_change)
else: else:
break break
return count
@AddressSynchronizer.with_local_height_cached @AddressSynchronizer.with_local_height_cached
def synchronize(self): def synchronize(self):
count = 0
with self.lock: with self.lock:
self.synchronize_sequence(False) count += self.synchronize_sequence(False)
self.synchronize_sequence(True) count += self.synchronize_sequence(True)
return count
def get_all_known_addresses_beyond_gap_limit(self): def get_all_known_addresses_beyond_gap_limit(self):
# note that we don't stop at first large gap # note that we don't stop at first large gap

Loading…
Cancel
Save