1use alloc::vec::Vec;
4
5use ethereum_types::H256;
6use hash256_std_hasher::Hash256StdHasher;
7use hash_db::Hasher;
8use sha3::{Digest, Keccak256};
9use trie_root::Value as TrieStreamValue;
10
11#[derive(Default, Debug, Clone, PartialEq, Eq)]
13pub struct KeccakHasher;
14impl Hasher for KeccakHasher {
15 type Out = H256;
16 type StdHasher = Hash256StdHasher;
17 const LENGTH: usize = 32;
18
19 fn hash(x: &[u8]) -> Self::Out {
20 H256::from_slice(Keccak256::digest(x).as_slice())
21 }
22}
23
24#[derive(Default)]
26pub struct Hash256RlpTrieStream {
27 stream: rlp::RlpStream,
28}
29
30impl trie_root::TrieStream for Hash256RlpTrieStream {
31 fn new() -> Self {
32 Self {
33 stream: rlp::RlpStream::new(),
34 }
35 }
36
37 fn append_empty_data(&mut self) {
38 self.stream.append_empty_data();
39 }
40
41 fn begin_branch(
42 &mut self,
43 _maybe_key: Option<&[u8]>,
44 _maybe_value: Option<TrieStreamValue>,
45 _has_children: impl Iterator<Item = bool>,
46 ) {
47 self.stream.begin_list(17);
50 }
51
52 fn append_empty_child(&mut self) {
53 self.stream.append_empty_data();
54 }
55
56 fn end_branch(&mut self, value: Option<TrieStreamValue>) {
57 match value {
58 Some(value) => match value {
59 TrieStreamValue::Inline(value) => self.stream.append(&value),
60 TrieStreamValue::Node(value) => self.stream.append(&value),
61 },
62 None => self.stream.append_empty_data(),
63 };
64 }
65
66 fn append_leaf(&mut self, key: &[u8], value: TrieStreamValue) {
67 self.stream.begin_list(2);
68 self.stream.append_iter(hex_prefix_encode(key, true));
69 match value {
70 TrieStreamValue::Inline(value) => self.stream.append(&value),
71 TrieStreamValue::Node(value) => self.stream.append(&value),
72 };
73 }
74
75 fn append_extension(&mut self, key: &[u8]) {
76 self.stream.begin_list(2);
77 self.stream.append_iter(hex_prefix_encode(key, false));
78 }
79
80 fn append_substream<H: Hasher>(&mut self, other: Self) {
81 let out = other.out();
82 match out.len() {
83 0..=31 => self.stream.append_raw(&out, 1),
84 _ => self.stream.append(&H::hash(&out).as_ref()),
85 };
86 }
87
88 fn out(self) -> Vec<u8> {
89 self.stream.out().freeze().into()
90 }
91}
92
93fn hex_prefix_encode(nibbles: &[u8], leaf: bool) -> impl Iterator<Item = u8> + '_ {
114 let inlen = nibbles.len();
115 let oddness_factor = inlen % 2;
116
117 let first_byte = {
118 let mut bits = ((inlen as u8 & 1) + (2 * leaf as u8)) << 4;
119 if oddness_factor == 1 {
120 bits += nibbles[0];
121 }
122 bits
123 };
124 core::iter::once(first_byte).chain(
125 nibbles[oddness_factor..]
126 .chunks(2)
127 .map(|ch| ch[0] << 4 | ch[1]),
128 )
129}
130
131pub fn trie_root<I, K, V>(input: I) -> H256
133where
134 I: IntoIterator<Item = (K, V)>,
135 K: AsRef<[u8]> + Ord,
136 V: AsRef<[u8]>,
137{
138 trie_root::trie_root::<KeccakHasher, Hash256RlpTrieStream, _, _, _>(input, None)
139}
140
141pub fn sec_trie_root<I, K, V>(input: I) -> H256
143where
144 I: IntoIterator<Item = (K, V)>,
145 K: AsRef<[u8]>,
146 V: AsRef<[u8]>,
147{
148 trie_root::sec_trie_root::<KeccakHasher, Hash256RlpTrieStream, _, _, _>(input, None)
149}
150
151pub fn ordered_trie_root<I, V>(input: I) -> H256
153where
154 I: IntoIterator<Item = V>,
155 V: AsRef<[u8]>,
156{
157 trie_root::trie_root::<KeccakHasher, Hash256RlpTrieStream, _, _, _>(
158 input
159 .into_iter()
160 .enumerate()
161 .map(|(i, v)| (rlp::encode(&i), v)),
162 None,
163 )
164}
165
166#[cfg(test)]
167mod tests {
168 use ethereum_types::H256;
169 use hash256_std_hasher::Hash256StdHasher;
170 use hex_literal::hex;
171 use sha3::{Digest, Keccak256};
172
173 #[derive(Default, Debug, Clone, PartialEq, Eq)]
174 struct KeccakHasher15;
175 impl hash_db15::Hasher for KeccakHasher15 {
176 type Out = H256;
177 type StdHasher = Hash256StdHasher;
178 const LENGTH: usize = 32;
179
180 fn hash(x: &[u8]) -> Self::Out {
181 H256::from_slice(Keccak256::digest(x).as_slice())
182 }
183 }
184
185 #[test]
186 fn test_trie_root() {
187 let v = vec![
188 ("doe", "reindeer"),
189 ("dog", "puppy"),
190 ("dogglesworth", "cat"),
191 ];
192 let root = hex!("8aad789dff2f538bca5d8ea56e8abe10f4c7ba3a5dea95fea4cd6e7c3a1168d3");
193
194 let before = triehash::trie_root::<KeccakHasher15, _, _, _>(v.clone());
195 assert_eq!(before.0, root);
196
197 let after = super::trie_root::<_, _, _>(v);
198 assert_eq!(after.0, root);
199 }
200
201 #[test]
202 fn test_sec_trie_root() {
203 let v = vec![
204 ("doe", "reindeer"),
205 ("dog", "puppy"),
206 ("dogglesworth", "cat"),
207 ];
208 let root = hex!("d4cd937e4a4368d7931a9cf51686b7e10abb3dce38a39000fd7902a092b64585");
209
210 let before = triehash::sec_trie_root::<KeccakHasher15, _, _, _>(v.clone());
211 assert_eq!(before.0, root);
212
213 let after = super::sec_trie_root::<_, _, _>(v);
214 assert_eq!(after.0, root);
215 }
216
217 #[test]
218 fn test_ordered_trie_root() {
219 let v = &["doe", "reindeer"];
220 let root = hex!("e766d5d51b89dc39d981b41bda63248d7abce4f0225eefd023792a540bcffee3");
221
222 let before = triehash::ordered_trie_root::<KeccakHasher15, _>(v);
223 assert_eq!(before.0, root);
224
225 let after = super::ordered_trie_root::<_, _>(v);
226 assert_eq!(after.0, root);
227 }
228}