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, 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)]
262mod private_u256 {
263 use parity_scale_codec::{Decode, Encode};
265 use scale_info::TypeInfo;
266
267 uint::construct_uint! {
268 #[derive(Encode, Decode, TypeInfo)]
269 pub struct U256(4);
270 }
271}
272
273#[derive(
275 Debug,
276 Display,
277 Add,
278 Sub,
279 Mul,
280 Div,
281 Rem,
282 Copy,
283 Clone,
284 Ord,
285 PartialOrd,
286 Eq,
287 PartialEq,
288 Hash,
289 Encode,
290 Decode,
291 TypeInfo,
292)]
293pub struct U256(private_u256::U256);
294
295impl U256 {
296 #[inline]
298 pub const fn zero() -> Self {
299 Self(private_u256::U256::zero())
300 }
301
302 #[inline]
304 pub fn one() -> Self {
305 Self(private_u256::U256::one())
306 }
307
308 pub fn from_be_bytes(bytes: [u8; 32]) -> Self {
310 Self(private_u256::U256::from_big_endian(&bytes))
311 }
312
313 pub fn to_be_bytes(self) -> [u8; 32] {
315 self.0.to_big_endian()
316 }
317
318 pub fn from_le_bytes(bytes: [u8; 32]) -> Self {
320 Self(private_u256::U256::from_little_endian(&bytes))
321 }
322
323 pub fn to_le_bytes(self) -> [u8; 32] {
325 self.0.to_little_endian()
326 }
327
328 pub fn checked_add(&self, v: &Self) -> Option<Self> {
330 self.0.checked_add(v.0).map(Self)
331 }
332
333 pub fn checked_sub(&self, v: &Self) -> Option<Self> {
335 self.0.checked_sub(v.0).map(Self)
336 }
337
338 pub fn checked_mul(&self, v: &Self) -> Option<Self> {
341 self.0.checked_mul(v.0).map(Self)
342 }
343
344 pub fn checked_div(&self, v: &Self) -> Option<Self> {
347 self.0.checked_div(v.0).map(Self)
348 }
349
350 pub fn saturating_add(&self, v: &Self) -> Self {
353 Self(self.0.saturating_add(v.0))
354 }
355
356 pub fn saturating_sub(&self, v: &Self) -> Self {
359 Self(self.0.saturating_sub(v.0))
360 }
361
362 pub fn saturating_mul(&self, v: &Self) -> Self {
365 Self(self.0.saturating_mul(v.0))
366 }
367
368 pub const MIDDLE: Self = {
371 Self(private_u256::U256([
374 u64::MAX,
375 u64::MAX,
376 u64::MAX,
377 u64::MAX / 2,
378 ]))
379 };
380
381 pub const MAX: Self = Self(private_u256::U256::MAX);
383}
384
385impl From<U256> for private_u256::U256 {
387 #[inline]
388 fn from(number: U256) -> Self {
389 number.0
390 }
391}
392
393impl WrappingAdd for U256 {
394 #[inline]
395 fn wrapping_add(&self, other: &Self) -> Self {
396 Self(self.0.overflowing_add(other.0).0)
397 }
398}
399
400impl WrappingSub for U256 {
401 #[inline]
402 fn wrapping_sub(&self, other: &Self) -> Self {
403 Self(self.0.overflowing_sub(other.0).0)
404 }
405}
406
407impl From<u8> for U256 {
408 #[inline]
409 fn from(number: u8) -> Self {
410 Self(number.into())
411 }
412}
413
414impl From<u16> for U256 {
415 #[inline]
416 fn from(number: u16) -> Self {
417 Self(number.into())
418 }
419}
420
421impl From<u32> for U256 {
422 #[inline]
423 fn from(number: u32) -> Self {
424 Self(number.into())
425 }
426}
427
428impl From<u64> for U256 {
429 #[inline]
430 fn from(number: u64) -> Self {
431 Self(number.into())
432 }
433}
434
435impl From<u128> for U256 {
436 #[inline]
437 fn from(number: u128) -> Self {
438 Self(number.into())
439 }
440}
441
442impl TryFrom<U256> for u8 {
443 type Error = &'static str;
444
445 #[inline]
446 fn try_from(value: U256) -> Result<Self, Self::Error> {
447 Self::try_from(value.0)
448 }
449}
450
451impl TryFrom<U256> for u16 {
452 type Error = &'static str;
453
454 #[inline]
455 fn try_from(value: U256) -> Result<Self, Self::Error> {
456 Self::try_from(value.0)
457 }
458}
459
460impl TryFrom<U256> for u32 {
461 type Error = &'static str;
462
463 #[inline]
464 fn try_from(value: U256) -> Result<Self, Self::Error> {
465 Self::try_from(value.0)
466 }
467}
468
469impl TryFrom<U256> for u64 {
470 type Error = &'static str;
471
472 #[inline]
473 fn try_from(value: U256) -> Result<Self, Self::Error> {
474 Self::try_from(value.0)
475 }
476}
477
478impl Default for U256 {
479 fn default() -> Self {
480 Self::zero()
481 }
482}