mirror of
https://github.com/aljazceru/lightning.git
synced 2026-01-26 17:24:20 +01:00
bkpr: mark external deposits (withdraws) via blockheight when confirmed
We issue events for external deposits (withdrawals) before the tx is confirmed in a block. To avoid double counting these, we don't count them as confirmed/included until after they're confirmed. We do this by keeping the blockheight as zero until the withdraw for the input for them comes through. Note that since we don't have any way to note when RBF'd withdraws aren't eligible for block inclusion anymore, we don't really have a good heuristic to trim them. Which is fine, they *will* show up in account events however.
This commit is contained in:
@@ -1072,6 +1072,18 @@ parse_and_log_chain_move(struct command *cmd,
|
||||
"Unable to update onchain fees %s",
|
||||
err);
|
||||
|
||||
/* If this is a spend confirmation event, it's possible
|
||||
* that it we've got an external deposit that's now
|
||||
* confirmed */
|
||||
if (e->spending_txid) {
|
||||
db_begin_transaction(db);
|
||||
/* Go see if there's any deposits to an external
|
||||
* that are now confirmed */
|
||||
/* FIXME: might need updating when we can splice? */
|
||||
maybe_closeout_external_deposits(db, e);
|
||||
db_commit_transaction(db);
|
||||
}
|
||||
|
||||
/* If this is an account close event, it's possible
|
||||
* that we *never* got the open event. (This happens
|
||||
* if you add the plugin *after* you've closed the channel) */
|
||||
|
||||
@@ -133,6 +133,12 @@ static struct income_event *maybe_chain_income(const tal_t *ctx,
|
||||
/* deposit to external is cost to us */
|
||||
if (streq(ev->acct_name, EXTERNAL_ACCT)) {
|
||||
struct income_event *iev;
|
||||
|
||||
/* External deposits w/o a blockheight
|
||||
* aren't confirmed yet */
|
||||
if (ev->blockheight == 0)
|
||||
return NULL;
|
||||
|
||||
iev = chain_to_income(ctx, ev,
|
||||
ev->origin_acct,
|
||||
ev->debit,
|
||||
|
||||
@@ -1638,6 +1638,44 @@ finished:
|
||||
return err;
|
||||
}
|
||||
|
||||
void maybe_closeout_external_deposits(struct db *db,
|
||||
struct chain_event *ev)
|
||||
{
|
||||
struct db_stmt *stmt;
|
||||
|
||||
assert(ev->spending_txid);
|
||||
stmt = db_prepare_v2(db, SQL("SELECT "
|
||||
" e.id"
|
||||
" FROM chain_events e"
|
||||
" LEFT OUTER JOIN accounts a"
|
||||
" ON e.account_id = a.id"
|
||||
" WHERE e.blockheight = ?"
|
||||
" AND e.utxo_txid = ?"
|
||||
" AND a.name = ?"));
|
||||
|
||||
/* Blockheight for unconfirmeds is zero */
|
||||
db_bind_int(stmt, 0, 0);
|
||||
db_bind_txid(stmt, 1, ev->spending_txid);
|
||||
db_bind_text(stmt, 2, EXTERNAL_ACCT);
|
||||
db_query_prepared(stmt);
|
||||
|
||||
while (db_step(stmt)) {
|
||||
struct db_stmt *update_stmt;
|
||||
u64 id;
|
||||
|
||||
id = db_col_u64(stmt, "e.id");
|
||||
update_stmt = db_prepare_v2(db, SQL("UPDATE chain_events SET"
|
||||
" blockheight = ?"
|
||||
" WHERE id = ?"));
|
||||
|
||||
db_bind_int(update_stmt, 0, ev->blockheight);
|
||||
db_bind_u64(update_stmt, 1, id);
|
||||
db_exec_prepared_v2(take(update_stmt));
|
||||
}
|
||||
|
||||
tal_free(stmt);
|
||||
}
|
||||
|
||||
bool log_chain_event(struct db *db,
|
||||
const struct account *acct,
|
||||
struct chain_event *e)
|
||||
|
||||
@@ -171,6 +171,14 @@ char *update_channel_onchain_fees(const tal_t *ctx,
|
||||
* The point of this is to allow us to prune data, eventually */
|
||||
void maybe_mark_account_onchain(struct db *db, struct account *acct);
|
||||
|
||||
/* When we make external deposits from the wallet, we don't
|
||||
* count them until any output that was spent *into* them is
|
||||
* confirmed onchain.
|
||||
*
|
||||
* This method updates the blockheight on these events to the
|
||||
* height an input was spent into */
|
||||
void maybe_closeout_external_deposits(struct db *db, struct chain_event *ev);
|
||||
|
||||
/* Log a channel event */
|
||||
void log_channel_event(struct db *db,
|
||||
const struct account *acct,
|
||||
|
||||
Reference in New Issue
Block a user