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:
Rusty Russell
2021-03-15 14:10:44 +10:30
parent cc6d2afe21
commit 30145209a9
10 changed files with 200 additions and 16 deletions

View File

@@ -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,

View File

@@ -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:

View File

@@ -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)));

View 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
View File

@@ -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
View File

@@ -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

View File

@@ -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,
1 msgtype,init,16
90 msgdata,shutdown,channel_id,channel_id,
91 msgdata,shutdown,len,u16,
92 msgdata,shutdown,scriptpubkey,byte,len
93 msgdata,shutdown,tlvs,shutdown_tlvs,
94 tlvtype,shutdown_tlvs,wrong_funding,100
95 tlvdata,shutdown_tlvs,wrong_funding,txid,sha256,
96 tlvdata,shutdown_tlvs,wrong_funding,outnum,u32,
97 msgtype,closing_signed,39
98 msgdata,closing_signed,channel_id,channel_id,
99 msgdata,closing_signed,fee_satoshis,u64,

65
wire/peer_wiregen.c generated
View File

@@ -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
View File

@@ -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

View File

@@ -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;
}