diff --git a/electrum/network.py b/electrum/network.py index 030c50c64..b9e7afb9e 100644 --- a/electrum/network.py +++ b/electrum/network.py @@ -780,7 +780,7 @@ class Network(PrintError): try: return await func(self, *args, **kwargs) except aiorpcx.jsonrpc.CodeMessageError as e: - raise UntrustedServerReturnedError(original_exception=e) + raise UntrustedServerReturnedError(original_exception=e) from e return wrapper @best_effort_reliable diff --git a/electrum/synchronizer.py b/electrum/synchronizer.py index cdde6d248..f327669fa 100644 --- a/electrum/synchronizer.py +++ b/electrum/synchronizer.py @@ -32,6 +32,7 @@ from aiorpcx import TaskGroup, run_in_thread from .transaction import Transaction from .util import bh2u, make_aiohttp_session, NetworkJobOnDefaultServer from .bitcoin import address_to_scripthash, is_address +from .network import UntrustedServerReturnedError if TYPE_CHECKING: from .network import Network @@ -165,7 +166,7 @@ class Synchronizer(SynchronizerBase): # Remove request; this allows up_to_date to be True self.requested_histories.pop(addr) - async def _request_missing_txs(self, hist): + async def _request_missing_txs(self, hist, *, allow_server_not_finding_tx=False): # "hist" is a list of [tx_hash, tx_height] lists transaction_hashes = [] for tx_hash, tx_height in hist: @@ -179,10 +180,18 @@ class Synchronizer(SynchronizerBase): if not transaction_hashes: return async with TaskGroup() as group: for tx_hash in transaction_hashes: - await group.spawn(self._get_transaction, tx_hash) + await group.spawn(self._get_transaction(tx_hash, allow_server_not_finding_tx=allow_server_not_finding_tx)) - async def _get_transaction(self, tx_hash): - result = await self.network.get_transaction(tx_hash) + async def _get_transaction(self, tx_hash, *, allow_server_not_finding_tx=False): + try: + result = await self.network.get_transaction(tx_hash) + except UntrustedServerReturnedError as e: + # most likely, "No such mempool or blockchain transaction" + if allow_server_not_finding_tx: + self.requested_tx.pop(tx_hash) + return + else: + raise tx = Transaction(result) try: tx.deserialize() @@ -207,7 +216,7 @@ class Synchronizer(SynchronizerBase): # Old electrum servers returned ['*'] when all history for the address # was pruned. This no longer happens but may remain in old wallets. if history == ['*']: continue - await self._request_missing_txs(history) + await self._request_missing_txs(history, allow_server_not_finding_tx=True) # add addresses to bootstrap for addr in self.wallet.get_addresses(): await self._add_address(addr)