mirror of
https://github.com/aljazceru/lightning.git
synced 2026-02-02 04:34:20 +01:00
protocol: add TLV for shutdown message, use 100 as "wrong_funding" outpoint.
Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
This commit is contained in:
@@ -748,7 +748,9 @@ static void maybe_send_shutdown(struct peer *peer)
|
||||
* over us */
|
||||
send_channel_update(peer, ROUTING_FLAGS_DISABLED);
|
||||
|
||||
msg = towire_shutdown(NULL, &peer->channel_id, peer->final_scriptpubkey);
|
||||
/* FIXME: send wrong_funding */
|
||||
msg = towire_shutdown(NULL, &peer->channel_id, peer->final_scriptpubkey,
|
||||
NULL);
|
||||
sync_crypto_write(peer->pps, take(msg));
|
||||
peer->send_shutdown = false;
|
||||
peer->shutdown_sent[LOCAL] = true;
|
||||
@@ -1633,11 +1635,13 @@ static void handle_peer_shutdown(struct peer *peer, const u8 *shutdown)
|
||||
{
|
||||
struct channel_id channel_id;
|
||||
u8 *scriptpubkey;
|
||||
struct tlv_shutdown_tlvs *tlvs = tlv_shutdown_tlvs_new(tmpctx);
|
||||
|
||||
/* Disable the channel. */
|
||||
send_channel_update(peer, ROUTING_FLAGS_DISABLED);
|
||||
|
||||
if (!fromwire_shutdown(tmpctx, shutdown, &channel_id, &scriptpubkey))
|
||||
if (!fromwire_shutdown(tmpctx, shutdown, &channel_id, &scriptpubkey,
|
||||
tlvs))
|
||||
peer_failed_warn(peer->pps, &peer->channel_id,
|
||||
"Bad shutdown %s", tal_hex(peer, shutdown));
|
||||
|
||||
@@ -1659,6 +1663,16 @@ static void handle_peer_shutdown(struct peer *peer, const u8 *shutdown)
|
||||
tal_hex(peer, scriptpubkey),
|
||||
tal_hex(peer, peer->remote_upfront_shutdown_script));
|
||||
|
||||
if (tlvs->wrong_funding) {
|
||||
if (!feature_negotiated(peer->our_features,
|
||||
peer->their_features,
|
||||
OPT_SHUTDOWN_WRONG_FUNDING))
|
||||
peer_failed_warn(peer->pps, &peer->channel_id,
|
||||
"wrong_funding shutdown needs"
|
||||
" feature %u",
|
||||
OPT_SHUTDOWN_WRONG_FUNDING);
|
||||
}
|
||||
|
||||
/* Tell master: we don't have to wait because on reconnect other end
|
||||
* will re-send anyway. */
|
||||
wire_sync_write(MASTER_FD,
|
||||
|
||||
@@ -218,7 +218,8 @@ static void do_reconnect(struct per_peer_state *pps,
|
||||
* - if it has sent a previous `shutdown`:
|
||||
* - MUST retransmit `shutdown`.
|
||||
*/
|
||||
msg = towire_shutdown(NULL, channel_id, final_scriptpubkey);
|
||||
/* FIXME: retransmit wrong_funding */
|
||||
msg = towire_shutdown(NULL, channel_id, final_scriptpubkey, NULL);
|
||||
sync_crypto_write(pps, take(msg));
|
||||
|
||||
/* BOLT #2:
|
||||
|
||||
@@ -376,8 +376,9 @@ static void send_shutdown(struct state *state, const u8 *final_scriptpubkey)
|
||||
{
|
||||
u8 *msg;
|
||||
|
||||
/* FIXME: send wrong_funding */
|
||||
msg = towire_shutdown(NULL, &state->channel_id,
|
||||
final_scriptpubkey);
|
||||
final_scriptpubkey, NULL);
|
||||
sync_crypto_write(state->pps, take(msg));
|
||||
state->shutdown_sent[LOCAL] = true;
|
||||
}
|
||||
@@ -386,8 +387,9 @@ static void handle_peer_shutdown(struct state *state, u8 *msg)
|
||||
{
|
||||
u8 *scriptpubkey;
|
||||
struct channel_id cid;
|
||||
struct tlv_shutdown_tlvs *tlvs = tlv_shutdown_tlvs_new(msg);
|
||||
|
||||
if (!fromwire_shutdown(tmpctx, msg, &cid, &scriptpubkey))
|
||||
if (!fromwire_shutdown(tmpctx, msg, &cid, &scriptpubkey, tlvs))
|
||||
open_err_warn(state, "Bad shutdown %s", tal_hex(msg, msg));
|
||||
|
||||
if (tal_count(state->upfront_shutdown_script[REMOTE])
|
||||
@@ -400,6 +402,13 @@ static void handle_peer_shutdown(struct state *state, u8 *msg)
|
||||
tal_hex(state,
|
||||
state->upfront_shutdown_script[REMOTE]));
|
||||
|
||||
/* @niftynei points out that negotiated this together, so this
|
||||
* hack is not required (or safe!). */
|
||||
if (tlvs->wrong_funding)
|
||||
open_err_warn(state,
|
||||
"wrong_funding shutdown"
|
||||
" invalid for dual-funding");
|
||||
|
||||
wire_sync_write(REQ_FD,
|
||||
take(towire_dualopend_got_shutdown(NULL,
|
||||
scriptpubkey)));
|
||||
|
||||
13
wire/extracted_peer-shutdown-wrong_funding.patch
Normal file
13
wire/extracted_peer-shutdown-wrong_funding.patch
Normal file
@@ -0,0 +1,13 @@
|
||||
--- wire/peer_wire.csv
|
||||
+++ wire/peer_wire.csv
|
||||
@@ -90,6 +90,10 @@ msgtype,shutdown,38
|
||||
msgdata,shutdown,channel_id,channel_id,
|
||||
msgdata,shutdown,len,u16,
|
||||
msgdata,shutdown,scriptpubkey,byte,len
|
||||
+msgdata,shutdown,tlvs,shutdown_tlvs,
|
||||
+tlvtype,shutdown_tlvs,wrong_funding,100
|
||||
+tlvdata,shutdown_tlvs,wrong_funding,txid,sha256,
|
||||
+tlvdata,shutdown_tlvs,wrong_funding,outnum,u32,
|
||||
msgtype,closing_signed,39
|
||||
msgdata,closing_signed,channel_id,channel_id,
|
||||
msgdata,closing_signed,fee_satoshis,u64,
|
||||
35
wire/peer_printgen.c
generated
35
wire/peer_printgen.c
generated
@@ -362,6 +362,34 @@ static const struct tlv_print_record_type print_tlvs_accept_channel_tlvs[] = {
|
||||
{ 0, printwire_tlv_accept_channel_tlvs_upfront_shutdown_script },
|
||||
};
|
||||
|
||||
static void printwire_tlv_shutdown_tlvs_wrong_funding(const char *fieldname, const u8 **cursor, size_t *plen)
|
||||
{
|
||||
printf("(msg_name=%s)\n", "wrong_funding");
|
||||
|
||||
printf("txid=");
|
||||
struct bitcoin_txid txid;
|
||||
fromwire_bitcoin_txid(cursor, plen, &txid);
|
||||
|
||||
printwire_bitcoin_txid(tal_fmt(NULL, "%s.txid", fieldname), &txid);
|
||||
if (!*cursor) {
|
||||
printf("**TRUNCATED**\n");
|
||||
return;
|
||||
}
|
||||
printf("outnum=");
|
||||
u32 outnum = fromwire_u32(cursor, plen);
|
||||
|
||||
printwire_u32(tal_fmt(NULL, "%s.outnum", fieldname), &outnum);
|
||||
if (!*cursor) {
|
||||
printf("**TRUNCATED**\n");
|
||||
return;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
static const struct tlv_print_record_type print_tlvs_shutdown_tlvs[] = {
|
||||
{ 100, printwire_tlv_shutdown_tlvs_wrong_funding },
|
||||
};
|
||||
|
||||
static void printwire_tlv_query_short_channel_ids_tlvs_query_flags(const char *fieldname, const u8 **cursor, size_t *plen)
|
||||
{
|
||||
printf("(msg_name=%s)\n", "query_flags");
|
||||
@@ -1088,6 +1116,8 @@ void printwire_shutdown(const char *fieldname, const u8 *cursor)
|
||||
printf("**TRUNCATED**\n");
|
||||
return;
|
||||
}
|
||||
printf("tlvs=");
|
||||
printwire_tlvs(tal_fmt(NULL, "%s.tlvs", fieldname), &cursor, &plen, print_tlvs_shutdown_tlvs, ARRAY_SIZE(print_tlvs_shutdown_tlvs));
|
||||
|
||||
|
||||
if (plen != 0)
|
||||
@@ -2117,6 +2147,9 @@ void printpeer_wire_tlv_message(const char *tlv_name, const u8 *msg) {
|
||||
if (strcmp(tlv_name, "accept_channel_tlvs") == 0) {
|
||||
printwire_tlvs(tlv_name, &msg, &plen, print_tlvs_accept_channel_tlvs, ARRAY_SIZE(print_tlvs_accept_channel_tlvs));
|
||||
}
|
||||
if (strcmp(tlv_name, "shutdown_tlvs") == 0) {
|
||||
printwire_tlvs(tlv_name, &msg, &plen, print_tlvs_shutdown_tlvs, ARRAY_SIZE(print_tlvs_shutdown_tlvs));
|
||||
}
|
||||
if (strcmp(tlv_name, "query_short_channel_ids_tlvs") == 0) {
|
||||
printwire_tlvs(tlv_name, &msg, &plen, print_tlvs_query_short_channel_ids_tlvs, ARRAY_SIZE(print_tlvs_query_short_channel_ids_tlvs));
|
||||
}
|
||||
@@ -2130,4 +2163,4 @@ void printpeer_wire_tlv_message(const char *tlv_name, const u8 *msg) {
|
||||
printwire_tlvs(tlv_name, &msg, &plen, print_tlvs_onion_message_tlvs, ARRAY_SIZE(print_tlvs_onion_message_tlvs));
|
||||
}
|
||||
}
|
||||
// SHA256STAMP:1b0c5319cd9ab8c0281132a4c64ca51ecd9ee0158c7f645e102f401ac64ca439
|
||||
// SHA256STAMP:c7056cc0ec6b038e425e0800dce339f6ba38a18f14d1b33271656de218052ee2
|
||||
|
||||
2
wire/peer_printgen.h
generated
2
wire/peer_printgen.h
generated
@@ -74,4 +74,4 @@ void printwire_onion_message(const char *fieldname, const u8 *cursor);
|
||||
void printwire_channel_update_checksums(const char *fieldname, const u8 **cursor, size_t *plen);
|
||||
void printwire_channel_update_timestamps(const char *fieldname, const u8 **cursor, size_t *plen);
|
||||
#endif /* LIGHTNING_WIRE_PEER_PRINTGEN_H */
|
||||
// SHA256STAMP:1b0c5319cd9ab8c0281132a4c64ca51ecd9ee0158c7f645e102f401ac64ca439
|
||||
// SHA256STAMP:c7056cc0ec6b038e425e0800dce339f6ba38a18f14d1b33271656de218052ee2
|
||||
|
||||
@@ -90,6 +90,10 @@ msgtype,shutdown,38
|
||||
msgdata,shutdown,channel_id,channel_id,
|
||||
msgdata,shutdown,len,u16,
|
||||
msgdata,shutdown,scriptpubkey,byte,len
|
||||
msgdata,shutdown,tlvs,shutdown_tlvs,
|
||||
tlvtype,shutdown_tlvs,wrong_funding,100
|
||||
tlvdata,shutdown_tlvs,wrong_funding,txid,sha256,
|
||||
tlvdata,shutdown_tlvs,wrong_funding,outnum,u32,
|
||||
msgtype,closing_signed,39
|
||||
msgdata,closing_signed,channel_id,channel_id,
|
||||
msgdata,closing_signed,fee_satoshis,u64,
|
||||
|
||||
|
65
wire/peer_wiregen.c
generated
65
wire/peer_wiregen.c
generated
@@ -504,6 +504,63 @@ bool accept_channel_tlvs_is_valid(const struct tlv_accept_channel_tlvs *record,
|
||||
}
|
||||
|
||||
|
||||
struct tlv_shutdown_tlvs *tlv_shutdown_tlvs_new(const tal_t *ctx)
|
||||
{
|
||||
/* Initialize everything to NULL. (Quiet, C pedants!) */
|
||||
struct tlv_shutdown_tlvs *inst = talz(ctx, struct tlv_shutdown_tlvs);
|
||||
|
||||
/* Initialized the fields to an empty array. */
|
||||
inst->fields = tal_arr(inst, struct tlv_field, 0);
|
||||
return inst;
|
||||
}
|
||||
|
||||
/* SHUTDOWN_TLVS MSG: wrong_funding */
|
||||
static u8 *towire_tlv_shutdown_tlvs_wrong_funding(const tal_t *ctx, const void *vrecord)
|
||||
{
|
||||
const struct tlv_shutdown_tlvs *r = vrecord;
|
||||
u8 *ptr;
|
||||
|
||||
if (!r->wrong_funding)
|
||||
return NULL;
|
||||
|
||||
|
||||
ptr = tal_arr(ctx, u8, 0);
|
||||
|
||||
towire_bitcoin_txid(&ptr, &r->wrong_funding->txid);
|
||||
|
||||
towire_u32(&ptr, r->wrong_funding->outnum);
|
||||
return ptr;
|
||||
}
|
||||
static void fromwire_tlv_shutdown_tlvs_wrong_funding(const u8 **cursor, size_t *plen, void *vrecord)
|
||||
{
|
||||
struct tlv_shutdown_tlvs *r = vrecord;
|
||||
|
||||
r->wrong_funding = tal(r, struct tlv_shutdown_tlvs_wrong_funding);
|
||||
fromwire_bitcoin_txid(cursor, plen, &r->wrong_funding->txid);
|
||||
r->wrong_funding->outnum = fromwire_u32(cursor, plen);
|
||||
}
|
||||
|
||||
static const struct tlv_record_type tlvs_shutdown_tlvs[] = {
|
||||
{ 100, towire_tlv_shutdown_tlvs_wrong_funding, fromwire_tlv_shutdown_tlvs_wrong_funding },
|
||||
};
|
||||
|
||||
void towire_shutdown_tlvs(u8 **pptr, const struct tlv_shutdown_tlvs *record)
|
||||
{
|
||||
towire_tlv(pptr, tlvs_shutdown_tlvs, 1, record);
|
||||
}
|
||||
|
||||
|
||||
bool fromwire_shutdown_tlvs(const u8 **cursor, size_t *max, struct tlv_shutdown_tlvs *record)
|
||||
{
|
||||
return fromwire_tlv(cursor, max, tlvs_shutdown_tlvs, 1, record, &record->fields);
|
||||
}
|
||||
|
||||
bool shutdown_tlvs_is_valid(const struct tlv_shutdown_tlvs *record, size_t *err_index)
|
||||
{
|
||||
return tlv_fields_valid(record->fields, err_index);
|
||||
}
|
||||
|
||||
|
||||
struct tlv_query_short_channel_ids_tlvs *tlv_query_short_channel_ids_tlvs_new(const tal_t *ctx)
|
||||
{
|
||||
/* Initialize everything to NULL. (Quiet, C pedants!) */
|
||||
@@ -1094,7 +1151,7 @@ bool fromwire_funding_locked(const void *p, struct channel_id *channel_id, struc
|
||||
}
|
||||
|
||||
/* WIRE: SHUTDOWN */
|
||||
u8 *towire_shutdown(const tal_t *ctx, const struct channel_id *channel_id, const u8 *scriptpubkey)
|
||||
u8 *towire_shutdown(const tal_t *ctx, const struct channel_id *channel_id, const u8 *scriptpubkey, const struct tlv_shutdown_tlvs *tlvs)
|
||||
{
|
||||
u16 len = tal_count(scriptpubkey);
|
||||
u8 *p = tal_arr(ctx, u8, 0);
|
||||
@@ -1103,10 +1160,11 @@ u8 *towire_shutdown(const tal_t *ctx, const struct channel_id *channel_id, const
|
||||
towire_channel_id(&p, channel_id);
|
||||
towire_u16(&p, len);
|
||||
towire_u8_array(&p, scriptpubkey, len);
|
||||
towire_shutdown_tlvs(&p, tlvs);
|
||||
|
||||
return memcheck(p, tal_count(p));
|
||||
}
|
||||
bool fromwire_shutdown(const tal_t *ctx, const void *p, struct channel_id *channel_id, u8 **scriptpubkey)
|
||||
bool fromwire_shutdown(const tal_t *ctx, const void *p, struct channel_id *channel_id, u8 **scriptpubkey, struct tlv_shutdown_tlvs *tlvs)
|
||||
{
|
||||
u16 len;
|
||||
|
||||
@@ -1120,6 +1178,7 @@ bool fromwire_shutdown(const tal_t *ctx, const void *p, struct channel_id *chann
|
||||
// 2nd case scriptpubkey
|
||||
*scriptpubkey = len ? tal_arr(ctx, u8, len) : NULL;
|
||||
fromwire_u8_array(&cursor, &plen, *scriptpubkey, len);
|
||||
fromwire_shutdown_tlvs(&cursor, &plen, tlvs);
|
||||
return cursor != NULL;
|
||||
}
|
||||
|
||||
@@ -1749,4 +1808,4 @@ bool fromwire_channel_update_option_channel_htlc_max(const void *p, secp256k1_ec
|
||||
*htlc_maximum_msat = fromwire_amount_msat(&cursor, &plen);
|
||||
return cursor != NULL;
|
||||
}
|
||||
// SHA256STAMP:1b0c5319cd9ab8c0281132a4c64ca51ecd9ee0158c7f645e102f401ac64ca439
|
||||
// SHA256STAMP:c7056cc0ec6b038e425e0800dce339f6ba38a18f14d1b33271656de218052ee2
|
||||
|
||||
55
wire/peer_wiregen.h
generated
55
wire/peer_wiregen.h
generated
@@ -73,6 +73,10 @@ struct tlv_n1_tlv3 {
|
||||
struct amount_msat amount_msat_1;
|
||||
struct amount_msat amount_msat_2;
|
||||
};
|
||||
struct tlv_shutdown_tlvs_wrong_funding {
|
||||
struct bitcoin_txid txid;
|
||||
u32 outnum;
|
||||
};
|
||||
struct tlv_query_short_channel_ids_tlvs_query_flags {
|
||||
u8 encoding_type;
|
||||
u8 *encoded_query_flags;
|
||||
@@ -125,6 +129,14 @@ struct tlv_accept_channel_tlvs {
|
||||
* tlv_field entries above to save on memory. */
|
||||
u8 *upfront_shutdown_script;
|
||||
};
|
||||
struct tlv_shutdown_tlvs {
|
||||
/* Raw fields including unknown ones. */
|
||||
struct tlv_field *fields;
|
||||
|
||||
/* TODO The following explicit fields could just point into the
|
||||
* tlv_field entries above to save on memory. */
|
||||
struct tlv_shutdown_tlvs_wrong_funding *wrong_funding;
|
||||
};
|
||||
struct tlv_query_short_channel_ids_tlvs {
|
||||
/* Raw fields including unknown ones. */
|
||||
struct tlv_field *fields;
|
||||
@@ -368,6 +380,43 @@ void towire_accept_channel_tlvs(u8 **pptr, const struct tlv_accept_channel_tlvs
|
||||
bool accept_channel_tlvs_is_valid(const struct tlv_accept_channel_tlvs *record,
|
||||
size_t *err_index);
|
||||
|
||||
struct tlv_shutdown_tlvs *tlv_shutdown_tlvs_new(const tal_t *ctx);
|
||||
|
||||
/**
|
||||
* Deserialize a TLV stream for the shutdown_tlvs namespace.
|
||||
*
|
||||
* This function will parse any TLV stream, as long as the type, length and
|
||||
* value fields are formatted correctly. Fields that are not known in the
|
||||
* current namespace are stored in the `fields` member. Validity can be
|
||||
* checked using shutdown_tlvs_is_valid.
|
||||
*/
|
||||
bool fromwire_shutdown_tlvs(const u8 **cursor, size_t *max,
|
||||
struct tlv_shutdown_tlvs * record);
|
||||
|
||||
/**
|
||||
* Serialize a TLV stream for the shutdown_tlvs namespace.
|
||||
*
|
||||
* This function only considers known fields from the shutdown_tlvs namespace,
|
||||
* and will ignore any fields that may be stored in the `fields` member. This
|
||||
* ensures that the resulting stream is valid according to
|
||||
* `shutdown_tlvs_is_valid`.
|
||||
*/
|
||||
void towire_shutdown_tlvs(u8 **pptr, const struct tlv_shutdown_tlvs *record);
|
||||
|
||||
/**
|
||||
* Check that the TLV stream is valid.
|
||||
*
|
||||
* Enforces the followin validity rules:
|
||||
* - Types must be in monotonic non-repeating order
|
||||
* - We must understand all even types
|
||||
*
|
||||
* Returns false if an error was detected, otherwise returns true. If err_index
|
||||
* is non-null and we detect an error it is set to the index of the first error
|
||||
* detected.
|
||||
*/
|
||||
bool shutdown_tlvs_is_valid(const struct tlv_shutdown_tlvs *record,
|
||||
size_t *err_index);
|
||||
|
||||
struct tlv_query_short_channel_ids_tlvs *tlv_query_short_channel_ids_tlvs_new(const tal_t *ctx);
|
||||
|
||||
/**
|
||||
@@ -565,8 +614,8 @@ u8 *towire_funding_locked(const tal_t *ctx, const struct channel_id *channel_id,
|
||||
bool fromwire_funding_locked(const void *p, struct channel_id *channel_id, struct pubkey *next_per_commitment_point);
|
||||
|
||||
/* WIRE: SHUTDOWN */
|
||||
u8 *towire_shutdown(const tal_t *ctx, const struct channel_id *channel_id, const u8 *scriptpubkey);
|
||||
bool fromwire_shutdown(const tal_t *ctx, const void *p, struct channel_id *channel_id, u8 **scriptpubkey);
|
||||
u8 *towire_shutdown(const tal_t *ctx, const struct channel_id *channel_id, const u8 *scriptpubkey, const struct tlv_shutdown_tlvs *tlvs);
|
||||
bool fromwire_shutdown(const tal_t *ctx, const void *p, struct channel_id *channel_id, u8 **scriptpubkey, struct tlv_shutdown_tlvs *tlvs);
|
||||
|
||||
/* WIRE: CLOSING_SIGNED */
|
||||
u8 *towire_closing_signed(const tal_t *ctx, const struct channel_id *channel_id, struct amount_sat fee_satoshis, const secp256k1_ecdsa_signature *signature);
|
||||
@@ -650,4 +699,4 @@ bool fromwire_channel_update_option_channel_htlc_max(const void *p, secp256k1_ec
|
||||
|
||||
|
||||
#endif /* LIGHTNING_WIRE_PEER_WIREGEN_H */
|
||||
// SHA256STAMP:1b0c5319cd9ab8c0281132a4c64ca51ecd9ee0158c7f645e102f401ac64ca439
|
||||
// SHA256STAMP:c7056cc0ec6b038e425e0800dce339f6ba38a18f14d1b33271656de218052ee2
|
||||
|
||||
@@ -634,7 +634,8 @@ static void *towire_struct_shutdown(const tal_t *ctx,
|
||||
{
|
||||
return towire_shutdown(ctx,
|
||||
&s->channel_id,
|
||||
s->scriptpubkey);
|
||||
s->scriptpubkey,
|
||||
NULL);
|
||||
}
|
||||
|
||||
static struct msg_shutdown *fromwire_struct_shutdown(const tal_t *ctx, const void *p)
|
||||
@@ -642,8 +643,9 @@ static struct msg_shutdown *fromwire_struct_shutdown(const tal_t *ctx, const voi
|
||||
struct msg_shutdown *s = tal(ctx, struct msg_shutdown);
|
||||
|
||||
if (!fromwire_shutdown(s, p,
|
||||
&s->channel_id,
|
||||
&s->scriptpubkey))
|
||||
&s->channel_id,
|
||||
&s->scriptpubkey,
|
||||
NULL))
|
||||
return tal_free(s);
|
||||
return s;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user