• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

stacks-network / stacks-core / 26250451051-1

21 May 2026 08:11PM UTC coverage: 85.585% (-0.1%) from 85.712%
26250451051-1

Pull #7215

github

ec9d4c
web-flow
Merge 9487bf852 into af1280aac
Pull Request #7215: Chore: fix flake in non_blocking_minority_configured_to_favour_...

188844 of 220651 relevant lines covered (85.58%)

18975267.44 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

83.38
/stackslib/src/net/poll.rs
1
// Copyright (C) 2013-2020 Blockstack PBC, a public benefit corporation
2
// Copyright (C) 2020-2023 Stacks Open Internet Foundation
3
//
4
// This program is free software: you can redistribute it and/or modify
5
// it under the terms of the GNU General Public License as published by
6
// the Free Software Foundation, either version 3 of the License, or
7
// (at your option) any later version.
8
//
9
// This program is distributed in the hope that it will be useful,
10
// but WITHOUT ANY WARRANTY; without even the implied warranty of
11
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12
// GNU General Public License for more details.
13
//
14
// You should have received a copy of the GNU General Public License
15
// along with this program.  If not, see <http://www.gnu.org/licenses/>.
16

17
use std::collections::{HashMap, HashSet};
18
use std::io::ErrorKind;
19
use std::net::{Shutdown, SocketAddr};
20
use std::time::Duration;
21
use std::{io, time};
22

23
use mio::{self, net as mio_net, PollOpt, Ready, Token};
24
use rand::{self, RngCore};
25
use stacks_common::util::sleep_ms;
26

27
use crate::net::Error as net_error;
28

29
const SERVER: Token = mio::Token(0);
30

31
pub struct NetworkPollState {
32
    pub new: HashMap<usize, mio_net::TcpStream>,
33
    pub ready: Vec<usize>,
34
}
35

36
impl NetworkPollState {
37
    pub fn new() -> NetworkPollState {
20,770,988✔
38
        NetworkPollState {
20,770,988✔
39
            new: HashMap::new(),
20,770,988✔
40
            ready: vec![],
20,770,988✔
41
        }
20,770,988✔
42
    }
20,770,988✔
43
}
44

45
// state for a single network server
46
#[derive(Debug)]
47
pub struct NetworkServerState {
48
    addr: SocketAddr,
49
    server_socket: mio_net::TcpListener,
50
    server_event: mio::Token,
51
}
52

53
// state for the entire network
54
#[derive(Debug)]
55
pub struct NetworkState {
56
    poll: mio::Poll,
57
    events: mio::Events,
58
    event_capacity: usize,
59
    servers: Vec<NetworkServerState>,
60
    count: usize,
61
    event_map: HashMap<usize, usize>, // map socket events to their registered server socket (including server sockets)
62
}
63

