From 26df586fbf9796818f7b9868081a150ebf7b365d Mon Sep 17 00:00:00 2001 From: Rusty Russell Date: Thu, 21 Feb 2019 11:52:47 +1030 Subject: [PATCH] pytest: add test for db constraint failure wallet_channel_insert: UNIQUE constraint failed: peers.node_id lightningd: Fatal signal 6 (version v0.6.3rc1-202-g4c8cb98) 0x555625b14261 crashdump common/daemon.c:40 0x7f8f7400e0ff ??? ???:0 0x7f8f7400e077 ??? ???:0 0x7f8f73fef534 ??? ???:0 0x555625af34f2 fatal lightningd/log.c:624 0x555625b3dd96 db_exec_prepared_ wallet/db.c:448 0x555625b44fcd wallet_channel_insert wallet/wallet.c:1067 0x555625af64f7 wallet_commit_channel lightningd/opening_control.c:229 0x555625af6e86 opening_funder_finished lightningd/opening_control.c:394 0x555625af7bfa openingd_msg lightningd/opening_control.c:714 0x555625b0d421 sd_msg_read lightningd/subd.c:474 0x555625b0cd3b read_fds lightningd/subd.c:302 0x555625b548d3 next_plan ccan/ccan/io/io.c:59 0x555625b553ef do_plan ccan/ccan/io/io.c:395 0x555625b5542d io_ready ccan/ccan/io/io.c:405 0x555625b5700e io_loop ccan/ccan/io/poll.c:310 0x555625af1562 main lightningd/lightningd.c:827 0x7f8f73ff109a ??? ???:0 0x555625adaad9 ??? ???:0 0xffffffffffffffff ??? ???:0 Log dumped in crash.log.20190220020526 Signed-off-by: Rusty Russell --- tests/test_connection.py | 47 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 47 insertions(+) diff --git a/tests/test_connection.py b/tests/test_connection.py index d188d806b..fe2dd84c8 100644 --- a/tests/test_connection.py +++ b/tests/test_connection.py @@ -1508,3 +1508,50 @@ def test_restart_many_payments(node_factory): # Wait for them to finish. for n in innodes: wait_for(lambda: 'pending' not in [p['status'] for p in n.rpc.listpayments()['payments']]) + + +@pytest.mark.xfail(strict=True) +@unittest.skipIf(not DEVELOPER, "need dev-disconnect") +def test_fail_unconfirmed(node_factory, bitcoind, executor): + """Test that if we crash with an unconfirmed connection to a known + peer, we don't have a dangling peer in db""" + # = is a NOOP disconnect, but sets up file. + l1 = node_factory.get_node(disconnect=['=WIRE_OPEN_CHANNEL']) + l2 = node_factory.get_node() + + # First one, we close by mutual agreement. + l1.rpc.connect(l2.info['id'], 'localhost', l2.port) + l1.fund_channel(l2, 200000, wait_for_active=True) + l1.rpc.close(l2.info['id']) + + # Make sure it's closed + l1.wait_for_channel_onchain(l2.info['id']) + bitcoind.generate_block(1) + l1.daemon.wait_for_log('State changed from CLOSINGD_COMPLETE to FUNDING_SPEND_SEEN') + + l1.stop() + # Mangle disconnect file so this time it blackholes.... + with open(l1.daemon.disconnect_file, "w") as f: + f.write("0WIRE_OPEN_CHANNEL\n") + l1.start() + + # Now we establish a new channel, which gets stuck. + l1.rpc.connect(l2.info['id'], 'localhost', l2.port) + l1.fundwallet(10**7) + executor.submit(l1.rpc.fundchannel, l2.info['id'], 100000) + + l1.daemon.wait_for_log("dev_disconnect") + + # Now complete old channel. + bitcoind.generate_block(100) + l1.daemon.wait_for_log('onchaind complete, forgetting peer') + + # And crash l1, which is stuck. + l1.daemon.kill() + + # Now, restart and see if it can connect OK. + del l1.daemon.opts['dev-disconnect'] + l1.start() + + l1.rpc.connect(l2.info['id'], 'localhost', l2.port) + l1.fund_channel(l2, 200000, wait_for_active=True)