Skip to content

Commit 03c4801

Browse files
nextFreePort got out of port range on win (#19400)
on win: ``` Error Trace: D:/a/erigon/erigon/txnprovider/shutter/block_building_integration_test.go:335 D:/a/erigon/erigon/txnprovider/shutter/block_building_integration_test.go:63 Error: Received unexpected error: failed to listen on any addresses: [listen tcp4 127.0.0.1:53528: bind: Only one usage of each socket address (protocol/network address/port) is normally permitted.] Test: TestShutterBlockBuilding ``` Root cause: Port 53528 is in the Windows dynamic/ephemeral port range (49152–65535). Windows uses this range to assign outgoing TCP connections. After NextFreePort closes its probe listener, the OS can immediately reassign that port for an outbound connection — then when DialDecryptionKeysSender tries to bind it (much later, after all the contract deployment setup), it's already taken.
1 parent c593300 commit 03c4801

File tree

1 file changed

+8
-7
lines changed

1 file changed

+8
-7
lines changed

common/freeport/free_port.go

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -27,8 +27,10 @@ import (
2727
)
2828

2929
const (
30-
maxPort = 65535
31-
minPort = 1024
30+
maxPort = 49151 // stay below Windows ephemeral ports 49152-65535 (TCP connections assigned there)
31+
minPort = 1024
32+
bucketSize = 2500
33+
numBuckets = (maxPort - minPort) / bucketSize
3234
)
3335

3436
var (
@@ -74,13 +76,12 @@ func nextPortNum(port int64) int64 {
7476
if port == 0 { // init case
7577
// generate a random starting point to avoid clashes
7678
// if more than 1 "go test ./erigon " processes are run on the same machine at the same time
77-
// for simplicity, assume there are 60,000 ports and each go test process needs 2500 ports
78-
// 60,000/2500=24 buckets - randomly pick 1 of these buckets
79+
// randomly pick 1 of numBuckets non-overlapping buckets
7980
// note: this randomness is not needed for a single run of a "go test ./erigon" process
8081
rnd := rand.New(rand.NewSource(time.Now().UnixNano()))
81-
n := rnd.Intn(24)
82-
return minPort + int64(n)*2500
83-
} else if port == maxPort {
82+
n := rnd.Intn(numBuckets)
83+
return minPort + int64(n)*bucketSize
84+
} else if port >= maxPort {
8485
return minPort
8586
} else {
8687
return port + 1

0 commit comments

Comments
 (0)