64
impl NetworkState {
65
    pub fn new(event_capacity: usize) -> Result<NetworkState, net_error> {
3,313✔
66
        let poll = mio::Poll::new().map_err(|e| {
3,313✔
67
            error!("Failed to initialize poller: {:?}", e);
×
68
            net_error::BindError
×
69
        })?;
×
70

71
        let events = mio::Events::with_capacity(event_capacity);
3,313✔
72

73
        Ok(NetworkState {
3,313✔
74
            poll,
3,313✔
75
            events,
3,313✔
76
            event_capacity,
3,313✔
77
            servers: vec![],
3,313✔
78
            count: 1,
3,313✔
79
            event_map: HashMap::new(),
3,313✔
80
        })
3,313✔
81
    }
3,313✔
82

83
    #[cfg_attr(test, mutants::skip)]
84
    pub fn num_events(&self) -> usize {
51✔
85
        self.event_map.len()
51✔
86
    }
51✔
87

88
    fn bind_address(addr: &SocketAddr) -> Result<mio_net::TcpListener, net_error> {
6,639✔
89
        if !cfg!(test) && !cfg!(feature = "testing") {
6,639✔
90
            mio_net::TcpListener::bind(addr).map_err(|e| {
×
91
                error!("Failed to bind to {:?}: {:?}", addr, e);
×
92
                net_error::BindError
×
93
            })
×
94
        } else {
95
            let mut backoff = 1000;
6,639✔
96
            let mut rng = rand::thread_rng();
6,639✔
97
            let mut count = 1000;
6,639✔
98
            loop {
99
                match mio_net::TcpListener::bind(addr) {
6,748✔
100
                    Ok(server) => {
6,639✔
101
                        return Ok(server);
6,639✔
102
                    }
103
                    Err(e) => match e.kind() {
109✔
104
                        io::ErrorKind::AddrInUse => {
105
                            debug!(
109✔
106
                                "Waiting {} millis and trying to bind {:?} again",
107
                                backoff, addr
108
                            );
109
                            sleep_ms(backoff);
109✔
110
                            backoff = count + (rng.next_u64() % count);
109✔
111
                            count += count;
109✔
112
                            continue;
109✔
113
                        }
114
                        _ => {
115
                            debug!("Failed to bind {:?}: {:?}", addr, &e);
×
116
                            return Err(net_error::BindError);
×
117
                        }
118
                    },
119
                }
120
            }
121
        }
122
    }
6,639✔
123

124
    /// Bind to the given socket address.
125
    /// Returns the handle to the poll state and the bound address, used to key network poll events.
126
    pub fn bind(&mut self, addr: &SocketAddr) -> Result<(usize, SocketAddr), net_error> {
6,639✔
127
        let server = NetworkState::bind_address(addr)?;
6,639✔
128
        let next_server_event = self.next_event_id()?;
6,639✔
129

130
        self.poll
6,639✔
131
            .register(
6,639✔
132
                &server,
6,639✔
133
                mio::Token(next_server_event),
6,639✔
134
                Ready::all(),
6,639✔
135
                PollOpt::edge(),
6,639✔
136
            )
137
            .map_err(|e| {
6,639✔
138
                error!("Failed to register server socket: {:?}", &e);
×
139
                net_error::BindError
×
140
            })?;
×
141

142
        // N.B. the port for `addr` might be 0, in which case, `local_addr` may not be equal to
143
        // `addr` since the port will be system-assigned.  Use `local_adddr`.
144
        let local_addr = server.local_addr().map_err(|e| {
6,639✔
145
            error!("Failed to get local address for server: {:?}", &e);
×
146
            net_error::BindError
×
147
        })?;
×
148

149
        let network_server = NetworkServerState {
6,639✔
150
            addr: local_addr,
6,639✔
151
            server_socket: server,
6,639✔
152
            server_event: mio::Token(next_server_event),
6,639✔
153
        };
6,639✔
154

155
        assert!(
6,639✔
156
            !self.event_map.contains_key(&next_server_event),
6,639✔
157
            "BUG: failed to generate an unused server event ID"
158
        );
159

160
        self.servers.push(network_server);
6,639✔
161
        self.event_map.insert(next_server_event, 0); // server events always mapped to 0
6,639✔
162

163
        Ok((next_server_event, local_addr))
6,639✔
164
    }
6,639✔
165

166
    /// Register a socket for read/write notifications with this poller.
167
    /// Try to use the given hint_event_id value, but generate a different event ID if it's been
168
    /// taken.
169
    /// Return the actual event ID used (it may be different than hint_event_id)
170
    pub fn register(
1,124,913✔
171
        &mut self,
1,124,913✔
172
        server_event_id: usize,
1,124,913✔
173
        hint_event_id: usize,
1,124,913✔
174
        sock: &mio_net::TcpStream,
1,124,913✔
175
    ) -> Result<usize, net_error> {
1,124,913✔
176
        let hint_event_id = hint_event_id % (self.event_capacity + self.servers.len());
1,124,913✔
177
        if let Some(x) = self.event_map.get(&server_event_id) {
1,124,913✔
178
            if x != &0 {
1,124,913✔
179
                // not a server event
180
                error!(
10✔
181
                    "Server event ID {} not mapped to a server token, but to {}",
182
                    &server_event_id, x
10✔
183
                );
184
                return Err(net_error::RegisterError);
10✔
185
            }
1,124,903✔
186
        } else {
187
            // not a server event
188
            panic!("Not a server event ID: {}", &server_event_id);
×
189
        }
190

191
        // if the event ID is in use, then find another one
192
        let event_id = if self.event_map.contains_key(&hint_event_id) {
1,124,903✔
193
            self.next_event_id()?
39✔
194
        } else {
195
            hint_event_id
1,124,864✔
196
        };
197

198
        assert!(
1,124,902✔
199
            self.event_map.len() <= self.event_capacity + self.servers.len(),
1,124,902✔
200
            "BUG: event map exceeded event capacity ({} > {} + {})",
201
            self.event_map.len(),
×
202
            self.event_capacity,
203
            self.servers.len()
×
204
        );
205

206
        self.poll
1,124,902✔
207
            .register(sock, mio::Token(event_id), Ready::all(), PollOpt::edge())
1,124,902✔
208
            .map_err(|e| {
1,124,902✔
209
                error!(
×
210
                    "Failed to register socket on server {} event ID {} ({}): {:?}",
211
                    server_event_id, event_id, hint_event_id, &e
×
212
                );
213
                net_error::RegisterError
×
214
            })?;
×
215

216
        self.event_map.insert(event_id, server_event_id);
1,124,902✔
217

218
        debug!(
1,124,902✔
219
            "Socket registered: {}, hint {}, {:?} on server {} (Events total: {}, max: {})",
220
            event_id,
221
            hint_event_id,
222
            sock,
223
            server_event_id,
224
            self.event_map.len(),
×
225
            self.event_capacity
226
        );
227
        Ok(event_id)
1,124,902✔
228
    }
1,124,913✔
229

230
    /// Deregister a socket event
231
    pub fn deregister(
1,111,023✔
232
        &mut self,
1,111,023✔
233
        event_id: usize,
1,111,023✔
234
        sock: &mio_net::TcpStream,
1,111,023✔
235
    ) -> Result<(), net_error> {
1,111,023✔
236
        assert!(
1,111,023✔
237
            self.event_map.contains_key(&event_id),
1,111,023✔
238
            "BUG: no such socket {}",
239
            event_id
240
        );
241
        self.event_map.remove(&event_id);
1,111,023✔
242

243
        if let Err(e) = self.poll.deregister(sock) {
1,111,023✔
244
            warn!("Failed to deregister socket {}: {:?}", event_id, &e);
×
245
        };
1,111,023✔
246

247
        debug!(
1,111,023✔
248
            "Socket deregistered: {}, {:?} (Events total: {}, max: {})",
249
            event_id,
250
            sock,
251
            self.event_map.len(),
×
252
            self.event_capacity
253
        );
254

255
        if let Err(e) = sock.shutdown(Shutdown::Both) {
1,111,023✔
256
            debug!("Failed to shut down socket {}: {:?}", event_id, &e);
1,322✔
257
        }
1,109,701✔
258

259
        Ok(())
1,111,023✔
260
    }
1,111,023✔
261

262
    fn make_next_event_id(&self, cur_count: usize, in_use: &HashSet<usize>) -> Option<usize> {
1,131,610✔
263
        let mut ret = cur_count;
1,131,610✔
264

265
        let mut in_use_count = 0;
1,131,610✔
266
        let mut event_map_count = 0;
1,131,610✔
267

268
        for _ in 0..(self.event_capacity + self.servers.len()) {
1,131,610✔
269
            if self.event_map.contains_key(&ret) || in_use.contains(&ret) {
1,134,506✔
270
                ret = (ret + 1) % (self.event_capacity + self.servers.len());
2,937✔
271

272
                if in_use.contains(&ret) {
2,937✔
273
                    in_use_count += 1;
571✔
274
                } else {
2,366✔
275
                    event_map_count += 1;
2,366✔
276
                }
2,366✔
277
            } else {
278
                return Some(ret);
1,131,569✔
279
            }
280
        }
281

282
        debug!(
41✔
283
            "Too many peers (events: {}, in_use: {}, max: {})",
284
            event_map_count, in_use_count, self.event_capacity
285
        );
286
        None
41✔
287
    }
1,131,610✔
288

289
    /// next event ID
290
    pub fn next_event_id(&mut self) -> Result<usize, net_error> {
25,380✔
291
        let ret = self
25,380✔
292
            .make_next_event_id(self.count, &HashSet::new())
25,380✔
293
            .ok_or(net_error::TooManyPeers)?;
25,380✔
294
        self.count = (ret + 1) % (self.event_capacity + self.servers.len());
25,379✔
295
        Ok(ret)
25,379✔
296
    }
25,380✔
297

298
    /// Connect to a remote peer, but don't register it with the poll handle.
299
    /// The underlying connect(2) is _asynchronous_, so the caller will need to register it with a
300
    /// poll handle and wait for it to be connected.
301
    pub fn connect(
18,733✔
302
        addr: &SocketAddr,
18,733✔
303
        socket_send_buffer: u32,
18,733✔
304
        socket_recv_buffer: u32,
18,733✔
305
    ) -> Result<mio_net::TcpStream, net_error> {
18,733✔
306
        let stream = mio_net::TcpStream::connect(addr).map_err(|_e| {
18,733✔
307
            test_debug!("Failed to convert to mio stream: {:?}", &_e);
×
308
            net_error::ConnectionError
×
309
        })?;
×
310

311
        // set some helpful defaults
312
        // Don't go crazy on TIME_WAIT states; have them all die after 5 seconds
313
        stream
18,733✔
314
            .set_linger(Some(time::Duration::from_millis(5000)))
18,733✔
315
            .map_err(|e| {
18,733✔
316
                warn!("Failed to set SO_LINGER: {:?}", &e);
×
317
                net_error::ConnectionError
×
318
            })?;
×
319

320
        // Disable Nagle algorithm
321
        stream.set_nodelay(true).map_err(|_e| {
18,733✔
322
            warn!("Failed to set TCP_NODELAY: {:?}", &_e);
×
323
            net_error::ConnectionError
×
324
        })?;
×
325

326
        // Make sure keep-alive is on, since at least in p2p messages, we keep sockets around
327
        // for a while.  Linux default is 7200 seconds, so make sure we keep it here.
328
        stream
18,733✔
329
            .set_keepalive(Some(time::Duration::from_millis(7200 * 1000)))
18,733✔
330
            .map_err(|e| {
18,733✔
331
                warn!("Failed to set TCP_KEEPALIVE and/or SO_KEEPALIVE: {:?}", &e);
×
332
                net_error::ConnectionError
×
333
            })?;
×
334

335
        if cfg!(test) {
18,733✔
336
            if std::env::var("STACKS_TEST_DISABLE_EDGE_TRIGGER_TEST") != Ok("1".to_string()) {
10,768✔
337
                // edge-trigger torture test
10,743✔
338
                stream.set_send_buffer_size(32).unwrap();
10,743✔
339
                stream.set_recv_buffer_size(32).unwrap();
10,743✔
340
            }
10,743✔
341
        } else {
342
            stream
7,965✔
343
                .set_send_buffer_size(socket_send_buffer as usize)
7,965✔
344
                .map_err(|e| {
7,965✔
345
                    warn!(
×
346
                        "Failed to set socket write buffer size to {}: {:?}",
347
                        socket_send_buffer, &e
×
348
                    );
349
                    net_error::ConnectionError
×
350
                })?;
×
351

352
            stream
7,965✔
353
                .set_recv_buffer_size(socket_recv_buffer as usize)
7,965✔
354
                .map_err(|e| {
7,965✔
355
                    warn!(
×
356
                        "Failed to set socket read buffer size to {}: {:?}",
357
                        socket_send_buffer, &e
×
358
                    );
359
                    net_error::ConnectionError
×
360
                })?;
×
361
        }
362

363
        test_debug!("New socket connected to {:?}: {:?}", addr, &stream);
18,733✔
364
        Ok(stream)
18,733✔
365
    }
18,733✔
366

367
    /// Poll all server sockets.
368
    /// Returns a map between network server handles (returned by bind()) and their new polling state
369
    pub fn poll(&mut self, timeout: u64) -> Result<HashMap<usize, NetworkPollState>, net_error> {
10,386,016✔
370
        self.events.clear();
10,386,016✔
371
        self.poll
10,386,016✔
372
            .poll(&mut self.events, Some(Duration::from_millis(timeout)))
10,386,016✔
373
            .map_err(|e| {
10,386,016✔
374
                error!("Failed to poll: {:?}", &e);
×
375
                net_error::PollError
×
376
            })?;
×
377

378
        let mut poll_states = HashMap::new();
10,386,016✔
379
        for server in self.servers.iter() {
3✔
380
            // pre-populate with server tokens
3✔
381
            let server_event_id = usize::from(server.server_event);
3✔
382
            poll_states.insert(server_event_id, NetworkPollState::new());
3✔
383
        }
3✔
384

385
        let mut new_events = HashSet::new();
10,386,016✔
386

387
        for event in &self.events {
13,093,762✔
388
            let token = event.token();
12,042,179✔
389
            let mut is_server_event = false;
12,042,179✔
390

391
            for server in self.servers.iter() {
24,074,120✔
392
                // server token?
393
                if token == server.server_event {
24,074,120✔
394
                    // new inbound connection(s)
395
                    let poll_state =
801,895✔
396
                        poll_states.get_mut(&usize::from(token)).unwrap_or_else(|| {
801,895✔
397
                            panic!(
×
398
                                "BUG: FATAL: no poll state registered for server {}",
399
                                usize::from(token)
×
400
                            )
401
                        });
402

403
                    loop {
404
                        let (client_sock, client_addr) = match server.server_socket.accept() {
1,908,045✔
405
                            Ok((client_sock, client_addr)) => (client_sock, client_addr),
1,106,150✔
406
                            Err(e) => match e.kind() {
801,895✔
407
                                ErrorKind::WouldBlock => {
408
                                    break;
1✔
409
                                }
410
                                _ => {
411
                                    error!("Network error: {}", e);
522✔
412
                                    return Err(net_error::AcceptError);
522✔
413
                                }
414
                            },
415
                        };
416

417
                        // this does the same thing as next_event_id(), but we can't borrow self
418
                        // mutably here (so we'll just do the increment-mod directly).
419
                        let next_event_id = match self.make_next_event_id(self.count, &new_events) {
1,106,150✔
420
                            Some(eid) => eid,
1,106,150✔
421
                            None => {
422
                                // no poll slots available. Close the socket and carry on.
423
                                info!("Too many peers on {:?}, closing {:?} (events: {}, in-flight: {}, capacity: {})", &server.server_socket, &client_sock, self.event_map.len(), new_events.len(), self.event_capacity);
×
424
                                let _ = client_sock.shutdown(Shutdown::Both);
×
425
                                continue;
×
426
                            }
427
                        };
428

429
                        self.count =
1,106,150✔
430
                            (next_event_id + 1) % (self.event_capacity + self.servers.len());
1,106,150✔
431

432
                        new_events.insert(next_event_id);
1,106,150✔
433

434
                        debug!(
1,106,150✔
435
                            "New socket event: {}, {:?} addr={:?} (Events total: {}, max: {}) on server {:?}",
436
                            next_event_id,
437
                            &client_sock,
×
438
                            &client_addr,
×
439
                            self.event_map.len(),
×
440
                            self.event_capacity,
441
                            &server.server_socket
×
442
                        );
443

444
                        poll_state.new.insert(next_event_id, client_sock);
1,106,150✔
445
                    }
446

447
                    is_server_event = true;
1✔
448
                    break;
1✔
449
                }
23,272,225✔
450
            }
451

452
            if is_server_event {
1✔
453
                continue;
1✔
454
            }
11,240,284✔
455

456
            // event for a client of one of our servers.  which one?
457
            let event_id = usize::from(token);
11,240,284✔
458
            match self.event_map.get(&event_id) {
11,240,284✔
459
                Some(server_event_id) => {
11,240,284✔
460
                    if let Some(poll_state) = poll_states.get_mut(server_event_id) {
11,240,284✔
461
                        test_debug!(
11,240,284✔
462
                            "Wakeup socket event {} on server {}",
463
                            event_id,
464
                            server_event_id
465
                        );
466
                        poll_state.ready.push(event_id);
11,240,284✔
467
                    } else {
468
                        warn!("Unknown server event ID {}", server_event_id);
×
469
                    }
470
                }
471
                None => {
472
                    warn!("Surreptitious readiness event {}", event_id);
×
473
                }
474
            }
475
        }
476

477
        Ok(poll_states)
10,385,494✔
478
    }
10,386,016✔
479
}
480

