Browse Source

swaps: when RBF-ing a forward swap tx, payment amt must not decrease

patch-4
SomberNight 3 years ago
parent
commit
357aaff582
No known key found for this signature in database GPG Key ID: B33B5F232C6271E9
  1. 8
      electrum/submarine_swaps.py
  2. 21
      electrum/wallet.py

8
electrum/submarine_swaps.py

@ -300,7 +300,7 @@ class SwapManager(Logger):
dummy_output = PartialTxOutput.from_address_and_value(ln_dummy_address(), expected_onchain_amount_sat)
tx.outputs().remove(dummy_output)
tx.add_outputs([funding_output])
tx.set_rbf(True) # rbf must not decrease payment
tx.set_rbf(True) # note: rbf must not decrease payment
self.wallet.sign_transaction(tx, password)
# save swap data in wallet in case we need a refund
swap = SwapData(
@ -543,6 +543,12 @@ class SwapManager(Logger):
return swap
return None
def is_lockup_address_for_a_swap(self, addr: str) -> bool:
for key, swap in self.swaps.items(): # TODO take lock? or add index to avoid looping
if addr == swap.lockup_address:
return True
return False
def sign_tx(self, tx, swap):
preimage = swap.preimage if swap.is_reverse else 0
witness_script = swap.redeem_script

21
electrum/wallet.py

@ -1713,11 +1713,7 @@ class Abstract_Wallet(AddressSynchronizer, ABC):
s = list(filter(lambda o: self.is_mine(o.address), outputs))
# ... unless there is none
if not s:
s = outputs
x_fee = run_hook('get_tx_extra_fee', self, tx)
if x_fee:
x_fee_address, x_fee_amount = x_fee
s = list(filter(lambda o: o.address != x_fee_address, s))
s = [out for out in outputs if self._is_rbf_allowed_to_touch_tx_output(out)]
if not s:
raise CannotBumpFee('No outputs at all??')
@ -1764,11 +1760,7 @@ class Abstract_Wallet(AddressSynchronizer, ABC):
# select non-ismine outputs
s = [(idx, out) for (idx, out) in enumerate(outputs)
if not self.is_mine(out.address)]
# exempt 2fa fee output if present
x_fee = run_hook('get_tx_extra_fee', self, tx)
if x_fee:
x_fee_address, x_fee_amount = x_fee
s = [(idx, out) for (idx, out) in s if out.address != x_fee_address]
s = [(idx, out) for (idx, out) in s if self._is_rbf_allowed_to_touch_tx_output(out)]
if not s:
raise CannotBumpFee("Cannot find payment output")
@ -1803,6 +1795,15 @@ class Abstract_Wallet(AddressSynchronizer, ABC):
outputs = [out for (idx, out) in enumerate(outputs) if idx not in del_out_idxs]
return PartialTransaction.from_io(inputs, outputs)
def _is_rbf_allowed_to_touch_tx_output(self, txout: TxOutput) -> bool:
# 2fa fee outputs if present, should not be removed or have their value decreased
if self.is_billing_address(txout.address):
return False
# submarine swap funding outputs must not be decreased
if self.lnworker and self.lnworker.swap_manager.is_lockup_address_for_a_swap(txout.address):
return False
return True
def cpfp(self, tx: Transaction, fee: int) -> Optional[PartialTransaction]:
txid = tx.txid()
for i, o in enumerate(tx.outputs()):

Loading…
Cancel
Save