From 05599eeda564f6d29928d2d58ed64ad09bfe0a99 Mon Sep 17 00:00:00 2001 From: SomberNight Date: Wed, 13 Mar 2024 11:09:09 +0000 Subject: [PATCH] swaps: fix get_swap_by_funding_tx, and types/type-hints - funding txs having only one output is not true... - batch_rbf can combine funding txs --- electrum/submarine_swaps.py | 19 +++++++++++++------ electrum/wallet.py | 9 +++++---- 2 files changed, 18 insertions(+), 10 deletions(-) diff --git a/electrum/submarine_swaps.py b/electrum/submarine_swaps.py index 6b5fb5480f3d..db3db306b553 100644 --- a/electrum/submarine_swaps.py +++ b/electrum/submarine_swaps.py @@ -1,7 +1,7 @@ import asyncio import json import os -from typing import TYPE_CHECKING, Optional, Dict, Union, Sequence, Tuple +from typing import TYPE_CHECKING, Optional, Dict, Union, Sequence, Tuple, Iterable from decimal import Decimal import math import time @@ -294,6 +294,7 @@ async def _claim_swap(self, swap: SwapData) -> None: if txin: # the swap is funded + # note: swap.funding_txid can change due to RBF, it will get updated here: swap.funding_txid = txin.prevout.txid.hex() swap._funding_prevout = txin.prevout self._add_or_reindex_swap(swap) # to update _swaps_by_funding_outpoint @@ -1012,13 +1013,19 @@ def get_send_amount(self, recv_amount: Optional[int], *, is_reverse: bool) -> Op f"recv_amount={recv_amount} -> send_amount={send_amount} -> inverted_recv_amount={inverted_recv_amount}") return send_amount - def get_swap_by_funding_tx(self, tx: Transaction) -> Optional[SwapData]: - if len(tx.outputs()) != 1: - return False - prevout = TxOutpoint(txid=bytes.fromhex(tx.txid()), out_idx=0) - return self._swaps_by_funding_outpoint.get(prevout) + def get_swaps_by_funding_tx(self, tx: Transaction) -> Iterable[SwapData]: + swaps = [] + for txout_idx, _txo in enumerate(tx.outputs()): + prevout = TxOutpoint(txid=bytes.fromhex(tx.txid()), out_idx=txout_idx) + if swap := self._swaps_by_funding_outpoint.get(prevout): + swaps.append(swap) + return swaps def get_swap_by_claim_tx(self, tx: Transaction) -> Optional[SwapData]: + # note: we don't batch claim txs atm (batch_rbf cannot combine them + # as the inputs do not belong to the wallet) + if not (len(tx.inputs()) == 1 and len(tx.outputs()) == 1): + return None txin = tx.inputs()[0] return self.get_swap_by_claim_txin(txin) diff --git a/electrum/wallet.py b/electrum/wallet.py index 5b4e705dafd0..b1fa943f0052 100644 --- a/electrum/wallet.py +++ b/electrum/wallet.py @@ -91,6 +91,7 @@ if TYPE_CHECKING: from .network import Network from .exchange_rate import FxThread + from .submarine_swaps import SwapData _logger = get_logger(__name__) @@ -838,11 +839,11 @@ def is_lightning_funding_tx(self, txid: Optional[str]) -> bool: return True return False - def get_swap_by_claim_tx(self, tx: Transaction) -> bool: + def get_swap_by_claim_tx(self, tx: Transaction) -> Optional['SwapData']: return self.lnworker.swap_manager.get_swap_by_claim_tx(tx) if self.lnworker else None - def get_swap_by_funding_tx(self, tx: Transaction) -> bool: - return bool(self.lnworker.swap_manager.get_swap_by_funding_tx(tx)) if self.lnworker else None + def get_swaps_by_funding_tx(self, tx: Transaction) -> Iterable['SwapData']: + return self.lnworker.swap_manager.get_swaps_by_funding_tx(tx) if self.lnworker else [] def get_wallet_delta(self, tx: Transaction) -> TxWalletDelta: """Return the effect a transaction has on the wallet. @@ -2049,7 +2050,7 @@ def get_bumpfee_strategies_for_tx( if invoices[0].outputs[0].value == '!': return all_strats, all_strats.index(BumpFeeStrategy.DECREASE_PAYMENT) # do not decrease payment if it is a swap - if self.get_swap_by_funding_tx(tx): + if self.get_swaps_by_funding_tx(tx): return [BumpFeeStrategy.PRESERVE_PAYMENT], 0 # default return all_strats, all_strats.index(BumpFeeStrategy.PRESERVE_PAYMENT)