pytest: fix the invoice typo migration if you ran and created both.

Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
This commit is contained in:
Rusty Russell 2023-07-31 11:26:17 +09:30
parent 81b30c9483
commit 97af40c545
2 changed files with 28 additions and 4 deletions

View file

@ -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):

View file

@ -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);