Skip to content

Commit

Permalink
db: migrate old runes table to fix up id fields.
Browse files Browse the repository at this point in the history
Signed-off-by: Rusty Russell <[email protected]>
  • Loading branch information
rustyrussell committed Aug 30, 2023
1 parent 496a6a8 commit f67e7b0
Show file tree
Hide file tree
Showing 5 changed files with 48 additions and 2 deletions.
Binary file added tests/data/runes_bad_id.sqlite3.xz
Binary file not shown.
15 changes: 15 additions & 0 deletions tests/test_runes.py
Original file line number Diff line number Diff line change
Expand Up @@ -478,3 +478,18 @@ def test_showrune_id(node_factory):

# Won't have stored: false
assert 'stored' not in only_one(l1.rpc.showrunes(rune)['runes'])


@unittest.skipIf(os.getenv('TEST_DB_PROVIDER', 'sqlite3') != 'sqlite3', "This test is based on a sqlite3 snapshot")
@unittest.skipIf(TEST_NETWORK != 'regtest', "The DB migration is network specific due to the chain var.")
def test_id_migration(node_factory):
"""Database was taken from test_createrune"""
l1 = node_factory.get_node(dbfile='runes_bad_id.sqlite3.xz',
options={'database-upgrade': True})

for rune in ('OSqc7ixY6F-gjcigBfxtzKUI54uzgFSA6YfBQoWGDV89MA==',
'zm0x_eLgHexaTvZn3Cz7gb_YlvrlYGDo_w4BYlR9SS09MSZtZXRob2RebGlzdHxtZXRob2ReZ2V0fG1ldGhvZD1zdW1tYXJ5Jm1ldGhvZC9saXN0ZGF0YXN0b3Jl',
'mxHwVsC_W-PH7r79wXQWqxBNHaHncIqIjEPyP_vGOsE9MiZ0aW1lPjE2NTY2NzUyMTE=',
'YPojv9qgHPa3im0eiqRb-g8aRq76OasyfltGGqdFUOU9MyZpZF4wMjJkMjIzNjIwYTM1OWE0N2ZmNyZtZXRob2Q9bGlzdHBlZXJz',
'enX0sTpHB8y1ktyTAF80CnEvGetG340Ne3AGItudBS49NCZwbnVtPTA='):
assert 'stored' not in only_one(l1.rpc.showrunes(rune)['runes'])
1 change: 1 addition & 0 deletions wallet/db.c
Original file line number Diff line number Diff line change
Expand Up @@ -975,6 +975,7 @@ static struct migration dbmigrations[] = {
{SQL("ALTER TABLE htlc_sigs ADD inflight_tx_outnum INTEGER"), NULL},
{SQL("ALTER TABLE channel_funding_inflights ADD splice_amnt BIGINT DEFAULT 0"), NULL},
{SQL("ALTER TABLE channel_funding_inflights ADD i_am_initiator INTEGER DEFAULT 0"), NULL},
{NULL, migrate_runes_idfix},
};

/**
Expand Down
2 changes: 2 additions & 0 deletions wallet/db.h
Original file line number Diff line number Diff line change
Expand Up @@ -28,4 +28,6 @@ void load_indexes(struct db *db, struct indexes *indexes);

/* Migration function for old commando datastore runes. */
void migrate_datastore_commando_runes(struct lightningd *ld, struct db *db);
/* Migrate old runes with incorrect id fields */
void migrate_runes_idfix(struct lightningd *ld, struct db *db);
#endif /* LIGHTNING_WALLET_DB_H */
32 changes: 30 additions & 2 deletions wallet/wallet.c
Original file line number Diff line number Diff line change
Expand Up @@ -5696,12 +5696,13 @@ const char *wallet_get_rune(const tal_t *ctx, struct wallet *wallet, u64 unique_
return runestr;
}

const char **wallet_get_runes(const tal_t *ctx, struct wallet *wallet)
/* Migration code needs db, not wallet access */
static const char **db_get_runes(const tal_t *ctx, struct db *db)
{
struct db_stmt *stmt;
const char **strs = tal_arr(ctx, const char *, 0);

stmt = db_prepare_v2(wallet->db, SQL("SELECT rune FROM runes"));
stmt = db_prepare_v2(db, SQL("SELECT rune FROM runes"));
db_query_prepared(stmt);

while (db_step(stmt)) {
Expand All @@ -5712,6 +5713,12 @@ const char **wallet_get_runes(const tal_t *ctx, struct wallet *wallet)
return strs;
}

const char **wallet_get_runes(const tal_t *ctx, struct wallet *wallet)
{
return db_get_runes(ctx, wallet->db);

}

static void db_rune_insert(struct db *db,
const struct rune *rune)
{
Expand Down Expand Up @@ -5825,3 +5832,24 @@ void migrate_datastore_commando_runes(struct lightningd *ld, struct db *db)
startkey[1] = "rune_counter";
db_datastore_remove(db, startkey);
}

void migrate_runes_idfix(struct lightningd *ld, struct db *db)
{
/* ID fields were wrong. Pull them all out and put them back */
const char **runes = db_get_runes(tmpctx, db);
struct db_stmt *stmt;

stmt = db_prepare_v2(db, SQL("DELETE FROM runes;"));
db_exec_prepared_v2(stmt);
tal_free(stmt);

for (size_t i = 0; i < tal_count(runes); i++) {
struct rune *r;

r = rune_from_base64(tmpctx, runes[i]);
if (!r)
db_fatal(db, "Invalid databse rune %s", runes[i]);

db_rune_insert(db, r);
}
}

0 comments on commit f67e7b0

Please sign in to comment.