alloy_trie/proof/
decoded_proof_nodes.rs

1use crate::{nodes::TrieNode, proof::ProofNodes, HashMap, Nibbles};
2use alloy_primitives::Bytes;
3use alloy_rlp::Decodable;
4use core::ops::Deref;
5
6use alloc::vec::Vec;
7
8/// A wrapper struct for trie node key to RLP encoded trie node.
9#[derive(PartialEq, Eq, Clone, Default, Debug)]
10#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
11pub struct DecodedProofNodes(HashMap<Nibbles, TrieNode>);
12
13impl Deref for DecodedProofNodes {
14    type Target = HashMap<Nibbles, TrieNode>;
15
16    fn deref(&self) -> &Self::Target {
17        &self.0
18    }
19}
20
21impl FromIterator<(Nibbles, TrieNode)> for DecodedProofNodes {
22    fn from_iter<T: IntoIterator<Item = (Nibbles, TrieNode)>>(iter: T) -> Self {
23        Self(HashMap::from_iter(iter))
24    }
25}
26
27impl Extend<(Nibbles, TrieNode)> for DecodedProofNodes {
28    fn extend<T: IntoIterator<Item = (Nibbles, TrieNode)>>(&mut self, iter: T) {
29        self.0.extend(iter);
30    }
31}
32
33impl TryFrom<ProofNodes> for DecodedProofNodes {
34    type Error = alloy_rlp::Error;
35
36    fn try_from(proof_nodes: ProofNodes) -> Result<Self, Self::Error> {
37        let mut decoded_proof_nodes =
38            HashMap::with_capacity_and_hasher(proof_nodes.len(), Default::default());
39        for (key, node) in proof_nodes.into_inner() {
40            decoded_proof_nodes.insert(key, TrieNode::decode(&mut &node[..])?);
41        }
42        Ok(Self(decoded_proof_nodes))
43    }
44}
45
46impl DecodedProofNodes {
47    /// Return iterator over proof nodes that match the target.
48    pub fn matching_nodes_iter<'a>(
49        &'a self,
50        target: &'a Nibbles,
51    ) -> impl Iterator<Item = (&'a Nibbles, &'a TrieNode)> {
52        self.0.iter().filter(|(key, _)| target.starts_with(key))
53    }
54
55    /// Return the vec of proof nodes that match the target.
56    pub fn matching_nodes(&self, target: &Nibbles) -> Vec<(Nibbles, TrieNode)> {
57        self.matching_nodes_iter(target).map(|(key, node)| (key.clone(), node.clone())).collect()
58    }
59
60    /// Return the sorted vec of proof nodes that match the target.
61    pub fn matching_nodes_sorted(&self, target: &Nibbles) -> Vec<(Nibbles, TrieNode)> {
62        let mut nodes = self.matching_nodes(target);
63        nodes.sort_unstable_by(|a, b| a.0.cmp(&b.0));
64        nodes
65    }
66
67    /// Insert the trie node at key.
68    pub fn insert(&mut self, key: Nibbles, node: TrieNode) -> Option<TrieNode> {
69        self.0.insert(key, node)
70    }
71
72    /// Insert the RLP encoded trie nodoe at key
73    pub fn insert_encoded(
74        &mut self,
75        key: Nibbles,
76        node: Bytes,
77    ) -> Result<Option<TrieNode>, alloy_rlp::Error> {
78        Ok(self.0.insert(key, TrieNode::decode(&mut &node[..])?))
79    }
80
81    /// Return the sorted vec of all proof nodes.
82    pub fn nodes_sorted(&self) -> Vec<(Nibbles, TrieNode)> {
83        let mut nodes = Vec::from_iter(self.0.iter().map(|(k, v)| (k.clone(), v.clone())));
84        nodes.sort_unstable_by(|a, b| a.0.cmp(&b.0));
85        nodes
86    }
87
88    /// Convert into sorted vec of all proof nodes.
89    pub fn into_nodes_sorted(self) -> Vec<(Nibbles, TrieNode)> {
90        let mut nodes = Vec::from_iter(self.0);
91        nodes.sort_unstable_by(|a, b| a.0.cmp(&b.0));
92        nodes
93    }
94
95    /// Convert wrapper struct into inner map.
96    pub fn into_inner(self) -> HashMap<Nibbles, TrieNode> {
97        self.0
98    }
99
100    /// Extends with the elements of another `DecodedProofNodes`.
101    pub fn extend_from(&mut self, other: Self) {
102        self.extend(other.0);
103    }
104}