Skip to content

Commit

Permalink
bkpr: failing test for bookkeeper crash
Browse files Browse the repository at this point in the history
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
  • Loading branch information
niftynei committed Sep 14, 2022
1 parent 7cb754c commit b2708cf
Showing 1 changed file with 55 additions and 0 deletions.
55 changes: 55 additions & 0 deletions tests/test_opening.py
Original file line number Diff line number Diff line change
Expand Up @@ -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=[{}, {},
Expand Down

0 comments on commit b2708cf

Please sign in to comment.