mirror of
https://github.com/aljazceru/lightning.git
synced 2026-02-23 15:04:19 +01:00
coin_mvt/bkpr: add "stealable" tag to stealable outputs
If we expect further events for an onchain output (because we can steal it away from the 'external'/rightful owner), we mark them. This prevents us from marking a channel as 'onchain-resolved' before all events that we're interested in have actually hit the chain. Case that this matters: Peer publishes a (cheating) unilateral close and a timeout htlc (which we can steal). We then steal the timeout htlc. W/o the stealable flag, we'd have marked the channel as resolved when the peer published the timeout htlc, which is incorrect as we're still waiting for the resolution of that timeout htlc (b/c we *can* steal it).
This commit is contained in:
@@ -618,6 +618,7 @@ static bool new_missed_channel_account(struct command *cmd,
|
||||
chain_ev->spending_txid = NULL;
|
||||
chain_ev->payment_id = NULL;
|
||||
chain_ev->ignored = false;
|
||||
chain_ev->stealable = false;
|
||||
|
||||
/* Update the account info too */
|
||||
tags = tal_arr(chain_ev, enum mvt_tag, 1);
|
||||
@@ -1234,8 +1235,12 @@ parse_and_log_chain_move(struct command *cmd,
|
||||
e->tag = mvt_tag_str(tags[0]);
|
||||
|
||||
e->ignored = false;
|
||||
for (size_t i = 0; i < tal_count(tags); i++)
|
||||
e->stealable = false;
|
||||
for (size_t i = 0; i < tal_count(tags); i++) {
|
||||
e->ignored |= tags[i] == IGNORED;
|
||||
e->stealable |= tags[i] == STEALABLE;
|
||||
}
|
||||
|
||||
|
||||
db_begin_transaction(db);
|
||||
acct = find_account(cmd, db, acct_name);
|
||||
|
||||
@@ -30,6 +30,10 @@ struct chain_event {
|
||||
/* Is the node's wallet ignoring this? */
|
||||
bool ignored;
|
||||
|
||||
/* Is this chain output stealable? If so
|
||||
* we'll need to watch it for longer */
|
||||
bool stealable;
|
||||
|
||||
/* Amount we received in this event */
|
||||
struct amount_msat credit;
|
||||
|
||||
|
||||
@@ -95,6 +95,7 @@ static struct migration db_migrations[] = {
|
||||
{SQL("ALTER TABLE chain_events ADD origin TEXT;"), NULL},
|
||||
{SQL("ALTER TABLE accounts ADD closed_count INTEGER DEFAULT 0;"), NULL},
|
||||
{SQL("ALTER TABLE chain_events ADD ignored INTEGER;"), NULL},
|
||||
{SQL("ALTER TABLE chain_events ADD stealable INTEGER;"), NULL},
|
||||
};
|
||||
|
||||
static bool db_migrate(struct plugin *p, struct db *db)
|
||||
|
||||
@@ -56,6 +56,7 @@ static struct chain_event *stmt2chain_event(const tal_t *ctx, struct db_stmt *st
|
||||
e->spending_txid = NULL;
|
||||
|
||||
e->ignored = db_col_int(stmt, "e.ignored") == 1;
|
||||
e->stealable = db_col_int(stmt, "e.stealable") == 1;
|
||||
|
||||
return e;
|
||||
}
|
||||
@@ -128,6 +129,7 @@ struct chain_event **list_chain_events_timebox(const tal_t *ctx,
|
||||
", e.spending_txid"
|
||||
", e.payment_id"
|
||||
", e.ignored"
|
||||
", e.stealable"
|
||||
" FROM chain_events e"
|
||||
" LEFT OUTER JOIN accounts a"
|
||||
" ON e.account_id = a.id"
|
||||
@@ -168,6 +170,7 @@ struct chain_event **account_get_chain_events(const tal_t *ctx,
|
||||
", e.spending_txid"
|
||||
", e.payment_id"
|
||||
", e.ignored"
|
||||
", e.stealable"
|
||||
" FROM chain_events e"
|
||||
" LEFT OUTER JOIN accounts a"
|
||||
" ON e.account_id = a.id"
|
||||
@@ -201,6 +204,7 @@ static struct chain_event **find_txos_for_tx(const tal_t *ctx,
|
||||
", e.spending_txid"
|
||||
", e.payment_id"
|
||||
", e.ignored"
|
||||
", e.stealable"
|
||||
" FROM chain_events e"
|
||||
" LEFT OUTER JOIN accounts a"
|
||||
" ON e.account_id = a.id"
|
||||
@@ -473,10 +477,12 @@ bool find_txo_chain(const tal_t *ctx,
|
||||
&& !streq(pr->spend->tag, "to_miner")
|
||||
&& !txid_in_list(txids, pr->spend->spending_txid)
|
||||
/* We dont trace utxos for non related accts */
|
||||
&& pr->spend->acct_db_id == acct->db_id) {
|
||||
&& (pr->spend->acct_db_id == acct->db_id
|
||||
/* Unless it's stealable, in which case
|
||||
* we track the resolution of the htlc tx */
|
||||
|| pr->spend->stealable))
|
||||
tal_arr_expand(&txids,
|
||||
pr->spend->spending_txid);
|
||||
}
|
||||
}
|
||||
|
||||
if (sets)
|
||||
@@ -604,6 +610,7 @@ struct chain_event *find_chain_event_by_id(const tal_t *ctx,
|
||||
", e.spending_txid"
|
||||
", e.payment_id"
|
||||
", e.ignored"
|
||||
", e.stealable"
|
||||
" FROM chain_events e"
|
||||
" LEFT OUTER JOIN accounts a"
|
||||
" ON e.account_id = a.id"
|
||||
@@ -649,6 +656,7 @@ static struct chain_event *find_chain_event(const tal_t *ctx,
|
||||
", e.spending_txid"
|
||||
", e.payment_id"
|
||||
", e.ignored"
|
||||
", e.stealable"
|
||||
" FROM chain_events e"
|
||||
" LEFT OUTER JOIN accounts a"
|
||||
" ON e.account_id = a.id"
|
||||
@@ -676,6 +684,7 @@ static struct chain_event *find_chain_event(const tal_t *ctx,
|
||||
", e.spending_txid"
|
||||
", e.payment_id"
|
||||
", e.ignored"
|
||||
", e.stealable"
|
||||
" FROM chain_events e"
|
||||
" LEFT OUTER JOIN accounts a"
|
||||
" ON e.account_id = a.id"
|
||||
@@ -1203,6 +1212,7 @@ void maybe_update_account(struct db *db,
|
||||
case STOLEN:
|
||||
case TO_MINER:
|
||||
case LEASE_FEE:
|
||||
case STEALABLE:
|
||||
/* Ignored */
|
||||
break;
|
||||
}
|
||||
@@ -1319,6 +1329,7 @@ static struct chain_event **find_chain_events_bytxid(const tal_t *ctx, struct db
|
||||
", e.spending_txid"
|
||||
", e.payment_id"
|
||||
", e.ignored"
|
||||
", e.stealable"
|
||||
" FROM chain_events e"
|
||||
" LEFT OUTER JOIN accounts a"
|
||||
" ON a.id = e.account_id"
|
||||
@@ -1808,9 +1819,10 @@ bool log_chain_event(struct db *db,
|
||||
", payment_id"
|
||||
", spending_txid"
|
||||
", ignored"
|
||||
", stealable"
|
||||
")"
|
||||
" VALUES "
|
||||
"(?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?);"));
|
||||
"(?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?);"));
|
||||
|
||||
db_bind_u64(stmt, 0, acct->db_id);
|
||||
if (e->origin_acct)
|
||||
@@ -1838,6 +1850,7 @@ bool log_chain_event(struct db *db,
|
||||
db_bind_null(stmt, 12);
|
||||
|
||||
db_bind_int(stmt, 13, e->ignored ? 1 : 0);
|
||||
db_bind_int(stmt, 14, e->stealable ? 1 : 0);
|
||||
db_exec_prepared_v2(stmt);
|
||||
e->db_id = db_last_insert_id_v2(stmt);
|
||||
e->acct_db_id = acct->db_id;
|
||||
|
||||
@@ -363,6 +363,7 @@ static struct chain_event *make_chain_event(const tal_t *ctx,
|
||||
ev->timestamp = 1919191;
|
||||
ev->blockheight = blockheight;
|
||||
ev->ignored = false;
|
||||
ev->stealable = false;
|
||||
memset(&ev->outpoint.txid, outpoint_char, sizeof(struct bitcoin_txid));
|
||||
ev->outpoint.n = outnum;
|
||||
|
||||
@@ -965,6 +966,7 @@ static bool test_chain_event_crud(const tal_t *ctx, struct plugin *p)
|
||||
ev1->timestamp = 1919191;
|
||||
ev1->blockheight = 1919191;
|
||||
ev1->ignored = false;
|
||||
ev1->stealable = false;
|
||||
memset(&ev1->outpoint.txid, 'D', sizeof(struct bitcoin_txid));
|
||||
ev1->outpoint.n = 1;
|
||||
ev1->spending_txid = tal(ctx, struct bitcoin_txid);
|
||||
@@ -985,6 +987,7 @@ static bool test_chain_event_crud(const tal_t *ctx, struct plugin *p)
|
||||
ev2->timestamp = 1919191;
|
||||
ev2->blockheight = 1919191;
|
||||
ev2->ignored = false;
|
||||
ev2->stealable = false;
|
||||
memset(&ev2->outpoint.txid, 'D', sizeof(struct bitcoin_txid));
|
||||
ev2->outpoint.n = 1;
|
||||
ev2->spending_txid = NULL;
|
||||
@@ -1002,6 +1005,7 @@ static bool test_chain_event_crud(const tal_t *ctx, struct plugin *p)
|
||||
ev3->timestamp = 3939393;
|
||||
ev3->blockheight = 3939393;
|
||||
ev3->ignored = false;
|
||||
ev3->stealable = false;
|
||||
memset(&ev3->outpoint.txid, 'E', sizeof(struct bitcoin_txid));
|
||||
ev3->outpoint.n = 1;
|
||||
ev3->spending_txid = tal(ctx, struct bitcoin_txid);
|
||||
@@ -1228,6 +1232,7 @@ static bool test_account_crud(const tal_t *ctx, struct plugin *p)
|
||||
ev1->timestamp = 1919191;
|
||||
ev1->blockheight = 1919191;
|
||||
ev1->ignored = false;
|
||||
ev1->stealable = false;
|
||||
memset(&ev1->outpoint.txid, 'D', sizeof(struct bitcoin_txid));
|
||||
ev1->outpoint.n = 1;
|
||||
ev1->spending_txid = tal(ctx, struct bitcoin_txid);
|
||||
|
||||
Reference in New Issue
Block a user