@@ -215,40 +215,15 @@ fn expand_path(s: &str) -> Result<PathBuf> {
215215impl FlashblocksArgs {
216216 /// Configures flashblocks for tests. Handles WS port assignment.
217217 pub fn default_on_for_tests ( ) -> Self {
218- use {
219- core:: net:: { Ipv4Addr , SocketAddrV4 } ,
220- std:: {
221- collections:: HashSet ,
222- net:: TcpListener ,
223- sync:: { Mutex , OnceLock } ,
224- } ,
225- } ;
226-
227- static RESERVED_PORTS : OnceLock < Mutex < HashSet < u16 > > > = OnceLock :: new ( ) ;
228- let reserved = RESERVED_PORTS . get_or_init ( || Mutex :: new ( HashSet :: new ( ) ) ) ;
229-
230- let port = ( 12000 ..19000 )
231- . find ( |port| {
232- let addr = format ! ( "0.0.0.0:{port}" ) ;
233- if let Ok ( listener) = TcpListener :: bind ( & addr) {
234- drop ( listener) ;
235- let mut set = reserved. lock ( ) . unwrap ( ) ;
236- if set. contains ( port) {
237- false
238- } else {
239- set. insert ( * port) ;
240- true
241- }
242- } else {
243- false
244- }
245- } )
246- . expect ( "No available ports found for test" ) ;
218+ use core:: net:: { Ipv4Addr , SocketAddrV4 } ;
247219
248220 Self {
249221 interval : Duration :: from_millis ( 250 ) ,
250222 leeway_time : Duration :: from_millis ( 75 ) ,
251- enabled : Some ( SocketAddrV4 :: new ( Ipv4Addr :: UNSPECIFIED , port) . into ( ) ) ,
223+ enabled : Some (
224+ SocketAddrV4 :: new ( Ipv4Addr :: UNSPECIFIED , Self :: get_available_port ( ) )
225+ . into ( ) ,
226+ ) ,
252227 calculate_state_root : true ,
253228 }
254229 }
@@ -257,41 +232,29 @@ impl FlashblocksArgs {
257232 leeway_time : Duration ,
258233 interval : Duration ,
259234 ) -> Self {
260- use {
261- core:: net:: { Ipv4Addr , SocketAddrV4 } ,
262- std:: {
263- collections:: HashSet ,
264- net:: TcpListener ,
265- sync:: { Mutex , OnceLock } ,
266- } ,
267- } ;
268-
269- static RESERVED_PORTS : OnceLock < Mutex < HashSet < u16 > > > = OnceLock :: new ( ) ;
270- let reserved = RESERVED_PORTS . get_or_init ( || Mutex :: new ( HashSet :: new ( ) ) ) ;
271-
272- let port = ( 12000 ..19000 )
273- . find ( |port| {
274- let addr = format ! ( "0.0.0.0:{port}" ) ;
275- if let Ok ( listener) = TcpListener :: bind ( & addr) {
276- drop ( listener) ;
277- let mut set = reserved. lock ( ) . unwrap ( ) ;
278- if set. contains ( port) {
279- false
280- } else {
281- set. insert ( * port) ;
282- true
283- }
284- } else {
285- false
286- }
287- } )
288- . expect ( "No available ports found for test" ) ;
235+ use core:: net:: { Ipv4Addr , SocketAddrV4 } ;
289236
290237 Self {
291238 interval,
292239 leeway_time,
293- enabled : Some ( SocketAddrV4 :: new ( Ipv4Addr :: UNSPECIFIED , port) . into ( ) ) ,
240+ enabled : Some (
241+ SocketAddrV4 :: new ( Ipv4Addr :: UNSPECIFIED , Self :: get_available_port ( ) )
242+ . into ( ) ,
243+ ) ,
294244 calculate_state_root : true ,
295245 }
296246 }
247+
248+ /// Gets an available port by first binding to port 0 -- instructing the OS to
249+ /// find and assign one. Then the listener is dropped when this goes out of
250+ /// scope, freeing the port for the next time this function is called.
251+ fn get_available_port ( ) -> u16 {
252+ use std:: net:: TcpListener ;
253+
254+ TcpListener :: bind ( "127.0.0.1:0" )
255+ . expect ( "Failed to bind to random port" )
256+ . local_addr ( )
257+ . expect ( "Failed to get local address" )
258+ . port ( )
259+ }
297260}
0 commit comments