1
0

Merge pull request #10165 from spesmilo/swaps_prepayment

reverse swaps: in the CLI, replace 'server_mining_fee' with
This commit is contained in:
ThomasV
2025-08-22 10:37:53 +02:00
committed by GitHub
6 changed files with 25 additions and 25 deletions

View File

@@ -1995,7 +1995,7 @@ class Commands(Logger):
"max_forward_sat": offer.pairs.max_forward, "max_forward_sat": offer.pairs.max_forward,
"max_reverse_sat": offer.pairs.max_reverse, "max_reverse_sat": offer.pairs.max_reverse,
"min_amount_sat": offer.pairs.min_amount, "min_amount_sat": offer.pairs.min_amount,
"provider_mining_fee": offer.pairs.mining_fee, "prepayment": 2 * offer.pairs.mining_fee,
} }
return result return result
@@ -2041,14 +2041,14 @@ class Commands(Logger):
@command('wnpl') @command('wnpl')
async def reverse_swap( async def reverse_swap(
self, lightning_amount, onchain_amount, provider_mining_fee='dryrun', password=None, wallet: Abstract_Wallet = None, self, lightning_amount, onchain_amount, prepayment='dryrun', password=None, wallet: Abstract_Wallet = None,
): ):
""" """
Reverse submarine swap: send on Lightning, receive on-chain Reverse submarine swap: send on Lightning, receive on-chain
arg:decimal_or_dryrun:lightning_amount:Amount to be sent, in BTC. Set it to 'dryrun' to receive a value arg:decimal_or_dryrun:lightning_amount:Amount to be sent, in BTC. Set it to 'dryrun' to receive a value
arg:decimal_or_dryrun:onchain_amount:Amount to be received, in BTC. Set it to 'dryrun' to receive a value arg:decimal_or_dryrun:onchain_amount:Amount to be received, in BTC. Set it to 'dryrun' to receive a value
arg:decimal_or_dryrun:provider_mining_fee:Mining fee required by the swap provider, in BTC. Set it to 'dryrun' to receive a value arg:decimal_or_dryrun:prepayment:Lightning payment required by the swap provider in order to cover their mining fees. This is included in lightning_amount. However, this part of the operation is not trustless; the provider is trusted to fail this payment if the swap fails.
""" """
sm = wallet.lnworker.swap_manager sm = wallet.lnworker.swap_manager
assert self.config.SWAPSERVER_NPUB or self.config.SWAPSERVER_URL, \ assert self.config.SWAPSERVER_NPUB or self.config.SWAPSERVER_URL, \
@@ -2061,32 +2061,32 @@ class Commands(Logger):
if onchain_amount == 'dryrun': if onchain_amount == 'dryrun':
lightning_amount_sat = satoshis(lightning_amount) lightning_amount_sat = satoshis(lightning_amount)
onchain_amount_sat = sm.get_recv_amount(lightning_amount_sat, is_reverse=True) onchain_amount_sat = sm.get_recv_amount(lightning_amount_sat, is_reverse=True)
assert provider_mining_fee == "dryrun", f"Cannot use {provider_mining_fee=} in dryrun. Set it to 'dryrun'." assert prepayment == "dryrun", f"Cannot use {prepayment=} in dryrun. Set it to 'dryrun'."
provider_mining_fee = sm.mining_fee prepayment_sat = 2 * sm.mining_fee
funding_txid = None funding_txid = None
elif lightning_amount == 'dryrun': elif lightning_amount == 'dryrun':
onchain_amount_sat = satoshis(onchain_amount) onchain_amount_sat = satoshis(onchain_amount)
lightning_amount_sat = sm.get_send_amount(onchain_amount_sat, is_reverse=True) lightning_amount_sat = sm.get_send_amount(onchain_amount_sat, is_reverse=True)
assert provider_mining_fee == "dryrun", f"Cannot use {provider_mining_fee=} in dryrun. Set it to 'dryrun'." assert prepayment == "dryrun", f"Cannot use {prepayment=} in dryrun. Set it to 'dryrun'."
provider_mining_fee = sm.mining_fee prepayment_sat = 2 * sm.mining_fee
funding_txid = None funding_txid = None
else: else:
lightning_amount_sat = satoshis(lightning_amount) lightning_amount_sat = satoshis(lightning_amount)
claim_fee = sm.get_fee_for_txbatcher() claim_fee = sm.get_fee_for_txbatcher()
onchain_amount_sat = satoshis(onchain_amount) + claim_fee onchain_amount_sat = satoshis(onchain_amount) + claim_fee
assert provider_mining_fee != "dryrun", "Provide the 'provider_mining_fee' obtained from the dryrun." assert prepayment != "dryrun", "Provide the 'prepayment' obtained from the dryrun."
provider_mining_fee = satoshis(provider_mining_fee) prepayment_sat = satoshis(prepayment)
funding_txid = await wallet.lnworker.swap_manager.reverse_swap( funding_txid = await wallet.lnworker.swap_manager.reverse_swap(
transport=transport, transport=transport,
lightning_amount_sat=lightning_amount_sat, lightning_amount_sat=lightning_amount_sat,
expected_onchain_amount_sat=onchain_amount_sat, expected_onchain_amount_sat=onchain_amount_sat,
server_mining_fee_sat=provider_mining_fee, prepayment_sat=prepayment_sat,
) )
return { return {
'funding_txid': funding_txid, 'funding_txid': funding_txid,
'lightning_amount': format_satoshis(lightning_amount_sat), 'lightning_amount': format_satoshis(lightning_amount_sat),
'onchain_amount': format_satoshis(onchain_amount_sat), 'onchain_amount': format_satoshis(onchain_amount_sat),
'provider_mining_fee': format_satoshis(provider_mining_fee) 'prepayment': format_satoshis(prepayment_sat)
} }
@command('n') @command('n')

