address_sync: "up_to_date" now waits for SPV
This commit is contained in:
@@ -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
|
||||||
|
|||||||
@@ -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,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
|
||||||
|
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
Reference in New Issue
Block a user