Bitcoin Core trennt Peers nicht mehr wegen eines verpassten Pings, während sie Blöcke liefern
Bitcoin Core hat am 5. Oktober den Pull Request #36080 übernommen, der ändert, wann ein Knoten sein Ping-Timeout durchsetzt. Verfasst hat ihn der Mitwirkende mzumsande.
Das Problem. Ein Knoten, der Blöcke ausliefert, bevorzugt die Blockanfragen eines Peers gegenüber seinen anderen Peer-to-Peer-Nachrichten. Beim ersten Blockdownload über eine Verbindung mit wenig Bandbreite, verteilt auf zehn Peers, kann diese Bevorzugung dazu führen, dass ein Peer einen Ping nicht vor Ablauf des 20-Minuten-Timeouts beantwortet – und der herunterladende Knoten trennt ihn dann, obwohl der Peer, wie es im Pull Request heißt, nichts falsch gemacht hat und selbst nicht einmal langsam ist. Gemeldet wurde das Problem als #35761.
Die Korrektur. Die Ping-Timeout-Prüfung wird aus MaybeSendPing() herausgelöst – laut Autor ohnehin ein etwas ungünstiger Ort – und ausgesetzt, solange mit diesem Peer Blöcke unterwegs sind. Nach dem letzten Block folgt eine Schonfrist, damit der Peer sein pong senden kann, bevor das Timeout wieder greift.

Warum nichts verloren geht. Der Pull Request zählt die anderen Schutzmechanismen auf, die beim Blockdownload weiter gelten:
- ein dynamisches Download-Timeout pro Block, das bei zehn parallelen Peers 600 s × (1 + 0,5 × 9) ergibt, also 55 Minuten pro Block;
- die Stalling-Logik, die einen Peer trennt, der deutlich langsamer ist als die anderen;
- die Prüfung auf Socket-Inaktivität, die einen Peer trennt, der 20 Minuten lang gar nichts gesendet hat.
Angesichts dessen, so der Autor, brachte das Ping-Timeout in dieser Lage wenig. Die Änderung ergänzt einen Funktionstest, p2p_ping_ibd.py.