mirror of
https://github.com/hl-archive-node/nanoreth.git
synced 2025-12-06 10:59:55 +00:00
feat(trie): proof blinded providers (#13085)
This commit is contained in:
1
Cargo.lock
generated
1
Cargo.lock
generated
@ -9430,6 +9430,7 @@ dependencies = [
|
||||
"reth-stages-types",
|
||||
"reth-storage-errors",
|
||||
"reth-trie-common",
|
||||
"reth-trie-sparse",
|
||||
"revm",
|
||||
"serde_json",
|
||||
"tracing",
|
||||
|
||||
@ -55,3 +55,11 @@ impl BlindedProvider for DefaultBlindedProvider {
|
||||
Ok(None)
|
||||
}
|
||||
}
|
||||
|
||||
/// Right pad the path with 0s and return as [`B256`].
|
||||
#[inline]
|
||||
pub fn pad_path_to_key(path: &Nibbles) -> B256 {
|
||||
let mut padded = path.pack();
|
||||
padded.resize(32, 0);
|
||||
B256::from_slice(&padded)
|
||||
}
|
||||
|
||||
@ -55,4 +55,7 @@ pub enum SparseTrieError {
|
||||
/// RLP error.
|
||||
#[error(transparent)]
|
||||
Rlp(#[from] alloy_rlp::Error),
|
||||
/// Other.
|
||||
#[error(transparent)]
|
||||
Other(#[from] Box<dyn std::error::Error>),
|
||||
}
|
||||
|
||||
@ -17,6 +17,7 @@ reth-execution-errors.workspace = true
|
||||
reth-primitives.workspace = true
|
||||
reth-stages-types.workspace = true
|
||||
reth-storage-errors.workspace = true
|
||||
reth-trie-sparse.workspace = true
|
||||
reth-trie-common.workspace = true
|
||||
|
||||
revm.workspace = true
|
||||
|
||||
116
crates/trie/trie/src/proof/blinded.rs
Normal file
116
crates/trie/trie/src/proof/blinded.rs
Normal file
@ -0,0 +1,116 @@
|
||||
use super::{Proof, StorageProof};
|
||||
use crate::{hashed_cursor::HashedCursorFactory, trie_cursor::TrieCursorFactory};
|
||||
use alloy_primitives::{
|
||||
map::{HashMap, HashSet},
|
||||
Bytes, B256,
|
||||
};
|
||||
use reth_trie_common::{prefix_set::TriePrefixSetsMut, Nibbles};
|
||||
use reth_trie_sparse::{
|
||||
blinded::{pad_path_to_key, BlindedProvider, BlindedProviderFactory},
|
||||
SparseTrieError,
|
||||
};
|
||||
use std::sync::Arc;
|
||||
|
||||
/// Factory for instantiating providers capable of retrieving blinded trie nodes via proofs.
|
||||
#[derive(Debug)]
|
||||
pub struct ProofBlindedProviderFactory<T, H> {
|
||||
/// The cursor factory for traversing trie nodes.
|
||||
trie_cursor_factory: T,
|
||||
/// The factory for hashed cursors.
|
||||
hashed_cursor_factory: H,
|
||||
/// A set of prefix sets that have changes.
|
||||
prefix_sets: Arc<TriePrefixSetsMut>,
|
||||
}
|
||||
|
||||
impl<T, H> BlindedProviderFactory for ProofBlindedProviderFactory<T, H>
|
||||
where
|
||||
T: TrieCursorFactory + Clone,
|
||||
H: HashedCursorFactory + Clone,
|
||||
{
|
||||
type AccountNodeProvider = ProofBlindedAccountProvider<T, H>;
|
||||
type StorageNodeProvider = ProofBlindedStorageProvider<T, H>;
|
||||
|
||||
fn account_node_provider(&self) -> Self::AccountNodeProvider {
|
||||
ProofBlindedAccountProvider {
|
||||
trie_cursor_factory: self.trie_cursor_factory.clone(),
|
||||
hashed_cursor_factory: self.hashed_cursor_factory.clone(),
|
||||
prefix_sets: self.prefix_sets.clone(),
|
||||
}
|
||||
}
|
||||
|
||||
fn storage_node_provider(&self, account: B256) -> Self::StorageNodeProvider {
|
||||
ProofBlindedStorageProvider {
|
||||
trie_cursor_factory: self.trie_cursor_factory.clone(),
|
||||
hashed_cursor_factory: self.hashed_cursor_factory.clone(),
|
||||
prefix_sets: self.prefix_sets.clone(),
|
||||
account,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Blinded provider for retrieving account trie nodes by path.
|
||||
#[derive(Debug)]
|
||||
pub struct ProofBlindedAccountProvider<T, H> {
|
||||
/// The cursor factory for traversing trie nodes.
|
||||
trie_cursor_factory: T,
|
||||
/// The factory for hashed cursors.
|
||||
hashed_cursor_factory: H,
|
||||
/// A set of prefix sets that have changes.
|
||||
prefix_sets: Arc<TriePrefixSetsMut>,
|
||||
}
|
||||
|
||||
impl<T, H> BlindedProvider for ProofBlindedAccountProvider<T, H>
|
||||
where
|
||||
T: TrieCursorFactory + Clone,
|
||||
H: HashedCursorFactory + Clone,
|
||||
{
|
||||
type Error = SparseTrieError;
|
||||
|
||||
fn blinded_node(&mut self, path: Nibbles) -> Result<Option<Bytes>, Self::Error> {
|
||||
let targets = HashMap::from_iter([(pad_path_to_key(&path), HashSet::default())]);
|
||||
let proof =
|
||||
Proof::new(self.trie_cursor_factory.clone(), self.hashed_cursor_factory.clone())
|
||||
.with_prefix_sets_mut(self.prefix_sets.as_ref().clone())
|
||||
.multiproof(targets)
|
||||
.map_err(|error| SparseTrieError::Other(Box::new(error)))?;
|
||||
|
||||
Ok(proof.account_subtree.into_inner().remove(&path))
|
||||
}
|
||||
}
|
||||
|
||||
/// Blinded provider for retrieving storage trie nodes by path.
|
||||
#[derive(Debug)]
|
||||
pub struct ProofBlindedStorageProvider<T, H> {
|
||||
/// The cursor factory for traversing trie nodes.
|
||||
trie_cursor_factory: T,
|
||||
/// The factory for hashed cursors.
|
||||
hashed_cursor_factory: H,
|
||||
/// A set of prefix sets that have changes.
|
||||
prefix_sets: Arc<TriePrefixSetsMut>,
|
||||
/// Target account.
|
||||
account: B256,
|
||||
}
|
||||
|
||||
impl<T, H> BlindedProvider for ProofBlindedStorageProvider<T, H>
|
||||
where
|
||||
T: TrieCursorFactory + Clone,
|
||||
H: HashedCursorFactory + Clone,
|
||||
{
|
||||
type Error = SparseTrieError;
|
||||
|
||||
fn blinded_node(&mut self, path: Nibbles) -> Result<Option<Bytes>, Self::Error> {
|
||||
let targets = HashSet::from_iter([pad_path_to_key(&path)]);
|
||||
let storage_prefix_set =
|
||||
self.prefix_sets.storage_prefix_sets.get(&self.account).cloned().unwrap_or_default();
|
||||
let proof = StorageProof::new_hashed(
|
||||
self.trie_cursor_factory.clone(),
|
||||
self.hashed_cursor_factory.clone(),
|
||||
self.account,
|
||||
)
|
||||
.with_prefix_set_mut(storage_prefix_set)
|
||||
.storage_multiproof(targets)
|
||||
.map_err(|error| SparseTrieError::Other(Box::new(error)))?;
|
||||
|
||||
Ok(proof.subtree.into_inner().remove(&path))
|
||||
}
|
||||
}
|
||||
@ -17,6 +17,9 @@ use reth_trie_common::{
|
||||
proof::ProofRetainer, AccountProof, MultiProof, StorageMultiProof, TrieAccount,
|
||||
};
|
||||
|
||||
mod blinded;
|
||||
pub use blinded::*;
|
||||
|
||||
/// A struct for generating merkle proofs.
|
||||
///
|
||||
/// Proof generator adds the target address and slots to the prefix set, enables the proof retainer
|
||||
Reference in New Issue
Block a user