From 8452d903b4514adcea9b7c554b0dba3669fc1eda Mon Sep 17 00:00:00 2001 From: niftynei Date: Mon, 12 Sep 2022 18:49:26 -0500 Subject: [PATCH] bkpr: failing test for bookkeeper crash Reproduce crash for #5557! If we record the channel open because bookkeeper was added after the channel open request started but the channel confirms later, we end up with re-recording any associated push or leased fees (paid or rcvd). In the case where you've paid for these fees, your channel balance goes negative and the node crashes the next time you call `listbalances`. Reported-by: @chrisguida --- tests/test_opening.py | 55 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 55 insertions(+) diff --git a/tests/test_opening.py b/tests/test_opening.py index 207ff5086..2ef1df163 100644 --- a/tests/test_opening.py +++ b/tests/test_opening.py @@ -1513,6 +1513,61 @@ def test_buy_liquidity_ad_no_v2(node_factory, bitcoind): compact_lease='029a002d000000004b2003e8') +@pytest.mark.xfail +@pytest.mark.openchannel('v2') +def test_buy_liquidity_ad_check_bookkeeping(node_factory, bitcoind): + """ Test that your bookkeeping for a liquidity ad is good.""" + + opts = [{'funder-policy': 'match', 'funder-policy-mod': 100, + 'lease-fee-base-sat': '100sat', 'lease-fee-basis': 100, + 'rescan': 10, 'disable-plugin': 'bookkeeper', + 'funding-confirms': 6, 'may_reconnect': True}, + {'funder-policy': 'match', 'funder-policy-mod': 100, + 'lease-fee-base-sat': '100sat', 'lease-fee-basis': 100}] + l1, l2, = node_factory.get_nodes(2, opts=opts) + amount = 500000 + feerate = 2000 + + l1.fundwallet(amount * 100) + l2.fundwallet(amount * 100) + + l1.rpc.connect(l2.info['id'], 'localhost', l2.port) + rates = l1.rpc.dev_queryrates(l2.info['id'], amount, amount) + wait_for(lambda: len(l1.rpc.listpeers(l2.info['id'])['peers']) == 0) + l1.rpc.connect(l2.info['id'], 'localhost', l2.port) + + # l1 leases a channel from l2 + l1.rpc.fundchannel(l2.info['id'], amount, request_amt=amount, + feerate='{}perkw'.format(feerate), + compact_lease=rates['compact_lease']) + + # add the funding transaction + bitcoind.generate_block(4, wait_for_mempool=1) + + l1.stop() + del l1.daemon.opts['disable-plugin'] + l1.start() + + chan_id = first_channel_id(l1, l2) + ev_tags = [e['tag'] for e in l1.rpc.bkpr_listaccountevents(chan_id)['events']] + assert 'lease_fee' in ev_tags + + bitcoind.generate_block(2) + l1.daemon.wait_for_log('to CHANNELD_NORMAL') + + # This should work ok + l1.rpc.bkpr_listbalances() + + l1.rpc.close(l2.info['id'], 1) + bitcoind.generate_block(6, wait_for_mempool=1) + + l1.daemon.wait_for_log(' to ONCHAIN') + l2.daemon.wait_for_log(' to ONCHAIN') + + # This should crash + l1.rpc.bkpr_listbalances() + + def test_scid_alias_private(node_factory, bitcoind): """Test that we don't allow use of real scid for scid_alias-type channels""" l1, l2, l3 = node_factory.line_graph(3, fundchannel=False, opts=[{}, {},