Description
Description
We've tried to rid our tests of the unused_port
crate by preferring to bind on port 0, but there are still some circumstances where binding on a non-zero port is useful for testing, e.g.
The unused_port
crate as currently written is inherently racy because it doesn't keep state across processes, i.e. there can be a small delay between a process allocating a "free" port, and starting the service to listen on that port. During this delay, another process can leap in, allocate the same port, and start a service which will cause the original process's service to fail to start.
Steps to resolve
Option 1: On-disk database
One option for sharing state would be to use an on-disk database at a static location (e.g. /tmp/lighthouse-ports.sqlite
). I think using a lightweight database like sqlite might be easiest, as it would let us outsource some of the consistency & locking logic. Alternatively we could roll our own file-locking, but this would also require defining an on-disk format (SSZ of Vec<u16>
?)
Option 2: Pass sockets
A slightly cleaner but less versatile solution than the on-disk DB would be to bind a socket on port 0, and hold onto it. If we could pass an already listening socket to libp2p, our HTTP library or whatever other listening service, then this would avoid the raciness of allocating the port, releasing it, and then re-binding it. However this approach will not work for external processes used in tests (like the dummy eth1 node, or web3signer).