481
#[cfg(test)]
482
mod test {
483
    use std::collections::HashSet;
484

485
    use super::*;
486

487
    #[test]
488
    fn test_bind() {
1✔
489
        let mut ns = NetworkState::new(100).unwrap();
1✔
490
        let mut server_events = HashSet::new();
1✔
491
        for _ in 0..10 {
1✔
492
            let addr = "127.0.0.1:0".parse::<SocketAddr>().unwrap();
10✔
493
            let (event_id, _local_addr) = ns.bind(&addr).unwrap();
10✔
494
            assert!(!server_events.contains(&event_id));
10✔
495
            server_events.insert(event_id);
10✔
496
        }
497
    }
1✔
498

499
    #[test]
500
    fn test_register_deregister() {
1✔
501
        let mut ns = NetworkState::new(100).unwrap();
1✔
502
        let mut server_events = vec![];
1✔
503
        let mut event_ids = HashSet::new();
1✔
504
        let mut ports = vec![];
1✔
505
        for _ in 0..10 {
10✔
506
            let addr = "127.0.0.1:0".parse::<SocketAddr>().unwrap();
10✔
507
            let (event_id, local_addr) = ns.bind(&addr).unwrap();
10✔
508
            server_events.push(event_id);
10✔
509
            event_ids.insert(event_id);
10✔
510

10✔
511
            ports.push(local_addr.port());
10✔
512
        }
10✔
513

514
        let mut client_events = vec![];
1✔
515
        for (i, port) in ports.iter().enumerate() {
10✔
516
            let addr = format!("127.0.0.1:{}", &port)
10✔
517
                .parse::<SocketAddr>()
10✔
518
                .unwrap();
10✔
519
            let sock = NetworkState::connect(&addr, 4096, 4096).unwrap();
10✔
520

521
            let event_id = ns.register(server_events[i], 1, &sock).unwrap();
10✔
522
            assert!(event_id != 0);
10✔
523
            assert!(!event_ids.contains(&event_id));
10✔
524
            ns.deregister(event_id, &sock).unwrap();
10✔
525

526
            let event_id = ns.register(server_events[i], 101, &sock).unwrap();
10✔
527
            assert!(event_id != 0);
10✔
528
            assert!(!event_ids.contains(&event_id));
10✔
529
            ns.deregister(event_id, &sock).unwrap();
10✔
530

531
            let event_id = ns
10✔
532
                .register(server_events[i], server_events[i], &sock)
10✔
533
                .unwrap();
10✔
534
            assert!(event_id != 0);
10✔
535
            assert!(!event_ids.contains(&event_id));
10✔
536
            ns.deregister(event_id, &sock).unwrap();
10✔
537

538
            let event_id = ns.register(server_events[i], 11, &sock).unwrap();
10✔
539
            assert!(!event_ids.contains(&event_id));
10✔
540

541
            event_ids.insert(event_id);
10✔
542
            client_events.push(event_id);
10✔
543
        }
544

545
        test_debug!("=====");
1✔
546
        for (i, port) in ports.iter().enumerate() {
10✔
547
            let addr = format!("127.0.0.1:{}", &port)
10✔
548
                .parse::<SocketAddr>()
10✔
549
                .unwrap();
10✔
550
            let sock = NetworkState::connect(&addr, 4096, 4096).unwrap();
10✔
551

552
            // can't use non-server events
553
            assert_eq!(
10✔
554
                Err(net_error::RegisterError),
555
                ns.register(client_events[i], i + 1, &sock)
10✔
556
            );
557
        }
558
    }
1✔
559

560
    #[test]
561
    fn test_register_too_many_peers() {
1✔
562
        let mut ns = NetworkState::new(10).unwrap();
1✔
563
        let mut event_ids = HashSet::new();
1✔
564
        let addr = "127.0.0.1:0".parse::<SocketAddr>().unwrap();
1✔
565
        let (server_event_id, local_addr) = ns.bind(&addr).unwrap();
1✔
566
        let port = local_addr.port();
1✔
567
        for _ in 0..10 {
1✔
568
            let addr = format!("127.0.0.1:{}", &port)
10✔
569
                .parse::<SocketAddr>()
10✔
570
                .unwrap();
10✔
571
            event_ids.insert(server_event_id);
10✔
572

573
            let sock = NetworkState::connect(&addr, 4096, 4096).unwrap();
10✔
574

575
            // register 10 client events
576
            let event_id = ns.register(server_event_id, 11, &sock).unwrap();
10✔
577
            assert!(!event_ids.contains(&event_id));
10✔
578
        }
579

580
        // the 11th socket should fail
581
        let addr = format!("127.0.0.1:{}", port).parse::<SocketAddr>().unwrap();
1✔
582
        let sock = NetworkState::connect(&addr, 4096, 4096).unwrap();
1✔
583
        let res = ns.register(server_event_id, 11, &sock);
1✔
584
        assert_eq!(Err(net_error::TooManyPeers), res);
1✔
585
    }
1✔
586

587
    #[test]
588
    fn test_register_deregister_stress() {
1✔
589
        let mut ns = NetworkState::new(20).unwrap();
1✔
590
        let count = 0;
1✔
591
        let mut in_use = HashSet::new();
1✔
592
        let mut events_in = vec![];
1✔
593

594
        for _ in 0..20 {
20✔
595
            let next_eid = ns.make_next_event_id(count, &in_use).unwrap();
20✔
596
            ns.event_map.insert(next_eid, 0);
20✔
597
            events_in.push(next_eid);
20✔
598
        }
20✔
599

600
        assert_eq!(ns.event_map.len(), 20);
1✔
601

602
        for _ in 0..20 {
1✔
603
            assert!(ns.make_next_event_id(count, &in_use).is_none());
20✔
604
        }
605

606
        for eid in events_in.iter() {
20✔
607
            ns.event_map.remove(eid);
20✔
608
        }
20✔
609

610
        events_in.clear();
1✔
611

612
        for _ in 0..20 {
20✔
613
            let next_eid = ns.make_next_event_id(count, &in_use).unwrap();
20✔
614
            events_in.push(next_eid);
20✔
615
            in_use.insert(next_eid);
20✔
616
        }
20✔
617

618
        assert!(ns.event_map.is_empty());
1✔
619

620
        for _ in 0..20 {
1✔
621
            assert!(ns.make_next_event_id(count, &in_use).is_none());
20✔
622
        }
623
    }
1✔
624
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc