core-lightning/common/read_peer_msg.c
Rusty Russell 2526e804f7 doc: big BOLT update to incorporate warnings language.
We do this (send warnings) in almost all cases anyway, so mainly this
is a textual update, but there are some changes:

1. Send ERROR not WARNING if they send a malformed commitment secret.
2. Send WARNING not ERROR if they get the shutdown_scriptpubkey wrong (vs upfront)
3. Send WARNING not ERROR if they send a bad shutdown_scriptpubkey (e.g. p2pkh in future)
4. Rename some vars 'err' to 'warn' to make it clear we send a warning.

This means test_option_upfront_shutdown_script can be made reliable, too,
and it now warns and doesn't automatically close channel.

Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
2022-04-02 09:40:18 +10:30

91 lines
2.4 KiB
C

#include "config.h"
#include <assert.h>
#include <bitcoin/chainparams.h>
#include <common/peer_failed.h>
#include <common/peer_io.h>
#include <common/per_peer_state.h>
#include <common/ping.h>
#include <common/read_peer_msg.h>
#include <common/status.h>
#include <common/wire_error.h>
#include <errno.h>
#include <wire/peer_wire.h>
#include <wire/wire_sync.h>
bool is_peer_error(const tal_t *ctx, const u8 *msg,
const struct channel_id *channel_id,
char **desc, bool *warning)
{
struct channel_id err_chanid;
if (fromwire_peektype(msg) == WIRE_ERROR)
*warning = false;
else if (fromwire_peektype(msg) == WIRE_WARNING)
*warning = true;
else
return false;
*desc = sanitize_error(ctx, msg, &err_chanid);
/* BOLT #1:
*
* The channel is referred to by `channel_id`, unless `channel_id` is
* 0 (i.e. all bytes are 0), in which case it refers to all channels.
* ...
* The receiving node:
* - upon receiving `error`:
* - if `channel_id` is all zero:
* - MUST fail all channels with the sending node.
* - otherwise:
* - MUST fail the channel referred to by `channel_id`, if that channel is with the sending node.
* - upon receiving `warning`:
* - SHOULD log the message for later diagnosis.
* - MAY disconnect.
* - MAY reconnect after some delay to retry.
* - MAY attempt `shutdown` if permitted at this point.
* - if no existing channel is referred to by `channel_id`:
* - MUST ignore the message.
*/
/* FIXME: We don't actually free all channels at once, they'll
* have to error each in turn. */
if (!channel_id_is_all(&err_chanid)
&& !channel_id_eq(&err_chanid, channel_id))
*desc = tal_free(*desc);
return true;
}
bool is_wrong_channel(const u8 *msg, const struct channel_id *expected,
struct channel_id *actual)
{
if (!expected)
return false;
if (!extract_channel_id(msg, actual))
return false;
return !channel_id_eq(expected, actual);
}
bool handle_peer_error(struct per_peer_state *pps,
const struct channel_id *channel_id,
const u8 *msg TAKES)
{
char *err;
bool warning;
if (is_peer_error(tmpctx, msg, channel_id, &err, &warning)) {
/* Ignore unknown channel errors. */
if (!err) {
if (taken(msg))
tal_free(msg);
return true;
}
/* We hang up when a warning is received. */
peer_failed_received_errmsg(pps, err, channel_id, warning);
}
return false;
}