diff --git a/db/bindings.c b/db/bindings.c index 22643e84d..119f82a62 100644 --- a/db/bindings.c +++ b/db/bindings.c @@ -6,6 +6,7 @@ #include #include #include +#include #include #include #include @@ -131,6 +132,11 @@ void db_bind_channel_id(struct db_stmt *stmt, int pos, const struct channel_id * db_bind_blob(stmt, pos, id->id, sizeof(id->id)); } +void db_bind_channel_type(struct db_stmt *stmt, int pos, const struct channel_type *type) +{ + db_bind_talarr(stmt, pos, type->features); +} + void db_bind_node_id(struct db_stmt *stmt, int pos, const struct node_id *id) { db_bind_blob(stmt, pos, id->k, sizeof(id->k)); @@ -447,6 +453,12 @@ struct bitcoin_tx *db_col_psbt_to_tx(const tal_t *ctx, struct db_stmt *stmt, con return bitcoin_tx_with_psbt(ctx, psbt); } +struct channel_type *db_col_channel_type(const tal_t *ctx, struct db_stmt *stmt, + const char *colname) +{ + return channel_type_from(ctx, take(db_col_arr(NULL, stmt, colname, u8))); +} + void *db_col_arr_(const tal_t *ctx, struct db_stmt *stmt, const char *colname, size_t bytes, const char *label, const char *caller) { diff --git a/db/bindings.h b/db/bindings.h index 83679fde8..4a5556eb0 100644 --- a/db/bindings.h +++ b/db/bindings.h @@ -10,6 +10,7 @@ #include struct channel_id; +struct channel_type; struct db_stmt; struct node_id; struct onionreply; @@ -33,6 +34,7 @@ void db_bind_secret(struct db_stmt *stmt, int pos, const struct secret *s); void db_bind_secret_arr(struct db_stmt *stmt, int col, const struct secret *s); void db_bind_txid(struct db_stmt *stmt, int pos, const struct bitcoin_txid *t); void db_bind_channel_id(struct db_stmt *stmt, int pos, const struct channel_id *id); +void db_bind_channel_type(struct db_stmt *stmt, int pos, const struct channel_type *type); void db_bind_node_id(struct db_stmt *stmt, int pos, const struct node_id *ni); void db_bind_node_id_arr(struct db_stmt *stmt, int col, const struct node_id *ids); @@ -78,6 +80,8 @@ struct secret *db_col_secret_arr(const tal_t *ctx, struct db_stmt *stmt, const char *colname); void db_col_txid(struct db_stmt *stmt, const char *colname, struct bitcoin_txid *t); void db_col_channel_id(struct db_stmt *stmt, const char *colname, struct channel_id *dest); +struct channel_type *db_col_channel_type(const tal_t *ctx, struct db_stmt *stmt, + const char *colname); void db_col_node_id(struct db_stmt *stmt, const char *colname, struct node_id *ni); struct node_id *db_col_node_id_arr(const tal_t *ctx, struct db_stmt *stmt, const char *colname); diff --git a/plugins/bkpr/Makefile b/plugins/bkpr/Makefile index b55a22bb6..18599631c 100644 --- a/plugins/bkpr/Makefile +++ b/plugins/bkpr/Makefile @@ -37,7 +37,7 @@ PLUGIN_ALL_HEADER += $(BOOKKEEPER_HEADER) C_PLUGINS += plugins/bookkeeper PLUGINS += plugins/bookkeeper -plugins/bookkeeper: common/bolt12.o common/bolt12_merkle.o $(BOOKKEEPER_OBJS) $(PLUGIN_LIB_OBJS) $(JSMN_OBJTS) $(PLUGIN_COMMON_OBJS) $(WIRE_OBJS) $(WIRE_BOLT12_OBJS) $(DB_OBJS) +plugins/bookkeeper: common/bolt12.o common/bolt12_merkle.o common/channel_type.o $(BOOKKEEPER_OBJS) $(PLUGIN_LIB_OBJS) $(JSMN_OBJTS) $(PLUGIN_COMMON_OBJS) $(WIRE_OBJS) $(WIRE_BOLT12_OBJS) $(DB_OBJS) # The following files contain SQL-annotated statements that we need to extact BOOKKEEPER_SQL_FILES := \ diff --git a/wallet/db.c b/wallet/db.c index ec7ed63a0..bf89d9fbf 100644 --- a/wallet/db.c +++ b/wallet/db.c @@ -17,6 +17,7 @@ #include #include #include +#include #include struct migration { @@ -58,6 +59,9 @@ static void fillin_missing_lease_satoshi(struct lightningd *ld, static void migrate_invalid_last_tx_psbts(struct lightningd *ld, struct db *db); +static void migrate_fill_in_channel_type(struct lightningd *ld, + struct db *db); + /* Do not reorder or remove elements from this array, it is used to * migrate existing databases from a previous state, based on the * string indices */ @@ -943,6 +947,8 @@ static struct migration dbmigrations[] = { {SQL("ALTER TABLE channels ADD require_confirm_inputs_local INTEGER DEFAULT 0;"), NULL}, {NULL, fillin_missing_lease_satoshi}, {NULL, migrate_invalid_last_tx_psbts}, + {SQL("ALTER TABLE channels ADD channel_type BLOB DEFAULT NULL;"), NULL}, + {NULL, migrate_fill_in_channel_type}, }; /** @@ -1567,6 +1573,49 @@ static void fillin_missing_lease_satoshi(struct lightningd *ld, tal_free(stmt); } +static void migrate_fill_in_channel_type(struct lightningd *ld, + struct db *db) +{ + struct db_stmt *stmt; + + stmt = db_prepare_v2(db, SQL("SELECT id, local_static_remotekey_start, option_anchor_outputs, channel_flags, alias_remote, minimum_depth FROM channels")); + db_query_prepared(stmt); + while (db_step(stmt)) { + struct db_stmt *update_stmt; + struct channel_type *type; + u64 id = db_col_u64(stmt, "id"); + int channel_flags = db_col_int(stmt, "channel_flags"); + + if (db_col_int(stmt, "option_anchor_outputs")) { + db_col_ignore(stmt, "local_static_remotekey_start"); + type = channel_type_anchor_outputs(tmpctx); + } else if (db_col_u64(stmt, "local_static_remotekey_start") != 0x7FFFFFFFFFFFFFFFULL) + type = channel_type_static_remotekey(tmpctx); + else + type = channel_type_none(tmpctx); + + /* We didn't keep type in db, so assume all private + * channels which support aliases don't want us to fwd + * unless using alias, which is how we behaved + * before. */ + if (!db_col_is_null(stmt, "alias_remote") + && !(channel_flags & CHANNEL_FLAGS_ANNOUNCE_CHANNEL)) + channel_type_set_scid_alias(type); + + if (db_col_int(stmt, "minimum_depth") == 0) + channel_type_set_zeroconf(type); + + update_stmt = db_prepare_v2(db, SQL("UPDATE channels SET" + " channel_type = ?" + " WHERE id = ?")); + db_bind_channel_type(update_stmt, 0, type); + db_bind_u64(update_stmt, 1, id); + db_exec_prepared_v2(update_stmt); + tal_free(update_stmt); + } + tal_free(stmt); +} + static void complain_unfixed(struct lightningd *ld, enum channel_state state, u64 id, diff --git a/wallet/wallet.c b/wallet/wallet.c index 65b02ad58..12dccbb0b 100644 --- a/wallet/wallet.c +++ b/wallet/wallet.c @@ -1480,12 +1480,7 @@ static struct channel *wallet_stmt2channel(struct wallet *w, struct db_stmt *stm lease_chan_max_ppt = 0; } - if (db_col_int(stmt, "option_anchor_outputs")) - type = channel_type_anchor_outputs(NULL); - else if (db_col_u64(stmt, "local_static_remotekey_start") != 0x7FFFFFFFFFFFFFFFULL) - type = channel_type_static_remotekey(NULL); - else - type = channel_type_none(NULL); + type = db_col_channel_type(NULL, stmt, "channel_type"); /* last_tx is null for stub channels used for recovering funds through * Static channel backups. */ @@ -1529,7 +1524,8 @@ static struct channel *wallet_stmt2channel(struct wallet *w, struct db_stmt *stm &last_sig, wallet_htlc_sigs_load(tmpctx, w, db_col_u64(stmt, "id"), - db_col_int(stmt, "option_anchor_outputs")), + channel_type_has(type, OPT_ANCHOR_OUTPUTS) + || channel_type_has(type, OPT_ANCHORS_ZERO_FEE_HTLC_TX)), &channel_info, take(fee_states), remote_shutdown_scriptpubkey, @@ -1601,13 +1597,7 @@ static struct closed_channel *wallet_stmt2closed_channel(const tal_t *ctx, else cc->last_tx = NULL; - if (db_col_int(stmt, "option_anchor_outputs")) { - cc->type = channel_type_anchor_outputs(cc); - db_col_ignore(stmt, "local_static_remotekey_start"); - } else if (db_col_u64(stmt, "local_static_remotekey_start") != 0x7FFFFFFFFFFFFFFFULL) - cc->type = channel_type_static_remotekey(cc); - else - cc->type = channel_type_none(cc); + cc->type = db_col_channel_type(cc, stmt, "channel_type"); cc->state_change_cause = state_change_in_db(db_col_int(stmt, "state_change_reason")); cc->leased = !db_col_is_null(stmt, "lease_commit_sig"); @@ -1642,8 +1632,7 @@ struct closed_channel **wallet_load_closed_channels(const tal_t *ctx, ", msatoshi_to_us_min" ", msatoshi_to_us_max" ", last_tx" - ", option_anchor_outputs" - ", local_static_remotekey_start" + ", channel_type" ", state_change_reason" ", lease_commit_sig" " FROM channels" @@ -1732,7 +1721,7 @@ static bool wallet_channels_load_active(struct wallet *w) ", remote_upfront_shutdown_script" ", local_static_remotekey_start" ", remote_static_remotekey_start" - ", option_anchor_outputs" + ", channel_type" ", shutdown_scriptpubkey_local" ", closer" ", state_change_reason" @@ -2021,7 +2010,7 @@ void wallet_channel_save(struct wallet *w, struct channel *chan) " remote_upfront_shutdown_script=?," // 29 " local_static_remotekey_start=?," // 30 " remote_static_remotekey_start=?," // 31 - " option_anchor_outputs=?," // 32 + " channel_type=?," // 32 " shutdown_scriptpubkey_local=?," // 33 " closer=?," // 34 " state_change_reason=?," // 35 @@ -2079,7 +2068,7 @@ void wallet_channel_save(struct wallet *w, struct channel *chan) db_bind_talarr(stmt, 29, chan->remote_upfront_shutdown_script); db_bind_u64(stmt, 30, chan->static_remotekey_start[LOCAL]); db_bind_u64(stmt, 31, chan->static_remotekey_start[REMOTE]); - db_bind_int(stmt, 32, channel_has(chan, OPT_ANCHOR_OUTPUTS)); + db_bind_channel_type(stmt, 32, chan->type); db_bind_talarr(stmt, 33, chan->shutdown_scriptpubkey[LOCAL]); db_bind_int(stmt, 34, chan->closer); db_bind_int(stmt, 35, state_change_in_db(chan->state_change_cause));