commit 5313591c28b942b118f572b83b97a786c398503a
parent 7b8114f865f644c5611c3bb849c4f4fc6ce9e376
Author: SomberNight <somber.night@protonmail.com>
Date: Fri, 15 Feb 2019 17:22:24 +0100
synchronizer: disconnect from server if cannot deserialize txn
Diffstat:
2 files changed, 17 insertions(+), 13 deletions(-)
diff --git a/electrum/synchronizer.py b/electrum/synchronizer.py
@@ -39,6 +39,9 @@ if TYPE_CHECKING:
from .address_synchronizer import AddressSynchronizer
+class SynchronizerFailure(Exception): pass
+
+
def history_status(h):
if not h:
return None
@@ -194,18 +197,19 @@ class Synchronizer(SynchronizerBase):
raise
tx = Transaction(result)
try:
- tx.deserialize()
- except Exception:
- self.print_msg("cannot deserialize transaction, skipping", tx_hash)
- return
+ tx.deserialize() # see if raises
+ except Exception as e:
+ # possible scenarios:
+ # 1: server is sending garbage
+ # 2: there is a bug in the deserialization code
+ # 3: there was a segwit-like upgrade that changed the tx structure
+ # that we don't know about
+ raise SynchronizerFailure(f"cannot deserialize transaction {tx_hash}") from e
if tx_hash != tx.txid():
- self.print_error("received tx does not match expected txid ({} != {})"
- .format(tx_hash, tx.txid()))
- return
+ raise SynchronizerFailure(f"received tx does not match expected txid ({tx_hash} != {tx.txid()})")
tx_height = self.requested_tx.pop(tx_hash)
self.wallet.receive_tx_callback(tx_hash, tx, tx_height)
- self.print_error("received tx %s height: %d bytes: %d" %
- (tx_hash, tx_height, len(tx.raw)))
+ self.print_error(f"received tx {tx_hash} height: {tx_height} bytes: {len(tx.raw)}")
# callbacks
self.wallet.network.trigger_callback('new_transaction', self.wallet, tx)
diff --git a/electrum/transaction.py b/electrum/transaction.py
@@ -125,7 +125,7 @@ class BCDataStream(object):
self.read_cursor += length
return result
except IndexError:
- raise SerializationError("attempt to read past end of buffer")
+ raise SerializationError("attempt to read past end of buffer") from None
def can_read_more(self) -> bool:
if not self.input:
@@ -159,8 +159,8 @@ class BCDataStream(object):
elif size == 255:
size = self._read_num('<Q')
return size
- except IndexError:
- raise SerializationError("attempt to read past end of buffer")
+ except IndexError as e:
+ raise SerializationError("attempt to read past end of buffer") from e
def write_compact_size(self, size):
if size < 0:
@@ -182,7 +182,7 @@ class BCDataStream(object):
(i,) = struct.unpack_from(format, self.input, self.read_cursor)
self.read_cursor += struct.calcsize(format)
except Exception as e:
- raise SerializationError(e)
+ raise SerializationError(e) from e
return i
def _write_num(self, format, num):