referrerpolicy=no-referrer-when-downgrade

sc_network_types/
kad.rs

1// This file is part of Substrate.
2
3// Copyright (C) Parity Technologies (UK) Ltd.
4// SPDX-License-Identifier: GPL-3.0-or-later WITH Classpath-exception-2.0
5
6// This program is free software: you can redistribute it and/or modify
7// it under the terms of the GNU General Public License as published by
8// the Free Software Foundation, either version 3 of the License, or
9// (at your option) any later version.
10
11// This program is distributed in the hope that it will be useful,
12// but WITHOUT ANY WARRANTY; without even the implied warranty of
13// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14// GNU General Public License for more details.
15
16// You should have received a copy of the GNU General Public License
17// along with this program. If not, see <https://www.gnu.org/licenses/>.
18
19use crate::{multihash::Multihash, PeerId};
20use bytes::Bytes;
21use libp2p_kad::RecordKey as Libp2pKey;
22use litep2p::protocol::libp2p::kademlia::{Record as Litep2pRecord, RecordKey as Litep2pKey};
23use std::{error::Error, fmt, time::Instant};
24
25/// The (opaque) key of a record.
26#[derive(Clone, Debug, PartialEq, Eq, Hash)]
27pub struct Key(Bytes);
28
29impl Key {
30	/// Creates a new key from the bytes of the input.
31	pub fn new<K: AsRef<[u8]>>(key: &K) -> Self {
32		Key(Bytes::copy_from_slice(key.as_ref()))
33	}
34
35	/// Copies the bytes of the key into a new vector.
36	pub fn to_vec(&self) -> Vec<u8> {
37		self.0.to_vec()
38	}
39}
40
41impl AsRef<[u8]> for Key {
42	fn as_ref(&self) -> &[u8] {
43		&self.0[..]
44	}
45}
46
47impl From<Vec<u8>> for Key {
48	fn from(v: Vec<u8>) -> Key {
49		Key(Bytes::from(v))
50	}
51}
52
53impl From<Multihash> for Key {
54	fn from(m: Multihash) -> Key {
55		Key::from(m.to_bytes())
56	}
57}
58
59impl From<Litep2pKey> for Key {
60	fn from(key: Litep2pKey) -> Self {
61		Self::from(key.to_vec())
62	}
63}
64
65impl From<Key> for Litep2pKey {
66	fn from(key: Key) -> Self {
67		Self::from(key.to_vec())
68	}
69}
70
71impl From<Libp2pKey> for Key {
72	fn from(key: Libp2pKey) -> Self {
73		Self::from(key.to_vec())
74	}
75}
76
77impl From<Key> for Libp2pKey {
78	fn from(key: Key) -> Self {
79		Self::from(key.to_vec())
80	}
81}
82
83/// A record stored in the DHT.
84#[derive(Clone, Debug, Eq, PartialEq)]
85pub struct Record {
86	/// Key of the record.
87	pub key: Key,
88	/// Value of the record.
89	pub value: Vec<u8>,
90	/// The (original) publisher of the record.
91	pub publisher: Option<PeerId>,
92	/// The expiration time as measured by a local, monotonic clock.
93	pub expires: Option<Instant>,
94}
95
96impl Record {
97	/// Creates a new record for insertion into the DHT.
98	pub fn new(key: Key, value: Vec<u8>) -> Self {
99		Record { key, value, publisher: None, expires: None }
100	}
101
102	/// Checks whether the record is expired w.r.t. the given `Instant`.
103	pub fn is_expired(&self, now: Instant) -> bool {
104		self.expires.is_some_and(|t| now >= t)
105	}
106}
107
108impl From<libp2p_kad::Record> for Record {
109	fn from(out: libp2p_kad::Record) -> Self {
110		let vec: Vec<u8> = out.key.to_vec();
111		let key: Key = vec.into();
112		let publisher = out.publisher.map(Into::into);
113		Record { key, value: out.value, publisher, expires: out.expires }
114	}
115}
116
117impl From<Record> for Litep2pRecord {
118	fn from(val: Record) -> Self {
119		let vec: Vec<u8> = val.key.to_vec();
120		let key: Litep2pKey = vec.into();
121		let publisher = val.publisher.map(Into::into);
122		Litep2pRecord { key, value: val.value, publisher, expires: val.expires }
123	}
124}
125
126impl From<Record> for libp2p_kad::Record {
127	fn from(a: Record) -> libp2p_kad::Record {
128		let peer = a.publisher.map(Into::into);
129		libp2p_kad::Record {
130			key: a.key.to_vec().into(),
131			value: a.value,
132			publisher: peer,
133			expires: a.expires,
134		}
135	}
136}
137
138/// A record either received by the given peer or retrieved from the local
139/// record store.
140#[derive(Debug, Clone, PartialEq, Eq)]
141pub struct PeerRecord {
142	/// The peer from whom the record was received. `None` if the record was
143	/// retrieved from local storage.
144	pub peer: Option<PeerId>,
145	pub record: Record,
146}
147
148impl From<libp2p_kad::PeerRecord> for PeerRecord {
149	fn from(out: libp2p_kad::PeerRecord) -> Self {
150		let peer = out.peer.map(Into::into);
151		let record = out.record.into();
152		PeerRecord { peer, record }
153	}
154}
155
156/// An error during signing of a message.
157#[derive(Debug)]
158pub struct SigningError {
159	msg: String,
160	source: Option<Box<dyn Error + Send + Sync>>,
161}
162
163/// An error during encoding of key material.
164#[allow(dead_code)]
165impl SigningError {
166	pub(crate) fn new<S: ToString>(msg: S) -> Self {
167		Self { msg: msg.to_string(), source: None }
168	}
169
170	pub(crate) fn source(self, source: impl Error + Send + Sync + 'static) -> Self {
171		Self { source: Some(Box::new(source)), ..self }
172	}
173}
174
175impl fmt::Display for SigningError {
176	fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
177		write!(f, "Key signing error: {}", self.msg)
178	}
179}
180
181impl Error for SigningError {
182	fn source(&self) -> Option<&(dyn Error + 'static)> {
183		self.source.as_ref().map(|s| &**s as &dyn Error)
184	}
185}