From 33d0e6dbec81585b539ce6c237a7a35ee6e3a726 Mon Sep 17 00:00:00 2001 From: ThomasV Date: Thu, 12 Dec 2024 12:25:07 +0100 Subject: [PATCH] Attach labels to outpoints instead of txids. Move labels logic from lnworker to wallet. Due to batching, a single transaction may have several labels attached to it. --- electrum/lnsweep.py | 4 ++-- electrum/lnwatcher.py | 2 ++ electrum/lnworker.py | 15 +++++---------- electrum/wallet.py | 27 +++++++++++++++++++++++++-- 4 files changed, 34 insertions(+), 14 deletions(-) diff --git a/electrum/lnsweep.py b/electrum/lnsweep.py index eb1f01726..b88ea833c 100644 --- a/electrum/lnsweep.py +++ b/electrum/lnsweep.py @@ -248,7 +248,7 @@ def sweep_their_htlctx_justice( for output_idx in htlc_outputs_idxs: prevout = htlc_tx.txid() + f':{output_idx}' index_to_sweepinfo[prevout] = SweepInfo( - name='redeem_htlc2', + name=f'second-stage-htlc:{output_idx}', csv_delay=0, cltv_abs=None, txin=justice_txin(output_idx), @@ -401,7 +401,7 @@ def sweep_our_ctx( is_revocation=False, config=chan.lnworker.config) txs[actual_htlc_tx.txid() + f':{output_idx}'] = SweepInfo( - name='second-stage-htlc', + name=f'second-stage-htlc:{output_idx}', csv_delay=to_self_delay, cltv_abs=0, txin=sweep_txin, diff --git a/electrum/lnwatcher.py b/electrum/lnwatcher.py index ce3db8911..47f445f8f 100644 --- a/electrum/lnwatcher.py +++ b/electrum/lnwatcher.py @@ -239,6 +239,7 @@ class LNWalletWatcher(LNWatcher): for prevout, sweep_info in sweep_info_dict.items(): prev_txid, prev_index = prevout.split(':') name = sweep_info.name + ' ' + chan.get_id_for_log() + self.lnworker.wallet.set_default_label(prevout, name) if not self.adb.get_transaction(prev_txid): # do not keep watching if prevout does not exist self.logger.info(f'prevout does not exist for {name}: {prev_txid}') @@ -250,6 +251,7 @@ class LNWalletWatcher(LNWatcher): htlc_sweepinfo = chan.maybe_sweep_htlcs(closing_tx, spender_tx) for prevout2, htlc_sweep_info in htlc_sweepinfo.items(): htlc_tx_spender = self.get_spender(prevout2) + self.lnworker.wallet.set_default_label(prevout2, htlc_sweep_info.name) if htlc_tx_spender: keep_watching |= not self.is_deeply_mined(htlc_tx_spender) else: diff --git a/electrum/lnworker.py b/electrum/lnworker.py index c384a2ebd..b4b8ce734 100644 --- a/electrum/lnworker.py +++ b/electrum/lnworker.py @@ -263,7 +263,6 @@ class LNWorker(Logger, EventListener, NetworkRetryManager[LNPeerAddr]): self.network = None # type: Optional[Network] self.config = config self.stopping_soon = False # whether we are being shut down - self._labels_cache = {} # txid -> str self.register_callbacks() @property @@ -1077,9 +1076,6 @@ class LNWallet(LNWorker): out[payment_hash] = item return out - def get_label_for_txid(self, txid: str) -> str: - return self._labels_cache.get(txid) - def get_onchain_history(self): out = {} # add funding events @@ -1089,11 +1085,11 @@ class LNWallet(LNWorker): continue funding_txid, funding_height, funding_timestamp = item tx_height = self.wallet.adb.get_tx_height(funding_txid) - self._labels_cache[funding_txid] = _('Open channel') + ' ' + chan.get_id_for_log() + self.wallet.set_default_label(chan.funding_outpoint.to_str(), _('Open channel') + ' ' + chan.get_id_for_log()) item = { 'channel_id': chan.channel_id.hex(), 'type': 'channel_opening', - 'label': self.get_label_for_txid(funding_txid), + 'label': self.wallet.get_label_for_txid(funding_txid), 'txid': funding_txid, 'amount_msat': chan.balance(LOCAL, ctn=0), 'direction': PaymentDirection.RECEIVED, @@ -1112,11 +1108,11 @@ class LNWallet(LNWorker): continue closing_txid, closing_height, closing_timestamp = item tx_height = self.wallet.adb.get_tx_height(closing_txid) - self._labels_cache[closing_txid] = _('Close channel') + ' ' + chan.get_id_for_log() + self.wallet.set_default_label(closing_txid, _('Close channel') + ' ' + chan.get_id_for_log()) item = { 'channel_id': chan.channel_id.hex(), 'txid': closing_txid, - 'label': self.get_label_for_txid(closing_txid), + 'label': self.wallet.get_label_for_txid(closing_txid), 'type': 'channel_closure', 'amount_msat': -chan.balance_minus_outgoing_htlcs(LOCAL), 'direction': PaymentDirection.SENT, @@ -1136,7 +1132,7 @@ class LNWallet(LNWorker): group_id = v.get('group_id') group_label = v.get('group_label') if group_id and group_label: - self._labels_cache[group_id] = group_label + self.wallet.set_default_label(group_id, group_label) out.update(d) return out @@ -1329,7 +1325,6 @@ class LNWallet(LNWorker): util.trigger_callback('channels_updated', self.wallet) self.wallet.adb.add_transaction(funding_tx) # save tx as local into the wallet self.wallet.sign_transaction(funding_tx, password) - self.wallet.set_label(funding_tx.txid(), _('Open channel')) if funding_tx.is_complete() and not zeroconf: await self.network.try_broadcasting(funding_tx, 'open_channel') return chan, funding_tx diff --git a/electrum/wallet.py b/electrum/wallet.py index 66664d95b..2f6a851dc 100644 --- a/electrum/wallet.py +++ b/electrum/wallet.py @@ -411,6 +411,7 @@ class Abstract_Wallet(ABC, Logger, EventListener): self.transaction_lock = self.adb.transaction_lock self._last_full_history = None self._tx_parents_cache = {} + self._default_labels = {} self.taskgroup = OldTaskGroup() @@ -1625,11 +1626,33 @@ class Abstract_Wallet(ABC, Logger, EventListener): label = request.get_message() return label + def set_default_label(self, key:str, value:str): + self._default_labels[key] = value + + def get_label_for_outpoint(self, outpoint:str) -> str: + return self._labels.get(outpoint) or self._get_default_label_for_outpoint(outpoint) + + def _get_default_label_for_outpoint(self, outpoint: str) -> str: + return self._default_labels.get(outpoint) + def get_label_for_txid(self, tx_hash: str) -> str: return self._labels.get(tx_hash) or self._get_default_label_for_txid(tx_hash) def _get_default_label_for_txid(self, tx_hash: str) -> str: + if label := self._default_labels.get(tx_hash): + return label labels = [] + tx = self.adb.get_transaction(tx_hash) + if tx: + for i in range(len(tx.outputs())): + outpoint = tx_hash + f':{i}' + if label := self.get_label_for_outpoint(outpoint): + labels.append(label) + for txin in tx.inputs(): + outpoint = txin.prevout.to_str() + if label := self.get_label_for_outpoint(outpoint): + labels.append(label) + # note: we don't deserialize tx as the history calls us for every tx, and that would be slow if not self.db.get_txi_addresses(tx_hash): # no inputs are ismine -> likely incoming payment -> concat labels of output addresses @@ -1642,8 +1665,8 @@ class Abstract_Wallet(ABC, Logger, EventListener): for invoice in self.get_relevant_invoices_for_tx(tx_hash): if invoice.message: labels.append(invoice.message) - if not labels and self.lnworker and (label:= self.lnworker.get_label_for_txid(tx_hash)): - labels.append(label) + #if not labels and self.lnworker and (label:= self.lnworker.get_label_for_txid(tx_hash)): + # labels.append(label) return ', '.join(labels) def _get_default_label_for_rhash(self, rhash: str) -> str: