electrum

Electrum Bitcoin wallet
git clone https://git.parazyd.org/electrum
Log | Files | Refs | Submodules

commit 7a574c3cbc03c982dfa6e8ea40a3a97c33afce7a
parent 32acc2b10e2049371b38aba875f2f830f06c4676
Author: SomberNight <somber.night@protonmail.com>
Date:   Mon,  2 Mar 2020 05:11:08 +0100

wallet/GUI: don't allow "removing" a LN force-close-tx from history

Diffstat:
Melectrum/address_synchronizer.py | 2+-
Melectrum/gui/kivy/uix/dialogs/tx_dialog.py | 4++--
Melectrum/gui/qt/history_list.py | 16+++++++---------
Melectrum/wallet.py | 5+++++
4 files changed, 15 insertions(+), 12 deletions(-)

diff --git a/electrum/address_synchronizer.py b/electrum/address_synchronizer.py @@ -345,7 +345,7 @@ class AddressSynchronizer(Logger): prevout = TxOutpoint(bfh(tx_hash), idx) self.db.remove_prevout_by_scripthash(scripthash, prevout=prevout, value=txo.value) - def get_depending_transactions(self, tx_hash): + def get_depending_transactions(self, tx_hash: str) -> Set[str]: """Returns all (grand-)children of tx_hash in this wallet.""" with self.transaction_lock: children = set() diff --git a/electrum/gui/kivy/uix/dialogs/tx_dialog.py b/electrum/gui/kivy/uix/dialogs/tx_dialog.py @@ -186,7 +186,7 @@ class TxDialog(Factory.Popup): for dict_entry in self.ids.output_list.data: dict_entry['color'], dict_entry['background_color'] = address_colors(self.wallet, dict_entry['address']) - self.is_local_tx = tx_mined_status.height == TX_HEIGHT_LOCAL + self.can_remove_tx = tx_details.can_remove self.update_action_button() def update_action_button(self): @@ -195,7 +195,7 @@ class TxDialog(Factory.Popup): ActionButtonOption(text=_('Sign'), func=lambda btn: self.do_sign(), enabled=self.can_sign), ActionButtonOption(text=_('Broadcast'), func=lambda btn: self.do_broadcast(), enabled=self.can_broadcast), ActionButtonOption(text=_('Bump fee'), func=lambda btn: self.do_rbf(), enabled=self.can_rbf), - ActionButtonOption(text=_('Remove'), func=lambda btn: self.remove_local_tx(), enabled=self.is_local_tx), + ActionButtonOption(text=_('Remove'), func=lambda btn: self.remove_local_tx(), enabled=self.can_remove_tx), ) num_options = sum(map(lambda o: bool(o.enabled), options)) # if no options available, hide button diff --git a/electrum/gui/qt/history_list.py b/electrum/gui/qt/history_list.py @@ -632,12 +632,11 @@ class HistoryList(MyTreeView, AcceptFileDragDrop): if not tx: return tx_URL = block_explorer_URL(self.config, 'tx', tx_hash) - height = self.wallet.get_tx_height(tx_hash).height - is_relevant, is_mine, v, fee = self.wallet.get_wallet_delta(tx) - is_unconfirmed = height <= 0 + tx_details = self.wallet.get_tx_info(tx) + is_unconfirmed = tx_details.tx_mined_status.height <= 0 invoice_keys = self.wallet._get_relevant_invoice_keys_for_tx(tx) menu = QMenu() - if height in [TX_HEIGHT_FUTURE, TX_HEIGHT_LOCAL]: + if tx_details.can_remove: menu.addAction(_("Remove"), lambda: self.remove_local_tx(tx_hash)) menu.addAction(_("Copy Transaction ID"), lambda: self.place_text_on_clipboard(tx_hash, title="TXID")) self.add_copy_menu(menu, idx) @@ -650,8 +649,7 @@ class HistoryList(MyTreeView, AcceptFileDragDrop): menu.addAction(_("Details"), lambda: self.show_transaction(tx_item, tx)) if is_unconfirmed and tx: # note: the current implementation of RBF *needs* the old tx fee - rbf = is_mine and not tx.is_final() and fee is not None - if rbf: + if tx_details.can_bump and tx_details.fee is not None: menu.addAction(_("Increase fee"), lambda: self.parent.bump_fee_dialog(tx)) else: child_tx = self.wallet.cpfp(tx, 0) @@ -663,9 +661,9 @@ class HistoryList(MyTreeView, AcceptFileDragDrop): menu.addAction(_("View on block explorer"), lambda: webopen(tx_URL)) menu.exec_(self.viewport().mapToGlobal(position)) - def remove_local_tx(self, delete_tx): - to_delete = {delete_tx} - to_delete |= self.wallet.get_depending_transactions(delete_tx) + def remove_local_tx(self, tx_hash: str): + to_delete = {tx_hash} + to_delete |= self.wallet.get_depending_transactions(tx_hash) question = _("Are you sure you want to remove this transaction?") if len(to_delete) > 1: question = (_("Are you sure you want to remove this transaction and {} child transactions?") diff --git a/electrum/wallet.py b/electrum/wallet.py @@ -210,6 +210,7 @@ class TxWalletDetails(NamedTuple): fee: Optional[int] tx_mined_status: TxMinedInfo mempool_depth_bytes: Optional[int] + can_remove: bool # whether user should be allowed to delete tx class Abstract_Wallet(AddressSynchronizer, ABC): @@ -495,6 +496,9 @@ class Abstract_Wallet(AddressSynchronizer, ABC): and (tx_we_already_have_in_db is None or not tx_we_already_have_in_db.is_complete())) label = '' tx_mined_status = self.get_tx_height(tx_hash) + # note: is_relevant check added to 'can_remove' as otherwise 'height' is unreliable (typically LOCAL). + # e.g. user should not be allowed to remove a lightning force-close-tx + can_remove = is_relevant and (tx_mined_status.height in [TX_HEIGHT_FUTURE, TX_HEIGHT_LOCAL]) if tx.is_complete(): if tx_we_already_have_in_db: label = self.get_label(tx_hash) @@ -545,6 +549,7 @@ class Abstract_Wallet(AddressSynchronizer, ABC): fee=fee, tx_mined_status=tx_mined_status, mempool_depth_bytes=exp_n, + can_remove=can_remove, ) def get_spendable_coins(self, domain, *, nonlocal_only=False) -> Sequence[PartialTxInput]: