Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
44 changes: 37 additions & 7 deletions channeld/channeld.c
Original file line number Diff line number Diff line change
Expand Up @@ -1614,6 +1614,10 @@ static void marshall_htlc_info(const tal_t *ctx,
assert(!htlc->failed);
f.id = htlc->id;
f.payment_preimage = *htlc->r;
if (htlc->attr_data)
f.attr_data = tal_dup(fulfilled, struct attribution_data, htlc->attr_data);
else
f.attr_data = NULL;
tal_arr_expand(fulfilled, f);
} else {
assert(!htlc->r);
Expand Down Expand Up @@ -2619,17 +2623,27 @@ static void handle_peer_fulfill_htlc(struct peer *peer, const u8 *msg)
struct preimage preimage;
enum channel_remove_err e;
struct htlc *h;
struct tlv_update_fulfill_htlc_tlvs *tlvs_attr_data;

if (!fromwire_update_fulfill_htlc(msg, &channel_id,
&id, &preimage)) {
if (!fromwire_update_fulfill_htlc(tmpctx, msg, &channel_id,
&id, &preimage, &tlvs_attr_data)) {
peer_failed_warn(peer->pps, &peer->channel_id,
"Bad update_fulfill_htlc %s", tal_hex(msg, msg));
}

e = channel_fulfill_htlc(peer->channel, LOCAL, id, &preimage, &h);
switch (e) {
case CHANNEL_ERR_REMOVE_OK:
/* FIXME: We could send preimages to master immediately. */
if (tlvs_attr_data && tlvs_attr_data->attribution_data) {
h->attr_data = tal(h, struct attribution_data);
h->attr_data->htlc_hold_time = tal_dup_arr(h->attr_data, u8,
tlvs_attr_data->attribution_data->htlc_hold_times, 80, 0);
h->attr_data->truncated_hmac = tal_dup_arr(h->attr_data, u8,
tlvs_attr_data->attribution_data->truncated_hmacs, 840, 0);
} else {
h->attr_data = NULL;
}

start_commit_timer(peer);
return;
/* These shouldn't happen, because any offered HTLC (which would give
Expand All @@ -2655,10 +2669,11 @@ static void handle_peer_fail_htlc(struct peer *peer, const u8 *msg)
u8 *reason;
struct htlc *htlc;
struct failed_htlc *f;
struct tlv_update_fail_htlc_tlvs *tlvs_attr_data;

/* reason is not an onionreply because spec doesn't know about that */
if (!fromwire_update_fail_htlc(msg, msg,
&channel_id, &id, &reason)) {
&channel_id, &id, &reason, &tlvs_attr_data)) {
peer_failed_warn(peer->pps, &peer->channel_id,
"Bad update_fail_htlc %s", tal_hex(msg, msg));
}
Expand All @@ -2669,7 +2684,12 @@ static void handle_peer_fail_htlc(struct peer *peer, const u8 *msg)
htlc->failed = f = tal(htlc, struct failed_htlc);
f->id = id;
f->sha256_of_onion = NULL;
f->onion = new_onionreply(f, take(reason));
struct attribution_data *attr = tal(f, struct attribution_data);
attr->htlc_hold_time = tal_dup_arr(f, u8, tlvs_attr_data->attribution_data->htlc_hold_times, 80, 0);
attr->truncated_hmac = tal_dup_arr(f, u8, tlvs_attr_data->attribution_data->truncated_hmacs, 840, 0);
f->onion = new_onionreply(f, take(reason),
attr);

start_commit_timer(peer);
return;
}
Expand Down Expand Up @@ -5137,12 +5157,22 @@ static void send_fail_or_fulfill(struct peer *peer, const struct htlc *h)
f->sha256_of_onion,
f->badonion);
} else {
struct tlv_update_fail_htlc_tlvs *attr_data_tlv = tlv_update_fail_htlc_tlvs_new(peer);
attr_data_tlv->attribution_data = tal(peer, struct tlv_update_fail_htlc_tlvs_attribution_data);
memcpy(attr_data_tlv->attribution_data->htlc_hold_times, f->onion->attr_data->htlc_hold_time, 80);
memcpy(attr_data_tlv->attribution_data->truncated_hmacs, f->onion->attr_data->truncated_hmac, 840);
msg = towire_update_fail_htlc(peer, &peer->channel_id, h->id,
f->onion->contents);
f->onion->contents, attr_data_tlv);
}
} else if (h->r) {
struct tlv_update_fulfill_htlc_tlvs *attr_data_tlv = tlv_update_fulfill_htlc_tlvs_new(peer);
attr_data_tlv->attribution_data = tal(peer, struct tlv_update_fulfill_htlc_tlvs_attribution_data);
if (h->attr_data != NULL) {
memcpy(attr_data_tlv->attribution_data->htlc_hold_times, h->attr_data->htlc_hold_time, 80);
memcpy(attr_data_tlv->attribution_data->truncated_hmacs, h->attr_data->truncated_hmac, 840);
}
msg = towire_update_fulfill_htlc(NULL, &peer->channel_id, h->id,
h->r);
h->r, attr_data_tlv);
} else
peer_failed_warn(peer->pps, &peer->channel_id,
"HTLC %"PRIu64" state %s not failed/fulfilled",
Expand Down
3 changes: 3 additions & 0 deletions channeld/channeld_htlc.h
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,9 @@ struct htlc {

/* Should we immediately fail this htlc? */
bool fail_immediate;

/* Attribution Data */
struct attribution_data *attr_data;
};

static inline bool htlc_has(const struct htlc *h, int flag)
Expand Down
18 changes: 16 additions & 2 deletions common/htlc_wire.c
Original file line number Diff line number Diff line change
Expand Up @@ -148,6 +148,11 @@ void towire_fulfilled_htlc(u8 **pptr, const struct fulfilled_htlc *fulfilled)
{
towire_u64(pptr, fulfilled->id);
towire_preimage(pptr, &fulfilled->payment_preimage);
towire_bool(pptr, fulfilled->attr_data != NULL);
if (fulfilled->attr_data) {
towire_u8_array(pptr, fulfilled->attr_data->htlc_hold_time, 80);
towire_u8_array(pptr, fulfilled->attr_data->truncated_hmac, 840);
}
}

void towire_failed_htlc(u8 **pptr, const struct failed_htlc *failed)
Expand Down Expand Up @@ -272,11 +277,20 @@ struct existing_htlc *fromwire_existing_htlc(const tal_t *ctx,
return existing;
}

void fromwire_fulfilled_htlc(const u8 **cursor, size_t *max,
struct fulfilled_htlc *fulfilled)
struct fulfilled_htlc *fromwire_fulfilled_htlc(const tal_t *ctx, const u8 **cursor, size_t *max)
{
struct fulfilled_htlc *fulfilled = tal(ctx, struct fulfilled_htlc);
fulfilled->id = fromwire_u64(cursor, max);
fromwire_preimage(cursor, max, &fulfilled->payment_preimage);
bool has_attr = fromwire_bool(cursor, max);
if (has_attr) {
fulfilled->attr_data = tal(fulfilled, struct attribution_data);
fulfilled->attr_data->htlc_hold_time = fromwire_tal_arrn(fulfilled->attr_data, cursor, max, 80);
fulfilled->attr_data->truncated_hmac = fromwire_tal_arrn(fulfilled->attr_data, cursor, max, 840);
} else {
fulfilled->attr_data = NULL;
}
return fulfilled;
}

struct failed_htlc *fromwire_failed_htlc(const tal_t *ctx, const u8 **cursor, size_t *max)
Expand Down
5 changes: 3 additions & 2 deletions common/htlc_wire.h
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ struct existing_htlc {
struct fulfilled_htlc {
u64 id;
struct preimage payment_preimage;
struct attribution_data *attr_data;
};

struct failed_htlc {
Expand Down Expand Up @@ -90,8 +91,8 @@ struct added_htlc *fromwire_added_htlc(const tal_t *ctx, const u8 **cursor,
size_t *max);
struct existing_htlc *fromwire_existing_htlc(const tal_t *ctx,
const u8 **cursor, size_t *max);
void fromwire_fulfilled_htlc(const u8 **cursor, size_t *max,
struct fulfilled_htlc *fulfilled);
struct fulfilled_htlc *fromwire_fulfilled_htlc(const tal_t *ctx, const u8 **cursor,
size_t *max);
struct failed_htlc *fromwire_failed_htlc(const tal_t *ctx, const u8 **cursor,
size_t *max);
void fromwire_changed_htlc(const u8 **cursor, size_t *max,
Expand Down
28 changes: 27 additions & 1 deletion common/onionreply.c
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,10 @@ void towire_onionreply(u8 **cursor, const struct onionreply *r)
{
towire_u16(cursor, tal_count(r->contents));
towire_u8_array(cursor, r->contents, tal_count(r->contents));
if (r->attr_data) {
towire_u8_array(cursor, r->attr_data->htlc_hold_time, 80);
towire_u8_array(cursor, r->attr_data->truncated_hmac, 840);
}
}

struct onionreply *fromwire_onionreply(const tal_t *ctx,
Expand All @@ -15,6 +19,14 @@ struct onionreply *fromwire_onionreply(const tal_t *ctx,
struct onionreply *r = tal(ctx, struct onionreply);
r->contents = fromwire_tal_arrn(r, cursor, max,
fromwire_u16(cursor, max));
if (*max >= 80 + 840) {
r->attr_data = tal(ctx, struct attribution_data);
r->attr_data->htlc_hold_time = fromwire_tal_arrn(r, cursor, max, 80);
r->attr_data->truncated_hmac = fromwire_tal_arrn(r, cursor, max, 840);
} else {
r->attr_data = NULL;
}

if (!*cursor)
return tal_free(r);
return r;
Expand All @@ -30,12 +42,26 @@ struct onionreply *dup_onionreply(const tal_t *ctx,

n = tal(ctx, struct onionreply);
n->contents = tal_dup_talarr(n, u8, r->contents);
if (r->attr_data) {
n->attr_data = tal(ctx, struct attribution_data);
n->attr_data->htlc_hold_time = tal_dup_talarr(r, u8, r->attr_data->htlc_hold_time);
n->attr_data->truncated_hmac = tal_dup_talarr(r, u8, r->attr_data->truncated_hmac);
} else {
n->attr_data = NULL;
}
return n;
}

struct onionreply *new_onionreply(const tal_t *ctx, const u8 *contents TAKES)
struct onionreply *new_onionreply(const tal_t *ctx, const u8 *contents TAKES, const struct attribution_data *attr_data TAKES)
{
struct onionreply *r = tal(ctx, struct onionreply);
r->contents = tal_dup_talarr(r, u8, contents);
if (attr_data) {
r->attr_data = tal(ctx, struct attribution_data);
r->attr_data->htlc_hold_time = tal_dup_talarr(r, u8, attr_data->htlc_hold_time);
r->attr_data->truncated_hmac = tal_dup_talarr(r, u8, attr_data->truncated_hmac);
} else {
r->attr_data = NULL;
}
return r;
}
9 changes: 8 additions & 1 deletion common/onionreply.h
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,16 @@
#include <ccan/short_types/short_types.h>
#include <ccan/tal/tal.h>

/* A separate type for attribution data. */
struct attribution_data {
u8 *htlc_hold_time;
u8 *truncated_hmac;
};

/* A separate type for an onion reply, to differentiate from a wire msg. */
struct onionreply {
u8 *contents;
struct attribution_data *attr_data;
};

/**
Expand All @@ -20,5 +27,5 @@ struct onionreply *fromwire_onionreply(const tal_t *ctx,
struct onionreply *dup_onionreply(const tal_t *ctx,
const struct onionreply *r TAKES);

struct onionreply *new_onionreply(const tal_t *ctx, const u8 *contents TAKES);
struct onionreply *new_onionreply(const tal_t *ctx, const u8 *contents TAKES, const struct attribution_data *attr_data TAKES);
#endif /* LIGHTNING_COMMON_ONIONREPLY_H */
Loading
Loading