Repository navigation
Conversation
TestWebsocketHTTPOnSeparatePort_WSRequest picked a "free" port by opening a listener on port 0 and closing it again, then configured the WebSocket server to bind that port while the HTTP server used port 0. Because the node starts its HTTP server first, the kernel can hand the just released port straight back to that listener, after which the WebSocket bind fails with EADDRINUSE and the whole shard goes red. This was observed on CI in the J-N test shard. Pick a fresh port and retry the start on EADDRINUSE instead of failing, so a port stolen between probing and binding no longer breaks the suite. The node closes itself when endpoint startup fails, so a discarded attempt leaks nothing. go-ethereum carries the same test and the same race.
|
Important Review skippedAuto reviews are disabled on base/target branches other than the default branch. Please check the settings in the CodeRabbit UI or the
|
gzliudan
requested review from
AnilChinchawale,
anunay-xin,
benjamin202410,
liam-lai and
wanwiset25
October 26, 2026 06:23
anunay-xin
approved these changes
Oct 26, 2026
benjamin202410
approved these changes
Oct 26, 2026
When all ten attempts to start the node on a freshly probed WebSocket port lost to a bind conflict, the helper failed with a bare "could not start node on a free websocket port". The attempt that produced the final error had been discarded by then, so on CI the only trace of the actual cause - which endpoint could not bind and on what address - was already gone. Carry the last EADDRINUSE out of the loop and print it, and say plainly that ten attempts were made instead of implying the port was the culprit: the retry classifies any bind conflict, not only the WebSocket one. The helper's doc comment now also records that the classification depends on syscall.EADDRINUSE, which Windows reports as a WSA errno instead, so the retry is a no-op there. Behaviour on the success path is unchanged; only the diagnosis of a lost race changes.
This branch has not been deployed
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
TestWebsocketHTTPOnSeparatePort_WSRequestprobed for a free port by listening on:0and closing the socket, then handed the number to the node. The node binds its own HTTP listener on:0first, and the kernel could return the just-released port to it — the WebSocket bind then failed withEADDRINUSE,node.Start()rolled the HTTP server back, and the test took the shard down.The second commit only changes the failure message: the last
EADDRINUSEis carried out of the loop and printed when all ten attempts are lost.if err := node.Start(); err != nil { if errors.Is(err, syscall.EADDRINUSE) { + lastErr = err continue } t.Fatalf("could not start http service on node: %v", err) } return node, port } -t.Fatalf("could not start node on a free websocket port") +t.Fatalf("could not start the node after 10 attempts: %v", lastErr)Evidence
Before — CI run for #2837,
J-N testsshard:After — same test five times, then the whole package and lint:
When the ten attempts are exhausted, the failure names the endpoint and address instead of blaming the port:
could not start the node after 10 attempts: listen tcp 127.0.0.1:<port>: bind: address already in use.Merge Danger
Door: two-way — test-only, one file, no production code. A revert restores the previous behaviour, flake included.
Blast Radius: shard-only
The retry classifies a bind conflict purely as
syscall.EADDRINUSE. Windows reports a WSA errno instead, so the retry is a no-op there and a lost race still fails the test; CI only runs Linux.go-ethereumcarries the same test and the same race, so this is local hardening rather than a port.Types of changes
Impacted Components
nodepackage test helper used byTestWebsocketHTTPOnSeparatePort_WSRequestChecklist