From 46dcc6e031b0b424fb77a44bcf009fdfa1b41934 Mon Sep 17 00:00:00 2001 From: niftynei Date: Tue, 6 Aug 2024 00:14:20 -0500 Subject: [PATCH] bkpr: properly account for fees and channel closures if splice We do some fancy accounting for channel closures; since we're tagging splice txs as closes we need to mark them as splices so we can treat them as any other 'normal' on chain event. --- plugins/bkpr/bookkeeper.c | 3 +++ plugins/bkpr/chain_event.h | 4 ++++ plugins/bkpr/db.c | 1 + plugins/bkpr/recorder.c | 22 +++++++++++++++++++--- plugins/bkpr/test/run-recorder.c | 7 +++++++ 5 files changed, 34 insertions(+), 3 deletions(-) diff --git a/plugins/bkpr/bookkeeper.c b/plugins/bkpr/bookkeeper.c index 4735e3359..33ffb87d1 100644 --- a/plugins/bkpr/bookkeeper.c +++ b/plugins/bkpr/bookkeeper.c @@ -671,6 +671,7 @@ static bool new_missed_channel_account(struct command *cmd, chain_ev->payment_id = NULL; chain_ev->ignored = false; chain_ev->stealable = false; + chain_ev->splice_close = false; chain_ev->desc = NULL; /* Update the account info too */ @@ -1458,9 +1459,11 @@ parse_and_log_chain_move(struct command *cmd, e->ignored = false; e->stealable = false; + e->splice_close = false; for (size_t i = 0; i < tal_count(tags); i++) { e->ignored |= tags[i] == IGNORED; e->stealable |= tags[i] == STEALABLE; + e->splice_close |= tags[i] == SPLICE; } db_begin_transaction(db); diff --git a/plugins/bkpr/chain_event.h b/plugins/bkpr/chain_event.h index a9c5f3a6a..4d9785d02 100644 --- a/plugins/bkpr/chain_event.h +++ b/plugins/bkpr/chain_event.h @@ -34,6 +34,10 @@ struct chain_event { * we'll need to watch it for longer */ bool stealable; + /* Is this chain event because of a splice + * confirmation? */ + bool splice_close; + /* Is this a rebalance event? */ bool rebalance; diff --git a/plugins/bkpr/db.c b/plugins/bkpr/db.c index b8f3fc32d..06943af91 100644 --- a/plugins/bkpr/db.c +++ b/plugins/bkpr/db.c @@ -99,6 +99,7 @@ static struct migration db_migrations[] = { {SQL("ALTER TABLE chain_events ADD ev_desc TEXT DEFAULT NULL;"), NULL}, {SQL("ALTER TABLE channel_events ADD ev_desc TEXT DEFAULT NULL;"), NULL}, {SQL("ALTER TABLE channel_events ADD rebalance_id BIGINT DEFAULT NULL;"), NULL}, + {SQL("ALTER TABLE chain_events ADD spliced INTEGER DEFAULT 0;"), NULL}, {NULL, migration_remove_dupe_lease_fees} }; diff --git a/plugins/bkpr/recorder.c b/plugins/bkpr/recorder.c index e7dd9b4d3..c165c435d 100644 --- a/plugins/bkpr/recorder.c +++ b/plugins/bkpr/recorder.c @@ -62,6 +62,8 @@ static struct chain_event *stmt2chain_event(const tal_t *ctx, struct db_stmt *st else e->desc = NULL; + e->splice_close = db_col_int(stmt, "e.spliced") == 1; + return e; } @@ -162,6 +164,7 @@ struct chain_event **list_chain_events_timebox(const tal_t *ctx, ", e.ignored" ", e.stealable" ", e.ev_desc" + ", e.spliced" " FROM chain_events e" " LEFT OUTER JOIN accounts a" " ON e.account_id = a.id" @@ -204,6 +207,7 @@ struct chain_event **account_get_chain_events(const tal_t *ctx, ", e.ignored" ", e.stealable" ", e.ev_desc" + ", e.spliced" " FROM chain_events e" " LEFT OUTER JOIN accounts a" " ON e.account_id = a.id" @@ -239,6 +243,7 @@ static struct chain_event **find_txos_for_tx(const tal_t *ctx, ", e.ignored" ", e.stealable" ", e.ev_desc" + ", e.spliced" " FROM chain_events e" " LEFT OUTER JOIN accounts a" " ON e.account_id = a.id" @@ -548,7 +553,9 @@ struct account *find_close_account(const tal_t *ctx, " ON e.account_id = a.id" " WHERE " " e.tag = ?" - " AND e.spending_txid = ?")); + " AND e.spending_txid = ?" + /* ignore splicing 'close' events */ + " AND e.spliced = 0 ")); db_bind_text(stmt, mvt_tag_str(CHANNEL_CLOSE)); db_bind_txid(stmt, txid); @@ -678,6 +685,7 @@ struct chain_event *find_chain_event_by_id(const tal_t *ctx, ", e.ignored" ", e.stealable" ", e.ev_desc" + ", e.spliced" " FROM chain_events e" " LEFT OUTER JOIN accounts a" " ON e.account_id = a.id" @@ -726,6 +734,7 @@ static struct chain_event *find_chain_event(const tal_t *ctx, ", e.ignored" ", e.stealable" ", e.ev_desc" + ", e.spliced" " FROM chain_events e" " LEFT OUTER JOIN accounts a" " ON e.account_id = a.id" @@ -755,6 +764,7 @@ static struct chain_event *find_chain_event(const tal_t *ctx, ", e.ignored" ", e.stealable" ", e.ev_desc" + ", e.spliced" " FROM chain_events e" " LEFT OUTER JOIN accounts a" " ON e.account_id = a.id" @@ -1263,6 +1273,9 @@ void maybe_update_account(struct db *db, *acct->open_event_db_id = e->db_id; break; case CHANNEL_CLOSE: + /* Splices dont count as closes */ + if (e->splice_close) + break; updated = true; acct->closed_event_db_id = tal(acct, u64); *acct->closed_event_db_id = e->db_id; @@ -1305,7 +1318,7 @@ void maybe_update_account(struct db *db, acct->peer_id = tal_dup(acct, struct node_id, peer_id); } - if (closed_count > 0) { + if (!e->splice_close && closed_count > 0) { updated = true; acct->closed_count = closed_count; } @@ -1424,6 +1437,7 @@ static struct chain_event **find_chain_events_bytxid(const tal_t *ctx, struct db ", e.ignored" ", e.stealable" ", e.ev_desc" + ", e.spliced" " FROM chain_events e" " LEFT OUTER JOIN accounts a" " ON a.id = e.account_id" @@ -2003,9 +2017,10 @@ bool log_chain_event(struct db *db, ", ignored" ", stealable" ", ev_desc" + ", spliced" ")" " VALUES " - "(?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?);")); + "(?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?);")); db_bind_u64(stmt, acct->db_id); if (e->origin_acct) @@ -2038,6 +2053,7 @@ bool log_chain_event(struct db *db, db_bind_text(stmt, e->desc); else db_bind_null(stmt); + db_bind_int(stmt, e->splice_close ? 1 : 0); db_exec_prepared_v2(stmt); e->db_id = db_last_insert_id_v2(stmt); e->acct_db_id = acct->db_id; diff --git a/plugins/bkpr/test/run-recorder.c b/plugins/bkpr/test/run-recorder.c index 5ebac38ab..8f805d413 100644 --- a/plugins/bkpr/test/run-recorder.c +++ b/plugins/bkpr/test/run-recorder.c @@ -355,6 +355,8 @@ static bool chain_events_eq(struct chain_event *e1, struct chain_event *e2) if (e1->desc) CHECK(streq(e1->desc, e2->desc)); + CHECK(e1->splice_close == e2->splice_close); + return true; } @@ -406,6 +408,7 @@ static struct chain_event *make_chain_event(const tal_t *ctx, ev->blockheight = blockheight; ev->ignored = false; ev->stealable = false; + ev->splice_close = false; ev->desc = tal_fmt(ev, "hello hello"); memset(&ev->outpoint.txid, outpoint_char, sizeof(struct bitcoin_txid)); ev->outpoint.n = outnum; @@ -1084,6 +1087,7 @@ static bool test_chain_event_crud(const tal_t *ctx, struct plugin *p) ev1->blockheight = 1919191; ev1->ignored = false; ev1->stealable = false; + ev1->splice_close = false; memset(&ev1->outpoint.txid, 'D', sizeof(struct bitcoin_txid)); ev1->outpoint.n = 1; ev1->spending_txid = tal(ctx, struct bitcoin_txid); @@ -1105,6 +1109,7 @@ static bool test_chain_event_crud(const tal_t *ctx, struct plugin *p) ev2->blockheight = 1919191; ev2->ignored = false; ev2->stealable = false; + ev2->splice_close = false; memset(&ev2->outpoint.txid, 'D', sizeof(struct bitcoin_txid)); ev2->outpoint.n = 1; ev2->spending_txid = NULL; @@ -1124,6 +1129,7 @@ static bool test_chain_event_crud(const tal_t *ctx, struct plugin *p) ev3->blockheight = 3939393; ev3->ignored = false; ev3->stealable = false; + ev3->splice_close = false; memset(&ev3->outpoint.txid, 'E', sizeof(struct bitcoin_txid)); ev3->outpoint.n = 1; ev3->spending_txid = tal(ctx, struct bitcoin_txid); @@ -1351,6 +1357,7 @@ static bool test_account_crud(const tal_t *ctx, struct plugin *p) ev1->blockheight = 1919191; ev1->ignored = false; ev1->stealable = false; + ev1->splice_close = false; memset(&ev1->outpoint.txid, 'D', sizeof(struct bitcoin_txid)); ev1->outpoint.n = 1; ev1->spending_txid = tal(ctx, struct bitcoin_txid);