mirror of
https://github.com/ElementsProject/lightning.git
synced 2024-11-19 09:54:16 +01:00
lightningd: check peers don't leave dangling HTLCs when they die.
Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
This commit is contained in:
parent
e9337820a0
commit
956350e62e
@ -198,6 +198,8 @@ static void shutdown_subdaemons(struct lightningd *ld)
|
|||||||
close(ld->hsm_fd);
|
close(ld->hsm_fd);
|
||||||
subd_shutdown(ld->gossip, 10);
|
subd_shutdown(ld->gossip, 10);
|
||||||
|
|
||||||
|
free_htlcs(ld, NULL);
|
||||||
|
|
||||||
while ((p = list_top(&ld->peers, struct peer, list)) != NULL)
|
while ((p = list_top(&ld->peers, struct peer, list)) != NULL)
|
||||||
tal_free(p);
|
tal_free(p);
|
||||||
}
|
}
|
||||||
|
@ -90,6 +90,32 @@ static void peer_set_owner(struct peer *peer, struct subd *owner)
|
|||||||
|
|
||||||
static void destroy_peer(struct peer *peer)
|
static void destroy_peer(struct peer *peer)
|
||||||
{
|
{
|
||||||
|
/* Must not have any HTLCs! */
|
||||||
|
struct htlc_out_map_iter outi;
|
||||||
|
struct htlc_out *hout;
|
||||||
|
struct htlc_in_map_iter ini;
|
||||||
|
struct htlc_in *hin;
|
||||||
|
|
||||||
|
for (hout = htlc_out_map_first(&peer->ld->htlcs_out, &outi);
|
||||||
|
hout;
|
||||||
|
hout = htlc_out_map_next(&peer->ld->htlcs_out, &outi)) {
|
||||||
|
if (hout->key.peer != peer)
|
||||||
|
continue;
|
||||||
|
fatal("Freeing peer %s has hout %s",
|
||||||
|
peer_state_name(peer->state),
|
||||||
|
htlc_state_name(hout->hstate));
|
||||||
|
}
|
||||||
|
|
||||||
|
for (hin = htlc_in_map_first(&peer->ld->htlcs_in, &ini);
|
||||||
|
hin;
|
||||||
|
hin = htlc_in_map_next(&peer->ld->htlcs_in, &ini)) {
|
||||||
|
if (hin->key.peer != peer)
|
||||||
|
continue;
|
||||||
|
fatal("Freeing peer %s has hin %s",
|
||||||
|
peer_state_name(peer->state),
|
||||||
|
htlc_state_name(hin->hstate));
|
||||||
|
}
|
||||||
|
|
||||||
/* Free any old owner still hanging around. */
|
/* Free any old owner still hanging around. */
|
||||||
peer_set_owner(peer, NULL);
|
peer_set_owner(peer, NULL);
|
||||||
list_del_from(&peer->ld->peers, &peer->list);
|
list_del_from(&peer->ld->peers, &peer->list);
|
||||||
@ -1163,7 +1189,8 @@ static void handle_onchain_htlc_timeout(struct peer *peer, const u8 *msg)
|
|||||||
onchain_failed_our_htlc(peer, &htlc, "timed out");
|
onchain_failed_our_htlc(peer, &htlc, "timed out");
|
||||||
}
|
}
|
||||||
|
|
||||||
static void handle_irrevocably_resolved(struct peer *peer, const u8 *msg)
|
/* If peer is NULL, free them all (for shutdown) */
|
||||||
|
void free_htlcs(struct lightningd *ld, const struct peer *peer)
|
||||||
{
|
{
|
||||||
struct htlc_out_map_iter outi;
|
struct htlc_out_map_iter outi;
|
||||||
struct htlc_out *hout;
|
struct htlc_out *hout;
|
||||||
@ -1175,25 +1202,31 @@ static void handle_irrevocably_resolved(struct peer *peer, const u8 *msg)
|
|||||||
|
|
||||||
do {
|
do {
|
||||||
deleted = false;
|
deleted = false;
|
||||||
for (hout = htlc_out_map_first(&peer->ld->htlcs_out, &outi);
|
for (hout = htlc_out_map_first(&ld->htlcs_out, &outi);
|
||||||
hout;
|
hout;
|
||||||
hout = htlc_out_map_next(&peer->ld->htlcs_out, &outi)) {
|
hout = htlc_out_map_next(&ld->htlcs_out, &outi)) {
|
||||||
if (hout->key.peer != peer)
|
if (peer && hout->key.peer != peer)
|
||||||
continue;
|
continue;
|
||||||
tal_free(hout);
|
tal_free(hout);
|
||||||
deleted = true;
|
deleted = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (hin = htlc_in_map_first(&peer->ld->htlcs_in, &ini);
|
for (hin = htlc_in_map_first(&ld->htlcs_in, &ini);
|
||||||
hin;
|
hin;
|
||||||
hin = htlc_in_map_next(&peer->ld->htlcs_in, &ini)) {
|
hin = htlc_in_map_next(&ld->htlcs_in, &ini)) {
|
||||||
if (hin->key.peer != peer)
|
if (peer && hin->key.peer != peer)
|
||||||
continue;
|
continue;
|
||||||
tal_free(hin);
|
tal_free(hin);
|
||||||
deleted = true;
|
deleted = true;
|
||||||
}
|
}
|
||||||
/* Can skip over elements due to iterating while deleting. */
|
/* Can skip over elements due to iterating while deleting. */
|
||||||
} while (deleted);
|
} while (deleted);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void handle_irrevocably_resolved(struct peer *peer, const u8 *msg)
|
||||||
|
{
|
||||||
|
/* FIXME: Implement check_htlcs to ensure no dangling hout->in ptrs! */
|
||||||
|
free_htlcs(peer->ld, peer);
|
||||||
|
|
||||||
/* FIXME: Remove peer from db. */
|
/* FIXME: Remove peer from db. */
|
||||||
log_info(peer->log, "onchaind complete, forgetting peer");
|
log_info(peer->log, "onchaind complete, forgetting peer");
|
||||||
|
@ -210,4 +210,6 @@ const char *peer_state_name(enum peer_state state);
|
|||||||
void peer_set_condition(struct peer *peer, enum peer_state oldstate,
|
void peer_set_condition(struct peer *peer, enum peer_state oldstate,
|
||||||
enum peer_state state);
|
enum peer_state state);
|
||||||
void setup_listeners(struct lightningd *ld);
|
void setup_listeners(struct lightningd *ld);
|
||||||
|
|
||||||
|
void free_htlcs(struct lightningd *ld, const struct peer *peer);
|
||||||
#endif /* LIGHTNING_LIGHTNINGD_PEER_CONTROL_H */
|
#endif /* LIGHTNING_LIGHTNINGD_PEER_CONTROL_H */
|
||||||
|
@ -19,6 +19,9 @@ int debug_poll(struct pollfd *fds UNNEEDED, nfds_t nfds UNNEEDED, int timeout UN
|
|||||||
/* Generated stub for fatal */
|
/* Generated stub for fatal */
|
||||||
void fatal(const char *fmt UNNEEDED, ...)
|
void fatal(const char *fmt UNNEEDED, ...)
|
||||||
{ fprintf(stderr, "fatal called!\n"); abort(); }
|
{ fprintf(stderr, "fatal called!\n"); abort(); }
|
||||||
|
/* Generated stub for free_htlcs */
|
||||||
|
void free_htlcs(struct lightningd *ld UNNEEDED, const struct peer *peer UNNEEDED)
|
||||||
|
{ fprintf(stderr, "free_htlcs called!\n"); abort(); }
|
||||||
/* Generated stub for gossip_init */
|
/* Generated stub for gossip_init */
|
||||||
void gossip_init(struct lightningd *ld UNNEEDED)
|
void gossip_init(struct lightningd *ld UNNEEDED)
|
||||||
{ fprintf(stderr, "gossip_init called!\n"); abort(); }
|
{ fprintf(stderr, "gossip_init called!\n"); abort(); }
|
||||||
|
Loading…
Reference in New Issue
Block a user