mirror of
https://github.com/paradigmxyz/reth.git
synced 2026-02-15 09:25:33 -05:00
159 lines
5.6 KiB
Rust
159 lines
5.6 KiB
Rust
use crate::{DatabaseHashedCursorFactory, DatabaseTrieCursorFactory};
|
|
use alloy_primitives::{
|
|
keccak256,
|
|
map::{B256HashMap, B256HashSet, HashMap},
|
|
Address, B256,
|
|
};
|
|
use reth_db_api::transaction::DbTx;
|
|
use reth_execution_errors::StateProofError;
|
|
use reth_trie::{
|
|
hashed_cursor::HashedPostStateCursorFactory,
|
|
proof::{Proof, StorageProof},
|
|
trie_cursor::InMemoryTrieCursorFactory,
|
|
AccountProof, HashedPostStateSorted, HashedStorage, MultiProof, StorageMultiProof, TrieInput,
|
|
};
|
|
|
|
/// Extends [`Proof`] with operations specific for working with a database transaction.
|
|
pub trait DatabaseProof<'a, TX> {
|
|
/// Create a new [Proof] from database transaction.
|
|
fn from_tx(tx: &'a TX) -> Self;
|
|
|
|
/// Generates the state proof for target account based on [`TrieInput`].
|
|
fn overlay_account_proof(
|
|
tx: &'a TX,
|
|
input: TrieInput,
|
|
address: Address,
|
|
slots: &[B256],
|
|
) -> Result<AccountProof, StateProofError>;
|
|
|
|
/// Generates the state [`MultiProof`] for target hashed account and storage keys.
|
|
fn overlay_multiproof(
|
|
tx: &'a TX,
|
|
input: TrieInput,
|
|
targets: B256HashMap<B256HashSet>,
|
|
) -> Result<MultiProof, StateProofError>;
|
|
}
|
|
|
|
impl<'a, TX: DbTx> DatabaseProof<'a, TX>
|
|
for Proof<DatabaseTrieCursorFactory<'a, TX>, DatabaseHashedCursorFactory<'a, TX>>
|
|
{
|
|
/// Create a new [Proof] instance from database transaction.
|
|
fn from_tx(tx: &'a TX) -> Self {
|
|
Self::new(DatabaseTrieCursorFactory::new(tx), DatabaseHashedCursorFactory::new(tx))
|
|
}
|
|
|
|
fn overlay_account_proof(
|
|
tx: &'a TX,
|
|
input: TrieInput,
|
|
address: Address,
|
|
slots: &[B256],
|
|
) -> Result<AccountProof, StateProofError> {
|
|
let nodes_sorted = input.nodes.into_sorted();
|
|
let state_sorted = input.state.into_sorted();
|
|
Self::from_tx(tx)
|
|
.with_trie_cursor_factory(InMemoryTrieCursorFactory::new(
|
|
DatabaseTrieCursorFactory::new(tx),
|
|
&nodes_sorted,
|
|
))
|
|
.with_hashed_cursor_factory(HashedPostStateCursorFactory::new(
|
|
DatabaseHashedCursorFactory::new(tx),
|
|
&state_sorted,
|
|
))
|
|
.with_prefix_sets_mut(input.prefix_sets)
|
|
.account_proof(address, slots)
|
|
}
|
|
|
|
fn overlay_multiproof(
|
|
tx: &'a TX,
|
|
input: TrieInput,
|
|
targets: B256HashMap<B256HashSet>,
|
|
) -> Result<MultiProof, StateProofError> {
|
|
let nodes_sorted = input.nodes.into_sorted();
|
|
let state_sorted = input.state.into_sorted();
|
|
Self::from_tx(tx)
|
|
.with_trie_cursor_factory(InMemoryTrieCursorFactory::new(
|
|
DatabaseTrieCursorFactory::new(tx),
|
|
&nodes_sorted,
|
|
))
|
|
.with_hashed_cursor_factory(HashedPostStateCursorFactory::new(
|
|
DatabaseHashedCursorFactory::new(tx),
|
|
&state_sorted,
|
|
))
|
|
.with_prefix_sets_mut(input.prefix_sets)
|
|
.multiproof(targets)
|
|
}
|
|
}
|
|
|
|
/// Extends [`StorageProof`] with operations specific for working with a database transaction.
|
|
pub trait DatabaseStorageProof<'a, TX> {
|
|
/// Create a new [`StorageProof`] from database transaction and account address.
|
|
fn from_tx(tx: &'a TX, address: Address) -> Self;
|
|
|
|
/// Generates the storage proof for target slot based on [`TrieInput`].
|
|
fn overlay_storage_proof(
|
|
tx: &'a TX,
|
|
address: Address,
|
|
slot: B256,
|
|
storage: HashedStorage,
|
|
) -> Result<reth_trie::StorageProof, StateProofError>;
|
|
|
|
/// Generates the storage multiproof for target slots based on [`TrieInput`].
|
|
fn overlay_storage_multiproof(
|
|
tx: &'a TX,
|
|
address: Address,
|
|
slots: &[B256],
|
|
storage: HashedStorage,
|
|
) -> Result<StorageMultiProof, StateProofError>;
|
|
}
|
|
|
|
impl<'a, TX: DbTx> DatabaseStorageProof<'a, TX>
|
|
for StorageProof<DatabaseTrieCursorFactory<'a, TX>, DatabaseHashedCursorFactory<'a, TX>>
|
|
{
|
|
fn from_tx(tx: &'a TX, address: Address) -> Self {
|
|
Self::new(DatabaseTrieCursorFactory::new(tx), DatabaseHashedCursorFactory::new(tx), address)
|
|
}
|
|
|
|
fn overlay_storage_proof(
|
|
tx: &'a TX,
|
|
address: Address,
|
|
slot: B256,
|
|
storage: HashedStorage,
|
|
) -> Result<reth_trie::StorageProof, StateProofError> {
|
|
let hashed_address = keccak256(address);
|
|
let prefix_set = storage.construct_prefix_set();
|
|
let state_sorted = HashedPostStateSorted::new(
|
|
Default::default(),
|
|
HashMap::from_iter([(hashed_address, storage.into_sorted())]),
|
|
);
|
|
Self::from_tx(tx, address)
|
|
.with_hashed_cursor_factory(HashedPostStateCursorFactory::new(
|
|
DatabaseHashedCursorFactory::new(tx),
|
|
&state_sorted,
|
|
))
|
|
.with_prefix_set_mut(prefix_set)
|
|
.storage_proof(slot)
|
|
}
|
|
|
|
fn overlay_storage_multiproof(
|
|
tx: &'a TX,
|
|
address: Address,
|
|
slots: &[B256],
|
|
storage: HashedStorage,
|
|
) -> Result<StorageMultiProof, StateProofError> {
|
|
let hashed_address = keccak256(address);
|
|
let targets = slots.iter().map(keccak256).collect();
|
|
let prefix_set = storage.construct_prefix_set();
|
|
let state_sorted = HashedPostStateSorted::new(
|
|
Default::default(),
|
|
HashMap::from_iter([(hashed_address, storage.into_sorted())]),
|
|
);
|
|
Self::from_tx(tx, address)
|
|
.with_hashed_cursor_factory(HashedPostStateCursorFactory::new(
|
|
DatabaseHashedCursorFactory::new(tx),
|
|
&state_sorted,
|
|
))
|
|
.with_prefix_set_mut(prefix_set)
|
|
.storage_multiproof(targets)
|
|
}
|
|
}
|