mirror of
https://github.com/ElementsProject/lightning.git
synced 2025-02-22 14:42:40 +01:00
openingd: handle ERROR packets (if other end fails negotiation).
Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
This commit is contained in:
parent
6b232de7b1
commit
97434d9c4a
1 changed files with 44 additions and 13 deletions
|
@ -66,7 +66,8 @@ struct state {
|
||||||
};
|
};
|
||||||
|
|
||||||
/* For negotiation failures: we can still gossip with client. */
|
/* 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;
|
va_list ap;
|
||||||
const char *errmsg;
|
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_. */
|
/* Make sure it's correct length for towire_. */
|
||||||
tal_resize(&errmsg, strlen(errmsg)+1);
|
tal_resize(&errmsg, strlen(errmsg)+1);
|
||||||
|
|
||||||
|
/* We don't send error in response to their error packet. */
|
||||||
|
if (send_error) {
|
||||||
/* Tell peer we're bailing on this channel. */
|
/* Tell peer we're bailing on this channel. */
|
||||||
msg = towire_errorfmt(errmsg, &state->channel_id, "%s", errmsg);
|
msg = towire_errorfmt(errmsg, &state->channel_id, "%s", errmsg);
|
||||||
sync_crypto_write(&state->cs, PEER_FD, take(msg));
|
sync_crypto_write(&state->cs, PEER_FD, take(msg));
|
||||||
|
}
|
||||||
|
|
||||||
/* Tell master we should return to gossiping. */
|
/* Tell master we should return to gossiping. */
|
||||||
msg = towire_opening_negotiation_failed(state, &state->cs,
|
msg = towire_opening_negotiation_failed(state, &state->cs,
|
||||||
|
@ -105,7 +109,7 @@ static void check_config_bounds(struct state *state,
|
||||||
* unreasonably large.
|
* unreasonably large.
|
||||||
*/
|
*/
|
||||||
if (remoteconf->to_self_delay > state->max_to_self_delay)
|
if (remoteconf->to_self_delay > state->max_to_self_delay)
|
||||||
negotiation_failed(state,
|
negotiation_failed(state, true,
|
||||||
"to_self_delay %u larger than %u",
|
"to_self_delay %u larger than %u",
|
||||||
remoteconf->to_self_delay,
|
remoteconf->to_self_delay,
|
||||||
state->max_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. */
|
/* Overflow check before capacity calc. */
|
||||||
if (remoteconf->channel_reserve_satoshis > state->funding_satoshis)
|
if (remoteconf->channel_reserve_satoshis > state->funding_satoshis)
|
||||||
negotiation_failed(state,
|
negotiation_failed(state, true,
|
||||||
"Invalid channel_reserve_satoshis %"PRIu64
|
"Invalid channel_reserve_satoshis %"PRIu64
|
||||||
" for funding_satoshis %"PRIu64,
|
" for funding_satoshis %"PRIu64,
|
||||||
remoteconf->channel_reserve_satoshis,
|
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;
|
capacity_msat = remoteconf->max_htlc_value_in_flight_msat;
|
||||||
|
|
||||||
if (remoteconf->htlc_minimum_msat * (u64)1000 > capacity_msat)
|
if (remoteconf->htlc_minimum_msat * (u64)1000 > capacity_msat)
|
||||||
negotiation_failed(state,
|
negotiation_failed(state, true,
|
||||||
"Invalid htlc_minimum_msat %"PRIu64
|
"Invalid htlc_minimum_msat %"PRIu64
|
||||||
" for funding_satoshis %"PRIu64
|
" for funding_satoshis %"PRIu64
|
||||||
" capacity_msat %"PRIu64,
|
" capacity_msat %"PRIu64,
|
||||||
|
@ -149,7 +153,7 @@ static void check_config_bounds(struct state *state,
|
||||||
capacity_msat);
|
capacity_msat);
|
||||||
|
|
||||||
if (capacity_msat < state->min_effective_htlc_capacity_msat)
|
if (capacity_msat < state->min_effective_htlc_capacity_msat)
|
||||||
negotiation_failed(state,
|
negotiation_failed(state, true,
|
||||||
"Channel capacity with funding %"PRIu64" msat,"
|
"Channel capacity with funding %"PRIu64" msat,"
|
||||||
" reserves %"PRIu64"/%"PRIu64" msat,"
|
" reserves %"PRIu64"/%"PRIu64" msat,"
|
||||||
" max_htlc_value_in_flight_msat %"PRIu64
|
" 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! */
|
/* We don't worry about how many HTLCs they accept, as long as > 0! */
|
||||||
if (remoteconf->max_accepted_htlcs == 0)
|
if (remoteconf->max_accepted_htlcs == 0)
|
||||||
negotiation_failed(state,
|
negotiation_failed(state, true,
|
||||||
"max_accepted_htlcs %u invalid",
|
"max_accepted_htlcs %u invalid",
|
||||||
remoteconf->max_accepted_htlcs);
|
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)))
|
if (!wire_sync_write(GOSSIP_FD, take(msg)))
|
||||||
status_failed(STATUS_FAIL_PEER_IO,
|
status_failed(STATUS_FAIL_PEER_IO,
|
||||||
"Relaying gossip message");
|
"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 {
|
} else {
|
||||||
return msg;
|
return msg;
|
||||||
}
|
}
|
||||||
|
@ -344,7 +375,7 @@ static u8 *funder_channel(struct state *state,
|
||||||
* `open_channel`.
|
* `open_channel`.
|
||||||
*/
|
*/
|
||||||
if (minimum_depth > max_minimum_depth)
|
if (minimum_depth > max_minimum_depth)
|
||||||
negotiation_failed(state,
|
negotiation_failed(state, true,
|
||||||
"minimum_depth %u larger than %u",
|
"minimum_depth %u larger than %u",
|
||||||
minimum_depth, max_minimum_depth);
|
minimum_depth, max_minimum_depth);
|
||||||
check_config_bounds(state, state->remoteconf);
|
check_config_bounds(state, state->remoteconf);
|
||||||
|
@ -537,7 +568,7 @@ static u8 *fundee_channel(struct state *state,
|
||||||
* unknown to the receiver.
|
* unknown to the receiver.
|
||||||
*/
|
*/
|
||||||
if (!structeq(&chain_hash, &state->chainparams->genesis_blockhash)) {
|
if (!structeq(&chain_hash, &state->chainparams->genesis_blockhash)) {
|
||||||
negotiation_failed(state,
|
negotiation_failed(state, true,
|
||||||
"Unknown chain-hash %s",
|
"Unknown chain-hash %s",
|
||||||
type_to_string(peer_msg,
|
type_to_string(peer_msg,
|
||||||
struct sha256_double,
|
struct sha256_double,
|
||||||
|
@ -570,12 +601,12 @@ static u8 *fundee_channel(struct state *state,
|
||||||
* too small for timely processing, or unreasonably large.
|
* too small for timely processing, or unreasonably large.
|
||||||
*/
|
*/
|
||||||
if (state->feerate_per_kw < min_feerate)
|
if (state->feerate_per_kw < min_feerate)
|
||||||
negotiation_failed(state,
|
negotiation_failed(state, true,
|
||||||
"feerate_per_kw %u below minimum %u",
|
"feerate_per_kw %u below minimum %u",
|
||||||
state->feerate_per_kw, min_feerate);
|
state->feerate_per_kw, min_feerate);
|
||||||
|
|
||||||
if (state->feerate_per_kw > max_feerate)
|
if (state->feerate_per_kw > max_feerate)
|
||||||
negotiation_failed(state,
|
negotiation_failed(state, true,
|
||||||
"feerate_per_kw %u above maximum %u",
|
"feerate_per_kw %u above maximum %u",
|
||||||
state->feerate_per_kw, max_feerate);
|
state->feerate_per_kw, max_feerate);
|
||||||
|
|
||||||
|
|
Loading…
Add table
Reference in a new issue