wallet: add accessor for closed channels.

This doesn't restore every bit of information we have, but it does
contain the important ones.

Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
This commit is contained in:
Rusty Russell
2023-03-20 10:49:15 +10:30
parent 6e1eafbb0b
commit 4b6e9649eb
4 changed files with 134 additions and 0 deletions

View File

@@ -48,6 +48,7 @@ include wallet/Makefile
LIGHTNINGD_HDRS := \
$(LIGHTNINGD_SRC:.c=.h) \
lightningd/closed_channel.h \
lightningd/channel_state.h \
lightningd/channel_state_names_gen.h \
$(WALLET_HDRS)

View File

@@ -0,0 +1,28 @@
/* Not to be confused with live channels in ld->channels */
#ifndef LIGHTNING_LIGHTNINGD_CLOSED_CHANNEL_H
#define LIGHTNING_LIGHTNINGD_CLOSED_CHANNEL_H
#include "config.h"
struct closed_channel {
/* This is often deleted on older nodes! */
struct node_id *peer_id;
struct channel_id cid;
struct short_channel_id *scid;
struct short_channel_id *alias[NUM_SIDES];
enum side opener, closer;
u8 channel_flags;
u64 next_index[NUM_SIDES], next_htlc_id;
struct bitcoin_outpoint funding;
struct amount_sat funding_sats;
struct amount_msat push;
struct amount_msat our_msat;
/* Statistics for min and max our_msatoshi. */
struct amount_msat msat_to_us_min;
struct amount_msat msat_to_us_max;
struct bitcoin_tx *last_tx;
const struct channel_type *type;
enum state_change state_change_cause;
bool leased;
};
#endif /* LIGHTNING_LIGHTNINGD_CLOSED_CHANNEL_H */

View File

@@ -14,6 +14,7 @@
#include <db/utils.h>
#include <lightningd/chaintopology.h>
#include <lightningd/channel.h>
#include <lightningd/closed_channel.h>
#include <lightningd/coin_mvts.h>
#include <lightningd/notification.h>
#include <lightningd/peer_control.h>
@@ -1557,6 +1558,100 @@ static struct channel *wallet_stmt2channel(struct wallet *w, struct db_stmt *stm
return chan;
}
static struct closed_channel *wallet_stmt2closed_channel(const tal_t *ctx,
struct wallet *w,
struct db_stmt *stmt)
{
struct closed_channel *cc = tal(ctx, struct closed_channel);
/* Can be missing in older dbs! */
cc->peer_id = db_col_optional(cc, stmt, "p.node_id", node_id);
db_col_channel_id(stmt, "full_channel_id", &cc->cid);
cc->scid = db_col_optional(cc, stmt, "scid", short_channel_id);
cc->alias[LOCAL] = db_col_optional(cc, stmt, "alias_local",
short_channel_id);
cc->alias[REMOTE] = db_col_optional(cc, stmt, "alias_remote",
short_channel_id);
cc->opener = db_col_int(stmt, "funder");
cc->closer = db_col_int(stmt, "closer");
cc->channel_flags = db_col_int(stmt, "channel_flags");
cc->next_index[LOCAL] = db_col_u64(stmt, "next_index_local");
cc->next_index[REMOTE] = db_col_u64(stmt, "next_index_remote");
cc->next_htlc_id = db_col_u64(stmt, "next_htlc_id");
db_col_sha256d(stmt, "funding_tx_id", &cc->funding.txid.shad);
cc->funding.n = db_col_int(stmt, "funding_tx_outnum");
db_col_amount_sat(stmt, "funding_satoshi", &cc->funding_sats);
db_col_amount_msat(stmt, "push_msatoshi", &cc->push);
db_col_amount_msat(stmt, "msatoshi_local", &cc->our_msat);
db_col_amount_msat(stmt, "msatoshi_to_us_min", &cc->msat_to_us_min);
db_col_amount_msat(stmt, "msatoshi_to_us_max", &cc->msat_to_us_max);
/* last_tx is null for stub channels used for recovering funds through
* Static channel backups. */
if (!db_col_is_null(stmt, "last_tx"))
cc->last_tx = db_col_psbt_to_tx(cc, stmt, "last_tx");
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->state_change_cause
= state_change_in_db(db_col_int(stmt, "state_change_reason"));
cc->leased = !db_col_is_null(stmt, "lease_commit_sig");
return cc;
}
struct closed_channel **wallet_load_closed_channels(const tal_t *ctx,
struct wallet *w)
{
struct db_stmt *stmt;
struct closed_channel **chans = tal_arr(ctx, struct closed_channel *, 0);
/* We load all channels */
stmt = db_prepare_v2(w->db, SQL("SELECT "
" p.node_id"
", full_channel_id"
", scid"
", alias_local"
", alias_remote"
", funder"
", closer"
", channel_flags"
", next_index_local"
", next_index_remote"
", next_htlc_id"
", funding_tx_id"
", funding_tx_outnum"
", funding_satoshi"
", push_msatoshi"
", msatoshi_local"
", msatoshi_to_us_min"
", msatoshi_to_us_max"
", last_tx"
", option_anchor_outputs"
", local_static_remotekey_start"
", state_change_reason"
", lease_commit_sig"
" FROM channels"
" LEFT JOIN peers p ON p.id = peer_id"
" WHERE state = ?;"));
db_bind_int(stmt, 0, CLOSED);
db_query_prepared(stmt);
while (db_step(stmt)) {
struct closed_channel *cc = wallet_stmt2closed_channel(chans,
w, stmt);
tal_arr_expand(&chans, cc);
}
tal_free(stmt);
return chans;
}
static void set_max_channel_dbid(struct wallet *w)
{
struct db_stmt *stmt;

View File

@@ -645,6 +645,16 @@ void wallet_delete_peer_if_unused(struct wallet *w, u64 peer_dbid);
*/
bool wallet_init_channels(struct wallet *w);
/**
* wallet_load_closed_channels -- Loads dead channels.
* @ctx: context to allocate returned array from
* @w: wallet to load from
*
* These will be all state CLOSED.
*/
struct closed_channel **wallet_load_closed_channels(const tal_t *ctx,
struct wallet *w);
/**
* wallet_channel_stats_incr_* - Increase channel statistics.
*