subspace_core_primitives/
lib.rs1#![cfg_attr(not(feature = "std"), no_std)]
4#![warn(rust_2018_idioms, missing_docs)]
5#![cfg_attr(feature = "std", warn(missing_debug_implementations))]
6#![feature(const_trait_impl, const_try, portable_simd, step_trait)]
7
8pub mod checksum;
9pub mod hashes;
10pub mod objects;
11pub mod pieces;
12pub mod pos;
13pub mod pot;
14pub mod sectors;
15pub mod segments;
16pub mod solutions;
17#[cfg(test)]
18mod tests;
19
20use crate::hashes::{Blake3Hash, blake3_hash, blake3_hash_list};
21use core::fmt;
22use derive_more::{Add, AsMut, AsRef, Deref, DerefMut, Display, Div, From, Into, Mul, Rem, Sub};
23use num_traits::{WrappingAdd, WrappingSub};
24use parity_scale_codec::{Decode, DecodeWithMemTracking, Encode, MaxEncodedLen};
25use scale_info::TypeInfo;
26#[cfg(feature = "serde")]
27use serde::{Deserialize, Serialize};
28#[cfg(feature = "serde")]
29use serde::{Deserializer, Serializer};
30use static_assertions::const_assert;
31
32const_assert!(core::mem::size_of::<usize>() >= core::mem::size_of::<u32>());
34
35pub const REWARD_SIGNING_CONTEXT: &[u8] = b"subspace_reward";
37
38#[derive(
40 Default, Copy, Clone, Eq, PartialEq, From, Into, Deref, Encode, Decode, TypeInfo, MaxEncodedLen,
41)]
42pub struct Randomness([u8; Randomness::SIZE]);
43
44impl fmt::Debug for Randomness {
45 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
46 write!(f, "{}", hex::encode(self.0))
47 }
48}
49
50#[cfg(feature = "serde")]
51#[derive(Serialize, Deserialize)]
52#[serde(transparent)]
53struct RandomnessBinary([u8; Randomness::SIZE]);
54
55#[cfg(feature = "serde")]
56#[derive(Serialize, Deserialize)]
57#[serde(transparent)]
58struct RandomnessHex(#[serde(with = "hex")] [u8; Randomness::SIZE]);
59
60#[cfg(feature = "serde")]
61impl Serialize for Randomness {
62 #[inline]
63 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
64 where
65 S: Serializer,
66 {
67 if serializer.is_human_readable() {
68 RandomnessHex(self.0).serialize(serializer)
69 } else {
70 RandomnessBinary(self.0).serialize(serializer)
71 }
72 }
73}
74
75#[cfg(feature = "serde")]
76impl<'de> Deserialize<'de> for Randomness {
77 #[inline]
78 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
79 where
80 D: Deserializer<'de>,
81 {
82 Ok(Self(if deserializer.is_human_readable() {
83 RandomnessHex::deserialize(deserializer)?.0
84 } else {
85 RandomnessBinary::deserialize(deserializer)?.0
86 }))
87 }
88}
89
90impl AsRef<[u8]> for Randomness {
91 #[inline]
92 fn as_ref(&self) -> &[u8] {
93 &self.0
94 }
95}
96
97impl AsMut<[u8]> for Randomness {
98 #[inline]
99 fn as_mut(&mut self) -> &mut [u8] {
100 &mut self.0
101 }
102}
103
104impl Randomness {
105 pub const SIZE: usize = 32;
107
108 pub fn derive_global_challenge(&self, slot: SlotNumber) -> Blake3Hash {
111 blake3_hash_list(&[&self.0, &slot.to_le_bytes()])
112 }
113}
114
115pub type BlockNumber = u32;
117
118pub type BlockHash = [u8; 32];
120
121pub type SlotNumber = u64;
123
124pub type BlockForkWeight = u128;
128
129#[derive(
131 Default,
132 Copy,
133 Clone,
134 PartialEq,
135 Eq,
136 Ord,
137 PartialOrd,
138 Hash,
139 Encode,
140 Decode,
141 TypeInfo,
142 Deref,
143 From,
144 Into,
145 DecodeWithMemTracking,
146)]
147pub struct PublicKey([u8; PublicKey::SIZE]);
148
149impl fmt::Debug for PublicKey {
150 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
151 write!(f, "{}", hex::encode(self.0))
152 }
153}
154
155#[cfg(feature = "serde")]
156#[derive(Serialize, Deserialize)]
157#[serde(transparent)]
158struct PublicKeyBinary([u8; PublicKey::SIZE]);
159
160#[cfg(feature = "serde")]
161#[derive(Serialize, Deserialize)]
162#[serde(transparent)]
163struct PublicKeyHex(#[serde(with = "hex")] [u8; PublicKey::SIZE]);
164
165#[cfg(feature = "serde")]
166impl Serialize for PublicKey {
167 #[inline]
168 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
169 where
170 S: Serializer,
171 {
172 if serializer.is_human_readable() {
173 PublicKeyHex(self.0).serialize(serializer)
174 } else {
175 PublicKeyBinary(self.0).serialize(serializer)
176 }
177 }
178}
179
180#[cfg(feature = "serde")]
181impl<'de> Deserialize<'de> for PublicKey {
182 #[inline]
183 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
184 where
185 D: Deserializer<'de>,
186 {
187 Ok(Self(if deserializer.is_human_readable() {
188 PublicKeyHex::deserialize(deserializer)?.0
189 } else {
190 PublicKeyBinary::deserialize(deserializer)?.0
191 }))
192 }
193}
194
195impl fmt::Display for PublicKey {
196 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
197 write!(f, "{}", hex::encode(self.0))
198 }
199}
200
201impl AsRef<[u8]> for PublicKey {
202 #[inline]
203 fn as_ref(&self) -> &[u8] {
204 &self.0
205 }
206}
207
208impl PublicKey {
209 pub const SIZE: usize = 32;
211
212 pub fn hash(&self) -> Blake3Hash {
214 blake3_hash(&self.0)
215 }
216}
217
218#[derive(
220 Default,
221 Copy,
222 Clone,
223 Eq,
224 PartialEq,
225 Ord,
226 PartialOrd,
227 Hash,
228 From,
229 Into,
230 AsRef,
231 AsMut,
232 Deref,
233 DerefMut,
234 Encode,
235 Decode,
236 TypeInfo,
237 DecodeWithMemTracking,
238)]
239#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
240#[cfg_attr(feature = "serde", serde(transparent))]
241pub struct ScalarBytes([u8; ScalarBytes::FULL_BYTES]);
242
243impl fmt::Debug for ScalarBytes {
244 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
245 write!(f, "{}", hex::encode(self.0))
246 }
247}
248
249impl ScalarBytes {
250 pub const SAFE_BYTES: usize = 31;
256 pub const FULL_BYTES: usize = 32;
259}
260
261#[expect(clippy::manual_div_ceil)]
262#[expect(clippy::double_parens)]
263mod private_u256 {
264 use parity_scale_codec::{Decode, Encode};
266 use scale_info::TypeInfo;
267
268 uint::construct_uint! {
269 #[derive(Encode, Decode, TypeInfo)]
270 pub struct U256(4);
271 }
272}
273
274#[derive(
276 Debug,
277 Display,
278 Add,
279 Sub,
280 Mul,
281 Div,
282 Rem,
283 Copy,
284 Clone,
285 Ord,
286 PartialOrd,
287 Eq,
288 PartialEq,
289 Hash,
290 Encode,
291 Decode,
292 TypeInfo,
293)]
294pub struct U256(private_u256::U256);
295
296impl U256 {
297 #[inline]
299 pub const fn zero() -> Self {
300 Self(private_u256::U256::zero())
301 }
302
303 #[inline]
305 pub fn one() -> Self {
306 Self(private_u256::U256::one())
307 }
308
309 pub fn from_be_bytes(bytes: [u8; 32]) -> Self {
311 Self(private_u256::U256::from_big_endian(&bytes))
312 }
313
314 pub fn to_be_bytes(self) -> [u8; 32] {
316 self.0.to_big_endian()
317 }
318
319 pub fn from_le_bytes(bytes: [u8; 32]) -> Self {
321 Self(private_u256::U256::from_little_endian(&bytes))
322 }
323
324 pub fn to_le_bytes(self) -> [u8; 32] {
326 self.0.to_little_endian()
327 }
328
329 pub fn checked_add(&self, v: &Self) -> Option<Self> {
331 self.0.checked_add(v.0).map(Self)
332 }
333
334 pub fn checked_sub(&self, v: &Self) -> Option<Self> {
336 self.0.checked_sub(v.0).map(Self)
337 }
338
339 pub fn checked_mul(&self, v: &Self) -> Option<Self> {
342 self.0.checked_mul(v.0).map(Self)
343 }
344
345 pub fn checked_div(&self, v: &Self) -> Option<Self> {
348 self.0.checked_div(v.0).map(Self)
349 }
350
351 pub fn saturating_add(&self, v: &Self) -> Self {
354 Self(self.0.saturating_add(v.0))
355 }
356
357 pub fn saturating_sub(&self, v: &Self) -> Self {
360 Self(self.0.saturating_sub(v.0))
361 }
362
363 pub fn saturating_mul(&self, v: &Self) -> Self {
366 Self(self.0.saturating_mul(v.0))
367 }
368
369 pub const MIDDLE: Self = {
372 Self(private_u256::U256([
375 u64::MAX,
376 u64::MAX,
377 u64::MAX,
378 u64::MAX / 2,
379 ]))
380 };
381
382 pub const MAX: Self = Self(private_u256::U256::MAX);
384}
385
386impl From<U256> for private_u256::U256 {
388 #[inline]
389 fn from(number: U256) -> Self {
390 number.0
391 }
392}
393
394impl WrappingAdd for U256 {
395 #[inline]
396 fn wrapping_add(&self, other: &Self) -> Self {
397 Self(self.0.overflowing_add(other.0).0)
398 }
399}
400
401impl WrappingSub for U256 {
402 #[inline]
403 fn wrapping_sub(&self, other: &Self) -> Self {
404 Self(self.0.overflowing_sub(other.0).0)
405 }
406}
407
408impl From<u8> for U256 {
409 #[inline]
410 fn from(number: u8) -> Self {
411 Self(number.into())
412 }
413}
414
415impl From<u16> for U256 {
416 #[inline]
417 fn from(number: u16) -> Self {
418 Self(number.into())
419 }
420}
421
422impl From<u32> for U256 {
423 #[inline]
424 fn from(number: u32) -> Self {
425 Self(number.into())
426 }
427}
428
429impl From<u64> for U256 {
430 #[inline]
431 fn from(number: u64) -> Self {
432 Self(number.into())
433 }
434}
435
436impl From<u128> for U256 {
437 #[inline]
438 fn from(number: u128) -> Self {
439 Self(number.into())
440 }
441}
442
443impl TryFrom<U256> for u8 {
444 type Error = &'static str;
445
446 #[inline]
447 fn try_from(value: U256) -> Result<Self, Self::Error> {
448 Self::try_from(value.0)
449 }
450}
451
452impl TryFrom<U256> for u16 {
453 type Error = &'static str;
454
455 #[inline]
456 fn try_from(value: U256) -> Result<Self, Self::Error> {
457 Self::try_from(value.0)
458 }
459}
460
461impl TryFrom<U256> for u32 {
462 type Error = &'static str;
463
464 #[inline]
465 fn try_from(value: U256) -> Result<Self, Self::Error> {
466 Self::try_from(value.0)
467 }
468}
469
470impl TryFrom<U256> for u64 {
471 type Error = &'static str;
472
473 #[inline]
474 fn try_from(value: U256) -> Result<Self, Self::Error> {
475 Self::try_from(value.0)
476 }
477}
478
479impl Default for U256 {
480 fn default() -> Self {
481 Self::zero()
482 }
483}