View File

@@ -719,7 +719,7 @@ class QESwapHelper(AuthMixin, QObject, QtEventListener):
transport=self.swap_transport, transport=self.swap_transport,
lightning_amount_sat=lightning_amount, lightning_amount_sat=lightning_amount,
expected_onchain_amount_sat=onchain_amount + swap_manager.get_fee_for_txbatcher(), expected_onchain_amount_sat=onchain_amount + swap_manager.get_fee_for_txbatcher(),
server_mining_fee_sat=self.serverMiningfee.satsInt, prepayment_sat=2 * self.serverMiningfee.satsInt,
) )
try: # swaphelper might be destroyed at this point try: # swaphelper might be destroyed at this point
if txid: if txid:

View File

@@ -338,7 +338,7 @@ class SwapDialog(WindowModalDialog, QtEventListener):
transport=transport, transport=transport,
lightning_amount_sat=lightning_amount, lightning_amount_sat=lightning_amount,
expected_onchain_amount_sat=onchain_amount + self.swap_manager.get_fee_for_txbatcher(), expected_onchain_amount_sat=onchain_amount + self.swap_manager.get_fee_for_txbatcher(),
server_mining_fee_sat=self.last_server_mining_fee_sat, prepayment_sat=2 * self.last_server_mining_fee_sat,
) )
try: try:
# we must not leave the context, so we use run_couroutine_dialog # we must not leave the context, so we use run_couroutine_dialog

View File

@@ -926,7 +926,7 @@ class SwapManager(Logger):
transport: 'SwapServerTransport', transport: 'SwapServerTransport',
lightning_amount_sat: int, lightning_amount_sat: int,
expected_onchain_amount_sat: int, expected_onchain_amount_sat: int,
server_mining_fee_sat: int, prepayment_sat: int,
channels: Optional[Sequence['Channel']] = None, channels: Optional[Sequence['Channel']] = None,
) -> Optional[str]: ) -> Optional[str]:
"""send on Lightning, receive on-chain """send on Lightning, receive on-chain
@@ -943,9 +943,9 @@ class SwapManager(Logger):
- Server fulfills HTLC using preimage. - Server fulfills HTLC using preimage.
Note: expected_onchain_amount_sat is BEFORE deducting the on-chain claim tx fee. Note: expected_onchain_amount_sat is BEFORE deducting the on-chain claim tx fee.
Note: server_mining_fee_sat is passed as argument instead of accessing self.mining_fee to ensure Note: prepayment_sat is passed as argument instead of accessing self.mining_fee to ensure
the mining fees the user sees in the GUI are also the values used for the checks performed here. the mining fees the user sees in the GUI are also the values used for the checks performed here.
We commit to server_mining_fee_sat as it limits the max fee pre-payment amt, which the server is trusted with. We commit to prepayment_sat as it limits the max fee pre-payment amt, which the server is trusted with.
""" """
assert self.network assert self.network
assert self.lnwatcher assert self.lnwatcher
@@ -1007,7 +1007,7 @@ class SwapManager(Logger):
raise Exception("rswap check failed: inconsistent RHASH and invoice") raise Exception("rswap check failed: inconsistent RHASH and invoice")
if fee_invoice: if fee_invoice:
fee_lnaddr = self.lnworker._check_bolt11_invoice(fee_invoice) fee_lnaddr = self.lnworker._check_bolt11_invoice(fee_invoice)
if fee_lnaddr.get_amount_sat() > server_mining_fee_sat * 2: if fee_lnaddr.get_amount_sat() > prepayment_sat:
raise SwapServerError(_("Mining fee requested by swap-server larger " raise SwapServerError(_("Mining fee requested by swap-server larger "
"than what was announced in their offer.")) "than what was announced in their offer."))
invoice_amount += fee_lnaddr.get_amount_sat() invoice_amount += fee_lnaddr.get_amount_sat()

