1#[cfg(feature = "alloc")]
4mod cow_bytes;
5#[cfg(feature = "alloc")]
6mod flat_pieces;
7#[cfg(feature = "alloc")]
8mod piece;
9
10#[cfg(feature = "alloc")]
11pub use crate::pieces::flat_pieces::FlatPieces;
12#[cfg(feature = "alloc")]
13pub use crate::pieces::piece::Piece;
14use crate::segments::{
15 LocalSegmentIndex, RecordedHistorySegment, SegmentIndex, SegmentPosition, SegmentRoot,
16 SuperSegmentIndex, SuperSegmentRoot,
17};
18use crate::shard::ShardIndex;
19#[cfg(feature = "serde")]
20use ::serde::{Deserialize, Deserializer, Serialize, Serializer};
21use ab_io_type::trivial_type::TrivialType;
22use ab_io_type::unaligned::Unaligned;
23use ab_merkle_tree::balanced::BalancedMerkleTree;
24#[cfg(feature = "alloc")]
25use alloc::boxed::Box;
26#[cfg(feature = "alloc")]
27use alloc::vec::Vec;
28use blake3::OUT_LEN;
29use core::array::TryFromSliceError;
30use core::hash::Hash;
31use core::iter::Step;
32use core::mem::MaybeUninit;
33#[cfg(feature = "alloc")]
34use core::slice;
35use core::{fmt, mem};
36use derive_more::{
37 Add, AddAssign, AsMut, AsRef, Deref, DerefMut, Display, Div, DivAssign, From, Into, Mul,
38 MulAssign, Sub, SubAssign,
39};
40#[cfg(feature = "scale-codec")]
41use parity_scale_codec::{Decode, Encode, MaxEncodedLen};
42#[cfg(feature = "serde")]
43use serde_big_array::BigArray;
44
45#[derive(
47 Debug,
48 Display,
49 Default,
50 Copy,
51 Clone,
52 Ord,
53 PartialOrd,
54 Eq,
55 PartialEq,
56 Hash,
57 Add,
58 AddAssign,
59 Sub,
60 SubAssign,
61 Mul,
62 MulAssign,
63 Div,
64 DivAssign,
65)]
66#[cfg_attr(feature = "scale-codec", derive(Encode, Decode, MaxEncodedLen))]
67#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
68#[repr(C)]
69pub struct PieceIndex(u64);
70
71impl Step for PieceIndex {
72 #[inline]
73 fn steps_between(start: &Self, end: &Self) -> (usize, Option<usize>) {
74 u64::steps_between(&start.0, &end.0)
75 }
76
77 #[inline]
78 fn forward_checked(start: Self, count: usize) -> Option<Self> {
79 u64::forward_checked(start.0, count).map(Self)
80 }
81
82 #[inline(always)]
83 fn forward_overflowing(start: Self, count: usize) -> (Self, bool) {
84 let (n, overflowing) = u64::forward_overflowing(start.0, count);
85 (Self(n), overflowing)
86 }
87
88 #[inline]
89 fn backward_checked(start: Self, count: usize) -> Option<Self> {
90 u64::backward_checked(start.0, count).map(Self)
91 }
92
93 #[inline(always)]
94 fn backward_overflowing(start: Self, count: usize) -> (Self, bool) {
95 let (n, overflowing) = u64::backward_overflowing(start.0, count);
96 (Self(n), overflowing)
97 }
98}
99
100const impl From<u64> for PieceIndex {
101 #[inline(always)]
102 fn from(value: u64) -> Self {
103 Self(value)
104 }
105}
106
107const impl From<PieceIndex> for u64 {
108 #[inline(always)]
109 fn from(value: PieceIndex) -> Self {
110 value.0
111 }
112}
113
114impl PieceIndex {
115 pub const SIZE: usize = size_of::<u64>();
117 pub const ZERO: PieceIndex = PieceIndex(0);
119 pub const ONE: PieceIndex = PieceIndex(1);
121
122 #[inline]
124 pub const fn from_bytes(bytes: [u8; Self::SIZE]) -> Self {
125 Self(u64::from_le_bytes(bytes))
126 }
127
128 #[inline]
130 pub const fn to_bytes(self) -> [u8; Self::SIZE] {
131 self.0.to_le_bytes()
132 }
133
134 #[inline]
136 pub const fn segment_index(&self) -> SegmentIndex {
137 SegmentIndex::from(self.0 / RecordedHistorySegment::NUM_PIECES as u64)
138 }
139
140 #[inline]
142 pub fn position(&self) -> PiecePosition {
143 PiecePosition::from((self.0 % RecordedHistorySegment::NUM_PIECES as u64) as u8)
144 }
145}
146
147const {
148 assert!(RecordedHistorySegment::NUM_PIECES == usize::from(u8::MAX) + 1);
150}
151
152#[derive(
154 Debug,
155 Display,
156 Default,
157 Copy,
158 Clone,
159 Ord,
160 PartialOrd,
161 Eq,
162 PartialEq,
163 Hash,
164 From,
165 Into,
166 TrivialType,
167)]
168#[cfg_attr(feature = "scale-codec", derive(Encode, Decode, MaxEncodedLen))]
169#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
170#[repr(C)]
171pub struct PiecePosition(u8);
172
173impl Step for PiecePosition {
174 #[inline]
175 fn steps_between(start: &Self, end: &Self) -> (usize, Option<usize>) {
176 u8::steps_between(&start.0, &end.0)
177 }
178
179 #[inline]
180 fn forward_checked(start: Self, count: usize) -> Option<Self> {
181 u8::forward_checked(start.0, count).map(Self)
182 }
183
184 #[inline(always)]
185 fn forward_overflowing(start: Self, count: usize) -> (Self, bool) {
186 let (n, overflowing) = u8::forward_overflowing(start.0, count);
187 (Self(n), overflowing)
188 }
189
190 #[inline]
191 fn backward_checked(start: Self, count: usize) -> Option<Self> {
192 u8::backward_checked(start.0, count).map(Self)
193 }
194
195 #[inline(always)]
196 fn backward_overflowing(start: Self, count: usize) -> (Self, bool) {
197 let (n, overflowing) = u8::backward_overflowing(start.0, count);
198 (Self(n), overflowing)
199 }
200}
201
202impl From<PiecePosition> for u16 {
203 #[inline]
204 fn from(original: PiecePosition) -> Self {
205 Self::from(original.0)
206 }
207}
208
209impl From<PiecePosition> for u32 {
210 #[inline]
211 fn from(original: PiecePosition) -> Self {
212 Self::from(original.0)
213 }
214}
215
216impl From<PiecePosition> for u64 {
217 #[inline]
218 fn from(original: PiecePosition) -> Self {
219 Self::from(original.0)
220 }
221}
222
223impl From<PiecePosition> for usize {
224 #[inline]
225 fn from(original: PiecePosition) -> Self {
226 usize::from(original.0)
227 }
228}
229
230#[derive(
232 Debug,
233 Display,
234 Default,
235 Copy,
236 Clone,
237 Ord,
238 PartialOrd,
239 Eq,
240 PartialEq,
241 Hash,
242 From,
243 Into,
244 Add,
245 AddAssign,
246 Sub,
247 SubAssign,
248 Mul,
249 MulAssign,
250 Div,
251 DivAssign,
252 TrivialType,
253)]
254#[cfg_attr(feature = "scale-codec", derive(Encode, Decode, MaxEncodedLen))]
255#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
256#[repr(C)]
257pub struct PieceOffset(u16);
258
259impl Step for PieceOffset {
260 #[inline]
261 fn steps_between(start: &Self, end: &Self) -> (usize, Option<usize>) {
262 u16::steps_between(&start.0, &end.0)
263 }
264
265 #[inline]
266 fn forward_checked(start: Self, count: usize) -> Option<Self> {
267 u16::forward_checked(start.0, count).map(Self)
268 }
269
270 #[inline(always)]
271 fn forward_overflowing(start: Self, count: usize) -> (Self, bool) {
272 let (n, overflowing) = u16::forward_overflowing(start.0, count);
273 (Self(n), overflowing)
274 }
275
276 #[inline]
277 fn backward_checked(start: Self, count: usize) -> Option<Self> {
278 u16::backward_checked(start.0, count).map(Self)
279 }
280
281 #[inline(always)]
282 fn backward_overflowing(start: Self, count: usize) -> (Self, bool) {
283 let (n, overflowing) = u16::backward_overflowing(start.0, count);
284 (Self(n), overflowing)
285 }
286}
287
288impl From<PieceOffset> for u32 {
289 #[inline]
290 fn from(original: PieceOffset) -> Self {
291 Self::from(original.0)
292 }
293}
294
295impl From<PieceOffset> for u64 {
296 #[inline]
297 fn from(original: PieceOffset) -> Self {
298 Self::from(original.0)
299 }
300}
301
302impl From<PieceOffset> for usize {
303 #[inline]
304 fn from(original: PieceOffset) -> Self {
305 usize::from(original.0)
306 }
307}
308
309impl PieceOffset {
310 pub const ZERO: Self = Self(0);
312 pub const ONE: Self = Self(1);
314 pub const SIZE: usize = size_of::<u16>();
316
317 #[inline]
319 pub const fn to_bytes(self) -> [u8; Self::SIZE] {
320 self.0.to_le_bytes()
321 }
322}
323
324#[derive(
326 Default,
327 Copy,
328 Clone,
329 Eq,
330 PartialEq,
331 Ord,
332 PartialOrd,
333 Hash,
334 From,
335 Into,
336 AsRef,
337 AsMut,
338 Deref,
339 DerefMut,
340 TrivialType,
341)]
342#[cfg_attr(feature = "scale-codec", derive(Encode, Decode, MaxEncodedLen))]
343#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
344#[cfg_attr(feature = "serde", serde(transparent))]
345#[repr(C)]
346pub struct RecordChunk([u8; RecordChunk::SIZE]);
347
348impl fmt::Debug for RecordChunk {
349 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
350 for byte in self.0 {
351 write!(f, "{byte:02x}")?;
352 }
353 Ok(())
354 }
355}
356
357impl RecordChunk {
358 pub const SIZE: usize = 32;
360
361 #[inline]
363 pub fn slice_to_repr(value: &[Self]) -> &[[u8; Self::SIZE]] {
364 unsafe { mem::transmute(value) }
366 }
367
368 #[inline]
370 pub fn slice_from_repr(value: &[[u8; Self::SIZE]]) -> &[Self] {
371 unsafe { mem::transmute(value) }
373 }
374
375 #[inline]
378 pub fn slice_mut_to_repr(value: &mut [Self]) -> &mut [[u8; Self::SIZE]] {
379 unsafe { mem::transmute(value) }
381 }
382
383 #[inline]
386 pub fn slice_mut_from_repr(value: &mut [[u8; Self::SIZE]]) -> &mut [Self] {
387 unsafe { mem::transmute(value) }
389 }
390}
391
392#[derive(Copy, Clone, Eq, PartialEq, Deref, DerefMut, TrivialType)]
396#[repr(C)]
397pub struct Record([[u8; RecordChunk::SIZE]; Record::NUM_CHUNKS]);
398
399impl fmt::Debug for Record {
400 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
401 for byte in self.0.as_flattened() {
402 write!(f, "{byte:02x}")?;
403 }
404 Ok(())
405 }
406}
407
408impl AsRef<[u8]> for Record {
409 #[inline]
410 fn as_ref(&self) -> &[u8] {
411 self.0.as_flattened()
412 }
413}
414
415impl AsMut<[u8]> for Record {
416 #[inline]
417 fn as_mut(&mut self) -> &mut [u8] {
418 self.0.as_flattened_mut()
419 }
420}
421
422impl From<&Record> for &[[u8; RecordChunk::SIZE]; Record::NUM_CHUNKS] {
423 #[inline]
424 fn from(value: &Record) -> Self {
425 unsafe { mem::transmute(value) }
427 }
428}
429
430impl From<&[[u8; RecordChunk::SIZE]; Record::NUM_CHUNKS]> for &Record {
431 #[inline]
432 fn from(value: &[[u8; RecordChunk::SIZE]; Record::NUM_CHUNKS]) -> Self {
433 unsafe { mem::transmute(value) }
435 }
436}
437
438impl From<&mut Record> for &mut [[u8; RecordChunk::SIZE]; Record::NUM_CHUNKS] {
439 #[inline]
440 fn from(value: &mut Record) -> Self {
441 unsafe { mem::transmute(value) }
443 }
444}
445
446impl From<&mut [[u8; RecordChunk::SIZE]; Record::NUM_CHUNKS]> for &mut Record {
447 #[inline]
448 fn from(value: &mut [[u8; RecordChunk::SIZE]; Record::NUM_CHUNKS]) -> Self {
449 unsafe { mem::transmute(value) }
451 }
452}
453
454impl Record {
455 pub const NUM_CHUNKS: usize = 2usize.pow(15);
457 pub const NUM_S_BUCKETS: usize = Record::NUM_CHUNKS
461 * RecordedHistorySegment::ERASURE_CODING_RATE.1
462 / RecordedHistorySegment::ERASURE_CODING_RATE.0;
463 pub const SIZE: usize = RecordChunk::SIZE * Record::NUM_CHUNKS;
465
466 #[inline]
468 #[cfg(feature = "alloc")]
469 pub fn new_boxed() -> Box<Self> {
470 unsafe { Box::new_zeroed().assume_init() }
473 }
474
475 #[inline]
477 #[cfg(feature = "alloc")]
478 pub fn new_zero_vec(length: usize) -> Vec<Self> {
479 let mut records = Vec::with_capacity(length);
482 {
483 let slice = records.spare_capacity_mut();
484 let slice = unsafe {
488 slice::from_raw_parts_mut(
489 slice
490 .as_mut_ptr()
491 .cast::<[[MaybeUninit<u8>; RecordChunk::SIZE]; Record::NUM_CHUNKS]>(),
492 length,
493 )
494 };
495 for byte in slice.as_flattened_mut().as_flattened_mut() {
496 byte.write(0);
497 }
498 }
499 unsafe {
501 records.set_len(records.capacity());
502 }
503
504 records
505 }
506
507 #[inline(always)]
510 pub fn slice_to_repr(value: &[Self]) -> &[[[u8; RecordChunk::SIZE]; Record::NUM_CHUNKS]] {
511 unsafe { mem::transmute(value) }
513 }
514
515 #[inline(always)]
518 pub fn slice_from_repr(value: &[[[u8; RecordChunk::SIZE]; Record::NUM_CHUNKS]]) -> &[Self] {
519 unsafe { mem::transmute(value) }
521 }
522
523 #[inline(always)]
526 pub fn slice_mut_to_repr(
527 value: &mut [Self],
528 ) -> &mut [[[u8; RecordChunk::SIZE]; Record::NUM_CHUNKS]] {
529 unsafe { mem::transmute(value) }
531 }
532
533 #[inline(always)]
536 pub fn slice_mut_from_repr(
537 value: &mut [[[u8; RecordChunk::SIZE]; Record::NUM_CHUNKS]],
538 ) -> &mut [Self] {
539 unsafe { mem::transmute(value) }
541 }
542
543 #[inline(always)]
545 pub fn source_chunks_root(&self) -> RecordChunksRoot {
546 RecordChunksRoot(BalancedMerkleTree::compute_root_only(self))
547 }
548}
549
550#[derive(Copy, Clone, Eq, PartialEq, Hash, Deref, DerefMut, From, Into, TrivialType)]
554#[cfg_attr(feature = "scale-codec", derive(Encode, Decode, MaxEncodedLen))]
555#[repr(C)]
556pub struct RecordRoot([u8; RecordRoot::SIZE]);
557
558impl fmt::Debug for RecordRoot {
559 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
560 for byte in self.0 {
561 write!(f, "{byte:02x}")?;
562 }
563 Ok(())
564 }
565}
566
567#[cfg(feature = "serde")]
568#[derive(Serialize, Deserialize)]
569#[serde(transparent)]
570struct RecordRootBinary(#[serde(with = "BigArray")] [u8; RecordRoot::SIZE]);
571
572#[cfg(feature = "serde")]
573#[derive(Serialize, Deserialize)]
574#[serde(transparent)]
575struct RecordRootHex(#[serde(with = "hex")] [u8; RecordRoot::SIZE]);
576
577#[cfg(feature = "serde")]
578impl Serialize for RecordRoot {
579 #[inline]
580 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
581 where
582 S: Serializer,
583 {
584 if serializer.is_human_readable() {
585 RecordRootHex(self.0).serialize(serializer)
586 } else {
587 RecordRootBinary(self.0).serialize(serializer)
588 }
589 }
590}
591
592#[cfg(feature = "serde")]
593impl<'de> Deserialize<'de> for RecordRoot {
594 #[inline]
595 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
596 where
597 D: Deserializer<'de>,
598 {
599 Ok(Self(if deserializer.is_human_readable() {
600 RecordRootHex::deserialize(deserializer)?.0
601 } else {
602 RecordRootBinary::deserialize(deserializer)?.0
603 }))
604 }
605}
606
607impl Default for RecordRoot {
608 #[inline]
609 fn default() -> Self {
610 Self([0; _])
611 }
612}
613
614impl TryFrom<&[u8]> for RecordRoot {
615 type Error = TryFromSliceError;
616
617 #[inline]
618 fn try_from(slice: &[u8]) -> Result<Self, Self::Error> {
619 <[u8; Self::SIZE]>::try_from(slice).map(Self)
620 }
621}
622
623impl AsRef<[u8]> for RecordRoot {
624 #[inline]
625 fn as_ref(&self) -> &[u8] {
626 &self.0
627 }
628}
629
630impl AsMut<[u8]> for RecordRoot {
631 #[inline]
632 fn as_mut(&mut self) -> &mut [u8] {
633 &mut self.0
634 }
635}
636
637impl From<&RecordRoot> for &[u8; RecordRoot::SIZE] {
638 #[inline]
639 fn from(value: &RecordRoot) -> Self {
640 unsafe { mem::transmute(value) }
643 }
644}
645
646impl From<&[u8; RecordRoot::SIZE]> for &RecordRoot {
647 #[inline]
648 fn from(value: &[u8; RecordRoot::SIZE]) -> Self {
649 unsafe { mem::transmute(value) }
652 }
653}
654
655impl From<&mut RecordRoot> for &mut [u8; RecordRoot::SIZE] {
656 #[inline]
657 fn from(value: &mut RecordRoot) -> Self {
658 unsafe { mem::transmute(value) }
661 }
662}
663
664impl From<&mut [u8; RecordRoot::SIZE]> for &mut RecordRoot {
665 #[inline]
666 fn from(value: &mut [u8; RecordRoot::SIZE]) -> Self {
667 unsafe { mem::transmute(value) }
670 }
671}
672
673impl RecordRoot {
674 pub const SIZE: usize = 32;
676
677 pub fn is_valid(
679 &self,
680 segment_root: &SegmentRoot,
681 record_proof: &RecordProof,
682 position: PiecePosition,
683 ) -> bool {
684 BalancedMerkleTree::<{ RecordedHistorySegment::NUM_PIECES }>::verify(
685 segment_root,
686 record_proof,
687 usize::from(position),
688 self.0,
689 )
690 }
691}
692
693#[derive(Copy, Clone, Eq, PartialEq, Hash, Deref, DerefMut, From, Into, TrivialType)]
695#[cfg_attr(feature = "scale-codec", derive(Encode, Decode, MaxEncodedLen))]
696#[repr(C)]
697pub struct RecordChunksRoot([u8; RecordChunksRoot::SIZE]);
698
699impl fmt::Debug for RecordChunksRoot {
700 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
701 for byte in self.0 {
702 write!(f, "{byte:02x}")?;
703 }
704 Ok(())
705 }
706}
707
708#[cfg(feature = "serde")]
709#[derive(Serialize, Deserialize)]
710#[serde(transparent)]
711struct RecordChunksRootBinary(#[serde(with = "BigArray")] [u8; RecordChunksRoot::SIZE]);
712
713#[cfg(feature = "serde")]
714#[derive(Serialize, Deserialize)]
715#[serde(transparent)]
716struct RecordChunksRootHex(#[serde(with = "hex")] [u8; RecordChunksRoot::SIZE]);
717
718#[cfg(feature = "serde")]
719impl Serialize for RecordChunksRoot {
720 #[inline]
721 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
722 where
723 S: Serializer,
724 {
725 if serializer.is_human_readable() {
726 RecordChunksRootHex(self.0).serialize(serializer)
727 } else {
728 RecordChunksRootBinary(self.0).serialize(serializer)
729 }
730 }
731}
732
733#[cfg(feature = "serde")]
734impl<'de> Deserialize<'de> for RecordChunksRoot {
735 #[inline]
736 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
737 where
738 D: Deserializer<'de>,
739 {
740 Ok(Self(if deserializer.is_human_readable() {
741 RecordChunksRootHex::deserialize(deserializer)?.0
742 } else {
743 RecordChunksRootBinary::deserialize(deserializer)?.0
744 }))
745 }
746}
747
748impl Default for RecordChunksRoot {
749 #[inline]
750 fn default() -> Self {
751 Self([0; _])
752 }
753}
754
755impl TryFrom<&[u8]> for RecordChunksRoot {
756 type Error = TryFromSliceError;
757
758 #[inline]
759 fn try_from(slice: &[u8]) -> Result<Self, Self::Error> {
760 <[u8; Self::SIZE]>::try_from(slice).map(Self)
761 }
762}
763
764impl AsRef<[u8]> for RecordChunksRoot {
765 #[inline]
766 fn as_ref(&self) -> &[u8] {
767 &self.0
768 }
769}
770
771impl AsMut<[u8]> for RecordChunksRoot {
772 #[inline]
773 fn as_mut(&mut self) -> &mut [u8] {
774 &mut self.0
775 }
776}
777
778impl From<&RecordChunksRoot> for &[u8; RecordChunksRoot::SIZE] {
779 #[inline]
780 fn from(value: &RecordChunksRoot) -> Self {
781 unsafe { mem::transmute(value) }
784 }
785}
786
787impl From<&[u8; RecordChunksRoot::SIZE]> for &RecordChunksRoot {
788 #[inline]
789 fn from(value: &[u8; RecordChunksRoot::SIZE]) -> Self {
790 unsafe { mem::transmute(value) }
793 }
794}
795
796impl From<&mut RecordChunksRoot> for &mut [u8; RecordChunksRoot::SIZE] {
797 #[inline]
798 fn from(value: &mut RecordChunksRoot) -> Self {
799 unsafe { mem::transmute(value) }
802 }
803}
804
805impl From<&mut [u8; RecordChunksRoot::SIZE]> for &mut RecordChunksRoot {
806 #[inline]
807 fn from(value: &mut [u8; RecordChunksRoot::SIZE]) -> Self {
808 unsafe { mem::transmute(value) }
811 }
812}
813
814impl RecordChunksRoot {
815 pub const SIZE: usize = 32;
817}
818
819#[derive(Copy, Clone, Eq, PartialEq, Hash, Deref, DerefMut, From, Into, TrivialType)]
821#[cfg_attr(feature = "scale-codec", derive(Encode, Decode, MaxEncodedLen))]
822#[repr(C)]
823pub struct RecordProof([[u8; OUT_LEN]; RecordProof::NUM_HASHES]);
824
825impl fmt::Debug for RecordProof {
826 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
827 write!(f, "[")?;
828 for hash in self.0 {
829 for byte in hash {
830 write!(f, "{byte:02x}")?;
831 }
832 write!(f, ", ")?;
833 }
834 write!(f, "]")?;
835 Ok(())
836 }
837}
838
839#[cfg(feature = "serde")]
840#[derive(Serialize, Deserialize)]
841#[serde(transparent)]
842struct RecordProofBinary([[u8; OUT_LEN]; RecordProof::NUM_HASHES]);
843
844#[cfg(feature = "serde")]
845#[derive(Serialize, Deserialize)]
846#[serde(transparent)]
847struct RecordProofHexHash(#[serde(with = "hex")] [u8; OUT_LEN]);
848
849#[cfg(feature = "serde")]
850#[derive(Serialize, Deserialize)]
851#[serde(transparent)]
852struct RecordProofHex([RecordProofHexHash; RecordProof::NUM_HASHES]);
853
854#[cfg(feature = "serde")]
855impl Serialize for RecordProof {
856 #[inline]
857 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
858 where
859 S: Serializer,
860 {
861 if serializer.is_human_readable() {
862 RecordProofHex(unsafe {
865 mem::transmute::<
866 [[u8; OUT_LEN]; Self::NUM_HASHES],
867 [RecordProofHexHash; Self::NUM_HASHES],
868 >(self.0)
869 })
870 .serialize(serializer)
871 } else {
872 RecordProofBinary(self.0).serialize(serializer)
873 }
874 }
875}
876
877#[cfg(feature = "serde")]
878impl<'de> Deserialize<'de> for RecordProof {
879 #[inline]
880 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
881 where
882 D: Deserializer<'de>,
883 {
884 Ok(Self(if deserializer.is_human_readable() {
885 unsafe {
888 mem::transmute::<
889 [RecordProofHexHash; Self::NUM_HASHES],
890 [[u8; OUT_LEN]; Self::NUM_HASHES],
891 >(RecordProofHex::deserialize(deserializer)?.0)
892 }
893 } else {
894 RecordProofBinary::deserialize(deserializer)?.0
895 }))
896 }
897}
898
899impl Default for RecordProof {
900 #[inline]
901 fn default() -> Self {
902 Self([[0; OUT_LEN]; _])
903 }
904}
905
906impl AsRef<[u8]> for RecordProof {
907 #[inline]
908 fn as_ref(&self) -> &[u8] {
909 self.0.as_flattened()
910 }
911}
912
913impl AsMut<[u8]> for RecordProof {
914 #[inline]
915 fn as_mut(&mut self) -> &mut [u8] {
916 self.0.as_flattened_mut()
917 }
918}
919
920impl From<&RecordProof> for &[u8; RecordProof::SIZE] {
921 #[inline]
922 fn from(value: &RecordProof) -> Self {
923 unsafe { mem::transmute(value) }
926 }
927}
928
929impl From<&[u8; RecordProof::SIZE]> for &RecordProof {
930 #[inline]
931 fn from(value: &[u8; RecordProof::SIZE]) -> Self {
932 unsafe { mem::transmute(value) }
935 }
936}
937
938impl From<&mut RecordProof> for &mut [u8; RecordProof::SIZE] {
939 #[inline]
940 fn from(value: &mut RecordProof) -> Self {
941 unsafe { mem::transmute(value) }
944 }
945}
946
947impl From<&mut [u8; RecordProof::SIZE]> for &mut RecordProof {
948 #[inline]
949 fn from(value: &mut [u8; RecordProof::SIZE]) -> Self {
950 unsafe { mem::transmute(value) }
953 }
954}
955
956impl RecordProof {
957 pub const SIZE: usize = OUT_LEN * Self::NUM_HASHES;
959 const NUM_HASHES: usize = RecordedHistorySegment::NUM_PIECES.ilog2() as usize;
960}
961
962#[derive(Copy, Clone, Eq, PartialEq, Hash, Deref, DerefMut, From, Into, TrivialType)]
964#[cfg_attr(feature = "scale-codec", derive(Encode, Decode, MaxEncodedLen))]
965#[repr(C)]
966pub struct SegmentProof([[u8; OUT_LEN]; SegmentProof::NUM_HASHES]);
967
968impl fmt::Debug for SegmentProof {
969 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
970 write!(f, "[")?;
971 for hash in self.0 {
972 for byte in hash {
973 write!(f, "{byte:02x}")?;
974 }
975 write!(f, ", ")?;
976 }
977 write!(f, "]")?;
978 Ok(())
979 }
980}
981
982#[cfg(feature = "serde")]
983#[derive(Serialize, Deserialize)]
984#[serde(transparent)]
985struct SegmentProofBinary([[u8; OUT_LEN]; SegmentProof::NUM_HASHES]);
986
987#[cfg(feature = "serde")]
988#[derive(Serialize, Deserialize)]
989#[serde(transparent)]
990struct SegmentProofHexHash(#[serde(with = "hex")] [u8; OUT_LEN]);
991
992#[cfg(feature = "serde")]
993#[derive(Serialize, Deserialize)]
994#[serde(transparent)]
995struct SegmentProofHex([SegmentProofHexHash; SegmentProof::NUM_HASHES]);
996
997#[cfg(feature = "serde")]
998impl Serialize for SegmentProof {
999 #[inline]
1000 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
1001 where
1002 S: Serializer,
1003 {
1004 if serializer.is_human_readable() {
1005 SegmentProofHex(unsafe {
1008 mem::transmute::<
1009 [[u8; OUT_LEN]; Self::NUM_HASHES],
1010 [SegmentProofHexHash; Self::NUM_HASHES],
1011 >(self.0)
1012 })
1013 .serialize(serializer)
1014 } else {
1015 SegmentProofBinary(self.0).serialize(serializer)
1016 }
1017 }
1018}
1019
1020#[cfg(feature = "serde")]
1021impl<'de> Deserialize<'de> for SegmentProof {
1022 #[inline]
1023 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
1024 where
1025 D: Deserializer<'de>,
1026 {
1027 Ok(Self(if deserializer.is_human_readable() {
1028 unsafe {
1031 mem::transmute::<
1032 [SegmentProofHexHash; Self::NUM_HASHES],
1033 [[u8; OUT_LEN]; Self::NUM_HASHES],
1034 >(SegmentProofHex::deserialize(deserializer)?.0)
1035 }
1036 } else {
1037 SegmentProofBinary::deserialize(deserializer)?.0
1038 }))
1039 }
1040}
1041
1042impl Default for SegmentProof {
1043 #[inline]
1044 fn default() -> Self {
1045 Self([[0; OUT_LEN]; _])
1046 }
1047}
1048
1049impl AsRef<[u8]> for SegmentProof {
1050 #[inline]
1051 fn as_ref(&self) -> &[u8] {
1052 self.0.as_flattened()
1053 }
1054}
1055
1056impl AsMut<[u8]> for SegmentProof {
1057 #[inline]
1058 fn as_mut(&mut self) -> &mut [u8] {
1059 self.0.as_flattened_mut()
1060 }
1061}
1062
1063impl From<&SegmentProof> for &[u8; SegmentProof::SIZE] {
1064 #[inline]
1065 fn from(value: &SegmentProof) -> Self {
1066 unsafe { mem::transmute(value) }
1069 }
1070}
1071
1072impl From<&[u8; SegmentProof::SIZE]> for &SegmentProof {
1073 #[inline]
1074 fn from(value: &[u8; SegmentProof::SIZE]) -> Self {
1075 unsafe { mem::transmute(value) }
1078 }
1079}
1080
1081impl From<&mut SegmentProof> for &mut [u8; SegmentProof::SIZE] {
1082 #[inline]
1083 fn from(value: &mut SegmentProof) -> Self {
1084 unsafe { mem::transmute(value) }
1087 }
1088}
1089
1090impl From<&mut [u8; SegmentProof::SIZE]> for &mut SegmentProof {
1091 #[inline]
1092 fn from(value: &mut [u8; SegmentProof::SIZE]) -> Self {
1093 unsafe { mem::transmute(value) }
1096 }
1097}
1098
1099impl SegmentProof {
1100 pub const SIZE: usize = OUT_LEN * Self::NUM_HASHES;
1102 const NUM_HASHES: usize = SuperSegmentRoot::MAX_SEGMENTS.next_power_of_two().ilog2() as usize;
1103
1104 pub fn as_uninit_repr(
1108 &mut self,
1109 ) -> &mut [MaybeUninit<[u8; OUT_LEN]>; SegmentProof::NUM_HASHES] {
1110 unsafe { mem::transmute(&mut self.0) }
1112 }
1113}
1114
1115#[derive(Debug, Default, Copy, Clone, Eq, PartialEq, TrivialType)]
1119#[cfg_attr(feature = "scale-codec", derive(Encode, Decode))]
1120#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
1121#[cfg_attr(feature = "serde", serde(rename_all = "camelCase"))]
1122#[repr(C)]
1123pub struct PieceHeader {
1124 pub shard_index: Unaligned<ShardIndex>,
1126 pub local_segment_index: Unaligned<LocalSegmentIndex>,
1128 pub super_segment_index: Unaligned<SuperSegmentIndex>,
1130 pub segment_position: Unaligned<SegmentPosition>,
1132 pub segment_root: SegmentRoot,
1134 pub segment_proof: SegmentProof,
1136 pub parity_chunks_root: RecordChunksRoot,
1140 pub record_proof: RecordProof,
1142}
1143
1144const {
1145 assert!(align_of::<PieceHeader>() == 1);
1147}
1148
1149#[derive(Debug, Copy, Clone, Eq, PartialEq, TrivialType)]
1158#[repr(C)]
1159pub struct InnerPiece {
1160 pub header: PieceHeader,
1162 pub record: Record,
1164}
1165
1166const {
1167 assert!(align_of::<InnerPiece>() == 1);
1169}
1170
1171impl InnerPiece {
1172 pub const SIZE: usize = size_of::<Self>();
1174
1175 #[inline]
1177 #[cfg(feature = "alloc")]
1178 pub fn new_boxed() -> Box<Self> {
1179 unsafe { Box::<Self>::new_zeroed().assume_init() }
1182 }
1183
1184 pub fn is_valid(
1186 &self,
1187 super_segment_root: &SuperSegmentRoot,
1188 num_segments: u32,
1189 position: PiecePosition,
1190 ) -> bool {
1191 if !self.header.segment_root.is_valid(
1192 self.header.shard_index.as_inner(),
1193 self.header.local_segment_index.as_inner(),
1194 self.header.segment_position.as_inner(),
1195 &self.header.segment_proof,
1196 num_segments,
1197 super_segment_root,
1198 ) {
1199 return false;
1200 }
1201 self.record_root().is_valid(
1202 &self.header.segment_root,
1203 &self.header.record_proof,
1204 position,
1205 )
1206 }
1207
1208 #[inline]
1212 pub fn record_root(&self) -> RecordRoot {
1213 let record_merkle_tree_root = BalancedMerkleTree::compute_root_only(&[
1214 *self.record.source_chunks_root(),
1215 *self.header.parity_chunks_root,
1216 ]);
1217
1218 RecordRoot::from(record_merkle_tree_root)
1219 }
1220
1221 #[inline]
1224 pub fn slice_to_repr(value: &[Self]) -> &[[u8; Self::SIZE]] {
1225 unsafe { mem::transmute(value) }
1228 }
1229
1230 #[inline]
1233 pub fn slice_from_repr(value: &[[u8; Self::SIZE]]) -> &[Self] {
1234 unsafe { mem::transmute(value) }
1237 }
1238
1239 #[inline]
1242 pub fn slice_mut_to_repr(value: &mut [Self]) -> &mut [[u8; Self::SIZE]] {
1243 unsafe { mem::transmute(value) }
1246 }
1247
1248 #[inline]
1251 pub fn slice_mut_from_repr(value: &mut [[u8; Self::SIZE]]) -> &mut [Self] {
1252 unsafe { mem::transmute(value) }
1255 }
1256}