Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
81 changes: 68 additions & 13 deletions electrum/lnsweep.py
Original file line number Diff line number Diff line change
Expand Up @@ -56,16 +56,18 @@ def txs_their_ctx_watchtower(chan: 'Channel', ctx: Transaction, per_commitment_s
# prep
ctn = extract_ctn_from_tx_and_chan(ctx, chan)
pcp = ecc.ECPrivkey(per_commitment_secret).get_public_key_bytes(compressed=True)
this_conf, other_conf = get_ordered_channel_configs(chan=chan, for_us=False)
other_revocation_privkey = derive_blinded_privkey(other_conf.revocation_basepoint.privkey,
per_commitment_secret)
to_self_delay = other_conf.to_self_delay
this_delayed_pubkey = derive_pubkey(this_conf.delayed_basepoint.pubkey, pcp)
breacher_conf, watcher_conf = get_ordered_channel_configs(chan=chan, for_us=False)
watcher_revocation_privkey = derive_blinded_privkey(
watcher_conf.revocation_basepoint.privkey,
per_commitment_secret
)
to_self_delay = watcher_conf.to_self_delay
breacher_delayed_pubkey = derive_pubkey(breacher_conf.delayed_basepoint.pubkey, pcp)
txs = []
# to_local
revocation_pubkey = ecc.ECPrivkey(other_revocation_privkey).get_public_key_bytes(compressed=True)
# create justice tx for breacher's to_local output
revocation_pubkey = ecc.ECPrivkey(watcher_revocation_privkey).get_public_key_bytes(compressed=True)
witness_script = make_commitment_output_to_local_witness_script(
revocation_pubkey, to_self_delay, this_delayed_pubkey)
revocation_pubkey, to_self_delay, breacher_delayed_pubkey)
to_local_address = redeem_script_to_address('p2wsh', witness_script)
output_idxs = ctx.get_output_idxs_from_address(to_local_address)
if output_idxs:
Expand All @@ -75,14 +77,67 @@ def txs_their_ctx_watchtower(chan: 'Channel', ctx: Transaction, per_commitment_s
ctx=ctx,
output_idx=output_idx,
witness_script=witness_script,
privkey=other_revocation_privkey,
privkey=watcher_revocation_privkey,
is_revocation=True,
config=chan.lnworker.config)
if sweep_tx:
txs.append(sweep_tx)
# HTLCs
def txs_their_htlctx_justice(*, htlc: 'UpdateAddHtlc', htlc_direction: Direction,
ctx_output_idx: int) -> Optional[Transaction]:

# create justice txs for breacher's HTLC outputs
breacher_htlc_pubkey = derive_pubkey(breacher_conf.htlc_basepoint.pubkey, pcp)
watcher_htlc_pubkey = derive_pubkey(watcher_conf.htlc_basepoint.pubkey, pcp)
def tx_htlc(
htlc: 'UpdateAddHtlc', is_received_htlc: bool,
ctx_output_idx: int) -> None:
htlc_output_witness_script = make_htlc_output_witness_script(
is_received_htlc=is_received_htlc,
remote_revocation_pubkey=revocation_pubkey,
remote_htlc_pubkey=watcher_htlc_pubkey,
local_htlc_pubkey=breacher_htlc_pubkey,
payment_hash=htlc.payment_hash,
cltv_abs=htlc.cltv_abs,
has_anchors=chan.has_anchors()
)

cltv_abs = htlc.cltv_abs if is_received_htlc else 0
return tx_their_ctx_htlc(
ctx=ctx,
witness_script=htlc_output_witness_script,
sweep_address=sweep_address,
preimage=None,
output_idx=ctx_output_idx,
privkey=watcher_revocation_privkey,
is_revocation=True,
cltv_abs=cltv_abs,
config=chan.lnworker.config,
has_anchors=chan.has_anchors()
)
htlc_to_ctx_output_idx_map = map_htlcs_to_ctx_output_idxs(
chan=chan,
ctx=ctx,
pcp=pcp,
subject=REMOTE,
ctn=ctn)
for (direction, htlc), (ctx_output_idx, htlc_relative_idx) in htlc_to_ctx_output_idx_map.items():
txs.append(
tx_htlc(
htlc=htlc,
is_received_htlc=direction == RECEIVED,
ctx_output_idx=ctx_output_idx)
)

# for anchor channels we don't know the HTLC transaction's txid beforehand due
# to malleability because of ANYONECANPAY
if chan.has_anchors():
return txs

# create justice transactions for HTLC transaction's outputs
def txs_their_htlctx_justice(
*,
htlc: 'UpdateAddHtlc',
htlc_direction: Direction,
ctx_output_idx: int
) -> Optional[Transaction]:
htlc_tx_witness_script, htlc_tx = make_htlc_tx_with_open_channel(
chan=chan,
pcp=pcp,
Expand All @@ -97,7 +152,7 @@ def txs_their_htlctx_justice(*, htlc: 'UpdateAddHtlc', htlc_direction: Direction
output_idx=HTLCTX_INPUT_OUTPUT_INDEX,
htlctx_witness_script=htlc_tx_witness_script,
sweep_address=sweep_address,
privkey=other_revocation_privkey,
privkey=watcher_revocation_privkey,
is_revocation=True,
config=chan.lnworker.config)

Expand Down