From db1a220744c1f9bf09be9360f008a256e287b34a Mon Sep 17 00:00:00 2001 From: Reckless_Satoshi Date: Mon, 22 Apr 2024 12:06:00 +0100 Subject: [PATCH] Add test to reproduce errors when all wallet balance is pending --- tests/test_trade_pipeline.py | 47 +++++++++++++++++++++++++++++++++++- tests/utils/node.py | 28 +++++++++++++++++++++ 2 files changed, 74 insertions(+), 1 deletion(-) diff --git a/tests/test_trade_pipeline.py b/tests/test_trade_pipeline.py index 4205b98c..2c7f8427 100644 --- a/tests/test_trade_pipeline.py +++ b/tests/test_trade_pipeline.py @@ -11,7 +11,12 @@ from django.contrib.admin.sites import AdminSite from control.models import BalanceLog from control.tasks import compute_node_balance, do_accounting from tests.test_api import BaseAPITestCase -from tests.utils.node import add_invoice, set_up_regtest_network +from tests.utils.node import ( + add_invoice, + set_up_regtest_network, + send_all_coins_to_self, + gen_blocks_to_confirm_pending, +) from tests.utils.pgp import sign_message from tests.utils.trade import Trade @@ -504,6 +509,46 @@ class TradeTest(BaseAPITestCase): trade.cancel_order(trade.maker_index) trade.cancel_order(trade.taker_index) + def test_trade_to_submitted_invoice_with_no_confirmed_onchain_balance(self): + """ + Tests a trade from order creation until escrow locked and + invoice is submitted by buyer while the node has all its onchain balance + as pending. + """ + + # Spend all balance to self, leaving all balance "unconfirmed" + send_all_coins_to_self("coordinator") + + trade = Trade(self.client) + trade.publish_order() + trade.take_order() + trade.lock_taker_bond() + + trade.get_order() + self.assertEqual(trade.response.status_code, 200) + self.assertResponse(trade.response) + + # Onchain payout option "swap_allowed" should not be possible + self.assertFalse(trade.response.json()["swap_allowed"]) + + trade.lock_escrow(trade.taker_index) + trade.submit_payout_invoice(trade.maker_index) + + data = trade.response.json() + + self.assertEqual(trade.response.status_code, 200) + self.assertResponse(trade.response) + + self.assertEqual(data["status_message"], Order.Status(Order.Status.CHA).label) + self.assertFalse(data["is_fiat_sent"]) + + # Cancel order to avoid leaving pending HTLCs after a successful test + trade.cancel_order(trade.maker_index) + trade.cancel_order(trade.taker_index) + + # Generate blocks to confirm the onchain pending balance + gen_blocks_to_confirm_pending("coordinator") + def test_trade_to_confirm_fiat_sent_LN(self): """ Tests a trade from order creation until fiat sent confirmed diff --git a/tests/utils/node.py b/tests/utils/node.py index d5cb1289..4d81e12c 100644 --- a/tests/utils/node.py +++ b/tests/utils/node.py @@ -1,6 +1,7 @@ import codecs import sys import time +import json import requests from decouple import config @@ -150,6 +151,33 @@ def wait_channels(): wait_for_active_channels("LND", "robot") +def send_coins(node_name, address, amount=0, send_all=False, spend_unconfirmed=False): + node = get_node(node_name) + data = { + "addr": address, + "amount": amount, + "send_all": send_all, + "spend_unconfirmed": spend_unconfirmed, + } + + response = requests.post( + f'http://localhost:{node["port"]}/v1/transactions', + headers=node["headers"], + data=json.dumps(data), + ) + return response.json() + + +def send_all_coins_to_self(node_name): + address = create_address(node_name) + send_coins(node_name, address, send_all=True) + + +def gen_blocks_to_confirm_pending(node_name): + address = create_address(node_name) + generate_blocks(address, 10) + + def set_up_regtest_network(): if channel_is_active(): print("Regtest network was already ready. Skipping initalization.")