diff --git a/lightningd/build_utxos.c b/lightningd/build_utxos.c index 0e0f41ef0..532c607bd 100644 --- a/lightningd/build_utxos.c +++ b/lightningd/build_utxos.c @@ -49,6 +49,7 @@ static void json_newaddr(struct command *cmd, ripemd160(&p2sh, h.u.u8, sizeof(h)); ld->bip32_max_index++; + db_set_intvar(ld->wallet->db, "bip32_max_index", ld->bip32_max_index); json_object_start(response, NULL); json_add_string(response, "address", diff --git a/lightningd/lightningd.c b/lightningd/lightningd.c index 48d84d86d..cf62978c9 100644 --- a/lightningd/lightningd.c +++ b/lightningd/lightningd.c @@ -257,6 +257,8 @@ int main(int argc, char *argv[]) /* Initialize wallet, now that we are in the correct directory */ ld->wallet = wallet_new(ld, ld->log); + ld->bip32_max_index = db_get_intvar(ld->wallet->db, "bip32_max_index", 0); + /* Mark ourselves live. */ log_info(ld->log, "Hello world from %s!", version()); diff --git a/wallet/db.c b/wallet/db.c index 81b3c0314..4d3223251 100644 --- a/wallet/db.c +++ b/wallet/db.c @@ -2,8 +2,10 @@ #include "daemon/log.h" #include "lightningd/lightningd.h" + #include #include +#include #define DB_FILE "lightningd.sqlite3" @@ -230,3 +232,40 @@ struct db *db_setup(const tal_t *ctx) } return db; } + +s64 db_get_intvar(struct db *db, char *varname, s64 defval) +{ + int err; + s64 res = defval; + const unsigned char *stringvar; + sqlite3_stmt *stmt = + db_query(__func__, db, + "SELECT val FROM vars WHERE name='%s' LIMIT 1", varname); + + if (!stmt) + return defval; + + err = sqlite3_step(stmt); + if (err == SQLITE_ROW) { + stringvar = sqlite3_column_text(stmt, 0); + res = atol((const char *)stringvar); + } + sqlite3_finalize(stmt); + return res; +} + +bool db_set_intvar(struct db *db, char *varname, s64 val) +{ + /* Attempt to update */ + db_exec(__func__, db, + "UPDATE vars SET val='%" PRId64 "' WHERE name='%s';", val, + varname); + if (sqlite3_changes(db->sql) > 0) + return true; + else + return db_exec( + __func__, db, + "INSERT INTO vars (name, val) VALUES ('%s', '%" PRId64 + "');", + varname, val); +} diff --git a/wallet/db.h b/wallet/db.h index d0e01d6dd..3e39efe97 100644 --- a/wallet/db.h +++ b/wallet/db.h @@ -57,4 +57,20 @@ bool db_commit_transaction(struct db *db); */ bool db_rollback_transaction(struct db *db); +/** + * db_set_intvar - Set an integer variable in the database + * + * Utility function to store generic integer values in the + * database. + */ +bool db_set_intvar(struct db *db, char *varname, s64 val); + +/** + * db_get_intvar - Retrieve an integer variable from the database + * + * Either returns the value in the database, or @defval if + * the query failed or no such variable exists. + */ +s64 db_get_intvar(struct db *db, char *varname, s64 defval); + #endif /* WALLET_DB_H */ diff --git a/wallet/db_tests.c b/wallet/db_tests.c index 13d946f7e..0fb57d109 100644 --- a/wallet/db_tests.c +++ b/wallet/db_tests.c @@ -31,11 +31,34 @@ static bool test_empty_db_migrate(void) return true; } +static bool test_vars(void) +{ + struct db *db = create_test_db(__func__); + char *varname = "testvar"; + CHECK(db); + CHECK(db_migrate(db)); + + /* Check default behavior */ + CHECK(db_get_intvar(db, varname, 42) == 42); + + /* Check setting and getting */ + CHECK(db_set_intvar(db, varname, 1)); + CHECK(db_get_intvar(db, varname, 42) == 1); + + /* Check updating */ + CHECK(db_set_intvar(db, varname, 2)); + CHECK(db_get_intvar(db, varname, 42) == 2); + + tal_free(db); + return true; +} + int main(void) { bool ok = true; ok &= test_empty_db_migrate(); + ok &= test_vars(); return !ok; }