From 4339d55844fe12bffd211331877739010139606c Mon Sep 17 00:00:00 2001 From: momosh Date: Thu, 3 Aug 2023 19:29:52 +0200 Subject: [PATCH 1/4] renamed types and fixed readme --- README.md | 42 +++++++++++++++--------------- src/main.rs | 10 ++----- src/types.rs | 73 ++++++++++++++++++++++++++-------------------------- 3 files changed, 59 insertions(+), 66 deletions(-) diff --git a/README.md b/README.md index 64d599825..d4f545fb6 100644 --- a/README.md +++ b/README.md @@ -81,29 +81,29 @@ http_server_port = "7000" # If set to seed, keypair will be generated from that seed. # If set to key, a valid ed25519 private key must be provided, else the client will fail # If `secret_key` is not set, random seed will be used. -secret_key = { key = "1498b5467a63dffa2dc9d9e069caf075d16fc33fdd4c3b01bfadae6433767d93" } -# Libp2p service port range (port, range) (default: 37000). -libp2p_port = "37000" -# Configures LibP2P TCP port reuse for local sockets, which implies reuse of listening ports for outgoing connections to enhance NAT traversal capabilities (default: false) -libp2p_tcp_port_reuse = false -# Configures LibP2P AutoNAT behaviour to reject probes as a server for clients that are observed at a non-global ip address (default: false) -libp2p_autonat_only_global_ips = false -# Libp2p AutoNat throttle period for re-using a peer as server for a dial-request. (default: 1 sec) -libp2p_autonat_throttle = 1 +secret_key = { seed={seed} } +# P2P service port (default: 37000). +port = 3700 +# Configures TCP port reuse for local sockets, which implies reuse of listening ports for outgoing connections to enhance NAT traversal capabilities (default: false) +tcp_port_reuse = bool +# Configures AutoNAT behaviour to reject probes as a server for clients that are observed at a non-global ip address (default: false) +autonat_only_global_ips = false +# AutoNat throttle period for re-using a peer as server for a dial-request. (default: 1 sec) +autonat_throttle = 2 # Interval in which the NAT status should be re-tried if it is currently unknown or max confidence was not reached yet. (default: 10 sec) -libp2p_autonat_retry_interval = 10 +autonat_retry_interval = 10 # Interval in which the NAT should be tested again if max confidence was reached in a status. (default: 30 sec) -libp2p_autonat_refresh_interval = 30 -# Libp2p AutoNat on init delay before starting the fist probe. (default: 5 sec) -libp2p_autonat_boot_delay = 5 -# Sets libp2p application-specific version of the protocol family used by the peer. (default: "/avail_kad/id/1.0.0") -libp2p_identify_protocol = "/avail_kad/id/1.0.0" -# Sets libp2p agent version that is sent to peers. (default: "avail-light-client/rust-client") -libp2p_identify_agent = "avail-light-client/rust-client" -# Vector of Relay nodes, which are used for hole punching (default: empty) -relays = [["12D3KooWMm1c4pzeLPGkkCJMAgFbsfQ8xmVDusg272icWsaNHWzN", "/ip4/127.0.0.1/tcp/37000"]] -# Vector of IPFS bootstrap nodes, used to bootstrap DHT. If not set, light client acts as a bootstrap node, waiting for first peer to connect for DHT bootstrap (default: empty). -bootstraps = [["12D3KooWMm1c4pzeLPGkkCJMAgFbsfQ8xmVDusg272icWsaNHWzN", "/ip4/127.0.0.1/tcp/37000"]] +autonat_refresh_interval = 30 +# AutoNat on init delay before starting the fist probe. (default: 5 sec) +autonat_boot_delay = 10 +# Sets application-specific version of the protocol family used by the peer. (default: "/avail_kad/id/1.0.0") +identify_protocol = "/avail_kad/id/1.0.0" +# Sets agent version that is sent to peers. (default: "avail-light-client/rust-client") +identify_agent = "avail-light-client/rust-client" +# Vector of Light Client bootstrap nodes, used to bootstrap DHT. If not set, light client acts as a bootstrap node, waiting for first peer to connect for DHT bootstrap (default: empty). +bootstraps = [["12D3KooWE2xXc6C2JzeaCaEg7jvZLogWyjLsB5dA3iw5o3KcF9ds", "/ip4/13.51.79.255/udp/39000/quic-v1"]] +# Vector of Relay nodes, which are used for hole punching +relays = [["12D3KooWBETtE42fN7DZ5QsGgi7qfrN3jeYdXmBPL4peVTDmgG9b", "/ip4/13.49.44.246/udp/39111/quic-v1"]] # WebSocket endpoint of a full node for subscribing to the latest header, etc (default: ws://127.0.0.1:9944). full_node_ws = ["ws://127.0.0.1:9944"] # ID of application used to start application client. If app_id is not set, or set to 0, application client is not started (default: 0). diff --git a/src/main.rs b/src/main.rs index a90cfb1e1..d984dfce7 100644 --- a/src/main.rs +++ b/src/main.rs @@ -14,7 +14,6 @@ use clap::Parser; use consts::STATE_CF; use libp2p::{metrics::Metrics as LibP2PMetrics, multiaddr::Protocol, Multiaddr, PeerId}; use prometheus_client::registry::Registry; -use rand::{thread_rng, Rng}; use rocksdb::{ColumnFamilyDescriptor, Options, DB}; use tokio::sync::mpsc::{channel, Sender}; use tracing::{error, info, metadata::ParseLevelError, trace, warn, Level}; @@ -191,13 +190,8 @@ async fn run(error_sender: Sender) -> Result<()> { tokio::spawn(network_event_loop.run()); // Start listening on provided port - let port = if cfg.libp2p_port.1 > 0 { - let port: u16 = thread_rng().gen_range(cfg.libp2p_port.0..=cfg.libp2p_port.1); - info!("Using random port: {port}"); - port - } else { - cfg.libp2p_port.0 - }; + let port = cfg.port; + info!("Listening on port: {port}"); // always listen on UDP to prioritize QUIC network_client diff --git a/src/types.rs b/src/types.rs index db2011bb0..3c212abfd 100644 --- a/src/types.rs +++ b/src/types.rs @@ -198,25 +198,24 @@ pub struct RuntimeConfig { /// If set to key, a valid ed25519 private key must be provided, else the client will fail /// If `secret_key` is not set, random seed will be used. pub secret_key: Option, - /// Libp2p service port range (port, range) (default: 37000). - #[serde(with = "port_range_format")] - pub libp2p_port: (u16, u16), - /// Configures LibP2P TCP port reuse for local sockets, which implies reuse of listening ports for outgoing connections to enhance NAT traversal capabilities (default: false) - pub libp2p_tcp_port_reuse: bool, - /// Configures LibP2P AutoNAT behaviour to reject probes as a server for clients that are observed at a non-global ip address (default: false) - pub libp2p_autonat_only_global_ips: bool, - /// Libp2p AutoNat throttle period for re-using a peer as server for a dial-request. (default: 1 sec) - pub libp2p_autonat_throttle: u64, + /// P2P service port (default: 37000). + pub port: u16, + /// Configures TCP port reuse for local sockets, which implies reuse of listening ports for outgoing connections to enhance NAT traversal capabilities (default: false) + pub tcp_port_reuse: bool, + /// Configures AutoNAT behaviour to reject probes as a server for clients that are observed at a non-global ip address (default: false) + pub autonat_only_global_ips: bool, + /// AutoNat throttle period for re-using a peer as server for a dial-request. (default: 1 sec) + pub autonat_throttle: u64, /// Interval in which the NAT status should be re-tried if it is currently unknown or max confidence was not reached yet. (default: 10 sec) - pub libp2p_autonat_retry_interval: u64, + pub autonat_retry_interval: u64, /// Interval in which the NAT should be tested again if max confidence was reached in a status. (default: 30 sec) - pub libp2p_autonat_refresh_interval: u64, - /// Libp2p AutoNat on init delay before starting the fist probe. (default: 5 sec) - pub libp2p_autonat_boot_delay: u64, - /// Sets libp2p application-specific version of the protocol family used by the peer. (default: "/avail_kad/id/1.0.0") - pub libp2p_identify_protocol: String, - /// Sets libp2p agent version that is sent to peers. (default: "avail-light-client/rust-client") - pub libp2p_identify_agent: String, + pub autonat_refresh_interval: u64, + /// AutoNat on init delay before starting the fist probe. (default: 5 sec) + pub autonat_boot_delay: u64, + /// Sets application-specific version of the protocol family used by the peer. (default: "/avail_kad/id/1.0.0") + pub identify_protocol: String, + /// Sets agent version that is sent to peers. (default: "avail-light-client/rust-client") + pub identify_agent: String, /// Vector of Light Client bootstrap nodes, used to bootstrap DHT. If not set, light client acts as a bootstrap node, waiting for first peer to connect for DHT bootstrap (default: empty). pub bootstraps: Vec<(String, Multiaddr)>, /// Vector of Relay nodes, which are used for hole punching @@ -345,7 +344,7 @@ impl From<&RuntimeConfig> for LightClientConfig { pub struct LibP2PConfig { pub secret_key: Option, - pub port: (u16, u16), + pub port: u16, pub identify: IdentifyConfig, pub autonat: AutoNATConfig, pub kademlia: KademliaConfig, @@ -364,7 +363,7 @@ impl From<&RuntimeConfig> for LibP2PConfig { Self { secret_key: val.secret_key.clone(), - port: val.libp2p_port, + port: val.port, identify: val.into(), autonat: val.into(), kademlia: val.into(), @@ -423,11 +422,11 @@ pub struct AutoNATConfig { impl From<&RuntimeConfig> for AutoNATConfig { fn from(val: &RuntimeConfig) -> Self { Self { - retry_interval: Duration::from_secs(val.libp2p_autonat_retry_interval), - refresh_interval: Duration::from_secs(val.libp2p_autonat_refresh_interval), - boot_delay: Duration::from_secs(val.libp2p_autonat_boot_delay), - throttle_server_period: Duration::from_secs(val.libp2p_autonat_throttle), - only_global_ips: val.libp2p_autonat_only_global_ips, + retry_interval: Duration::from_secs(val.autonat_retry_interval), + refresh_interval: Duration::from_secs(val.autonat_refresh_interval), + boot_delay: Duration::from_secs(val.autonat_boot_delay), + throttle_server_period: Duration::from_secs(val.autonat_throttle), + only_global_ips: val.autonat_only_global_ips, } } } @@ -440,8 +439,8 @@ pub struct IdentifyConfig { impl From<&RuntimeConfig> for IdentifyConfig { fn from(val: &RuntimeConfig) -> Self { Self { - agent_version: val.libp2p_identify_agent.clone(), - protocol_version: val.libp2p_identify_protocol.clone(), + agent_version: val.identify_agent.clone(), + protocol_version: val.identify_protocol.clone(), } } } @@ -488,21 +487,21 @@ impl Default for RuntimeConfig { RuntimeConfig { http_server_host: "127.0.0.1".to_owned(), http_server_port: (7000, 0), - libp2p_port: (37000, 0), + port: 37000, secret_key: None, - libp2p_tcp_port_reuse: false, - libp2p_autonat_only_global_ips: false, - libp2p_autonat_refresh_interval: 30, - libp2p_autonat_retry_interval: 10, - libp2p_autonat_throttle: 1, - libp2p_autonat_boot_delay: 5, - libp2p_identify_protocol: "/avail_kad/id/1.0.0".to_string(), - libp2p_identify_agent: "avail-light-client/rust-client".to_string(), + tcp_port_reuse: false, + autonat_only_global_ips: false, + autonat_refresh_interval: 30, + autonat_retry_interval: 10, + autonat_throttle: 1, + autonat_boot_delay: 5, + identify_protocol: "/avail_kad/id/1.0.0".to_string(), + identify_agent: "avail-light-client/rust-client".to_string(), + bootstraps: Vec::new(), + relays: Vec::new(), full_node_ws: vec!["ws://127.0.0.1:9944".to_owned()], app_id: None, confidence: 92.0, - bootstraps: Vec::new(), - relays: Vec::new(), avail_path: "avail_path".to_owned(), log_level: "INFO".to_owned(), log_format_json: false, From c6782b0124fb4c45fabbb8d122f275d517c7a061 Mon Sep 17 00:00:00 2001 From: momosh Date: Thu, 3 Aug 2023 20:20:37 +0200 Subject: [PATCH 2/4] fixed typos --- src/network/event_loop.rs | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/network/event_loop.rs b/src/network/event_loop.rs index 06e5264d2..3bb9ef4fb 100644 --- a/src/network/event_loop.rs +++ b/src/network/event_loop.rs @@ -269,7 +269,7 @@ impl EventLoop { } }, SwarmEvent::Behaviour(BehaviourEvent::Identify(event)) => { - // record Indetify Behaviour events + // record Identify Behaviour events self.metrics.record(&event); match event { @@ -426,7 +426,7 @@ impl EventLoop { num_established, cause, } => { - trace!("Connection closed. PeerID: {peer_id:?}. Address: {:?}. Num establ: {num_established:?}. Cause: {cause:?}", endpoint.get_remote_address()); + trace!("Connection closed. PeerID: {peer_id:?}. Address: {:?}. Num established: {num_established:?}. Cause: {cause:?}", endpoint.get_remote_address()); if let Some(cause) = cause { match cause { @@ -554,7 +554,7 @@ impl EventLoop { } fn dump_hash_map_block_stats(&mut self) { - let mut occurence_map = HashMap::new(); + let mut occurrence_map = HashMap::new(); for record in self .swarm @@ -571,10 +571,10 @@ impl EventLoop { .split_once(':') .expect("unable to split the key string"); - let count = occurence_map.entry(block_num.to_string()).or_insert(0); + let count = occurrence_map.entry(block_num.to_string()).or_insert(0); *count += 1; } - let mut sorted: Vec<(&String, &i32)> = occurence_map.iter().collect(); + let mut sorted: Vec<(&String, &i32)> = occurrence_map.iter().collect(); sorted.sort_by(|a, b| a.0.cmp(b.0)); for (block_number, cell_count) in sorted { trace!( From 9ffcce095be685127312125e5cb49f838a04a798 Mon Sep 17 00:00:00 2001 From: momosh Date: Thu, 3 Aug 2023 20:20:59 +0200 Subject: [PATCH 3/4] added periodic bootstraps --- src/network/event_loop.rs | 214 +++++++++++++++++++++++++------------- src/network/mod.rs | 1 + src/types.rs | 5 + 3 files changed, 145 insertions(+), 75 deletions(-) diff --git a/src/network/event_loop.rs b/src/network/event_loop.rs index 3bb9ef4fb..ee79a43a9 100644 --- a/src/network/event_loop.rs +++ b/src/network/event_loop.rs @@ -1,11 +1,14 @@ -use std::collections::HashMap; +use std::{collections::HashMap, time::Duration}; use anyhow::Result; use async_std::stream::StreamExt; use itertools::Either; use rand::seq::SliceRandom; use std::str; -use tokio::sync::{mpsc, oneshot}; +use tokio::{ + sync::{mpsc, oneshot}, + time::{interval_at, Instant, Interval}, +}; use void::Void; use super::{ @@ -53,10 +56,43 @@ enum QueryChannel { Bootstrap(oneshot::Sender>), } -struct RelayReservation { +// RelayState keeps track of all things relay related +struct RelayState { + // id of the selected Relay that needs to be connected id: PeerId, + // Multiaddress of the selected Relay that needs to be connected address: Multiaddr, - is_reserved: bool, + // boolean value that signals if have established a circuit with the selected Relay + is_circuit_established: bool, + // list of available Relay nodes + nodes: Vec<(PeerId, Multiaddr)>, +} + +impl RelayState { + fn reset(&mut self) { + self.id = PeerId::random(); + self.address = Multiaddr::empty(); + self.is_circuit_established = false; + } + + fn select_random(&mut self) { + // choose relay by random + if let Some(relay) = self.nodes.choose(&mut rand::thread_rng()) { + let (id, addr) = relay.clone(); + // appoint this relay as our chosen one + self.id = id; + self.address = addr; + } + } +} + +// BootstrapState keeps track of all things bootstrap related +struct BootstrapState { + // referring to the initial bootstrap process, + // one that runs when the Light Client node starts up + is_startup_done: bool, + // timer that is responsible for firing periodic bootstraps + timer: Interval, } enum QueryState { @@ -75,8 +111,8 @@ pub struct EventLoop { pending_batch_complete: Option, metrics: Metrics, avail_metrics: AvailMetrics, - relay_nodes: Vec<(PeerId, Multiaddr)>, - relay_reservation: RelayReservation, + relay: RelayState, + bootstrap: BootstrapState, kad_remove_local_record: bool, } @@ -105,6 +141,7 @@ impl EventLoop { metrics: Metrics, avail_metrics: AvailMetrics, relay_nodes: Vec<(PeerId, Multiaddr)>, + bootstrap_interval: Duration, kad_remove_local_record: bool, ) -> Self { Self { @@ -117,11 +154,15 @@ impl EventLoop { pending_batch_complete: None, metrics, avail_metrics, - relay_nodes, - relay_reservation: RelayReservation { + relay: RelayState { id: PeerId::random(), address: Multiaddr::empty(), - is_reserved: Default::default(), + is_circuit_established: false, + nodes: relay_nodes, + }, + bootstrap: BootstrapState { + is_startup_done: false, + timer: interval_at(Instant::now() + bootstrap_interval, bootstrap_interval), }, kad_remove_local_record, } @@ -131,7 +172,12 @@ impl EventLoop { loop { tokio::select! { event = self.swarm.next() => self.handle_event(event.expect("Swarm stream should be infinite")).await, - Some(command) = self.command_receiver.recv() => self.handle_command(command).await, + command = self.command_receiver.recv() => match command { + Some(c) => self.handle_command(c), + // Command channel closed, thus shutting down the network event loop. + None => return, + }, + _ = self.bootstrap.timer.tick() => self.handle_periodic_bootstraps(), } } } @@ -278,54 +324,32 @@ impl EventLoop { info: Info { listen_addrs, .. }, } => { debug!("Identity Received from: {peer_id:?} on listen address: {listen_addrs:?}"); - // before we try and do a reservation with the relay - // we have to exchange observed addresses - // in this case relay needs to tell us our own - if peer_id == self.relay_reservation.id - && !self.relay_reservation.is_reserved - { - match self.swarm.listen_on( - self.relay_reservation - .address - .clone() - .with(Protocol::P2p(peer_id.into())) - .with(Protocol::P2pCircuit), - ) { - Ok(_) => { - self.relay_reservation.is_reserved = true; - }, - Err(e) => { - error!("Local node failed to listen on relay address. Error: {e:#?}"); - }, - } - } + self.establish_relay_circuit(peer_id); // only interested in addresses with actual Multiaddresses // ones that contains the 'p2p' tag - let addrs = listen_addrs + listen_addrs .into_iter() .filter(|a| a.to_string().contains(Protocol::P2p(peer_id.into()).tag())) - .collect::>(); - - for addr in addrs { - self.swarm - .behaviour_mut() - .kademlia - .add_address(&peer_id, addr.clone()); - - // if address contains relay circuit tag, - // dial that address for immediate Direct Connection Upgrade - if *self.swarm.local_peer_id() != peer_id - && addr.to_string().contains(Protocol::P2pCircuit.tag()) - { - _ = self.swarm.dial( - DialOpts::peer_id(peer_id) - .condition(PeerCondition::Disconnected) - .addresses(vec![addr.with(Protocol::P2pCircuit)]) - .build(), - ); - } - } + .for_each(|a| { + self.swarm + .behaviour_mut() + .kademlia + .add_address(&peer_id, a.clone()); + + // if address contains relay circuit tag, + // dial that address for immediate Direct Connection Upgrade + if *self.swarm.local_peer_id() != peer_id + && a.to_string().contains(Protocol::P2pCircuit.tag()) + { + _ = self.swarm.dial( + DialOpts::peer_id(peer_id) + .condition(PeerCondition::Disconnected) + .addresses(vec![a.with(Protocol::P2pCircuit)]) + .build(), + ); + } + }); }, IdentifyEvent::Sent { peer_id } => { debug!("Identity Sent event to: {peer_id:?}"); @@ -377,12 +401,8 @@ impl EventLoop { // if so, create reservation request with relay if new == NatStatus::Private || old == NatStatus::Private { info!("Autonat says we're still private."); - // choose relay by random - if let Some(relay) = self.relay_nodes.choose(&mut rand::thread_rng()) { - let (relay_id, relay_addr) = relay.clone(); - // appoint this relay as our chosen one - self.relay_reservation(relay_id, relay_addr); - } + // select a relay, try to dial it + self.select_and_dial_relay(); }; }, }, @@ -467,9 +487,9 @@ impl EventLoop { if let Some(peer_id) = peer_id { trace!("Error produced by peer with PeerId: {peer_id:?}"); // if the peer giving us problems is the chosen relay - // just remove it by reseting the reservatin state slot - if self.relay_reservation.id == peer_id { - self.reset_relay_reservation(); + // just remove it by resetting the reservation state slot + if self.relay.id == peer_id { + self.relay.reset(); } } }, @@ -480,7 +500,7 @@ impl EventLoop { } } - async fn handle_command(&mut self, command: Command) { + fn handle_command(&mut self, command: Command) { match command { Command::StartListening { addr, sender } => { _ = match self.swarm.listen_on(addr) { @@ -612,19 +632,63 @@ impl EventLoop { )); } - fn reset_relay_reservation(&mut self) { - self.relay_reservation = RelayReservation { - id: PeerId::random(), - address: Multiaddr::empty(), - is_reserved: false, - }; + fn handle_periodic_bootstraps(&mut self) { + // commence with periodic bootstraps, + // only when the initial startup bootstrap is done + if self.bootstrap.is_startup_done { + _ = self.swarm.behaviour_mut().kademlia.bootstrap(); + } } - fn relay_reservation(&mut self, id: PeerId, address: Multiaddr) { - self.relay_reservation = RelayReservation { - id, - address, - is_reserved: false, - }; + fn establish_relay_circuit(&mut self, peer_id: PeerId) { + // before we try and create a circuit with the relay + // we have to exchange observed addresses + // in this case we're waiting on relay to tell us our own + if peer_id == self.relay.id && !self.relay.is_circuit_established { + match self.swarm.listen_on( + self.relay + .address + .clone() + .with(Protocol::P2p(peer_id.into())) + .with(Protocol::P2pCircuit), + ) { + Ok(_) => { + info!("Relay circuit established with relay: {peer_id:?}"); + self.relay.is_circuit_established = true; + }, + Err(e) => { + // failed to establish a circuit, reset to try another relay + self.relay.reset(); + error!("Local node failed to listen on relay address. Error: {e:#?}"); + }, + } + } + } + + fn select_and_dial_relay(&mut self) { + // select a random relay from the list of known ones + self.relay.select_random(); + + // dial selected relay, + // so we don't wait on swarm to do it eventually + match self.swarm.dial( + DialOpts::peer_id(self.relay.id) + .condition(PeerCondition::NotDialing) + .addresses(vec![self.relay.address.clone()]) + .build(), + ) { + Ok(_) => { + info!("Dialing Relay: {id:?} succeeded.", id = self.relay.id); + }, + Err(e) => { + // got an error while dialing, + // better select a new relay and try again + self.relay.reset(); + error!( + "Dialing Relay: {id:?}, produced an error: {e:?}", + id = self.relay.id + ); + }, + } } } diff --git a/src/network/mod.rs b/src/network/mod.rs index 7c291d66b..cfc0dec30 100644 --- a/src/network/mod.rs +++ b/src/network/mod.rs @@ -185,6 +185,7 @@ pub fn init( metrics, avail_metrics, cfg.relays, + cfg.bootstrap_interval, kad_remove_local_record, ), )) diff --git a/src/types.rs b/src/types.rs index 3c212abfd..4819cdb49 100644 --- a/src/types.rs +++ b/src/types.rs @@ -218,6 +218,8 @@ pub struct RuntimeConfig { pub identify_agent: String, /// Vector of Light Client bootstrap nodes, used to bootstrap DHT. If not set, light client acts as a bootstrap node, waiting for first peer to connect for DHT bootstrap (default: empty). pub bootstraps: Vec<(String, Multiaddr)>, + /// Defines a period of time in which periodic bootstraps will be repeated. (default: 300 sec) + pub bootstrap_period: u64, /// Vector of Relay nodes, which are used for hole punching pub relays: Vec<(String, Multiaddr)>, /// WebSocket endpoint of full node for subscribing to latest header, etc (default: [ws://127.0.0.1:9944]). @@ -350,6 +352,7 @@ pub struct LibP2PConfig { pub kademlia: KademliaConfig, pub is_relay: bool, pub relays: Vec<(PeerId, Multiaddr)>, + pub bootstrap_interval: Duration, } impl From<&RuntimeConfig> for LibP2PConfig { @@ -369,6 +372,7 @@ impl From<&RuntimeConfig> for LibP2PConfig { kademlia: val.into(), is_relay: val.relays.is_empty(), relays: relay_nodes, + bootstrap_interval: Duration::from_secs(val.bootstrap_period), } } } @@ -498,6 +502,7 @@ impl Default for RuntimeConfig { identify_protocol: "/avail_kad/id/1.0.0".to_string(), identify_agent: "avail-light-client/rust-client".to_string(), bootstraps: Vec::new(), + bootstrap_period: 300, relays: Vec::new(), full_node_ws: vec!["ws://127.0.0.1:9944".to_owned()], app_id: None, From a2f0199334955942c4182313a721a5e48fc65fec Mon Sep 17 00:00:00 2001 From: momosh Date: Fri, 4 Aug 2023 07:24:40 +0200 Subject: [PATCH 4/4] starting periodic bootstraps after initial one --- src/network/event_loop.rs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/network/event_loop.rs b/src/network/event_loop.rs index ee79a43a9..eae3d617b 100644 --- a/src/network/event_loop.rs +++ b/src/network/event_loop.rs @@ -298,6 +298,8 @@ impl EventLoop { self.pending_kad_queries.remove(&id) { _ = ch.send(Ok(())); + // we can say that the startup bootstrap is done here + self.bootstrap.is_startup_done = true; } } },