Listeners can't be stopped, so bitcoin-node can hang after shutdown when an IPC client reconnects

Abierto
#385 0 comentarios 0 reacciones 0 asignados Ver en GitHub

Los mantenedores suelen responder en 1 día

Nadie ha tomado este issue todavía.

Evaluación

Dificultad
5/5
Tiempo estimado
Más de una semana
Aptitud para principiantes
35/100
Tipo de issue
Nueva funcionalidad
Claridad
Bien especificado
Estado de actividad
Activo
Stack tecnológico
cpp

Línea de trabajo

Start with include/mp/proxy-io.h around ListenConnections and _Listen, then read the linked review discussion for the listener stop behavior. The proposed change also requires updates to Bitcoin Core's src/ipc/capnp/protocol.cpp and coordination with #361 and #384, which affect the same accept loop. Done means listener stop prevents new connections from being served, with coverage in listen_tests.cpp and a Bitcoin Core shutdown reconnect test.

Escrito por el modelo de indexación a partir del texto del issue.

Descripción

bug

bitcoin/bitcoin#36585 reports a v32.0rc3 node that hit a fatal error, logged "Shutdown done", and then stayed alive for 5.7 hours until systemd killed it. The threads left were the main thread (b-shutoff) and two b-capnp-loop threads, and a mining client was connected over IPC. The report has no backtrace, so the cause of that hang is not confirmed, but the code allows this sequence:

  1. Shutdown() calls disconnectIncoming(), which closes the IPC connections that exist at that moment.
  2. Nothing stops the listeners. ListenConnections returns void, so Bitcoin Core's CapnpProtocol::listen() has no handle to stop, and _Listen keeps an accept() pending.
  3. A client that reconnects, as a mining client does when its connection drops, is accepted and served. Each Connection holds an EventLoopRef.
  4. After "Shutdown done", ~CapnpProtocol releases its own reference and joins the event loop thread, which runs until no references remain. It waits for as long as the new client stays connected. SIGTERM does nothing at that point, since shutdown has already run.

Proposed change

  • libmultiprocess: ListenConnections returns the Listener (or a handle to it), and a stop call, run on the event loop thread, prevents further accepts. After stopping, a pending accept() that completes is not served, and disconnect callbacks do not resume accepting at the connection limit. This was suggested in the #269 review. Closing the listening socket on stop would also make clients get "connection refused" instead of waiting in the backlog.
  • Bitcoin Core: CapnpProtocol keeps the handles from listen() and stops them at the start of disconnectIncoming(), before closing the current connections.
  • Tests: a listen_tests.cpp case that stops a listener and checks that a later client is not served, including at the connection limit, and a Bitcoin Core functional test that reconnects an IPC client right after shutdown disconnects it and checks that the process exits.

The stop logic has to be tested together with the accept-retry fix in #384 and the connection-limit fix in #361, which change the same accept loop.

Origin

The window was opened by bitcoin/bitcoin#32345 ("ipc: Handle unclean shutdowns better", 2025, first released in v30.0). Before it, shutdown waited for every IPC client to disconnect on its own, so a connected client could block shutdown indefinitely. bitcoin/bitcoin@7f65aac78b95 made shutdown disconnect clients instead, but did not stop new ones from connecting, because the library has no way to stop a listener. bitcoin/bitcoin#35932 lists "new connections can still be accepted during shutdown" as a known limitation. Releases from v30.0 on are affected.

The missing stop operation was also reported privately in an independent security review (2026-08-16), at the time as an API gap with no effect on Bitcoin Core.

Links

Lenguaje dominante
C++
Estrellas
62
Forks
58
Merge medio
6 d 11 h
PR fusionados (30 d)
7

Preparar el entorno

Este proyecto no incluye contenedor de desarrollo, Dockerfile ni guía de contribución, así que la configuración corre por tu cuenta: empieza por su README y consulta nuestra guía para la primera contribución para los pasos generales.

Primeros pasos

  1. Lee el issue completo y luego la guía de contribución del proyecto.
  2. Comenta en el issue que vas a ocuparte — evita que dos personas hagan lo mismo.
  3. Haz un fork del repositorio y trabaja en una rama.
  4. Abre un pull request que haga referencia al número del issue.

Más de bitcoin-core/libmultiprocess

Todos los issues de bitcoin-core/libmultiprocess

Issues similares

Más issues de C++

Recibe los nuevos issues en tu correo

Un resumen breve de issues de GitHub para principiantes.