Merge pull request #10165 from spesmilo/swaps_prepayment
reverse swaps: in the CLI, replace 'server_mining_fee' with
This commit is contained in:
@@ -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')
|
||||||
|
|||||||
@@ -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:
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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()
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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)
|
||||||
|
|||||||
Reference in New Issue
Block a user