Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix coordinator crash on order get with no confirmed wallet balance #1243

Draft
wants to merge 1 commit into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
47 changes: 46 additions & 1 deletion tests/test_trade_pipeline.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,12 @@
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

Expand Down Expand Up @@ -504,6 +509,46 @@ def test_trade_to_submitted_invoice(self):
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
Expand Down
28 changes: 28 additions & 0 deletions tests/utils/node.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import codecs
import sys
import time
import json

import requests
from decouple import config
Expand Down Expand Up @@ -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.")
Expand Down