From 838490fea44e9f06c5e3ff78005285f9d5edf933 Mon Sep 17 00:00:00 2001 From: SomberNight Date: Fri, 10 Jan 2025 12:24:26 +0000 Subject: [PATCH] adb.add_transaction: try to ser-deser tx early Previously calling add_transaction with a malformed Transaction obj could result in an exception late in the flow, after the walletdb was already side-effected. Rollback of such side-effects is not implemented :/ but this small patch should at least cover and prevent some common cases. ``` File "/opt/electrum/electrum/address_synchronizer.py", line 358, in add_transaction self.db.add_transaction(tx_hash, tx) File "/opt/electrum/electrum/json_db.py", line 42, in wrapper return func(self, *args, **kwargs) File "/opt/electrum/electrum/wallet_db.py", line 1434, in add_transaction tx = tx_from_any(str(tx)) File "/opt/electrum/electrum/transaction.py", line 1339, in tx_from_any raise SerializationError(f"Failed to recognise tx encoding, or to parse transaction. " ``` --- electrum/address_synchronizer.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/electrum/address_synchronizer.py b/electrum/address_synchronizer.py index 413409b84..1d559a762 100644 --- a/electrum/address_synchronizer.py +++ b/electrum/address_synchronizer.py @@ -31,7 +31,7 @@ from .crypto import sha256 from . import bitcoin, util from .bitcoin import COINBASE_MATURITY from .util import profiler, bfh, TxMinedInfo, UnrelatedTransactionException, with_lock, OldTaskGroup -from .transaction import Transaction, TxOutput, TxInput, PartialTxInput, TxOutpoint, PartialTransaction +from .transaction import Transaction, TxOutput, TxInput, PartialTxInput, TxOutpoint, PartialTransaction, tx_from_any from .synchronizer import Synchronizer from .verifier import SPV from .blockchain import hash_header, Blockchain @@ -275,6 +275,8 @@ class AddressSynchronizer(Logger, EventListener): tx_hash = tx.txid() if tx_hash is None: raise Exception("cannot add tx without txid to wallet history") + # For sanity, try to serialize and deserialize tx early: + tx_from_any(str(tx)) # see if raises (no-side-effects) # we need self.transaction_lock but get_tx_height will take self.lock # so we need to take that too here, to enforce order of locks with self.lock, self.transaction_lock: