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);
|
||||
subd_shutdown(ld->gossip, 10);
|
||||
|
||||
free_htlcs(ld, NULL);
|
||||
|
||||
while ((p = list_top(&ld->peers, struct peer, list)) != NULL)
|
||||
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)
|
||||
{
|
||||
/* 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. */
|
||||
peer_set_owner(peer, NULL);
|
||||
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");
|
||||
}
|
||||
|
||||
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 *hout;
|
||||
@ -1175,25 +1202,31 @@ static void handle_irrevocably_resolved(struct peer *peer, const u8 *msg)
|
||||
|
||||
do {
|
||||
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 = htlc_out_map_next(&peer->ld->htlcs_out, &outi)) {
|
||||
if (hout->key.peer != peer)
|
||||
hout = htlc_out_map_next(&ld->htlcs_out, &outi)) {
|
||||
if (peer && hout->key.peer != peer)
|
||||
continue;
|
||||
tal_free(hout);
|
||||
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 = htlc_in_map_next(&peer->ld->htlcs_in, &ini)) {
|
||||
if (hin->key.peer != peer)
|
||||
hin = htlc_in_map_next(&ld->htlcs_in, &ini)) {
|
||||
if (peer && hin->key.peer != peer)
|
||||
continue;
|
||||
tal_free(hin);
|
||||
deleted = true;
|
||||
}
|
||||
/* Can skip over elements due to iterating while deleting. */
|
||||
} 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. */
|
||||
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,
|
||||
enum peer_state state);
|
||||
void setup_listeners(struct lightningd *ld);
|
||||
|
||||
void free_htlcs(struct lightningd *ld, const struct peer *peer);
|
||||
#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 */
|
||||
void fatal(const char *fmt UNNEEDED, ...)
|
||||
{ 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 */
|
||||
void gossip_init(struct lightningd *ld UNNEEDED)
|
||||
{ fprintf(stderr, "gossip_init called!\n"); abort(); }
|
||||
|
Loading…
Reference in New Issue
Block a user