From d00eeded9f49703b45feb378f2246a6f4017dba5 Mon Sep 17 00:00:00 2001 From: Rusty Russell Date: Thu, 24 Sep 2015 15:02:49 +0930 Subject: [PATCH] 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 --- lightning.pb-c.c | 184 ++++++++++++++------------ lightning.pb-c.h | 109 +++++++-------- lightning.proto | 27 ++-- pkt.c | 24 +++- pkt.h | 16 ++- test-cli/gather_updates.c | 39 +++++- test-cli/update-channel-htlc-remove.c | 12 +- 7 files changed, 245 insertions(+), 166 deletions(-) diff --git a/lightning.pb-c.c b/lightning.pb-c.c index 977fb8b4e..1ad350b34 100644 --- a/lightning.pb-c.c +++ b/lightning.pb-c.c @@ -566,90 +566,90 @@ void update_complete_htlc__free_unpacked assert(message->base.descriptor == &update_complete_htlc__descriptor); protobuf_c_message_free_unpacked ((ProtobufCMessage*)message, allocator); } -void update_remove_htlc__init - (UpdateRemoveHtlc *message) +void update_timedout_htlc__init + (UpdateTimedoutHtlc *message) { - static UpdateRemoveHtlc init_value = UPDATE_REMOVE_HTLC__INIT; + static UpdateTimedoutHtlc init_value = UPDATE_TIMEDOUT_HTLC__INIT; *message = init_value; } -size_t update_remove_htlc__get_packed_size - (const UpdateRemoveHtlc *message) +size_t update_timedout_htlc__get_packed_size + (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)); } -size_t update_remove_htlc__pack - (const UpdateRemoveHtlc *message, +size_t update_timedout_htlc__pack + (const UpdateTimedoutHtlc *message, 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); } -size_t update_remove_htlc__pack_to_buffer - (const UpdateRemoveHtlc *message, +size_t update_timedout_htlc__pack_to_buffer + (const UpdateTimedoutHtlc *message, 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); } -UpdateRemoveHtlc * - update_remove_htlc__unpack +UpdateTimedoutHtlc * + update_timedout_htlc__unpack (ProtobufCAllocator *allocator, size_t len, const uint8_t *data) { - return (UpdateRemoveHtlc *) - protobuf_c_message_unpack (&update_remove_htlc__descriptor, + return (UpdateTimedoutHtlc *) + protobuf_c_message_unpack (&update_timedout_htlc__descriptor, allocator, len, data); } -void update_remove_htlc__free_unpacked - (UpdateRemoveHtlc *message, +void update_timedout_htlc__free_unpacked + (UpdateTimedoutHtlc *message, 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); } -void update_remove_htlc_delay__init - (UpdateRemoveHtlcDelay *message) +void update_routefail_htlc__init + (UpdateRoutefailHtlc *message) { - static UpdateRemoveHtlcDelay init_value = UPDATE_REMOVE_HTLC_DELAY__INIT; + static UpdateRoutefailHtlc init_value = UPDATE_ROUTEFAIL_HTLC__INIT; *message = init_value; } -size_t update_remove_htlc_delay__get_packed_size - (const UpdateRemoveHtlcDelay *message) +size_t update_routefail_htlc__get_packed_size + (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)); } -size_t update_remove_htlc_delay__pack - (const UpdateRemoveHtlcDelay *message, +size_t update_routefail_htlc__pack + (const UpdateRoutefailHtlc *message, 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); } -size_t update_remove_htlc_delay__pack_to_buffer - (const UpdateRemoveHtlcDelay *message, +size_t update_routefail_htlc__pack_to_buffer + (const UpdateRoutefailHtlc *message, 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); } -UpdateRemoveHtlcDelay * - update_remove_htlc_delay__unpack +UpdateRoutefailHtlc * + update_routefail_htlc__unpack (ProtobufCAllocator *allocator, size_t len, const uint8_t *data) { - return (UpdateRemoveHtlcDelay *) - protobuf_c_message_unpack (&update_remove_htlc_delay__descriptor, + return (UpdateRoutefailHtlc *) + protobuf_c_message_unpack (&update_routefail_htlc__descriptor, allocator, len, data); } -void update_remove_htlc_delay__free_unpacked - (UpdateRemoveHtlcDelay *message, +void update_routefail_htlc__free_unpacked + (UpdateRoutefailHtlc *message, 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); } void update_accept__init @@ -1831,7 +1831,7 @@ const ProtobufCMessageDescriptor update_complete_htlc__descriptor = (ProtobufCMessageInit) update_complete_htlc__init, 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", @@ -1839,7 +1839,7 @@ static const ProtobufCFieldDescriptor update_remove_htlc__field_descriptors[2] = PROTOBUF_C_LABEL_REQUIRED, PROTOBUF_C_TYPE_MESSAGE, 0, /* quantifier_offset */ - offsetof(UpdateRemoveHtlc, revocation_hash), + offsetof(UpdateTimedoutHtlc, revocation_hash), &sha256_hash__descriptor, NULL, 0, /* flags */ @@ -1851,74 +1851,88 @@ static const ProtobufCFieldDescriptor update_remove_htlc__field_descriptors[2] = PROTOBUF_C_LABEL_REQUIRED, PROTOBUF_C_TYPE_MESSAGE, 0, /* quantifier_offset */ - offsetof(UpdateRemoveHtlc, r_hash), + offsetof(UpdateTimedoutHtlc, r_hash), &sha256_hash__descriptor, NULL, 0, /* flags */ 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 */ 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 }, { 3, 1 }, { 0, 2 } }; -const ProtobufCMessageDescriptor update_remove_htlc__descriptor = +const ProtobufCMessageDescriptor update_timedout_htlc__descriptor = { PROTOBUF_C__MESSAGE_DESCRIPTOR_MAGIC, - "update_remove_htlc", - "UpdateRemoveHtlc", - "UpdateRemoveHtlc", + "update_timedout_htlc", + "UpdateTimedoutHtlc", + "UpdateTimedoutHtlc", "", - sizeof(UpdateRemoveHtlc), + sizeof(UpdateTimedoutHtlc), 2, - update_remove_htlc__field_descriptors, - update_remove_htlc__field_indices_by_name, - 2, update_remove_htlc__number_ranges, - (ProtobufCMessageInit) update_remove_htlc__init, + update_timedout_htlc__field_descriptors, + update_timedout_htlc__field_indices_by_name, + 2, update_timedout_htlc__number_ranges, + (ProtobufCMessageInit) update_timedout_htlc__init, 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, PROTOBUF_C_LABEL_REQUIRED, PROTOBUF_C_TYPE_MESSAGE, 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, NULL, 0, /* flags */ 0,NULL,NULL /* reserved1,reserved2, etc */ }, }; -static const unsigned update_remove_htlc_delay__field_indices_by_name[] = { - 0, /* field[0] = r_hash */ +static const unsigned update_routefail_htlc__field_indices_by_name[] = { + 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 }, - { 0, 1 } + { 3, 1 }, + { 0, 2 } }; -const ProtobufCMessageDescriptor update_remove_htlc_delay__descriptor = +const ProtobufCMessageDescriptor update_routefail_htlc__descriptor = { PROTOBUF_C__MESSAGE_DESCRIPTOR_MAGIC, - "update_remove_htlc_delay", - "UpdateRemoveHtlcDelay", - "UpdateRemoveHtlcDelay", + "update_routefail_htlc", + "UpdateRoutefailHtlc", + "UpdateRoutefailHtlc", "", - sizeof(UpdateRemoveHtlcDelay), - 1, - update_remove_htlc_delay__field_descriptors, - update_remove_htlc_delay__field_indices_by_name, - 1, update_remove_htlc_delay__number_ranges, - (ProtobufCMessageInit) update_remove_htlc_delay__init, + sizeof(UpdateRoutefailHtlc), + 2, + update_routefail_htlc__field_descriptors, + update_routefail_htlc__field_indices_by_name, + 2, update_routefail_htlc__number_ranges, + (ProtobufCMessageInit) update_routefail_htlc__init, NULL,NULL,NULL /* reserved[123] */ }; 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 */ }, { - "update_complete_htlc", + "update_decline_htlc", 6, PROTOBUF_C_LABEL_OPTIONAL, PROTOBUF_C_TYPE_MESSAGE, offsetof(Pkt, pkt_case), - offsetof(Pkt, update_complete_htlc), - &update_complete_htlc__descriptor, + offsetof(Pkt, update_decline_htlc), + &update_decline_htlc__descriptor, NULL, 0 | PROTOBUF_C_FIELD_FLAG_ONEOF, /* flags */ 0,NULL,NULL /* reserved1,reserved2, etc */ }, { - "update_remove_htlc", + "update_complete_htlc", 7, PROTOBUF_C_LABEL_OPTIONAL, PROTOBUF_C_TYPE_MESSAGE, offsetof(Pkt, pkt_case), - offsetof(Pkt, update_remove_htlc), - &update_remove_htlc__descriptor, + offsetof(Pkt, update_complete_htlc), + &update_complete_htlc__descriptor, NULL, 0 | PROTOBUF_C_FIELD_FLAG_ONEOF, /* flags */ 0,NULL,NULL /* reserved1,reserved2, etc */ }, { - "update_remove_htlc_delay", + "update_timedout_htlc", 8, PROTOBUF_C_LABEL_OPTIONAL, PROTOBUF_C_TYPE_MESSAGE, offsetof(Pkt, pkt_case), - offsetof(Pkt, update_remove_htlc_delay), - &update_remove_htlc_delay__descriptor, + offsetof(Pkt, update_timedout_htlc), + &update_timedout_htlc__descriptor, NULL, 0 | PROTOBUF_C_FIELD_FLAG_ONEOF, /* flags */ 0,NULL,NULL /* reserved1,reserved2, etc */ }, { - "update_decline_htlc", + "update_routefail_htlc", 9, PROTOBUF_C_LABEL_OPTIONAL, PROTOBUF_C_TYPE_MESSAGE, offsetof(Pkt, pkt_case), - offsetof(Pkt, update_decline_htlc), - &update_decline_htlc__descriptor, + offsetof(Pkt, update_routefail_htlc), + &update_routefail_htlc__descriptor, NULL, 0 | PROTOBUF_C_FIELD_FLAG_ONEOF, /* flags */ 0,NULL,NULL /* reserved1,reserved2, etc */ @@ -2396,11 +2410,11 @@ static const unsigned pkt__field_indices_by_name[] = { 2, /* field[2] = update_accept */ 1, /* field[1] = update_add_htlc */ 4, /* field[4] = update_complete */ - 5, /* field[5] = update_complete_htlc */ - 8, /* field[8] = update_decline_htlc */ - 6, /* field[6] = update_remove_htlc */ - 7, /* field[7] = update_remove_htlc_delay */ + 6, /* field[6] = update_complete_htlc */ + 5, /* field[5] = update_decline_htlc */ + 8, /* field[8] = update_routefail_htlc */ 3, /* field[3] = update_signature */ + 7, /* field[7] = update_timedout_htlc */ }; static const ProtobufCIntRange pkt__number_ranges[4 + 1] = { diff --git a/lightning.pb-c.h b/lightning.pb-c.h index 21b13bae0..e12eebb64 100644 --- a/lightning.pb-c.h +++ b/lightning.pb-c.h @@ -28,8 +28,8 @@ typedef struct _Update Update; typedef struct _UpdateAddHtlc UpdateAddHtlc; typedef struct _UpdateDeclineHtlc UpdateDeclineHtlc; typedef struct _UpdateCompleteHtlc UpdateCompleteHtlc; -typedef struct _UpdateRemoveHtlc UpdateRemoveHtlc; -typedef struct _UpdateRemoveHtlcDelay UpdateRemoveHtlcDelay; +typedef struct _UpdateTimedoutHtlc UpdateTimedoutHtlc; +typedef struct _UpdateRoutefailHtlc UpdateRoutefailHtlc; typedef struct _UpdateAccept UpdateAccept; typedef struct _UpdateSignature UpdateSignature; typedef struct _UpdateComplete UpdateComplete; @@ -302,7 +302,7 @@ typedef enum { } UpdateDeclineHtlc__ReasonCase; /* - * We can't do this HTLC, sorry. + * We can't do this HTLC, sorry (instead of update_accept) */ struct _UpdateDeclineHtlc { @@ -319,7 +319,7 @@ struct _UpdateDeclineHtlc /* - * Complete an HTLC + * Complete your HTLC: I have the R value, pay me! */ 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; /* @@ -353,26 +353,29 @@ struct _UpdateRemoveHtlc */ Sha256Hash *r_hash; }; -#define UPDATE_REMOVE_HTLC__INIT \ - { PROTOBUF_C_MESSAGE_INIT (&update_remove_htlc__descriptor) \ +#define UPDATE_TIMEDOUT_HTLC__INIT \ + { PROTOBUF_C_MESSAGE_INIT (&update_timedout_htlc__descriptor) \ , NULL, NULL } /* - * Respond to an HTLC remove request: not yet. - * Expect a remove_htlc later. + * Remove your HTLC: routing has failed upstream */ -struct _UpdateRemoveHtlcDelay +struct _UpdateRoutefailHtlc { ProtobufCMessage base; + /* + * Hash for which I will supply preimage to revoke this commitment tx. + */ + Sha256Hash *revocation_hash; /* * Hash for HTLC R value. */ Sha256Hash *r_hash; }; -#define UPDATE_REMOVE_HTLC_DELAY__INIT \ - { PROTOBUF_C_MESSAGE_INIT (&update_remove_htlc_delay__descriptor) \ - , NULL } +#define UPDATE_ROUTEFAIL_HTLC__INIT \ + { PROTOBUF_C_MESSAGE_INIT (&update_routefail_htlc__descriptor) \ + , NULL, NULL } /* @@ -493,10 +496,10 @@ typedef enum { PKT__PKT_UPDATE_ACCEPT = 3, PKT__PKT_UPDATE_SIGNATURE = 4, PKT__PKT_UPDATE_COMPLETE = 5, - PKT__PKT_UPDATE_COMPLETE_HTLC = 6, - PKT__PKT_UPDATE_REMOVE_HTLC = 7, - PKT__PKT_UPDATE_REMOVE_HTLC_DELAY = 8, - PKT__PKT_UPDATE_DECLINE_HTLC = 9, + PKT__PKT_UPDATE_DECLINE_HTLC = 6, + PKT__PKT_UPDATE_COMPLETE_HTLC = 7, + PKT__PKT_UPDATE_TIMEDOUT_HTLC = 8, + PKT__PKT_UPDATE_ROUTEFAIL_HTLC = 9, PKT__PKT_CLOSE = 401, PKT__PKT_CLOSE_COMPLETE = 402, PKT__PKT_ERROR = 1000, @@ -525,10 +528,10 @@ struct _Pkt UpdateAccept *update_accept; UpdateSignature *update_signature; UpdateComplete *update_complete; - UpdateCompleteHtlc *update_complete_htlc; - UpdateRemoveHtlc *update_remove_htlc; - UpdateRemoveHtlcDelay *update_remove_htlc_delay; UpdateDeclineHtlc *update_decline_htlc; + UpdateCompleteHtlc *update_complete_htlc; + UpdateTimedoutHtlc *update_timedout_htlc; + UpdateRoutefailHtlc *update_routefail_htlc; /* * Closing */ @@ -792,43 +795,43 @@ UpdateCompleteHtlc * void update_complete_htlc__free_unpacked (UpdateCompleteHtlc *message, ProtobufCAllocator *allocator); -/* UpdateRemoveHtlc methods */ -void update_remove_htlc__init - (UpdateRemoveHtlc *message); -size_t update_remove_htlc__get_packed_size - (const UpdateRemoveHtlc *message); -size_t update_remove_htlc__pack - (const UpdateRemoveHtlc *message, +/* UpdateTimedoutHtlc methods */ +void update_timedout_htlc__init + (UpdateTimedoutHtlc *message); +size_t update_timedout_htlc__get_packed_size + (const UpdateTimedoutHtlc *message); +size_t update_timedout_htlc__pack + (const UpdateTimedoutHtlc *message, uint8_t *out); -size_t update_remove_htlc__pack_to_buffer - (const UpdateRemoveHtlc *message, +size_t update_timedout_htlc__pack_to_buffer + (const UpdateTimedoutHtlc *message, ProtobufCBuffer *buffer); -UpdateRemoveHtlc * - update_remove_htlc__unpack +UpdateTimedoutHtlc * + update_timedout_htlc__unpack (ProtobufCAllocator *allocator, size_t len, const uint8_t *data); -void update_remove_htlc__free_unpacked - (UpdateRemoveHtlc *message, +void update_timedout_htlc__free_unpacked + (UpdateTimedoutHtlc *message, ProtobufCAllocator *allocator); -/* UpdateRemoveHtlcDelay methods */ -void update_remove_htlc_delay__init - (UpdateRemoveHtlcDelay *message); -size_t update_remove_htlc_delay__get_packed_size - (const UpdateRemoveHtlcDelay *message); -size_t update_remove_htlc_delay__pack - (const UpdateRemoveHtlcDelay *message, +/* UpdateRoutefailHtlc methods */ +void update_routefail_htlc__init + (UpdateRoutefailHtlc *message); +size_t update_routefail_htlc__get_packed_size + (const UpdateRoutefailHtlc *message); +size_t update_routefail_htlc__pack + (const UpdateRoutefailHtlc *message, uint8_t *out); -size_t update_remove_htlc_delay__pack_to_buffer - (const UpdateRemoveHtlcDelay *message, +size_t update_routefail_htlc__pack_to_buffer + (const UpdateRoutefailHtlc *message, ProtobufCBuffer *buffer); -UpdateRemoveHtlcDelay * - update_remove_htlc_delay__unpack +UpdateRoutefailHtlc * + update_routefail_htlc__unpack (ProtobufCAllocator *allocator, size_t len, const uint8_t *data); -void update_remove_htlc_delay__free_unpacked - (UpdateRemoveHtlcDelay *message, +void update_routefail_htlc__free_unpacked + (UpdateRoutefailHtlc *message, ProtobufCAllocator *allocator); /* UpdateAccept methods */ void update_accept__init @@ -1004,11 +1007,11 @@ typedef void (*UpdateDeclineHtlc_Closure) typedef void (*UpdateCompleteHtlc_Closure) (const UpdateCompleteHtlc *message, void *closure_data); -typedef void (*UpdateRemoveHtlc_Closure) - (const UpdateRemoveHtlc *message, +typedef void (*UpdateTimedoutHtlc_Closure) + (const UpdateTimedoutHtlc *message, void *closure_data); -typedef void (*UpdateRemoveHtlcDelay_Closure) - (const UpdateRemoveHtlcDelay *message, +typedef void (*UpdateRoutefailHtlc_Closure) + (const UpdateRoutefailHtlc *message, void *closure_data); typedef void (*UpdateAccept_Closure) (const UpdateAccept *message, @@ -1051,8 +1054,8 @@ extern const ProtobufCMessageDescriptor update__descriptor; extern const ProtobufCMessageDescriptor update_add_htlc__descriptor; extern const ProtobufCMessageDescriptor update_decline_htlc__descriptor; extern const ProtobufCMessageDescriptor update_complete_htlc__descriptor; -extern const ProtobufCMessageDescriptor update_remove_htlc__descriptor; -extern const ProtobufCMessageDescriptor update_remove_htlc_delay__descriptor; +extern const ProtobufCMessageDescriptor update_timedout_htlc__descriptor; +extern const ProtobufCMessageDescriptor update_routefail_htlc__descriptor; extern const ProtobufCMessageDescriptor update_accept__descriptor; extern const ProtobufCMessageDescriptor update_signature__descriptor; extern const ProtobufCMessageDescriptor update_complete__descriptor; diff --git a/lightning.proto b/lightning.proto index 8c0e51dbb..e4c89e6e8 100644 --- a/lightning.proto +++ b/lightning.proto @@ -123,7 +123,7 @@ message update_add_htlc { // 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 { oneof reason { 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 { // Hash for which I will supply preimage to revoke this commitment tx. required sha256_hash revocation_hash = 1; @@ -139,22 +139,23 @@ message update_complete_htlc { required sha256_hash r = 3; } -// Remove an HTLC -message update_remove_htlc { +// Remove my HTLC: it has timed out, before you got the R value. +message update_timedout_htlc { // Hash for which I will supply preimage to revoke this commitment tx. required sha256_hash revocation_hash = 1; // Hash for HTLC R value. required sha256_hash r_hash = 3; } -// Respond to an HTLC remove request: not yet. -// Expect a remove_htlc later. -message update_remove_htlc_delay { +// Remove your HTLC: routing has failed upstream +message update_routefail_htlc { + // Hash for which I will supply preimage to revoke this commitment tx. + required sha256_hash revocation_hash = 1; // 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 { // Signature for your new commitment tx. required signature sig = 1; @@ -211,10 +212,10 @@ message pkt { update_accept update_accept = 3; update_signature update_signature = 4; update_complete update_complete = 5; - update_complete_htlc update_complete_htlc = 6; - update_remove_htlc update_remove_htlc = 7; - update_remove_htlc_delay update_remove_htlc_delay = 8; - update_decline_htlc update_decline_htlc = 9; + update_decline_htlc update_decline_htlc = 6; + update_complete_htlc update_complete_htlc = 7; + update_timedout_htlc update_timedout_htlc = 8; + update_routefail_htlc update_routefail_htlc = 9; // Closing close_channel close = 401; close_channel_complete close_complete = 402; diff --git a/pkt.c b/pkt.c index e272bb0ff..2f3c7005f 100644 --- a/pkt.c +++ b/pkt.c @@ -174,17 +174,29 @@ struct pkt *update_htlc_complete_pkt(const tal_t *ctx, return to_pkt(ctx, PKT__PKT_UPDATE_COMPLETE_HTLC, &u); } - -struct pkt *update_htlc_remove_pkt(const tal_t *ctx, - const struct sha256 *revocation_hash, - const struct sha256 *htlc_rhash) + +struct pkt *update_htlc_timedout_pkt(const tal_t *ctx, + const struct sha256 *revocation_hash, + const struct sha256 *htlc_rhash) +{ + UpdateTimedoutHtlc u = UPDATE_TIMEDOUT_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_TIMEDOUT_HTLC, &u); +} + +struct pkt *update_htlc_routefail_pkt(const tal_t *ctx, + const struct sha256 *revocation_hash, + const struct sha256 *htlc_rhash) { - UpdateRemoveHtlc u = UPDATE_REMOVE_HTLC__INIT; + 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_REMOVE_HTLC, &u); + return to_pkt(ctx, PKT__PKT_UPDATE_ROUTEFAIL_HTLC, &u); } struct pkt *update_accept_pkt(const tal_t *ctx, diff --git a/pkt.h b/pkt.h index ef5e08160..9a6119f97 100644 --- a/pkt.h +++ b/pkt.h @@ -105,7 +105,7 @@ struct pkt *update_htlc_add_pkt(const tal_t *ctx, 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. * @revocation_hash: the revocation hash for the next commitment tx. * @rval: the r value for the HTLC @@ -115,15 +115,25 @@ struct pkt *update_htlc_complete_pkt(const tal_t *ctx, 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. * @revocation_hash: the revocation hash for the next commitment tx. * @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 *htlc_rhash); + /** * update_accept_pkt - create an update_accept message * @ctx: tal context to allocate off. diff --git a/test-cli/gather_updates.c b/test-cli/gather_updates.c index 089a4b8a5..7f5af8843 100644 --- a/test-cli/gather_updates.c +++ b/test-cli/gather_updates.c @@ -167,10 +167,10 @@ struct channel_state *gather_updates(const tal_t *ctx, our_rhash, their_rhash); break; - case PKT__PKT_UPDATE_REMOVE_HTLC: + case PKT__PKT_UPDATE_TIMEDOUT_HTLC: if (received) { n = find_htlc(&cstate->b, - pkt->update_remove_htlc->r_hash); + pkt->update_timedout_htlc->r_hash); if (n == tal_count(cstate->b.htlcs)) errx(1, "Unknown R hash in %s", *argv); 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); } else { n = find_htlc(&cstate->a, - pkt->update_remove_htlc->r_hash); + pkt->update_timedout_htlc->r_hash); if (n == tal_count(cstate->a.htlcs)) errx(1, "Unknown R hash in %s", *argv); amount = cstate->a.htlcs[n]->amount_msat; @@ -191,12 +191,43 @@ struct channel_state *gather_updates(const tal_t *ctx, (long long)amount, *argv); 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, + &old_our_rhash, &old_their_rhash, + our_rhash, their_rhash); + break; + case PKT__PKT_UPDATE_COMPLETE_HTLC: { struct sha256 r_hash, r_val; Sha256Hash *rh; diff --git a/test-cli/update-channel-htlc-remove.c b/test-cli/update-channel-htlc-remove.c index b71e97a62..fa34e1cd5 100644 --- a/test-cli/update-channel-htlc-remove.c +++ b/test-cli/update-channel-htlc-remove.c @@ -25,13 +25,16 @@ int main(int argc, char *argv[]) struct pkt *pkt; unsigned update_num; UpdateAddHtlc *u; + bool routefail = false; err_set_progname(argv[0]); opt_register_noarg("--help|-h", opt_usage_and_exit, " \n" - "Create a new HTLC remove message", + "Create a new HTLC (timedout) remove message", "Print this message."); + opt_register_noarg("--routefail", opt_set_bool, &routefail, + "Generate a routefail instead of timedout"); opt_register_version(); opt_parse(&argc, argv, opt_log_stderr_exit); @@ -53,7 +56,12 @@ int main(int argc, char *argv[]) sha256(&revocation_hash, 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))) err(1, "Writing out packet");