mirror of
https://github.com/ElementsProject/lightning.git
synced 2025-02-21 14:24:09 +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. */
|
||||
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…
Add table
Reference in a new issue