diff --git a/electrum/commands.py b/electrum/commands.py index ee0763d48..64699ad65 100644 --- a/electrum/commands.py +++ b/electrum/commands.py @@ -675,7 +675,7 @@ class Commands: @command('wp') async def payto(self, destination, amount, fee=None, feerate=None, from_addr=None, from_coins=None, change_addr=None, - nocheck=False, unsigned=False, rbf=None, password=None, locktime=None, addtransaction=False, wallet: Abstract_Wallet = None): + nocheck=False, unsigned=False, rbf=True, password=None, locktime=None, addtransaction=False, wallet: Abstract_Wallet = None): """Create a transaction. """ self.nocheck = nocheck tx_fee = satoshis(fee) diff --git a/electrum/gui/kivy/uix/dialogs/confirm_tx_dialog.py b/electrum/gui/kivy/uix/dialogs/confirm_tx_dialog.py index f308964f2..87caba9ba 100644 --- a/electrum/gui/kivy/uix/dialogs/confirm_tx_dialog.py +++ b/electrum/gui/kivy/uix/dialogs/confirm_tx_dialog.py @@ -26,7 +26,6 @@ Builder.load_string(''' message: '' warning: '' extra_fee: '' - show_final: False size_hint: 0.8, 0.8 pos_hint: {'top':0.9} method: 0 @@ -82,17 +81,6 @@ Builder.load_string(''' range: 0, 4 step: 1 on_value: root.on_slider(self.value) - BoxLayout: - orientation: 'horizontal' - size_hint: 1, 0.2 - Label: - text: _('Final') - opacity: int(root.show_final) - CheckBox: - id: final_cb - opacity: int(root.show_final) - disabled: not root.show_final - on_release: root.update_tx() Label: text: root.warning text_size: self.width, None @@ -122,7 +110,7 @@ Builder.load_string(''' class ConfirmTxDialog(FeeSliderDialog, Factory.Popup): - def __init__(self, app: 'ElectrumWindow', amount, make_tx, on_pay, *, show_final=True): + def __init__(self, app: 'ElectrumWindow', amount, make_tx, on_pay): Factory.Popup.__init__(self) FeeSliderDialog.__init__(self, app.electrum_config, self.ids.slider) @@ -130,16 +118,14 @@ class ConfirmTxDialog(FeeSliderDialog, Factory.Popup): self.amount = amount self.make_tx = make_tx self.on_pay = on_pay - self.show_final = show_final self.update_slider() self.update_text() self.update_tx() def update_tx(self): - rbf = not bool(self.ids.final_cb.active) if self.show_final else False try: # make unsigned transaction - tx = self.make_tx(rbf) + tx = self.make_tx() except NotEnoughFunds: self.warning = _("Not enough funds") self.ids.ok_button.disabled = True diff --git a/electrum/gui/kivy/uix/screens.py b/electrum/gui/kivy/uix/screens.py index 301860306..143e44ae2 100644 --- a/electrum/gui/kivy/uix/screens.py +++ b/electrum/gui/kivy/uix/screens.py @@ -438,7 +438,7 @@ class SendScreen(CScreen, Logger): outputs = invoice.outputs amount = sum(map(lambda x: x.value, outputs)) if not any(parse_max_spend(x.value) for x in outputs) else '!' coins = self.app.wallet.get_spendable_coins(None) - make_tx = lambda rbf: self.app.wallet.make_unsigned_transaction(coins=coins, outputs=outputs, rbf=rbf) + make_tx = lambda: self.app.wallet.make_unsigned_transaction(coins=coins, outputs=outputs) on_pay = lambda tx: self.app.protected(_('Send payment?'), self.send_tx, (tx, invoice)) d = ConfirmTxDialog(self.app, amount=amount, make_tx=make_tx, on_pay=on_pay) d.open() diff --git a/electrum/gui/qml/components/Preferences.qml b/electrum/gui/qml/components/Preferences.qml index f5f53fe42..12d7b2a75 100644 --- a/electrum/gui/qml/components/Preferences.qml +++ b/electrum/gui/qml/components/Preferences.qml @@ -130,16 +130,6 @@ Pane { } } - Switch { - id: useRbf - text: qsTr('Use Replace-By-Fee') - Layout.columnSpan: 2 - onCheckedChanged: { - if (activeFocus) - Config.useRbf = checked - } - } - Label { text: qsTr('Default request expiry') Layout.fillWidth: false @@ -269,7 +259,6 @@ Pane { lnRoutingType.currentIndex = Config.useGossip ? 0 : 1 useFallbackAddress.checked = Config.useFallbackAddress enableDebugLogs.checked = Config.enableDebugLogs - useRbf.checked = Config.useRbf useRecoverableChannels.checked = Config.useRecoverableChannels } } diff --git a/electrum/gui/qml/qeconfig.py b/electrum/gui/qml/qeconfig.py index 4580bdb10..e8a2de2a6 100644 --- a/electrum/gui/qml/qeconfig.py +++ b/electrum/gui/qml/qeconfig.py @@ -146,16 +146,6 @@ class QEConfig(AuthMixin, QObject): self.config.set_key('gui_enable_debug_logs', enable) self.enableDebugLogsChanged.emit() - useRbfChanged = pyqtSignal() - @pyqtProperty(bool, notify=useRbfChanged) - def useRbf(self): - return self.config.get('use_rbf', True) - - @useRbf.setter - def useRbf(self, useRbf): - self.config.set_key('use_rbf', useRbf) - self.useRbfChanged.emit() - useRecoverableChannelsChanged = pyqtSignal() @pyqtProperty(bool, notify=useRecoverableChannelsChanged) def useRecoverableChannels(self): diff --git a/electrum/gui/qml/qewallet.py b/electrum/gui/qml/qewallet.py index 73bce87ce..dfabf9b54 100644 --- a/electrum/gui/qml/qewallet.py +++ b/electrum/gui/qml/qewallet.py @@ -455,9 +455,7 @@ class QEWallet(AuthMixin, QObject, QtEventListener): # see qt/confirm_tx_dialog qt/main_window tx = self.wallet.make_unsigned_transaction(coins=coins,outputs=outputs, fee=None) self._logger.info(str(tx.to_json())) - - use_rbf = bool(self.wallet.config.get('use_rbf', True)) - tx.set_rbf(use_rbf) + tx.set_rbf(True) self.sign(tx, broadcast=True) @auth_protect diff --git a/electrum/gui/qt/confirm_tx_dialog.py b/electrum/gui/qt/confirm_tx_dialog.py index 8b26e24f0..d06723742 100644 --- a/electrum/gui/qt/confirm_tx_dialog.py +++ b/electrum/gui/qt/confirm_tx_dialog.py @@ -113,8 +113,7 @@ class TxEditor: self.tx = None self.main_window.show_error(str(e)) raise - use_rbf = bool(self.config.get('use_rbf', True)) - self.tx.set_rbf(use_rbf) + self.tx.set_rbf(True) def have_enough_funds_assuming_zero_fees(self) -> bool: try: diff --git a/electrum/gui/qt/rbf_dialog.py b/electrum/gui/qt/rbf_dialog.py index 168445269..bf4df3b27 100644 --- a/electrum/gui/qt/rbf_dialog.py +++ b/electrum/gui/qt/rbf_dialog.py @@ -47,6 +47,8 @@ class _BaseRBFDialog(WindowModalDialog): ok_button = OkButton(self) self.adv_button = QPushButton(_("Show advanced settings")) + self.adv_button.setEnabled(False) + self.adv_button.setVisible(False) warning_label = WWLabel('\n') warning_label.setStyleSheet(ColorScheme.RED.as_stylesheet()) self.feerate_e = FeerateEdit(lambda: 0) @@ -115,21 +117,18 @@ class _BaseRBFDialog(WindowModalDialog): vbox.addWidget(adv_widget) def _add_advanced_options(self, adv_vbox: QVBoxLayout) -> None: - self.cb_rbf = QCheckBox(_('Keep Replace-By-Fee enabled')) - self.cb_rbf.setChecked(True) - adv_vbox.addWidget(self.cb_rbf) + pass def run(self) -> None: if not self.exec_(): return - is_rbf = self.cb_rbf.isChecked() new_fee_rate = self.feerate_e.get_amount() try: new_tx = self.rbf_func(new_fee_rate) except Exception as e: self.window.show_error(str(e)) return - new_tx.set_rbf(is_rbf) + new_tx.set_rbf(True) tx_label = self.wallet.get_label_for_txid(self.txid) self.window.show_transaction(new_tx, tx_desc=tx_label) # TODO maybe save tx_label as label for new tx?? @@ -164,10 +163,8 @@ class BumpFeeDialog(_BaseRBFDialog): ) def _add_advanced_options(self, adv_vbox: QVBoxLayout) -> None: - self.cb_rbf = QCheckBox(_('Keep Replace-By-Fee enabled')) - self.cb_rbf.setChecked(True) - adv_vbox.addWidget(self.cb_rbf) - + self.adv_button.setVisible(True) + self.adv_button.setEnabled(True) self.strat_combo = QComboBox() options = [ _("decrease change, or add new inputs, or decrease any outputs"), diff --git a/electrum/gui/qt/settings_dialog.py b/electrum/gui/qt/settings_dialog.py index a88483779..53a71cfe8 100644 --- a/electrum/gui/qt/settings_dialog.py +++ b/electrum/gui/qt/settings_dialog.py @@ -118,21 +118,8 @@ class SettingsDialog(QDialog, QtEventListener): self.config.set_key('bip21_lightning', bool(x)) bip21_lightning_cb.stateChanged.connect(on_bip21_lightning) - use_rbf = bool(self.config.get('use_rbf', True)) - use_rbf_cb = QCheckBox(_('Use Replace-By-Fee')) - use_rbf_cb.setChecked(use_rbf) - use_rbf_cb.setToolTip( - _('If you check this box, your transactions will be marked as non-final,') + '\n' + \ - _('and you will have the possibility, while they are unconfirmed, to replace them with transactions that pay higher fees.') + '\n' + \ - _('Note that some merchants do not accept non-final transactions until they are confirmed.')) - def on_use_rbf(x): - self.config.set_key('use_rbf', bool(x)) - batch_rbf_cb.setEnabled(bool(x)) - use_rbf_cb.stateChanged.connect(on_use_rbf) - - batch_rbf_cb = QCheckBox(_('Batch RBF transactions')) + batch_rbf_cb = QCheckBox(_('Batch unconfirmed transactions')) batch_rbf_cb.setChecked(bool(self.config.get('batch_rbf', False))) - batch_rbf_cb.setEnabled(use_rbf) batch_rbf_cb.setToolTip( _('If you check this box, your unconfirmed transactions will be consolidated into a single transaction.') + '\n' + \ _('This will save fees.')) @@ -505,7 +492,6 @@ class SettingsDialog(QDialog, QtEventListener): invoices_widgets.append((bip21_lightning_cb, None)) tx_widgets = [] tx_widgets.append((usechange_cb, None)) - tx_widgets.append((use_rbf_cb, None)) tx_widgets.append((batch_rbf_cb, None)) tx_widgets.append((preview_cb, None)) tx_widgets.append((unconf_cb, None)) diff --git a/electrum/gui/qt/transaction_dialog.py b/electrum/gui/qt/transaction_dialog.py index 6cc6d98c5..0007b2212 100644 --- a/electrum/gui/qt/transaction_dialog.py +++ b/electrum/gui/qt/transaction_dialog.py @@ -680,9 +680,6 @@ class BaseTxDialog(QDialog, MessageBoxMixin): vbox_right.addWidget(self.size_label) self.rbf_label = TxDetailLabel() vbox_right.addWidget(self.rbf_label) - self.rbf_cb = QCheckBox(_('Replace by fee')) - self.rbf_cb.setChecked(bool(self.config.get('use_rbf', True))) - vbox_right.addWidget(self.rbf_cb) self.locktime_final_label = TxDetailLabel() vbox_right.addWidget(self.locktime_final_label) @@ -713,7 +710,6 @@ class BaseTxDialog(QDialog, MessageBoxMixin): # set visibility after parenting can be determined by Qt self.rbf_label.setVisible(self.finalized) - self.rbf_cb.setVisible(not self.finalized) self.locktime_final_label.setVisible(self.finalized) self.locktime_setter_widget.setVisible(not self.finalized) @@ -982,11 +978,11 @@ class PreviewTxDialog(BaseTxDialog, TxEditor): assert self.tx self.finalized = True self.stop_editor_updates() - self.tx.set_rbf(self.rbf_cb.isChecked()) + self.tx.set_rbf(True) locktime = self.locktime_e.get_locktime() if locktime is not None: self.tx.locktime = locktime - for widget in [self.fee_slider, self.fee_combo, self.feecontrol_fields, self.rbf_cb, + for widget in [self.fee_slider, self.fee_combo, self.feecontrol_fields, self.locktime_setter_widget, self.locktime_e]: widget.setEnabled(False) widget.setVisible(False) diff --git a/electrum/wallet.py b/electrum/wallet.py index 0afc3f5ae..0d5bc6332 100644 --- a/electrum/wallet.py +++ b/electrum/wallet.py @@ -204,8 +204,7 @@ async def sweep( locktime = get_locktime_for_new_transaction(network) tx = PartialTransaction.from_io(inputs, outputs, locktime=locktime, version=tx_version) - rbf = bool(config.get('use_rbf', True)) - tx.set_rbf(rbf) + tx.set_rbf(True) tx.sign(keypairs) return tx @@ -1420,8 +1419,6 @@ class Abstract_Wallet(ABC, Logger, EventListener): if not tx: return 2, 'unknown' is_final = tx and tx.is_final() - if not is_final: - extra.append('rbf') fee = self.adb.get_tx_fee(tx_hash) if fee is not None: size = tx.estimated_size() @@ -1569,7 +1566,7 @@ class Abstract_Wallet(ABC, Logger, EventListener): fee=None, change_addr: str = None, is_sweep=False, - rbf=False) -> PartialTransaction: + rbf=True) -> PartialTransaction: """Can raise NotEnoughFunds or NoDynamicFeeEstimates.""" if not coins: # any bitcoin tx must have at least 1 input by consensus @@ -1668,7 +1665,6 @@ class Abstract_Wallet(ABC, Logger, EventListener): # Timelock tx to current height. tx.locktime = get_locktime_for_new_transaction(self.network) - tx.set_rbf(rbf) tx.add_info_from_wallet(self) run_hook('make_unsigned_transaction', self, tx) @@ -1677,7 +1673,7 @@ class Abstract_Wallet(ABC, Logger, EventListener): def mktx(self, *, outputs: List[PartialTxOutput], password=None, fee=None, change_addr=None, - domain=None, rbf=False, nonlocal_only=False, + domain=None, rbf=True, nonlocal_only=False, tx_version=None, sign=True) -> PartialTransaction: coins = self.get_spendable_coins(domain, nonlocal_only=nonlocal_only) tx = self.make_unsigned_transaction( @@ -2726,7 +2722,7 @@ class Abstract_Wallet(ABC, Logger, EventListener): pass def create_transaction(self, outputs, *, fee=None, feerate=None, change_addr=None, domain_addr=None, domain_coins=None, - unsigned=False, rbf=None, password=None, locktime=None): + unsigned=False, rbf=True, password=None, locktime=None): if fee is not None and feerate is not None: raise Exception("Cannot specify both 'fee' and 'feerate' at the same time!") coins = self.get_spendable_coins(domain_addr) @@ -2744,8 +2740,6 @@ class Abstract_Wallet(ABC, Logger, EventListener): change_addr=change_addr) if locktime is not None: tx.locktime = locktime - if rbf is None: - rbf = bool(self.config.get('use_rbf', True)) tx.set_rbf(rbf) if not unsigned: self.sign_transaction(tx, password)