1#[cfg(not(feature = "std"))]
4extern crate alloc;
5
6use crate::ScalarBytes;
7use crate::segments::{ArchivedHistorySegment, RecordedHistorySegment, SegmentIndex};
8#[cfg(feature = "serde")]
9use ::serde::{Deserialize, Serialize};
10#[cfg(feature = "serde")]
11use ::serde::{Deserializer, Serializer};
12#[cfg(not(feature = "std"))]
13use alloc::boxed::Box;
14#[cfg(not(feature = "std"))]
15use alloc::format;
16#[cfg(not(feature = "std"))]
17use alloc::vec::Vec;
18use bytes::{Bytes, BytesMut};
19use core::array::TryFromSliceError;
20use core::hash::{Hash, Hasher};
21use core::iter::Step;
22use core::{fmt, mem, slice};
23use derive_more::with_trait::{
24 Add, AddAssign, AsMut, AsRef, Deref, DerefMut, Display, Div, DivAssign, From, Into, Mul,
25 MulAssign, Sub, SubAssign,
26};
27use parity_scale_codec::{
28 Decode, DecodeWithMemTracking, Encode, EncodeLike, Input, MaxEncodedLen, Output,
29};
30#[cfg(feature = "parallel")]
31use rayon::prelude::*;
32use scale_info::build::Fields;
33use scale_info::{Path, Type, TypeInfo};
34#[cfg(feature = "serde")]
35use serde_big_array::BigArray;
36
37#[derive(
39 Debug,
40 Display,
41 Default,
42 Copy,
43 Clone,
44 Ord,
45 PartialOrd,
46 Eq,
47 PartialEq,
48 Hash,
49 Encode,
50 Decode,
51 Add,
52 AddAssign,
53 Sub,
54 SubAssign,
55 Mul,
56 MulAssign,
57 Div,
58 DivAssign,
59 TypeInfo,
60 MaxEncodedLen,
61)]
62#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
63#[repr(transparent)]
64pub struct PieceIndex(u64);
65
66impl Step for PieceIndex {
67 #[inline]
68 fn steps_between(start: &Self, end: &Self) -> (usize, Option<usize>) {
69 u64::steps_between(&start.0, &end.0)
70 }
71
72 #[inline]
73 fn forward_checked(start: Self, count: usize) -> Option<Self> {
74 u64::forward_checked(start.0, count).map(Self)
75 }
76
77 #[inline]
78 fn forward_overflowing(start: Self, count: usize) -> (Self, bool) {
79 let (n, overflowing) = u64::forward_overflowing(start.0, count);
80 (Self(n), overflowing)
81 }
82
83 #[inline]
84 fn backward_checked(start: Self, count: usize) -> Option<Self> {
85 u64::backward_checked(start.0, count).map(Self)
86 }
87
88 #[inline]
89 fn backward_overflowing(start: Self, count: usize) -> (Self, bool) {
90 let (n, overflowing) = u64::backward_overflowing(start.0, count);
91 (Self(n), overflowing)
92 }
93}
94
95impl From<u64> for PieceIndex {
96 #[inline]
97 fn from(original: u64) -> Self {
98 Self(original)
99 }
100}
101
102impl From<PieceIndex> for u64 {
103 #[inline]
104 fn from(original: PieceIndex) -> Self {
105 original.0
106 }
107}
108
109impl PieceIndex {
110 pub const SIZE: usize = mem::size_of::<u64>();
112 pub const ZERO: PieceIndex = PieceIndex(0);
114 pub const ONE: PieceIndex = PieceIndex(1);
116
117 #[inline]
119 pub const fn new(n: u64) -> Self {
120 Self(n)
121 }
122
123 #[inline]
125 pub const fn from_bytes(bytes: [u8; Self::SIZE]) -> Self {
126 Self(u64::from_le_bytes(bytes))
127 }
128
129 #[inline]
131 pub const fn to_bytes(self) -> [u8; Self::SIZE] {
132 self.0.to_le_bytes()
133 }
134
135 #[inline]
137 pub const fn segment_index(&self) -> SegmentIndex {
138 SegmentIndex::new(self.0 / ArchivedHistorySegment::NUM_PIECES as u64)
139 }
140
141 #[inline]
143 pub const fn position(&self) -> u32 {
144 (self.0 % ArchivedHistorySegment::NUM_PIECES as u64) as u32
146 }
147
148 #[inline]
151 pub const fn source_position(&self) -> u32 {
152 assert!(self.is_source());
153
154 let source_start = self.position() / RecordedHistorySegment::ERASURE_CODING_RATE.1 as u32
155 * RecordedHistorySegment::ERASURE_CODING_RATE.0 as u32;
156 let source_offset = self.position() % RecordedHistorySegment::ERASURE_CODING_RATE.1 as u32;
157
158 source_start + source_offset
159 }
160
161 #[inline]
164 pub const fn from_source_position(
165 source_position: u32,
166 segment_index: SegmentIndex,
167 ) -> PieceIndex {
168 let source_position = source_position as u64;
169 let start = source_position / RecordedHistorySegment::ERASURE_CODING_RATE.0 as u64
170 * RecordedHistorySegment::ERASURE_CODING_RATE.1 as u64;
171 let offset = source_position % RecordedHistorySegment::ERASURE_CODING_RATE.0 as u64;
172
173 PieceIndex(segment_index.first_piece_index().0 + start + offset)
174 }
175
176 #[inline]
178 pub const fn is_source(&self) -> bool {
179 self.0 % (RecordedHistorySegment::ERASURE_CODING_RATE.1 as u64)
181 < (RecordedHistorySegment::ERASURE_CODING_RATE.0 as u64)
182 }
183
184 #[inline]
187 pub const fn next_source_index(&self) -> PieceIndex {
188 PieceIndex::from_source_position(self.source_position() + 1, self.segment_index())
189 }
190
191 #[inline]
194 pub const fn prev_source_index(&self) -> Option<PieceIndex> {
195 if self.source_position() == 0 {
196 match self.segment_index().checked_sub(SegmentIndex::ONE) {
198 Some(segment_index) => Some(PieceIndex::from_source_position(
199 RecordedHistorySegment::NUM_RAW_RECORDS as u32 - 1,
200 segment_index,
201 )),
202 None => None,
203 }
204 } else {
205 Some(PieceIndex::from_source_position(
206 self.source_position() - 1,
207 self.segment_index(),
208 ))
209 }
210 }
211}
212
213#[derive(
215 Debug,
216 Display,
217 Default,
218 Copy,
219 Clone,
220 Ord,
221 PartialOrd,
222 Eq,
223 PartialEq,
224 Hash,
225 Encode,
226 Decode,
227 Add,
228 AddAssign,
229 Sub,
230 SubAssign,
231 Mul,
232 MulAssign,
233 Div,
234 DivAssign,
235 TypeInfo,
236 MaxEncodedLen,
237 DecodeWithMemTracking,
238)]
239#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
240#[repr(transparent)]
241pub struct PieceOffset(u16);
242
243impl Step for PieceOffset {
244 #[inline]
245 fn steps_between(start: &Self, end: &Self) -> (usize, Option<usize>) {
246 u16::steps_between(&start.0, &end.0)
247 }
248
249 #[inline]
250 fn forward_checked(start: Self, count: usize) -> Option<Self> {
251 u16::forward_checked(start.0, count).map(Self)
252 }
253
254 #[inline]
255 fn forward_overflowing(start: Self, count: usize) -> (Self, bool) {
256 let (n, overflowing) = u16::forward_overflowing(start.0, count);
257 (Self(n), overflowing)
258 }
259
260 #[inline]
261 fn backward_checked(start: Self, count: usize) -> Option<Self> {
262 u16::backward_checked(start.0, count).map(Self)
263 }
264
265 #[inline]
266 fn backward_overflowing(start: Self, count: usize) -> (Self, bool) {
267 let (n, overflowing) = u16::backward_overflowing(start.0, count);
268 (Self(n), overflowing)
269 }
270}
271
272impl From<u16> for PieceOffset {
273 #[inline]
274 fn from(original: u16) -> Self {
275 Self(original)
276 }
277}
278
279impl From<PieceOffset> for u16 {
280 #[inline]
281 fn from(original: PieceOffset) -> Self {
282 original.0
283 }
284}
285
286impl From<PieceOffset> for u32 {
287 #[inline]
288 fn from(original: PieceOffset) -> Self {
289 Self::from(original.0)
290 }
291}
292
293impl From<PieceOffset> for u64 {
294 #[inline]
295 fn from(original: PieceOffset) -> Self {
296 Self::from(original.0)
297 }
298}
299
300impl From<PieceOffset> for usize {
301 #[inline]
302 fn from(original: PieceOffset) -> Self {
303 usize::from(original.0)
304 }
305}
306
307impl PieceOffset {
308 pub const ZERO: PieceOffset = PieceOffset(0);
310 pub const ONE: PieceOffset = PieceOffset(1);
312
313 #[inline]
315 pub const fn to_bytes(self) -> [u8; mem::size_of::<u16>()] {
316 self.0.to_le_bytes()
317 }
318}
319
320#[derive(Copy, Clone, Eq, PartialEq, Deref, DerefMut)]
324#[repr(transparent)]
325pub struct RawRecord([[u8; ScalarBytes::SAFE_BYTES]; Self::NUM_CHUNKS]);
326
327impl fmt::Debug for RawRecord {
328 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
329 write!(f, "{}", hex::encode(self.0.as_flattened()))
330 }
331}
332
333impl Default for RawRecord {
334 #[inline]
335 fn default() -> Self {
336 Self([Default::default(); Self::NUM_CHUNKS])
337 }
338}
339
340impl AsRef<[u8]> for RawRecord {
341 #[inline]
342 fn as_ref(&self) -> &[u8] {
343 self.0.as_slice().as_flattened()
344 }
345}
346
347impl AsMut<[u8]> for RawRecord {
348 #[inline]
349 fn as_mut(&mut self) -> &mut [u8] {
350 self.0.as_mut_slice().as_flattened_mut()
351 }
352}
353
354impl From<&RawRecord> for &[[u8; ScalarBytes::SAFE_BYTES]; RawRecord::NUM_CHUNKS] {
355 #[inline]
356 fn from(value: &RawRecord) -> Self {
357 unsafe { mem::transmute(value) }
360 }
361}
362
363impl From<&[[u8; ScalarBytes::SAFE_BYTES]; RawRecord::NUM_CHUNKS]> for &RawRecord {
364 #[inline]
365 fn from(value: &[[u8; ScalarBytes::SAFE_BYTES]; RawRecord::NUM_CHUNKS]) -> Self {
366 unsafe { mem::transmute(value) }
369 }
370}
371
372impl From<&mut RawRecord> for &mut [[u8; ScalarBytes::SAFE_BYTES]; RawRecord::NUM_CHUNKS] {
373 #[inline]
374 fn from(value: &mut RawRecord) -> Self {
375 unsafe { mem::transmute(value) }
378 }
379}
380
381impl From<&mut [[u8; ScalarBytes::SAFE_BYTES]; RawRecord::NUM_CHUNKS]> for &mut RawRecord {
382 #[inline]
383 fn from(value: &mut [[u8; ScalarBytes::SAFE_BYTES]; RawRecord::NUM_CHUNKS]) -> Self {
384 unsafe { mem::transmute(value) }
387 }
388}
389
390impl From<&RawRecord> for &[u8; ScalarBytes::SAFE_BYTES * RawRecord::NUM_CHUNKS] {
391 #[inline]
392 fn from(value: &RawRecord) -> Self {
393 unsafe { mem::transmute(value) }
396 }
397}
398
399impl From<&[u8; ScalarBytes::SAFE_BYTES * RawRecord::NUM_CHUNKS]> for &RawRecord {
400 #[inline]
401 fn from(value: &[u8; ScalarBytes::SAFE_BYTES * RawRecord::NUM_CHUNKS]) -> Self {
402 unsafe { mem::transmute(value) }
405 }
406}
407
408impl From<&mut RawRecord> for &mut [u8; ScalarBytes::SAFE_BYTES * RawRecord::NUM_CHUNKS] {
409 #[inline]
410 fn from(value: &mut RawRecord) -> Self {
411 unsafe { mem::transmute(value) }
414 }
415}
416
417impl From<&mut [u8; ScalarBytes::SAFE_BYTES * RawRecord::NUM_CHUNKS]> for &mut RawRecord {
418 #[inline]
419 fn from(value: &mut [u8; ScalarBytes::SAFE_BYTES * RawRecord::NUM_CHUNKS]) -> Self {
420 unsafe { mem::transmute(value) }
423 }
424}
425
426impl RawRecord {
427 pub const NUM_CHUNKS: usize = 2_usize.pow(15);
429 pub const SIZE: usize = ScalarBytes::SAFE_BYTES * Self::NUM_CHUNKS;
431
432 #[inline]
434 pub fn new_boxed() -> Box<Self> {
435 unsafe { Box::new_zeroed().assume_init() }
438 }
439
440 #[inline]
443 pub fn slice_to_repr(value: &[Self]) -> &[[[u8; ScalarBytes::SAFE_BYTES]; Self::NUM_CHUNKS]] {
444 unsafe { mem::transmute(value) }
447 }
448
449 #[inline]
452 pub fn slice_from_repr(value: &[[[u8; ScalarBytes::SAFE_BYTES]; Self::NUM_CHUNKS]]) -> &[Self] {
453 unsafe { mem::transmute(value) }
456 }
457
458 #[inline]
461 pub fn slice_mut_to_repr(
462 value: &mut [Self],
463 ) -> &mut [[[u8; ScalarBytes::SAFE_BYTES]; Self::NUM_CHUNKS]] {
464 unsafe { mem::transmute(value) }
467 }
468
469 #[inline]
472 pub fn slice_mut_from_repr(
473 value: &mut [[[u8; ScalarBytes::SAFE_BYTES]; Self::NUM_CHUNKS]],
474 ) -> &mut [Self] {
475 unsafe { mem::transmute(value) }
478 }
479}
480
481#[derive(Copy, Clone, Eq, PartialEq, Deref, DerefMut)]
485#[repr(transparent)]
486pub struct Record([[u8; ScalarBytes::FULL_BYTES]; Self::NUM_CHUNKS]);
487
488impl fmt::Debug for Record {
489 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
490 write!(f, "{}", hex::encode(self.0.as_flattened()))
491 }
492}
493
494impl Default for Record {
495 #[inline]
496 fn default() -> Self {
497 Self([Default::default(); Self::NUM_CHUNKS])
498 }
499}
500
501impl AsRef<[u8]> for Record {
502 #[inline]
503 fn as_ref(&self) -> &[u8] {
504 self.0.as_flattened()
505 }
506}
507
508impl AsMut<[u8]> for Record {
509 #[inline]
510 fn as_mut(&mut self) -> &mut [u8] {
511 self.0.as_flattened_mut()
512 }
513}
514
515impl From<&Record> for &[[u8; ScalarBytes::FULL_BYTES]; Record::NUM_CHUNKS] {
516 #[inline]
517 fn from(value: &Record) -> Self {
518 unsafe { mem::transmute(value) }
520 }
521}
522
523impl From<&[[u8; ScalarBytes::FULL_BYTES]; Record::NUM_CHUNKS]> for &Record {
524 #[inline]
525 fn from(value: &[[u8; ScalarBytes::FULL_BYTES]; Record::NUM_CHUNKS]) -> Self {
526 unsafe { mem::transmute(value) }
528 }
529}
530
531impl From<&mut Record> for &mut [[u8; ScalarBytes::FULL_BYTES]; Record::NUM_CHUNKS] {
532 #[inline]
533 fn from(value: &mut Record) -> Self {
534 unsafe { mem::transmute(value) }
536 }
537}
538
539impl From<&mut [[u8; ScalarBytes::FULL_BYTES]; Record::NUM_CHUNKS]> for &mut Record {
540 #[inline]
541 fn from(value: &mut [[u8; ScalarBytes::FULL_BYTES]; Record::NUM_CHUNKS]) -> Self {
542 unsafe { mem::transmute(value) }
544 }
545}
546
547impl From<&Record> for &[u8; ScalarBytes::FULL_BYTES * Record::NUM_CHUNKS] {
548 #[inline]
549 fn from(value: &Record) -> Self {
550 unsafe { mem::transmute(value) }
553 }
554}
555
556impl From<&[u8; ScalarBytes::FULL_BYTES * Record::NUM_CHUNKS]> for &Record {
557 #[inline]
558 fn from(value: &[u8; ScalarBytes::FULL_BYTES * Record::NUM_CHUNKS]) -> Self {
559 unsafe { mem::transmute(value) }
562 }
563}
564
565impl From<&mut Record> for &mut [u8; ScalarBytes::FULL_BYTES * Record::NUM_CHUNKS] {
566 #[inline]
567 fn from(value: &mut Record) -> Self {
568 unsafe { mem::transmute(value) }
571 }
572}
573
574impl From<&mut [u8; ScalarBytes::FULL_BYTES * Record::NUM_CHUNKS]> for &mut Record {
575 #[inline]
576 fn from(value: &mut [u8; ScalarBytes::FULL_BYTES * Record::NUM_CHUNKS]) -> Self {
577 unsafe { mem::transmute(value) }
580 }
581}
582
583impl Record {
584 pub const NUM_CHUNKS: usize = RawRecord::NUM_CHUNKS;
586 pub const NUM_S_BUCKETS: usize = Self::NUM_CHUNKS
590 * RecordedHistorySegment::ERASURE_CODING_RATE.1
591 / RecordedHistorySegment::ERASURE_CODING_RATE.0;
592 pub const SIZE: usize = ScalarBytes::FULL_BYTES * Self::NUM_CHUNKS;
595
596 #[inline]
598 pub fn new_boxed() -> Box<Self> {
599 unsafe { Box::new_zeroed().assume_init() }
602 }
603
604 #[inline]
606 pub fn new_zero_vec(length: usize) -> Vec<Self> {
607 let mut records = Vec::with_capacity(length);
609 {
610 let slice = records.spare_capacity_mut();
611 let slice = unsafe {
615 slice::from_raw_parts_mut(
616 slice.as_mut_ptr()
617 as *mut [[mem::MaybeUninit<u8>; ScalarBytes::FULL_BYTES]; Self::NUM_CHUNKS],
618 length,
619 )
620 };
621 for byte in slice.as_flattened_mut().as_flattened_mut() {
622 byte.write(0);
623 }
624 }
625 unsafe {
627 records.set_len(records.capacity());
628 }
629
630 records
631 }
632
633 #[inline]
636 pub fn slice_to_repr(value: &[Self]) -> &[[[u8; ScalarBytes::FULL_BYTES]; Self::NUM_CHUNKS]] {
637 unsafe { mem::transmute(value) }
639 }
640
641 #[inline]
644 pub fn slice_from_repr(value: &[[[u8; ScalarBytes::FULL_BYTES]; Self::NUM_CHUNKS]]) -> &[Self] {
645 unsafe { mem::transmute(value) }
647 }
648
649 #[inline]
652 pub fn slice_mut_to_repr(
653 value: &mut [Self],
654 ) -> &mut [[[u8; ScalarBytes::FULL_BYTES]; Self::NUM_CHUNKS]] {
655 unsafe { mem::transmute(value) }
657 }
658
659 #[inline]
662 pub fn slice_mut_from_repr(
663 value: &mut [[[u8; ScalarBytes::FULL_BYTES]; Self::NUM_CHUNKS]],
664 ) -> &mut [Self] {
665 unsafe { mem::transmute(value) }
667 }
668
669 #[inline]
672 pub fn to_raw_record_chunks(
673 &self,
674 ) -> impl DoubleEndedIterator<Item = &'_ [u8; ScalarBytes::SAFE_BYTES]> + '_ {
675 self.iter()
678 .map(|bytes| bytes[1..].try_into().expect("Correct length; qed"))
679 }
680
681 #[inline]
684 pub fn to_mut_raw_record_chunks(
685 &mut self,
686 ) -> impl DoubleEndedIterator<Item = &'_ mut [u8; ScalarBytes::SAFE_BYTES]> + '_ {
687 self.iter_mut()
688 .map(|bytes| (&mut bytes[1..]).try_into().expect("Correct length; qed"))
689 }
690}
691
692#[derive(
694 Copy,
695 Clone,
696 Eq,
697 PartialEq,
698 Hash,
699 Deref,
700 DerefMut,
701 From,
702 Into,
703 Encode,
704 Decode,
705 TypeInfo,
706 MaxEncodedLen,
707 DecodeWithMemTracking,
708)]
709pub struct RecordCommitment([u8; RecordCommitment::SIZE]);
710
711impl fmt::Debug for RecordCommitment {
712 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
713 write!(f, "{}", hex::encode(self.0))
714 }
715}
716
717#[cfg(feature = "serde")]
718#[derive(Serialize, Deserialize)]
719#[serde(transparent)]
720struct RecordCommitmentBinary(#[serde(with = "BigArray")] [u8; RecordCommitment::SIZE]);
721
722#[cfg(feature = "serde")]
723#[derive(Serialize, Deserialize)]
724#[serde(transparent)]
725struct RecordCommitmentHex(#[serde(with = "hex")] [u8; RecordCommitment::SIZE]);
726
727#[cfg(feature = "serde")]
728impl Serialize for RecordCommitment {
729 #[inline]
730 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
731 where
732 S: Serializer,
733 {
734 if serializer.is_human_readable() {
735 RecordCommitmentHex(self.0).serialize(serializer)
736 } else {
737 RecordCommitmentBinary(self.0).serialize(serializer)
738 }
739 }
740}
741
742#[cfg(feature = "serde")]
743impl<'de> Deserialize<'de> for RecordCommitment {
744 #[inline]
745 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
746 where
747 D: Deserializer<'de>,
748 {
749 Ok(Self(if deserializer.is_human_readable() {
750 RecordCommitmentHex::deserialize(deserializer)?.0
751 } else {
752 RecordCommitmentBinary::deserialize(deserializer)?.0
753 }))
754 }
755}
756
757impl Default for RecordCommitment {
758 #[inline]
759 fn default() -> Self {
760 Self([0; Self::SIZE])
761 }
762}
763
764impl TryFrom<&[u8]> for RecordCommitment {
765 type Error = TryFromSliceError;
766
767 #[inline]
768 fn try_from(slice: &[u8]) -> Result<Self, Self::Error> {
769 <[u8; Self::SIZE]>::try_from(slice).map(Self)
770 }
771}
772
773impl AsRef<[u8]> for RecordCommitment {
774 #[inline]
775 fn as_ref(&self) -> &[u8] {
776 &self.0
777 }
778}
779
780impl AsMut<[u8]> for RecordCommitment {
781 #[inline]
782 fn as_mut(&mut self) -> &mut [u8] {
783 &mut self.0
784 }
785}
786
787impl From<&RecordCommitment> for &[u8; RecordCommitment::SIZE] {
788 #[inline]
789 fn from(value: &RecordCommitment) -> Self {
790 unsafe { mem::transmute(value) }
793 }
794}
795
796impl From<&[u8; RecordCommitment::SIZE]> for &RecordCommitment {
797 #[inline]
798 fn from(value: &[u8; RecordCommitment::SIZE]) -> Self {
799 unsafe { mem::transmute(value) }
802 }
803}
804
805impl From<&mut RecordCommitment> for &mut [u8; RecordCommitment::SIZE] {
806 #[inline]
807 fn from(value: &mut RecordCommitment) -> Self {
808 unsafe { mem::transmute(value) }
811 }
812}
813
814impl From<&mut [u8; RecordCommitment::SIZE]> for &mut RecordCommitment {
815 #[inline]
816 fn from(value: &mut [u8; RecordCommitment::SIZE]) -> Self {
817 unsafe { mem::transmute(value) }
820 }
821}
822
823impl RecordCommitment {
824 pub const SIZE: usize = 48;
826}
827
828#[derive(
830 Copy,
831 Clone,
832 Eq,
833 PartialEq,
834 Hash,
835 Deref,
836 DerefMut,
837 From,
838 Into,
839 Encode,
840 Decode,
841 TypeInfo,
842 MaxEncodedLen,
843 DecodeWithMemTracking,
844)]
845pub struct RecordWitness([u8; RecordWitness::SIZE]);
846
847impl fmt::Debug for RecordWitness {
848 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
849 write!(f, "{}", hex::encode(self.0))
850 }
851}
852
853#[cfg(feature = "serde")]
854#[derive(Serialize, Deserialize)]
855#[serde(transparent)]
856struct RecordWitnessBinary(#[serde(with = "BigArray")] [u8; RecordWitness::SIZE]);
857
858#[cfg(feature = "serde")]
859#[derive(Serialize, Deserialize)]
860#[serde(transparent)]
861struct RecordWitnessHex(#[serde(with = "hex")] [u8; RecordWitness::SIZE]);
862
863#[cfg(feature = "serde")]
864impl Serialize for RecordWitness {
865 #[inline]
866 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
867 where
868 S: Serializer,
869 {
870 if serializer.is_human_readable() {
871 RecordWitnessHex(self.0).serialize(serializer)
872 } else {
873 RecordWitnessBinary(self.0).serialize(serializer)
874 }
875 }
876}
877
878#[cfg(feature = "serde")]
879impl<'de> Deserialize<'de> for RecordWitness {
880 #[inline]
881 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
882 where
883 D: Deserializer<'de>,
884 {
885 Ok(Self(if deserializer.is_human_readable() {
886 RecordWitnessHex::deserialize(deserializer)?.0
887 } else {
888 RecordWitnessBinary::deserialize(deserializer)?.0
889 }))
890 }
891}
892
893impl Default for RecordWitness {
894 #[inline]
895 fn default() -> Self {
896 Self([0; Self::SIZE])
897 }
898}
899
900impl TryFrom<&[u8]> for RecordWitness {
901 type Error = TryFromSliceError;
902
903 #[inline]
904 fn try_from(slice: &[u8]) -> Result<Self, Self::Error> {
905 <[u8; Self::SIZE]>::try_from(slice).map(Self)
906 }
907}
908
909impl AsRef<[u8]> for RecordWitness {
910 #[inline]
911 fn as_ref(&self) -> &[u8] {
912 &self.0
913 }
914}
915
916impl AsMut<[u8]> for RecordWitness {
917 #[inline]
918 fn as_mut(&mut self) -> &mut [u8] {
919 &mut self.0
920 }
921}
922
923impl From<&RecordWitness> for &[u8; RecordWitness::SIZE] {
924 #[inline]
925 fn from(value: &RecordWitness) -> Self {
926 unsafe { mem::transmute(value) }
929 }
930}
931
932impl From<&[u8; RecordWitness::SIZE]> for &RecordWitness {
933 #[inline]
934 fn from(value: &[u8; RecordWitness::SIZE]) -> Self {
935 unsafe { mem::transmute(value) }
938 }
939}
940
941impl From<&mut RecordWitness> for &mut [u8; RecordWitness::SIZE] {
942 #[inline]
943 fn from(value: &mut RecordWitness) -> Self {
944 unsafe { mem::transmute(value) }
947 }
948}
949
950impl From<&mut [u8; RecordWitness::SIZE]> for &mut RecordWitness {
951 #[inline]
952 fn from(value: &mut [u8; RecordWitness::SIZE]) -> Self {
953 unsafe { mem::transmute(value) }
956 }
957}
958
959impl RecordWitness {
960 pub const SIZE: usize = 48;
962}
963
964enum CowBytes {
965 Shared(Bytes),
966 Owned(BytesMut),
967}
968
969impl fmt::Debug for CowBytes {
970 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
971 write!(f, "{}", hex::encode(self.as_ref()))
972 }
973}
974
975impl PartialEq for CowBytes {
976 fn eq(&self, other: &Self) -> bool {
977 self.as_ref().eq(other.as_ref())
978 }
979}
980
981impl Eq for CowBytes {}
982
983impl Hash for CowBytes {
984 fn hash<H: Hasher>(&self, state: &mut H) {
985 self.as_ref().hash(state)
986 }
987}
988
989impl Clone for CowBytes {
990 fn clone(&self) -> Self {
991 match self {
992 Self::Shared(bytes) => Self::Shared(bytes.clone()),
993 Self::Owned(bytes) => Self::Shared(Bytes::copy_from_slice(bytes)),
995 }
996 }
997}
998
999impl AsRef<[u8]> for CowBytes {
1000 fn as_ref(&self) -> &[u8] {
1001 match self {
1002 CowBytes::Shared(bytes) => bytes.as_ref(),
1003 CowBytes::Owned(bytes) => bytes.as_ref(),
1004 }
1005 }
1006}
1007
1008impl AsMut<[u8]> for CowBytes {
1009 #[inline]
1010 fn as_mut(&mut self) -> &mut [u8] {
1011 match self {
1012 CowBytes::Shared(bytes) => {
1013 *self = CowBytes::Owned(BytesMut::from(mem::take(bytes)));
1014
1015 let CowBytes::Owned(bytes) = self else {
1016 unreachable!("Just replaced; qed");
1017 };
1018
1019 bytes.as_mut()
1020 }
1021 CowBytes::Owned(bytes) => bytes.as_mut(),
1022 }
1023 }
1024}
1025
1026#[derive(Debug, Clone, PartialEq, Eq, Hash)]
1034pub struct Piece(CowBytes);
1035
1036impl Encode for Piece {
1037 #[inline]
1038 fn size_hint(&self) -> usize {
1039 self.as_ref().size_hint()
1040 }
1041
1042 #[inline]
1043 fn encode_to<O: Output + ?Sized>(&self, output: &mut O) {
1044 self.as_ref().encode_to(output)
1045 }
1046
1047 #[inline]
1048 fn encode(&self) -> Vec<u8> {
1049 self.as_ref().encode()
1050 }
1051
1052 #[inline]
1053 fn using_encoded<R, F: FnOnce(&[u8]) -> R>(&self, f: F) -> R {
1054 self.as_ref().using_encoded(f)
1055 }
1056}
1057
1058impl EncodeLike for Piece {}
1059
1060impl Decode for Piece {
1061 fn decode<I: Input>(input: &mut I) -> Result<Self, parity_scale_codec::Error> {
1062 let bytes =
1063 Bytes::decode(input).map_err(|error| error.chain("Could not decode `Piece`"))?;
1064
1065 if bytes.len() != Self::SIZE {
1066 return Err(
1067 parity_scale_codec::Error::from("Incorrect Piece length").chain(format!(
1068 "Expected {} bytes, found {} bytes",
1069 Self::SIZE,
1070 bytes.len()
1071 )),
1072 );
1073 }
1074
1075 Ok(Piece(CowBytes::Shared(bytes)))
1076 }
1077}
1078
1079impl TypeInfo for Piece {
1080 type Identity = Self;
1081
1082 fn type_info() -> Type {
1083 Type::builder()
1084 .path(Path::new("Piece", module_path!()))
1085 .docs(&["A piece of archival history in Subspace Network"])
1086 .composite(
1087 Fields::unnamed().field(|f| f.ty::<[u8; Piece::SIZE]>().type_name("PieceArray")),
1088 )
1089 }
1090}
1091
1092#[cfg(feature = "serde")]
1093impl Serialize for Piece {
1094 #[inline]
1095 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
1096 where
1097 S: Serializer,
1098 {
1099 let bytes = match &self.0 {
1100 CowBytes::Shared(bytes) => bytes.as_ref(),
1101 CowBytes::Owned(bytes) => bytes.as_ref(),
1102 };
1103
1104 if serializer.is_human_readable() {
1105 hex::serde::serialize(bytes, serializer)
1106 } else {
1107 bytes.serialize(serializer)
1108 }
1109 }
1110}
1111
1112#[cfg(feature = "serde")]
1113impl<'de> Deserialize<'de> for Piece {
1114 #[inline]
1115 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
1116 where
1117 D: Deserializer<'de>,
1118 {
1119 let bytes = if deserializer.is_human_readable() {
1120 hex::serde::deserialize::<_, Vec<u8>>(deserializer).and_then(|bytes| {
1121 if bytes.len() == Piece::SIZE {
1122 Ok(Bytes::from(bytes))
1123 } else {
1124 Err(serde::de::Error::invalid_length(
1125 bytes.len(),
1126 &format!("Expected {} bytes", Piece::SIZE).as_str(),
1127 ))
1128 }
1129 })?
1130 } else {
1131 Bytes::deserialize(deserializer)?
1132 };
1133
1134 Ok(Piece(CowBytes::Shared(bytes)))
1135 }
1136}
1137
1138impl Default for Piece {
1139 #[inline]
1140 fn default() -> Self {
1141 Self(CowBytes::Owned(BytesMut::zeroed(Self::SIZE)))
1142 }
1143}
1144
1145impl From<Piece> for Vec<u8> {
1146 #[inline]
1147 fn from(piece: Piece) -> Self {
1148 match piece.0 {
1149 CowBytes::Shared(bytes) => bytes.to_vec(),
1150 CowBytes::Owned(bytes) => Vec::from(bytes),
1151 }
1152 }
1153}
1154
1155impl TryFrom<&[u8]> for Piece {
1156 type Error = ();
1157
1158 #[inline]
1159 fn try_from(slice: &[u8]) -> Result<Self, Self::Error> {
1160 if slice.len() != Self::SIZE {
1161 return Err(());
1162 }
1163
1164 Ok(Self(CowBytes::Shared(Bytes::copy_from_slice(slice))))
1165 }
1166}
1167
1168impl TryFrom<Vec<u8>> for Piece {
1169 type Error = ();
1170
1171 #[inline]
1172 fn try_from(vec: Vec<u8>) -> Result<Self, Self::Error> {
1173 if vec.len() != Self::SIZE {
1174 return Err(());
1175 }
1176
1177 Ok(Self(CowBytes::Shared(Bytes::from(vec))))
1178 }
1179}
1180
1181impl TryFrom<Bytes> for Piece {
1182 type Error = ();
1183
1184 #[inline]
1185 fn try_from(bytes: Bytes) -> Result<Self, Self::Error> {
1186 if bytes.len() != Self::SIZE {
1187 return Err(());
1188 }
1189
1190 Ok(Self(CowBytes::Shared(bytes)))
1191 }
1192}
1193
1194impl TryFrom<BytesMut> for Piece {
1195 type Error = ();
1196
1197 #[inline]
1198 fn try_from(bytes: BytesMut) -> Result<Self, Self::Error> {
1199 if bytes.len() != Self::SIZE {
1200 return Err(());
1201 }
1202
1203 Ok(Self(CowBytes::Owned(bytes)))
1204 }
1205}
1206
1207impl From<&PieceArray> for Piece {
1208 #[inline]
1209 fn from(value: &PieceArray) -> Self {
1210 Self(CowBytes::Shared(Bytes::copy_from_slice(value.as_ref())))
1211 }
1212}
1213
1214impl Deref for Piece {
1215 type Target = PieceArray;
1216
1217 #[inline]
1218 fn deref(&self) -> &Self::Target {
1219 <&[u8; Self::SIZE]>::try_from(self.as_ref())
1220 .expect("Slice of memory has correct length; qed")
1221 .into()
1222 }
1223}
1224
1225impl DerefMut for Piece {
1226 #[inline]
1227 fn deref_mut(&mut self) -> &mut Self::Target {
1228 <&mut [u8; Self::SIZE]>::try_from(self.as_mut())
1229 .expect("Slice of memory has correct length; qed")
1230 .into()
1231 }
1232}
1233
1234impl AsRef<[u8]> for Piece {
1235 #[inline]
1236 fn as_ref(&self) -> &[u8] {
1237 self.0.as_ref()
1238 }
1239}
1240
1241impl AsMut<[u8]> for Piece {
1242 #[inline]
1243 fn as_mut(&mut self) -> &mut [u8] {
1244 self.0.as_mut()
1245 }
1246}
1247
1248impl Piece {
1249 pub const SIZE: usize = Record::SIZE + RecordCommitment::SIZE + RecordWitness::SIZE;
1251
1252 pub fn to_shared(self) -> Self {
1258 Self(match self.0 {
1259 CowBytes::Shared(bytes) => CowBytes::Shared(bytes),
1260 CowBytes::Owned(bytes) => CowBytes::Shared(bytes.freeze()),
1261 })
1262 }
1263}
1264
1265#[derive(Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Hash, Deref, DerefMut, AsRef, AsMut)]
1273#[repr(transparent)]
1274pub struct PieceArray([u8; Piece::SIZE]);
1275
1276impl fmt::Debug for PieceArray {
1277 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1278 write!(f, "{}", hex::encode(self.0))
1279 }
1280}
1281
1282impl Default for PieceArray {
1283 #[inline]
1284 fn default() -> Self {
1285 Self([0u8; Piece::SIZE])
1286 }
1287}
1288
1289impl AsRef<[u8]> for PieceArray {
1290 #[inline]
1291 fn as_ref(&self) -> &[u8] {
1292 &self.0
1293 }
1294}
1295
1296impl AsMut<[u8]> for PieceArray {
1297 #[inline]
1298 fn as_mut(&mut self) -> &mut [u8] {
1299 &mut self.0
1300 }
1301}
1302
1303impl From<&PieceArray> for &[u8; Piece::SIZE] {
1304 #[inline]
1305 fn from(value: &PieceArray) -> Self {
1306 unsafe { mem::transmute(value) }
1309 }
1310}
1311
1312impl From<&[u8; Piece::SIZE]> for &PieceArray {
1313 #[inline]
1314 fn from(value: &[u8; Piece::SIZE]) -> Self {
1315 unsafe { mem::transmute(value) }
1318 }
1319}
1320
1321impl From<&mut PieceArray> for &mut [u8; Piece::SIZE] {
1322 #[inline]
1323 fn from(value: &mut PieceArray) -> Self {
1324 unsafe { mem::transmute(value) }
1327 }
1328}
1329
1330impl From<&mut [u8; Piece::SIZE]> for &mut PieceArray {
1331 #[inline]
1332 fn from(value: &mut [u8; Piece::SIZE]) -> Self {
1333 unsafe { mem::transmute(value) }
1336 }
1337}
1338
1339impl PieceArray {
1340 #[inline]
1342 pub fn new_boxed() -> Box<Self> {
1343 unsafe { Box::<Self>::new_zeroed().assume_init() }
1346 }
1347
1348 #[inline]
1350 pub fn split(&self) -> (&Record, &RecordCommitment, &RecordWitness) {
1351 let (record, extra) = self.0.split_at(Record::SIZE);
1352 let (commitment, witness) = extra.split_at(RecordCommitment::SIZE);
1353
1354 let record = <&[u8; Record::SIZE]>::try_from(record)
1355 .expect("Slice of memory has correct length; qed");
1356 let commitment = <&[u8; RecordCommitment::SIZE]>::try_from(commitment)
1357 .expect("Slice of memory has correct length; qed");
1358 let witness = <&[u8; RecordWitness::SIZE]>::try_from(witness)
1359 .expect("Slice of memory has correct length; qed");
1360
1361 (record.into(), commitment.into(), witness.into())
1362 }
1363
1364 #[inline]
1366 pub fn split_mut(&mut self) -> (&mut Record, &mut RecordCommitment, &mut RecordWitness) {
1367 let (record, extra) = self.0.split_at_mut(Record::SIZE);
1368 let (commitment, witness) = extra.split_at_mut(RecordCommitment::SIZE);
1369
1370 let record = <&mut [u8; Record::SIZE]>::try_from(record)
1371 .expect("Slice of memory has correct length; qed");
1372 let commitment = <&mut [u8; RecordCommitment::SIZE]>::try_from(commitment)
1373 .expect("Slice of memory has correct length; qed");
1374 let witness = <&mut [u8; RecordWitness::SIZE]>::try_from(witness)
1375 .expect("Slice of memory has correct length; qed");
1376
1377 (record.into(), commitment.into(), witness.into())
1378 }
1379
1380 #[inline]
1382 pub fn record(&self) -> &Record {
1383 self.split().0
1384 }
1385
1386 #[inline]
1388 pub fn record_mut(&mut self) -> &mut Record {
1389 self.split_mut().0
1390 }
1391
1392 #[inline]
1394 pub fn commitment(&self) -> &RecordCommitment {
1395 self.split().1
1396 }
1397
1398 #[inline]
1400 pub fn commitment_mut(&mut self) -> &mut RecordCommitment {
1401 self.split_mut().1
1402 }
1403
1404 #[inline]
1406 pub fn witness(&self) -> &RecordWitness {
1407 self.split().2
1408 }
1409
1410 #[inline]
1412 pub fn witness_mut(&mut self) -> &mut RecordWitness {
1413 self.split_mut().2
1414 }
1415
1416 #[inline]
1419 pub fn slice_to_repr(value: &[Self]) -> &[[u8; Piece::SIZE]] {
1420 unsafe { mem::transmute(value) }
1423 }
1424
1425 #[inline]
1428 pub fn slice_from_repr(value: &[[u8; Piece::SIZE]]) -> &[Self] {
1429 unsafe { mem::transmute(value) }
1432 }
1433
1434 #[inline]
1437 pub fn slice_mut_to_repr(value: &mut [Self]) -> &mut [[u8; Piece::SIZE]] {
1438 unsafe { mem::transmute(value) }
1441 }
1442
1443 #[inline]
1446 pub fn slice_mut_from_repr(value: &mut [[u8; Piece::SIZE]]) -> &mut [Self] {
1447 unsafe { mem::transmute(value) }
1450 }
1451}
1452
1453impl From<Box<PieceArray>> for Vec<u8> {
1454 fn from(value: Box<PieceArray>) -> Self {
1455 let mut value = mem::ManuallyDrop::new(value);
1456 unsafe { Vec::from_raw_parts(value.as_mut_ptr(), Piece::SIZE, Piece::SIZE) }
1458 }
1459}
1460
1461#[derive(Clone, PartialEq, Eq)]
1463pub struct FlatPieces(CowBytes);
1464
1465impl fmt::Debug for FlatPieces {
1466 #[inline]
1467 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1468 f.debug_struct("FlatPieces").finish_non_exhaustive()
1469 }
1470}
1471
1472impl Deref for FlatPieces {
1473 type Target = [PieceArray];
1474
1475 #[inline]
1476 fn deref(&self) -> &Self::Target {
1477 let bytes = self.0.as_ref();
1478 let pieces = unsafe {
1481 slice::from_raw_parts(
1482 bytes.as_ptr() as *const [u8; Piece::SIZE],
1483 bytes.len() / Piece::SIZE,
1484 )
1485 };
1486 PieceArray::slice_from_repr(pieces)
1487 }
1488}
1489
1490impl DerefMut for FlatPieces {
1491 #[inline]
1492 fn deref_mut(&mut self) -> &mut Self::Target {
1493 let bytes = self.0.as_mut();
1494 let pieces = unsafe {
1497 slice::from_raw_parts_mut(
1498 bytes.as_mut_ptr() as *mut [u8; Piece::SIZE],
1499 bytes.len() / Piece::SIZE,
1500 )
1501 };
1502 PieceArray::slice_mut_from_repr(pieces)
1503 }
1504}
1505
1506impl FlatPieces {
1507 #[inline]
1509 pub fn new(piece_count: usize) -> Self {
1510 Self(CowBytes::Owned(BytesMut::zeroed(piece_count * Piece::SIZE)))
1511 }
1512
1513 #[inline]
1518 pub fn pieces(&self) -> Box<dyn ExactSizeIterator<Item = Piece> + '_> {
1519 match &self.0 {
1520 CowBytes::Shared(bytes) => Box::new(
1521 bytes
1522 .as_chunks::<{ Piece::SIZE }>()
1523 .0
1524 .iter()
1525 .map(|slice| Piece(CowBytes::Shared(bytes.slice_ref(slice)))),
1526 ),
1527 CowBytes::Owned(bytes) => Box::new(
1528 bytes
1529 .as_chunks::<{ Piece::SIZE }>()
1530 .0
1531 .iter()
1532 .map(|slice| Piece(CowBytes::Shared(Bytes::copy_from_slice(slice)))),
1533 ),
1534 }
1535 }
1536
1537 #[inline]
1539 pub fn source_pieces(&self) -> impl ExactSizeIterator<Item = Piece> + '_ {
1540 self.pieces().step_by(2)
1541 }
1542
1543 #[inline]
1545 pub fn source(&self) -> impl ExactSizeIterator<Item = &'_ PieceArray> + '_ {
1546 self.iter().step_by(2)
1547 }
1548
1549 #[inline]
1551 pub fn source_mut(&mut self) -> impl ExactSizeIterator<Item = &'_ mut PieceArray> + '_ {
1552 self.iter_mut().step_by(2)
1553 }
1554
1555 #[inline]
1557 pub fn parity_pieces(&self) -> impl ExactSizeIterator<Item = Piece> + '_ {
1558 self.pieces().skip(1).step_by(2)
1559 }
1560
1561 #[inline]
1563 pub fn parity(&self) -> impl ExactSizeIterator<Item = &'_ PieceArray> + '_ {
1564 self.iter().skip(1).step_by(2)
1565 }
1566
1567 #[inline]
1569 pub fn parity_mut(&mut self) -> impl ExactSizeIterator<Item = &'_ mut PieceArray> + '_ {
1570 self.iter_mut().skip(1).step_by(2)
1571 }
1572
1573 pub fn to_shared(self) -> Self {
1579 Self(match self.0 {
1580 CowBytes::Shared(bytes) => CowBytes::Shared(bytes),
1581 CowBytes::Owned(bytes) => CowBytes::Shared(bytes.freeze()),
1582 })
1583 }
1584}
1585
1586#[cfg(feature = "parallel")]
1587impl FlatPieces {
1588 #[inline]
1590 pub fn par_source(&self) -> impl IndexedParallelIterator<Item = &'_ PieceArray> + '_ {
1591 self.par_iter().step_by(2)
1592 }
1593
1594 #[inline]
1596 pub fn par_source_mut(
1597 &mut self,
1598 ) -> impl IndexedParallelIterator<Item = &'_ mut PieceArray> + '_ {
1599 self.par_iter_mut().step_by(2)
1600 }
1601
1602 #[inline]
1604 pub fn par_parity(&self) -> impl IndexedParallelIterator<Item = &'_ PieceArray> + '_ {
1605 self.par_iter().skip(1).step_by(2)
1606 }
1607
1608 #[inline]
1610 pub fn par_parity_mut(
1611 &mut self,
1612 ) -> impl IndexedParallelIterator<Item = &'_ mut PieceArray> + '_ {
1613 self.par_iter_mut().skip(1).step_by(2)
1614 }
1615}