libp2p_kad/
record_priv.rs1pub mod store;
24
25use bytes::Bytes;
26use instant::Instant;
27use libp2p_core::{multihash::Multihash, Multiaddr};
28use libp2p_identity::PeerId;
29#[cfg(feature = "serde")]
30use serde::{Deserialize, Serialize};
31use std::borrow::Borrow;
32use std::hash::{Hash, Hasher};
33
34#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
36#[derive(Clone, Debug, PartialEq, Eq, Hash)]
37pub struct Key(Bytes);
38
39impl Key {
40 pub fn new<K: AsRef<[u8]>>(key: &K) -> Self {
42 Key(Bytes::copy_from_slice(key.as_ref()))
43 }
44
45 pub fn to_vec(&self) -> Vec<u8> {
47 Vec::from(&self.0[..])
48 }
49}
50
51impl Borrow<[u8]> for Key {
52 fn borrow(&self) -> &[u8] {
53 &self.0[..]
54 }
55}
56
57impl AsRef<[u8]> for Key {
58 fn as_ref(&self) -> &[u8] {
59 &self.0[..]
60 }
61}
62
63impl From<Vec<u8>> for Key {
64 fn from(v: Vec<u8>) -> Key {
65 Key(Bytes::from(v))
66 }
67}
68
69impl<const S: usize> From<Multihash<S>> for Key {
70 fn from(m: Multihash<S>) -> Key {
71 Key::from(m.to_bytes())
72 }
73}
74
75#[derive(Clone, Debug, Eq, PartialEq)]
77pub struct Record {
78 pub key: Key,
80 pub value: Vec<u8>,
82 pub publisher: Option<PeerId>,
84 pub expires: Option<Instant>,
86}
87
88impl Record {
89 pub fn new<K>(key: K, value: Vec<u8>) -> Self
91 where
92 K: Into<Key>,
93 {
94 Record {
95 key: key.into(),
96 value,
97 publisher: None,
98 expires: None,
99 }
100 }
101
102 pub fn is_expired(&self, now: Instant) -> bool {
104 self.expires.map_or(false, |t| now >= t)
105 }
106}
107
108#[derive(Clone, Debug)]
115pub struct ProviderRecord {
116 pub key: Key,
118 pub provider: PeerId,
120 pub expires: Option<Instant>,
122 pub addresses: Vec<Multiaddr>,
124}
125
126impl Hash for ProviderRecord {
127 fn hash<H: Hasher>(&self, state: &mut H) {
128 self.key.hash(state);
129 self.provider.hash(state);
130 }
131}
132
133impl PartialEq for ProviderRecord {
134 fn eq(&self, other: &Self) -> bool {
135 self.key == other.key && self.provider == other.provider
136 }
137}
138
139impl Eq for ProviderRecord {}
140
141impl ProviderRecord {
142 pub fn new<K>(key: K, provider: PeerId, addresses: Vec<Multiaddr>) -> Self
144 where
145 K: Into<Key>,
146 {
147 ProviderRecord {
148 key: key.into(),
149 provider,
150 expires: None,
151 addresses,
152 }
153 }
154
155 pub fn is_expired(&self, now: Instant) -> bool {
157 self.expires.map_or(false, |t| now >= t)
158 }
159}
160
161#[cfg(test)]
162mod tests {
163 use super::*;
164 use crate::SHA_256_MH;
165 use quickcheck::*;
166 use std::time::Duration;
167
168 impl Arbitrary for Key {
169 fn arbitrary(g: &mut Gen) -> Key {
170 let hash: [u8; 32] = core::array::from_fn(|_| u8::arbitrary(g));
171 Key::from(Multihash::<64>::wrap(SHA_256_MH, &hash).unwrap())
172 }
173 }
174
175 impl Arbitrary for Record {
176 fn arbitrary(g: &mut Gen) -> Record {
177 Record {
178 key: Key::arbitrary(g),
179 value: Vec::arbitrary(g),
180 publisher: if bool::arbitrary(g) {
181 Some(PeerId::random())
182 } else {
183 None
184 },
185 expires: if bool::arbitrary(g) {
186 Some(Instant::now() + Duration::from_secs(g.gen_range(0..60)))
187 } else {
188 None
189 },
190 }
191 }
192 }
193
194 impl Arbitrary for ProviderRecord {
195 fn arbitrary(g: &mut Gen) -> ProviderRecord {
196 ProviderRecord {
197 key: Key::arbitrary(g),
198 provider: PeerId::random(),
199 expires: if bool::arbitrary(g) {
200 Some(Instant::now() + Duration::from_secs(g.gen_range(0..60)))
201 } else {
202 None
203 },
204 addresses: vec![],
205 }
206 }
207 }
208}