Files
lightning/wallet/test/run-db.c
niftynei 65c2bac2f3 hsmd/wallet: pass the bip32_key down into migrations
we're about to add a migration that requires access to the bip32_key
in order to calculate missing scriptpubkeys.

prior to this patch, we don't have access to the bip32 key in the db
migration, as it's set on the wallet but after the db migrations are
run.

here we patch it through so that every migration can access it
2020-07-29 13:13:46 +02:00

167 lines
4.1 KiB
C

#include <lightningd/log.h>
static void db_test_fatal(const char *fmt, ...);
#define db_fatal db_test_fatal
static void db_log_(struct log *log UNUSED, enum log_level level UNUSED, const struct node_id *node_id UNUSED, bool call_notifier UNUSED, const char *fmt UNUSED, ...)
{
}
#define log_ db_log_
#include "wallet/db.c"
#include "test_utils.h"
#include <common/amount.h>
#include <common/memleak.h>
#include <stdio.h>
#include <unistd.h>
/* AUTOGENERATED MOCKS START */
/* Generated stub for fatal */
void fatal(const char *fmt UNNEEDED, ...)
{ fprintf(stderr, "fatal called!\n"); abort(); }
/* Generated stub for get_channel_basepoints */
void get_channel_basepoints(struct lightningd *ld UNNEEDED,
const struct node_id *peer_id UNNEEDED,
const u64 dbid UNNEEDED,
struct basepoints *local_basepoints UNNEEDED,
struct pubkey *local_funding_pubkey UNNEEDED)
{ fprintf(stderr, "get_channel_basepoints called!\n"); abort(); }
/* Generated stub for new_log */
struct log *new_log(const tal_t *ctx UNNEEDED, struct log_book *record UNNEEDED,
const struct node_id *default_node_id UNNEEDED,
const char *fmt UNNEEDED, ...)
{ fprintf(stderr, "new_log called!\n"); abort(); }
/* AUTOGENERATED MOCKS END */
static char *db_err;
static void db_test_fatal(const char *fmt, ...)
{
va_list ap;
/* Fail hard if we're complaining about not being in transaction */
assert(!strstarts(fmt, "No longer in transaction"));
va_start(ap, fmt);
db_err = tal_vfmt(NULL, fmt, ap);
va_end(ap);
}
void plugin_hook_db_sync(struct db *db UNNEEDED)
{
}
static struct db *create_test_db(void)
{
struct db *db;
char *dsn, filename[] = "/tmp/ldb-XXXXXX";
int fd = mkstemp(filename);
if (fd == -1)
return NULL;
close(fd);
dsn = tal_fmt(NULL, "sqlite3://%s", filename);
db = db_open(NULL, dsn);
db->data_version = 0;
tal_free(dsn);
return db;
}
static bool test_empty_db_migrate(struct lightningd *ld)
{
struct db *db = create_test_db();
const struct ext_key *bip32_base = NULL;
CHECK(db);
db_begin_transaction(db);
CHECK(db_get_version(db) == -1);
db_migrate(ld, db, bip32_base);
db_commit_transaction(db);
db_begin_transaction(db);
CHECK(db_get_version(db) == ARRAY_SIZE(dbmigrations) - 1);
db_commit_transaction(db);
tal_free(db);
return true;
}
static bool test_primitives(void)
{
struct db_stmt *stmt;
struct db *db = create_test_db();
db_err = NULL;
db_begin_transaction(db);
CHECK(db->in_transaction);
db_commit_transaction(db);
CHECK(!db->in_transaction);
db_begin_transaction(db);
db_commit_transaction(db);
db_begin_transaction(db);
stmt = db_prepare_v2(db, SQL("SELECT name FROM sqlite_master WHERE type='table';"));
CHECK_MSG(db_exec_prepared_v2(stmt), "db_exec_prepared must succeed");
CHECK_MSG(!db_err, "Simple correct SQL command");
tal_free(stmt);
stmt = db_prepare_v2(db, SQL("not a valid SQL statement"));
CHECK_MSG(!db_exec_prepared_v2(stmt), "db_exec_prepared must fail");
CHECK_MSG(db_err, "Failing SQL command");
tal_free(stmt);
db_err = tal_free(db_err);
/* We didn't migrate the DB, so don't have the vars table. Pretend we
* didn't change anything so we don't bump the data_version. */
db->dirty = false;
db_commit_transaction(db);
CHECK(!db->in_transaction);
tal_free(db);
return true;
}
static bool test_vars(struct lightningd *ld)
{
struct db *db = create_test_db();
char *varname = "testvar";
const struct ext_key *bip32_base = NULL;
CHECK(db);
db_begin_transaction(db);
db_migrate(ld, db, bip32_base);
/* Check default behavior */
CHECK(db_get_intvar(db, varname, 42) == 42);
/* Check setting and getting */
db_set_intvar(db, varname, 1);
CHECK(db_get_intvar(db, varname, 42) == 1);
/* Check updating */
db_set_intvar(db, varname, 2);
CHECK(db_get_intvar(db, varname, 42) == 2);
db_commit_transaction(db);
tal_free(db);
return true;
}
int main(void)
{
setup_locale();
setup_tmpctx();
bool ok = true;
/* Dummy for migration hooks */
struct lightningd *ld = tal(NULL, struct lightningd);
ld->config = test_config;
ok &= test_empty_db_migrate(ld);
ok &= test_vars(ld);
ok &= test_primitives();
tal_free(ld);
tal_free(tmpctx);
return !ok;
}