From ee52154542aa4daa48fe4288c9f683056a109006 Mon Sep 17 00:00:00 2001 From: SomberNight Date: Wed, 26 Apr 2023 13:08:27 +0000 Subject: [PATCH] transaction: TxInput: store addr/spk/value_sats, instead of re-calc We were re-calculating txin.address from the prevtx-utxo on every call, e.g. in electrum/gui/qt/utxo_list.py#L103 (for every utxo in the wallet). For a wallet with ~1300 utxos, UTXOList.update() took ~3.2 sec before this, now it's ~0.8 sec. --- electrum/transaction.py | 24 +++++++++++++----------- 1 file changed, 13 insertions(+), 11 deletions(-) diff --git a/electrum/transaction.py b/electrum/transaction.py index b5bf0705e..d30183ffc 100644 --- a/electrum/transaction.py +++ b/electrum/transaction.py @@ -265,6 +265,9 @@ class TxInput: self.spent_height = None # type: Optional[int] # height at which the TXO got spent self.spent_txid = None # type: Optional[str] # txid of the spender self._utxo = None # type: Optional[Transaction] + self.__scriptpubkey = None # type: Optional[bytes] + self.__address = None # type: Optional[str] + self.__value_sats = None # type: Optional[int] @property def short_id(self): @@ -289,6 +292,11 @@ class TxInput: return self.validate_data(utxo=tx) self._utxo = tx + # update derived fields + out_idx = self.prevout.out_idx + self.__scriptpubkey = self._utxo.outputs()[out_idx].scriptpubkey + self.__address = get_address_from_output_script(self.__scriptpubkey) + self.__value_sats = self._utxo.outputs()[out_idx].value def validate_data(self, *, utxo: Optional['Transaction'] = None, **kwargs) -> None: utxo = utxo or self.utxo @@ -308,23 +316,15 @@ class TxInput: return self._is_coinbase_output def value_sats(self) -> Optional[int]: - if self.utxo: - out_idx = self.prevout.out_idx - return self.utxo.outputs()[out_idx].value - return None + return self.__value_sats @property def address(self) -> Optional[str]: - if self.scriptpubkey: - return get_address_from_output_script(self.scriptpubkey) - return None + return self.__address @property def scriptpubkey(self) -> Optional[bytes]: - if self.utxo: - out_idx = self.prevout.out_idx - return self.utxo.outputs()[out_idx].scriptpubkey - return None + return self.__scriptpubkey def to_json(self): d = { @@ -1560,6 +1560,8 @@ class PartialTxInput(TxInput, PSBTSection): return addr if self._trusted_address is not None: return self._trusted_address + if self.witness_utxo: + return self.witness_utxo.address return None @property