1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
//! Copyright (c) 2022 MASSA LABS <info@massa.net>
//! Bootstrap crate
//!
//! At start up, if now is after genesis timestamp,
//! the node will bootstrap from one of the provided bootstrap servers.
//!
//! On server side, the server will query consensus for the graph and the ledger,
//! execution for execution related data and network for the peer list.
//!

#![warn(missing_docs)]
#![warn(unused_crate_dependencies)]

use massa_consensus_exports::bootstrapable_graph::BootstrapableGraph;
use massa_final_state::FinalStateController;
use massa_protocol_exports::BootstrapPeers;
use parking_lot::RwLock;
use std::sync::Arc;

mod bindings;
mod client;
mod error;
pub use error::BootstrapError;
mod listener;
mod messages;
mod server;
mod settings;
mod tools;
/// white/black list
pub mod white_black_list;

pub use client::{get_state, DefaultConnector};
pub use listener::BootstrapTcpListener;
pub use messages::{
    BootstrapClientMessage, BootstrapClientMessageDeserializer, BootstrapClientMessageSerializer,
    BootstrapServerMessage, BootstrapServerMessageDeserializer, BootstrapServerMessageSerializer,
};
pub use server::{start_bootstrap_server, BootstrapManager};
pub use settings::IpType;
pub use settings::{BootstrapConfig, BootstrapServerMessageDeserializerArgs};

#[cfg(test)]
pub(crate) mod tests;

/// a collection of the bootstrap state snapshots of all relevant modules
pub struct GlobalBootstrapState {
    /// state of the final state
    pub final_state: Arc<RwLock<dyn FinalStateController>>,

    /// state of the consensus graph
    pub graph: Option<BootstrapableGraph>,

    /// list of network peers
    pub peers: Option<BootstrapPeers>,
}

impl GlobalBootstrapState {
    fn new(final_state: Arc<RwLock<dyn FinalStateController>>) -> Self {
        Self {
            final_state,
            graph: None,
            peers: None,
        }
    }
}
/*
trait BindingReadExact: io::Read {
    /// similar to std::io::Read::read_exact, but with a timeout that is function-global instead of per-individual-read
    fn read_exact_timeout(
        &mut self,
        buf: &mut [u8],
        deadline: Option<Instant>,
    ) -> Result<(), (std::io::Error, usize)> {
        let mut count = 0;
        self.set_read_timeout(None).map_err(|err| (err, count))?;
        while count < buf.len() {
            // update the timeout
            if let Some(deadline) = deadline {
                let dur = deadline.saturating_duration_since(Instant::now());
                if dur.is_zero() {
                    return Err((
                        std::io::Error::new(ErrorKind::TimedOut, "deadline has elapsed"),
                        count,
                    ));
                }
                self.set_read_timeout(Some(dur))
                    .map_err(|err| (err, count))?;
            }

            // do the read
            match self.read(&mut buf[count..]) {
                Ok(0) => break,
                Ok(n) => {
                    count += n;
                }
                Err(ref e) if e.kind() == std::io::ErrorKind::Interrupted => {}
                Err(e) => return Err((e, count)),
            }
        }
        if count != buf.len() {
            Err((
                std::io::Error::new(ErrorKind::UnexpectedEof, "failed to fill whole buffer"),
                count,
            ))
        } else {
            Ok(())
        }
    }

    /// Internal helper
    fn set_read_timeout(&mut self, deadline: Option<Duration>) -> Result<(), std::io::Error>;
}
*/