From e9337820a0a745fc91fe84090daeb2b9734fdb1e Mon Sep 17 00:00:00 2001 From: Rusty Russell Date: Fri, 10 Nov 2017 12:17:15 +1030 Subject: [PATCH] onchaind: remove htlcs when peer is irrevocably committed. We don't track them accurately when in onchaind, but we don't want to: onchaind can be restarted at any time. Once it's all settled, we're clear to clean them up. Before this, valgrind could complain about deferncing hout->key.peer: Valgrind error file: valgrind-errors.10876 ==10876== Invalid read of size 4 ==10876== at 0x41F8AF: peer_on_chain (peer_control.h:127) ==10876== by 0x42340D: notify_new_block (peer_htlcs.c:1461) ==10876== by 0x40A08D: connect_block (chaintopology.c:96) ==10876== by 0x40A96B: topology_changed (chaintopology.c:313) ==10876== by 0x40AC85: add_block (chaintopology.c:384) ==10876== by 0x40ABF0: gather_previous_blocks (chaintopology.c:363) ==10876== by 0x4051B3: process_rawblock (bitcoind.c:410) ==10876== by 0x4044DD: bcli_finished (bitcoind.c:155) ==10876== by 0x454665: destroy_conn (poll.c:183) ==10876== by 0x454685: destroy_conn_close_fd (poll.c:189) ==10876== by 0x45DF89: notify (tal.c:240) ==10876== by 0x45E43A: del_tree (tal.c:400) ==10876== Address 0x6929208 is 2,120 bytes inside a block of size 2,416 free'd ==10876== at 0x4C2EDEB: free (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so) ==10876== by 0x45E513: del_tree (tal.c:421) ==10876== by 0x45E849: tal_free (tal.c:509) ==10876== by 0x41A8E9: handle_irrevocably_resolved (peer_control.c:1172) Signed-off-by: Rusty Russell --- lightningd/peer_control.c | 30 ++++++++++++++++++++++++++++++ 1 file changed, 30 insertions(+) diff --git a/lightningd/peer_control.c b/lightningd/peer_control.c index 5bd57a95d..035a710f3 100644 --- a/lightningd/peer_control.c +++ b/lightningd/peer_control.c @@ -1165,6 +1165,36 @@ static void handle_onchain_htlc_timeout(struct peer *peer, const u8 *msg) static void handle_irrevocably_resolved(struct peer *peer, const u8 *msg) { + struct htlc_out_map_iter outi; + struct htlc_out *hout; + struct htlc_in_map_iter ini; + struct htlc_in *hin; + bool deleted; + + /* FIXME: Implement check_htlcs to ensure no dangling hout->in ptrs! */ + + do { + deleted = false; + 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; + tal_free(hout); + deleted = true; + } + + 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; + tal_free(hin); + deleted = true; + } + /* Can skip over elements due to iterating while deleting. */ + } while (deleted); + /* FIXME: Remove peer from db. */ log_info(peer->log, "onchaind complete, forgetting peer");