From 79ebb8a92e122c66bfa4e31c41a80feef047d756 Mon Sep 17 00:00:00 2001 From: Rusty Russell Date: Tue, 9 Oct 2018 19:26:52 +1030 Subject: [PATCH] db: save the failcode / failuremsg into db. Now we can finally move the fixup code under COMPAT_V061, so it's only for old nodes. Signed-off-by: Rusty Russell --- lightningd/peer_htlcs.c | 16 +++++++++++----- wallet/test/run-wallet.c | 7 +++++-- wallet/wallet.c | 19 ++++++++++++++++--- wallet/wallet.h | 7 +++++-- 4 files changed, 37 insertions(+), 12 deletions(-) diff --git a/lightningd/peer_htlcs.c b/lightningd/peer_htlcs.c index 7d8a7603f..27d204cab 100644 --- a/lightningd/peer_htlcs.c +++ b/lightningd/peer_htlcs.c @@ -62,7 +62,8 @@ static bool htlc_in_update_state(struct channel *channel, return false; wallet_htlc_update(channel->peer->ld->wallet, - hin->dbid, newstate, hin->preimage); + hin->dbid, newstate, hin->preimage, + hin->failcode, hin->failuremsg); hin->hstate = newstate; return true; @@ -77,7 +78,7 @@ static bool htlc_out_update_state(struct channel *channel, return false; wallet_htlc_update(channel->peer->ld->wallet, hout->dbid, newstate, - hout->preimage); + hout->preimage, hout->failcode, hout->failuremsg); hout->hstate = newstate; return true; @@ -727,7 +728,8 @@ static void fulfill_our_htlc_out(struct channel *channel, struct htlc_out *hout, hout->preimage = tal_dup(hout, struct preimage, preimage); htlc_out_check(hout, __func__); - wallet_htlc_update(ld->wallet, hout->dbid, hout->hstate, preimage); + wallet_htlc_update(ld->wallet, hout->dbid, hout->hstate, + hout->preimage, hout->failcode, hout->failuremsg); /* Update channel stats */ wallet_channel_stats_incr_out_fulfilled(ld->wallet, channel->dbid, @@ -868,9 +870,9 @@ void onchain_failed_our_htlc(const struct channel *channel, /* Force state to something which expects a failure, and save to db */ hout->hstate = RCVD_REMOVE_HTLC; - wallet_htlc_update(channel->peer->ld->wallet, hout->dbid, hout->hstate, - NULL); htlc_out_check(hout, __func__); + wallet_htlc_update(channel->peer->ld->wallet, hout->dbid, hout->hstate, + hout->preimage, hout->failcode, hout->failuremsg); if (hout->local) { assert(why != NULL); @@ -1679,6 +1681,7 @@ void htlcs_notify_new_block(struct lightningd *ld, u32 height) } while (removed); } +#ifdef COMPAT_V061 static void fixup_hout(struct lightningd *ld, struct htlc_out *hout) { const char *fix; @@ -1724,6 +1727,7 @@ static void fixup_hout(struct lightningd *ld, struct htlc_out *hout) &hout->key.channel->peer->id), fix); } +#endif /* COMPAT_V061 */ /** * htlcs_reconnect -- Link outgoing HTLCs to their origins after initial db load @@ -1774,7 +1778,9 @@ void htlcs_reconnect(struct lightningd *ld, hout->origin_htlc_id, hout->dbid); #endif } +#ifdef COMPAT_V061 fixup_hout(ld, hout); +#endif } } diff --git a/wallet/test/run-wallet.c b/wallet/test/run-wallet.c index 22f5bd1ce..2e478bcc8 100644 --- a/wallet/test/run-wallet.c +++ b/wallet/test/run-wallet.c @@ -963,11 +963,14 @@ 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)), + CHECK_MSG(transaction_wrap(w->db, wallet_htlc_update(w, in.dbid, RCVD_ADD_HTLC, NULL, 0, NULL)), "Update HTLC with null payment_key failed"); CHECK_MSG( - transaction_wrap(w->db, wallet_htlc_update(w, in.dbid, SENT_REMOVE_HTLC, &payment_key)), + transaction_wrap(w->db, wallet_htlc_update(w, in.dbid, SENT_REMOVE_HTLC, &payment_key, 0, NULL)), "Update HTLC with payment_key failed"); + CHECK_MSG( + transaction_wrap(w->db, wallet_htlc_update(w, in.dbid, SENT_REMOVE_HTLC, NULL, 0, tal_arrz(tmpctx, u8, 100))), + "Update HTLC with failreason failed"); CHECK_MSG(transaction_wrap(w->db, wallet_htlc_save_out(w, chan, &out)), tal_fmt(ctx, "Save htlc_out failed: %s", wallet_err)); diff --git a/wallet/wallet.c b/wallet/wallet.c index 55bb29b7f..bba4a9621 100644 --- a/wallet/wallet.c +++ b/wallet/wallet.c @@ -1248,7 +1248,8 @@ void wallet_htlc_save_out(struct wallet *wallet, void wallet_htlc_update(struct wallet *wallet, const u64 htlc_dbid, const enum htlc_state new_state, - const struct preimage *payment_key) + const struct preimage *payment_key, + enum onion_type failcode, const u8 *failuremsg) { sqlite3_stmt *stmt; @@ -1257,17 +1258,25 @@ void wallet_htlc_update(struct wallet *wallet, const u64 htlc_dbid, assert(htlc_dbid); stmt = db_prepare( wallet->db, - "UPDATE channel_htlcs SET hstate=?, payment_key=? WHERE id=?"); + "UPDATE channel_htlcs SET hstate=?, payment_key=?, malformed_onion=?, failuremsg=? WHERE id=?"); /* FIXME: htlc_state_in_db */ sqlite3_bind_int(stmt, 1, new_state); - sqlite3_bind_int64(stmt, 3, htlc_dbid); + sqlite3_bind_int64(stmt, 5, htlc_dbid); if (payment_key) sqlite3_bind_preimage(stmt, 2, payment_key); else sqlite3_bind_null(stmt, 2); + sqlite3_bind_int(stmt, 3, failcode); + if (failuremsg) + sqlite3_bind_blob(stmt, 4, + failuremsg, tal_bytelen(failuremsg), + SQLITE_TRANSIENT); + else + sqlite3_bind_null(stmt, 4); + db_exec_prepared(wallet->db, stmt); } @@ -1353,6 +1362,7 @@ static bool wallet_stmt2htlc_out(struct channel *channel, return ok; } +#ifdef COMPAT_V061 /* We didn't used to save failcore, failuremsg... */ static void fixup_hin(struct wallet *wallet, struct htlc_in *hin) { @@ -1380,6 +1390,7 @@ static void fixup_hin(struct wallet *wallet, struct htlc_in *hin) type_to_string(tmpctx, struct pubkey, &hin->key.channel->peer->id)); } +#endif bool wallet_htlcs_load_for_channel(struct wallet *wallet, struct channel *chan, @@ -1405,7 +1416,9 @@ bool wallet_htlcs_load_for_channel(struct wallet *wallet, struct htlc_in *in = tal(chan, struct htlc_in); ok &= wallet_stmt2htlc_in(chan, stmt, in); connect_htlc_in(htlcs_in, in); +#ifdef COMPAT_V061 fixup_hin(wallet, in); +#endif ok &= htlc_in_check(in, NULL) != NULL; incount++; } diff --git a/wallet/wallet.h b/wallet/wallet.h index 6399a42da..edd8431a2 100644 --- a/wallet/wallet.h +++ b/wallet/wallet.h @@ -454,14 +454,17 @@ void wallet_htlc_save_out(struct wallet *wallet, * @new_state: the state we should transition to * @payment_key: the `payment_key` which hashes to the `payment_hash`, * or NULL if unknown. + * @failcode: the current failure code, or 0. + * @failuremsg: the current failure message (from peer), or NULL. * * 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 - * HTLC have been settled. + * HTLC have been settled, or `failcode`/`failuremsg` if failed. */ void wallet_htlc_update(struct wallet *wallet, const u64 htlc_dbid, const enum htlc_state new_state, - const struct preimage *payment_key); + const struct preimage *payment_key, + enum onion_type failcode, const u8 *failuremsg); /** * wallet_htlcs_load_for_channel - Load HTLCs associated with chan from DB.