1pub use crate::{
25 discovery::DEFAULT_KADEMLIA_REPLICATION_FACTOR,
26 peer_store::PeerStoreProvider,
27 protocol::{notification_service, NotificationsSink, ProtocolHandlePair},
28 request_responses::{
29 IncomingRequest, OutgoingResponse, ProtocolConfig as RequestResponseConfig,
30 },
31 service::{
32 metrics::NotificationMetrics,
33 traits::{NotificationConfig, NotificationService, PeerStore},
34 },
35 types::ProtocolName,
36};
37
38pub use litep2p::protocol::libp2p::bitswap::BitswapHandle as Litep2pBitswapHandle;
39pub use sc_network_types::{build_multiaddr, ed25519};
40use sc_network_types::{
41 multiaddr::{self, Multiaddr},
42 PeerId,
43};
44
45use crate::{
46 service::{ensure_addresses_consistent_with_transport, traits::NetworkBackend},
47 webrtc,
48};
49use codec::Encode;
50use prometheus_endpoint::Registry;
51use zeroize::Zeroize;
52
53pub use sc_network_common::{
54 role::{Role, Roles},
55 sync::SyncMode,
56 ExHashT,
57};
58
59use sp_runtime::traits::Block as BlockT;
60
61use std::{
62 error::Error,
63 fmt, fs,
64 future::Future,
65 io::{self, Write},
66 iter,
67 net::Ipv4Addr,
68 num::NonZeroUsize,
69 path::{Path, PathBuf},
70 pin::Pin,
71 str::{self, FromStr},
72 sync::Arc,
73 time::Duration,
74};
75
76pub const DEFAULT_IDLE_CONNECTION_TIMEOUT: Duration = Duration::from_secs(10);
80
81pub const KADEMLIA_MAX_PROVIDER_KEYS: usize = 10000;
85
86pub const KADEMLIA_PROVIDER_RECORD_TTL: Duration = Duration::from_secs(10 * 3600);
90
91pub const KADEMLIA_PROVIDER_REPUBLISH_INTERVAL: Duration = Duration::from_secs(12600);
95
96#[derive(Clone, PartialEq, Eq, Hash)]
100pub struct ProtocolId(smallvec::SmallVec<[u8; 6]>);
101
102impl<'a> From<&'a str> for ProtocolId {
103 fn from(bytes: &'a str) -> ProtocolId {
104 Self(bytes.as_bytes().into())
105 }
106}
107
108impl AsRef<str> for ProtocolId {
109 fn as_ref(&self) -> &str {
110 str::from_utf8(&self.0[..])
111 .expect("the only way to build a ProtocolId is through a UTF-8 String; qed")
112 }
113}
114
115impl fmt::Debug for ProtocolId {
116 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
117 fmt::Debug::fmt(self.as_ref(), f)
118 }
119}
120
121pub fn parse_str_addr(addr_str: &str) -> Result<(PeerId, Multiaddr), ParseErr> {
136 let addr: Multiaddr = addr_str.parse()?;
137 parse_addr(addr)
138}
139
140pub fn parse_addr(mut addr: Multiaddr) -> Result<(PeerId, Multiaddr), ParseErr> {
142 let multihash = match addr.pop() {
143 Some(multiaddr::Protocol::P2p(multihash)) => multihash,
144 _ => return Err(ParseErr::PeerIdMissing),
145 };
146 let peer_id = PeerId::from_multihash(multihash).map_err(|_| ParseErr::InvalidPeerId)?;
147
148 Ok((peer_id, addr))
149}
150
151#[derive(Debug, Clone, serde::Serialize, serde::Deserialize, PartialEq)]
166#[serde(try_from = "String", into = "String")]
167pub struct MultiaddrWithPeerId {
168 pub multiaddr: Multiaddr,
170 pub peer_id: PeerId,
172}
173
174impl MultiaddrWithPeerId {
175 pub fn concat(&self) -> Multiaddr {
177 let mut addr = self.multiaddr.clone();
178 if matches!(addr.iter().last(), Some(multiaddr::Protocol::P2p(_))) {
180 addr.pop();
181 }
182 addr.with(multiaddr::Protocol::P2p(From::from(self.peer_id)))
183 }
184}
185
186impl fmt::Display for MultiaddrWithPeerId {
187 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
188 fmt::Display::fmt(&self.concat(), f)
189 }
190}
191
192impl FromStr for MultiaddrWithPeerId {
193 type Err = ParseErr;
194
195 fn from_str(s: &str) -> Result<Self, Self::Err> {
196 let (peer_id, multiaddr) = parse_str_addr(s)?;
197 Ok(Self { peer_id, multiaddr })
198 }
199}
200
201impl From<MultiaddrWithPeerId> for String {
202 fn from(ma: MultiaddrWithPeerId) -> String {
203 format!("{}", ma)
204 }
205}
206
207impl TryFrom<String> for MultiaddrWithPeerId {
208 type Error = ParseErr;
209 fn try_from(string: String) -> Result<Self, Self::Error> {
210 string.parse()
211 }
212}
213
214#[derive(Debug)]
216pub enum ParseErr {
217 MultiaddrParse(multiaddr::ParseError),
219 InvalidPeerId,
221 PeerIdMissing,
223}
224
225impl fmt::Display for ParseErr {
226 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
227 match self {
228 Self::MultiaddrParse(err) => write!(f, "{}", err),
229 Self::InvalidPeerId => write!(f, "Peer id at the end of the address is invalid"),
230 Self::PeerIdMissing => write!(f, "Peer id is missing from the address"),
231 }
232 }
233}
234
235impl std::error::Error for ParseErr {
236 fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
237 match self {
238 Self::MultiaddrParse(err) => Some(err),
239 Self::InvalidPeerId => None,
240 Self::PeerIdMissing => None,
241 }
242 }
243}
244
245impl From<multiaddr::ParseError> for ParseErr {
246 fn from(err: multiaddr::ParseError) -> ParseErr {
247 Self::MultiaddrParse(err)
248 }
249}
250
251#[derive(Debug, Clone)]
253pub struct NotificationHandshake(Vec<u8>);
254
255impl NotificationHandshake {
256 pub fn new<H: Encode>(handshake: H) -> Self {
258 Self(handshake.encode())
259 }
260
261 pub fn from_bytes(bytes: Vec<u8>) -> Self {
263 Self(bytes)
264 }
265}
266
267impl std::ops::Deref for NotificationHandshake {
268 type Target = Vec<u8>;
269
270 fn deref(&self) -> &Self::Target {
271 &self.0
272 }
273}
274
275#[derive(Clone, Debug)]
277pub enum TransportConfig {
278 Normal {
280 enable_mdns: bool,
283
284 allow_private_ip: bool,
288 },
289
290 MemoryOnly,
293}
294
295#[derive(Clone, Debug, PartialEq, Eq)]
297pub enum NonReservedPeerMode {
298 Accept,
300 Deny,
302}
303
304impl NonReservedPeerMode {
305 pub fn parse(s: &str) -> Option<Self> {
307 match s {
308 "accept" => Some(Self::Accept),
309 "deny" => Some(Self::Deny),
310 _ => None,
311 }
312 }
313
314 pub fn is_reserved_only(&self) -> bool {
316 matches!(self, NonReservedPeerMode::Deny)
317 }
318}
319
320#[derive(Clone, Debug)]
324pub enum NodeKeyConfig {
325 Ed25519(Secret<ed25519::SecretKey>),
327}
328
329impl Default for NodeKeyConfig {
330 fn default() -> NodeKeyConfig {
331 Self::Ed25519(Secret::New)
332 }
333}
334
335pub type Ed25519Secret = Secret<ed25519::SecretKey>;
337
338#[derive(Clone)]
340pub enum Secret<K> {
341 Input(K),
343 File(PathBuf),
349 New,
351}
352
353impl<K> fmt::Debug for Secret<K> {
354 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
355 match self {
356 Self::Input(_) => f.debug_tuple("Secret::Input").finish(),
357 Self::File(path) => f.debug_tuple("Secret::File").field(path).finish(),
358 Self::New => f.debug_tuple("Secret::New").finish(),
359 }
360 }
361}
362
363impl NodeKeyConfig {
364 pub fn into_keypair(self) -> io::Result<ed25519::Keypair> {
375 use NodeKeyConfig::*;
376 match self {
377 Ed25519(Secret::New) => Ok(ed25519::Keypair::generate()),
378
379 Ed25519(Secret::Input(k)) => Ok(ed25519::Keypair::from(k).into()),
380
381 Ed25519(Secret::File(f)) => get_secret(
382 f,
383 |mut b| match String::from_utf8(b.to_vec()).ok().and_then(|s| {
384 if s.len() == 64 {
385 array_bytes::hex2bytes(&s).ok()
386 } else {
387 None
388 }
389 }) {
390 Some(s) => ed25519::SecretKey::try_from_bytes(s),
391 _ => ed25519::SecretKey::try_from_bytes(&mut b),
392 },
393 ed25519::SecretKey::generate,
394 |b| b.as_ref().to_vec(),
395 )
396 .map(ed25519::Keypair::from),
397 }
398 }
399}
400
401fn get_secret<P, F, G, E, W, K>(file: P, parse: F, generate: G, serialize: W) -> io::Result<K>
405where
406 P: AsRef<Path>,
407 F: for<'r> FnOnce(&'r mut [u8]) -> Result<K, E>,
408 G: FnOnce() -> K,
409 E: Error + Send + Sync + 'static,
410 W: Fn(&K) -> Vec<u8>,
411{
412 std::fs::read(&file)
413 .and_then(|mut sk_bytes| {
414 parse(&mut sk_bytes).map_err(|e| io::Error::new(io::ErrorKind::InvalidData, e))
415 })
416 .or_else(|e| {
417 if e.kind() == io::ErrorKind::NotFound {
418 file.as_ref().parent().map_or(Ok(()), fs::create_dir_all)?;
419 let sk = generate();
420 let mut sk_vec = serialize(&sk);
421 write_secret_file(file, &sk_vec)?;
422 sk_vec.zeroize();
423 Ok(sk)
424 } else {
425 Err(e)
426 }
427 })
428}
429
430pub(super) fn write_secret_file<P>(path: P, sk_bytes: &[u8]) -> io::Result<()>
432where
433 P: AsRef<Path>,
434{
435 let mut file = open_secret_file(&path)?;
436 file.write_all(sk_bytes)
437}
438
439#[cfg(unix)]
441fn open_secret_file<P>(path: P) -> io::Result<fs::File>
442where
443 P: AsRef<Path>,
444{
445 use std::os::unix::fs::OpenOptionsExt;
446 fs::OpenOptions::new().write(true).create_new(true).mode(0o600).open(path)
447}
448
449#[cfg(not(unix))]
451fn open_secret_file<P>(path: P) -> Result<fs::File, io::Error>
452where
453 P: AsRef<Path>,
454{
455 fs::OpenOptions::new().write(true).create_new(true).open(path)
456}
457
458#[derive(Clone, Debug)]
460pub struct SetConfig {
461 pub in_peers: u32,
463
464 pub out_peers: u32,
466
467 pub reserved_nodes: Vec<MultiaddrWithPeerId>,
469
470 pub non_reserved_mode: NonReservedPeerMode,
473}
474
475impl Default for SetConfig {
476 fn default() -> Self {
477 Self {
478 in_peers: 25,
479 out_peers: 75,
480 reserved_nodes: Vec::new(),
481 non_reserved_mode: NonReservedPeerMode::Accept,
482 }
483 }
484}
485
486#[derive(Debug)]
491pub struct NonDefaultSetConfig {
492 protocol_name: ProtocolName,
498
499 fallback_names: Vec<ProtocolName>,
506
507 handshake: Option<NotificationHandshake>,
513
514 max_notification_size: u64,
516
517 set_config: SetConfig,
519
520 protocol_handle_pair: ProtocolHandlePair,
528}
529
530impl NonDefaultSetConfig {
531 pub fn new(
534 protocol_name: ProtocolName,
535 fallback_names: Vec<ProtocolName>,
536 max_notification_size: u64,
537 handshake: Option<NotificationHandshake>,
538 set_config: SetConfig,
539 ) -> (Self, Box<dyn NotificationService>) {
540 let (protocol_handle_pair, notification_service) =
541 notification_service(protocol_name.clone());
542 (
543 Self {
544 protocol_name,
545 max_notification_size,
546 fallback_names,
547 handshake,
548 set_config,
549 protocol_handle_pair,
550 },
551 notification_service,
552 )
553 }
554
555 pub fn protocol_name(&self) -> &ProtocolName {
557 &self.protocol_name
558 }
559
560 pub fn fallback_names(&self) -> impl Iterator<Item = &ProtocolName> {
562 self.fallback_names.iter()
563 }
564
565 pub fn handshake(&self) -> &Option<NotificationHandshake> {
567 &self.handshake
568 }
569
570 pub fn max_notification_size(&self) -> u64 {
572 self.max_notification_size
573 }
574
575 pub fn set_config(&self) -> &SetConfig {
577 &self.set_config
578 }
579
580 pub fn take_protocol_handle(self) -> ProtocolHandlePair {
582 self.protocol_handle_pair
583 }
584
585 pub fn allow_non_reserved(&mut self, in_peers: u32, out_peers: u32) {
587 self.set_config.in_peers = in_peers;
588 self.set_config.out_peers = out_peers;
589 self.set_config.non_reserved_mode = NonReservedPeerMode::Accept;
590 }
591
592 pub fn add_reserved(&mut self, peer: MultiaddrWithPeerId) {
594 self.set_config.reserved_nodes.push(peer);
595 }
596
597 pub fn add_fallback_names(&mut self, fallback_names: Vec<ProtocolName>) {
601 self.fallback_names.extend(fallback_names);
602 }
603}
604
605impl NotificationConfig for NonDefaultSetConfig {
606 fn set_config(&self) -> &SetConfig {
607 &self.set_config
608 }
609
610 fn protocol_name(&self) -> &ProtocolName {
612 &self.protocol_name
613 }
614}
615
616#[derive(Clone, Debug)]
618pub struct NetworkConfiguration {
619 pub net_config_path: Option<PathBuf>,
621
622 pub listen_addresses: Vec<Multiaddr>,
624
625 pub public_addresses: Vec<Multiaddr>,
627
628 pub boot_nodes: Vec<MultiaddrWithPeerId>,
630
631 pub node_key: NodeKeyConfig,
633
634 pub default_peers_set: SetConfig,
636
637 pub default_peers_set_num_full: u32,
642
643 pub client_version: String,
645
646 pub node_name: String,
648
649 pub transport: TransportConfig,
651
652 pub idle_connection_timeout: Duration,
656
657 pub max_parallel_downloads: u32,
659
660 pub max_blocks_per_request: u32,
662
663 pub min_peers_to_start_warp_sync: Option<usize>,
665
666 pub sync_mode: SyncMode,
668
669 pub enable_dht_random_walk: bool,
673
674 pub allow_non_globals_in_dht: bool,
676
677 pub kademlia_disjoint_query_paths: bool,
680
681 pub kademlia_replication_factor: NonZeroUsize,
686
687 pub ipfs_server: bool,
689
690 pub ipfs_bootnodes: Vec<MultiaddrWithPeerId>,
696
697 pub network_backend: NetworkBackendType,
699}
700
701impl NetworkConfiguration {
702 pub fn new<SN: Into<String>, SV: Into<String>>(
704 node_name: SN,
705 client_version: SV,
706 node_key: NodeKeyConfig,
707 net_config_path: Option<PathBuf>,
708 ) -> Self {
709 let default_peers_set = SetConfig::default();
710 Self {
711 net_config_path,
712 listen_addresses: Vec::new(),
713 public_addresses: Vec::new(),
714 boot_nodes: Vec::new(),
715 node_key,
716 default_peers_set_num_full: default_peers_set.in_peers + default_peers_set.out_peers,
717 default_peers_set,
718 client_version: client_version.into(),
719 node_name: node_name.into(),
720 transport: TransportConfig::Normal { enable_mdns: false, allow_private_ip: true },
721 idle_connection_timeout: DEFAULT_IDLE_CONNECTION_TIMEOUT,
722 max_parallel_downloads: 5,
723 max_blocks_per_request: 64,
724 min_peers_to_start_warp_sync: None,
725 sync_mode: SyncMode::Full,
726 enable_dht_random_walk: true,
727 allow_non_globals_in_dht: false,
728 kademlia_disjoint_query_paths: false,
729 kademlia_replication_factor: NonZeroUsize::new(DEFAULT_KADEMLIA_REPLICATION_FACTOR)
730 .expect("value is a constant; constant is non-zero; qed."),
731 ipfs_server: false,
732 ipfs_bootnodes: Vec::new(),
733 network_backend: NetworkBackendType::Litep2p,
734 }
735 }
736
737 pub fn new_local() -> NetworkConfiguration {
740 let mut config =
741 NetworkConfiguration::new("test-node", "test-client", Default::default(), None);
742
743 config.listen_addresses =
744 vec![iter::once(multiaddr::Protocol::Ip4(Ipv4Addr::new(127, 0, 0, 1)))
745 .chain(iter::once(multiaddr::Protocol::Tcp(0)))
746 .collect()];
747
748 config.allow_non_globals_in_dht = true;
749 config
750 }
751
752 pub fn new_memory() -> NetworkConfiguration {
755 let mut config =
756 NetworkConfiguration::new("test-node", "test-client", Default::default(), None);
757
758 config.listen_addresses =
759 vec![iter::once(multiaddr::Protocol::Ip4(Ipv4Addr::new(127, 0, 0, 1)))
760 .chain(iter::once(multiaddr::Protocol::Tcp(0)))
761 .collect()];
762
763 config.allow_non_globals_in_dht = true;
764 config
765 }
766
767 pub fn validate_and_complete_webrtc_addresses(&mut self) -> Result<(), crate::error::Error> {
774 let has_webrtc_addr = |addrs: &[Multiaddr]| addrs.iter().any(webrtc::is_webrtc_address);
775
776 let listen_webrtc = has_webrtc_addr(&self.listen_addresses);
777 let public_webrtc = has_webrtc_addr(&self.public_addresses);
778
779 if matches!(self.network_backend, NetworkBackendType::Libp2p) {
781 if listen_webrtc || public_webrtc {
782 return Err(crate::error::Error::WebRtcNotSupportedByBackend);
783 }
784 return Ok(());
785 }
786
787 match (listen_webrtc, public_webrtc) {
788 (false, false) => Ok(()),
790 (false, true) => Err(crate::error::Error::WebRtcTransportNotConfigured),
794 (true, _) => {
797 let keypair = self.node_key.clone().into_keypair()?;
798 self.node_key = NodeKeyConfig::Ed25519(Secret::Input(keypair.secret()));
801 let certificate = webrtc::derive_certificate(keypair.secret().into())
802 .map_err(crate::error::Error::Litep2p)?;
803 webrtc::validate_and_complete_addresses(
804 &self.listen_addresses,
805 &mut self.public_addresses,
806 certificate.certhash().into(),
807 )
808 },
809 }
810 }
811
812 pub fn remove_webrtc_addresses(&mut self) {
818 self.listen_addresses.retain(|address| !webrtc::is_webrtc_address(address));
819 self.public_addresses.retain(|address| {
820 let keep = !webrtc::is_webrtc_address(address);
821 if !keep {
822 log::warn!(
823 target: crate::LOG_TARGET,
824 "removing public WebRTC address {address}: no WebRTC listener on this node",
825 );
826 }
827 keep
828 });
829 }
830}
831
832pub struct IpfsConfig {
834 pub litep2p_bitswap_config: litep2p::protocol::libp2p::bitswap::Config,
836 pub block_provider: Box<dyn crate::IpfsBlockProvider>,
838 pub bootnodes: Vec<MultiaddrWithPeerId>,
840}
841
842impl IpfsConfig {
843 pub fn new(
845 block_provider: Box<dyn crate::IpfsBlockProvider>,
846 bootnodes: Vec<MultiaddrWithPeerId>,
847 ) -> (Self, Litep2pBitswapHandle) {
848 let (litep2p_bitswap_config, litep2p_handle) =
849 litep2p::protocol::libp2p::bitswap::Config::new();
850 (Self { litep2p_bitswap_config, block_provider, bootnodes }, litep2p_handle)
851 }
852}
853
854pub struct Params<Block: BlockT, H: ExHashT, N: NetworkBackend<Block, H>> {
856 pub role: Role,
858
859 pub executor: Box<dyn Fn(Pin<Box<dyn Future<Output = ()> + Send>>) + Send + Sync>,
861
862 pub network_config: FullNetworkConfiguration<Block, H, N>,
864
865 pub protocol_id: ProtocolId,
867
868 pub genesis_hash: Block::Hash,
870
871 pub fork_id: Option<String>,
874
875 pub metrics_registry: Option<Registry>,
877
878 pub block_announce_config: N::NotificationProtocolConfig,
880
881 pub ipfs_config: Option<IpfsConfig>,
883
884 pub notification_metrics: NotificationMetrics,
886}
887
888pub struct FullNetworkConfiguration<B: BlockT + 'static, H: ExHashT, N: NetworkBackend<B, H>> {
890 pub(crate) notification_protocols: Vec<N::NotificationProtocolConfig>,
892
893 pub(crate) request_response_protocols: Vec<N::RequestResponseProtocolConfig>,
895
896 pub network_config: NetworkConfiguration,
898
899 peer_store: Option<N::PeerStore>,
901
902 peer_store_handle: Arc<dyn PeerStoreProvider>,
904
905 pub metrics_registry: Option<Registry>,
907}
908
909impl<B: BlockT + 'static, H: ExHashT, N: NetworkBackend<B, H>> FullNetworkConfiguration<B, H, N> {
910 pub fn new(network_config: &NetworkConfiguration, metrics_registry: Option<Registry>) -> Self {
912 let bootnodes = network_config.boot_nodes.iter().map(|bootnode| bootnode.peer_id).collect();
913 let peer_store = N::peer_store(bootnodes, metrics_registry.clone());
914 let peer_store_handle = peer_store.handle();
915
916 Self {
917 peer_store: Some(peer_store),
918 peer_store_handle,
919 notification_protocols: Vec::new(),
920 request_response_protocols: Vec::new(),
921 network_config: network_config.clone(),
922 metrics_registry,
923 }
924 }
925
926 pub fn add_notification_protocol(&mut self, config: N::NotificationProtocolConfig) {
928 self.notification_protocols.push(config);
929 }
930
931 pub fn notification_protocols(&self) -> &Vec<N::NotificationProtocolConfig> {
933 &self.notification_protocols
934 }
935
936 pub fn add_request_response_protocol(&mut self, config: N::RequestResponseProtocolConfig) {
938 self.request_response_protocols.push(config);
939 }
940
941 pub fn peer_store_handle(&self) -> Arc<dyn PeerStoreProvider> {
943 Arc::clone(&self.peer_store_handle)
944 }
945
946 pub fn take_peer_store(&mut self) -> N::PeerStore {
954 self.peer_store
955 .take()
956 .expect("`PeerStore` can only be taken once when it's started; qed")
957 }
958
959 pub fn sanity_check_addresses(&self) -> Result<(), crate::error::Error> {
961 ensure_addresses_consistent_with_transport(
962 self.network_config.listen_addresses.iter(),
963 &self.network_config.transport,
964 )?;
965 ensure_addresses_consistent_with_transport(
966 self.network_config.boot_nodes.iter().map(|x| &x.multiaddr),
967 &self.network_config.transport,
968 )?;
969 ensure_addresses_consistent_with_transport(
970 self.network_config
971 .default_peers_set
972 .reserved_nodes
973 .iter()
974 .map(|x| &x.multiaddr),
975 &self.network_config.transport,
976 )?;
977
978 for notification_protocol in &self.notification_protocols {
979 ensure_addresses_consistent_with_transport(
980 notification_protocol.set_config().reserved_nodes.iter().map(|x| &x.multiaddr),
981 &self.network_config.transport,
982 )?;
983 }
984 ensure_addresses_consistent_with_transport(
985 self.network_config.public_addresses.iter(),
986 &self.network_config.transport,
987 )?;
988
989 Ok(())
990 }
991
992 pub fn sanity_check_bootnodes(&self) -> Result<(), crate::error::Error> {
994 self.network_config.boot_nodes.iter().try_for_each(|bootnode| {
995 if let Some(other) = self
996 .network_config
997 .boot_nodes
998 .iter()
999 .filter(|o| o.multiaddr == bootnode.multiaddr)
1000 .find(|o| o.peer_id != bootnode.peer_id)
1001 {
1002 Err(crate::error::Error::DuplicateBootnode {
1003 address: bootnode.multiaddr.clone().into(),
1004 first_id: bootnode.peer_id.into(),
1005 second_id: other.peer_id.into(),
1006 })
1007 } else {
1008 Ok(())
1009 }
1010 })
1011 }
1012
1013 pub fn known_addresses(&self) -> Vec<(PeerId, Multiaddr)> {
1015 let mut addresses: Vec<_> = self
1016 .network_config
1017 .default_peers_set
1018 .reserved_nodes
1019 .iter()
1020 .map(|reserved| (reserved.peer_id, reserved.multiaddr.clone()))
1021 .chain(self.notification_protocols.iter().flat_map(|protocol| {
1022 protocol
1023 .set_config()
1024 .reserved_nodes
1025 .iter()
1026 .map(|reserved| (reserved.peer_id, reserved.multiaddr.clone()))
1027 }))
1028 .chain(
1029 self.network_config
1030 .boot_nodes
1031 .iter()
1032 .map(|bootnode| (bootnode.peer_id, bootnode.multiaddr.clone())),
1033 )
1034 .collect();
1035
1036 addresses.sort();
1038 addresses.dedup();
1039
1040 addresses
1041 }
1042}
1043
1044#[derive(Debug, Clone, Default, Copy)]
1046pub enum NetworkBackendType {
1047 #[default]
1051 Litep2p,
1052
1053 Libp2p,
1060}
1061
1062#[cfg(test)]
1063mod tests {
1064 use super::*;
1065 use tempfile::TempDir;
1066
1067 fn tempdir_with_prefix(prefix: &str) -> TempDir {
1068 tempfile::Builder::new().prefix(prefix).tempdir().unwrap()
1069 }
1070
1071 fn secret_bytes(kp: ed25519::Keypair) -> Vec<u8> {
1072 kp.secret().to_bytes().into()
1073 }
1074
1075 #[test]
1076 fn test_secret_file() {
1077 let tmp = tempdir_with_prefix("x");
1078 std::fs::remove_dir(tmp.path()).unwrap(); let file = tmp.path().join("x").to_path_buf();
1080 let kp1 = NodeKeyConfig::Ed25519(Secret::File(file.clone())).into_keypair().unwrap();
1081 let kp2 = NodeKeyConfig::Ed25519(Secret::File(file.clone())).into_keypair().unwrap();
1082 assert!(file.is_file() && secret_bytes(kp1) == secret_bytes(kp2))
1083 }
1084
1085 #[test]
1086 fn test_secret_input() {
1087 let sk = ed25519::SecretKey::generate();
1088 let kp1 = NodeKeyConfig::Ed25519(Secret::Input(sk.clone())).into_keypair().unwrap();
1089 let kp2 = NodeKeyConfig::Ed25519(Secret::Input(sk)).into_keypair().unwrap();
1090 assert!(secret_bytes(kp1) == secret_bytes(kp2));
1091 }
1092
1093 #[test]
1094 fn test_secret_new() {
1095 let kp1 = NodeKeyConfig::Ed25519(Secret::New).into_keypair().unwrap();
1096 let kp2 = NodeKeyConfig::Ed25519(Secret::New).into_keypair().unwrap();
1097 assert!(secret_bytes(kp1) != secret_bytes(kp2));
1098 }
1099}