Skip to content

Commit

Permalink
common: remove peer_failed in favor of peer_failed_warn/peer_failed_err
Browse files Browse the repository at this point in the history
And make all the callers choose which one.  In general, I prefer warn,
which lets them reconnect and try again, however some places are either
stated that they must be errors in the spec itself, or in openingd
where we abandon the channel when we close the connection anyway.

Signed-off-by: Rusty Russell <[email protected]>
Changelog-Changed: Protocol: we now send warning messages and close the connection, except on unrecoverable errors.
  • Loading branch information
rustyrussell committed Feb 4, 2021
1 parent e6cefc4 commit f4ee41a
Show file tree
Hide file tree
Showing 9 changed files with 581 additions and 573 deletions.
433 changes: 199 additions & 234 deletions channeld/channeld.c

Large diffs are not rendered by default.

100 changes: 50 additions & 50 deletions closingd/closingd.c
Original file line number Diff line number Diff line change
Expand Up @@ -51,13 +51,13 @@ static struct bitcoin_tx *close_tx(const tal_t *ctx,
out_minus_fee[LOCAL] = out[LOCAL];
out_minus_fee[REMOTE] = out[REMOTE];
if (!amount_sat_sub(&out_minus_fee[opener], out[opener], fee))
peer_failed(pps, channel_id,
"Funder cannot afford fee %s (%s and %s)",
type_to_string(tmpctx, struct amount_sat, &fee),
type_to_string(tmpctx, struct amount_sat,
&out[LOCAL]),
type_to_string(tmpctx, struct amount_sat,
&out[REMOTE]));
peer_failed_warn(pps, channel_id,
"Funder cannot afford fee %s (%s and %s)",
type_to_string(tmpctx, struct amount_sat, &fee),
type_to_string(tmpctx, struct amount_sat,
&out[LOCAL]),
type_to_string(tmpctx, struct amount_sat,
&out[REMOTE]));

status_debug("Making close tx at = %s/%s fee %s",
type_to_string(tmpctx, struct amount_sat, &out[LOCAL]),
Expand All @@ -76,18 +76,18 @@ static struct bitcoin_tx *close_tx(const tal_t *ctx,
out_minus_fee[REMOTE],
dust_limit);
if (!tx)
peer_failed(pps, channel_id,
"Both outputs below dust limit:"
" funding = %s"
" fee = %s"
" dust_limit = %s"
" LOCAL = %s"
" REMOTE = %s",
type_to_string(tmpctx, struct amount_sat, &funding),
type_to_string(tmpctx, struct amount_sat, &fee),
type_to_string(tmpctx, struct amount_sat, &dust_limit),
type_to_string(tmpctx, struct amount_sat, &out[LOCAL]),
type_to_string(tmpctx, struct amount_sat, &out[REMOTE]));
peer_failed_err(pps, channel_id,
"Both outputs below dust limit:"
" funding = %s"
" fee = %s"
" dust_limit = %s"
" LOCAL = %s"
" REMOTE = %s",
type_to_string(tmpctx, struct amount_sat, &funding),
type_to_string(tmpctx, struct amount_sat, &fee),
type_to_string(tmpctx, struct amount_sat, &dust_limit),
type_to_string(tmpctx, struct amount_sat, &out[LOCAL]),
type_to_string(tmpctx, struct amount_sat, &out[REMOTE]));
return tx;
}

Expand Down Expand Up @@ -201,10 +201,10 @@ static void do_reconnect(struct per_peer_state *pps,
&next_remote_revocation_number,
&their_secret,
&next_commitment_point)) {
peer_failed(pps, channel_id,
"bad reestablish msg: %s %s",
peer_wire_name(fromwire_peektype(channel_reestablish)),
tal_hex(tmpctx, channel_reestablish));
peer_failed_warn(pps, channel_id,
"bad reestablish msg: %s %s",
peer_wire_name(fromwire_peektype(channel_reestablish)),
tal_hex(tmpctx, channel_reestablish));
}
status_debug("Got reestablish commit=%"PRIu64" revoke=%"PRIu64,
next_local_commitment_number,
Expand Down Expand Up @@ -360,9 +360,9 @@ receive_offer(struct per_peer_state *pps,
their_sig.sighash_type = SIGHASH_ALL;
if (!fromwire_closing_signed(msg, &their_channel_id,
&received_fee, &their_sig.s))
peer_failed(pps, channel_id,
"Expected closing_signed: %s",
tal_hex(tmpctx, msg));
peer_failed_warn(pps, channel_id,
"Expected closing_signed: %s",
tal_hex(tmpctx, msg));

/* BOLT #2:
*
Expand Down Expand Up @@ -412,17 +412,17 @@ receive_offer(struct per_peer_state *pps,
if (!trimmed
|| !check_tx_sig(trimmed, 0, NULL, funding_wscript,
&funding_pubkey[REMOTE], &their_sig)) {
peer_failed(pps, channel_id,
"Bad closing_signed signature for"
" %s (and trimmed version %s)",
type_to_string(tmpctx,
struct bitcoin_tx,
tx),
trimmed ?
type_to_string(tmpctx,
struct bitcoin_tx,
trimmed)
: "NONE");
peer_failed_warn(pps, channel_id,
"Bad closing_signed signature for"
" %s (and trimmed version %s)",
type_to_string(tmpctx,
struct bitcoin_tx,
tx),
trimmed ?
type_to_string(tmpctx,
struct bitcoin_tx,
trimmed)
: "NONE");
}
tx = trimmed;
}
Expand Down Expand Up @@ -507,10 +507,10 @@ adjust_offer(struct per_peer_state *pps, const struct channel_id *channel_id,

/* Within 1 satoshi? Agree. */
if (!amount_sat_add(&min_plus_one, feerange->min, AMOUNT_SAT(1)))
peer_failed(pps, channel_id,
"Fee offer %s min too large",
type_to_string(tmpctx, struct amount_sat,
&feerange->min));
peer_failed_warn(pps, channel_id,
"Fee offer %s min too large",
type_to_string(tmpctx, struct amount_sat,
&feerange->min));

if (amount_sat_greater_eq(min_plus_one, feerange->max))
return remote_offer;
Expand All @@ -524,15 +524,15 @@ adjust_offer(struct per_peer_state *pps, const struct channel_id *channel_id,

/* Max is below our minimum acceptable? */
if (!amount_sat_sub(&range_len, feerange->max, min_fee_to_accept))
peer_failed(pps, channel_id,
"Feerange %s-%s"
" below minimum acceptable %s",
type_to_string(tmpctx, struct amount_sat,
&feerange->min),
type_to_string(tmpctx, struct amount_sat,
&feerange->max),
type_to_string(tmpctx, struct amount_sat,
&min_fee_to_accept));
peer_failed_warn(pps, channel_id,
"Feerange %s-%s"
" below minimum acceptable %s",
type_to_string(tmpctx, struct amount_sat,
&feerange->min),
type_to_string(tmpctx, struct amount_sat,
&feerange->max),
type_to_string(tmpctx, struct amount_sat,
&min_fee_to_accept));

if (fee_negotiation_step_unit ==
CLOSING_FEE_NEGOTIATION_STEP_UNIT_SATOSHI) {
Expand Down
60 changes: 43 additions & 17 deletions common/peer_failed.c
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
#include <assert.h>
#include <ccan/breakpoint/breakpoint.h>
#include <ccan/tal/str/str.h>
#include <common/crypto_sync.h>
Expand All @@ -24,34 +25,59 @@ peer_fatal_continue(const u8 *msg TAKES, const struct per_peer_state *pps)
}

/* We only support one channel per peer anyway */
void peer_failed(struct per_peer_state *pps,
const struct channel_id *channel_id,
const char *fmt, ...)
static void NORETURN
peer_failed(struct per_peer_state *pps,
bool warn,
const struct channel_id *channel_id,
const char *desc)
{
va_list ap;
const char *desc;
u8 *msg, *err;

va_start(ap, fmt);
desc = tal_vfmt(NULL, fmt, ap);
va_end(ap);
u8 *msg;

/* Tell peer the error. */
err = towire_errorfmt(desc, channel_id, "%s", desc);
sync_crypto_write(pps, err);
if (warn) {
msg = towire_warningfmt(desc, channel_id, "%s", desc);
} else {
msg = towire_errorfmt(desc, channel_id, "%s", desc);
}
sync_crypto_write(pps, msg);

/* Tell master the error so it can re-xmit. */
msg = towire_status_peer_error(NULL, channel_id,
desc,
/* all-channels errors should not close channels */
channel_id_is_all(channel_id),
warn,
pps,
err);
msg);
peer_billboard(true, desc);
tal_free(desc);
peer_fatal_continue(take(msg), pps);
}

void peer_failed_warn(struct per_peer_state *pps,
const struct channel_id *channel_id,
const char *fmt, ...)
{
va_list ap;
const char *desc;

va_start(ap, fmt);
desc = tal_vfmt(tmpctx, fmt, ap);
va_end(ap);

peer_failed(pps, true, channel_id, desc);
}

void peer_failed_err(struct per_peer_state *pps,
const struct channel_id *channel_id,
const char *fmt, ...)
{
va_list ap;
const char *desc;

va_start(ap, fmt);
desc = tal_vfmt(tmpctx, fmt, ap);
va_end(ap);

peer_failed(pps, false, channel_id, desc);
}

/* We're failing because peer sent us an error/warning message */
void peer_failed_received_errmsg(struct per_peer_state *pps,
const char *desc,
Expand Down
21 changes: 16 additions & 5 deletions common/peer_failed.h
Original file line number Diff line number Diff line change
Expand Up @@ -8,14 +8,25 @@ struct channel_id;
struct per_peer_state;

/**
* peer_failed - Exit with error for peer.
* peer_failed_warn - Send a warning msg and close the connection.
* @pps: the per-peer state.
* @channel_id: channel with error, or NULL for all.
* @channel_id: channel with error, or NULL for no particular channel.
* @fmt...: format as per status_failed(STATUS_FAIL_PEER_BAD)
*/
void peer_failed(struct per_peer_state *pps,
const struct channel_id *channel_id,
const char *fmt, ...)
void peer_failed_warn(struct per_peer_state *pps,
const struct channel_id *channel_id,
const char *fmt, ...)
PRINTF_FMT(3,4) NORETURN;

/**
* peer_failed_err - Send a warning msg and close the channel.
* @pps: the per-peer state.
* @channel_id: channel with error.
* @fmt...: format as per status_failed(STATUS_FAIL_PEER_BAD)
*/
void peer_failed_err(struct per_peer_state *pps,
const struct channel_id *channel_id,
const char *fmt, ...)
PRINTF_FMT(3,4) NORETURN;

/* We're failing because peer sent us an error message: NULL
Expand Down
Loading

0 comments on commit f4ee41a

Please sign in to comment.