Browse Source

db: Split the vars table to have type-specific columns

This was weird right from the start, so we just split the table into integers
and blobs, so each column has a well-defined format. It is also required for
postgres not to cry about explicit casts in the `paramTypes` array.

Signed-off-by: Christian Decker <decker.christian@gmail.com>
travis-debug
Christian Decker 5 years ago
committed by Rusty Russell
parent
commit
6b26ce5764
  1. 2
      tests/test_closing.py
  2. 18
      wallet/db.c
  3. 4
      wallet/wallet.c

2
tests/test_closing.py

@ -1550,7 +1550,7 @@ def test_option_upfront_shutdown_script(node_factory, bitcoind):
wait_for(lambda: [c['state'] for c in only_one(l2.rpc.listpeers()['peers'])['channels']] == ['ONCHAIN', 'ONCHAIN'])
# Figure out what address it will try to use.
keyidx = int(l1.db_query("SELECT val FROM vars WHERE name='bip32_max_index';")[0]['val'])
keyidx = int(l1.db_query("SELECT intval FROM vars WHERE name='bip32_max_index';")[0]['intval'])
# Expect 1 for change address, 1 for the channel final address,
# which are discarded as the 'scratch' tx that the fundchannel

18
wallet/db.c

@ -459,6 +459,10 @@ static struct migration dbmigrations[] = {
/* option_static_remotekey is nailed at creation time. */
{SQL("ALTER TABLE channels ADD COLUMN option_static_remotekey"
" DEFAULT FALSE;"), NULL },
{SQL("ALTER TABLE vars ADD COLUMN intval INTEGER"), NULL},
{SQL("ALTER TABLE vars ADD COLUMN blobval BLOB"), NULL},
{SQL("UPDATE vars SET intval = CAST(val AS INTEGER) WHERE name IN (\"bip32_max_index\", \"last_processed_block\", \"next_pay_index\")"), NULL},
{SQL("UPDATE vars SET blobval = CAST(val AS BLOB) WHERE name = 'genesis_hash'"), NULL},
};
/* Leak tracking. */
@ -798,13 +802,13 @@ s64 db_get_intvar(struct db *db, char *varname, s64 defval)
{
s64 res = defval;
struct db_stmt *stmt = db_prepare_v2(
db, SQL("SELECT val FROM vars WHERE name= ? LIMIT 1"));
db, SQL("SELECT intval FROM vars WHERE name= ? LIMIT 1"));
db_bind_text(stmt, 0, varname);
if (!db_query_prepared(stmt))
goto done;
if (db_step(stmt))
res = atol((const char*)db_column_text(stmt, 0));
res = db_column_int(stmt, 0);
done:
tal_free(stmt);
@ -813,10 +817,9 @@ done:
void db_set_intvar(struct db *db, char *varname, s64 val)
{
char *v = tal_fmt(NULL, "%"PRIi64, val);
size_t changes;
struct db_stmt *stmt = db_prepare_v2(db, SQL("UPDATE vars SET val=? WHERE name=?;"));
db_bind_text(stmt, 0, v);
struct db_stmt *stmt = db_prepare_v2(db, SQL("UPDATE vars SET intval=? WHERE name=?;"));
db_bind_int(stmt, 0, val);
db_bind_text(stmt, 1, varname);
if (!db_exec_prepared_v2(stmt))
db_fatal("Error executing update: %s", stmt->error);
@ -824,14 +827,13 @@ void db_set_intvar(struct db *db, char *varname, s64 val)
tal_free(stmt);
if (changes == 0) {
stmt = db_prepare_v2(db, SQL("INSERT INTO vars (name, val) VALUES (?, ?);"));
stmt = db_prepare_v2(db, SQL("INSERT INTO vars (name, intval) VALUES (?, ?);"));
db_bind_text(stmt, 0, varname);
db_bind_text(stmt, 1, v);
db_bind_int(stmt, 1, val);
if (!db_exec_prepared_v2(stmt))
db_fatal("Error executing insert: %s", stmt->error);
tal_free(stmt);
}
tal_free(v);
}
/* Will apply the current config fee settings to all channels */

4
wallet/wallet.c

@ -2483,7 +2483,7 @@ bool wallet_network_check(struct wallet *w,
{
struct bitcoin_blkid chainhash;
struct db_stmt *stmt = db_prepare_v2(
w->db, SQL("SELECT val FROM vars WHERE name='genesis_hash'"));
w->db, SQL("SELECT blobval FROM vars WHERE name='genesis_hash'"));
db_query_prepared(stmt);
if (db_step(stmt)) {
@ -2507,7 +2507,7 @@ bool wallet_network_check(struct wallet *w,
tal_free(stmt);
/* Still a pristine wallet, claim it for the chain
* that we are running */
stmt = db_prepare_v2(w->db, SQL("INSERT INTO vars (name, val) "
stmt = db_prepare_v2(w->db, SQL("INSERT INTO vars (name, blobval) "
"VALUES ('genesis_hash', ?);"));
db_bind_sha256d(stmt, 0, &chainparams->genesis_blockhash.shad);
db_exec_prepared_v2(take(stmt));

Loading…
Cancel
Save