Browse Source

openingd: handle ERROR packets (if other end fails negotiation).

Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
ppa-0.6.1
Rusty Russell 7 years ago
parent
commit
97434d9c4a
  1. 57
      openingd/opening.c

57
openingd/opening.c

@ -66,7 +66,8 @@ struct state {
};
/* For negotiation failures: we can still gossip with client. */
static void negotiation_failed(struct state *state, const char *fmt, ...)
static void negotiation_failed(struct state *state, bool send_error,
const char *fmt, ...)
{
va_list ap;
const char *errmsg;
@ -79,9 +80,12 @@ static void negotiation_failed(struct state *state, const char *fmt, ...)
/* Make sure it's correct length for towire_. */
tal_resize(&errmsg, strlen(errmsg)+1);
/* Tell peer we're bailing on this channel. */
msg = towire_errorfmt(errmsg, &state->channel_id, "%s", errmsg);
sync_crypto_write(&state->cs, PEER_FD, take(msg));
/* We don't send error in response to their error packet. */
if (send_error) {
/* Tell peer we're bailing on this channel. */
msg = towire_errorfmt(errmsg, &state->channel_id, "%s", errmsg);
sync_crypto_write(&state->cs, PEER_FD, take(msg));
}
/* Tell master we should return to gossiping. */
msg = towire_opening_negotiation_failed(state, &state->cs,
@ -105,7 +109,7 @@ static void check_config_bounds(struct state *state,
* unreasonably large.
*/
if (remoteconf->to_self_delay > state->max_to_self_delay)
negotiation_failed(state,
negotiation_failed(state, true,
"to_self_delay %u larger than %u",
remoteconf->to_self_delay,
state->max_to_self_delay);
@ -123,7 +127,7 @@ static void check_config_bounds(struct state *state,
/* Overflow check before capacity calc. */
if (remoteconf->channel_reserve_satoshis > state->funding_satoshis)
negotiation_failed(state,
negotiation_failed(state, true,
"Invalid channel_reserve_satoshis %"PRIu64
" for funding_satoshis %"PRIu64,
remoteconf->channel_reserve_satoshis,
@ -140,7 +144,7 @@ static void check_config_bounds(struct state *state,
capacity_msat = remoteconf->max_htlc_value_in_flight_msat;
if (remoteconf->htlc_minimum_msat * (u64)1000 > capacity_msat)
negotiation_failed(state,
negotiation_failed(state, true,
"Invalid htlc_minimum_msat %"PRIu64
" for funding_satoshis %"PRIu64
" capacity_msat %"PRIu64,
@ -149,7 +153,7 @@ static void check_config_bounds(struct state *state,
capacity_msat);
if (capacity_msat < state->min_effective_htlc_capacity_msat)
negotiation_failed(state,
negotiation_failed(state, true,
"Channel capacity with funding %"PRIu64" msat,"
" reserves %"PRIu64"/%"PRIu64" msat,"
" max_htlc_value_in_flight_msat %"PRIu64
@ -163,7 +167,7 @@ static void check_config_bounds(struct state *state,
/* We don't worry about how many HTLCs they accept, as long as > 0! */
if (remoteconf->max_accepted_htlcs == 0)
negotiation_failed(state,
negotiation_failed(state, true,
"max_accepted_htlcs %u invalid",
remoteconf->max_accepted_htlcs);
@ -220,6 +224,33 @@ static u8 *read_next_peer_msg(struct state *state, const tal_t *ctx)
if (!wire_sync_write(GOSSIP_FD, take(msg)))
status_failed(STATUS_FAIL_PEER_IO,
"Relaying gossip message");
} else if (fromwire_peektype(msg) == WIRE_ERROR) {
struct channel_id chanid;
char *err = sanitize_error(msg, msg, &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`:
* - MUST fail the channel referred to by the error
* message.
* - if no existing channel is referred to by the
* message:
* - MUST ignore the message.
*/
if (channel_id_is_all(&chanid))
peer_failed(PEER_FD, &state->cs,
&state->channel_id,
"Error packet: %s", err);
if (structeq(&chanid, &state->channel_id))
negotiation_failed(state, false,
"Error packet: %s", err);
} else {
return msg;
}
@ -344,7 +375,7 @@ static u8 *funder_channel(struct state *state,
* `open_channel`.
*/
if (minimum_depth > max_minimum_depth)
negotiation_failed(state,
negotiation_failed(state, true,
"minimum_depth %u larger than %u",
minimum_depth, max_minimum_depth);
check_config_bounds(state, state->remoteconf);
@ -537,7 +568,7 @@ static u8 *fundee_channel(struct state *state,
* unknown to the receiver.
*/
if (!structeq(&chain_hash, &state->chainparams->genesis_blockhash)) {
negotiation_failed(state,
negotiation_failed(state, true,
"Unknown chain-hash %s",
type_to_string(peer_msg,
struct sha256_double,
@ -570,12 +601,12 @@ static u8 *fundee_channel(struct state *state,
* too small for timely processing, or unreasonably large.
*/
if (state->feerate_per_kw < min_feerate)
negotiation_failed(state,
negotiation_failed(state, true,
"feerate_per_kw %u below minimum %u",
state->feerate_per_kw, min_feerate);
if (state->feerate_per_kw > max_feerate)
negotiation_failed(state,
negotiation_failed(state, true,
"feerate_per_kw %u above maximum %u",
state->feerate_per_kw, max_feerate);

Loading…
Cancel
Save