MCPcopy Create free account
hub / github.com/ElementsProject/lightning / test_channel_persistence

Function test_channel_persistence

tests/test_connection.py:2321–2404  ·  view source on GitHub ↗
(node_factory, bitcoind, executor)

Source from the content-addressed store, hash-verified

2319@unittest.skipIf(os.environ.get("TEST_CHECK_DBSTMTS", None) == "1",
2320 "We kill l2, dblog plugin replay will be unreliable")
2321def test_channel_persistence(node_factory, bitcoind, executor):
2322 # Start two nodes and open a channel (to remember). l2 will
2323 # mysteriously die while committing the first HTLC so we can
2324 # check that HTLCs reloaded from the DB work.
2325 # Feerates identical so we don't get gratuitous commit to update them
2326 disable_commit_after = 1
2327 if EXPERIMENTAL_DUAL_FUND:
2328 disable_commit_after = 2
2329
2330 l1 = node_factory.get_node(may_reconnect=True, feerates=(7500, 7500, 7500,
2331 7500))
2332 l2 = node_factory.get_node(options={'dev-disable-commit-after': disable_commit_after},
2333 may_reconnect=True, start=False)
2334 # Saving IO can cause JSON errors when we check it, due to partial writes if we
2335 # get lucky when we kill it.
2336 del l2.daemon.opts['dev-save-plugin-io']
2337 l2.start()
2338 l1.rpc.connect(l2.info['id'], 'localhost', l2.port)
2339
2340 # Neither node should have a channel open, they are just connected
2341 for n in (l1, l2):
2342 assert(n.db_query('SELECT COUNT(id) as count FROM channels;')[0]['count'] == 0)
2343
2344 l1.fundchannel(l2, 100000)
2345
2346 channels = l1.rpc.listpeerchannels()['channels']
2347 assert(only_one(channels)['state'] == 'CHANNELD_NORMAL')
2348
2349 # Both nodes should now have exactly one channel in the database
2350 for n in (l1, l2):
2351 assert(n.db_query('SELECT COUNT(id) as count FROM channels;')[0]['count'] == 1)
2352
2353 # Fire off a sendpay request, it'll get interrupted by a restart
2354 executor.submit(l1.pay, l2, 10000)
2355 # Wait for it to be committed to, i.e., stored in the DB
2356 l1.daemon.wait_for_log('peer_in WIRE_CHANNEL_READY')
2357 l1.daemon.wait_for_log('peer_in WIRE_COMMITMENT_SIGNED')
2358
2359 # Stop l2, l1 will reattempt to connect
2360 print("Killing l2 in mid HTLC")
2361 l2.daemon.kill()
2362
2363 # Clear the disconnect and timer stop so we can proceed normally
2364 del l2.daemon.opts['dev-disable-commit-after']
2365
2366 # Wait for l1 to notice
2367 wait_for(lambda: 'connected' not in l1.rpc.listpeerchannels()['channels'])
2368
2369 # Now restart l2 and it should reload peers/channels from the DB
2370 l2.start()
2371 wait_for(lambda: len(l2.rpc.listpeers()['peers']) == 1)
2372
2373 # Wait for the restored HTLC to finish
2374 wait_for(lambda: only_one(l1.rpc.listpeerchannels()['channels'])['to_us_msat'] == 99990000)
2375
2376 wait_for(lambda: len([p for p in l1.rpc.listpeers()['peers'] if p['connected']]))
2377 wait_for(lambda: len([p for p in l2.rpc.listpeers()['peers'] if p['connected']]))
2378

Callers

nothing calls this directly

Calls 15

only_oneFunction · 0.90
wait_forFunction · 0.90
db_queryMethod · 0.80
listpeerchannelsMethod · 0.80
wait_for_logMethod · 0.80
killMethod · 0.80
restartMethod · 0.80
mock_rpcMethod · 0.80
dev_failMethod · 0.80
generate_blockMethod · 0.80
get_nodeMethod · 0.45

Tested by

no test coverage detected