massa_bootstrap/
lib.rs

1//! Copyright (c) 2022 MASSA LABS <info@massa.net>
2//! Bootstrap crate
3//!
4//! At start up, if now is after genesis timestamp,
5//! the node will bootstrap from one of the provided bootstrap servers.
6//!
7//! On server side, the server will query consensus for the graph and the ledger,
8//! execution for execution related data and network for the peer list.
9//!
10
11#![warn(missing_docs)]
12#![warn(unused_crate_dependencies)]
13// `BootstrapError` is large by design: it carries a `BootstrapServerMessage`.
14// Boxing it would be an API break, so the lint is silenced crate-wide rather
15// than on each of the ~40 fallible functions here.
16#![allow(clippy::result_large_err)]
17
18use massa_consensus_exports::bootstrapable_graph::BootstrapableGraph;
19use massa_final_state::FinalStateController;
20use massa_protocol_exports::BootstrapPeers;
21use parking_lot::RwLock;
22use std::sync::Arc;
23
24mod bindings;
25mod client;
26mod error;
27pub use error::BootstrapError;
28mod listener;
29mod messages;
30mod server;
31mod settings;
32mod tools;
33/// white/black list
34pub mod white_black_list;
35
36pub use client::{get_state, DefaultConnector};
37pub use listener::BootstrapTcpListener;
38pub use messages::{
39    BootstrapClientMessage, BootstrapClientMessageDeserializer, BootstrapClientMessageSerializer,
40    BootstrapServerMessage, BootstrapServerMessageDeserializer, BootstrapServerMessageSerializer,
41};
42pub use server::{start_bootstrap_server, BootstrapManager};
43pub use settings::IpType;
44pub use settings::{BootstrapConfig, BootstrapServerMessageDeserializerArgs};
45
46#[cfg(test)]
47pub(crate) mod tests;
48
49/// a collection of the bootstrap state snapshots of all relevant modules
50pub struct GlobalBootstrapState {
51    /// state of the final state
52    pub final_state: Arc<RwLock<dyn FinalStateController>>,
53
54    /// state of the consensus graph
55    pub graph: Option<BootstrapableGraph>,
56
57    /// list of network peers
58    pub peers: Option<BootstrapPeers>,
59}
60
61impl GlobalBootstrapState {
62    fn new(final_state: Arc<RwLock<dyn FinalStateController>>) -> Self {
63        Self {
64            final_state,
65            graph: None,
66            peers: None,
67        }
68    }
69}
70/*
71trait BindingReadExact: io::Read {
72    /// similar to std::io::Read::read_exact, but with a timeout that is function-global instead of per-individual-read
73    fn read_exact_timeout(
74        &mut self,
75        buf: &mut [u8],
76        deadline: Option<Instant>,
77    ) -> Result<(), (std::io::Error, usize)> {
78        let mut count = 0;
79        self.set_read_timeout(None).map_err(|err| (err, count))?;
80        while count < buf.len() {
81            // update the timeout
82            if let Some(deadline) = deadline {
83                let dur = deadline.saturating_duration_since(Instant::now());
84                if dur.is_zero() {
85                    return Err((
86                        std::io::Error::new(ErrorKind::TimedOut, "deadline has elapsed"),
87                        count,
88                    ));
89                }
90                self.set_read_timeout(Some(dur))
91                    .map_err(|err| (err, count))?;
92            }
93
94            // do the read
95            match self.read(&mut buf[count..]) {
96                Ok(0) => break,
97                Ok(n) => {
98                    count += n;
99                }
100                Err(ref e) if e.kind() == std::io::ErrorKind::Interrupted => {}
101                Err(e) => return Err((e, count)),
102            }
103        }
104        if count != buf.len() {
105            Err((
106                std::io::Error::new(ErrorKind::UnexpectedEof, "failed to fill whole buffer"),
107                count,
108            ))
109        } else {
110            Ok(())
111        }
112    }
113
114    /// Internal helper
115    fn set_read_timeout(&mut self, deadline: Option<Duration>) -> Result<(), std::io::Error>;
116}
117*/