From 667a7636595b31e8fdc3eff6d2b8dba0bd9c4221 Mon Sep 17 00:00:00 2001 From: Christian Decker Date: Thu, 7 May 2020 10:12:40 +0930 Subject: [PATCH] db: Add a table to track the penalty_bases for revocations --- wallet/db.c | 8 +++++++ wallet/wallet.c | 61 +++++++++++++++++++++++++++++++++++++++++++++++++ wallet/wallet.h | 25 ++++++++++++++++++++ 3 files changed, 94 insertions(+) diff --git a/wallet/db.c b/wallet/db.c index 673d4d88a..ff1423802 100644 --- a/wallet/db.c +++ b/wallet/db.c @@ -599,6 +599,14 @@ static struct migration dbmigrations[] = { {SQL("ALTER TABLE channel_htlcs ADD localfailmsg BLOB;"), NULL}, {SQL("UPDATE channel_htlcs SET localfailmsg=decode('2002', 'hex') WHERE malformed_onion != 0 AND direction = 1;"), NULL}, {SQL("ALTER TABLE channels ADD our_funding_satoshi BIGINT DEFAULT 0;"), migrate_our_funding}, + {SQL("CREATE TABLE penalty_bases (" + " channel_id BIGINT REFERENCES channels(id) ON DELETE CASCADE" + ", commitnum BIGINT" + ", txid BLOB" + ", outnum INTEGER" + ", amount BIGINT" + ", PRIMARY KEY (channel_id, commitnum)" + ");"), NULL}, }; /* Leak tracking. */ diff --git a/wallet/wallet.c b/wallet/wallet.c index 662a4f10f..1a3532860 100644 --- a/wallet/wallet.c +++ b/wallet/wallet.c @@ -3786,3 +3786,64 @@ struct wallet_transaction *wallet_transactions_get(struct wallet *w, const tal_t tal_free(stmt); return txs; } + +void wallet_penalty_base_add(struct wallet *w, u64 chan_id, + const struct penalty_base *pb) +{ + struct db_stmt *stmt; + stmt = db_prepare_v2(w->db, + SQL("INSERT INTO penalty_bases (" + " channel_id" + ", commitnum" + ", txid" + ", outnum" + ", amount" + ") VALUES (?, ?, ?, ?, ?);")); + + db_bind_u64(stmt, 0, chan_id); + db_bind_u64(stmt, 1, pb->commitment_num); + db_bind_txid(stmt, 2, &pb->txid); + db_bind_int(stmt, 3, pb->outnum); + db_bind_amount_sat(stmt, 4, &pb->amount); + + db_exec_prepared_v2(take(stmt)); +} + +struct penalty_base *wallet_penalty_base_load_for_channel(const tal_t *ctx, + struct wallet *w, + u64 chan_id) +{ + struct db_stmt *stmt; + struct penalty_base *res = tal_arr(ctx, struct penalty_base, 0); + stmt = db_prepare_v2( + w->db, + SQL("SELECT commitnum, txid, outnum, amount " + "FROM penalty_bases " + "WHERE channel_id = ?")); + + db_bind_u64(stmt, 0, chan_id); + db_query_prepared(stmt); + + while (db_step(stmt)) { + struct penalty_base pb; + pb.commitment_num = db_column_u64(stmt, 0); + db_column_txid(stmt, 1, &pb.txid); + pb.outnum = db_column_int(stmt, 2); + db_column_amount_sat(stmt, 3, &pb.amount); + tal_arr_expand(&res, pb); + } + tal_free(stmt); + return res; +} + +void wallet_penalty_base_delete(struct wallet *w, u64 chan_id, u64 commitnum) +{ + struct db_stmt *stmt; + stmt = db_prepare_v2( + w->db, + SQL("DELETE FROM penalty_bases " + "WHERE channel_id = ? AND commitnum = ?")); + db_bind_u64(stmt, 0, chan_id); + db_bind_u64(stmt, 1, commitnum); + db_exec_prepared_v2(take(stmt)); +} diff --git a/wallet/wallet.h b/wallet/wallet.h index 40aead5ca..911367deb 100644 --- a/wallet/wallet.h +++ b/wallet/wallet.h @@ -10,6 +10,7 @@ #include #include #include +#include #include #include #include @@ -1251,4 +1252,28 @@ struct wallet_transaction *wallet_transactions_get(struct wallet *w, const tal_t */ void wallet_filteredblock_add(struct wallet *w, const struct filteredblock *fb); +/** + * Store a penalty base in the database. + * + * Required to eventually create a penalty transaction when we get a + * revocation. + */ +void wallet_penalty_base_add(struct wallet *w, u64 chan_id, + const struct penalty_base *pb); + +/** + * Retrieve all pending penalty bases for a given channel. + * + * This list should stay relatively small since we remove items from it as we + * get revocations. We retrieve this list whenever we start a new `channeld`. + */ +struct penalty_base *wallet_penalty_base_load_for_channel(const tal_t *ctx, + struct wallet *w, + u64 chan_id); + +/** + * Delete a penalty_base, after we created and delivered it to the hook. + */ +void wallet_penalty_base_delete(struct wallet *w, u64 chan_id, u64 commitnum); + #endif /* LIGHTNING_WALLET_WALLET_H */