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*/