pytest: save pre-movement dbs, and accounting dbs.
What changed, and why it matters
This commit only adds test data files (compressed SQLite snapshots) and a new pytest test case for the bookkeeper module. It is a testing-only change with no modifications to production code, so it has no security impact on running Core Lightning nodes.
No action required; this is a benign test-only commit.
Security signals we found
No strong security signals were identified.
Evidence from the diff
The commit adds four .sqlite3.xz snapshots under tests/data/ and a new test_migration() function in tests/test_bookkeeper.py. The test loads pre-captured node databases and verifies that bookkeeper account events are correctly produced after migration. No C/Python source code that runs in production is changed.
Changed components
tests/test_bookkeeper.pytests/data/l1-before-moves-in-db.sqlite3.xztests/data/l1-bkpr-accounts.sqlite3.xztests/data/l2-before-moves-in-db.sqlite3.xztests/data/l2-bkpr-accounts.sqlite3.xzInspect captured patch +73 / −0
diff --git a/tests/data/l1-before-moves-in-db.sqlite3.xz b/tests/data/l1-before-moves-in-db.sqlite3.xz
new file mode 100644
index 00000000..06e5ec87
Binary files /dev/null and b/tests/data/l1-before-moves-in-db.sqlite3.xz differ
diff --git a/tests/data/l1-bkpr-accounts.sqlite3.xz b/tests/data/l1-bkpr-accounts.sqlite3.xz
new file mode 100644
index 00000000..a03b7d89
Binary files /dev/null and b/tests/data/l1-bkpr-accounts.sqlite3.xz differ
diff --git a/tests/data/l2-before-moves-in-db.sqlite3.xz b/tests/data/l2-before-moves-in-db.sqlite3.xz
new file mode 100644
index 00000000..55717156
Binary files /dev/null and b/tests/data/l2-before-moves-in-db.sqlite3.xz differ
diff --git a/tests/data/l2-bkpr-accounts.sqlite3.xz b/tests/data/l2-bkpr-accounts.sqlite3.xz
new file mode 100644
index 00000000..075ca53d
Binary files /dev/null and b/tests/data/l2-bkpr-accounts.sqlite3.xz differ
diff --git a/tests/test_bookkeeper.py b/tests/test_bookkeeper.py
index 82d0e259..18243df1 100644
--- a/tests/test_bookkeeper.py
+++ b/tests/test_bookkeeper.py
@@ -985,3 +985,76 @@ def test_bookkeeper_bad_migration(node_factory):
# l2 will *not* do this
assert not l2.daemon.is_in_log("adding spliced column")
+
+
+@unittest.skipIf(TEST_NETWORK != 'regtest', "Snapshots are bitcoin regtest.")
+@unittest.skipIf(os.getenv('TEST_DB_PROVIDER', 'sqlite3') != 'sqlite3', "uses snapshots")
+def test_migration(node_factory, bitcoind):
+ generate = False
+
+ if generate:
+ l1, l2 = node_factory.line_graph(2)
+
+ l1.pay(l2, 12345678, label="Rusty's payment")
+
+ wait_for(lambda: only_one(l1.rpc.listpeerchannels()['channels'])['htlcs'] == [])
+ wait_for(lambda: only_one(l2.rpc.listpeerchannels()['channels'])['htlcs'] == [])
+
+ chan = only_one(l1.rpc.listpeerchannels()['channels'])
+ # Label change output and funding output
+ l1.rpc.bkpr_editdescriptionbyoutpoint(f"{chan['funding_txid']}:{chan['funding_outnum']}",
+ "Rusty's channel")
+ l1.rpc.bkpr_editdescriptionbyoutpoint(f"{chan['funding_txid']}:{chan['funding_outnum'] ^ 1}",
+ "Rusty's change")
+ else:
+ bitcoind.generate_block(1)
+ l1 = node_factory.get_node(dbfile="l1-before-moves-in-db.sqlite3.xz",
+ bkpr_dbfile="l1-bkpr-accounts.sqlite3.xz",
+ options={'database-upgrade': True})
+ l2 = node_factory.get_node(dbfile="l2-before-moves-in-db.sqlite3.xz",
+ bkpr_dbfile="l2-bkpr-accounts.sqlite3.xz",
+ options={'database-upgrade': True})
+
+ chan = only_one(l1.rpc.listpeerchannels()['channels'])
+
+ payment = only_one(l1.rpc.listsendpays()['payments'])
+ events = l1.rpc.bkpr_listaccountevents()['events']
+
+ pay_event = only_one([e for e in events if e.get('description') == "Rusty's payment"])
+ del pay_event['timestamp']
+ assert pay_event == {'account': chan['channel_id'],
+ 'credit_msat': 0,
+ 'currency': 'bcrt',
+ 'debit_msat': 12345678,
+ 'description': "Rusty's payment",
+ 'is_rebalance': False,
+ 'part_id': 0,
+ 'payment_id': payment['payment_hash'],
+ 'tag': 'invoice',
+ 'type': 'channel'}
+ open_event = only_one([e for e in events if e.get('description') == "Rusty's channel"])
+ del open_event['timestamp']
+ assert open_event == {'account': chan['channel_id'],
+ 'blockheight': 103,
+ 'credit_msat': 1000000000,
+ 'currency': 'bcrt',
+ 'debit_msat': 0,
+ 'description': "Rusty's channel",
+ 'outpoint': f"{chan['funding_txid']}:{chan['funding_outnum']}",
+ 'tag': 'channel_open',
+ 'type': 'chain'}
+
+ change_event = only_one([e for e in events if e.get('description') == "Rusty's change"])
+ del change_event['timestamp']
+ assert change_event == {'account': 'wallet',
+ 'blockheight': 103,
+ 'credit_msat': 995073000,
+ 'currency': 'bcrt',
+ 'debit_msat': 0,
+ 'description': "Rusty's change",
+ 'outpoint': f"{chan['funding_txid']}:{chan['funding_outnum'] ^ 1}",
+ 'tag': 'deposit',
+ 'type': 'chain'}
+
+ # When generating, we want to stop so you can grab databases.
+ assert generate is False
Why this scored 15/100
Community notes
Notes can correct, qualify, or add evidence to the AI analysis. Every note shown here has been validated by a human moderator.
The AI analysis stands alone for now. Submit a note if you can add evidence or important context.