View File

@@ -248,8 +248,8 @@ if [[ $1 == "swapserver_success" ]]; then
echo "alice initiates swap" echo "alice initiates swap"
dryrun=$($alice reverse_swap 0.02 dryrun) dryrun=$($alice reverse_swap 0.02 dryrun)
onchain_amount=$(echo $dryrun| jq -r ".onchain_amount") onchain_amount=$(echo $dryrun| jq -r ".onchain_amount")
swapserver_mining_fee=$(echo $dryrun| jq -r ".provider_mining_fee") prepayment=$(echo $dryrun| jq -r ".prepayment")
swap=$($alice reverse_swap 0.02 $onchain_amount --provider_mining_fee $swapserver_mining_fee) swap=$($alice reverse_swap 0.02 $onchain_amount --prepayment $prepayment)
echo $swap | jq echo $swap | jq
funding_txid=$(echo $swap| jq -r ".funding_txid") funding_txid=$(echo $swap| jq -r ".funding_txid")
new_blocks 1 new_blocks 1
@@ -273,8 +273,8 @@ if [[ $1 == "swapserver_forceclose" ]]; then
echo "alice initiates swap" echo "alice initiates swap"
dryrun=$($alice reverse_swap 0.02 dryrun) dryrun=$($alice reverse_swap 0.02 dryrun)
onchain_amount=$(echo $dryrun| jq -r ".onchain_amount") onchain_amount=$(echo $dryrun| jq -r ".onchain_amount")
swapserver_mining_fee=$(echo $dryrun| jq -r ".provider_mining_fee") prepayment=$(echo $dryrun| jq -r ".prepayment")
swap=$($alice reverse_swap 0.02 $onchain_amount --provider_mining_fee $swapserver_mining_fee) swap=$($alice reverse_swap 0.02 $onchain_amount --prepayment $prepayment)
echo $swap | jq echo $swap | jq
funding_txid=$(echo $swap| jq -r ".funding_txid") funding_txid=$(echo $swap| jq -r ".funding_txid")
ctx_id=$($bob close_channel --force $channel) ctx_id=$($bob close_channel --force $channel)
@@ -309,8 +309,8 @@ if [[ $1 == "swapserver_refund" ]]; then
echo "alice initiates swap" echo "alice initiates swap"
dryrun=$($alice reverse_swap 0.02 dryrun) dryrun=$($alice reverse_swap 0.02 dryrun)
onchain_amount=$(echo $dryrun| jq -r ".onchain_amount") onchain_amount=$(echo $dryrun| jq -r ".onchain_amount")
swapserver_mining_fee=$(echo $dryrun| jq -r ".provider_mining_fee") prepayment=$(echo $dryrun| jq -r ".prepayment")
swap=$($alice reverse_swap 0.02 $onchain_amount --provider_mining_fee $swapserver_mining_fee) swap=$($alice reverse_swap 0.02 $onchain_amount --prepayment $prepayment)
echo $swap | jq echo $swap | jq
funding_txid=$(echo $swap| jq -r ".funding_txid") funding_txid=$(echo $swap| jq -r ".funding_txid")
new_blocks 140 new_blocks 140

View File

@@ -711,14 +711,14 @@ class TestCommandsTestnet(ElectrumTestCase):
"max_forward_sat": offer1.pairs.max_forward, "max_forward_sat": offer1.pairs.max_forward,
"max_reverse_sat": offer1.pairs.max_reverse, "max_reverse_sat": offer1.pairs.max_reverse,
"min_amount_sat": offer1.pairs.min_amount, "min_amount_sat": offer1.pairs.min_amount,
"provider_mining_fee": offer1.pairs.mining_fee, "prepayment": 2 * offer1.pairs.mining_fee,
}, },
offer2.server_npub: { offer2.server_npub: {
"percentage_fee": offer2.pairs.percentage, "percentage_fee": offer2.pairs.percentage,
"max_forward_sat": offer2.pairs.max_forward, "max_forward_sat": offer2.pairs.max_forward,
"max_reverse_sat": offer2.pairs.max_reverse, "max_reverse_sat": offer2.pairs.max_reverse,
"min_amount_sat": offer2.pairs.min_amount, "min_amount_sat": offer2.pairs.min_amount,
"provider_mining_fee": offer2.pairs.mining_fee, "prepayment": 2 * offer2.pairs.mining_fee,
} }
} }
self.assertEqual(result, expected_result) self.assertEqual(result, expected_result)