Browse Source

channeld: use fulfilled_htlc and failed_htlc msgs in single htlc case.

We use these for receiving arrays at init time, we should also use them
for fulfull/fail of HTLCs in normal operation.  That we we benefit from all
those assertions.

Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
ppa-0.6.1
Rusty Russell 6 years ago
committed by Christian Decker
parent
commit
162879d6a2
  1. 44
      channeld/channel.c
  2. 12
      channeld/channel_wire.csv
  3. 20
      lightningd/peer_htlcs.c

44
channeld/channel.c

@ -2195,16 +2195,19 @@ static void handle_feerates(struct peer *peer, const u8 *inmsg)
static void handle_preimage(struct peer *peer, const u8 *inmsg) static void handle_preimage(struct peer *peer, const u8 *inmsg)
{ {
u64 id; struct fulfilled_htlc fulfilled_htlc;
struct preimage preimage;
struct htlc *h; struct htlc *h;
if (!fromwire_channel_fulfill_htlc(inmsg, &id, &preimage)) if (!fromwire_channel_fulfill_htlc(inmsg, &fulfilled_htlc))
master_badmsg(WIRE_CHANNEL_FULFILL_HTLC, inmsg); master_badmsg(WIRE_CHANNEL_FULFILL_HTLC, inmsg);
switch (channel_fulfill_htlc(peer->channel, REMOTE, id, &preimage, &h)) { switch (channel_fulfill_htlc(peer->channel, REMOTE,
fulfilled_htlc.id,
&fulfilled_htlc.payment_preimage,
&h)) {
case CHANNEL_ERR_REMOVE_OK: case CHANNEL_ERR_REMOVE_OK:
h->r = tal_dup(h, struct preimage, &preimage); h->r = tal_dup(h, struct preimage,
&fulfilled_htlc.payment_preimage);
send_fail_or_fulfill(peer, h); send_fail_or_fulfill(peer, h);
start_commit_timer(peer); start_commit_timer(peer);
return; return;
@ -2217,39 +2220,27 @@ static void handle_preimage(struct peer *peer, const u8 *inmsg)
case CHANNEL_ERR_HTLC_NOT_IRREVOCABLE: case CHANNEL_ERR_HTLC_NOT_IRREVOCABLE:
case CHANNEL_ERR_BAD_PREIMAGE: case CHANNEL_ERR_BAD_PREIMAGE:
status_failed(STATUS_FAIL_MASTER_IO, status_failed(STATUS_FAIL_MASTER_IO,
"HTLC %"PRIu64" preimage failed", id); "HTLC %"PRIu64" preimage failed",
fulfilled_htlc.id);
} }
abort(); abort();
} }
static void handle_fail(struct peer *peer, const u8 *inmsg) static void handle_fail(struct peer *peer, const u8 *inmsg)
{ {
u64 id; struct failed_htlc *failed_htlc;
u8 *errpkt;
u16 failcode;
struct short_channel_id scid;
enum channel_remove_err e; enum channel_remove_err e;
struct htlc *h; struct htlc *h;
if (!fromwire_channel_fail_htlc(inmsg, inmsg, &id, &errpkt, if (!fromwire_channel_fail_htlc(inmsg, inmsg, &failed_htlc))
&failcode, &scid))
master_badmsg(WIRE_CHANNEL_FAIL_HTLC, inmsg); master_badmsg(WIRE_CHANNEL_FAIL_HTLC, inmsg);
if (failcode && tal_len(errpkt)) e = channel_fail_htlc(peer->channel, REMOTE, failed_htlc->id, &h);
status_failed(STATUS_FAIL_MASTER_IO,
"Invalid channel_fail_htlc: %s with errpkt?",
onion_type_name(failcode));
e = channel_fail_htlc(peer->channel, REMOTE, id, &h);
switch (e) { switch (e) {
case CHANNEL_ERR_REMOVE_OK: case CHANNEL_ERR_REMOVE_OK:
h->failcode = failcode; h->failcode = failed_htlc->failcode;
h->fail = tal_steal(h, errpkt); h->fail = tal_steal(h, failed_htlc->failreason);
if (failcode & UPDATE) h->failed_scid = tal_steal(h, failed_htlc->scid);
h->failed_scid
= tal_dup(h, struct short_channel_id, &scid);
else
h->failed_scid = NULL;
send_fail_or_fulfill(peer, h); send_fail_or_fulfill(peer, h);
start_commit_timer(peer); start_commit_timer(peer);
return; return;
@ -2259,7 +2250,8 @@ static void handle_fail(struct peer *peer, const u8 *inmsg)
case CHANNEL_ERR_HTLC_NOT_IRREVOCABLE: case CHANNEL_ERR_HTLC_NOT_IRREVOCABLE:
case CHANNEL_ERR_BAD_PREIMAGE: case CHANNEL_ERR_BAD_PREIMAGE:
status_failed(STATUS_FAIL_MASTER_IO, status_failed(STATUS_FAIL_MASTER_IO,
"HTLC %"PRIu64" removal failed: %s", id, "HTLC %"PRIu64" removal failed: %s",
failed_htlc->id,
channel_remove_err_name(e)); channel_remove_err_name(e));
} }
abort(); abort();

12
channeld/channel_wire.csv

@ -82,19 +82,11 @@ channel_offer_htlc_reply,,failurestr,failurestrlen*u8
# Main daemon found out the preimage for an HTLC # Main daemon found out the preimage for an HTLC
#include <bitcoin/preimage.h> #include <bitcoin/preimage.h>
channel_fulfill_htlc,1005 channel_fulfill_htlc,1005
channel_fulfill_htlc,,id,u64 channel_fulfill_htlc,,fulfilled_htlc,struct fulfilled_htlc
channel_fulfill_htlc,,payment_preimage,struct preimage
# Main daemon says HTLC failed # Main daemon says HTLC failed
channel_fail_htlc,1006 channel_fail_htlc,1006
channel_fail_htlc,,id,u64 channel_fail_htlc,,failed_htlc,struct failed_htlc
# If this is non-zero length, you need to wrap this and pass it on.
channel_fail_htlc,,len,u16
channel_fail_htlc,,error_pkt,len*u8
# If it errcode is != 0, it's a local error, otherwise we're passing through.
channel_fail_htlc,,errcode,u16
# If errcode & UPDATE, this says which outgoing channel failed.
channel_fail_htlc,,which_channel,struct short_channel_id
# When we receive funding_locked. # When we receive funding_locked.
channel_got_funding_locked,1019 channel_got_funding_locked,1019

Can't render this file because it has a wrong number of fields in line 6.

20
lightningd/peer_htlcs.c

@ -1,5 +1,6 @@
#include <bitcoin/tx.h> #include <bitcoin/tx.h>
#include <ccan/build_assert/build_assert.h> #include <ccan/build_assert/build_assert.h>
#include <ccan/cast/cast.h>
#include <ccan/crypto/ripemd160/ripemd160.h> #include <ccan/crypto/ripemd160/ripemd160.h>
#include <ccan/mem/mem.h> #include <ccan/mem/mem.h>
#include <ccan/tal/str/str.h> #include <ccan/tal/str/str.h>
@ -88,6 +89,7 @@ static void fail_in_htlc(struct htlc_in *hin,
const u8 *failuremsg, const u8 *failuremsg,
const struct short_channel_id *out_channelid) const struct short_channel_id *out_channelid)
{ {
struct failed_htlc failed_htlc;
assert(!hin->preimage); assert(!hin->preimage);
assert(failcode || failuremsg); assert(failcode || failuremsg);
@ -112,12 +114,15 @@ static void fail_in_htlc(struct htlc_in *hin,
if (channel_on_chain(hin->key.channel)) if (channel_on_chain(hin->key.channel))
return; return;
failed_htlc.id = hin->key.id;
failed_htlc.failcode = hin->failcode;
failed_htlc.failreason = cast_const(u8 *, hin->failuremsg);
if (failed_htlc.failcode & UPDATE)
failed_htlc.scid = &hin->failoutchannel;
else
failed_htlc.scid = NULL;
subd_send_msg(hin->key.channel->owner, subd_send_msg(hin->key.channel->owner,
take(towire_channel_fail_htlc(hin, take(towire_channel_fail_htlc(NULL, &failed_htlc)));
hin->key.id,
hin->failuremsg,
hin->failcode,
&hin->failoutchannel)));
} }
/* This is used for cases where we can immediately fail the HTLC. */ /* This is used for cases where we can immediately fail the HTLC. */
@ -228,7 +233,10 @@ static void fulfill_htlc(struct htlc_in *hin, const struct preimage *preimage)
if (channel_on_chain(channel)) { if (channel_on_chain(channel)) {
msg = towire_onchain_known_preimage(hin, preimage); msg = towire_onchain_known_preimage(hin, preimage);
} else { } else {
msg = towire_channel_fulfill_htlc(hin, hin->key.id, preimage); struct fulfilled_htlc fulfilled_htlc;
fulfilled_htlc.id = hin->key.id;
fulfilled_htlc.payment_preimage = *preimage;
msg = towire_channel_fulfill_htlc(hin, &fulfilled_htlc);
} }
subd_send_msg(channel->owner, take(msg)); subd_send_msg(channel->owner, take(msg));
} }

Loading…
Cancel
Save