#[macro_use]
extern crate log;
#[macro_use]
extern crate unwrap;
#[macro_use]
extern crate serde_derive;
mod common;
use bincode;
use bytes::Bytes;
use common::Rpc;
use crossbeam_channel as mpmc;
use env_logger;
use quic_p2p::{Builder, Config, Event, Peer};
use serde_json;
use std::collections::HashMap;
use std::io;
use structopt::StructOpt;
#[derive(Serialize, Deserialize, StructOpt)]
pub struct BootstrapNodeConfig {
#[structopt(short, long)]
expected_conns: usize,
#[structopt(flatten)]
quic_p2p_opts: Config,
}
fn main() -> Result<(), io::Error> {
env_logger::init();
let bootstrap_node_config = BootstrapNodeConfig::from_args();
let (ev_tx, ev_rx) = mpmc::unbounded();
let mut qp2p = unwrap!(Builder::new(ev_tx)
.with_config(bootstrap_node_config.quic_p2p_opts)
.build());
let our_conn_info = unwrap!(qp2p.our_connection_info());
info!("QuicP2p started on {}", our_conn_info.peer_addr);
println!(
"Our connection info:\n{}\n",
unwrap!(serde_json::to_string(&our_conn_info)),
);
let expected_connections = bootstrap_node_config.expected_conns;
let mut connected_peers = HashMap::new();
let mut test_triggered = false;
for event in ev_rx.iter() {
match event {
Event::ConnectedTo { peer } => {
let peer_addr = match &peer {
Peer::Node { node_info } => node_info.peer_addr,
Peer::Client { .. } => panic!("In this example only Node peers are expected"),
};
let _ = connected_peers.insert(peer_addr, peer);
if connected_peers.len() == expected_connections && !test_triggered {
info!(
"{} connections collected, triggering the test",
expected_connections
);
let contacts: Vec<_> = connected_peers.values().cloned().collect();
let msg = Bytes::from(unwrap!(bincode::serialize(&Rpc::StartTest(contacts))));
for peer in connected_peers.values() {
qp2p.send(peer.clone(), msg.clone(), 0);
}
test_triggered = true;
} else if connected_peers.len() >= expected_connections {
error!("More than expected connections received");
}
}
event => warn!("Unexpected event: {:?}", event),
}
}
Ok(())
}