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