From c91955110909019a45c7a226823995e3e2e9bbc2 Mon Sep 17 00:00:00 2001 From: Rusty Russell Date: Tue, 23 Oct 2018 20:10:22 +1030 Subject: [PATCH] onchaind: include htlc id in htlc_stub so we agree on what HTLC we're closing. If there are two HTLCs with the same preimage, lightningd would always find the first one. By including the id in the `struct htlc_stub` it's both faster (normal HTLC lookup) and allows lightningd to detect that onchaind wants to fail both of them. Signed-off-by: Rusty Russell --- lightningd/onchain_control.c | 8 ++++++-- lightningd/peer_htlcs.c | 32 ++++++-------------------------- lightningd/peer_htlcs.h | 2 -- onchaind/onchain_wire.c | 2 ++ onchaind/onchain_wire.h | 1 + wallet/wallet.c | 5 +++-- 6 files changed, 18 insertions(+), 32 deletions(-) diff --git a/lightningd/onchain_control.c b/lightningd/onchain_control.c index d8d8ab553..13759b4cb 100644 --- a/lightningd/onchain_control.c +++ b/lightningd/onchain_control.c @@ -343,8 +343,12 @@ static bool tell_if_missing(const struct channel *channel, /* Keep valgrind happy. */ *tell_immediate = false; - /* Is it a current HTLC? */ - hout = find_htlc_out_by_ripemd(channel, &stub->ripemd); + /* Don't care about incoming HTLCs, just ones we offered. */ + if (stub->owner == REMOTE) + return false; + + /* Might not be a current HTLC. */ + hout = find_htlc_out(&channel->peer->ld->htlcs_out, channel, stub->id); if (!hout) return false; diff --git a/lightningd/peer_htlcs.c b/lightningd/peer_htlcs.c index 55d8d9e58..8cdcea241 100644 --- a/lightningd/peer_htlcs.c +++ b/lightningd/peer_htlcs.c @@ -823,36 +823,16 @@ static bool peer_failed_our_htlc(struct channel *channel, return true; } -/* FIXME: Crazy slow! */ -struct htlc_out *find_htlc_out_by_ripemd(const struct channel *channel, - const struct ripemd160 *ripemd) -{ - struct htlc_out_map_iter outi; - struct htlc_out *hout; - struct lightningd *ld = channel->peer->ld; - - for (hout = htlc_out_map_first(&ld->htlcs_out, &outi); - hout; - hout = htlc_out_map_next(&ld->htlcs_out, &outi)) { - struct ripemd160 hash; - - if (hout->key.channel != channel) - continue; - - ripemd160(&hash, - &hout->payment_hash, sizeof(hout->payment_hash)); - if (ripemd160_eq(&hash, ripemd)) - return hout; - } - return NULL; -} - void onchain_failed_our_htlc(const struct channel *channel, const struct htlc_stub *htlc, const char *why) { struct lightningd *ld = channel->peer->ld; - struct htlc_out *hout = find_htlc_out_by_ripemd(channel, &htlc->ripemd); + struct htlc_out *hout; + + hout = find_htlc_out(&ld->htlcs_out, channel, htlc->id); + if (!hout) + return; /* Don't fail twice (or if already succeeded)! */ if (hout->failuremsg || hout->failcode || hout->preimage) @@ -863,7 +843,7 @@ 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; htlc_out_check(hout, __func__); - wallet_htlc_update(channel->peer->ld->wallet, hout->dbid, hout->hstate, + wallet_htlc_update(ld->wallet, hout->dbid, hout->hstate, hout->preimage, hout->failcode, hout->failuremsg); if (hout->am_origin) { diff --git a/lightningd/peer_htlcs.h b/lightningd/peer_htlcs.h index a36c01b96..6f3ad3646 100644 --- a/lightningd/peer_htlcs.h +++ b/lightningd/peer_htlcs.h @@ -50,8 +50,6 @@ enum onion_type send_htlc_out(struct channel *out, u64 amount, u32 cltv, struct htlc_in *in, struct htlc_out **houtp); -struct htlc_out *find_htlc_out_by_ripemd(const struct channel *channel, - const struct ripemd160 *ripemd160); void onchain_failed_our_htlc(const struct channel *channel, const struct htlc_stub *htlc, const char *why); diff --git a/onchaind/onchain_wire.c b/onchaind/onchain_wire.c index 18b11c2ce..f6de30d7d 100644 --- a/onchaind/onchain_wire.c +++ b/onchaind/onchain_wire.c @@ -6,6 +6,7 @@ void towire_htlc_stub(u8 **pptr, const struct htlc_stub *htlc_stub) { towire_side(pptr, htlc_stub->owner); towire_u32(pptr, htlc_stub->cltv_expiry); + towire_u64(pptr, htlc_stub->id); towire_ripemd160(pptr, &htlc_stub->ripemd); } @@ -14,5 +15,6 @@ void fromwire_htlc_stub(const u8 **cursor, size_t *max, { htlc_stub->owner = fromwire_side(cursor, max); htlc_stub->cltv_expiry = fromwire_u32(cursor, max); + htlc_stub->id = fromwire_u64(cursor, max); fromwire_ripemd160(cursor, max, &htlc_stub->ripemd); } diff --git a/onchaind/onchain_wire.h b/onchaind/onchain_wire.h index b23a03e4b..aeb0f50d7 100644 --- a/onchaind/onchain_wire.h +++ b/onchaind/onchain_wire.h @@ -9,6 +9,7 @@ struct htlc_stub { enum side owner; u32 cltv_expiry; + u64 id; struct ripemd160 ripemd; }; diff --git a/wallet/wallet.c b/wallet/wallet.c index 5245da69a..0048b4766 100644 --- a/wallet/wallet.c +++ b/wallet/wallet.c @@ -1551,7 +1551,7 @@ struct htlc_stub *wallet_htlc_stubs(const tal_t *ctx, struct wallet *wallet, struct htlc_stub *stubs; struct sha256 payment_hash; sqlite3_stmt *stmt = db_prepare(wallet->db, - "SELECT channel_id, direction, cltv_expiry, payment_hash " + "SELECT channel_id, direction, cltv_expiry, channel_htlc_id, payment_hash " "FROM channel_htlcs WHERE channel_id = ?;"); sqlite3_bind_int64(stmt, 1, chan->dbid); @@ -1566,8 +1566,9 @@ struct htlc_stub *wallet_htlc_stubs(const tal_t *ctx, struct wallet *wallet, /* FIXME: merge these two enums */ stub->owner = sqlite3_column_int(stmt, 1)==DIRECTION_INCOMING?REMOTE:LOCAL; stub->cltv_expiry = sqlite3_column_int(stmt, 2); + stub->id = sqlite3_column_int(stmt, 3); - sqlite3_column_sha256(stmt, 3, &payment_hash); + sqlite3_column_sha256(stmt, 4, &payment_hash); ripemd160(&stub->ripemd, payment_hash.u.u8, sizeof(payment_hash.u)); } db_stmt_done(stmt);