smoldot/trie/proof_decode.rs
1// Smoldot
2// Copyright (C) 2019-2022 Parity Technologies (UK) Ltd.
3// SPDX-License-Identifier: GPL-3.0-or-later WITH Classpath-exception-2.0
4
5// This program is free software: you can redistribute it and/or modify
6// it under the terms of the GNU General Public License as published by
7// the Free Software Foundation, either version 3 of the License, or
8// (at your option) any later version.
9
10// This program is distributed in the hope that it will be useful,
11// but WITHOUT ANY WARRANTY; without even the implied warranty of
12// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13// GNU General Public License for more details.
14
15// You should have received a copy of the GNU General Public License
16// along with this program. If not, see <http://www.gnu.org/licenses/>.
17
18//! Decodes and verifies a trie proof.
19//!
20//! A trie proof is a proof that a certain key in the trie has a certain storage value (or lacks
21//! a storage value). The proof can be verified by knowing only the Merkle value of the root node.
22//!
23//! # Details
24//!
25//! > **Note**: For reminder, the Merkle value of a node is the hash of its node value, or the
26//! > node value directly if its length is smaller than 32 bytes.
27//!
28//! A trie proof consists in a list of node values of nodes in the trie. For the proof to be valid,
29//! the hash of one of these node values must match the expected trie root node value. Since a
30//! node value contains the Merkle values of the children of the node, it is possible to iterate
31//! down the hierarchy of nodes until the one closest to the desired key is found.
32//!
33//! # Usage
34//!
35//! This modules provides the [`decode_and_verify_proof`] function that decodes a proof and
36//! verifies whether it is correct.
37//!
38//! Once decoded, one can examine the content of the proof, in other words the list of storage
39//! items and values.
40
41use super::{TrieEntryVersion, nibble, trie_node};
42
43use alloc::vec::Vec;
44use core::{fmt, iter, ops};
45
46mod tests;
47
48/// Configuration to pass to [`decode_and_verify_proof`].
49pub struct Config<I> {
50 /// List of node values of nodes found in the trie. At least one entry corresponding to the
51 /// root node of the trie must be present in order for the verification to succeed.
52 pub proof: I,
53}
54
55/// Proof is in an invalid format.
56#[derive(Debug, Clone, derive_more::Display, derive_more::Error)]
57pub struct ParseError();
58
59/// Decomposes the given proof into its entries.
60///
61/// Each entry is a node value.
62///
63/// Doesn't verify anything about the proof except that it can be decomposed into entries.
64pub fn decode_proof(proof: &[u8]) -> Result<impl ExactSizeIterator<Item = &[u8]>, ParseError> {
65 // TODO: don't use Vec?
66 let (_, decoded_proof) = nom::Parser::parse(
67 &mut nom::combinator::all_consuming(nom::combinator::flat_map(
68 crate::util::nom_scale_compact_usize,
69 |num_elems| nom::multi::many_m_n(num_elems, num_elems, crate::util::nom_bytes_decode),
70 )),
71 proof,
72 )
73 .map_err(|_: nom::Err<nom::error::Error<&[u8]>>| ParseError())?;
74 Ok(decoded_proof.into_iter())
75}
76
77/// Verifies whether a proof is correct and returns an object that allows examining its content.
78///
79/// The proof is then stored within the [`DecodedTrieProof`].
80///
81/// Due to the generic nature of this function, the proof can be either a `Vec<u8>` or a `&[u8]`.
82///
83/// Returns an error if the proof is invalid, or if the proof contains entries that are
84/// disconnected from the root node of the trie.
85pub fn decode_and_verify_proof<T>(config: Config<T>) -> Result<DecodedTrieProof<T>, Error>
86where
87 T: AsRef<[u8]>,
88{
89 // Call `as_ref()` once at the beginning in order to guarantee stability of the memory
90 // location.
91 let proof_as_ref = config.proof.as_ref();
92
93 struct InProgressEntry<'a> {
94 index_in_proof: usize,
95 range_in_proof: ops::Range<usize>,
96 decode_result: Result<
97 trie_node::Decoded<'a, trie_node::DecodedPartialKey<'a>, &'a [u8]>,
98 trie_node::Error,
99 >,
100 }
101
102 // A Merkle proof is a SCALE-encoded `Vec<Vec<u8>>`.
103 //
104 // This `Vec` contains two types of items: trie node values, and standalone storage items. In
105 // both cases, we will later need a hashed version of them. Create a list of hashes, one per
106 // entry in `proof`.
107 //
108 // This hashmap uses a FNV hasher, theoretically vulnerable to HashDos attacks. While it is
109 // possible for an attacker to craft a proof that leads to all entries being in the same
110 // bucket, this proof is going to be invalid (unless the blake2 hash function is broken, which
111 // we assume it isn't). So while an attacker can slightly increase the time that this function
112 // takes, it is always cause this function to return an error and is actually likely to make
113 // the function actually take less time than if it was a legitimate proof.
114 let entries_by_merkle_value = {
115 let decoded_proof = decode_proof(proof_as_ref).map_err(Error::InvalidFormat)?;
116 let decoded_proof_len = decoded_proof.len();
117
118 let entries_by_merkle_value = decoded_proof
119 .enumerate()
120 .map(
121 |(proof_entry_num, proof_entry)| -> ([u8; 32], InProgressEntry) {
122 // The merkle value of a trie node is normally either its hash or the node
123 // itself if its length is < 32. In the context of a proof, however, nodes
124 // whose length is < 32 aren't supposed to be their own entry. For this reason,
125 // we only hash each entry.
126 let hash = *<&[u8; 32]>::try_from(
127 blake2_rfc::blake2b::blake2b(32, &[], proof_entry).as_bytes(),
128 )
129 .unwrap();
130
131 let proof_entry_offset = if proof_entry.is_empty() {
132 0
133 } else {
134 proof_entry.as_ptr() as usize - proof_as_ref.as_ptr() as usize
135 };
136
137 (
138 hash,
139 InProgressEntry {
140 index_in_proof: proof_entry_num,
141 range_in_proof: proof_entry_offset
142 ..(proof_entry_offset + proof_entry.len()),
143 decode_result: trie_node::decode(proof_entry),
144 },
145 )
146 },
147 )
148 .collect::<hashbrown::HashMap<_, _, fnv::FnvBuildHasher>>();
149
150 // Using a hashmap has the consequence that if multiple proof entries were identical, only
151 // one would be tracked. This allows us to make sure that the proof doesn't contain
152 // multiple identical entries.
153 if entries_by_merkle_value.len() != decoded_proof_len {
154 return Err(Error::DuplicateProofEntry);
155 }
156
157 entries_by_merkle_value
158 };
159
160 // Start by iterating over each element of the proof, and keep track of elements that are
161 // decodable but aren't mentioned in any other element. This gives us the tries roots.
162 let trie_roots = {
163 let mut maybe_trie_roots = entries_by_merkle_value
164 .keys()
165 .collect::<hashbrown::HashSet<_, fnv::FnvBuildHasher>>();
166 for (hash, InProgressEntry { decode_result, .. }) in entries_by_merkle_value.iter() {
167 let Ok(decoded) = decode_result else {
168 maybe_trie_roots.remove(hash);
169 continue;
170 };
171 for child in decoded.children.into_iter().flatten() {
172 if let Ok(child) = &<[u8; 32]>::try_from(child) {
173 maybe_trie_roots.remove(child);
174 }
175 }
176 }
177 maybe_trie_roots
178 };
179
180 // The implementation below iterates down the tree of nodes represented by this proof, keeping
181 // note of the traversed elements.
182
183 // Keep track of all the entries found in the proof.
184 let mut entries: Vec<Entry> = Vec::with_capacity(entries_by_merkle_value.len());
185
186 let mut trie_roots_with_entries =
187 hashbrown::HashMap::with_capacity_and_hasher(trie_roots.len(), Default::default());
188
189 // Keep track of the proof entries that haven't been visited when traversing.
190 let mut unvisited_proof_entries =
191 (0..entries_by_merkle_value.len()).collect::<hashbrown::HashSet<_, fnv::FnvBuildHasher>>();
192
193 // We repeat this operation for every trie root.
194 for trie_root_hash in trie_roots {
195 struct StackEntry<'a> {
196 range_in_proof: ops::Range<usize>,
197 index_in_entries: usize,
198 num_visited_children: u8,
199 children_node_values: [Option<&'a [u8]>; 16],
200 }
201
202 // Keep track of the number of entries before this trie root.
203 // This allows us to truncate `entries` to this value in case of decoding failure.
204 let num_entries_before_current_trie_root = entries.len();
205
206 // Keep track of the indices of the proof entries that are visited when traversing this trie.
207 let mut visited_proof_entries_during_trie =
208 Vec::with_capacity(entries_by_merkle_value.len());
209
210 // TODO: configurable capacity?
211 let mut visited_entries_stack: Vec<StackEntry> = Vec::with_capacity(24);
212
213 loop {
214 // Find which node to visit next.
215 // This is the next child of the node at the top of the stack, or if the node at
216 // the top of the stack doesn't have any child, we pop it and continue iterating.
217 // If the stack is empty, we are necessarily at the first iteration.
218 let (visited_node_entry_range, visited_node_decoded) =
219 match visited_entries_stack.last_mut() {
220 None => {
221 // Stack is empty.
222 // Because we immediately `break` after popping the last element, the stack
223 // can only ever be empty at the very start.
224 let InProgressEntry {
225 index_in_proof: root_position,
226 range_in_proof: root_range,
227 decode_result,
228 } = entries_by_merkle_value.get(&trie_root_hash[..]).unwrap();
229 visited_proof_entries_during_trie.push(*root_position);
230 // If the node can't be decoded, we ignore the entire trie and jump
231 // to the next one.
232 let Ok(decoded) = decode_result.clone() else {
233 debug_assert_eq!(num_entries_before_current_trie_root, entries.len());
234 break;
235 };
236 (root_range.clone(), decoded)
237 }
238 Some(StackEntry {
239 num_visited_children: stack_top_visited_children,
240 ..
241 }) if *stack_top_visited_children == 16 => {
242 // We have visited all the children of the top of the stack. Pop the node from
243 // the stack.
244 let Some(StackEntry {
245 index_in_entries: stack_top_index_in_entries,
246 ..
247 }) = visited_entries_stack.pop()
248 else {
249 unreachable!()
250 };
251
252 // Update the value of `child_entries_follow_up`
253 // and `children_present_in_proof_bitmap` of the parent.
254 if let Some(&StackEntry {
255 index_in_entries: parent_index_in_entries,
256 num_visited_children: parent_children_visited,
257 ..
258 }) = visited_entries_stack.last()
259 {
260 entries[parent_index_in_entries].child_entries_follow_up +=
261 entries[stack_top_index_in_entries].child_entries_follow_up + 1;
262 entries[parent_index_in_entries].children_present_in_proof_bitmap |=
263 1 << (parent_children_visited - 1);
264 }
265
266 // If we popped the last node of the stack, we have finished the iteration.
267 if visited_entries_stack.is_empty() {
268 trie_roots_with_entries
269 .insert(*trie_root_hash, num_entries_before_current_trie_root);
270 // Remove the visited entries from `unvisited_proof_entries`.
271 // Note that it is questionable what to do if the same entry is visited
272 // multiple times. In case where multiple storage branches are identical,
273 // the sender of the proof should de-duplicate the identical nodes. For
274 // this reason, it could be legitimate for the same proof entry to be
275 // visited multiple times.
276 for entry_num in visited_proof_entries_during_trie {
277 unvisited_proof_entries.remove(&entry_num);
278 }
279 break;
280 } else {
281 continue;
282 }
283 }
284 Some(StackEntry {
285 range_in_proof: stack_top_proof_range,
286 num_visited_children: stack_top_visited_children,
287 children_node_values: stack_top_children,
288 ..
289 }) => {
290 // Find the next child of the top of the stack.
291 let stack_top_entry = &proof_as_ref[stack_top_proof_range.clone()];
292
293 // Find the index of the next child (that we are about to visit).
294 let next_child_to_visit = stack_top_children
295 .iter()
296 .skip(usize::from(*stack_top_visited_children))
297 .position(|c| c.is_some())
298 .map(|idx| u8::try_from(idx).unwrap() + *stack_top_visited_children)
299 .unwrap_or(16);
300
301 // `continue` if all children have been visited. The next iteration will
302 // pop the stack entry.
303 if next_child_to_visit == 16 {
304 *stack_top_visited_children = 16;
305 continue;
306 }
307 *stack_top_visited_children = next_child_to_visit + 1;
308
309 // The value of the child node is either directly inlined (if less
310 // than 32 bytes) or is a hash.
311 let child_node_value =
312 stack_top_children[usize::from(next_child_to_visit)].unwrap();
313 debug_assert!(child_node_value.len() <= 32); // Guaranteed by decoding API.
314 if child_node_value.len() < 32 {
315 let offset = stack_top_proof_range.start
316 + if !child_node_value.is_empty() {
317 child_node_value.as_ptr() as usize
318 - stack_top_entry.as_ptr() as usize
319 } else {
320 0
321 };
322 debug_assert!(offset == 0 || offset >= stack_top_proof_range.start);
323 debug_assert!(
324 offset <= (stack_top_proof_range.start + stack_top_entry.len())
325 );
326
327 let child_range_in_proof = offset..(offset + child_node_value.len());
328
329 // Decodes the child.
330 // If the node can't be decoded, we ignore the entire trie and jump
331 // to the next one.
332 let Ok(child_decoded) =
333 trie_node::decode(&proof_as_ref[child_range_in_proof.clone()])
334 else {
335 entries.truncate(num_entries_before_current_trie_root);
336 break;
337 };
338
339 (child_range_in_proof, child_decoded)
340 } else if let Some(&InProgressEntry {
341 index_in_proof: child_position,
342 range_in_proof: ref child_entry_range,
343 ref decode_result,
344 }) = entries_by_merkle_value.get(child_node_value)
345 {
346 // If the node value of the child is less than 32 bytes long, it should
347 // have been inlined instead of given separately.
348 if child_entry_range.end - child_entry_range.start < 32 {
349 entries.truncate(num_entries_before_current_trie_root);
350 break;
351 }
352
353 visited_proof_entries_during_trie.push(child_position);
354
355 // If the node can't be decoded, we ignore the entire trie and jump
356 // to the next one.
357 let Ok(decoded) = decode_result.clone() else {
358 entries.truncate(num_entries_before_current_trie_root);
359 break;
360 };
361 (child_entry_range.clone(), decoded)
362 } else {
363 // Child is a hash that was not found in the proof. Simply continue
364 // iterating, in order to try to find the follow-up child.
365 continue;
366 }
367 }
368 };
369
370 // All nodes must either have a child or a storage value or be the root.
371 if visited_node_decoded.children_bitmap() == 0
372 && matches!(
373 visited_node_decoded.storage_value,
374 trie_node::StorageValue::None
375 )
376 && !visited_entries_stack.is_empty()
377 {
378 entries.truncate(num_entries_before_current_trie_root);
379 break;
380 }
381
382 // Nodes with no storage value and one children are forbidden.
383 if visited_node_decoded
384 .children
385 .iter()
386 .filter(|c| c.is_some())
387 .count()
388 == 1
389 && matches!(
390 visited_node_decoded.storage_value,
391 trie_node::StorageValue::None
392 )
393 {
394 entries.truncate(num_entries_before_current_trie_root);
395 break;
396 }
397
398 // Add an entry for this node in the final list of entries.
399 entries.push(Entry {
400 parent_entry_index: visited_entries_stack.last().map(|entry| {
401 (
402 entry.index_in_entries,
403 nibble::Nibble::try_from(entry.num_visited_children - 1).unwrap(),
404 )
405 }),
406 range_in_proof: visited_node_entry_range.clone(),
407 storage_value_in_proof: match visited_node_decoded.storage_value {
408 trie_node::StorageValue::None => None,
409 trie_node::StorageValue::Hashed(value_hash) => {
410 if let Some(&InProgressEntry {
411 index_in_proof: value_position,
412 range_in_proof: ref value_entry_range,
413 ..
414 }) = entries_by_merkle_value.get(&value_hash[..])
415 {
416 visited_proof_entries_during_trie.push(value_position);
417 Some(value_entry_range.clone())
418 } else {
419 None
420 }
421 }
422 trie_node::StorageValue::Unhashed(v) => {
423 let offset = if !v.is_empty() {
424 v.as_ptr() as usize - proof_as_ref.as_ptr() as usize
425 } else {
426 0
427 };
428 debug_assert!(offset == 0 || offset >= visited_node_entry_range.start);
429 debug_assert!(offset <= visited_node_entry_range.end);
430 Some(offset..offset + v.len())
431 }
432 },
433 child_entries_follow_up: 0, // Filled later.
434 children_present_in_proof_bitmap: 0, // Filled later.
435 });
436
437 // Add the visited node to the stack. The next iteration will either go to its first
438 // child, or pop the node from the stack.
439 visited_entries_stack.push(StackEntry {
440 range_in_proof: visited_node_entry_range,
441 index_in_entries: entries.len() - 1,
442 num_visited_children: 0,
443 children_node_values: visited_node_decoded.children,
444 });
445 }
446 }
447
448 // The entire reason why we track the unvisited proof entries is to return this error if
449 // necessary.
450 if !unvisited_proof_entries.is_empty() {
451 return Err(Error::UnusedProofEntry);
452 }
453
454 drop(entries_by_merkle_value);
455 Ok(DecodedTrieProof {
456 proof: config.proof,
457 entries,
458 trie_roots: trie_roots_with_entries,
459 })
460}
461
462/// Decoded Merkle proof. The proof is guaranteed valid.
463pub struct DecodedTrieProof<T> {
464 /// The proof itself.
465 proof: T,
466
467 /// All entries in the proof, in lexicographic order. Ordering between trie roots is
468 /// unspecified.
469 entries: Vec<Entry>,
470
471 ///
472 /// Given that hashes are verified to actually match their values, there is no risk of
473 /// HashDoS attack.
474 // TODO: is that true? ^ depends on whether there are a lot of storage values
475 trie_roots: hashbrown::HashMap<[u8; 32], usize, fnv::FnvBuildHasher>,
476}
477
478struct Entry {
479 /// Index within [`DecodedTrieProof::entries`] of the parent of this entry and child direction
480 /// nibble, or `None` if it is the root.
481 parent_entry_index: Option<(usize, nibble::Nibble)>,
482
483 /// Range within [`DecodedTrieProof::proof`] of the node value of this entry.
484 range_in_proof: ops::Range<usize>,
485
486 /// Range within [`DecodedTrieProof::proof`] of the unhashed storage value of this entry.
487 /// `None` if the entry doesn't have any storage entry or if it's missing from the proof.
488 storage_value_in_proof: Option<ops::Range<usize>>,
489
490 // TODO: doc
491 children_present_in_proof_bitmap: u16,
492
493 /// Given an entry of index `N`, it is always followed with `k` entries that correspond to the
494 /// sub-tree of that entry, where `k` is equal to [`Entry::child_entries_follow_up`]. In order
495 /// to jump to the next sibling of that entry, jump to `N + 1 + k`. If `k` is non-zero, then
496 /// entry `N + 1` corresponds to the first child of the entry of index `N`.
497 child_entries_follow_up: usize,
498 // TODO: by adding the partial key, we should be able to avoid decoding the entry while iterating down the trie
499}
500
501impl<T: AsRef<[u8]>> fmt::Debug for DecodedTrieProof<T> {
502 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
503 f.debug_map()
504 .entries(self.iter_ordered().map(
505 |(
506 EntryKey {
507 trie_root_hash,
508 key,
509 },
510 entry,
511 )| {
512 struct DummyHash<'a>(&'a [u8]);
513 impl<'a> fmt::Debug for DummyHash<'a> {
514 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
515 if self.0.is_empty() {
516 write!(f, "∅")?
517 }
518 for byte in self.0 {
519 write!(f, "{:02x}", *byte)?
520 }
521 Ok(())
522 }
523 }
524
525 struct DummyNibbles<'a, T: AsRef<[u8]>>(EntryKeyIter<'a, T>);
526 impl<'a, T: AsRef<[u8]>> fmt::Debug for DummyNibbles<'a, T> {
527 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
528 let mut any_written = false;
529 for nibble in self.0.clone() {
530 any_written = true;
531 write!(f, "{:x}", nibble)?
532 }
533 if !any_written {
534 write!(f, "∅")?
535 }
536 Ok(())
537 }
538 }
539
540 (
541 (DummyHash(trie_root_hash), DummyNibbles(key)),
542 (
543 entry.trie_node_info.children,
544 entry.trie_node_info.storage_value,
545 ),
546 )
547 },
548 ))
549 .finish()
550 }
551}
552
553/// Identifier for an entry within a decoded proof.
554pub struct EntryKey<'a, K> {
555 /// Hash of the root of the trie the key is in.
556 pub trie_root_hash: &'a [u8; 32],
557 /// The trie node key.
558 pub key: K,
559}
560
561impl<T: AsRef<[u8]>> DecodedTrieProof<T> {
562 /// Returns a list of all elements of the proof, ordered by key in lexicographic order.
563 ///
564 /// This function is a convenient wrapper around [`DecodedTrieProof::iter_ordered`] that
565 /// converts the keys into arrays of bytes. If a key can't be represented as an array of
566 /// bytes, then it is filtered out. Assuming that the trie has only ever been used in the
567 /// context of the runtime, then this cannot happen. See the section below for an
568 /// explanation.
569 ///
570 /// The iterator might include branch nodes. It is not possible for this function to
571 /// differentiate between value-less nodes that are present in the proof only because they are
572 /// branch nodes, and value-less nodes that are present in the proof because the fact that they
573 /// have no value is important for the proof.
574 ///
575 /// # Detailed explanation
576 ///
577 /// The trie consists of nodes, each with a key and a value. The keys consist of an array of
578 /// "nibbles", which are 4 bits each.
579 ///
580 /// When the runtime writes a value in the trie, it passes a key as an array a bytes. In order
581 /// to know where to write this value, this array of bytes is converted into an array of
582 /// nibbles by turning each byte into two nibbles.
583 ///
584 /// Due to the fact that the host-runtime interface only ever uses arrays of bytes, it is not
585 /// possible for the runtime to store a value or read a value in the trie at a key that
586 /// consists in an uneven number of nibbles, as an uneven number of nibbles cannot be
587 /// converted to an array of bytes.
588 ///
589 /// In other words, if a trie has only ever been used in the context of a runtime, then it is
590 /// guaranteed to not contain any storage value at key that consists in an uneven number of
591 /// nibbles.
592 ///
593 /// The trie format itself, however, technically doesn't forbid storing reading and writing
594 /// values at keys that consist in an uneven number of nibbles. For this reason, a proof
595 /// containing a value at a key that consists in an uneven number of nibbles is considered as
596 /// valid according to [`decode_and_verify_proof`].
597 ///
598 // TODO: paragraph below not true anymore
599 /// However, given that [`decode_and_verify_proof`] verifies the trie proof against the state
600 /// trie root hash, we are also guaranteed that this proof reflects the actual trie. If the
601 /// actual trie can't contain any storage value at a key that consists in an uneven number of
602 /// nibbles, then the proof is also guaranteed to not contain any storage value at a key that
603 /// consists in an uneven number of nibbles. Importantly, this is only true if we are sure that
604 /// the block is valid, in other words that it has indeed been created using a runtime. Blocks
605 /// that are invalid might have been created through a fake trie.
606 ///
607 /// As a conclusion, if this proof is made against a trie that has only ever been used in the
608 /// context of a runtime, and that the block using this trie is guaranteed to be valid, then
609 /// this function will work as intended and return the entire content of the proof.
610 ///
611 // TODO: ordering between trie roots unspecified
612 // TODO: consider not returning a Vec
613 pub fn iter_runtime_context_ordered(
614 &'_ self,
615 ) -> impl Iterator<Item = (EntryKey<'_, Vec<u8>>, StorageValue<'_>)> {
616 self.iter_ordered().filter_map(
617 |(
618 EntryKey {
619 trie_root_hash,
620 key,
621 },
622 entry,
623 )| {
624 let value = entry.trie_node_info.storage_value;
625
626 if key.clone().count() % 2 != 0 {
627 return None;
628 }
629
630 let key = nibble::nibbles_to_bytes_suffix_extend(key).collect();
631 Some((
632 EntryKey {
633 trie_root_hash,
634 key,
635 },
636 value,
637 ))
638 },
639 )
640 }
641
642 /// Returns a list of all elements of the proof, ordered by key in lexicographic order.
643 ///
644 /// The iterator includes branch nodes.
645 // TODO: ordering between trie roots unspecified
646 pub fn iter_ordered(
647 &self,
648 ) -> impl Iterator<Item = (EntryKey<'_, EntryKeyIter<'_, T>>, ProofEntry<'_, T>)> {
649 self.trie_roots
650 .iter()
651 .flat_map(|(trie_root_hash, &trie_root_entry_index)| {
652 (0..=self.entries[trie_root_entry_index].child_entries_follow_up)
653 .map(move |idx| idx + trie_root_entry_index)
654 .map(|entry_index| {
655 (
656 EntryKey {
657 trie_root_hash,
658 key: EntryKeyIter::new(self, entry_index),
659 },
660 self.build_proof_entry(trie_root_hash, entry_index),
661 )
662 })
663 })
664 }
665
666 /// Returns the [`ProofEntry`] of the given proof entry.
667 ///
668 /// # Panic
669 ///
670 /// Panics if `entry_index` is out of range.
671 ///
672 fn build_proof_entry<'a>(
673 &'a self,
674 trie_root_hash: &'a [u8; 32],
675 entry_index: usize,
676 ) -> ProofEntry<'a, T> {
677 let proof = self.proof.as_ref();
678
679 let entry = &self.entries[entry_index];
680
681 let Ok(entry_index_decoded) = trie_node::decode(&proof[entry.range_in_proof.clone()])
682 else {
683 // Proof has been checked to be entirely decodable.
684 unreachable!()
685 };
686
687 ProofEntry {
688 merkle_value: if let Some((parent_index, parent_nibble)) =
689 self.entries[entry_index].parent_entry_index
690 {
691 let Ok(parent_decoded) =
692 trie_node::decode(&proof[self.entries[parent_index].range_in_proof.clone()])
693 else {
694 // Proof has been checked to be entirely decodable.
695 unreachable!()
696 };
697 parent_decoded.children[usize::from(parent_nibble)]
698 .as_ref()
699 .unwrap()
700 } else {
701 trie_root_hash
702 },
703 node_value: &self.proof.as_ref()[entry.range_in_proof.clone()],
704 partial_key_nibbles: entry_index_decoded.partial_key,
705 unhashed_storage_value: entry
706 .storage_value_in_proof
707 .as_ref()
708 .map(|range| &proof[range.clone()]),
709 trie_node_info: TrieNodeInfo {
710 children: Children {
711 children: {
712 let mut children = core::array::from_fn(|_| Child::NoChild);
713 let mut i = entry_index + 1;
714 for child_num in 0..16 {
715 let Some(child_merkle_value) = entry_index_decoded.children[child_num]
716 else {
717 continue;
718 };
719 if entry.children_present_in_proof_bitmap & (1 << child_num) != 0 {
720 children[child_num] = Child::InProof {
721 child_key: EntryKeyIter::new(self, i),
722 merkle_value: child_merkle_value,
723 };
724 i += self.entries[i].child_entries_follow_up;
725 i += 1;
726 } else {
727 children[child_num] = Child::AbsentFromProof {
728 merkle_value: child_merkle_value,
729 };
730 }
731 }
732 children
733 },
734 },
735 storage_value: match (
736 entry_index_decoded.storage_value,
737 &entry.storage_value_in_proof,
738 ) {
739 (trie_node::StorageValue::Unhashed(value), _) => StorageValue::Known {
740 value,
741 inline: true,
742 },
743 (trie_node::StorageValue::Hashed(_), Some(value_range)) => {
744 StorageValue::Known {
745 value: &proof[value_range.clone()],
746 inline: false,
747 }
748 }
749 (trie_node::StorageValue::Hashed(hash), None) => {
750 StorageValue::HashKnownValueMissing(hash)
751 }
752 (trie_node::StorageValue::None, _v) => {
753 debug_assert!(_v.is_none());
754 StorageValue::None
755 }
756 },
757 },
758 }
759 }
760
761 /// Returns the [`ProofEntry`] of the proof entry whose Merkle value is given as parameter.
762 ///
763 /// The returned [`ProofEntry`] is guaranteed to have no parent.
764 ///
765 /// Returns `None` if the proof doesn't contain any sub-trie with the given Merkle value.
766 pub fn trie_root_proof_entry<'a>(
767 &'a self,
768 trie_root_merkle_value: &'a [u8; 32],
769 ) -> Option<ProofEntry<'a, T>> {
770 let entry_index = *self.trie_roots.get(trie_root_merkle_value)?;
771 Some(self.build_proof_entry(trie_root_merkle_value, entry_index))
772 }
773
774 /// Returns the [`ProofEntry`] of the given key.
775 ///
776 /// Returns `None` if the key doesn't have any entry in the proof.
777 ///
778 /// > **Note**: In situations where the key isn't in the proof but the proof contains enough
779 /// > information about the trie in order to infer some information about that key,
780 /// > the [`DecodedTrieProof::trie_node_info`] function will be successful whereas
781 /// > the [`DecodedTrieProof::proof_entry`] function will fail.
782 pub fn proof_entry<'a>(
783 &'a self,
784 trie_root_merkle_value: &'a [u8; 32],
785 key: impl Iterator<Item = nibble::Nibble>,
786 ) -> Option<ProofEntry<'a, T>> {
787 let (entry_index, exact_match) = self
788 .closest_ancestor_in_proof_entry(trie_root_merkle_value, key)
789 .ok()
790 .flatten()?;
791
792 if !exact_match {
793 return None;
794 }
795
796 Some(self.build_proof_entry(trie_root_merkle_value, entry_index))
797 }
798
799 /// Returns the key of the closest ancestor to the given key that can be found in the proof.
800 /// If `key` is in the proof, returns `key`.
801 ///
802 /// Returns `None` if the key is completely outside of the trie (i.e. the trie root is not
803 /// an ancestor of the key).
804 pub fn closest_ancestor_in_proof<'a>(
805 &'a self,
806 trie_root_merkle_value: &[u8; 32],
807 key: impl Iterator<Item = nibble::Nibble>,
808 ) -> Result<Option<EntryKeyIter<'a, T>>, IncompleteProofError> {
809 Ok(self
810 .closest_ancestor_in_proof_entry(trie_root_merkle_value, key)?
811 .map(|(idx, _)| EntryKeyIter::new(self, idx)))
812 }
813
814 /// Same as [`DecodedTrieProof::closest_ancestor_in_proof`], but returns the entry index
815 /// instead of its key.
816 ///
817 /// In addition to the entry index, also returns whether there was an exact match.
818 fn closest_ancestor_in_proof_entry<'a>(
819 &'a self,
820 trie_root_merkle_value: &[u8; 32],
821 mut key: impl Iterator<Item = nibble::Nibble>,
822 ) -> Result<Option<(usize, bool)>, IncompleteProofError> {
823 let proof = self.proof.as_ref();
824
825 // If the proof doesn't contain any entry for the requested trie, then we have no
826 // information about the node whatsoever.
827 // This check is necessary because we assume below that a lack of ancestor means that the
828 // key is outside of the trie.
829 let Some(&(mut iter_entry)) = self.trie_roots.get(trie_root_merkle_value) else {
830 return Err(IncompleteProofError());
831 };
832
833 loop {
834 let Ok(iter_entry_decoded) =
835 trie_node::decode(&proof[self.entries[iter_entry].range_in_proof.clone()])
836 else {
837 unreachable!()
838 };
839
840 let mut iter_entry_partial_key_iter = iter_entry_decoded.partial_key;
841 loop {
842 match (key.next(), iter_entry_partial_key_iter.next()) {
843 (Some(a), Some(b)) if a == b => {}
844 (_, Some(_)) => {
845 // Mismatch in partial key. Closest ancestor is the parent entry.
846 let Some((parent_entry, _)) = self.entries[iter_entry].parent_entry_index
847 else {
848 // Key is completely outside of the trie.
849 return Ok(None);
850 };
851 return Ok(Some((parent_entry, false)));
852 }
853 (Some(child_num), None) => {
854 if let Some(_) = iter_entry_decoded.children[usize::from(child_num)] {
855 // Key points to child. Update `iter_entry` and continue.
856 let children_present_in_proof_bitmap =
857 self.entries[iter_entry].children_present_in_proof_bitmap;
858
859 // If the child isn't present in the proof, then the proof is
860 // incomplete.
861 if children_present_in_proof_bitmap & (1 << u8::from(child_num)) == 0 {
862 return Err(IncompleteProofError());
863 }
864
865 for c in 0..u8::from(child_num) {
866 if children_present_in_proof_bitmap & (1 << c) != 0 {
867 iter_entry += 1;
868 iter_entry += self.entries[iter_entry].child_entries_follow_up;
869 }
870 }
871 iter_entry += 1;
872 } else {
873 // Key points to non-existing child. Closest ancestor is `iter_entry`.
874 return Ok(Some((iter_entry, false)));
875 }
876 break;
877 }
878 (None, None) => {
879 // Exact match. Closest ancestor is `iter_entry`.
880 return Ok(Some((iter_entry, true)));
881 }
882 }
883 }
884 }
885 }
886
887 /// Returns information about a trie node.
888 ///
889 /// Returns an error if the proof doesn't contain enough information about this trie node.
890 ///
891 /// This function will return `Ok` even if there is no node in the trie for `key`, in which
892 /// case the returned [`TrieNodeInfo`] will indicate no storage value and no children.
893 pub fn trie_node_info(
894 &self,
895 trie_root_merkle_value: &[u8; 32],
896 mut key: impl Iterator<Item = nibble::Nibble>,
897 ) -> Result<TrieNodeInfo<'_, T>, IncompleteProofError> {
898 let proof = self.proof.as_ref();
899
900 // Find the starting point of the requested trie.
901 let Some((mut iter_entry_merkle_value, mut iter_entry)) = self
902 .trie_roots
903 .get_key_value(trie_root_merkle_value)
904 .map(|(k, v)| (&k[..], *v))
905 else {
906 return Err(IncompleteProofError());
907 };
908
909 loop {
910 let Ok(iter_entry_decoded) =
911 trie_node::decode(&proof[self.entries[iter_entry].range_in_proof.clone()])
912 else {
913 // Proof has been checked to be entirely decodable.
914 unreachable!()
915 };
916
917 let mut iter_entry_partial_key_iter = iter_entry_decoded.partial_key;
918 loop {
919 match (key.next(), iter_entry_partial_key_iter.next()) {
920 (Some(a), Some(b)) if a == b => {}
921 (Some(_), Some(_)) => {
922 // Mismatch in partial key. No node with the requested key in the trie.
923 return Ok(TrieNodeInfo {
924 storage_value: StorageValue::None,
925 children: Children {
926 children: core::array::from_fn(|_| Child::NoChild),
927 },
928 });
929 }
930 (None, Some(a)) => {
931 // Input key is a subslice of `iter_entry`'s key.
932 // One has one descendant that is `iter_entry`.
933 let mut children = core::array::from_fn(|_| Child::NoChild);
934 children[usize::from(a)] = Child::InProof {
935 child_key: EntryKeyIter::new(self, iter_entry),
936 merkle_value: iter_entry_merkle_value,
937 };
938 return Ok(TrieNodeInfo {
939 storage_value: StorageValue::None,
940 children: Children { children },
941 });
942 }
943 (Some(child_num), None) => {
944 if let Some(child) = iter_entry_decoded.children[usize::from(child_num)] {
945 // Key points in the direction of a child.
946 let children_present_in_proof_bitmap =
947 self.entries[iter_entry].children_present_in_proof_bitmap;
948
949 // If the child isn't present in the proof, then the proof is
950 // incomplete.
951 if children_present_in_proof_bitmap & (1 << u8::from(child_num)) == 0 {
952 return Err(IncompleteProofError());
953 }
954
955 // Child is present in the proof. Update `iter_entry` and continue.
956 iter_entry_merkle_value = child;
957 for c in 0..u8::from(child_num) {
958 if children_present_in_proof_bitmap & (1 << c) != 0 {
959 iter_entry += 1;
960 iter_entry += self.entries[iter_entry].child_entries_follow_up;
961 }
962 }
963 iter_entry += 1;
964 break;
965 } else {
966 // Key points to non-existing child.
967 return Ok(TrieNodeInfo {
968 storage_value: StorageValue::None,
969 children: Children {
970 children: core::array::from_fn(|_| Child::NoChild),
971 },
972 });
973 }
974 }
975 (None, None) => {
976 // Exact match. Trie node is `iter_entry`.
977 return Ok(TrieNodeInfo {
978 storage_value: match (
979 iter_entry_decoded.storage_value,
980 &self.entries[iter_entry].storage_value_in_proof,
981 ) {
982 (trie_node::StorageValue::Unhashed(value), _) => {
983 StorageValue::Known {
984 value,
985 inline: true,
986 }
987 }
988 (trie_node::StorageValue::Hashed(_), Some(value_range)) => {
989 StorageValue::Known {
990 value: &proof[value_range.clone()],
991 inline: false,
992 }
993 }
994 (trie_node::StorageValue::Hashed(hash), None) => {
995 StorageValue::HashKnownValueMissing(hash)
996 }
997 (trie_node::StorageValue::None, _v) => {
998 debug_assert!(_v.is_none());
999 StorageValue::None
1000 }
1001 },
1002 children: Children {
1003 children: {
1004 let mut children = core::array::from_fn(|_| Child::NoChild);
1005 let mut i = iter_entry + 1;
1006 for child_num in 0..16 {
1007 let Some(child_merkle_value) =
1008 iter_entry_decoded.children[child_num]
1009 else {
1010 continue;
1011 };
1012 if self.entries[iter_entry].children_present_in_proof_bitmap
1013 & (1 << child_num)
1014 != 0
1015 {
1016 children[child_num] = Child::InProof {
1017 child_key: EntryKeyIter::new(self, i),
1018 merkle_value: child_merkle_value,
1019 };
1020 i += self.entries[i].child_entries_follow_up;
1021 i += 1;
1022 } else {
1023 children[child_num] = Child::AbsentFromProof {
1024 merkle_value: child_merkle_value,
1025 };
1026 }
1027 }
1028 children
1029 },
1030 },
1031 });
1032 }
1033 }
1034 }
1035 }
1036 }
1037
1038 /// Queries from the proof the storage value at the given key.
1039 ///
1040 /// Returns an error if the storage value couldn't be determined from the proof. Returns
1041 /// `Ok(None)` if the storage value is known to have no value.
1042 ///
1043 /// > **Note**: This function is a convenient wrapper around
1044 /// > [`DecodedTrieProof::trie_node_info`].
1045 // TODO: accept param as iterator rather than slice?
1046 pub fn storage_value(
1047 &self,
1048 trie_root_merkle_value: &[u8; 32],
1049 key: &[u8],
1050 ) -> Result<Option<(&[u8], TrieEntryVersion)>, IncompleteProofError> {
1051 match self
1052 .trie_node_info(
1053 trie_root_merkle_value,
1054 nibble::bytes_to_nibbles(key.iter().copied()),
1055 )?
1056 .storage_value
1057 {
1058 StorageValue::Known { value, inline } => Ok(Some((
1059 value,
1060 if inline {
1061 TrieEntryVersion::V0
1062 } else {
1063 TrieEntryVersion::V1
1064 },
1065 ))),
1066 StorageValue::HashKnownValueMissing(_) => Err(IncompleteProofError()),
1067 StorageValue::None => Ok(None),
1068 }
1069 }
1070
1071 /// Find in the proof the trie node that follows `key_before` in lexicographic order.
1072 ///
1073 /// If `or_equal` is `true`, then `key_before` is returned if it is equal to a node in the
1074 /// trie. If `false`, then only keys that are strictly superior are returned.
1075 ///
1076 /// The returned value must always start with `prefix`. Note that the value of `prefix` is
1077 /// important as it can be the difference between `Err(IncompleteProofError)` and `Ok(None)`.
1078 ///
1079 /// If `branch_nodes` is `false`, then trie nodes that don't have a storage value are skipped.
1080 ///
1081 /// Returns an error if the proof doesn't contain enough information to determine the next key.
1082 /// Returns `Ok(None)` if the proof indicates that there is no next key (within the given
1083 /// prefix).
1084 pub fn next_key(
1085 &self,
1086 trie_root_merkle_value: &[u8; 32],
1087 key_before: impl Iterator<Item = nibble::Nibble>,
1088 mut or_equal: bool,
1089 prefix: impl Iterator<Item = nibble::Nibble>,
1090 branch_nodes: bool,
1091 ) -> Result<Option<EntryKeyIter<'_, T>>, IncompleteProofError> {
1092 let proof = self.proof.as_ref();
1093
1094 // The implementation below might continue iterating `prefix` even after it has returned
1095 // `None`, thus we have to fuse it.
1096 let mut prefix = prefix.fuse();
1097
1098 // The implementation below might continue iterating `key_before` even after it has
1099 // returned `None`, thus we have to fuse it.
1100 // Furthermore, `key_before` might be modified in the implementation below. When that
1101 // happens, de do this by setting it to `either::Right`.
1102 let mut key_before = either::Left(key_before.fuse());
1103
1104 // Find the starting point of the requested trie.
1105 let Some(&(mut iter_entry)) = self.trie_roots.get(trie_root_merkle_value) else {
1106 return Err(IncompleteProofError());
1107 };
1108
1109 // If `true`, then it was determined that `key_before` was after the last child of
1110 // `iter_entry`. The next iteration must find `iter_entry`'s next sibling.
1111 let mut iterating_up: bool = false;
1112
1113 // Indicates the depth of ancestors of `iter_entry` that match `prefix`.
1114 // For example, if the value is 2, then `iter_entry`'s parent and grandparent match
1115 // `prefix`, but `iter_entry`'s grandparent parent does not.
1116 let mut prefix_match_iter_entry_ancestor_depth = 0;
1117
1118 loop {
1119 let Ok(iter_entry_decoded) =
1120 trie_node::decode(&proof[self.entries[iter_entry].range_in_proof.clone()])
1121 else {
1122 // Proof has been checked to be entirely decodable.
1123 unreachable!()
1124 };
1125
1126 if iterating_up {
1127 debug_assert!(matches!(key_before, either::Right(_)));
1128 debug_assert!(or_equal);
1129
1130 // It was determined that `key_before` was after the last child of `iter_entry`.
1131 // The next iteration must find `iter_entry`'s next sibling.
1132
1133 if prefix_match_iter_entry_ancestor_depth == 0 {
1134 // `prefix` only matches `iter_entry` and not its parent and
1135 // thus wouldn't match `iter_entry`'s sibling or uncle.
1136 // Therefore, the next node is `None`.
1137 return Ok(None);
1138 }
1139
1140 // Go to `iter_entry`'s next sibling, if any.
1141 let Some((parent_entry, parent_to_child_nibble)) =
1142 self.entries[iter_entry].parent_entry_index
1143 else {
1144 // `iter_entry` is the root of the trie. `key_before` is therefore
1145 // after the last entry of the trie.
1146 return Ok(None);
1147 };
1148 let Ok(parent_entry_decoded) =
1149 trie_node::decode(&proof[self.entries[parent_entry].range_in_proof.clone()])
1150 else {
1151 // Proof has been checked to be entirely decodable.
1152 unreachable!()
1153 };
1154
1155 let Some(child_num) = parent_entry_decoded
1156 .children
1157 .iter()
1158 .skip(usize::from(parent_to_child_nibble) + 1)
1159 .position(|c| c.is_some())
1160 .map(|n| n + usize::from(parent_to_child_nibble) + 1)
1161 else {
1162 // No child found. Continue iterating up.
1163 iterating_up = true;
1164 iter_entry = parent_entry;
1165 prefix_match_iter_entry_ancestor_depth -= 1;
1166 continue;
1167 };
1168
1169 // Found a next sibling.
1170
1171 let children_present_in_proof_bitmap =
1172 self.entries[parent_entry].children_present_in_proof_bitmap;
1173
1174 // If the child isn't present in the proof, then the proof is
1175 // incomplete. While in some situations we could prove that the child
1176 // is necessarily the next key, there is no way to know its full key.
1177 if children_present_in_proof_bitmap & (1 << child_num) == 0 {
1178 return Err(IncompleteProofError());
1179 }
1180
1181 // `iter_entry` is still pointing to the child at index `parent_to_child_nibble`.
1182 // Since we're jumping to its next sibling, all we have to do is skip over it
1183 // and its descedants.
1184 iter_entry += self.entries[iter_entry].child_entries_follow_up;
1185 iter_entry += 1;
1186 iterating_up = false;
1187 continue; // Continue in order to refresh `iter_entry_decoded`.
1188 }
1189
1190 let mut iter_entry_partial_key_iter = iter_entry_decoded.partial_key;
1191 loop {
1192 match (
1193 key_before.next(),
1194 prefix.next(),
1195 iter_entry_partial_key_iter.next(),
1196 ) {
1197 (Some(k), Some(p), Some(pk)) if k == p && p == pk => {
1198 // Continue descending down the tree.
1199 }
1200 (None, Some(p), Some(pk)) if p == pk => {
1201 // Continue descending down the tree.
1202 }
1203 (Some(k), None, Some(pk)) if k == pk => {
1204 // Continue descending down the tree.
1205 }
1206 (None, None, Some(_)) => {
1207 // Exact match. Due to the `branch_nodes` setting, we can't just
1208 // return `iter_entry` and instead continue iterating.
1209 or_equal = true;
1210 }
1211 (Some(k), None, Some(pk)) if k < pk => {
1212 // `key_before` points to somewhere between `iter_entry`'s parent
1213 // and `iter_entry`. Due to the `branch_nodes` setting, we can't just
1214 // return `iter_entry` and instead continue iterating.
1215 key_before = either::Right(iter::empty().fuse());
1216 or_equal = true;
1217 }
1218 (Some(k), Some(p), _) if k > p => {
1219 // `key_before` is strictly superior to `prefix`. The next key is
1220 // thus necessarily `None`.
1221 // Note that this is not a situation that is expected to be common, as
1222 // doing such a call is pointless.
1223 return Ok(None);
1224 }
1225 (Some(k), Some(p), Some(pk)) if k < p && p == pk => {
1226 // The key and prefix diverge.
1227 // We know that there isn't any key in the trie between `key_before`
1228 // and `prefix`.
1229 // Starting next iteration, the next node matching the prefix
1230 // will be the result.
1231 key_before = either::Right(iter::empty().fuse());
1232 or_equal = true;
1233 }
1234 (_, Some(p), Some(pk)) => {
1235 debug_assert!(p != pk); // Other situations covered by other match blocks.
1236
1237 // Mismatch between prefix and partial key. No matter the value of
1238 // `key_before` There is no node in the trie that starts with `prefix`.
1239 return Ok(None);
1240 }
1241 (Some(k), None, Some(pk)) if k < pk => {
1242 // `key_before` points to somewhere between `iter_entry`'s parent
1243 // and `iter_entry`. We know that `iter_entry` necessarily matches
1244 // the prefix. The next key is necessarily `iter_entry`.
1245 return Ok(Some(EntryKeyIter::new(self, iter_entry)));
1246 }
1247 (Some(k), None, Some(pk)) => {
1248 debug_assert!(k > pk); // Checked above.
1249
1250 // `key_before` points to somewhere between the last child of `iter_entry`
1251 // and its next sibling.
1252 // The next key is thus the next sibling of `iter_entry`.
1253 iterating_up = true;
1254 key_before = either::Right(iter::empty().fuse());
1255 or_equal = true;
1256 break;
1257 }
1258 (None, None, None)
1259 if or_equal
1260 && (branch_nodes
1261 || !matches!(
1262 iter_entry_decoded.storage_value,
1263 trie_node::StorageValue::None,
1264 )) =>
1265 {
1266 // Exact match. Next key is `iter_entry`.
1267 return Ok(Some(EntryKeyIter::new(self, iter_entry)));
1268 }
1269 (key_before_nibble, prefix_nibble, None) => {
1270 // The moment when we have finished traversing a node and go to the
1271 // next one is the most complicated situation.
1272
1273 // We know for sure that `iter_entry` can't be returned, as it is covered
1274 // by the other match variants above. Therefore, `key_before_nibble` equal
1275 // to `None` is the same as if it is equal to `0`.
1276 let key_before_nibble = match key_before_nibble {
1277 Some(n) => u8::from(n),
1278 None => {
1279 or_equal = true;
1280 0
1281 }
1282 };
1283
1284 // Try to find the first child that is after `key_before`.
1285 if let Some(child_num) = iter_entry_decoded
1286 .children
1287 .iter()
1288 .skip(usize::from(key_before_nibble))
1289 .position(|c| c.is_some())
1290 .map(|n| n + usize::from(key_before_nibble))
1291 {
1292 // Found a child. Make sure that it matches the prefix nibble.
1293 if prefix_nibble.map_or(false, |p| child_num != usize::from(p)) {
1294 // Child doesn't match prefix. No next key.
1295 return Ok(None);
1296 }
1297
1298 // Continue iterating down through the child that has been found.
1299
1300 let children_present_in_proof_bitmap =
1301 self.entries[iter_entry].children_present_in_proof_bitmap;
1302
1303 // If the child isn't present in the proof, then the proof is
1304 // incomplete. While in some situations we could prove that the child
1305 // is necessarily the next key, there is no way to know its full key.
1306 if children_present_in_proof_bitmap & (1 << child_num) == 0 {
1307 return Err(IncompleteProofError());
1308 }
1309
1310 for c in 0..child_num {
1311 if children_present_in_proof_bitmap & (1 << c) != 0 {
1312 iter_entry += 1;
1313 iter_entry += self.entries[iter_entry].child_entries_follow_up;
1314 }
1315 }
1316
1317 iter_entry += 1;
1318 if prefix_nibble.is_none() {
1319 prefix_match_iter_entry_ancestor_depth += 1;
1320 }
1321 if usize::from(key_before_nibble) != child_num {
1322 key_before = either::Right(iter::empty().fuse());
1323 or_equal = true;
1324 }
1325 break;
1326 } else {
1327 // Childless branch nodes are forbidden. This is checked when
1328 // decoding the proof.
1329 debug_assert!(!matches!(
1330 iter_entry_decoded.storage_value,
1331 trie_node::StorageValue::None,
1332 ));
1333
1334 // `key_before` is after the last child of `iter_entry`. The next
1335 // node is thus a sibling or uncle of `iter_entry`.
1336 iterating_up = true;
1337 key_before = either::Right(iter::empty().fuse());
1338 or_equal = true;
1339 break;
1340 }
1341 }
1342 }
1343 }
1344 }
1345 }
1346
1347 /// Find in the proof the closest trie node that descends from `key` and returns its Merkle
1348 /// value.
1349 ///
1350 /// Returns an error if the proof doesn't contain enough information to determine the Merkle
1351 /// value.
1352 /// Returns `Ok(None)` if the proof indicates that there is no descendant.
1353 pub fn closest_descendant_merkle_value(
1354 &self,
1355 trie_root_merkle_value: &[u8; 32],
1356 mut key: impl Iterator<Item = nibble::Nibble>,
1357 ) -> Result<Option<&[u8]>, IncompleteProofError> {
1358 let proof = self.proof.as_ref();
1359
1360 // Find the starting point of the requested trie.
1361 let Some((mut iter_entry_merkle_value, mut iter_entry)) = self
1362 .trie_roots
1363 .get_key_value(trie_root_merkle_value)
1364 .map(|(k, v)| (&k[..], *v))
1365 else {
1366 return Err(IncompleteProofError());
1367 };
1368
1369 loop {
1370 let Ok(iter_entry_decoded) =
1371 trie_node::decode(&proof[self.entries[iter_entry].range_in_proof.clone()])
1372 else {
1373 // Proof has been checked to be entirely decodable.
1374 unreachable!()
1375 };
1376
1377 let mut iter_entry_partial_key_iter = iter_entry_decoded.partial_key;
1378 loop {
1379 match (key.next(), iter_entry_partial_key_iter.next()) {
1380 (Some(a), Some(b)) if a == b => {}
1381 (Some(_), Some(_)) => {
1382 // Mismatch in partial key. No descendant.
1383 return Ok(None);
1384 }
1385 (None, Some(_)) => {
1386 // Input key is a subslice of `iter_entry`'s key.
1387 // Descendant is thus `iter_entry`.
1388 return Ok(Some(iter_entry_merkle_value));
1389 }
1390 (Some(child_num), None) => {
1391 if let Some(child) = iter_entry_decoded.children[usize::from(child_num)] {
1392 // Key points in the direction of a child.
1393 let children_present_in_proof_bitmap =
1394 self.entries[iter_entry].children_present_in_proof_bitmap;
1395
1396 // If the child isn't present in the proof, then the proof is
1397 // incomplete, unless the input key doesn't have any nibble anymore,
1398 // in which case we know that the closest descendant is this child,
1399 // even if it's not present.
1400 if children_present_in_proof_bitmap & (1 << u8::from(child_num)) == 0 {
1401 if key.next().is_none() {
1402 return Ok(Some(child));
1403 } else {
1404 return Err(IncompleteProofError());
1405 }
1406 }
1407
1408 // Child is present in the proof. Update `iter_entry` and continue.
1409 iter_entry_merkle_value = child;
1410 for c in 0..u8::from(child_num) {
1411 if children_present_in_proof_bitmap & (1 << c) != 0 {
1412 iter_entry += 1;
1413 iter_entry += self.entries[iter_entry].child_entries_follow_up;
1414 }
1415 }
1416 iter_entry += 1;
1417 break;
1418 } else {
1419 // Key points to non-existing child. We know that there's no
1420 // descendant.
1421 return Ok(None);
1422 }
1423 }
1424 (None, None) => {
1425 // Exact match. Closest descendant is `iter_entry`.
1426 return Ok(Some(iter_entry_merkle_value));
1427 }
1428 }
1429 }
1430 }
1431 }
1432}
1433
1434/// Proof doesn't contain enough information to answer the request.
1435#[derive(Debug, Clone, derive_more::Display, derive_more::Error)]
1436pub struct IncompleteProofError();
1437
1438/// Storage value of the node.
1439#[derive(Copy, Clone)]
1440pub enum StorageValue<'a> {
1441 /// The storage value was found in the proof.
1442 Known {
1443 /// The storage value.
1444 value: &'a [u8],
1445 /// `true` if the storage value was inline in the node. This indicates "version 0" of the
1446 /// state version, while `false` indicates "version 1".
1447 inline: bool,
1448 },
1449 /// The hash of the storage value was found, but the un-hashed value wasn't in the proof. This
1450 /// indicates an incomplete proof.
1451 HashKnownValueMissing(&'a [u8; 32]),
1452 /// The node doesn't have a storage value.
1453 None,
1454}
1455
1456impl<'a> fmt::Debug for StorageValue<'a> {
1457 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
1458 match self {
1459 StorageValue::Known { value, inline } if value.len() <= 48 => {
1460 write!(
1461 f,
1462 "0x{}{}",
1463 hex::encode(value),
1464 if *inline { " (inline)" } else { "" }
1465 )
1466 }
1467 StorageValue::Known { value, inline } => {
1468 write!(
1469 f,
1470 "0x{}…{} ({} bytes{})",
1471 hex::encode(&value[0..4]),
1472 hex::encode(&value[value.len() - 4..]),
1473 value.len(),
1474 if *inline { ", inline" } else { "" }
1475 )
1476 }
1477 StorageValue::HashKnownValueMissing(hash) => {
1478 write!(f, "hash(0x{})", hex::encode(hash))
1479 }
1480 StorageValue::None => write!(f, "<none>"),
1481 }
1482 }
1483}
1484
1485/// Possible error returned by [`decode_and_verify_proof`].
1486#[derive(Debug, Clone, derive_more::Display, derive_more::Error)]
1487pub enum Error {
1488 /// Proof is in an invalid format.
1489 InvalidFormat(ParseError),
1490 /// One of the entries of the proof is disconnected from the root node.
1491 UnusedProofEntry,
1492 /// The same entry has been found multiple times in the proof.
1493 DuplicateProofEntry,
1494}
1495
1496pub struct EntryKeyIter<'a, T> {
1497 proof: &'a DecodedTrieProof<T>,
1498 target_entry: usize,
1499 /// [`EntryKeyIter::entry_key_iterator`] is the `target_entry_depth_remaining` nth ancestor
1500 /// of [`EntryKeyIter::target_entry`].
1501 target_entry_depth_remaining: usize,
1502 /// `None` if iteration is finished.
1503 entry_key_iterator: Option<trie_node::DecodedPartialKey<'a>>,
1504}
1505
1506impl<'a, T: AsRef<[u8]>> EntryKeyIter<'a, T> {
1507 fn new(proof: &'a DecodedTrieProof<T>, target_entry: usize) -> Self {
1508 // Find the number of nodes between `target_entry` and the trie root.
1509 let mut entry_iter = target_entry;
1510 let mut target_entry_depth_remaining = 0;
1511 loop {
1512 if let Some((parent, _)) = proof.entries[entry_iter].parent_entry_index {
1513 target_entry_depth_remaining += 1;
1514 entry_iter = parent;
1515 } else {
1516 break;
1517 }
1518 }
1519
1520 let Ok(decoded_entry) = trie_node::decode(
1521 &proof.proof.as_ref()[proof.entries[entry_iter].range_in_proof.clone()],
1522 ) else {
1523 unreachable!()
1524 };
1525
1526 EntryKeyIter {
1527 proof,
1528 target_entry,
1529 target_entry_depth_remaining,
1530 entry_key_iterator: Some(decoded_entry.partial_key),
1531 }
1532 }
1533}
1534
1535impl<'a, T: AsRef<[u8]>> Iterator for EntryKeyIter<'a, T> {
1536 type Item = nibble::Nibble;
1537
1538 fn next(&mut self) -> Option<Self::Item> {
1539 // `entry_key_iterator` is `None` only if the iteration is finished, as a way to fuse
1540 // the iterator.
1541 let Some(entry_key_iterator) = &mut self.entry_key_iterator else {
1542 return None;
1543 };
1544
1545 // Still yielding from `entry_key_iterator`.
1546 if let Some(nibble) = entry_key_iterator.next() {
1547 return Some(nibble);
1548 }
1549
1550 // `entry_key_iterator` has finished iterating. Update the local state for the next node
1551 // in the hierarchy.
1552 if self.target_entry_depth_remaining == 0 {
1553 // Iteration finished.
1554 self.entry_key_iterator = None;
1555 return None;
1556 }
1557 self.target_entry_depth_remaining -= 1;
1558
1559 // Find the `target_entry_depth_remaining`th ancestor of `target_entry`.
1560 let mut entry_iter = self.target_entry;
1561 for _ in 0..self.target_entry_depth_remaining {
1562 let Some((parent, _)) = self.proof.entries[entry_iter].parent_entry_index else {
1563 unreachable!()
1564 };
1565 entry_iter = parent;
1566 }
1567
1568 // Store the partial key of `entry_iter` in `entry_key_iterator`, so that it starts being
1569 // yielded at the next iteration.
1570 self.entry_key_iterator = Some(
1571 trie_node::decode(
1572 &self.proof.proof.as_ref()[self.proof.entries[entry_iter].range_in_proof.clone()],
1573 )
1574 .unwrap_or_else(|_| unreachable!())
1575 .partial_key,
1576 );
1577
1578 // Yield the "parent-child nibble" of `entry_iter`.
1579 Some(
1580 self.proof.entries[entry_iter]
1581 .parent_entry_index
1582 .unwrap_or_else(|| unreachable!())
1583 .1,
1584 )
1585 }
1586
1587 fn size_hint(&self) -> (usize, Option<usize>) {
1588 // We know we're going to yield `self.target_entry_depth_remaining` "parent-child nibbles".
1589 // We add to that the size hint of `entry_key_iterator`.
1590 let entry_key_iterator = self
1591 .entry_key_iterator
1592 .as_ref()
1593 .map_or(0, |i| i.size_hint().0);
1594 (entry_key_iterator + self.target_entry_depth_remaining, None)
1595 }
1596}
1597
1598impl<'a, T: AsRef<[u8]>> iter::FusedIterator for EntryKeyIter<'a, T> {}
1599
1600// We need to implement `Clone` manually, otherwise Rust adds an implicit `T: Clone` requirements.
1601impl<'a, T> Clone for EntryKeyIter<'a, T> {
1602 fn clone(&self) -> Self {
1603 EntryKeyIter {
1604 proof: self.proof,
1605 target_entry: self.target_entry,
1606 target_entry_depth_remaining: self.target_entry_depth_remaining,
1607 entry_key_iterator: self.entry_key_iterator.clone(),
1608 }
1609 }
1610}
1611
1612impl<'a, T: AsRef<[u8]>> fmt::Debug for EntryKeyIter<'a, T> {
1613 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
1614 let mut any_printed = false;
1615 for nibble in self.clone() {
1616 any_printed = true;
1617 write!(f, "{:x}", nibble)?;
1618 }
1619 if !any_printed {
1620 write!(f, "∅")?;
1621 }
1622 Ok(())
1623 }
1624}
1625
1626/// Information about an entry in the proof.
1627#[derive(Debug)]
1628pub struct ProofEntry<'a, T> {
1629 /// Information about the node of the trie associated to this entry.
1630 pub trie_node_info: TrieNodeInfo<'a, T>,
1631
1632 /// Merkle value of that proof entry.
1633 ///
1634 /// > **Note**: This is a low-level information. If you're not familiar with how the trie
1635 /// > works, you most likely don't need this.
1636 pub merkle_value: &'a [u8],
1637
1638 /// Node value of that proof entry.
1639 ///
1640 /// > **Note**: This is a low-level information. If you're not familiar with how the trie
1641 /// > works, you most likely don't need this.
1642 pub node_value: &'a [u8],
1643
1644 /// Partial key of that proof entry.
1645 ///
1646 /// > **Note**: This is a low-level information. If you're not familiar with how the trie
1647 /// > works, you most likely don't need this.
1648 pub partial_key_nibbles: trie_node::DecodedPartialKey<'a>,
1649
1650 /// If [`ProofEntry::node_value`] indicates that the storage value is hashed, then this field
1651 /// contains the unhashed storage value that is found in the proof, if any.
1652 ///
1653 /// If this field contains `Some`, then [`TrieNodeInfo::storage_value`] is guaranteed to
1654 /// contain [`StorageValue::Known`]. However the opposite is not necessarily true.
1655 ///
1656 /// > **Note**: This is a low-level information. If you're not familiar with how the trie
1657 /// > works, you most likely don't need this.
1658 pub unhashed_storage_value: Option<&'a [u8]>,
1659}
1660
1661// We need to implement `Clone` manually, otherwise Rust adds an implicit `T: Clone` requirements.
1662impl<'a, T> Clone for ProofEntry<'a, T> {
1663 fn clone(&self) -> Self {
1664 ProofEntry {
1665 trie_node_info: self.trie_node_info.clone(),
1666 merkle_value: self.merkle_value,
1667 node_value: self.node_value,
1668 partial_key_nibbles: self.partial_key_nibbles.clone(),
1669 unhashed_storage_value: self.unhashed_storage_value,
1670 }
1671 }
1672}
1673
1674/// Information about a node of the trie.
1675///
1676/// > **Note**: This structure might represent a node that doesn't actually exist in the trie.
1677#[derive(Debug)]
1678pub struct TrieNodeInfo<'a, T> {
1679 /// Storage value of the node, if any.
1680 pub storage_value: StorageValue<'a>,
1681 /// Which children the node has.
1682 pub children: Children<'a, T>,
1683}
1684
1685// We need to implement `Clone` manually, otherwise Rust adds an implicit `T: Clone` requirements.
1686impl<'a, T> Clone for TrieNodeInfo<'a, T> {
1687 fn clone(&self) -> Self {
1688 TrieNodeInfo {
1689 storage_value: self.storage_value,
1690 children: self.children.clone(),
1691 }
1692 }
1693}
1694
1695/// See [`TrieNodeInfo::children`].
1696pub struct Children<'a, T> {
1697 children: [Child<'a, T>; 16],
1698}
1699
1700/// Information about a specific child in the list of children.
1701pub enum Child<'a, T> {
1702 /// Child exists and can be found in the proof.
1703 InProof {
1704 /// Key of the child. Always starts with the key of its parent.
1705 child_key: EntryKeyIter<'a, T>,
1706 /// Merkle value of the child.
1707 merkle_value: &'a [u8],
1708 },
1709 /// Child exists but isn't present in the proof.
1710 AbsentFromProof {
1711 /// Merkle value of the child.
1712 merkle_value: &'a [u8],
1713 },
1714 /// Child doesn't exist.
1715 NoChild,
1716}
1717
1718impl<'a, T> Child<'a, T> {
1719 /// Returns the Merkle value of this child. `None` if the child doesn't exist.
1720 pub fn merkle_value(&self) -> Option<&'a [u8]> {
1721 match self {
1722 Child::InProof { merkle_value, .. } => Some(merkle_value),
1723 Child::AbsentFromProof { merkle_value } => Some(merkle_value),
1724 Child::NoChild => None,
1725 }
1726 }
1727}
1728
1729// We need to implement `Clone` manually, otherwise Rust adds an implicit `T: Clone` requirements.
1730impl<'a, T> Clone for Child<'a, T> {
1731 fn clone(&self) -> Self {
1732 match self {
1733 Child::AbsentFromProof { merkle_value } => Child::AbsentFromProof { merkle_value },
1734 Child::InProof {
1735 child_key,
1736 merkle_value,
1737 } => Child::InProof {
1738 child_key: child_key.clone(),
1739 merkle_value,
1740 },
1741 Child::NoChild => Child::NoChild,
1742 }
1743 }
1744}
1745
1746impl<'a, T> Children<'a, T> {
1747 /// Returns `true` if a child in the direction of the given nibble is present.
1748 pub fn has_child(&self, nibble: nibble::Nibble) -> bool {
1749 match self.children[usize::from(u8::from(nibble))] {
1750 Child::InProof { .. } | Child::AbsentFromProof { .. } => true,
1751 Child::NoChild => false,
1752 }
1753 }
1754
1755 /// Returns the information about the child in the given direction.
1756 pub fn child(&self, direction: nibble::Nibble) -> Child<'a, T> {
1757 self.children[usize::from(u8::from(direction))].clone()
1758 }
1759
1760 /// Returns an iterator of 16 items, one for each child.
1761 pub fn children(&self) -> impl DoubleEndedIterator + ExactSizeIterator<Item = Child<'a, T>> {
1762 self.children.iter().cloned()
1763 }
1764}
1765
1766// We need to implement `Clone` manually, otherwise Rust adds an implicit `T: Clone` requirements.
1767impl<'a, T> Clone for Children<'a, T> {
1768 fn clone(&self) -> Self {
1769 Children {
1770 children: self.children.clone(),
1771 }
1772 }
1773}
1774
1775impl<'a, T> fmt::Debug for Children<'a, T> {
1776 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
1777 fmt::Binary::fmt(&self, f)
1778 }
1779}
1780
1781impl<'a, T> fmt::Binary for Children<'a, T> {
1782 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
1783 for child in &self.children {
1784 let chr = match child {
1785 Child::InProof { .. } | Child::AbsentFromProof { .. } => '1',
1786 Child::NoChild => '0',
1787 };
1788
1789 fmt::Write::write_char(f, chr)?
1790 }
1791
1792 Ok(())
1793 }
1794}