1use std::{
13 collections::hash_map::HashMap,
14 convert::TryFrom,
15 io::{prelude::*, Cursor, Read, SeekFrom, Write},
16 mem::size_of,
17};
18
19use anyhow::{ensure, Context, Result};
20use byteorder::{BigEndian, LittleEndian, ReadBytesExt, WriteBytesExt};
21use num_derive::{FromPrimitive, ToPrimitive};
22use num_traits::cast::FromPrimitive;
23#[cfg(any(test, feature = "fuzzing"))]
24use proptest::{collection::hash_map, prelude::*};
25#[cfg(any(test, feature = "fuzzing"))]
26use proptest_derive::Arbitrary;
27use serde::{Deserialize, Serialize};
28use thiserror::Error;
29
30use crate::{
31 metrics::{DIEM_JELLYFISH_INTERNAL_ENCODED_BYTES, DIEM_JELLYFISH_LEAF_ENCODED_BYTES},
32 types::{
33 nibble::{nibble_path::NibblePath, Nibble, ROOT_NIBBLE_HEIGHT},
34 proof::{SparseMerkleInternalNode, SparseMerkleLeafNode},
35 Version,
36 },
37 KeyHash, ValueHash, SPARSE_MERKLE_PLACEHOLDER_HASH,
38};
39
40#[derive(Clone, Debug, Hash, Eq, PartialEq, Ord, PartialOrd)]
42#[cfg_attr(any(test, feature = "fuzzing"), derive(Arbitrary))]
43pub struct NodeKey {
44 version: Version,
46 nibble_path: NibblePath,
48}
49
50impl NodeKey {
51 pub(crate) fn new(version: Version, nibble_path: NibblePath) -> Self {
53 Self {
54 version,
55 nibble_path,
56 }
57 }
58
59 pub(crate) fn new_empty_path(version: Version) -> Self {
61 Self::new(version, NibblePath::new(vec![]))
62 }
63
64 pub fn version(&self) -> Version {
66 self.version
67 }
68
69 pub(crate) fn nibble_path(&self) -> &NibblePath {
71 &self.nibble_path
72 }
73
74 pub(crate) fn gen_child_node_key(&self, version: Version, n: Nibble) -> Self {
76 let mut node_nibble_path = self.nibble_path().clone();
77 node_nibble_path.push(n);
78 Self::new(version, node_nibble_path)
79 }
80
81 pub(crate) fn gen_parent_node_key(&self) -> Self {
83 let mut node_nibble_path = self.nibble_path().clone();
84 assert!(
85 node_nibble_path.pop().is_some(),
86 "Current node key is root.",
87 );
88 Self::new(self.version, node_nibble_path)
89 }
90
91 pub(crate) fn set_version(&mut self, version: Version) {
93 self.version = version;
94 }
95
96 pub fn encode(&self) -> Result<Vec<u8>> {
98 let mut out = vec![];
99 out.write_u64::<BigEndian>(self.version())?;
100 out.write_u8(self.nibble_path().num_nibbles() as u8)?;
101 out.write_all(self.nibble_path().bytes())?;
102 Ok(out)
103 }
104
105 pub fn decode(val: &[u8]) -> Result<NodeKey> {
107 let mut reader = Cursor::new(val);
108 let version = reader.read_u64::<BigEndian>()?;
109 let num_nibbles = reader.read_u8()? as usize;
110 ensure!(
111 num_nibbles <= ROOT_NIBBLE_HEIGHT,
112 "Invalid number of nibbles: {}",
113 num_nibbles,
114 );
115 let mut nibble_bytes = Vec::with_capacity((num_nibbles + 1) / 2);
116 reader.read_to_end(&mut nibble_bytes)?;
117 ensure!(
118 (num_nibbles + 1) / 2 == nibble_bytes.len(),
119 "encoded num_nibbles {} mismatches nibble path bytes {:?}",
120 num_nibbles,
121 nibble_bytes
122 );
123 let nibble_path = if num_nibbles % 2 == 0 {
124 NibblePath::new(nibble_bytes)
125 } else {
126 let padding = nibble_bytes.last().unwrap() & 0x0f;
127 ensure!(
128 padding == 0,
129 "Padding nibble expected to be 0, got: {}",
130 padding,
131 );
132 NibblePath::new_odd(nibble_bytes)
133 };
134 Ok(NodeKey::new(version, nibble_path))
135 }
136}
137
138#[derive(Clone, Debug, Eq, PartialEq)]
139pub enum NodeType {
140 Leaf,
141 InternalLegacy,
144 Internal {
145 leaf_count: usize,
146 },
147}
148
149#[cfg(any(test, feature = "fuzzing"))]
150impl Arbitrary for NodeType {
151 type Parameters = ();
152 type Strategy = BoxedStrategy<Self>;
153
154 fn arbitrary_with(_args: ()) -> Self::Strategy {
155 prop_oneof![
156 Just(NodeType::Leaf),
157 Just(NodeType::InternalLegacy),
158 (2..100usize).prop_map(|leaf_count| NodeType::Internal { leaf_count })
159 ]
160 .boxed()
161 }
162}
163
164#[derive(Clone, Debug, Eq, PartialEq)]
166#[cfg_attr(any(test, feature = "fuzzing"), derive(Arbitrary))]
167pub struct Child {
168 pub hash: [u8; 32],
170 pub version: Version,
174 pub node_type: NodeType,
177}
178
179impl Child {
180 pub fn new(hash: [u8; 32], version: Version, node_type: NodeType) -> Self {
181 Self {
182 hash,
183 version,
184 node_type,
185 }
186 }
187
188 pub fn is_leaf(&self) -> bool {
189 matches!(self.node_type, NodeType::Leaf)
190 }
191
192 pub fn leaf_count(&self) -> Option<usize> {
193 match self.node_type {
194 NodeType::Leaf => Some(1),
195 NodeType::InternalLegacy => None,
196 NodeType::Internal { leaf_count } => Some(leaf_count),
197 }
198 }
199}
200
201pub(crate) type Children = HashMap<Nibble, Child>;
204
205#[derive(Clone, Debug, Eq, PartialEq)]
211pub struct InternalNode {
212 children: Children,
214 leaf_count: Option<usize>,
216 leaf_count_migration: bool,
218}
219
220#[cfg(any(test, feature = "fuzzing"))]
267impl Arbitrary for InternalNode {
268 type Parameters = ();
269 type Strategy = BoxedStrategy<Self>;
270
271 fn arbitrary_with(_args: ()) -> Self::Strategy {
272 hash_map(any::<Nibble>(), any::<Child>(), 1..=16)
273 .prop_filter(
274 "InternalNode constructor panics when its only child is a leaf.",
275 |children| {
276 !(children.len() == 1
277 && children.values().next().expect("Must exist.").is_leaf())
278 },
279 )
280 .prop_map(InternalNode::new)
281 .boxed()
282 }
283}
284
285impl InternalNode {
286 #[cfg(any(test, feature = "fuzzing"))]
288 pub fn new(children: Children) -> Self {
289 Self::new_migration(children, true )
290 }
291
292 pub fn new_migration(children: Children, leaf_count_migration: bool) -> Self {
293 Self::new_impl(children, leaf_count_migration).expect("Input children are logical.")
294 }
295
296 pub fn new_impl(children: Children, leaf_count_migration: bool) -> Result<Self> {
297 ensure!(!children.is_empty(), "Children must not be empty");
300 if children.len() == 1 {
301 ensure!(
302 !children
303 .values()
304 .next()
305 .expect("Must have 1 element")
306 .is_leaf(),
307 "If there's only one child, it must not be a leaf."
308 );
309 }
310
311 let leaf_count = Self::sum_leaf_count(&children);
312 Ok(Self {
313 children,
314 leaf_count,
315 leaf_count_migration,
316 })
317 }
318
319 fn sum_leaf_count(children: &Children) -> Option<usize> {
320 let mut leaf_count = 0;
321 for child in children.values() {
322 if let Some(n) = child.leaf_count() {
323 leaf_count += n;
324 } else {
325 return None;
326 }
327 }
328 Some(leaf_count)
329 }
330
331 pub fn leaf_count(&self) -> Option<usize> {
332 self.leaf_count
333 }
334
335 pub fn node_type(&self) -> NodeType {
336 match self.leaf_count {
337 Some(leaf_count) => NodeType::Internal { leaf_count },
338 None => NodeType::InternalLegacy,
339 }
340 }
341
342 pub fn hash(&self) -> [u8; 32] {
343 self.merkle_hash(
344 0, 16, self.generate_bitmaps(),
347 )
348 }
349
350 pub fn children_sorted(&self) -> impl Iterator<Item = (&Nibble, &Child)> {
351 let mut sorted: Vec<(&Nibble, &Child)> = self.children.iter().collect();
355 sorted.sort_by_key(|(&nibble, _)| nibble);
356 sorted.into_iter()
357 }
358
359 pub fn serialize(&self, binary: &mut Vec<u8>, persist_leaf_counts: bool) -> Result<()> {
360 let (mut existence_bitmap, leaf_bitmap) = self.generate_bitmaps();
361 binary.write_u16::<LittleEndian>(existence_bitmap)?;
362 binary.write_u16::<LittleEndian>(leaf_bitmap)?;
363 for _ in 0..existence_bitmap.count_ones() {
364 let next_child = existence_bitmap.trailing_zeros() as u8;
365 let child = &self.children[&Nibble::from(next_child)];
366 serialize_u64_varint(child.version, binary);
367 binary.extend(child.hash.to_vec());
368 match child.node_type {
369 NodeType::Leaf => (),
370 NodeType::InternalLegacy => {
371 if persist_leaf_counts {
372 serialize_u64_varint(0, binary);
378 }
379 }
380 NodeType::Internal { leaf_count } => {
381 if persist_leaf_counts {
382 serialize_u64_varint(leaf_count as u64, binary);
383 }
384 }
385 };
386 existence_bitmap &= !(1 << next_child);
387 }
388 Ok(())
389 }
390
391 pub fn deserialize(data: &[u8], read_leaf_counts: bool) -> Result<Self> {
392 let mut reader = Cursor::new(data);
393 let len = data.len();
394
395 let mut existence_bitmap = reader.read_u16::<LittleEndian>()?;
397 let leaf_bitmap = reader.read_u16::<LittleEndian>()?;
398 match existence_bitmap {
399 0 => return Err(NodeDecodeError::NoChildren.into()),
400 _ if (existence_bitmap & leaf_bitmap) != leaf_bitmap => {
401 return Err(NodeDecodeError::ExtraLeaves {
402 existing: existence_bitmap,
403 leaves: leaf_bitmap,
404 }
405 .into())
406 }
407 _ => (),
408 }
409
410 let mut children = HashMap::new();
412 for _ in 0..existence_bitmap.count_ones() {
413 let next_child = existence_bitmap.trailing_zeros() as u8;
414 let version = deserialize_u64_varint(&mut reader)?;
415 let pos = reader.position() as usize;
416 let remaining = len - pos;
417
418 ensure!(
419 remaining >= size_of::<[u8; 32]>(),
420 "not enough bytes left, children: {}, bytes: {}",
421 existence_bitmap.count_ones(),
422 remaining
423 );
424 let hash = <[u8; 32]>::try_from(&reader.get_ref()[pos..pos + size_of::<[u8; 32]>()])?;
425 reader.seek(SeekFrom::Current(size_of::<[u8; 32]>() as i64))?;
426
427 let child_bit = 1 << next_child;
428 let node_type = if (leaf_bitmap & child_bit) != 0 {
429 NodeType::Leaf
430 } else if read_leaf_counts {
431 let leaf_count = deserialize_u64_varint(&mut reader)? as usize;
432 if leaf_count == 0 {
433 NodeType::InternalLegacy
434 } else {
435 NodeType::Internal { leaf_count }
436 }
437 } else {
438 NodeType::InternalLegacy
439 };
440
441 children.insert(
442 Nibble::from(next_child),
443 Child::new(hash, version, node_type),
444 );
445 existence_bitmap &= !child_bit;
446 }
447 assert_eq!(existence_bitmap, 0);
448
449 Self::new_impl(children, read_leaf_counts )
452 }
453
454 pub fn child(&self, n: Nibble) -> Option<&Child> {
456 self.children.get(&n)
457 }
458
459 pub fn generate_bitmaps(&self) -> (u16, u16) {
463 let mut existence_bitmap = 0;
464 let mut leaf_bitmap = 0;
465 for (nibble, child) in self.children.iter() {
466 let i = u8::from(*nibble);
467 existence_bitmap |= 1u16 << i;
468 if child.is_leaf() {
469 leaf_bitmap |= 1u16 << i;
470 }
471 }
472 assert_eq!(existence_bitmap | leaf_bitmap, existence_bitmap);
474 (existence_bitmap, leaf_bitmap)
475 }
476
477 fn range_bitmaps(start: u8, width: u8, bitmaps: (u16, u16)) -> (u16, u16) {
479 assert!(start < 16 && width.count_ones() == 1 && start % width == 0);
480 assert!(width <= 16 && (start + width) <= 16);
481 let mask = (((1u32 << width) - 1) << start) as u16;
484 (bitmaps.0 & mask, bitmaps.1 & mask)
485 }
486
487 fn merkle_hash(
488 &self,
489 start: u8,
490 width: u8,
491 (existence_bitmap, leaf_bitmap): (u16, u16),
492 ) -> [u8; 32] {
493 let (range_existence_bitmap, range_leaf_bitmap) =
495 Self::range_bitmaps(start, width, (existence_bitmap, leaf_bitmap));
496 if range_existence_bitmap == 0 {
497 SPARSE_MERKLE_PLACEHOLDER_HASH
499 } else if width == 1 || (range_existence_bitmap.count_ones() == 1 && range_leaf_bitmap != 0)
500 {
501 let only_child_index = Nibble::from(range_existence_bitmap.trailing_zeros() as u8);
503 self.child(only_child_index)
504 .with_context(|| {
505 format!(
506 "Corrupted internal node: existence_bitmap indicates \
507 the existence of a non-exist child at index {:x}",
508 only_child_index
509 )
510 })
511 .unwrap()
512 .hash
513 } else {
514 let left_child = self.merkle_hash(
515 start,
516 width / 2,
517 (range_existence_bitmap, range_leaf_bitmap),
518 );
519 let right_child = self.merkle_hash(
520 start + width / 2,
521 width / 2,
522 (range_existence_bitmap, range_leaf_bitmap),
523 );
524 SparseMerkleInternalNode::new(left_child, right_child).hash()
525 }
526 }
527
528 pub fn get_child_without_siblings(&self, node_key: &NodeKey, n: Nibble) -> Option<NodeKey> {
532 let (existence_bitmap, leaf_bitmap) = self.generate_bitmaps();
533
534 for h in (0..4).rev() {
536 let width = 1 << h;
539 let child_half_start = get_child_half_start(n, h);
540
541 let (range_existence_bitmap, range_leaf_bitmap) =
542 Self::range_bitmaps(child_half_start, width, (existence_bitmap, leaf_bitmap));
543
544 if range_existence_bitmap == 0 {
545 return None;
547 } else if width == 1
548 || (range_existence_bitmap.count_ones() == 1 && range_leaf_bitmap != 0)
549 {
550 let only_child_index = Nibble::from(range_existence_bitmap.trailing_zeros() as u8);
555
556 let only_child_version = self
557 .child(only_child_index)
558 .with_context(|| {
560 format!(
561 "Corrupted internal node: child_bitmap indicates \
562 the existence of a non-exist child at index {:x}",
563 only_child_index
564 )
565 })
566 .unwrap()
567 .version;
568
569 return Some(node_key.gen_child_node_key(only_child_version, only_child_index));
570 }
571 }
572 unreachable!("Impossible to get here without returning even at the lowest level.")
573 }
574
575 pub fn get_child_with_siblings(
596 &self,
597 node_key: &NodeKey,
598 n: Nibble,
599 ) -> (Option<NodeKey>, Vec<[u8; 32]>) {
600 let mut siblings = vec![];
601 let (existence_bitmap, leaf_bitmap) = self.generate_bitmaps();
602
603 for h in (0..4).rev() {
605 let width = 1 << h;
608 let (child_half_start, sibling_half_start) = get_child_and_sibling_half_start(n, h);
609 siblings.push(self.merkle_hash(
611 sibling_half_start,
612 width,
613 (existence_bitmap, leaf_bitmap),
614 ));
615
616 let (range_existence_bitmap, range_leaf_bitmap) =
617 Self::range_bitmaps(child_half_start, width, (existence_bitmap, leaf_bitmap));
618
619 if range_existence_bitmap == 0 {
620 return (None, siblings);
622 } else if width == 1
623 || (range_existence_bitmap.count_ones() == 1 && range_leaf_bitmap != 0)
624 {
625 let only_child_index = Nibble::from(range_existence_bitmap.trailing_zeros() as u8);
630 return (
631 {
632 let only_child_version = self
633 .child(only_child_index)
634 .with_context(|| {
636 format!(
637 "Corrupted internal node: child_bitmap indicates \
638 the existence of a non-exist child at index {:x}",
639 only_child_index
640 )
641 })
642 .unwrap()
643 .version;
644 Some(node_key.gen_child_node_key(only_child_version, only_child_index))
645 },
646 siblings,
647 );
648 }
649 }
650 unreachable!("Impossible to get here without returning even at the lowest level.")
651 }
652
653 #[cfg(test)]
654 pub(crate) fn into_legacy_internal(self) -> InternalNode {
655 let mut children = self.children;
656 children.iter_mut().for_each(|(_, mut child)| {
657 if matches!(child.node_type, NodeType::Internal { .. }) {
658 child.node_type = NodeType::InternalLegacy
659 }
660 });
661
662 InternalNode::new_migration(children, false )
663 }
664
665 #[cfg(test)]
666 pub(crate) fn children(&self) -> &Children {
667 &self.children
668 }
669}
670
671pub(crate) fn get_child_and_sibling_half_start(n: Nibble, height: u8) -> (u8, u8) {
674 let child_half_start = (0xff << height) & u8::from(n);
678
679 let sibling_half_start = child_half_start ^ (1 << height);
682
683 (child_half_start, sibling_half_start)
684}
685
686pub(crate) fn get_child_half_start(n: Nibble, height: u8) -> u8 {
688 (0xff << height) & u8::from(n)
692}
693
694#[derive(Clone, Debug, Eq, PartialEq, Serialize, Deserialize)]
698pub struct LeafNode {
699 key_hash: KeyHash,
701 value_hash: ValueHash,
703 value: Vec<u8>,
705}
706
707impl LeafNode {
708 pub fn new(key_hash: KeyHash, value: Vec<u8>) -> Self {
710 let value_hash = value.as_slice().into();
711 Self {
712 key_hash,
713 value_hash,
714 value,
715 }
716 }
717
718 pub fn key_hash(&self) -> KeyHash {
720 self.key_hash
721 }
722
723 pub fn value(&self) -> &[u8] {
725 self.value.as_ref()
726 }
727
728 pub(crate) fn value_hash(&self) -> ValueHash {
730 self.value_hash
731 }
732
733 pub fn hash(&self) -> [u8; 32] {
734 SparseMerkleLeafNode::new(self.key_hash, self.value_hash).hash()
735 }
736}
737
738impl From<LeafNode> for SparseMerkleLeafNode {
739 fn from(leaf_node: LeafNode) -> Self {
740 Self::new(leaf_node.key_hash, leaf_node.value_hash)
741 }
742}
743
744#[repr(u8)]
745#[derive(FromPrimitive, ToPrimitive)]
746enum NodeTag {
747 Null = 0,
748 InternalLegacy = 1,
749 Leaf = 2,
750 Internal = 3,
751}
752
753#[derive(Clone, Debug, Eq, PartialEq)]
755pub enum Node {
756 Null,
758 Internal(InternalNode),
760 Leaf(LeafNode),
762}
763
764impl From<InternalNode> for Node {
765 fn from(node: InternalNode) -> Self {
766 Node::Internal(node)
767 }
768}
769
770impl From<InternalNode> for Children {
771 fn from(node: InternalNode) -> Self {
772 node.children
773 }
774}
775
776impl From<LeafNode> for Node {
777 fn from(node: LeafNode) -> Self {
778 Node::Leaf(node)
779 }
780}
781
782impl Node {
783 pub(crate) fn new_null() -> Self {
785 Node::Null
786 }
787
788 #[cfg(any(test, feature = "fuzzing"))]
790 pub(crate) fn new_internal(children: Children) -> Self {
791 Node::Internal(InternalNode::new(children))
792 }
793
794 pub(crate) fn new_leaf(key_hash: KeyHash, value: Vec<u8>) -> Self {
796 Node::Leaf(LeafNode::new(key_hash, value))
797 }
798
799 pub(crate) fn is_leaf(&self) -> bool {
801 matches!(self, Node::Leaf(_))
802 }
803
804 pub(crate) fn node_type(&self) -> NodeType {
806 match self {
807 Self::Null => unreachable!(),
810 Self::Leaf(_) => NodeType::Leaf,
811 Self::Internal(n) => n.node_type(),
812 }
813 }
814
815 pub(crate) fn leaf_count(&self) -> Option<usize> {
817 match self {
818 Node::Null => Some(0),
819 Node::Leaf(_) => Some(1),
820 Node::Internal(internal_node) => internal_node.leaf_count,
821 }
822 }
823
824 pub fn encode(&self) -> Result<Vec<u8>> {
826 let mut out = vec![];
827
828 match self {
829 Node::Null => {
830 out.push(NodeTag::Null as u8);
831 }
832 Node::Internal(internal_node) => {
833 let persist_leaf_count = internal_node.leaf_count_migration;
834 let tag = if persist_leaf_count {
835 NodeTag::Internal
836 } else {
837 NodeTag::InternalLegacy
838 };
839 out.push(tag as u8);
840 internal_node.serialize(&mut out, persist_leaf_count)?;
841 DIEM_JELLYFISH_INTERNAL_ENCODED_BYTES.inc_by(out.len() as u64);
842 }
843 Node::Leaf(leaf_node) => {
844 out.push(NodeTag::Leaf as u8);
845 out.extend(bcs::to_bytes(&leaf_node)?);
846 DIEM_JELLYFISH_LEAF_ENCODED_BYTES.inc_by(out.len() as u64);
847 }
848 }
849 Ok(out)
850 }
851
852 pub(crate) fn hash(&self) -> [u8; 32] {
854 match self {
855 Node::Null => SPARSE_MERKLE_PLACEHOLDER_HASH,
856 Node::Internal(internal_node) => internal_node.hash(),
857 Node::Leaf(leaf_node) => leaf_node.hash(),
858 }
859 }
860
861 pub fn decode(val: &[u8]) -> Result<Node> {
863 if val.is_empty() {
864 return Err(NodeDecodeError::EmptyInput.into());
865 }
866 let tag = val[0];
867 let node_tag = NodeTag::from_u8(tag);
868 match node_tag {
869 Some(NodeTag::Null) => Ok(Node::Null),
870 Some(NodeTag::InternalLegacy) => {
871 Ok(Node::Internal(InternalNode::deserialize(&val[1..], false)?))
872 }
873 Some(NodeTag::Internal) => {
874 Ok(Node::Internal(InternalNode::deserialize(&val[1..], true)?))
875 }
876 Some(NodeTag::Leaf) => Ok(Node::Leaf(bcs::from_bytes(&val[1..])?)),
877 None => Err(NodeDecodeError::UnknownTag { unknown_tag: tag }.into()),
878 }
879 }
880}
881
882#[derive(Debug, Error, Eq, PartialEq)]
885pub enum NodeDecodeError {
886 #[error("Missing tag due to empty input")]
888 EmptyInput,
889
890 #[error("lead tag byte is unknown: {}", unknown_tag)]
892 UnknownTag { unknown_tag: u8 },
893
894 #[error("No children found in internal node")]
896 NoChildren,
897
898 #[error(
900 "Non-existent leaf bits set, existing: {}, leaves: {}",
901 existing,
902 leaves
903 )]
904 ExtraLeaves { existing: u16, leaves: u16 },
905}
906
907pub(crate) fn serialize_u64_varint(mut num: u64, binary: &mut Vec<u8>) {
910 for _ in 0..8 {
911 let low_bits = num as u8 & 0x7f;
912 num >>= 7;
913 let more = match num {
914 0 => 0u8,
915 _ => 0x80,
916 };
917 binary.push(low_bits | more);
918 if more == 0 {
919 return;
920 }
921 }
922 assert_ne!(num, 0);
924 assert!(num <= 0xff);
925 binary.push(num as u8);
926}
927
928pub(crate) fn deserialize_u64_varint<T>(reader: &mut T) -> Result<u64>
930where
931 T: Read,
932{
933 let mut num = 0u64;
934 for i in 0..8 {
935 let byte = reader.read_u8()?;
936 num |= u64::from(byte & 0x7f) << (i * 7);
937 if (byte & 0x80) == 0 {
938 return Ok(num);
939 }
940 }
941 let byte = reader.read_u8()?;
943 num |= u64::from(byte) << 56;
944 Ok(num)
945}