Browse Source

protocol: split message update_remove_htlc into update_timedout_htlc and update_routefail_htlc, remove update_remove_htlc_delay.

For the moment, there's no way to remove an in-progress HTLC before
it's timed out.  The other side can remove it with a routefail, but
you can't push for it to be removed.

We may add that later, but by definition it's only a polited request, and
normally we should rely on timeouts.

Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
ppa-0.6.1
Rusty Russell 9 years ago
parent
commit
d00eeded9f
  1. 184
      lightning.pb-c.c
  2. 109
      lightning.pb-c.h
  3. 27
      lightning.proto
  4. 18
      pkt.c
  5. 16
      pkt.h
  6. 39
      test-cli/gather_updates.c
  7. 12
      test-cli/update-channel-htlc-remove.c

184
lightning.pb-c.c

@ -566,90 +566,90 @@ void update_complete_htlc__free_unpacked
assert(message->base.descriptor == &update_complete_htlc__descriptor); assert(message->base.descriptor == &update_complete_htlc__descriptor);
protobuf_c_message_free_unpacked ((ProtobufCMessage*)message, allocator); protobuf_c_message_free_unpacked ((ProtobufCMessage*)message, allocator);
} }
void update_remove_htlc__init void update_timedout_htlc__init
(UpdateRemoveHtlc *message) (UpdateTimedoutHtlc *message)
{ {
static UpdateRemoveHtlc init_value = UPDATE_REMOVE_HTLC__INIT; static UpdateTimedoutHtlc init_value = UPDATE_TIMEDOUT_HTLC__INIT;
*message = init_value; *message = init_value;
} }
size_t update_remove_htlc__get_packed_size size_t update_timedout_htlc__get_packed_size
(const UpdateRemoveHtlc *message) (const UpdateTimedoutHtlc *message)
{ {
assert(message->base.descriptor == &update_remove_htlc__descriptor); assert(message->base.descriptor == &update_timedout_htlc__descriptor);
return protobuf_c_message_get_packed_size ((const ProtobufCMessage*)(message)); return protobuf_c_message_get_packed_size ((const ProtobufCMessage*)(message));
} }
size_t update_remove_htlc__pack size_t update_timedout_htlc__pack
(const UpdateRemoveHtlc *message, (const UpdateTimedoutHtlc *message,
uint8_t *out) uint8_t *out)
{ {
assert(message->base.descriptor == &update_remove_htlc__descriptor); assert(message->base.descriptor == &update_timedout_htlc__descriptor);
return protobuf_c_message_pack ((const ProtobufCMessage*)message, out); return protobuf_c_message_pack ((const ProtobufCMessage*)message, out);
} }
size_t update_remove_htlc__pack_to_buffer size_t update_timedout_htlc__pack_to_buffer
(const UpdateRemoveHtlc *message, (const UpdateTimedoutHtlc *message,
ProtobufCBuffer *buffer) ProtobufCBuffer *buffer)
{ {
assert(message->base.descriptor == &update_remove_htlc__descriptor); assert(message->base.descriptor == &update_timedout_htlc__descriptor);
return protobuf_c_message_pack_to_buffer ((const ProtobufCMessage*)message, buffer); return protobuf_c_message_pack_to_buffer ((const ProtobufCMessage*)message, buffer);
} }
UpdateRemoveHtlc * UpdateTimedoutHtlc *
update_remove_htlc__unpack update_timedout_htlc__unpack
(ProtobufCAllocator *allocator, (ProtobufCAllocator *allocator,
size_t len, size_t len,
const uint8_t *data) const uint8_t *data)
{ {
return (UpdateRemoveHtlc *) return (UpdateTimedoutHtlc *)
protobuf_c_message_unpack (&update_remove_htlc__descriptor, protobuf_c_message_unpack (&update_timedout_htlc__descriptor,
allocator, len, data); allocator, len, data);
} }
void update_remove_htlc__free_unpacked void update_timedout_htlc__free_unpacked
(UpdateRemoveHtlc *message, (UpdateTimedoutHtlc *message,
ProtobufCAllocator *allocator) ProtobufCAllocator *allocator)
{ {
assert(message->base.descriptor == &update_remove_htlc__descriptor); assert(message->base.descriptor == &update_timedout_htlc__descriptor);
protobuf_c_message_free_unpacked ((ProtobufCMessage*)message, allocator); protobuf_c_message_free_unpacked ((ProtobufCMessage*)message, allocator);
} }
void update_remove_htlc_delay__init void update_routefail_htlc__init
(UpdateRemoveHtlcDelay *message) (UpdateRoutefailHtlc *message)
{ {
static UpdateRemoveHtlcDelay init_value = UPDATE_REMOVE_HTLC_DELAY__INIT; static UpdateRoutefailHtlc init_value = UPDATE_ROUTEFAIL_HTLC__INIT;
*message = init_value; *message = init_value;
} }
size_t update_remove_htlc_delay__get_packed_size size_t update_routefail_htlc__get_packed_size
(const UpdateRemoveHtlcDelay *message) (const UpdateRoutefailHtlc *message)
{ {
assert(message->base.descriptor == &update_remove_htlc_delay__descriptor); assert(message->base.descriptor == &update_routefail_htlc__descriptor);
return protobuf_c_message_get_packed_size ((const ProtobufCMessage*)(message)); return protobuf_c_message_get_packed_size ((const ProtobufCMessage*)(message));
} }
size_t update_remove_htlc_delay__pack size_t update_routefail_htlc__pack
(const UpdateRemoveHtlcDelay *message, (const UpdateRoutefailHtlc *message,
uint8_t *out) uint8_t *out)
{ {
assert(message->base.descriptor == &update_remove_htlc_delay__descriptor); assert(message->base.descriptor == &update_routefail_htlc__descriptor);
return protobuf_c_message_pack ((const ProtobufCMessage*)message, out); return protobuf_c_message_pack ((const ProtobufCMessage*)message, out);
} }
size_t update_remove_htlc_delay__pack_to_buffer size_t update_routefail_htlc__pack_to_buffer
(const UpdateRemoveHtlcDelay *message, (const UpdateRoutefailHtlc *message,
ProtobufCBuffer *buffer) ProtobufCBuffer *buffer)
{ {
assert(message->base.descriptor == &update_remove_htlc_delay__descriptor); assert(message->base.descriptor == &update_routefail_htlc__descriptor);
return protobuf_c_message_pack_to_buffer ((const ProtobufCMessage*)message, buffer); return protobuf_c_message_pack_to_buffer ((const ProtobufCMessage*)message, buffer);
} }
UpdateRemoveHtlcDelay * UpdateRoutefailHtlc *
update_remove_htlc_delay__unpack update_routefail_htlc__unpack
(ProtobufCAllocator *allocator, (ProtobufCAllocator *allocator,
size_t len, size_t len,
const uint8_t *data) const uint8_t *data)
{ {
return (UpdateRemoveHtlcDelay *) return (UpdateRoutefailHtlc *)
protobuf_c_message_unpack (&update_remove_htlc_delay__descriptor, protobuf_c_message_unpack (&update_routefail_htlc__descriptor,
allocator, len, data); allocator, len, data);
} }
void update_remove_htlc_delay__free_unpacked void update_routefail_htlc__free_unpacked
(UpdateRemoveHtlcDelay *message, (UpdateRoutefailHtlc *message,
ProtobufCAllocator *allocator) ProtobufCAllocator *allocator)
{ {
assert(message->base.descriptor == &update_remove_htlc_delay__descriptor); assert(message->base.descriptor == &update_routefail_htlc__descriptor);
protobuf_c_message_free_unpacked ((ProtobufCMessage*)message, allocator); protobuf_c_message_free_unpacked ((ProtobufCMessage*)message, allocator);
} }
void update_accept__init void update_accept__init
@ -1831,7 +1831,7 @@ const ProtobufCMessageDescriptor update_complete_htlc__descriptor =
(ProtobufCMessageInit) update_complete_htlc__init, (ProtobufCMessageInit) update_complete_htlc__init,
NULL,NULL,NULL /* reserved[123] */ NULL,NULL,NULL /* reserved[123] */
}; };
static const ProtobufCFieldDescriptor update_remove_htlc__field_descriptors[2] = static const ProtobufCFieldDescriptor update_timedout_htlc__field_descriptors[2] =
{ {
{ {
"revocation_hash", "revocation_hash",
@ -1839,7 +1839,7 @@ static const ProtobufCFieldDescriptor update_remove_htlc__field_descriptors[2] =
PROTOBUF_C_LABEL_REQUIRED, PROTOBUF_C_LABEL_REQUIRED,
PROTOBUF_C_TYPE_MESSAGE, PROTOBUF_C_TYPE_MESSAGE,
0, /* quantifier_offset */ 0, /* quantifier_offset */
offsetof(UpdateRemoveHtlc, revocation_hash), offsetof(UpdateTimedoutHtlc, revocation_hash),
&sha256_hash__descriptor, &sha256_hash__descriptor,
NULL, NULL,
0, /* flags */ 0, /* flags */
@ -1851,74 +1851,88 @@ static const ProtobufCFieldDescriptor update_remove_htlc__field_descriptors[2] =
PROTOBUF_C_LABEL_REQUIRED, PROTOBUF_C_LABEL_REQUIRED,
PROTOBUF_C_TYPE_MESSAGE, PROTOBUF_C_TYPE_MESSAGE,
0, /* quantifier_offset */ 0, /* quantifier_offset */
offsetof(UpdateRemoveHtlc, r_hash), offsetof(UpdateTimedoutHtlc, r_hash),
&sha256_hash__descriptor, &sha256_hash__descriptor,
NULL, NULL,
0, /* flags */ 0, /* flags */
0,NULL,NULL /* reserved1,reserved2, etc */ 0,NULL,NULL /* reserved1,reserved2, etc */
}, },
}; };
static const unsigned update_remove_htlc__field_indices_by_name[] = { static const unsigned update_timedout_htlc__field_indices_by_name[] = {
1, /* field[1] = r_hash */ 1, /* field[1] = r_hash */
0, /* field[0] = revocation_hash */ 0, /* field[0] = revocation_hash */
}; };
static const ProtobufCIntRange update_remove_htlc__number_ranges[2 + 1] = static const ProtobufCIntRange update_timedout_htlc__number_ranges[2 + 1] =
{ {
{ 1, 0 }, { 1, 0 },
{ 3, 1 }, { 3, 1 },
{ 0, 2 } { 0, 2 }
}; };
const ProtobufCMessageDescriptor update_remove_htlc__descriptor = const ProtobufCMessageDescriptor update_timedout_htlc__descriptor =
{ {
PROTOBUF_C__MESSAGE_DESCRIPTOR_MAGIC, PROTOBUF_C__MESSAGE_DESCRIPTOR_MAGIC,
"update_remove_htlc", "update_timedout_htlc",
"UpdateRemoveHtlc", "UpdateTimedoutHtlc",
"UpdateRemoveHtlc", "UpdateTimedoutHtlc",
"", "",
sizeof(UpdateRemoveHtlc), sizeof(UpdateTimedoutHtlc),
2, 2,
update_remove_htlc__field_descriptors, update_timedout_htlc__field_descriptors,
update_remove_htlc__field_indices_by_name, update_timedout_htlc__field_indices_by_name,
2, update_remove_htlc__number_ranges, 2, update_timedout_htlc__number_ranges,
(ProtobufCMessageInit) update_remove_htlc__init, (ProtobufCMessageInit) update_timedout_htlc__init,
NULL,NULL,NULL /* reserved[123] */ NULL,NULL,NULL /* reserved[123] */
}; };
static const ProtobufCFieldDescriptor update_remove_htlc_delay__field_descriptors[1] = static const ProtobufCFieldDescriptor update_routefail_htlc__field_descriptors[2] =
{ {
{ {
"r_hash", "revocation_hash",
1, 1,
PROTOBUF_C_LABEL_REQUIRED, PROTOBUF_C_LABEL_REQUIRED,
PROTOBUF_C_TYPE_MESSAGE, PROTOBUF_C_TYPE_MESSAGE,
0, /* quantifier_offset */ 0, /* quantifier_offset */
offsetof(UpdateRemoveHtlcDelay, r_hash), offsetof(UpdateRoutefailHtlc, revocation_hash),
&sha256_hash__descriptor,
NULL,
0, /* flags */
0,NULL,NULL /* reserved1,reserved2, etc */
},
{
"r_hash",
3,
PROTOBUF_C_LABEL_REQUIRED,
PROTOBUF_C_TYPE_MESSAGE,
0, /* quantifier_offset */
offsetof(UpdateRoutefailHtlc, r_hash),
&sha256_hash__descriptor, &sha256_hash__descriptor,
NULL, NULL,
0, /* flags */ 0, /* flags */
0,NULL,NULL /* reserved1,reserved2, etc */ 0,NULL,NULL /* reserved1,reserved2, etc */
}, },
}; };
static const unsigned update_remove_htlc_delay__field_indices_by_name[] = { static const unsigned update_routefail_htlc__field_indices_by_name[] = {
0, /* field[0] = r_hash */ 1, /* field[1] = r_hash */
0, /* field[0] = revocation_hash */
}; };
static const ProtobufCIntRange update_remove_htlc_delay__number_ranges[1 + 1] = static const ProtobufCIntRange update_routefail_htlc__number_ranges[2 + 1] =
{ {
{ 1, 0 }, { 1, 0 },
{ 0, 1 } { 3, 1 },
{ 0, 2 }
}; };
const ProtobufCMessageDescriptor update_remove_htlc_delay__descriptor = const ProtobufCMessageDescriptor update_routefail_htlc__descriptor =
{ {
PROTOBUF_C__MESSAGE_DESCRIPTOR_MAGIC, PROTOBUF_C__MESSAGE_DESCRIPTOR_MAGIC,
"update_remove_htlc_delay", "update_routefail_htlc",
"UpdateRemoveHtlcDelay", "UpdateRoutefailHtlc",
"UpdateRemoveHtlcDelay", "UpdateRoutefailHtlc",
"", "",
sizeof(UpdateRemoveHtlcDelay), sizeof(UpdateRoutefailHtlc),
1, 2,
update_remove_htlc_delay__field_descriptors, update_routefail_htlc__field_descriptors,
update_remove_htlc_delay__field_indices_by_name, update_routefail_htlc__field_indices_by_name,
1, update_remove_htlc_delay__number_ranges, 2, update_routefail_htlc__number_ranges,
(ProtobufCMessageInit) update_remove_htlc_delay__init, (ProtobufCMessageInit) update_routefail_htlc__init,
NULL,NULL,NULL /* reserved[123] */ NULL,NULL,NULL /* reserved[123] */
}; };
static const ProtobufCFieldDescriptor update_accept__field_descriptors[2] = static const ProtobufCFieldDescriptor update_accept__field_descriptors[2] =
@ -2252,49 +2266,49 @@ static const ProtobufCFieldDescriptor pkt__field_descriptors[16] =
0,NULL,NULL /* reserved1,reserved2, etc */ 0,NULL,NULL /* reserved1,reserved2, etc */
}, },
{ {
"update_complete_htlc", "update_decline_htlc",
6, 6,
PROTOBUF_C_LABEL_OPTIONAL, PROTOBUF_C_LABEL_OPTIONAL,
PROTOBUF_C_TYPE_MESSAGE, PROTOBUF_C_TYPE_MESSAGE,
offsetof(Pkt, pkt_case), offsetof(Pkt, pkt_case),
offsetof(Pkt, update_complete_htlc), offsetof(Pkt, update_decline_htlc),
&update_complete_htlc__descriptor, &update_decline_htlc__descriptor,
NULL, NULL,
0 | PROTOBUF_C_FIELD_FLAG_ONEOF, /* flags */ 0 | PROTOBUF_C_FIELD_FLAG_ONEOF, /* flags */
0,NULL,NULL /* reserved1,reserved2, etc */ 0,NULL,NULL /* reserved1,reserved2, etc */
}, },
{ {
"update_remove_htlc", "update_complete_htlc",
7, 7,
PROTOBUF_C_LABEL_OPTIONAL, PROTOBUF_C_LABEL_OPTIONAL,
PROTOBUF_C_TYPE_MESSAGE, PROTOBUF_C_TYPE_MESSAGE,
offsetof(Pkt, pkt_case), offsetof(Pkt, pkt_case),
offsetof(Pkt, update_remove_htlc), offsetof(Pkt, update_complete_htlc),
&update_remove_htlc__descriptor, &update_complete_htlc__descriptor,
NULL, NULL,
0 | PROTOBUF_C_FIELD_FLAG_ONEOF, /* flags */ 0 | PROTOBUF_C_FIELD_FLAG_ONEOF, /* flags */
0,NULL,NULL /* reserved1,reserved2, etc */ 0,NULL,NULL /* reserved1,reserved2, etc */
}, },
{ {
"update_remove_htlc_delay", "update_timedout_htlc",
8, 8,
PROTOBUF_C_LABEL_OPTIONAL, PROTOBUF_C_LABEL_OPTIONAL,
PROTOBUF_C_TYPE_MESSAGE, PROTOBUF_C_TYPE_MESSAGE,
offsetof(Pkt, pkt_case), offsetof(Pkt, pkt_case),
offsetof(Pkt, update_remove_htlc_delay), offsetof(Pkt, update_timedout_htlc),
&update_remove_htlc_delay__descriptor, &update_timedout_htlc__descriptor,
NULL, NULL,
0 | PROTOBUF_C_FIELD_FLAG_ONEOF, /* flags */ 0 | PROTOBUF_C_FIELD_FLAG_ONEOF, /* flags */
0,NULL,NULL /* reserved1,reserved2, etc */ 0,NULL,NULL /* reserved1,reserved2, etc */
}, },
{ {
"update_decline_htlc", "update_routefail_htlc",
9, 9,
PROTOBUF_C_LABEL_OPTIONAL, PROTOBUF_C_LABEL_OPTIONAL,
PROTOBUF_C_TYPE_MESSAGE, PROTOBUF_C_TYPE_MESSAGE,
offsetof(Pkt, pkt_case), offsetof(Pkt, pkt_case),
offsetof(Pkt, update_decline_htlc), offsetof(Pkt, update_routefail_htlc),
&update_decline_htlc__descriptor, &update_routefail_htlc__descriptor,
NULL, NULL,
0 | PROTOBUF_C_FIELD_FLAG_ONEOF, /* flags */ 0 | PROTOBUF_C_FIELD_FLAG_ONEOF, /* flags */
0,NULL,NULL /* reserved1,reserved2, etc */ 0,NULL,NULL /* reserved1,reserved2, etc */
@ -2396,11 +2410,11 @@ static const unsigned pkt__field_indices_by_name[] = {
2, /* field[2] = update_accept */ 2, /* field[2] = update_accept */
1, /* field[1] = update_add_htlc */ 1, /* field[1] = update_add_htlc */
4, /* field[4] = update_complete */ 4, /* field[4] = update_complete */
5, /* field[5] = update_complete_htlc */ 6, /* field[6] = update_complete_htlc */
8, /* field[8] = update_decline_htlc */ 5, /* field[5] = update_decline_htlc */
6, /* field[6] = update_remove_htlc */ 8, /* field[8] = update_routefail_htlc */
7, /* field[7] = update_remove_htlc_delay */
3, /* field[3] = update_signature */ 3, /* field[3] = update_signature */
7, /* field[7] = update_timedout_htlc */
}; };
static const ProtobufCIntRange pkt__number_ranges[4 + 1] = static const ProtobufCIntRange pkt__number_ranges[4 + 1] =
{ {

109
lightning.pb-c.h

@ -28,8 +28,8 @@ typedef struct _Update Update;
typedef struct _UpdateAddHtlc UpdateAddHtlc; typedef struct _UpdateAddHtlc UpdateAddHtlc;
typedef struct _UpdateDeclineHtlc UpdateDeclineHtlc; typedef struct _UpdateDeclineHtlc UpdateDeclineHtlc;
typedef struct _UpdateCompleteHtlc UpdateCompleteHtlc; typedef struct _UpdateCompleteHtlc UpdateCompleteHtlc;
typedef struct _UpdateRemoveHtlc UpdateRemoveHtlc; typedef struct _UpdateTimedoutHtlc UpdateTimedoutHtlc;
typedef struct _UpdateRemoveHtlcDelay UpdateRemoveHtlcDelay; typedef struct _UpdateRoutefailHtlc UpdateRoutefailHtlc;
typedef struct _UpdateAccept UpdateAccept; typedef struct _UpdateAccept UpdateAccept;
typedef struct _UpdateSignature UpdateSignature; typedef struct _UpdateSignature UpdateSignature;
typedef struct _UpdateComplete UpdateComplete; typedef struct _UpdateComplete UpdateComplete;
@ -302,7 +302,7 @@ typedef enum {
} UpdateDeclineHtlc__ReasonCase; } UpdateDeclineHtlc__ReasonCase;
/* /*
* We can't do this HTLC, sorry. * We can't do this HTLC, sorry (instead of update_accept)
*/ */
struct _UpdateDeclineHtlc struct _UpdateDeclineHtlc
{ {
@ -319,7 +319,7 @@ struct _UpdateDeclineHtlc
/* /*
* Complete an HTLC * Complete your HTLC: I have the R value, pay me!
*/ */
struct _UpdateCompleteHtlc struct _UpdateCompleteHtlc
{ {
@ -339,9 +339,9 @@ struct _UpdateCompleteHtlc
/* /*
* Remove an HTLC * Remove my HTLC: it has timed out, before you got the R value.
*/ */
struct _UpdateRemoveHtlc struct _UpdateTimedoutHtlc
{ {
ProtobufCMessage base; ProtobufCMessage base;
/* /*
@ -353,26 +353,29 @@ struct _UpdateRemoveHtlc
*/ */
Sha256Hash *r_hash; Sha256Hash *r_hash;
}; };
#define UPDATE_REMOVE_HTLC__INIT \ #define UPDATE_TIMEDOUT_HTLC__INIT \
{ PROTOBUF_C_MESSAGE_INIT (&update_remove_htlc__descriptor) \ { PROTOBUF_C_MESSAGE_INIT (&update_timedout_htlc__descriptor) \
, NULL, NULL } , NULL, NULL }
/* /*
* Respond to an HTLC remove request: not yet. * Remove your HTLC: routing has failed upstream
* Expect a remove_htlc later.
*/ */
struct _UpdateRemoveHtlcDelay struct _UpdateRoutefailHtlc
{ {
ProtobufCMessage base; ProtobufCMessage base;
/*
* Hash for which I will supply preimage to revoke this commitment tx.
*/
Sha256Hash *revocation_hash;
/* /*
* Hash for HTLC R value. * Hash for HTLC R value.
*/ */
Sha256Hash *r_hash; Sha256Hash *r_hash;
}; };
#define UPDATE_REMOVE_HTLC_DELAY__INIT \ #define UPDATE_ROUTEFAIL_HTLC__INIT \
{ PROTOBUF_C_MESSAGE_INIT (&update_remove_htlc_delay__descriptor) \ { PROTOBUF_C_MESSAGE_INIT (&update_routefail_htlc__descriptor) \
, NULL } , NULL, NULL }
/* /*
@ -493,10 +496,10 @@ typedef enum {
PKT__PKT_UPDATE_ACCEPT = 3, PKT__PKT_UPDATE_ACCEPT = 3,
PKT__PKT_UPDATE_SIGNATURE = 4, PKT__PKT_UPDATE_SIGNATURE = 4,
PKT__PKT_UPDATE_COMPLETE = 5, PKT__PKT_UPDATE_COMPLETE = 5,
PKT__PKT_UPDATE_COMPLETE_HTLC = 6, PKT__PKT_UPDATE_DECLINE_HTLC = 6,
PKT__PKT_UPDATE_REMOVE_HTLC = 7, PKT__PKT_UPDATE_COMPLETE_HTLC = 7,
PKT__PKT_UPDATE_REMOVE_HTLC_DELAY = 8, PKT__PKT_UPDATE_TIMEDOUT_HTLC = 8,
PKT__PKT_UPDATE_DECLINE_HTLC = 9, PKT__PKT_UPDATE_ROUTEFAIL_HTLC = 9,
PKT__PKT_CLOSE = 401, PKT__PKT_CLOSE = 401,
PKT__PKT_CLOSE_COMPLETE = 402, PKT__PKT_CLOSE_COMPLETE = 402,
PKT__PKT_ERROR = 1000, PKT__PKT_ERROR = 1000,
@ -525,10 +528,10 @@ struct _Pkt
UpdateAccept *update_accept; UpdateAccept *update_accept;
UpdateSignature *update_signature; UpdateSignature *update_signature;
UpdateComplete *update_complete; UpdateComplete *update_complete;
UpdateCompleteHtlc *update_complete_htlc;
UpdateRemoveHtlc *update_remove_htlc;
UpdateRemoveHtlcDelay *update_remove_htlc_delay;
UpdateDeclineHtlc *update_decline_htlc; UpdateDeclineHtlc *update_decline_htlc;
UpdateCompleteHtlc *update_complete_htlc;
UpdateTimedoutHtlc *update_timedout_htlc;
UpdateRoutefailHtlc *update_routefail_htlc;
/* /*
* Closing * Closing
*/ */
@ -792,43 +795,43 @@ UpdateCompleteHtlc *
void update_complete_htlc__free_unpacked void update_complete_htlc__free_unpacked
(UpdateCompleteHtlc *message, (UpdateCompleteHtlc *message,
ProtobufCAllocator *allocator); ProtobufCAllocator *allocator);
/* UpdateRemoveHtlc methods */ /* UpdateTimedoutHtlc methods */
void update_remove_htlc__init void update_timedout_htlc__init
(UpdateRemoveHtlc *message); (UpdateTimedoutHtlc *message);
size_t update_remove_htlc__get_packed_size size_t update_timedout_htlc__get_packed_size
(const UpdateRemoveHtlc *message); (const UpdateTimedoutHtlc *message);
size_t update_remove_htlc__pack size_t update_timedout_htlc__pack
(const UpdateRemoveHtlc *message, (const UpdateTimedoutHtlc *message,
uint8_t *out); uint8_t *out);
size_t update_remove_htlc__pack_to_buffer size_t update_timedout_htlc__pack_to_buffer
(const UpdateRemoveHtlc *message, (const UpdateTimedoutHtlc *message,
ProtobufCBuffer *buffer); ProtobufCBuffer *buffer);
UpdateRemoveHtlc * UpdateTimedoutHtlc *
update_remove_htlc__unpack update_timedout_htlc__unpack
(ProtobufCAllocator *allocator, (ProtobufCAllocator *allocator,
size_t len, size_t len,
const uint8_t *data); const uint8_t *data);
void update_remove_htlc__free_unpacked void update_timedout_htlc__free_unpacked
(UpdateRemoveHtlc *message, (UpdateTimedoutHtlc *message,
ProtobufCAllocator *allocator); ProtobufCAllocator *allocator);
/* UpdateRemoveHtlcDelay methods */ /* UpdateRoutefailHtlc methods */
void update_remove_htlc_delay__init void update_routefail_htlc__init
(UpdateRemoveHtlcDelay *message); (UpdateRoutefailHtlc *message);
size_t update_remove_htlc_delay__get_packed_size size_t update_routefail_htlc__get_packed_size
(const UpdateRemoveHtlcDelay *message); (const UpdateRoutefailHtlc *message);
size_t update_remove_htlc_delay__pack size_t update_routefail_htlc__pack
(const UpdateRemoveHtlcDelay *message, (const UpdateRoutefailHtlc *message,
uint8_t *out); uint8_t *out);
size_t update_remove_htlc_delay__pack_to_buffer size_t update_routefail_htlc__pack_to_buffer
(const UpdateRemoveHtlcDelay *message, (const UpdateRoutefailHtlc *message,
ProtobufCBuffer *buffer); ProtobufCBuffer *buffer);
UpdateRemoveHtlcDelay * UpdateRoutefailHtlc *
update_remove_htlc_delay__unpack update_routefail_htlc__unpack
(ProtobufCAllocator *allocator, (ProtobufCAllocator *allocator,
size_t len, size_t len,
const uint8_t *data); const uint8_t *data);
void update_remove_htlc_delay__free_unpacked void update_routefail_htlc__free_unpacked
(UpdateRemoveHtlcDelay *message, (UpdateRoutefailHtlc *message,
ProtobufCAllocator *allocator); ProtobufCAllocator *allocator);
/* UpdateAccept methods */ /* UpdateAccept methods */
void update_accept__init void update_accept__init
@ -1004,11 +1007,11 @@ typedef void (*UpdateDeclineHtlc_Closure)
typedef void (*UpdateCompleteHtlc_Closure) typedef void (*UpdateCompleteHtlc_Closure)
(const UpdateCompleteHtlc *message, (const UpdateCompleteHtlc *message,
void *closure_data); void *closure_data);
typedef void (*UpdateRemoveHtlc_Closure) typedef void (*UpdateTimedoutHtlc_Closure)
(const UpdateRemoveHtlc *message, (const UpdateTimedoutHtlc *message,
void *closure_data); void *closure_data);
typedef void (*UpdateRemoveHtlcDelay_Closure) typedef void (*UpdateRoutefailHtlc_Closure)
(const UpdateRemoveHtlcDelay *message, (const UpdateRoutefailHtlc *message,
void *closure_data); void *closure_data);
typedef void (*UpdateAccept_Closure) typedef void (*UpdateAccept_Closure)
(const UpdateAccept *message, (const UpdateAccept *message,
@ -1051,8 +1054,8 @@ extern const ProtobufCMessageDescriptor update__descriptor;
extern const ProtobufCMessageDescriptor update_add_htlc__descriptor; extern const ProtobufCMessageDescriptor update_add_htlc__descriptor;
extern const ProtobufCMessageDescriptor update_decline_htlc__descriptor; extern const ProtobufCMessageDescriptor update_decline_htlc__descriptor;
extern const ProtobufCMessageDescriptor update_complete_htlc__descriptor; extern const ProtobufCMessageDescriptor update_complete_htlc__descriptor;
extern const ProtobufCMessageDescriptor update_remove_htlc__descriptor; extern const ProtobufCMessageDescriptor update_timedout_htlc__descriptor;
extern const ProtobufCMessageDescriptor update_remove_htlc_delay__descriptor; extern const ProtobufCMessageDescriptor update_routefail_htlc__descriptor;
extern const ProtobufCMessageDescriptor update_accept__descriptor; extern const ProtobufCMessageDescriptor update_accept__descriptor;
extern const ProtobufCMessageDescriptor update_signature__descriptor; extern const ProtobufCMessageDescriptor update_signature__descriptor;
extern const ProtobufCMessageDescriptor update_complete__descriptor; extern const ProtobufCMessageDescriptor update_complete__descriptor;

27
lightning.proto

@ -123,7 +123,7 @@ message update_add_htlc {
// FIXME: Routing information. // FIXME: Routing information.
} }
// We can't do this HTLC, sorry. // We can't do this HTLC, sorry (instead of update_accept)
message update_decline_htlc { message update_decline_htlc {
oneof reason { oneof reason {
funding insufficient_funds = 1; funding insufficient_funds = 1;
@ -131,7 +131,7 @@ message update_decline_htlc {
}; };
} }
// Complete an HTLC // Complete your HTLC: I have the R value, pay me!
message update_complete_htlc { message update_complete_htlc {
// Hash for which I will supply preimage to revoke this commitment tx. // Hash for which I will supply preimage to revoke this commitment tx.
required sha256_hash revocation_hash = 1; required sha256_hash revocation_hash = 1;
@ -139,22 +139,23 @@ message update_complete_htlc {
required sha256_hash r = 3; required sha256_hash r = 3;
} }
// Remove an HTLC // Remove my HTLC: it has timed out, before you got the R value.
message update_remove_htlc { message update_timedout_htlc {
// Hash for which I will supply preimage to revoke this commitment tx. // Hash for which I will supply preimage to revoke this commitment tx.
required sha256_hash revocation_hash = 1; required sha256_hash revocation_hash = 1;
// Hash for HTLC R value. // Hash for HTLC R value.
required sha256_hash r_hash = 3; required sha256_hash r_hash = 3;
} }
// Respond to an HTLC remove request: not yet. // Remove your HTLC: routing has failed upstream
// Expect a remove_htlc later. message update_routefail_htlc {
message update_remove_htlc_delay { // Hash for which I will supply preimage to revoke this commitment tx.
required sha256_hash revocation_hash = 1;
// Hash for HTLC R value. // Hash for HTLC R value.
required sha256_hash r_hash = 1; required sha256_hash r_hash = 3;
} }
// OK, I accept that update; here's your signature. // OK, I accept that update; here's your signature.
message update_accept { message update_accept {
// Signature for your new commitment tx. // Signature for your new commitment tx.
required signature sig = 1; required signature sig = 1;
@ -211,10 +212,10 @@ message pkt {
update_accept update_accept = 3; update_accept update_accept = 3;
update_signature update_signature = 4; update_signature update_signature = 4;
update_complete update_complete = 5; update_complete update_complete = 5;
update_complete_htlc update_complete_htlc = 6; update_decline_htlc update_decline_htlc = 6;
update_remove_htlc update_remove_htlc = 7; update_complete_htlc update_complete_htlc = 7;
update_remove_htlc_delay update_remove_htlc_delay = 8; update_timedout_htlc update_timedout_htlc = 8;
update_decline_htlc update_decline_htlc = 9; update_routefail_htlc update_routefail_htlc = 9;
// Closing // Closing
close_channel close = 401; close_channel close = 401;
close_channel_complete close_complete = 402; close_channel_complete close_complete = 402;

18
pkt.c

@ -175,16 +175,28 @@ struct pkt *update_htlc_complete_pkt(const tal_t *ctx,
return to_pkt(ctx, PKT__PKT_UPDATE_COMPLETE_HTLC, &u); return to_pkt(ctx, PKT__PKT_UPDATE_COMPLETE_HTLC, &u);
} }
struct pkt *update_htlc_remove_pkt(const tal_t *ctx, struct pkt *update_htlc_timedout_pkt(const tal_t *ctx,
const struct sha256 *revocation_hash, const struct sha256 *revocation_hash,
const struct sha256 *htlc_rhash) const struct sha256 *htlc_rhash)
{ {
UpdateRemoveHtlc u = UPDATE_REMOVE_HTLC__INIT; UpdateTimedoutHtlc u = UPDATE_TIMEDOUT_HTLC__INIT;
u.revocation_hash = sha256_to_proto(ctx, revocation_hash); u.revocation_hash = sha256_to_proto(ctx, revocation_hash);
u.r_hash = sha256_to_proto(ctx, htlc_rhash); u.r_hash = sha256_to_proto(ctx, htlc_rhash);
return to_pkt(ctx, PKT__PKT_UPDATE_REMOVE_HTLC, &u); return to_pkt(ctx, PKT__PKT_UPDATE_TIMEDOUT_HTLC, &u);
}
struct pkt *update_htlc_routefail_pkt(const tal_t *ctx,
const struct sha256 *revocation_hash,
const struct sha256 *htlc_rhash)
{
UpdateRoutefailHtlc u = UPDATE_ROUTEFAIL_HTLC__INIT;
u.revocation_hash = sha256_to_proto(ctx, revocation_hash);
u.r_hash = sha256_to_proto(ctx, htlc_rhash);
return to_pkt(ctx, PKT__PKT_UPDATE_ROUTEFAIL_HTLC, &u);
} }
struct pkt *update_accept_pkt(const tal_t *ctx, struct pkt *update_accept_pkt(const tal_t *ctx,

16
pkt.h

@ -105,7 +105,7 @@ struct pkt *update_htlc_add_pkt(const tal_t *ctx,
u32 abs_locktime_seconds); u32 abs_locktime_seconds);
/** /**
* update_htlc_complete_pkt - create an update message removing a HTLC * update_htlc_complete_pkt - create an update message completing a HTLC
* @ctx: tal context to allocate off. * @ctx: tal context to allocate off.
* @revocation_hash: the revocation hash for the next commitment tx. * @revocation_hash: the revocation hash for the next commitment tx.
* @rval: the r value for the HTLC * @rval: the r value for the HTLC
@ -115,12 +115,22 @@ struct pkt *update_htlc_complete_pkt(const tal_t *ctx,
const struct sha256 *rval); const struct sha256 *rval);
/** /**
* update_htlc_remove_pkt - create an update message completing a HTLC * update_htlc_timedout_pkt - create an update message removing a HTLC
* @ctx: tal context to allocate off. * @ctx: tal context to allocate off.
* @revocation_hash: the revocation hash for the next commitment tx. * @revocation_hash: the revocation hash for the next commitment tx.
* @htlc_rhash: the hash of the htlc secret. * @htlc_rhash: the hash of the htlc secret.
*/ */
struct pkt *update_htlc_remove_pkt(const tal_t *ctx, struct pkt *update_htlc_timedout_pkt(const tal_t *ctx,
const struct sha256 *revocation_hash,
const struct sha256 *htlc_rhash);
/**
* update_htlc_routefail_pkt - create an update message removing a HTLC
* @ctx: tal context to allocate off.
* @revocation_hash: the revocation hash for the next commitment tx.
* @htlc_rhash: the hash of the htlc secret.
*/
struct pkt *update_htlc_routefail_pkt(const tal_t *ctx,
const struct sha256 *revocation_hash, const struct sha256 *revocation_hash,
const struct sha256 *htlc_rhash); const struct sha256 *htlc_rhash);

39
test-cli/gather_updates.c

@ -167,10 +167,10 @@ struct channel_state *gather_updates(const tal_t *ctx,
our_rhash, their_rhash); our_rhash, their_rhash);
break; break;
case PKT__PKT_UPDATE_REMOVE_HTLC: case PKT__PKT_UPDATE_TIMEDOUT_HTLC:
if (received) { if (received) {
n = find_htlc(&cstate->b, n = find_htlc(&cstate->b,
pkt->update_remove_htlc->r_hash); pkt->update_timedout_htlc->r_hash);
if (n == tal_count(cstate->b.htlcs)) if (n == tal_count(cstate->b.htlcs))
errx(1, "Unknown R hash in %s", *argv); errx(1, "Unknown R hash in %s", *argv);
amount = cstate->b.htlcs[n]->amount_msat; amount = cstate->b.htlcs[n]->amount_msat;
@ -181,7 +181,7 @@ struct channel_state *gather_updates(const tal_t *ctx,
remove_htlc(&cstate->b, n); remove_htlc(&cstate->b, n);
} else { } else {
n = find_htlc(&cstate->a, n = find_htlc(&cstate->a,
pkt->update_remove_htlc->r_hash); pkt->update_timedout_htlc->r_hash);
if (n == tal_count(cstate->a.htlcs)) if (n == tal_count(cstate->a.htlcs))
errx(1, "Unknown R hash in %s", *argv); errx(1, "Unknown R hash in %s", *argv);
amount = cstate->a.htlcs[n]->amount_msat; amount = cstate->a.htlcs[n]->amount_msat;
@ -191,7 +191,38 @@ struct channel_state *gather_updates(const tal_t *ctx,
(long long)amount, *argv); (long long)amount, *argv);
remove_htlc(&cstate->a, n); remove_htlc(&cstate->a, n);
} }
update_rhash(pkt->update_remove_htlc->revocation_hash, update_rhash(pkt->update_timedout_htlc->revocation_hash,
received, num_updates,
&old_our_rhash, &old_their_rhash,
our_rhash, their_rhash);
break;
/* HTLC acceptor sends this to initiator. */
case PKT__PKT_UPDATE_ROUTEFAIL_HTLC:
if (received) {
n = find_htlc(&cstate->a,
pkt->update_routefail_htlc->r_hash);
if (n == tal_count(cstate->a.htlcs))
errx(1, "Unknown R hash in %s", *argv);
amount = cstate->a.htlcs[n]->amount;
if (!funding_delta(o1, o2, oa, 0, -amount,
&cstate->a, &cstate->b))
errx(1, "Impossible htlc %llu %s",
(long long)amount, *argv);
remove_htlc(&cstate->a, n);
} else {
n = find_htlc(&cstate->b,
pkt->update_routefail_htlc->r_hash);
if (n == tal_count(cstate->b.htlcs))
errx(1, "Unknown R hash in %s", *argv);
amount = cstate->b.htlcs[n]->amount;
if (!funding_delta(o2, o1, oa, 0, -amount,
&cstate->b, &cstate->a))
errx(1, "Impossible htlc %llu %s",
(long long)amount, *argv);
remove_htlc(&cstate->b, n);
}
update_rhash(pkt->update_routefail_htlc->revocation_hash,
received, num_updates, received, num_updates,
&old_our_rhash, &old_their_rhash, &old_our_rhash, &old_their_rhash,
our_rhash, their_rhash); our_rhash, their_rhash);

12
test-cli/update-channel-htlc-remove.c

@ -25,13 +25,16 @@ int main(int argc, char *argv[])
struct pkt *pkt; struct pkt *pkt;
unsigned update_num; unsigned update_num;
UpdateAddHtlc *u; UpdateAddHtlc *u;
bool routefail = false;
err_set_progname(argv[0]); err_set_progname(argv[0]);
opt_register_noarg("--help|-h", opt_usage_and_exit, opt_register_noarg("--help|-h", opt_usage_and_exit,
"<seed> <update-number> <update-pkt>\n" "<seed> <update-number> <update-pkt>\n"
"Create a new HTLC remove message", "Create a new HTLC (timedout) remove message",
"Print this message."); "Print this message.");
opt_register_noarg("--routefail", opt_set_bool, &routefail,
"Generate a routefail instead of timedout");
opt_register_version(); opt_register_version();
opt_parse(&argc, argv, opt_log_stderr_exit); opt_parse(&argc, argv, opt_log_stderr_exit);
@ -53,7 +56,12 @@ int main(int argc, char *argv[])
sha256(&revocation_hash, sha256(&revocation_hash,
revocation_hash.u.u8, sizeof(revocation_hash.u.u8)); revocation_hash.u.u8, sizeof(revocation_hash.u.u8));
pkt = update_htlc_remove_pkt(ctx, &revocation_hash, &htlc_rhash); if (routefail)
pkt = update_htlc_routefail_pkt(ctx, &revocation_hash,
&htlc_rhash);
else
pkt = update_htlc_timedout_pkt(ctx, &revocation_hash,
&htlc_rhash);
if (!write_all(STDOUT_FILENO, pkt, pkt_totlen(pkt))) if (!write_all(STDOUT_FILENO, pkt, pkt_totlen(pkt)))
err(1, "Writing out packet"); err(1, "Writing out packet");

Loading…
Cancel
Save