From 434cad0c3b47c4fbb5fdbb8dcc5658ba775444d0 Mon Sep 17 00:00:00 2001 From: lisa neigut Date: Wed, 18 Mar 2020 18:28:29 -0500 Subject: [PATCH] wallet-htlc: add 'we-filled' flag to saved htlc state The current plan for coin movements involves tagging origination/destination htlc's with a separate tag from 'routed' htlcs (which pass through our node). In order to do this, we need a persistent flag on incoming htlcs as to whether or not we are the final destination. --- lightningd/htlc_end.c | 1 + lightningd/htlc_end.h | 2 ++ lightningd/htlc_set.c | 3 +++ lightningd/peer_htlcs.c | 12 +++++++----- wallet/db.c | 3 +++ wallet/test/run-wallet.c | 10 +++++----- wallet/wallet.c | 18 ++++++++++++++---- wallet/wallet.h | 4 +++- 8 files changed, 38 insertions(+), 15 deletions(-) diff --git a/lightningd/htlc_end.c b/lightningd/htlc_end.c index c41121f31..5ed0937d1 100644 --- a/lightningd/htlc_end.c +++ b/lightningd/htlc_end.c @@ -158,6 +158,7 @@ struct htlc_in *new_htlc_in(const tal_t *ctx, hin->badonion = 0; hin->failonion = NULL; hin->preimage = NULL; + hin->we_filled = false; hin->received_time = time_now(); diff --git a/lightningd/htlc_end.h b/lightningd/htlc_end.h index 8d180e724..ce090f2ca 100644 --- a/lightningd/htlc_end.h +++ b/lightningd/htlc_end.h @@ -53,6 +53,8 @@ struct htlc_in { struct pubkey *blinding; /* Only set if blinding != NULL */ struct secret blinding_ss; + /* true if we supplied the preimage */ + bool we_filled; }; struct htlc_out { diff --git a/lightningd/htlc_set.c b/lightningd/htlc_set.c index ee27d90b8..a3c8308ab 100644 --- a/lightningd/htlc_set.c +++ b/lightningd/htlc_set.c @@ -57,6 +57,9 @@ void htlc_set_fulfill(struct htlc_set *set, const struct preimage *preimage) for (size_t i = 0; i < tal_count(set->htlcs); i++) { /* Don't remove from set */ tal_del_destructor2(set->htlcs[i], htlc_set_hin_destroyed, set); + + /* mark that we filled -- needed for tagging coin mvt */ + set->htlcs[i]->we_filled = true; fulfill_htlc(set->htlcs[i], preimage); } tal_free(set); diff --git a/lightningd/peer_htlcs.c b/lightningd/peer_htlcs.c index fdd69b71e..abce577ae 100644 --- a/lightningd/peer_htlcs.c +++ b/lightningd/peer_htlcs.c @@ -78,7 +78,8 @@ static bool htlc_in_update_state(struct channel *channel, wallet_htlc_update(channel->peer->ld->wallet, hin->dbid, newstate, hin->preimage, - hin->badonion, hin->failonion, NULL); + hin->badonion, hin->failonion, NULL, + hin->we_filled); hin->hstate = newstate; return true; @@ -94,7 +95,7 @@ static bool htlc_out_update_state(struct channel *channel, wallet_htlc_update(channel->peer->ld->wallet, hout->dbid, newstate, hout->preimage, 0, hout->failonion, - hout->failmsg); + hout->failmsg, false); hout->hstate = newstate; return true; @@ -187,7 +188,7 @@ static void failmsg_update_reply(struct subd *gossipd, cbdata->hin->dbid, cbdata->hin->hstate, cbdata->hin->preimage, cbdata->hin->badonion, - cbdata->hin->failonion, NULL); + cbdata->hin->failonion, NULL, false); failed_htlc = mk_failed_htlc(tmpctx, cbdata->hin, cbdata->hin->failonion); @@ -850,6 +851,7 @@ htlc_accepted_hook_try_resolve(struct htlc_accepted_hook_payload *request, towire_u16(&unknown_details, 0x400f); local_fail_in_htlc(hin, take(unknown_details)); } else { + hin->we_filled = true; fulfill_htlc(hin, payment_preimage); } } @@ -1247,7 +1249,7 @@ static void fulfill_our_htlc_out(struct channel *channel, struct htlc_out *hout, wallet_htlc_update(ld->wallet, hout->dbid, hout->hstate, hout->preimage, 0, hout->failonion, - hout->failmsg); + hout->failmsg, false); /* Update channel stats */ wallet_channel_stats_incr_out_fulfilled(ld->wallet, channel->dbid, @@ -1416,7 +1418,7 @@ void onchain_failed_our_htlc(const struct channel *channel, htlc_out_check(hout, __func__); wallet_htlc_update(ld->wallet, hout->dbid, hout->hstate, hout->preimage, 0, hout->failonion, - hout->failmsg); + hout->failmsg, false); if (hout->am_origin) { assert(why != NULL); diff --git a/wallet/db.c b/wallet/db.c index ff1423802..1a87e8b93 100644 --- a/wallet/db.c +++ b/wallet/db.c @@ -607,6 +607,9 @@ static struct migration dbmigrations[] = { ", amount BIGINT" ", PRIMARY KEY (channel_id, commitnum)" ");"), NULL}, + /* For incoming HTLCs, we now keep track of whether or not we provided + * the preimage for it, or not. */ + {SQL("ALTER TABLE channel_htlcs ADD we_filled INTEGER;"), NULL}, }; /* Leak tracking. */ diff --git a/wallet/test/run-wallet.c b/wallet/test/run-wallet.c index 6ae1fe4b3..2e9797983 100644 --- a/wallet/test/run-wallet.c +++ b/wallet/test/run-wallet.c @@ -1311,17 +1311,17 @@ static bool test_htlc_crud(struct lightningd *ld, const tal_t *ctx) wallet_err = tal_free(wallet_err); /* Update */ - CHECK_MSG(transaction_wrap(w->db, wallet_htlc_update(w, in.dbid, RCVD_ADD_HTLC, NULL, 0, NULL, NULL)), + CHECK_MSG(transaction_wrap(w->db, wallet_htlc_update(w, in.dbid, RCVD_ADD_HTLC, NULL, 0, NULL, NULL, false)), "Update HTLC with null payment_key failed"); CHECK_MSG( - transaction_wrap(w->db, wallet_htlc_update(w, in.dbid, SENT_REMOVE_HTLC, &payment_key, 0, NULL, NULL)), + transaction_wrap(w->db, wallet_htlc_update(w, in.dbid, SENT_REMOVE_HTLC, &payment_key, 0, NULL, NULL, false)), "Update HTLC with payment_key failed"); onionreply = new_onionreply(tmpctx, tal_arrz(tmpctx, u8, 100)); CHECK_MSG( - transaction_wrap(w->db, wallet_htlc_update(w, in.dbid, SENT_REMOVE_HTLC, NULL, 0, onionreply, NULL)), + transaction_wrap(w->db, wallet_htlc_update(w, in.dbid, SENT_REMOVE_HTLC, NULL, 0, onionreply, NULL, false)), "Update HTLC with failonion failed"); CHECK_MSG( - transaction_wrap(w->db, wallet_htlc_update(w, in.dbid, SENT_REMOVE_HTLC, NULL, WIRE_INVALID_ONION_VERSION, NULL, NULL)), + transaction_wrap(w->db, wallet_htlc_update(w, in.dbid, SENT_REMOVE_HTLC, NULL, WIRE_INVALID_ONION_VERSION, NULL, NULL, false)), "Update HTLC with failcode failed"); CHECK_MSG(transaction_wrap(w->db, wallet_htlc_save_out(w, chan, &out)), @@ -1333,7 +1333,7 @@ static bool test_htlc_crud(struct lightningd *ld, const tal_t *ctx) CHECK(wallet_err); wallet_err = tal_free(wallet_err); CHECK_MSG( - transaction_wrap(w->db, wallet_htlc_update(w, out.dbid, SENT_ADD_ACK_REVOCATION, NULL, 0, NULL, tal_arrz(tmpctx, u8, 100))), + transaction_wrap(w->db, wallet_htlc_update(w, out.dbid, SENT_ADD_ACK_REVOCATION, NULL, 0, NULL, tal_arrz(tmpctx, u8, 100), false)), "Update outgoing HTLC with failmsg failed"); /* Attempt to load them from the DB again */ diff --git a/wallet/wallet.c b/wallet/wallet.c index 1a3532860..557174c4a 100644 --- a/wallet/wallet.c +++ b/wallet/wallet.c @@ -1785,13 +1785,14 @@ void wallet_htlc_save_out(struct wallet *wallet, tal_free(stmt); } -/* input htlcs use failcode & failonion, output htlcs use failmsg & failonion */ +/* input htlcs use failcode & failonion & we_filled, output htlcs use failmsg & failonion */ void wallet_htlc_update(struct wallet *wallet, const u64 htlc_dbid, const enum htlc_state new_state, const struct preimage *payment_key, enum onion_type badonion, const struct onionreply *failonion, - const u8 *failmsg) + const u8 *failmsg, + bool we_filled) { struct db_stmt *stmt; @@ -1803,12 +1804,13 @@ void wallet_htlc_update(struct wallet *wallet, const u64 htlc_dbid, assert(htlc_dbid); stmt = db_prepare_v2( wallet->db, SQL("UPDATE channel_htlcs SET hstate=?, payment_key=?, " - "malformed_onion=?, failuremsg=?, localfailmsg=?" + "malformed_onion=?, failuremsg=?, localfailmsg=?, " + "we_filled=?" " WHERE id=?")); /* FIXME: htlc_state_in_db */ db_bind_int(stmt, 0, new_state); - db_bind_u64(stmt, 5, htlc_dbid); + db_bind_u64(stmt, 6, htlc_dbid); if (payment_key) db_bind_preimage(stmt, 1, payment_key); @@ -1827,6 +1829,11 @@ void wallet_htlc_update(struct wallet *wallet, const u64 htlc_dbid, else db_bind_null(stmt, 4); + if (we_filled) + db_bind_int(stmt, 5, 1); + else + db_bind_null(stmt, 5); + db_exec_prepared_v2(take(stmt)); } @@ -1897,6 +1904,8 @@ static bool wallet_stmt2htlc_in(struct channel *channel, } #endif + in->we_filled = !db_column_is_null(stmt, 13); + return ok; } @@ -2023,6 +2032,7 @@ bool wallet_htlcs_load_in_for_channel(struct wallet *wallet, ", origin_htlc" ", shared_secret" ", received_time" + ", we_filled" " FROM channel_htlcs" " WHERE direction= ?" " AND channel_id= ?" diff --git a/wallet/wallet.h b/wallet/wallet.h index 911367deb..d68c9d4f3 100644 --- a/wallet/wallet.h +++ b/wallet/wallet.h @@ -596,6 +596,7 @@ void wallet_htlc_save_out(struct wallet *wallet, * @badonion: the current BADONION failure code, or 0. * @failonion: the current failure onion message (from peer), or NULL. * @failmsg: the current local failure message, or NULL. + * @we_filled: for htlc-ins, true if we originated the preimage. * * Used to update the state of an HTLC, either a `struct htlc_in` or a * `struct htlc_out` and optionally set the `payment_key` should the @@ -606,7 +607,8 @@ void wallet_htlc_update(struct wallet *wallet, const u64 htlc_dbid, const struct preimage *payment_key, enum onion_type badonion, const struct onionreply *failonion, - const u8 *failmsg); + const u8 *failmsg, + bool we_filled); /** * wallet_htlcs_load_in_for_channel - Load incoming HTLCs associated with chan from DB.