From 248e50eed0ca1f123ffa3afe55b10c7fda97bbe1 Mon Sep 17 00:00:00 2001 From: SomberNight Date: Wed, 17 Jan 2024 02:08:15 +0000 Subject: [PATCH] transaction: rename tx.is_final to tx.is_rbf_enabled, and invert it --- electrum/gui/qml/qetxdetails.py | 8 ++++---- electrum/gui/qt/transaction_dialog.py | 2 +- electrum/transaction.py | 6 +++--- electrum/wallet.py | 13 ++++++------- 4 files changed, 14 insertions(+), 15 deletions(-) diff --git a/electrum/gui/qml/qetxdetails.py b/electrum/gui/qml/qetxdetails.py index 451290ed3..79a6a1adb 100644 --- a/electrum/gui/qml/qetxdetails.py +++ b/electrum/gui/qml/qetxdetails.py @@ -55,7 +55,7 @@ class QETxDetails(QObject, QtEventListener): self._is_unrelated = False self._is_complete = False self._is_mined = False - self._is_final = False + self._is_rbf_enabled = False self._lock_delay = 0 self._sighash_danger = TxSighashDanger() @@ -244,8 +244,8 @@ class QETxDetails(QObject, QtEventListener): return self._is_complete @pyqtProperty(bool, notify=detailsChanged) - def isFinal(self): - return self._is_final + def isRbfEnabled(self): + return self._is_rbf_enabled @pyqtProperty(int, notify=detailsChanged) def lockDelay(self): @@ -339,7 +339,7 @@ class QETxDetails(QObject, QtEventListener): self._lnamount.satsInt = 0 self._is_complete = self._tx.is_complete() - self._is_final = self._tx.is_final() + self._is_rbf_enabled = self._tx.is_rbf_enabled() self._is_unrelated = txinfo.amount is None and self._lnamount.isEmpty self._is_lightning_funding_tx = txinfo.is_lightning_funding_tx self._can_broadcast = txinfo.can_broadcast diff --git a/electrum/gui/qt/transaction_dialog.py b/electrum/gui/qt/transaction_dialog.py index d360cdc4f..bc492c942 100644 --- a/electrum/gui/qt/transaction_dialog.py +++ b/electrum/gui/qt/transaction_dialog.py @@ -838,7 +838,7 @@ class TxDialog(QDialog, MessageBoxMixin): locktime_final_str = f"LockTime: {self.tx.locktime} ({datetime.datetime.fromtimestamp(self.tx.locktime)})" self.locktime_final_label.setText(locktime_final_str) - self.rbf_label.setText(_('Replace by fee') + f": {not self.tx.is_final()}") + self.rbf_label.setText(_('Replace by fee') + f": {self.tx.is_rbf_enabled()}") if tx_mined_status.header_hash: self.block_height_label.setText(_("At block height: {}") diff --git a/electrum/transaction.py b/electrum/transaction.py index e40421145..95fca9522 100644 --- a/electrum/transaction.py +++ b/electrum/transaction.py @@ -1069,9 +1069,9 @@ class Transaction: return False return True - def is_final(self) -> bool: - """Whether RBF is disabled.""" - return not any([txin.nsequence < 0xffffffff - 1 for txin in self.inputs()]) + def is_rbf_enabled(self) -> bool: + """Whether the tx explicitly signals BIP-0125 replace-by-fee.""" + return any([txin.nsequence < 0xffffffff - 1 for txin in self.inputs()]) def estimated_size(self): """Return an estimated virtual tx size in vbytes. diff --git a/electrum/wallet.py b/electrum/wallet.py index 5c82eb647..28a0bb55d 100644 --- a/electrum/wallet.py +++ b/electrum/wallet.py @@ -922,8 +922,8 @@ class Abstract_Wallet(ABC, Logger, EventListener): size = tx.estimated_size() fee_per_byte = fee / size exp_n = self.config.fee_to_depth(fee_per_byte) - can_bump = (is_any_input_ismine or is_swap) and not tx.is_final() - can_dscancel = (is_any_input_ismine and not tx.is_final() + can_bump = (is_any_input_ismine or is_swap) and tx.is_rbf_enabled() + can_dscancel = (is_any_input_ismine and tx.is_rbf_enabled() and not all([self.is_mine(txout.address) for txout in tx.outputs()])) try: self.cpfp(tx, 0) @@ -937,7 +937,7 @@ class Abstract_Wallet(ABC, Logger, EventListener): num_blocks_remainining = max(0, num_blocks_remainining) status = _('Local (future: {})').format(_('in {} blocks').format(num_blocks_remainining)) can_broadcast = self.network is not None - can_bump = (is_any_input_ismine or is_swap) and not tx.is_final() + can_bump = (is_any_input_ismine or is_swap) and tx.is_rbf_enabled() else: status = _("Signed") can_broadcast = self.network is not None @@ -1650,7 +1650,6 @@ class Abstract_Wallet(ABC, Logger, EventListener): tx = self.db.get_transaction(tx_hash) if not tx: return 2, _("unknown") - is_final = tx and tx.is_final() fee = self.adb.get_tx_fee(tx_hash) if fee is not None: size = tx.estimated_size() @@ -1713,7 +1712,7 @@ class Abstract_Wallet(ABC, Logger, EventListener): if self.is_lightning_funding_tx(txid): continue # tx must have opted-in for RBF (even if local, for consistency) - if tx.is_final(): + if not tx.is_rbf_enabled(): continue # reject merge if we need to spend outputs from the base tx remaining_amount = sum(c.value_sats() for c in coins if c.prevout.txid.hex() != tx.txid()) @@ -2079,7 +2078,7 @@ class Abstract_Wallet(ABC, Logger, EventListener): tx = PartialTransaction.from_tx(tx) assert isinstance(tx, PartialTransaction) tx.remove_signatures() - if tx.is_final(): + if not tx.is_rbf_enabled(): raise CannotBumpFee(_('Transaction is final')) new_fee_rate = quantize_feerate(new_fee_rate) # strip excess precision tx.add_info_from_wallet(self) @@ -2344,7 +2343,7 @@ class Abstract_Wallet(ABC, Logger, EventListener): assert isinstance(tx, PartialTransaction) tx.remove_signatures() - if tx.is_final(): + if not tx.is_rbf_enabled(): raise CannotDoubleSpendTx(_('Transaction is final')) new_fee_rate = quantize_feerate(new_fee_rate) # strip excess precision tx.add_info_from_wallet(self)