You are an expert in writing code in many different languages. Your goal is to perform code completion for the following code, keeping in mind the rest of the code and the file meta data.
    Metadata details:
    filename: main.rs
    path of file: ./repos/cita/cita-network/src
    
    the code of the file until where you have to start completion: // Copyright Rivtower Technologies LLC.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

//! ## Summary
//!
//! One of the CITA's core components is used to implement the peer-to-peer network
//! and provide point-to-point connection interaction.
//!
//! ### Message queuing situation
//!
//! 1. Subscribe channel
//!
//!     |       Queue       | PubModule | Message Type          |
//!     | ----------------- | --------- | --------------------- |
//!     | network_tx        | Auth      | Request               |
//!     | network_consensus | Consensus | CompactSignedProposal |
//!     | network_consensus | Consensus | RawBytes              |
//!     | network           | Chain     | Status                |
//!     | network           | Chain     | SyncResponse          |
//!     | network           | Jsonrpc   | RequestNet            |
//!     | network           | Jsonrpc   | RequestPeersInfo      |
//!     | network           | Auth      | GetBlockTxn           |
//!     | network           | Auth      | BlockTxn              |
//!
//! 2. Publish channel
//!
//!     |       Queue       | PubModule | SubModule           | Message Type          |
//!     | ----------------- | --------- | ------------------- | --------------------- |
//!     | network           | Net       | Chain, Executor     | SyncResponse          |
//!     | network           | Net       | Snapshot            | SnapshotResp          |
//!     | network           | Net       | Jsonrpc             | Response              |
//!     | network_tx        | Net       | Auth                | Request               |
//!     | network_consensus | Net       | Consensus           | ComapctSignedProposal |
//!     | network_consensus | Net       | Consensus           | RawBytes              |
//!     | network           | Net       | Auth                | BlockTxn              |
//!     | network           | Net       | Auth                | GetBlockTxn           |
//!
//! ### p2p binary protocol
//! | Start      | Full length | Key length | Key value      | Message value    |
//! | ---------- | ----------- | ---------- | -------------- | ---------------- |
//! | \xDEADBEEF | u32         | u8(byte)   | bytes of a str | a serialize data |
//!
//! full_len = 1 + key_len + body_len
//!
//! ### Key behavoir
//!
//! the key struct:
//!
//! - [`Connection`]
//! - [`NetWork`]
//! - [`Synchronizer`]
//!
//! In addition to the `tokio_server`, there is an `Arc<Connection>` for
//! this st
    
fn main() {
    // init app
    let matches = App::new("network")
        .version(get_build_info_str(true))
        .long_version(get_build_info_str(false))
        .author("Rivtower")
        .about("CITA Block Chain Node powered by Rust")
        .args_from_usage(
            "-c, --config=[FILE] 'Sets a custom config file'
                        -a, --address=[FILE] 'Sets an address file'
                        -s, --stdout 'Log to console'",
        )
        .get_matches();

    let stdout = matches.is_present("stdout");
    micro_service_init!("cita-network", "CITA:network", stdout);
    info!("Version: {}", get_build_info_str(true));

    let config_file = matches.value_of("config").unwrap_or("network.toml");

    let config_path = Path::new(config_file);
    let mut dir = config_path
        .parent()
        .unwrap_or_else(|| Path::new(""))
        .to_str()
        .unwrap();
    if dir.is_empty() {
        dir = ".";
    }
    let fname = config_path
        .file_name()
        .expect("Wrong config file")
        .to_str()
        .unwrap()
        .to_string();

    // Init config
    debug!("Config path {:?}", config_path);
    let config = NetConfig::new(&config_file);
    debug!("Network config is {:?}", config_file);

    let addr_path = matches.value_of("address").unwrap_or("address");
    let own_addr = AddressConfig::new(&addr_path);
    debug!("Node address is {:?}", own_addr.addr);
    // End init config

    let mut nodes_mgr = NodesManager::from_config(config.clone(), own_addr.addr);
    let mut mq_agent = MqAgent::default();
    let mut synchronizer_mgr = Synchronizer::new(mq_agent.client(), nodes_mgr.client());
    let mut network_mgr = Network::new(
        mq_agent.client(),
        nodes_mgr.client(),
        synchronizer_mgr.client(),
    );
    mq_agent.set_nodes_mgr_client(nodes_mgr.client());
    mq_agent.set_network_client(network_mgr.client());

    let transfer_meta =
        create_transfer_meta(network_mgr.client(), nodes_mgr.client(), own_addr.addr);
    let mut service_cfg = ServiceBuilder::default()
        .insert_protocol(transfer_meta)
        .forever(true);

    let discovery_flag = config.enable_discovery.unwrap_or(true);
    let (tx, rx) = channel();
    let mut watcher: RecommendedWatcher =
        Watcher::new(tx, std::time::Duration::from_secs(NOTIFY_DELAY_SECS)).unwrap();
    if discovery_flag {
        let discovery_meta = create_discovery_meta(nodes_mgr.client());
        service_cfg = service_cfg.insert_protocol(discovery_meta);
    } else if watcher.watch(dir, RecursiveMode::NonRecursive).is_ok() {
        let notify_client = nodes_mgr.client();
        thread::spawn(move || {
            NodesManager::notify_config_change(rx, notify_client, fname);
        });
    }

    if config.enable_tls.unwrap_or(false) {
        service_cfg = service_cfg.key_pair(SecioKeyPair::secp256k1_generated());
    }
    let mut service = service_cfg.build(SHandle::new(nodes_mgr.client()));

    let addr = format!("/ip4/0.0.0.0/tcp/{}", config.port.unwrap_or(DEFAULT_PORT));
    let _ = service.listen(addr.parse().unwrap());
    nodes_mgr.set_service_task_sender(service.control().clone());
    // End init p2p protocols

    // Run system
    mq_agent.run();
    thread::spawn(move || nodes_mgr.run());
    thread::spawn(move || network_mgr.run());
    thread::spawn(move || synchronizer_mgr.run());
    tokio::run(service.for_each(|_| Ok(())));
    // End run system
}