Browse Source

lnsweep: rm code dupe: 2nd stage htlc tx out vs ctx to_local addr reuse

master
SomberNight 4 years ago
parent
commit
d67e24438e
No known key found for this signature in database
GPG Key ID: B33B5F232C6271E9
  1. 58
      electrum/lnsweep.py
  2. 24
      electrum/lnutil.py

58
electrum/lnsweep.py

@ -61,7 +61,7 @@ def create_sweeptxs_for_watchtower(chan: 'Channel', ctx: Transaction, per_commit
sweep_address=sweep_address, sweep_address=sweep_address,
ctx=ctx, ctx=ctx,
output_idx=output_idx, output_idx=output_idx,
witness_script=witness_script, witness_script=bfh(witness_script),
privkey=other_revocation_privkey, privkey=other_revocation_privkey,
is_revocation=True, is_revocation=True,
config=chan.lnworker.config) config=chan.lnworker.config)
@ -80,7 +80,6 @@ def create_sweeptxs_for_watchtower(chan: 'Channel', ctx: Transaction, per_commit
htlc=htlc, htlc=htlc,
ctx_output_idx=ctx_output_idx) ctx_output_idx=ctx_output_idx)
return create_sweeptx_that_spends_htlctx_that_spends_htlc_in_ctx( return create_sweeptx_that_spends_htlctx_that_spends_htlc_in_ctx(
to_self_delay=0,
htlc_tx=htlc_tx, htlc_tx=htlc_tx,
htlctx_witness_script=htlc_tx_witness_script, htlctx_witness_script=htlc_tx_witness_script,
sweep_address=sweep_address, sweep_address=sweep_address,
@ -129,7 +128,7 @@ def create_sweeptx_for_their_revoked_ctx(
sweep_address=sweep_address, sweep_address=sweep_address,
ctx=ctx, ctx=ctx,
output_idx=output_idx, output_idx=output_idx,
witness_script=witness_script, witness_script=bfh(witness_script),
privkey=other_revocation_privkey, privkey=other_revocation_privkey,
is_revocation=True, is_revocation=True,
config=chan.lnworker.config) config=chan.lnworker.config)
@ -165,11 +164,10 @@ def create_sweeptx_for_their_revoked_htlc(
# check that htlc_tx is a htlc # check that htlc_tx is a htlc
if htlc_tx.outputs()[0].address != htlc_address: if htlc_tx.outputs()[0].address != htlc_address:
return return
gen_tx = lambda: create_sweeptx_ctx_to_local( gen_tx = lambda: create_sweeptx_that_spends_htlctx_that_spends_htlc_in_ctx(
sweep_address=sweep_address, sweep_address=sweep_address,
ctx=htlc_tx, htlc_tx=htlc_tx,
output_idx=0, htlctx_witness_script=bfh(witness_script),
witness_script=witness_script,
privkey=other_revocation_privkey, privkey=other_revocation_privkey,
is_revocation=True, is_revocation=True,
config=chan.lnworker.config) config=chan.lnworker.config)
@ -227,7 +225,7 @@ def create_sweeptxs_for_our_ctx(
sweep_address=sweep_address, sweep_address=sweep_address,
ctx=ctx, ctx=ctx,
output_idx=output_idx, output_idx=output_idx,
witness_script=to_local_witness_script, witness_script=bfh(to_local_witness_script),
privkey=our_localdelayed_privkey.get_secret_bytes(), privkey=our_localdelayed_privkey.get_secret_bytes(),
is_revocation=False, is_revocation=False,
to_self_delay=to_self_delay, to_self_delay=to_self_delay,
@ -527,9 +525,9 @@ def create_sweeptx_their_ctx_to_remote(
def create_sweeptx_ctx_to_local( def create_sweeptx_ctx_to_local(
*, sweep_address: str, ctx: Transaction, output_idx: int, witness_script: str, *, sweep_address: str, ctx: Transaction, output_idx: int, witness_script: bytes,
privkey: bytes, is_revocation: bool, config: SimpleConfig, privkey: bytes, is_revocation: bool, config: SimpleConfig,
to_self_delay: int=None) -> Optional[PartialTransaction]: to_self_delay: int = None) -> Optional[PartialTransaction]:
"""Create a txn that sweeps the 'to_local' output of a commitment """Create a txn that sweeps the 'to_local' output of a commitment
transaction into our wallet. transaction into our wallet.
@ -541,7 +539,7 @@ def create_sweeptx_ctx_to_local(
txin = PartialTxInput(prevout=prevout) txin = PartialTxInput(prevout=prevout)
txin._trusted_value_sats = val txin._trusted_value_sats = val
txin.script_sig = b'' txin.script_sig = b''
txin.witness_script = bfh(witness_script) txin.witness_script = witness_script
sweep_inputs = [txin] sweep_inputs = [txin]
if not is_revocation: if not is_revocation:
assert isinstance(to_self_delay, int) assert isinstance(to_self_delay, int)
@ -561,26 +559,20 @@ def create_sweeptx_ctx_to_local(
def create_sweeptx_that_spends_htlctx_that_spends_htlc_in_ctx( def create_sweeptx_that_spends_htlctx_that_spends_htlc_in_ctx(
*, htlc_tx: Transaction, htlctx_witness_script: bytes, sweep_address: str, *, htlc_tx: Transaction, htlctx_witness_script: bytes, sweep_address: str,
privkey: bytes, is_revocation: bool, to_self_delay: int, privkey: bytes, is_revocation: bool, to_self_delay: int = None,
config: SimpleConfig) -> Optional[PartialTransaction]: config: SimpleConfig) -> Optional[PartialTransaction]:
val = htlc_tx.outputs()[0].value """Create a txn that sweeps the output of a second stage htlc tx
prevout = TxOutpoint(txid=bfh(htlc_tx.txid()), out_idx=0) (i.e. sweeps from an HTLC-Timeout or an HTLC-Success tx).
txin = PartialTxInput(prevout=prevout) """
txin._trusted_value_sats = val # note: this is the same as sweeping the to_local output of the ctx,
txin.script_sig = b'' # as these are the same script (address-reuse).
txin.witness_script = htlctx_witness_script return create_sweeptx_ctx_to_local(
sweep_inputs = [txin] sweep_address=sweep_address,
if not is_revocation: ctx=htlc_tx,
assert isinstance(to_self_delay, int) output_idx=0,
sweep_inputs[0].nsequence = to_self_delay witness_script=htlctx_witness_script,
tx_size_bytes = 200 # TODO privkey=privkey,
fee = config.estimate_fee(tx_size_bytes, allow_fallback_to_static_rates=True) is_revocation=is_revocation,
outvalue = val - fee to_self_delay=to_self_delay,
if outvalue <= dust_threshold(): return None config=config,
sweep_outputs = [PartialTxOutput.from_address_and_value(sweep_address, outvalue)] )
tx = PartialTransaction.from_io(sweep_inputs, sweep_outputs, version=2)
sig = bfh(tx.sign_txin(0, privkey))
witness = construct_witness([sig, int(is_revocation), htlctx_witness_script])
tx.inputs()[0].witness = bfh(witness)
assert tx.is_complete()
return tx

24
electrum/lnutil.py

@ -509,19 +509,11 @@ def derive_blinded_privkey(basepoint_secret: bytes, per_commitment_secret: bytes
def make_htlc_tx_output(amount_msat, local_feerate, revocationpubkey, local_delayedpubkey, success, to_self_delay): def make_htlc_tx_output(amount_msat, local_feerate, revocationpubkey, local_delayedpubkey, success, to_self_delay):
assert type(amount_msat) is int assert type(amount_msat) is int
assert type(local_feerate) is int assert type(local_feerate) is int
assert type(revocationpubkey) is bytes script = make_commitment_output_to_local_witness_script(
assert type(local_delayedpubkey) is bytes revocation_pubkey=revocationpubkey,
script = bfh(construct_script([ to_self_delay=to_self_delay,
opcodes.OP_IF, delayed_pubkey=local_delayedpubkey,
revocationpubkey, )
opcodes.OP_ELSE,
to_self_delay,
opcodes.OP_CHECKSEQUENCEVERIFY,
opcodes.OP_DROP,
local_delayedpubkey,
opcodes.OP_ENDIF,
opcodes.OP_CHECKSIG,
]))
p2wsh = bitcoin.redeem_script_to_address('p2wsh', bh2u(script)) p2wsh = bitcoin.redeem_script_to_address('p2wsh', bh2u(script))
weight = HTLC_SUCCESS_WEIGHT if success else HTLC_TIMEOUT_WEIGHT weight = HTLC_SUCCESS_WEIGHT if success else HTLC_TIMEOUT_WEIGHT
@ -896,7 +888,11 @@ def make_commitment(
return tx return tx
def make_commitment_output_to_local_witness_script( def make_commitment_output_to_local_witness_script(
revocation_pubkey: bytes, to_self_delay: int, delayed_pubkey: bytes) -> bytes: revocation_pubkey: bytes, to_self_delay: int, delayed_pubkey: bytes,
) -> bytes:
assert type(revocation_pubkey) is bytes
assert type(to_self_delay) is int
assert type(delayed_pubkey) is bytes
script = bfh(construct_script([ script = bfh(construct_script([
opcodes.OP_IF, opcodes.OP_IF,
revocation_pubkey, revocation_pubkey,

Loading…
Cancel
Save