From 97af40c545e4e98490014702094d79b9e147bd85 Mon Sep 17 00:00:00 2001 From: Rusty Russell Date: Mon, 31 Jul 2023 11:26:17 +0930 Subject: [PATCH] pytest: fix the invoice typo migration if you ran and created both. Signed-off-by: Rusty Russell --- tests/test_invoices.py | 1 - wallet/db.c | 31 ++++++++++++++++++++++++++++--- 2 files changed, 28 insertions(+), 4 deletions(-) diff --git a/tests/test_invoices.py b/tests/test_invoices.py index f76f9f88c..1a00a5436 100644 --- a/tests/test_invoices.py +++ b/tests/test_invoices.py @@ -926,7 +926,6 @@ def test_invoices_wait_db_migration(node_factory, bitcoind): l2.rpc.invoice(1000, "test", "test") -@pytest.mark.xfail(strict=True) @unittest.skipIf(TEST_NETWORK != 'regtest', "The DB migration is network specific due to the chain var.") def test_invoice_botched_migration(node_factory, chainparams): """Test for grubles' case, where they ran successfully with the wrong var: they have *both* last_invoice_created_index *and *last_invoices_created_index* (this can happen if invoice id 1 was deleted, so they didn't die on invoice creation): diff --git a/wallet/db.c b/wallet/db.c index 648c8d603..b97053732 100644 --- a/wallet/db.c +++ b/wallet/db.c @@ -1679,10 +1679,35 @@ static void migrate_initialize_wait_indexes(struct lightningd *ld, static void migrate_invoice_created_index_var(struct lightningd *ld, struct db *db) { struct db_stmt *stmt; + s64 badindex, realindex; - /* Prior migration had a typo! */ - stmt = db_prepare_v2(db, SQL("UPDATE vars" - " SET name = 'last_invoices_created_index'" + /* Prior migration had a typo! But we might have run since + * then and created an invoice, so we have to set the real one + * to the max of the two... */ + badindex = db_get_intvar(db, "last_invoice_created_index", -1); + realindex = db_get_intvar(db, "last_invoices_created_index", -1); + + /* Bad index does not exist? Fine */ + if (badindex < 0) + return; + + /* Bad index exists, real index doesn't? Rename */ + if (badindex >= 0 && realindex < 0) { + stmt = db_prepare_v2(db, SQL("UPDATE vars" + " SET name = 'last_invoices_created_index'" + " WHERE name = 'last_invoice_created_index'")); + db_exec_prepared_v2(stmt); + tal_free(stmt); + return; + } + + /* Both exist. Correct value is the higher one. */ + if (badindex > realindex) + realindex = badindex; + + /* Update correct one, remove bad one. */ + db_set_intvar(db, "last_invoices_created_index", realindex); + stmt = db_prepare_v2(db, SQL("DELETE FROM vars" " WHERE name = 'last_invoice_created_index'")); db_exec_prepared_v2(stmt); tal_free(stmt);