swapserver: add test for refund path
This commit is contained in:
@@ -1318,22 +1318,22 @@ class Commands:
|
||||
await sm.get_pairs()
|
||||
lightning_amount_sat = satoshis(lightning_amount)
|
||||
onchain_amount_sat = sm.get_recv_amount(lightning_amount_sat, is_reverse=True)
|
||||
success = None
|
||||
funding_txid = None
|
||||
elif lightning_amount == 'dryrun':
|
||||
await sm.get_pairs()
|
||||
onchain_amount_sat = satoshis(onchain_amount)
|
||||
lightning_amount_sat = sm.get_send_amount(onchain_amount_sat, is_reverse=True)
|
||||
success = None
|
||||
funding_txid = None
|
||||
else:
|
||||
lightning_amount_sat = satoshis(lightning_amount)
|
||||
claim_fee = sm.get_claim_fee()
|
||||
onchain_amount_sat = satoshis(onchain_amount) + claim_fee
|
||||
success = await wallet.lnworker.swap_manager.reverse_swap(
|
||||
funding_txid = await wallet.lnworker.swap_manager.reverse_swap(
|
||||
lightning_amount_sat=lightning_amount_sat,
|
||||
expected_onchain_amount_sat=onchain_amount_sat,
|
||||
)
|
||||
return {
|
||||
'success': success,
|
||||
'funding_txid': funding_txid,
|
||||
'lightning_amount': format_satoshis(lightning_amount_sat),
|
||||
'onchain_amount': format_satoshis(onchain_amount_sat),
|
||||
}
|
||||
|
||||
@@ -2704,3 +2704,8 @@ class LNWallet(LNWorker):
|
||||
self._channel_backups[bfh(channel_id)] = cb
|
||||
util.trigger_callback('channels_updated', self.wallet)
|
||||
self.lnwatcher.add_channel(cb.funding_outpoint.to_str(), cb.get_funding_address())
|
||||
|
||||
def fail_trampoline_forwarding(self, payment_key):
|
||||
""" use this to fail htlcs received for hold invoices"""
|
||||
e = OnionRoutingFailure(code=OnionFailureCode.UNKNOWN_NEXT_PEER, data=b'')
|
||||
self.trampoline_forwarding_failures[payment_key] = e
|
||||
|
||||
@@ -967,6 +967,7 @@ class SimpleConfig(Logger):
|
||||
SWAPSERVER_URL_MAINNET = ConfigVar('swapserver_url_mainnet', default='https://swaps.electrum.org/api', type_=str)
|
||||
SWAPSERVER_URL_TESTNET = ConfigVar('swapserver_url_testnet', default='https://swaps.electrum.org/testnet', type_=str)
|
||||
SWAPSERVER_URL_REGTEST = ConfigVar('swapserver_url_regtest', default='http://localhost:5455/api', type_=str)
|
||||
TEST_SWAPSERVER_REFUND = ConfigVar('test_swapserver_refund', default=False, type_=bool)
|
||||
# connect to remote WT
|
||||
WATCHTOWER_CLIENT_ENABLED = ConfigVar('use_watchtower', default=False, type_=bool)
|
||||
WATCHTOWER_CLIENT_URL = ConfigVar('watchtower_url', default=None, type_=str)
|
||||
|
||||
@@ -232,11 +232,18 @@ class SwapManager(Logger):
|
||||
#
|
||||
tx = self.lnwatcher.adb.get_transaction(txin.spent_txid)
|
||||
preimage = tx.inputs()[0].witness_elements()[1]
|
||||
assert swap.payment_hash == sha256(preimage)
|
||||
swap.preimage = preimage
|
||||
self.logger.info(f'found preimage: {preimage.hex()}')
|
||||
self.lnworker.preimages[swap.payment_hash.hex()] = preimage.hex()
|
||||
# note: we must check the payment secret before we broadcast the funding tx
|
||||
if sha256(preimage) == swap.payment_hash:
|
||||
swap.preimage = preimage
|
||||
self.logger.info(f'found preimage: {preimage.hex()}')
|
||||
self.lnworker.preimages[swap.payment_hash.hex()] = preimage.hex()
|
||||
# note: we must check the payment secret before we broadcast the funding tx
|
||||
else:
|
||||
# refund tx
|
||||
if spent_height > 0:
|
||||
self.logger.info(f'found confirmed refund')
|
||||
payment_secret = self.lnworker.get_payment_secret(swap.payment_hash)
|
||||
payment_key = swap.payment_hash + payment_secret
|
||||
self.lnworker.fail_trampoline_forwarding(payment_key)
|
||||
|
||||
if spent_height > 0:
|
||||
if current_height - spent_height > REDEEM_AFTER_DOUBLE_SPENT_DELAY:
|
||||
@@ -257,6 +264,8 @@ class SwapManager(Logger):
|
||||
if swap.is_reverse and swap.preimage is None:
|
||||
self.logger.info('preimage not available yet')
|
||||
continue
|
||||
if swap.is_reverse and self.network.config.TEST_SWAPSERVER_REFUND:
|
||||
continue
|
||||
try:
|
||||
tx = self._create_and_sign_claim_tx(txin=txin, swap=swap, config=self.wallet.config)
|
||||
except BelowDustLimit:
|
||||
@@ -586,13 +595,12 @@ class SwapManager(Logger):
|
||||
asyncio.ensure_future(self.lnworker.pay_invoice(fee_invoice, attempts=10))
|
||||
# we return if we detect funding
|
||||
async def wait_for_funding(swap):
|
||||
while swap.spending_txid is None:
|
||||
while swap.funding_txid is None:
|
||||
await asyncio.sleep(1)
|
||||
# initiate main payment
|
||||
tasks = [asyncio.create_task(self.lnworker.pay_invoice(invoice, attempts=10, channels=channels)), asyncio.create_task(wait_for_funding(swap))]
|
||||
await asyncio.wait(tasks, return_when=asyncio.FIRST_COMPLETED)
|
||||
success = swap.spending_txid is not None
|
||||
return success
|
||||
return swap.funding_txid
|
||||
|
||||
def _add_or_reindex_swap(self, swap: SwapData) -> None:
|
||||
if swap.payment_hash.hex() not in self.swaps:
|
||||
|
||||
@@ -47,8 +47,11 @@ class TestLightningAB(TestLightning):
|
||||
def test_collaborative_close(self):
|
||||
self.run_shell(['collaborative_close'])
|
||||
|
||||
def test_submarine_swap(self):
|
||||
self.run_shell(['reverse_swap'])
|
||||
def test_swapserver_success(self):
|
||||
self.run_shell(['swapserver_success'])
|
||||
|
||||
def test_swapserver_refund(self):
|
||||
self.run_shell(['swapserver_refund'])
|
||||
|
||||
def test_backup(self):
|
||||
self.run_shell(['backup'])
|
||||
|
||||
@@ -15,6 +15,19 @@ function new_blocks()
|
||||
$bitcoin_cli generatetoaddress $1 $($bitcoin_cli getnewaddress) > /dev/null
|
||||
}
|
||||
|
||||
function wait_until_htlcs_settled()
|
||||
{
|
||||
msg="wait until $1's local_unsettled_sent is zero"
|
||||
cmd="./run_electrum --regtest -D /tmp/$1"
|
||||
while unsettled=$($alice list_channels | jq '.[] | .local_unsettled_sent') && [ $unsettled != "0" ]; do
|
||||
sleep 1
|
||||
msg="$msg."
|
||||
printf "$msg\r"
|
||||
done
|
||||
printf "\n"
|
||||
}
|
||||
|
||||
|
||||
function wait_for_balance()
|
||||
{
|
||||
msg="wait until $1's balance reaches $2"
|
||||
@@ -171,7 +184,7 @@ if [[ $1 == "collaborative_close" ]]; then
|
||||
fi
|
||||
|
||||
|
||||
if [[ $1 == "reverse_swap" ]]; then
|
||||
if [[ $1 == "swapserver_success" ]]; then
|
||||
wait_for_balance alice 1
|
||||
echo "alice opens channel"
|
||||
bob_node=$($bob nodeid)
|
||||
@@ -180,12 +193,34 @@ if [[ $1 == "reverse_swap" ]]; then
|
||||
wait_until_channel_open alice
|
||||
echo "alice initiates swap"
|
||||
dryrun=$($alice reverse_swap 0.02 dryrun)
|
||||
echo $dryrun | jq
|
||||
onchain_amount=$(echo $dryrun| jq -r ".onchain_amount")
|
||||
$alice reverse_swap 0.02 $onchain_amount
|
||||
swap=$($alice reverse_swap 0.02 $onchain_amount)
|
||||
echo $swap | jq
|
||||
funding_txid=$(echo $swap| jq -r ".funding_txid")
|
||||
new_blocks 1
|
||||
sleep 1
|
||||
wait_until_spent $funding_txid 0
|
||||
wait_until_htlcs_settled alice
|
||||
fi
|
||||
|
||||
|
||||
if [[ $1 == "swapserver_refund" ]]; then
|
||||
$alice setconfig test_swapserver_refund true
|
||||
wait_for_balance alice 1
|
||||
echo "alice opens channel"
|
||||
bob_node=$($bob nodeid)
|
||||
channel=$($alice open_channel $bob_node 0.15)
|
||||
new_blocks 3
|
||||
wait_until_channel_open alice
|
||||
echo "alice initiates swap"
|
||||
dryrun=$($alice reverse_swap 0.02 dryrun)
|
||||
onchain_amount=$(echo $dryrun| jq -r ".onchain_amount")
|
||||
swap=$($alice reverse_swap 0.02 $onchain_amount)
|
||||
echo $swap | jq
|
||||
funding_txid=$(echo $swap| jq -r ".funding_txid")
|
||||
new_blocks 140
|
||||
wait_until_spent $funding_txid 0
|
||||
new_blocks 1
|
||||
wait_until_htlcs_settled alice
|
||||
fi
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user