diff --git a/Cargo.lock b/Cargo.lock index f0a133227b320..775a7fe99e1ee 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -21989,7 +21989,6 @@ dependencies = [ "futures", "futures-timer", "ip_network", - "libp2p", "linked_hash_set", "log", "multihash 0.19.1", @@ -23092,8 +23091,10 @@ name = "sc-network-types" version = "0.10.0" dependencies = [ "bs58", + "bytes", "ed25519-dalek", "libp2p-identity", + "libp2p-kad", "litep2p", "log", "multiaddr 0.18.1", diff --git a/prdoc/pr_5842.prdoc b/prdoc/pr_5842.prdoc new file mode 100644 index 0000000000000..0175c7583419b --- /dev/null +++ b/prdoc/pr_5842.prdoc @@ -0,0 +1,18 @@ +# Schema: Polkadot SDK PRDoc Schema (prdoc) v1.0.0 +# See doc at https://raw.githubusercontent.com/paritytech/polkadot-sdk/master/prdoc/schema_user.json + +title: Get rid of libp2p dependency in sc-authority-discovery + +doc: + - audience: Node Dev + description: | + Removes `libp2p` types in authority-discovery, and replace them with network backend agnostic types from `sc-network-types`. + The `sc-network` interface is therefore updated accordingly. + +crates: + - name: sc-network + bump: patch + - name: sc-network-types + bump: patch + - name: sc-authority-discovery + bump: patch diff --git a/substrate/client/authority-discovery/Cargo.toml b/substrate/client/authority-discovery/Cargo.toml index 09381ec6b553d..fc88d07ef936e 100644 --- a/substrate/client/authority-discovery/Cargo.toml +++ b/substrate/client/authority-discovery/Cargo.toml @@ -24,7 +24,6 @@ codec = { workspace = true } futures = { workspace = true } futures-timer = { workspace = true } ip_network = { workspace = true } -libp2p = { features = ["ed25519", "kad"], workspace = true } multihash = { workspace = true } linked_hash_set = { workspace = true } log = { workspace = true, default-features = true } diff --git a/substrate/client/authority-discovery/src/tests.rs b/substrate/client/authority-discovery/src/tests.rs index acfd0e61de019..a73515ee00d26 100644 --- a/substrate/client/authority-discovery/src/tests.rs +++ b/substrate/client/authority-discovery/src/tests.rs @@ -25,7 +25,7 @@ use crate::{ }; use futures::{channel::mpsc::channel, executor::LocalPool, task::LocalSpawn}; -use libp2p::identity::ed25519; +use sc_network_types::ed25519; use std::{collections::HashSet, sync::Arc}; use sc_network::{multiaddr::Protocol, Multiaddr, PeerId}; diff --git a/substrate/client/authority-discovery/src/worker.rs b/substrate/client/authority-discovery/src/worker.rs index 9319fbe6321e7..ba82910efcdf2 100644 --- a/substrate/client/authority-discovery/src/worker.rs +++ b/substrate/client/authority-discovery/src/worker.rs @@ -34,8 +34,8 @@ use futures::{channel::mpsc, future, stream::Fuse, FutureExt, Stream, StreamExt} use addr_cache::AddrCache; use codec::{Decode, Encode}; use ip_network::IpNetwork; -use libp2p::kad::{PeerRecord, Record}; use linked_hash_set::LinkedHashSet; +use sc_network_types::kad::{Key, PeerRecord, Record}; use log::{debug, error, trace}; use prometheus_endpoint::{register, Counter, CounterVec, Gauge, Opts, U64}; @@ -682,7 +682,7 @@ where async fn handle_put_record_requested( &mut self, - record_key: KademliaKey, + record_key: Key, record_value: Vec, publisher: Option, expires: Option, @@ -943,7 +943,7 @@ where authority_id, new_record.creation_time, current_record_info.creation_time, ); self.network.put_record_to( - current_record_info.record.clone(), + current_record_info.record.clone().into(), new_record.peers_with_record.clone(), // If this is empty it means we received the answer from our node local // storage, so we need to update that as well. diff --git a/substrate/client/authority-discovery/src/worker/schema/tests.rs b/substrate/client/authority-discovery/src/worker/schema/tests.rs index 557fa9641f97b..1dff1b93e06d1 100644 --- a/substrate/client/authority-discovery/src/worker/schema/tests.rs +++ b/substrate/client/authority-discovery/src/worker/schema/tests.rs @@ -26,9 +26,9 @@ mod schema_v2 { use super::*; use codec::Encode; -use libp2p::identity::Keypair; use prost::Message; use sc_network::{Multiaddr, PeerId}; +use sc_network_types::ed25519::Keypair; #[test] fn v2_decodes_v1() { @@ -61,7 +61,7 @@ fn v2_decodes_v1() { #[test] fn v1_decodes_v2() { - let peer_secret = Keypair::generate_ed25519(); + let peer_secret = Keypair::generate(); let peer_public = peer_secret.public(); let peer_id = peer_public.to_peer_id(); let multiaddress: Multiaddr = @@ -73,7 +73,7 @@ fn v1_decodes_v2() { let record_v2 = schema_v2::AuthorityRecord { addresses: vec_addresses.clone() }; let mut vec_record_v2 = vec![]; record_v2.encode(&mut vec_record_v2).unwrap(); - let vec_peer_public = peer_public.encode_protobuf(); + let vec_peer_public = peer_public.to_bytes().to_vec(); let peer_signature_v2 = PeerSignature { public_key: vec_peer_public, signature: vec_peer_signature }; let signed_record_v2 = SignedAuthorityRecord { @@ -97,7 +97,7 @@ fn v1_decodes_v2() { #[test] fn v1_decodes_v3() { - let peer_secret = Keypair::generate_ed25519(); + let peer_secret = Keypair::generate(); let peer_public = peer_secret.public(); let peer_id = peer_public.to_peer_id(); let multiaddress: Multiaddr = @@ -112,7 +112,7 @@ fn v1_decodes_v3() { }; let mut vec_record_v3 = vec![]; record_v3.encode(&mut vec_record_v3).unwrap(); - let vec_peer_public = peer_public.encode_protobuf(); + let vec_peer_public = peer_public.to_bytes().to_vec(); let peer_signature_v3 = PeerSignature { public_key: vec_peer_public, signature: vec_peer_signature }; let signed_record_v3 = SignedAuthorityRecord { @@ -136,7 +136,7 @@ fn v1_decodes_v3() { #[test] fn v3_decodes_v2() { - let peer_secret = Keypair::generate_ed25519(); + let peer_secret = Keypair::generate(); let peer_public = peer_secret.public(); let peer_id = peer_public.to_peer_id(); let multiaddress: Multiaddr = @@ -148,7 +148,7 @@ fn v3_decodes_v2() { let record_v2 = schema_v2::AuthorityRecord { addresses: vec_addresses.clone() }; let mut vec_record_v2 = vec![]; record_v2.encode(&mut vec_record_v2).unwrap(); - let vec_peer_public = peer_public.encode_protobuf(); + let vec_peer_public = peer_public.to_bytes().to_vec(); let peer_signature_v2 = schema_v2::PeerSignature { public_key: vec_peer_public, signature: vec_peer_signature }; let signed_record_v2 = schema_v2::SignedAuthorityRecord { diff --git a/substrate/client/authority-discovery/src/worker/tests.rs b/substrate/client/authority-discovery/src/worker/tests.rs index 8018b5ea492dc..6c3a3b56b1cbf 100644 --- a/substrate/client/authority-discovery/src/worker/tests.rs +++ b/substrate/client/authority-discovery/src/worker/tests.rs @@ -30,12 +30,14 @@ use futures::{ sink::SinkExt, task::LocalSpawn, }; -use libp2p::{identity::SigningError, kad::record::Key as KademliaKey}; use prometheus_endpoint::prometheus::default_registry; - use sc_client_api::HeaderBackend; -use sc_network::{service::signature::Keypair, Signature}; +use sc_network::{ + service::signature::{Keypair, SigningError}, + PublicKey, Signature, +}; use sc_network_types::{ + kad::Key as KademliaKey, multiaddr::{Multiaddr, Protocol}, PeerId, }; @@ -178,8 +180,8 @@ impl NetworkSigner for TestNetwork { signature: &Vec, message: &Vec, ) -> std::result::Result { - let public_key = libp2p::identity::PublicKey::try_decode_protobuf(&public_key) - .map_err(|error| error.to_string())?; + let public_key = + PublicKey::try_decode_protobuf(&public_key).map_err(|error| error.to_string())?; let peer_id: PeerId = peer_id.into(); let remote: PeerId = public_key.to_peer_id().into(); diff --git a/substrate/client/network/src/behaviour.rs b/substrate/client/network/src/behaviour.rs index 5ecbec52d507e..dbb72381b6604 100644 --- a/substrate/client/network/src/behaviour.rs +++ b/substrate/client/network/src/behaviour.rs @@ -375,18 +375,18 @@ impl From for BehaviourOut { }, DiscoveryOut::Discovered(peer_id) => BehaviourOut::Discovered(peer_id), DiscoveryOut::ValueFound(results, duration) => - BehaviourOut::Dht(DhtEvent::ValueFound(results), Some(duration)), + BehaviourOut::Dht(DhtEvent::ValueFound(results.into()), Some(duration)), DiscoveryOut::ValueNotFound(key, duration) => - BehaviourOut::Dht(DhtEvent::ValueNotFound(key), Some(duration)), + BehaviourOut::Dht(DhtEvent::ValueNotFound(key.into()), Some(duration)), DiscoveryOut::ValuePut(key, duration) => - BehaviourOut::Dht(DhtEvent::ValuePut(key), Some(duration)), + BehaviourOut::Dht(DhtEvent::ValuePut(key.into()), Some(duration)), DiscoveryOut::PutRecordRequest(record_key, record_value, publisher, expires) => BehaviourOut::Dht( - DhtEvent::PutRecordRequest(record_key, record_value, publisher, expires), + DhtEvent::PutRecordRequest(record_key.into(), record_value, publisher, expires), None, ), DiscoveryOut::ValuePutFailed(key, duration) => - BehaviourOut::Dht(DhtEvent::ValuePutFailed(key), Some(duration)), + BehaviourOut::Dht(DhtEvent::ValuePutFailed(key.into()), Some(duration)), DiscoveryOut::RandomKademliaStarted => BehaviourOut::RandomKademliaStarted, } } diff --git a/substrate/client/network/src/event.rs b/substrate/client/network/src/event.rs index 5400d11cb6ac2..626cf516a7ec2 100644 --- a/substrate/client/network/src/event.rs +++ b/substrate/client/network/src/event.rs @@ -22,12 +22,12 @@ use crate::types::ProtocolName; use bytes::Bytes; -use libp2p::{ - kad::{record::Key, PeerRecord}, - PeerId, -}; use sc_network_common::role::ObservedRole; +use sc_network_types::{ + kad::{Key, PeerRecord}, + PeerId, +}; /// Events generated by DHT as a response to get_value and put_value requests. #[derive(Debug, Clone)] diff --git a/substrate/client/network/src/litep2p/discovery.rs b/substrate/client/network/src/litep2p/discovery.rs index 9043f9420e8dc..3a9454e317ccd 100644 --- a/substrate/client/network/src/litep2p/discovery.rs +++ b/substrate/client/network/src/litep2p/discovery.rs @@ -27,7 +27,6 @@ use array_bytes::bytes2hex; use futures::{FutureExt, Stream}; use futures_timer::Delay; use ip_network::IpNetwork; -use libp2p::kad::record::Key as KademliaKey; use litep2p::{ protocol::{ libp2p::{ @@ -45,6 +44,7 @@ use litep2p::{ PeerId, ProtocolName, }; use parking_lot::RwLock; +use sc_network_types::kad::Key as KademliaKey; use schnellru::{ByLength, LruMap}; use std::{ diff --git a/substrate/client/network/src/litep2p/mod.rs b/substrate/client/network/src/litep2p/mod.rs index 87b9924236744..15501dab688b5 100644 --- a/substrate/client/network/src/litep2p/mod.rs +++ b/substrate/client/network/src/litep2p/mod.rs @@ -50,7 +50,6 @@ use crate::{ use codec::Encode; use futures::StreamExt; -use libp2p::kad::{PeerRecord, Record as P2PRecord, RecordKey}; use litep2p::{ config::ConfigBuilder, crypto::ed25519::Keypair, @@ -74,6 +73,7 @@ use litep2p::{ Litep2p, Litep2pEvent, ProtocolName as Litep2pProtocolName, }; use prometheus_endpoint::Registry; +use sc_network_types::kad::{Key as RecordKey, PeerRecord, Record as P2PRecord}; use sc_client_api::BlockBackend; use sc_network_common::{role::Roles, ExHashT}; @@ -711,8 +711,8 @@ impl NetworkBackend for Litep2pNetworkBac self.pending_put_values.insert(query_id, (key, Instant::now())); } NetworkServiceCommand::PutValueTo { record, peers, update_local_storage} => { - let kademlia_key = record.key.to_vec().into(); - let query_id = self.discovery.put_value_to_peers(record, peers, update_local_storage).await; + let kademlia_key = record.key.clone(); + let query_id = self.discovery.put_value_to_peers(record.into(), peers, update_local_storage).await; self.pending_put_values.insert(query_id, (kademlia_key, Instant::now())); } @@ -836,7 +836,7 @@ impl NetworkBackend for Litep2pNetworkBac self.event_streams.send( Event::Dht( DhtEvent::ValueFound( - record + record.into() ) ) ); @@ -864,7 +864,7 @@ impl NetworkBackend for Litep2pNetworkBac ); self.event_streams.send(Event::Dht( - DhtEvent::ValuePut(libp2p::kad::RecordKey::new(&key)) + DhtEvent::ValuePut(key) )); if let Some(ref metrics) = self.metrics { @@ -890,7 +890,7 @@ impl NetworkBackend for Litep2pNetworkBac ); self.event_streams.send(Event::Dht( - DhtEvent::ValuePutFailed(libp2p::kad::RecordKey::new(&key)) + DhtEvent::ValuePutFailed(key) )); if let Some(ref metrics) = self.metrics { @@ -908,7 +908,7 @@ impl NetworkBackend for Litep2pNetworkBac ); self.event_streams.send(Event::Dht( - DhtEvent::ValueNotFound(libp2p::kad::RecordKey::new(&key)) + DhtEvent::ValueNotFound(key) )); if let Some(ref metrics) = self.metrics { @@ -964,7 +964,7 @@ impl NetworkBackend for Litep2pNetworkBac Some(DiscoveryEvent::IncomingRecord { record: Record { key, value, publisher, expires }} ) => { self.event_streams.send(Event::Dht( DhtEvent::PutRecordRequest( - libp2p::kad::RecordKey::new(&key), + key.into(), value, publisher.map(Into::into), expires, diff --git a/substrate/client/network/src/litep2p/service.rs b/substrate/client/network/src/litep2p/service.rs index 693217f5ad94c..fa1d47e5a1b79 100644 --- a/substrate/client/network/src/litep2p/service.rs +++ b/substrate/client/network/src/litep2p/service.rs @@ -32,15 +32,15 @@ use crate::{ RequestFailure, Signature, }; -use crate::litep2p::Record; use codec::DecodeAll; use futures::{channel::oneshot, stream::BoxStream}; -use libp2p::{identity::SigningError, kad::record::Key as KademliaKey}; +use libp2p::identity::SigningError; use litep2p::{ addresses::PublicAddresses, crypto::ed25519::Keypair, types::multiaddr::Multiaddr as LiteP2pMultiaddr, }; use parking_lot::RwLock; +use sc_network_types::kad::{Key as KademliaKey, Record}; use sc_network_common::{ role::{ObservedRole, Roles}, @@ -266,12 +266,7 @@ impl NetworkDHTProvider for Litep2pNetworkService { let _ = self.cmd_tx.unbounded_send(NetworkServiceCommand::PutValue { key, value }); } - fn put_record_to( - &self, - record: libp2p::kad::Record, - peers: HashSet, - update_local_storage: bool, - ) { + fn put_record_to(&self, record: Record, peers: HashSet, update_local_storage: bool) { let _ = self.cmd_tx.unbounded_send(NetworkServiceCommand::PutValueTo { record: Record { key: record.key.to_vec().into(), diff --git a/substrate/client/network/src/service.rs b/substrate/client/network/src/service.rs index 71d0b45aa06da..438ef1ff7421d 100644 --- a/substrate/client/network/src/service.rs +++ b/substrate/client/network/src/service.rs @@ -68,7 +68,6 @@ use libp2p::{ core::{upgrade, ConnectedPoint, Endpoint}, identify::Info as IdentifyInfo, identity::ed25519, - kad::{record::Key as KademliaKey, Record}, multiaddr::{self, Multiaddr}, swarm::{ Config as SwarmConfig, ConnectionError, ConnectionId, DialError, Executor, ListenError, @@ -80,6 +79,7 @@ use log::{debug, error, info, trace, warn}; use metrics::{Histogram, MetricSources, Metrics}; use parking_lot::Mutex; use prometheus_endpoint::Registry; +use sc_network_types::kad::{Key as KademliaKey, Record}; use sc_client_api::BlockBackend; use sc_network_common::{ @@ -1455,17 +1455,17 @@ where fn handle_worker_message(&mut self, msg: ServiceToWorkerMsg) { match msg { ServiceToWorkerMsg::GetValue(key) => - self.network_service.behaviour_mut().get_value(key), + self.network_service.behaviour_mut().get_value(key.to_vec().into()), ServiceToWorkerMsg::PutValue(key, value) => - self.network_service.behaviour_mut().put_value(key, value), + self.network_service.behaviour_mut().put_value(key.to_vec().into(), value), ServiceToWorkerMsg::PutRecordTo { record, peers, update_local_storage } => self .network_service .behaviour_mut() - .put_record_to(record, peers, update_local_storage), + .put_record_to(record.into(), peers, update_local_storage), ServiceToWorkerMsg::StoreRecord(key, value, publisher, expires) => self .network_service .behaviour_mut() - .store_record(key, value, publisher, expires), + .store_record(key.to_vec().into(), value, publisher, expires), ServiceToWorkerMsg::AddKnownAddress(peer_id, addr) => self.network_service.behaviour_mut().add_known_address(peer_id, addr), ServiceToWorkerMsg::EventStream(sender) => self.event_streams.push(sender), diff --git a/substrate/client/network/src/service/traits.rs b/substrate/client/network/src/service/traits.rs index bd4f83c7fd440..f5dd2995acb14 100644 --- a/substrate/client/network/src/service/traits.rs +++ b/substrate/client/network/src/service/traits.rs @@ -32,12 +32,15 @@ use crate::{ }; use futures::{channel::oneshot, Stream}; -use libp2p::kad::Record; use prometheus_endpoint::Registry; use sc_client_api::BlockBackend; use sc_network_common::{role::ObservedRole, ExHashT}; -use sc_network_types::{multiaddr::Multiaddr, PeerId}; +pub use sc_network_types::{ + kad::{Key as KademliaKey, Record}, + multiaddr::Multiaddr, + PeerId, +}; use sp_runtime::traits::Block as BlockT; use std::{ @@ -49,7 +52,7 @@ use std::{ time::{Duration, Instant}, }; -pub use libp2p::{identity::SigningError, kad::record::Key as KademliaKey}; +pub use libp2p::identity::SigningError; /// Supertrait defining the services provided by [`NetworkBackend`] service handle. pub trait NetworkService: diff --git a/substrate/client/network/src/types.rs b/substrate/client/network/src/types.rs index 0652bbcdddecf..5289389de3818 100644 --- a/substrate/client/network/src/types.rs +++ b/substrate/client/network/src/types.rs @@ -26,8 +26,6 @@ use std::{ sync::Arc, }; -pub use libp2p::{multiaddr, Multiaddr, PeerId}; - /// The protocol name transmitted on the wire. #[derive(Debug, Clone)] pub enum ProtocolName { diff --git a/substrate/client/network/types/Cargo.toml b/substrate/client/network/types/Cargo.toml index 655f104111e41..7438eaeffcd2e 100644 --- a/substrate/client/network/types/Cargo.toml +++ b/substrate/client/network/types/Cargo.toml @@ -11,8 +11,10 @@ documentation = "https://docs.rs/sc-network-types" [dependencies] bs58 = { workspace = true, default-features = true } +bytes = { version = "1.4.0", default-features = false } ed25519-dalek = { workspace = true, default-features = true } libp2p-identity = { features = ["ed25519", "peerid", "rand"], workspace = true } +libp2p-kad = { version = "0.44.6", default-features = false } litep2p = { workspace = true } log = { workspace = true, default-features = true } multiaddr = { workspace = true } diff --git a/substrate/client/network/types/src/kad.rs b/substrate/client/network/types/src/kad.rs new file mode 100644 index 0000000000000..72028d356dc78 --- /dev/null +++ b/substrate/client/network/types/src/kad.rs @@ -0,0 +1,185 @@ +// This file is part of Substrate. + +// Copyright (C) Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: GPL-3.0-or-later WITH Classpath-exception-2.0 + +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +use crate::{multihash::Multihash, PeerId}; +use bytes::Bytes; +use libp2p_kad::RecordKey as Libp2pKey; +use litep2p::protocol::libp2p::kademlia::{Record as Litep2pRecord, RecordKey as Litep2pKey}; +use std::{error::Error, fmt, time::Instant}; + +/// The (opaque) key of a record. +#[derive(Clone, Debug, PartialEq, Eq, Hash)] +pub struct Key(Bytes); + +impl Key { + /// Creates a new key from the bytes of the input. + pub fn new>(key: &K) -> Self { + Key(Bytes::copy_from_slice(key.as_ref())) + } + + /// Copies the bytes of the key into a new vector. + pub fn to_vec(&self) -> Vec { + self.0.to_vec() + } +} + +impl AsRef<[u8]> for Key { + fn as_ref(&self) -> &[u8] { + &self.0[..] + } +} + +impl From> for Key { + fn from(v: Vec) -> Key { + Key(Bytes::from(v)) + } +} + +impl From for Key { + fn from(m: Multihash) -> Key { + Key::from(m.to_bytes()) + } +} + +impl From for Key { + fn from(key: Litep2pKey) -> Self { + Self::from(key.to_vec()) + } +} + +impl From for Litep2pKey { + fn from(key: Key) -> Self { + Self::from(key.to_vec()) + } +} + +impl From for Key { + fn from(key: Libp2pKey) -> Self { + Self::from(key.to_vec()) + } +} + +impl From for Libp2pKey { + fn from(key: Key) -> Self { + Self::from(key.to_vec()) + } +} + +/// A record stored in the DHT. +#[derive(Clone, Debug, Eq, PartialEq)] +pub struct Record { + /// Key of the record. + pub key: Key, + /// Value of the record. + pub value: Vec, + /// The (original) publisher of the record. + pub publisher: Option, + /// The expiration time as measured by a local, monotonic clock. + pub expires: Option, +} + +impl Record { + /// Creates a new record for insertion into the DHT. + pub fn new(key: Key, value: Vec) -> Self { + Record { key, value, publisher: None, expires: None } + } + + /// Checks whether the record is expired w.r.t. the given `Instant`. + pub fn is_expired(&self, now: Instant) -> bool { + self.expires.map_or(false, |t| now >= t) + } +} + +impl From for Record { + fn from(out: libp2p_kad::Record) -> Self { + let vec: Vec = out.key.to_vec(); + let key: Key = vec.into(); + let publisher = out.publisher.map(Into::into); + Record { key, value: out.value, publisher, expires: out.expires } + } +} + +impl From for Litep2pRecord { + fn from(val: Record) -> Self { + let vec: Vec = val.key.to_vec(); + let key: Litep2pKey = vec.into(); + let publisher = val.publisher.map(Into::into); + Litep2pRecord { key, value: val.value, publisher, expires: val.expires } + } +} + +impl From for libp2p_kad::Record { + fn from(a: Record) -> libp2p_kad::Record { + let peer = a.publisher.map(Into::into); + libp2p_kad::Record { + key: a.key.to_vec().into(), + value: a.value, + publisher: peer, + expires: a.expires, + } + } +} + +/// A record either received by the given peer or retrieved from the local +/// record store. +#[derive(Debug, Clone, PartialEq, Eq)] +pub struct PeerRecord { + /// The peer from whom the record was received. `None` if the record was + /// retrieved from local storage. + pub peer: Option, + pub record: Record, +} + +impl From for PeerRecord { + fn from(out: libp2p_kad::PeerRecord) -> Self { + let peer = out.peer.map(Into::into); + let record = out.record.into(); + PeerRecord { peer, record } + } +} + +/// An error during signing of a message. +#[derive(Debug)] +pub struct SigningError { + msg: String, + source: Option>, +} + +/// An error during encoding of key material. +#[allow(dead_code)] +impl SigningError { + pub(crate) fn new(msg: S) -> Self { + Self { msg: msg.to_string(), source: None } + } + + pub(crate) fn source(self, source: impl Error + Send + Sync + 'static) -> Self { + Self { source: Some(Box::new(source)), ..self } + } +} + +impl fmt::Display for SigningError { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + write!(f, "Key signing error: {}", self.msg) + } +} + +impl Error for SigningError { + fn source(&self) -> Option<&(dyn Error + 'static)> { + self.source.as_ref().map(|s| &**s as &dyn Error) + } +} diff --git a/substrate/client/network/types/src/lib.rs b/substrate/client/network/types/src/lib.rs index 5684e38ab2e84..093d81533f603 100644 --- a/substrate/client/network/types/src/lib.rs +++ b/substrate/client/network/types/src/lib.rs @@ -17,8 +17,8 @@ // along with this program. If not, see . pub mod ed25519; +pub mod kad; pub mod multiaddr; pub mod multihash; - mod peer_id; pub use peer_id::PeerId;