consensus_config/
test_committee.rs1use std::net::{TcpListener, TcpStream};
5
6use mysten_network::Multiaddr;
7use rand::{SeedableRng as _, rngs::StdRng};
8
9use crate::{
10 Authority, AuthorityKeyPair, Committee, Epoch, NetworkKeyPair, ProtocolKeyPair, Stake,
11};
12
13pub fn local_committee_and_keys(
15 epoch: Epoch,
16 authorities_stake: Vec<Stake>,
17) -> (Committee, Vec<(NetworkKeyPair, ProtocolKeyPair)>) {
18 local_committee_and_keys_with_test_options(epoch, authorities_stake, true)
19}
20
21pub fn local_committee_and_keys_with_test_options(
22 epoch: Epoch,
23 authorities_stake: Vec<Stake>,
24 unused_port: bool,
25) -> (Committee, Vec<(NetworkKeyPair, ProtocolKeyPair)>) {
26 let mut authorities = vec![];
27 let mut key_pairs = vec![];
28 let mut rng = StdRng::from_seed([0; 32]);
29 for (i, stake) in authorities_stake.into_iter().enumerate() {
30 let authority_keypair = AuthorityKeyPair::generate(&mut rng);
31 let protocol_keypair = ProtocolKeyPair::generate(&mut rng);
32 let network_keypair = NetworkKeyPair::generate(&mut rng);
33 authorities.push(Authority {
34 stake,
35 address: if unused_port {
36 get_available_local_address()
37 } else {
38 "/ip4/127.0.0.1/udp/8081".parse().unwrap()
39 },
40 hostname: format!("test_host_{i}").to_string(),
41 authority_key: authority_keypair.public(),
42 protocol_key: protocol_keypair.public(),
43 network_key: network_keypair.public(),
44 });
45 key_pairs.push((network_keypair, protocol_keypair));
46 }
47
48 let committee = Committee::new(epoch, authorities);
49 (committee, key_pairs)
50}
51
52fn get_available_local_address() -> Multiaddr {
54 let host = "127.0.0.1";
55 let port = get_available_port(host);
56 format!("/ip4/{}/udp/{}", host, port).parse().unwrap()
57}
58
59fn get_available_port(host: &str) -> u16 {
63 const MAX_PORT_RETRIES: u32 = 1000;
64
65 for _ in 0..MAX_PORT_RETRIES {
66 if let Ok(port) = get_ephemeral_port(host) {
67 return port;
68 }
69 }
70
71 panic!("Error: could not find an available port");
72}
73
74fn get_ephemeral_port(host: &str) -> std::io::Result<u16> {
75 let listener = TcpListener::bind((host, 0))?;
77 let addr = listener.local_addr()?;
78
79 let _sender = TcpStream::connect(addr)?;
83 let _incoming = listener.accept()?;
84
85 Ok(addr.port())
86}