1use crate::{
21 node_header::{size_and_prefix_iterator, NodeKind},
22 trie_constants,
23};
24use alloc::vec::Vec;
25use codec::{Compact, Encode};
26use hash_db::Hasher;
27use trie_root;
28
29#[derive(Default, Clone)]
31pub struct TrieStream {
32 buffer: Vec<u8>,
34}
35
36impl TrieStream {
37 pub fn as_raw(&self) -> &[u8] {
39 &self.buffer
40 }
41}
42
43fn branch_node_bit_mask(has_children: impl Iterator<Item = bool>) -> (u8, u8) {
44 let mut bitmap: u16 = 0;
45 let mut cursor: u16 = 1;
46 for v in has_children {
47 if v {
48 bitmap |= cursor
49 }
50 cursor <<= 1;
51 }
52 ((bitmap % 256) as u8, (bitmap / 256) as u8)
53}
54
55fn fuse_nibbles_node(nibbles: &[u8], kind: NodeKind) -> impl Iterator<Item = u8> + '_ {
57 let size = nibbles.len();
58 let iter_start = match kind {
59 NodeKind::Leaf => size_and_prefix_iterator(size, trie_constants::LEAF_PREFIX_MASK, 2),
60 NodeKind::BranchNoValue => {
61 size_and_prefix_iterator(size, trie_constants::BRANCH_WITHOUT_MASK, 2)
62 },
63 NodeKind::BranchWithValue => {
64 size_and_prefix_iterator(size, trie_constants::BRANCH_WITH_MASK, 2)
65 },
66 NodeKind::HashedValueLeaf => {
67 size_and_prefix_iterator(size, trie_constants::ALT_HASHING_LEAF_PREFIX_MASK, 3)
68 },
69 NodeKind::HashedValueBranch => {
70 size_and_prefix_iterator(size, trie_constants::ALT_HASHING_BRANCH_WITH_MASK, 4)
71 },
72 };
73 iter_start
74 .chain(if nibbles.len() % 2 == 1 { Some(nibbles[0]) } else { None })
75 .chain(nibbles[nibbles.len() % 2..].chunks(2).map(|ch| (ch[0] << 4) | ch[1]))
76}
77
78use trie_root::Value as TrieStreamValue;
79impl trie_root::TrieStream for TrieStream {
80 fn new() -> Self {
81 Self { buffer: Vec::new() }
82 }
83
84 fn append_empty_data(&mut self) {
85 self.buffer.push(trie_constants::EMPTY_TRIE);
86 }
87
88 fn append_leaf(&mut self, key: &[u8], value: TrieStreamValue) {
89 let kind = match &value {
90 TrieStreamValue::Inline(..) => NodeKind::Leaf,
91 TrieStreamValue::Node(..) => NodeKind::HashedValueLeaf,
92 };
93 self.buffer.extend(fuse_nibbles_node(key, kind));
94 match &value {
95 TrieStreamValue::Inline(value) => {
96 Compact(value.len() as u32).encode_to(&mut self.buffer);
97 self.buffer.extend_from_slice(value);
98 },
99 TrieStreamValue::Node(hash) => {
100 self.buffer.extend_from_slice(hash.as_slice());
101 },
102 };
103 }
104
105 fn begin_branch(
106 &mut self,
107 maybe_partial: Option<&[u8]>,
108 maybe_value: Option<TrieStreamValue>,
109 has_children: impl Iterator<Item = bool>,
110 ) {
111 if let Some(partial) = maybe_partial {
112 let kind = match &maybe_value {
113 None => NodeKind::BranchNoValue,
114 Some(TrieStreamValue::Inline(..)) => NodeKind::BranchWithValue,
115 Some(TrieStreamValue::Node(..)) => NodeKind::HashedValueBranch,
116 };
117
118 self.buffer.extend(fuse_nibbles_node(partial, kind));
119 let bm = branch_node_bit_mask(has_children);
120 self.buffer.extend([bm.0, bm.1].iter());
121 } else {
122 unreachable!("trie stream codec only for no extension trie");
123 }
124 match maybe_value {
125 None => (),
126 Some(TrieStreamValue::Inline(value)) => {
127 Compact(value.len() as u32).encode_to(&mut self.buffer);
128 self.buffer.extend_from_slice(value);
129 },
130 Some(TrieStreamValue::Node(hash)) => {
131 self.buffer.extend_from_slice(hash.as_slice());
132 },
133 }
134 }
135
136 fn append_extension(&mut self, _key: &[u8]) {
137 debug_assert!(false, "trie stream codec only for no extension trie");
138 }
139
140 fn append_substream<H: Hasher>(&mut self, other: Self) {
141 let data = other.out();
142 match data.len() {
143 0..=31 => data.encode_to(&mut self.buffer),
144 _ => H::hash(&data).as_ref().encode_to(&mut self.buffer),
145 }
146 }
147
148 fn out(self) -> Vec<u8> {
149 self.buffer
150 }
151}