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}