Skip to content

Commit a48e7ca

Browse files
committed
fix output index, lnwatcher
1 parent 8627a4e commit a48e7ca

File tree

3 files changed

+26
-55
lines changed

3 files changed

+26
-55
lines changed

electrum/lnsweep.py

+16-15
Original file line numberDiff line numberDiff line change
@@ -319,14 +319,14 @@ def sweep_our_ctx(
319319
found_to_remote = False
320320
if not found_to_local and not found_to_remote:
321321
return {}
322-
chan.logger.debug(f'(lnsweep) found our ctx: {to_local_address} {to_remote_address}')
322+
#chan.logger.debug(f'(lnsweep) found our ctx: {to_local_address} {to_remote_address}')
323323
# other outputs are htlcs
324324
# if they are spent, we need to generate the script
325325
# so, second-stage htlc sweep should not be returned here
326326
txs = {} # type: Dict[str, SweepInfo]
327327
# to_local
328328
output_idxs = ctx.get_output_idxs_from_address(to_local_address)
329-
if output_idxs:
329+
if known_htlc_tx is None and output_idxs:
330330
output_idx = output_idxs.pop()
331331
txin = sweep_ctx_to_local(
332332
ctx=ctx,
@@ -377,19 +377,20 @@ def txs_htlc(
377377
else:
378378
# second-stage
379379
address = bitcoin.script_to_p2wsh(htlctx_witness_script)
380-
output_idx = htlc_tx.get_output_idxs_from_address(address).pop()
381-
sweep_txin = sweep_htlctx_output(
382-
to_self_delay=to_self_delay,
383-
htlc_tx=known_htlc_tx,
384-
output_idx=output_idx,
385-
htlctx_witness_script=htlctx_witness_script,
386-
privkey=our_localdelayed_privkey.get_secret_bytes(),
387-
is_revocation=False,
388-
config=chan.lnworker.config)
389-
txs[known_htlc_tx.txid() + f':{output_idx}'] = SweepInfo(
390-
name='second-stage-htlc',
391-
csv_delay=to_self_delay,
392-
cltv_abs=0,
380+
output_idxs = known_htlc_tx.get_output_idxs_from_address(address)
381+
for output_idx in output_idxs:
382+
sweep_txin = sweep_htlctx_output(
383+
to_self_delay=to_self_delay,
384+
htlc_tx=known_htlc_tx,
385+
output_idx=output_idx,
386+
htlctx_witness_script=htlctx_witness_script,
387+
privkey=our_localdelayed_privkey.get_secret_bytes(),
388+
is_revocation=False,
389+
config=chan.lnworker.config)
390+
txs[known_htlc_tx.txid() + f':{output_idx}'] = SweepInfo(
391+
name='second-stage-htlc',
392+
csv_delay=to_self_delay,
393+
cltv_abs=0,
393394
txin=sweep_txin)
394395

395396
# offered HTLCs, in our ctx --> "timeout"

electrum/lnwatcher.py

+8-40
Original file line numberDiff line numberDiff line change
@@ -464,13 +464,13 @@ async def sweep_commitment_transaction(self, funding_outpoint, closing_tx, spend
464464
if spender_tx:
465465
# the spender might be the remote, revoked or not
466466
htlc_sweepinfo = chan.maybe_sweep_htlcs(closing_tx, spender_tx)
467-
for prevout, htlc_sweep_info in htlc_sweepinfo.items():
468-
htlc_tx_spender = spenders.get(prevout)
467+
for prevout2, htlc_sweep_info in htlc_sweepinfo.items():
468+
htlc_tx_spender = spenders.get(prevout2)
469469
if htlc_tx_spender:
470470
keep_watching |= not self.is_deeply_mined(htlc_tx_spender)
471471
else:
472472
keep_watching = True
473-
await self.maybe_redeem(spenders, prevout, htlc_sweep_info, name)
473+
await self.maybe_redeem(spenders, prevout2, htlc_sweep_info, name)
474474
# extract preimage
475475
keep_watching |= not self.is_deeply_mined(spender_txid)
476476
txin_idx = spender_tx.get_input_idx_that_spent_prevout(TxOutpoint.from_str(prevout))
@@ -484,44 +484,12 @@ async def sweep_commitment_transaction(self, funding_outpoint, closing_tx, spend
484484

485485
return keep_watching
486486

487-
def get_redeem_tx(self, spenders, prevout: str, sweep_info: 'SweepInfo', name: str):
488-
# check if redeem tx needs to be updated
489-
# if it is in the mempool, we need to check fee rise
490-
txid = spenders.get(prevout)
491-
old_tx = self.adb.get_transaction(txid)
492-
assert old_tx is not None or txid is None
493-
tx_depth = self.get_tx_mined_depth(txid) if txid else None
494-
if txid and tx_depth not in [TxMinedDepth.FREE, TxMinedDepth.MEMPOOL]:
495-
assert old_tx is not None
496-
return old_tx, None
497-
new_tx = sweep_info.gen_tx()
498-
if new_tx is None:
499-
self.logger.info(f'{name} could not claim output: {prevout}, dust')
500-
assert old_tx is not None
501-
return old_tx, None
502-
if txid is None:
503-
return None, new_tx
504-
elif tx_depth == TxMinedDepth.MEMPOOL:
505-
delta = new_tx.get_fee() - self.adb.get_tx_fee(txid)
506-
if delta > 1:
507-
self.logger.info(f'increasing fee of mempool tx {name}: {prevout}')
508-
return old_tx, new_tx
509-
else:
510-
assert old_tx is not None
511-
return old_tx, None
512-
elif tx_depth == TxMinedDepth.FREE:
513-
# return new tx, even if it is equal to old_tx,
514-
# because we need to test if it can be broadcast
515-
return old_tx, new_tx
516-
else:
517-
assert old_tx is not None
518-
return old_tx, None
519487

520488
async def maybe_redeem(self, spenders, prevout, sweep_info: 'SweepInfo', name: str) -> None:
521-
#old_tx, new_tx = self.get_redeem_tx(spenders, prevout, sweep_info, name)
522-
#if new_tx is None:
523-
# return
524-
prev_txid, prev_index = prevout.split(':')
489+
# early return if it is spent. rbf is handled by the wallet
490+
prev_txid, index = prevout.split(':')
491+
if self.adb.db.get_spent_outpoint(prev_txid, int(index)):
492+
return
525493
can_broadcast = True
526494
local_height = self.network.get_local_height()
527495
if sweep_info.cltv_abs:
@@ -546,7 +514,7 @@ async def maybe_redeem(self, spenders, prevout, sweep_info: 'SweepInfo', name: s
546514
if not self.lnworker.enable_htlc_settle_onchain:
547515
return
548516
if can_broadcast:
549-
self.logger.info(f'we can broadcast: {name}')
517+
self.logger.info(f'we can broadcast: {sweep_info.name}')
550518
if sweep_info.name == 'first-stage-htlc':
551519
tx = sweep_info.txin
552520
txin = tx.inputs()[0]

tests/regtest/regtest.sh

+2
Original file line numberDiff line numberDiff line change
@@ -250,6 +250,8 @@ if [[ $1 == "swapserver_forceclose" ]]; then
250250
new_blocks 1
251251
wait_until_spent $funding_txid 0 # alice reveals preimage
252252
new_blocks 1
253+
sleep 2
254+
new_blocks 144
253255
wait_for_balance bob 0.999
254256
fi
255257

0 commit comments

Comments
 (0)