discv5_cli/server/
bootstrap.rs

1use std::{fs::File, io::BufReader, str::FromStr};
2
3use discv5::{Discv5, Enr};
4use serde::{Deserialize, Serialize};
5
6/// The top level bootstrap object.
7#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq, Ord, PartialOrd, Hash)]
8pub struct BootstrapStore {
9    /// The list of bootstrap nodes.
10    pub data: Vec<BootstrapNode>,
11}
12
13/// A bootstrap node.
14#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq, Ord, PartialOrd, Hash)]
15pub struct BootstrapNode {
16    /// The node's peer id.
17    pub peer_id: String,
18    /// The node's ENR.
19    pub enr: String,
20    /// The last seen p2p address.
21    pub last_seen_p2p_address: String,
22    /// The node's state.
23    pub state: State,
24    /// The node's direction.
25    pub direction: Direction,
26}
27
28/// The direction of node connection.
29#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq, Ord, PartialOrd, Hash)]
30pub enum Direction {
31    /// An inbound connection
32    #[serde(rename = "inbound")]
33    Inbound,
34    /// An outbound connection
35    #[serde(rename = "outbound")]
36    Outbound,
37}
38
39/// The connection state.
40#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq, Ord, PartialOrd, Hash)]
41pub enum State {
42    /// Connected state
43    #[serde(rename = "connected")]
44    Connected,
45    /// Disconnected state
46    #[serde(rename = "disconnected")]
47    Disconnected,
48}
49
50/// Function to bootstrap peers using a JSON file.
51pub async fn boostrap(discv5: &mut Discv5, file: Option<String>) -> eyre::Result<()> {
52    if let Some(f) = file {
53        // Read the JSON bootstrap file
54        let file = File::open(f)?;
55        let reader = BufReader::new(file);
56        let bootstrap_store: BootstrapStore = serde_json::from_reader(reader)?;
57
58        // For each bootstrap node, try to connect to it.
59        for node in bootstrap_store.data {
60            // Skip over invalid enrs
61            if let Ok(enr) = Enr::from_str(&node.enr) {
62                let node_id = enr.node_id();
63                match discv5.add_enr(enr) {
64                    Err(_) => { /* log::warn!("Failed to bootstrap node with id: {node_id}") */ }
65                    Ok(_) => {
66                        log::debug!("Bootstrapped node: {node_id}");
67                    }
68                }
69            }
70        }
71    }
72
73    Ok(())
74}