Browse Source

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 <rusty@rustcorp.com.au>
ppa-0.6.2rc1
Rusty Russell 6 years ago
committed by Christian Decker
parent
commit
c919551109
  1. 8
      lightningd/onchain_control.c
  2. 32
      lightningd/peer_htlcs.c
  3. 2
      lightningd/peer_htlcs.h
  4. 2
      onchaind/onchain_wire.c
  5. 1
      onchaind/onchain_wire.h
  6. 5
      wallet/wallet.c

8
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;

32
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) {

2
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);

2
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);
}

1
onchaind/onchain_wire.h

@ -9,6 +9,7 @@
struct htlc_stub {
enum side owner;
u32 cltv_expiry;
u64 id;
struct ripemd160 ripemd;
};

5
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);

Loading…
Cancel
Save