From 58c624d067419989b30e532d24362fd2faa16780 Mon Sep 17 00:00:00 2001 From: Rusty Russell Date: Wed, 12 Apr 2023 14:22:15 +0930 Subject: [PATCH] pytest: fix test_penalty_htlc_tx_timeout accounting flake. This test makes l2 save db, make a payment, then rollback. *Sometimes* under CI (but not here) we don't shutdown fast enough after the payment, so the moves.json from the coin_movements.py records it. Sure enough, the result is the node ends up with a -10000msat balance. Validated by putting a time.sleep(5) between: ``` l2.rpc.pay(inv['bolt11']) import time time.sleep(5) # stop both nodes, roll back l2's database ``` The answer, of course, is to save and rollback *both* the db and moves.json file. Here's the error: ``` def test_penalty_htlc_tx_timeout(node_factory, bitcoind, chainparams): ... assert account_balance(l3, channel_id) == 0 > assert account_balance(l2, channel_id) == 0 tests/test_closing.py:1527: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ tests/utils.py:184: in account_balance m_sum -= Millisatoshi(m['debit_msat']) contrib/pyln-client/pyln/client/lightning.py:197: in __sub__ return Millisatoshi(int(self) - int(other)) _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ self = -10000msat, v = -10000 ... if self.millisatoshis < 0: > raise ValueError("Millisatoshi must be >= 0") E ValueError: Millisatoshi must be >= 0 contrib/pyln-client/pyln/client/lightning.py:82: ValueError ``` Signed-off-by: Rusty Russell --- tests/test_closing.py | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/tests/test_closing.py b/tests/test_closing.py index a58a5189a..022daf2fc 100644 --- a/tests/test_closing.py +++ b/tests/test_closing.py @@ -1435,6 +1435,10 @@ def test_penalty_htlc_tx_timeout(node_factory, bitcoind, chainparams): l2_db_path = os.path.join(l2.daemon.lightning_dir, chainparams['name'], 'lightningd.sqlite3') l2_db_path_bak = os.path.join(l2.daemon.lightning_dir, chainparams['name'], 'lightningd.sqlite3.bak') copyfile(l2_db_path, l2_db_path_bak) + # make snapshot of l2 moves accounting too! + l2_moves_path = os.path.join(l2.daemon.lightning_dir, chainparams['name'], 'moves.json') + l2_moves_path_bak = os.path.join(l2.daemon.lightning_dir, chainparams['name'], 'moves.json.bak') + copyfile(l2_moves_path, l2_moves_path_bak) l2.start() sync_blockheight(bitcoind, [l2]) @@ -1450,6 +1454,7 @@ def test_penalty_htlc_tx_timeout(node_factory, bitcoind, chainparams): l2.stop() l3.stop() copyfile(l2_db_path_bak, l2_db_path) + copyfile(l2_moves_path_bak, l2_moves_path) # start l2, now back a bit. force close channel with l3 while l3 is still offline l2.start()