|
|
@ -99,7 +99,6 @@ def create_claim_tx( |
|
|
|
txin: PartialTxInput, |
|
|
|
witness_script: bytes, |
|
|
|
preimage: Union[bytes, int], # 0 if timing out forward-swap |
|
|
|
privkey: bytes, |
|
|
|
address: str, |
|
|
|
amount_sat: int, |
|
|
|
locktime: int, |
|
|
@ -117,10 +116,7 @@ def create_claim_tx( |
|
|
|
txin.witness_script = witness_script |
|
|
|
txout = PartialTxOutput.from_address_and_value(address, amount_sat) |
|
|
|
tx = PartialTransaction.from_io([txin], [txout], version=2, locktime=locktime) |
|
|
|
#tx.set_rbf(True) |
|
|
|
sig = bytes.fromhex(tx.sign_txin(0, privkey)) |
|
|
|
witness = [sig, preimage, witness_script] |
|
|
|
txin.witness = bytes.fromhex(construct_witness(witness)) |
|
|
|
tx.set_rbf(True) |
|
|
|
return tx |
|
|
|
|
|
|
|
|
|
|
@ -169,21 +165,23 @@ class SwapManager(Logger): |
|
|
|
return |
|
|
|
current_height = self.network.get_local_height() |
|
|
|
delta = current_height - swap.locktime |
|
|
|
if not swap.is_reverse and delta < 0: |
|
|
|
# too early for refund |
|
|
|
return |
|
|
|
txos = self.lnwatcher.get_addr_outputs(swap.lockup_address) |
|
|
|
for txin in txos.values(): |
|
|
|
if swap.is_reverse and txin.value_sats() < swap.onchain_amount: |
|
|
|
self.logger.info('amount too low, we should not reveal the preimage') |
|
|
|
continue |
|
|
|
swap.funding_txid = txin.prevout.txid.hex() |
|
|
|
spent_height = txin.spent_height |
|
|
|
if spent_height is not None: |
|
|
|
swap.spending_txid = txin.spent_txid |
|
|
|
if spent_height > 0 and current_height - spent_height > REDEEM_AFTER_DOUBLE_SPENT_DELAY: |
|
|
|
self.logger.info(f'stop watching swap {swap.lockup_address}') |
|
|
|
self.lnwatcher.remove_callback(swap.lockup_address) |
|
|
|
swap.is_redeemed = True |
|
|
|
continue |
|
|
|
if not swap.is_reverse and delta < 0: |
|
|
|
# too early for refund |
|
|
|
return |
|
|
|
# FIXME the mining fee should depend on swap.is_reverse. |
|
|
|
# the txs are not the same size... |
|
|
|
amount_sat = txin.value_sats() - self.get_claim_fee() |
|
|
@ -201,17 +199,12 @@ class SwapManager(Logger): |
|
|
|
txin=txin, |
|
|
|
witness_script=swap.redeem_script, |
|
|
|
preimage=preimage, |
|
|
|
privkey=swap.privkey, |
|
|
|
address=address, |
|
|
|
amount_sat=amount_sat, |
|
|
|
locktime=locktime, |
|
|
|
) |
|
|
|
self.sign_tx(tx, swap) |
|
|
|
await self.network.broadcast_transaction(tx) |
|
|
|
# save txid |
|
|
|
if swap.is_reverse: |
|
|
|
swap.spending_txid = tx.txid() |
|
|
|
else: |
|
|
|
self.wallet.set_label(tx.txid(), 'Swap refund') |
|
|
|
|
|
|
|
def get_claim_fee(self): |
|
|
|
return self.wallet.config.estimate_fee(136, allow_fallback_to_static_rates=True) |
|
|
@ -307,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(False) |
|
|
|
tx.set_rbf(True) # rbf must not decrease payment |
|
|
|
self.wallet.sign_transaction(tx, password) |
|
|
|
# save swap data in wallet in case we need a refund |
|
|
|
swap = SwapData( |
|
|
@ -321,7 +314,7 @@ class SwapManager(Logger): |
|
|
|
lightning_amount = lightning_amount_sat, |
|
|
|
is_reverse = False, |
|
|
|
is_redeemed = False, |
|
|
|
funding_txid = tx.txid(), |
|
|
|
funding_txid = None, |
|
|
|
spending_txid = None, |
|
|
|
) |
|
|
|
self.swaps[payment_hash.hex()] = swap |
|
|
@ -541,3 +534,22 @@ class SwapManager(Logger): |
|
|
|
if is_reverse and send_amount is not None: |
|
|
|
send_amount += self.get_claim_fee() |
|
|
|
return send_amount |
|
|
|
|
|
|
|
def get_swap_by_tx(self, tx): |
|
|
|
# determine if tx is spending from a swap |
|
|
|
txin = tx.inputs()[0] |
|
|
|
for key, swap in self.swaps.items(): |
|
|
|
if txin.prevout.txid.hex() == swap.funding_txid: |
|
|
|
return swap |
|
|
|
return None |
|
|
|
|
|
|
|
def sign_tx(self, tx, swap): |
|
|
|
preimage = swap.preimage if swap.is_reverse else 0 |
|
|
|
witness_script = swap.redeem_script |
|
|
|
txin = tx.inputs()[0] |
|
|
|
txin.script_type = 'p2wsh' |
|
|
|
txin.script_sig = b'' |
|
|
|
txin.witness_script = witness_script |
|
|
|
sig = bytes.fromhex(tx.sign_txin(0, swap.privkey)) |
|
|
|
witness = [sig, preimage, witness_script] |
|
|
|
txin.witness = bytes.fromhex(construct_witness(witness)) |
|
|
|