| 3051 | } |
| 3052 | |
| 3053 | static struct command_result *check_graceful_shutdown_progress(struct lightningd *ld, struct command *cmd) |
| 3054 | { |
| 3055 | struct htlc_out_map_iter outi; |
| 3056 | const struct htlc_out *hout, *closest_hout = NULL; |
| 3057 | struct htlc_in_map_iter ini; |
| 3058 | const struct htlc_in *hin, *closest_hin = NULL; |
| 3059 | size_t num_connected; |
| 3060 | struct graceful_waiter *w; |
| 3061 | const char *msg; |
| 3062 | |
| 3063 | if (ld->state != LD_STATE_GRACE) |
| 3064 | return NULL; |
| 3065 | |
| 3066 | /* Try disconnecing anyone who no longer has htlcs */ |
| 3067 | num_connected = disconnect_idle_peers(ld); |
| 3068 | |
| 3069 | /* Report on any remaining htlcs */ |
| 3070 | for (hout = htlc_out_map_first(ld->htlcs_out, &outi); |
| 3071 | hout; |
| 3072 | hout = htlc_out_map_next(ld->htlcs_out, &outi)) { |
| 3073 | if (!closest_hout || hout->cltv_expiry < closest_hout->cltv_expiry) |
| 3074 | closest_hout = hout; |
| 3075 | } |
| 3076 | for (hin = htlc_in_map_first(ld->htlcs_in, &ini); |
| 3077 | hin; |
| 3078 | hin = htlc_in_map_next(ld->htlcs_in, &ini)) { |
| 3079 | if (!closest_hin || hin->cltv_expiry < closest_hin->cltv_expiry) |
| 3080 | closest_hin = hin; |
| 3081 | } |
| 3082 | |
| 3083 | /* Choose single closest one if both */ |
| 3084 | if (closest_hin && closest_hout) { |
| 3085 | if (closest_hin->cltv_expiry < closest_hout->cltv_expiry) |
| 3086 | closest_hout = NULL; |
| 3087 | else |
| 3088 | closest_hin = NULL; |
| 3089 | } |
| 3090 | |
| 3091 | /* If given a cmd, only do that one */ |
| 3092 | if (closest_hin || closest_hout) { |
| 3093 | u32 expiry = closest_hin ? closest_hin->cltv_expiry : closest_hout->cltv_expiry; |
| 3094 | const struct channel *c = closest_hin ? closest_hin->key.channel : closest_hout->key.channel; |
| 3095 | u32 blockheight = get_block_height(ld->topology); |
| 3096 | const char *state = htlc_state_name(closest_hin ? closest_hin->hstate : closest_hout->hstate); |
| 3097 | |
| 3098 | msg = tal_fmt(tmpctx, |
| 3099 | "Next HTLC %s expires at block #%u (%u blocks %s) %s peer %s (%s)", |
| 3100 | state, expiry, |
| 3101 | expiry >= blockheight ? expiry - blockheight : blockheight - expiry, |
| 3102 | expiry >= blockheight ? "from now" : "ago", |
| 3103 | closest_hin ? "coming from" : "going to", |
| 3104 | fmt_node_id(tmpctx, &c->peer->id), |
| 3105 | c->peer->connected == PEER_CONNECTED ? "connected" : "disconnected"); |
| 3106 | } else if (num_connected) { |
| 3107 | msg = tal_fmt(tmpctx, "%zu peers still connected", num_connected); |
| 3108 | } else { |
| 3109 | struct graceful_waiter *next; |
| 3110 | /* All finished! */ |
no test coverage detected