bkpr: annotate an account with the block at which it's been resolved

Due to the way that onchain channel closes work, there is often a delay
between when the funding output is spent and the channel is considered
'closed'.

Once *every* downstream utxo of a channel has landed on chain, we
annotate the account with the resolving blockheight.

This gives us some insight into whether or not the chain fees etc of a
channel are going to update further and allows for a natural marker to
prune data (at a later date)
This commit is contained in:
niftynei
2022-07-19 17:04:36 +09:30
committed by Rusty Russell
parent b33bd05524
commit 7b6956e4f9
3 changed files with 59 additions and 6 deletions

View File

@@ -756,7 +756,11 @@ listpeers_done(struct command *cmd, const char *buf,
"Unable to find account %s in listpeers",
info->acct->name);
/* FIXME: maybe mark channel as 'onchain_resolved' */
/* Maybe mark acct as onchain resolved */
db_begin_transaction(db);
if (info->acct->closed_event_db_id)
maybe_mark_account_onchain(db, info->acct);
db_commit_transaction(db);
return notification_handled(cmd);
}
@@ -1078,9 +1082,11 @@ parse_and_log_chain_move(struct command *cmd,
return command_still_pending(cmd);
}
/* FIXME: maybe mark channel as 'onchain_resolved' */
if (err)
plugin_err(cmd->plugin, err);
/* Maybe mark acct as onchain resolved */
db_begin_transaction(db);
if (acct->closed_event_db_id)
maybe_mark_account_onchain(db, acct);
db_commit_transaction(db);
return notification_handled(cmd);;
}

View File

@@ -334,7 +334,8 @@ bool find_txo_chain(const tal_t *ctx,
open_ev = find_chain_event_by_id(ctx, db,
*acct->open_event_db_id);
*sets = tal_arr(ctx, struct txo_set *, 0);
if (sets)
*sets = tal_arr(ctx, struct txo_set *, 0);
txids = tal_arr(ctx, struct bitcoin_txid *, 0);
tal_arr_expand(&txids, &open_ev->outpoint.txid);
@@ -379,12 +380,51 @@ bool find_txo_chain(const tal_t *ctx,
}
}
tal_arr_expand(sets, set);
if (sets)
tal_arr_expand(sets, set);
}
return is_complete;
}
void maybe_mark_account_onchain(struct db *db, struct account *acct)
{
const u8 *ctx = tal(NULL, u8);
if (find_txo_chain(ctx, db, acct, NULL)) {
/* Ok now we find the max block height of the
* spending chain_events for this channel */
bool ok;
struct db_stmt *stmt = db_prepare_v2(db,
SQL("SELECT"
" blockheight"
" FROM chain_events"
" WHERE account_id = ?"
" AND spending_txid IS NOT NULL"
" ORDER BY blockheight DESC"
" LIMIT 1"));
db_bind_u64(stmt, 0, acct->db_id);
db_query_prepared(stmt);
ok = db_step(stmt);
assert(ok);
acct->onchain_resolved_block = db_col_int(stmt, "blockheight");
tal_free(stmt);
/* Ok, now we update the account with this blockheight */
stmt = db_prepare_v2(db, SQL("UPDATE accounts SET"
" onchain_resolved_block = ?"
" WHERE"
" id = ?"));
db_bind_int(stmt, 0, acct->onchain_resolved_block);
db_bind_u64(stmt, 1, acct->db_id);
db_exec_prepared_v2(take(stmt));
}
tal_free(ctx);
}
struct chain_event *find_chain_event_by_id(const tal_t *ctx,
struct db *db,
u64 event_db_id)

View File

@@ -117,6 +117,13 @@ char *maybe_update_onchain_fees(const tal_t *ctx,
struct db *db,
struct bitcoin_txid *txid);
/* Have all the outputs for this account's close tx
* been resolved onchain? If so, update the account with the
* highest blockheight that has a resolving tx in it.
*
* The point of this is to allow us to prune data, eventually */
void maybe_mark_account_onchain(struct db *db, struct account *acct);
/* Log a channel event */
void log_channel_event(struct db *db,
const struct account *acct,