alloy_trie/proof/
decoded_retainer.rs

1use crate::{proof::DecodedProofNodes, Nibbles};
2use alloy_primitives::Bytes;
3
4use alloc::vec::Vec;
5
6/// Proof retainer is used to store proofs during merkle trie construction.
7/// It is intended to be used within the [`HashBuilder`](crate::HashBuilder).
8#[derive(Default, Clone, Debug)]
9pub struct DecodedProofRetainer {
10    /// The nibbles of the target trie keys to retain proofs for.
11    targets: Vec<Nibbles>,
12    /// The map retained trie node keys to RLP serialized trie nodes.
13    proof_nodes: DecodedProofNodes,
14}
15
16impl FromIterator<Nibbles> for DecodedProofRetainer {
17    fn from_iter<T: IntoIterator<Item = Nibbles>>(iter: T) -> Self {
18        Self::new(FromIterator::from_iter(iter))
19    }
20}
21
22impl DecodedProofRetainer {
23    /// Create new retainer with target nibbles.
24    pub fn new(targets: Vec<Nibbles>) -> Self {
25        Self { targets, proof_nodes: Default::default() }
26    }
27
28    /// Returns `true` if the given prefix matches the retainer target.
29    pub fn matches(&self, prefix: &Nibbles) -> bool {
30        self.targets.iter().any(|target| target.starts_with(prefix))
31    }
32
33    /// Returns all collected proofs.
34    pub fn into_proof_nodes(self) -> DecodedProofNodes {
35        self.proof_nodes
36    }
37
38    /// Retain the proof if the key matches any of the targets.
39    ///
40    /// Returns an error if the proof could not be decoded from the given proof bytes.
41    pub fn retain(&mut self, prefix: &Nibbles, proof: &[u8]) -> Result<(), alloy_rlp::Error> {
42        if prefix.is_empty() || self.matches(prefix) {
43            self.proof_nodes.insert_encoded(prefix.clone(), Bytes::from(proof.to_vec()))?;
44        }
45
46        Ok(())
47    }
48}