mirror of
https://github.com/hl-archive-node/nanoreth.git
synced 2025-12-06 19:09:54 +00:00
feat(trie): StorageRootProvider::storage_multiproof (#12879)
This commit is contained in:
@ -944,7 +944,9 @@ mod tests {
|
|||||||
AccountReader, BlockHashReader, StateProofProvider, StateProvider, StateRootProvider,
|
AccountReader, BlockHashReader, StateProofProvider, StateProvider, StateRootProvider,
|
||||||
StorageRootProvider,
|
StorageRootProvider,
|
||||||
};
|
};
|
||||||
use reth_trie::{AccountProof, HashedStorage, MultiProof, StorageProof, TrieInput};
|
use reth_trie::{
|
||||||
|
AccountProof, HashedStorage, MultiProof, StorageMultiProof, StorageProof, TrieInput,
|
||||||
|
};
|
||||||
|
|
||||||
fn create_mock_state(
|
fn create_mock_state(
|
||||||
test_block_builder: &mut TestBlockBuilder<EthPrimitives>,
|
test_block_builder: &mut TestBlockBuilder<EthPrimitives>,
|
||||||
@ -1054,6 +1056,15 @@ mod tests {
|
|||||||
) -> ProviderResult<StorageProof> {
|
) -> ProviderResult<StorageProof> {
|
||||||
Ok(StorageProof::new(slot))
|
Ok(StorageProof::new(slot))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn storage_multiproof(
|
||||||
|
&self,
|
||||||
|
_address: Address,
|
||||||
|
_slots: &[B256],
|
||||||
|
_hashed_storage: HashedStorage,
|
||||||
|
) -> ProviderResult<StorageMultiProof> {
|
||||||
|
Ok(StorageMultiProof::empty())
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl StateProofProvider for MockStateProvider {
|
impl StateProofProvider for MockStateProvider {
|
||||||
|
|||||||
@ -11,7 +11,8 @@ use reth_storage_api::{
|
|||||||
StorageRootProvider,
|
StorageRootProvider,
|
||||||
};
|
};
|
||||||
use reth_trie::{
|
use reth_trie::{
|
||||||
updates::TrieUpdates, AccountProof, HashedPostState, HashedStorage, MultiProof, TrieInput,
|
updates::TrieUpdates, AccountProof, HashedPostState, HashedStorage, MultiProof,
|
||||||
|
StorageMultiProof, TrieInput,
|
||||||
};
|
};
|
||||||
use std::sync::OnceLock;
|
use std::sync::OnceLock;
|
||||||
|
|
||||||
@ -167,6 +168,20 @@ macro_rules! impl_state_provider {
|
|||||||
hashed_storage.extend(&storage);
|
hashed_storage.extend(&storage);
|
||||||
self.historical.storage_proof(address, slot, hashed_storage)
|
self.historical.storage_proof(address, slot, hashed_storage)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TODO: Currently this does not reuse available in-memory trie nodes.
|
||||||
|
fn storage_multiproof(
|
||||||
|
&self,
|
||||||
|
address: Address,
|
||||||
|
slots: &[B256],
|
||||||
|
storage: HashedStorage,
|
||||||
|
) -> ProviderResult<StorageMultiProof> {
|
||||||
|
let state = &self.trie_state().state;
|
||||||
|
let mut hashed_storage =
|
||||||
|
state.storages.get(&keccak256(address)).cloned().unwrap_or_default();
|
||||||
|
hashed_storage.extend(&storage);
|
||||||
|
self.historical.storage_multiproof(address, slots, hashed_storage)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl $($tokens)* StateProofProvider for $type {
|
impl $($tokens)* StateProofProvider for $type {
|
||||||
|
|||||||
@ -11,8 +11,8 @@ use reth_storage_api::{
|
|||||||
};
|
};
|
||||||
use reth_storage_errors::provider::ProviderResult;
|
use reth_storage_errors::provider::ProviderResult;
|
||||||
use reth_trie::{
|
use reth_trie::{
|
||||||
updates::TrieUpdates, AccountProof, HashedPostState, HashedStorage, MultiProof, StorageProof,
|
updates::TrieUpdates, AccountProof, HashedPostState, HashedStorage, MultiProof,
|
||||||
TrieInput,
|
StorageMultiProof, StorageProof, TrieInput,
|
||||||
};
|
};
|
||||||
|
|
||||||
/// Mock state for testing
|
/// Mock state for testing
|
||||||
@ -112,6 +112,15 @@ impl StorageRootProvider for StateProviderTest {
|
|||||||
) -> ProviderResult<StorageProof> {
|
) -> ProviderResult<StorageProof> {
|
||||||
unimplemented!("proof generation is not supported")
|
unimplemented!("proof generation is not supported")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn storage_multiproof(
|
||||||
|
&self,
|
||||||
|
_address: Address,
|
||||||
|
_slots: &[B256],
|
||||||
|
_hashed_storage: HashedStorage,
|
||||||
|
) -> ProviderResult<StorageMultiProof> {
|
||||||
|
unimplemented!("proof generation is not supported")
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl StateProofProvider for StateProviderTest {
|
impl StateProofProvider for StateProviderTest {
|
||||||
|
|||||||
9
crates/rpc/rpc-eth-types/src/cache/db.rs
vendored
9
crates/rpc/rpc-eth-types/src/cache/db.rs
vendored
@ -67,6 +67,15 @@ impl reth_storage_api::StorageRootProvider for StateProviderTraitObjWrapper<'_>
|
|||||||
) -> ProviderResult<reth_trie::StorageProof> {
|
) -> ProviderResult<reth_trie::StorageProof> {
|
||||||
self.0.storage_proof(address, slot, hashed_storage)
|
self.0.storage_proof(address, slot, hashed_storage)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn storage_multiproof(
|
||||||
|
&self,
|
||||||
|
address: Address,
|
||||||
|
slots: &[B256],
|
||||||
|
hashed_storage: HashedStorage,
|
||||||
|
) -> ProviderResult<reth_trie::StorageMultiProof> {
|
||||||
|
self.0.storage_multiproof(address, slots, hashed_storage)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl reth_storage_api::StateProofProvider for StateProviderTraitObjWrapper<'_> {
|
impl reth_storage_api::StateProofProvider for StateProviderTraitObjWrapper<'_> {
|
||||||
|
|||||||
@ -9,7 +9,8 @@ use reth_primitives::{Account, Bytecode};
|
|||||||
use reth_storage_api::{StateProofProvider, StorageRootProvider};
|
use reth_storage_api::{StateProofProvider, StorageRootProvider};
|
||||||
use reth_storage_errors::provider::ProviderResult;
|
use reth_storage_errors::provider::ProviderResult;
|
||||||
use reth_trie::{
|
use reth_trie::{
|
||||||
updates::TrieUpdates, AccountProof, HashedPostState, HashedStorage, MultiProof, TrieInput,
|
updates::TrieUpdates, AccountProof, HashedPostState, HashedStorage, MultiProof,
|
||||||
|
StorageMultiProof, TrieInput,
|
||||||
};
|
};
|
||||||
|
|
||||||
/// A state provider that resolves to data from either a wrapped [`crate::ExecutionOutcome`]
|
/// A state provider that resolves to data from either a wrapped [`crate::ExecutionOutcome`]
|
||||||
@ -138,6 +139,17 @@ impl<SP: StateProvider, EDP: ExecutionDataProvider> StorageRootProvider
|
|||||||
storage.extend(&hashed_storage);
|
storage.extend(&hashed_storage);
|
||||||
self.state_provider.storage_proof(address, slot, storage)
|
self.state_provider.storage_proof(address, slot, storage)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn storage_multiproof(
|
||||||
|
&self,
|
||||||
|
address: Address,
|
||||||
|
slots: &[B256],
|
||||||
|
hashed_storage: HashedStorage,
|
||||||
|
) -> ProviderResult<StorageMultiProof> {
|
||||||
|
let mut storage = self.get_hashed_storage(address);
|
||||||
|
storage.extend(&hashed_storage);
|
||||||
|
self.state_provider.storage_multiproof(address, slots, storage)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<SP: StateProvider, EDP: ExecutionDataProvider> StateProofProvider
|
impl<SP: StateProvider, EDP: ExecutionDataProvider> StateProofProvider
|
||||||
|
|||||||
@ -21,7 +21,8 @@ use reth_trie::{
|
|||||||
proof::{Proof, StorageProof},
|
proof::{Proof, StorageProof},
|
||||||
updates::TrieUpdates,
|
updates::TrieUpdates,
|
||||||
witness::TrieWitness,
|
witness::TrieWitness,
|
||||||
AccountProof, HashedPostState, HashedStorage, MultiProof, StateRoot, StorageRoot, TrieInput,
|
AccountProof, HashedPostState, HashedStorage, MultiProof, StateRoot, StorageMultiProof,
|
||||||
|
StorageRoot, TrieInput,
|
||||||
};
|
};
|
||||||
use reth_trie_db::{
|
use reth_trie_db::{
|
||||||
DatabaseHashedPostState, DatabaseHashedStorage, DatabaseProof, DatabaseStateRoot,
|
DatabaseHashedPostState, DatabaseHashedStorage, DatabaseProof, DatabaseStateRoot,
|
||||||
@ -341,6 +342,18 @@ impl<Provider: DBProvider + BlockNumReader> StorageRootProvider
|
|||||||
StorageProof::overlay_storage_proof(self.tx(), address, slot, revert_storage)
|
StorageProof::overlay_storage_proof(self.tx(), address, slot, revert_storage)
|
||||||
.map_err(Into::<ProviderError>::into)
|
.map_err(Into::<ProviderError>::into)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn storage_multiproof(
|
||||||
|
&self,
|
||||||
|
address: Address,
|
||||||
|
slots: &[B256],
|
||||||
|
hashed_storage: HashedStorage,
|
||||||
|
) -> ProviderResult<StorageMultiProof> {
|
||||||
|
let mut revert_storage = self.revert_storage(address)?;
|
||||||
|
revert_storage.extend(&hashed_storage);
|
||||||
|
StorageProof::overlay_storage_multiproof(self.tx(), address, slots, revert_storage)
|
||||||
|
.map_err(Into::<ProviderError>::into)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<Provider: DBProvider + BlockNumReader> StateProofProvider
|
impl<Provider: DBProvider + BlockNumReader> StateProofProvider
|
||||||
|
|||||||
@ -15,7 +15,8 @@ use reth_trie::{
|
|||||||
proof::{Proof, StorageProof},
|
proof::{Proof, StorageProof},
|
||||||
updates::TrieUpdates,
|
updates::TrieUpdates,
|
||||||
witness::TrieWitness,
|
witness::TrieWitness,
|
||||||
AccountProof, HashedPostState, HashedStorage, MultiProof, StateRoot, StorageRoot, TrieInput,
|
AccountProof, HashedPostState, HashedStorage, MultiProof, StateRoot, StorageMultiProof,
|
||||||
|
StorageRoot, TrieInput,
|
||||||
};
|
};
|
||||||
use reth_trie_db::{
|
use reth_trie_db::{
|
||||||
DatabaseProof, DatabaseStateRoot, DatabaseStorageProof, DatabaseStorageRoot,
|
DatabaseProof, DatabaseStateRoot, DatabaseStorageProof, DatabaseStorageRoot,
|
||||||
@ -108,6 +109,16 @@ impl<Provider: DBProvider> StorageRootProvider for LatestStateProviderRef<'_, Pr
|
|||||||
StorageProof::overlay_storage_proof(self.tx(), address, slot, hashed_storage)
|
StorageProof::overlay_storage_proof(self.tx(), address, slot, hashed_storage)
|
||||||
.map_err(Into::<ProviderError>::into)
|
.map_err(Into::<ProviderError>::into)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn storage_multiproof(
|
||||||
|
&self,
|
||||||
|
address: Address,
|
||||||
|
slots: &[B256],
|
||||||
|
hashed_storage: HashedStorage,
|
||||||
|
) -> ProviderResult<StorageMultiProof> {
|
||||||
|
StorageProof::overlay_storage_multiproof(self.tx(), address, slots, hashed_storage)
|
||||||
|
.map_err(Into::<ProviderError>::into)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<Provider: DBProvider> StateProofProvider for LatestStateProviderRef<'_, Provider> {
|
impl<Provider: DBProvider> StateProofProvider for LatestStateProviderRef<'_, Provider> {
|
||||||
|
|||||||
@ -50,6 +50,7 @@ macro_rules! delegate_provider_impls {
|
|||||||
StorageRootProvider $(where [$($generics)*])? {
|
StorageRootProvider $(where [$($generics)*])? {
|
||||||
fn storage_root(&self, address: alloy_primitives::Address, storage: reth_trie::HashedStorage) -> reth_storage_errors::provider::ProviderResult<alloy_primitives::B256>;
|
fn storage_root(&self, address: alloy_primitives::Address, storage: reth_trie::HashedStorage) -> reth_storage_errors::provider::ProviderResult<alloy_primitives::B256>;
|
||||||
fn storage_proof(&self, address: alloy_primitives::Address, slot: alloy_primitives::B256, storage: reth_trie::HashedStorage) -> reth_storage_errors::provider::ProviderResult<reth_trie::StorageProof>;
|
fn storage_proof(&self, address: alloy_primitives::Address, slot: alloy_primitives::B256, storage: reth_trie::HashedStorage) -> reth_storage_errors::provider::ProviderResult<reth_trie::StorageProof>;
|
||||||
|
fn storage_multiproof(&self, address: alloy_primitives::Address, slots: &[alloy_primitives::B256], storage: reth_trie::HashedStorage) -> reth_storage_errors::provider::ProviderResult<reth_trie::StorageMultiProof>;
|
||||||
}
|
}
|
||||||
StateProofProvider $(where [$($generics)*])? {
|
StateProofProvider $(where [$($generics)*])? {
|
||||||
fn proof(&self, input: reth_trie::TrieInput, address: alloy_primitives::Address, slots: &[alloy_primitives::B256]) -> reth_storage_errors::provider::ProviderResult<reth_trie::AccountProof>;
|
fn proof(&self, input: reth_trie::TrieInput, address: alloy_primitives::Address, slots: &[alloy_primitives::B256]) -> reth_storage_errors::provider::ProviderResult<reth_trie::AccountProof>;
|
||||||
|
|||||||
@ -32,8 +32,8 @@ use reth_storage_api::{
|
|||||||
};
|
};
|
||||||
use reth_storage_errors::provider::{ConsistentViewError, ProviderError, ProviderResult};
|
use reth_storage_errors::provider::{ConsistentViewError, ProviderError, ProviderResult};
|
||||||
use reth_trie::{
|
use reth_trie::{
|
||||||
updates::TrieUpdates, AccountProof, HashedPostState, HashedStorage, MultiProof, StorageProof,
|
updates::TrieUpdates, AccountProof, HashedPostState, HashedStorage, MultiProof,
|
||||||
TrieInput,
|
StorageMultiProof, StorageProof, TrieInput,
|
||||||
};
|
};
|
||||||
use reth_trie_db::MerklePatriciaTrie;
|
use reth_trie_db::MerklePatriciaTrie;
|
||||||
use revm::primitives::{BlockEnv, CfgEnvWithHandlerCfg};
|
use revm::primitives::{BlockEnv, CfgEnvWithHandlerCfg};
|
||||||
@ -639,6 +639,15 @@ impl StorageRootProvider for MockEthProvider {
|
|||||||
) -> ProviderResult<reth_trie::StorageProof> {
|
) -> ProviderResult<reth_trie::StorageProof> {
|
||||||
Ok(StorageProof::new(slot))
|
Ok(StorageProof::new(slot))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn storage_multiproof(
|
||||||
|
&self,
|
||||||
|
_address: Address,
|
||||||
|
_slots: &[B256],
|
||||||
|
_hashed_storage: HashedStorage,
|
||||||
|
) -> ProviderResult<StorageMultiProof> {
|
||||||
|
Ok(StorageMultiProof::empty())
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl StateProofProvider for MockEthProvider {
|
impl StateProofProvider for MockEthProvider {
|
||||||
|
|||||||
@ -372,6 +372,15 @@ impl StorageRootProvider for NoopProvider {
|
|||||||
) -> ProviderResult<reth_trie::StorageProof> {
|
) -> ProviderResult<reth_trie::StorageProof> {
|
||||||
Ok(reth_trie::StorageProof::new(slot))
|
Ok(reth_trie::StorageProof::new(slot))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn storage_multiproof(
|
||||||
|
&self,
|
||||||
|
_address: Address,
|
||||||
|
_slots: &[B256],
|
||||||
|
_hashed_storage: HashedStorage,
|
||||||
|
) -> ProviderResult<reth_trie::StorageMultiProof> {
|
||||||
|
Ok(reth_trie::StorageMultiProof::empty())
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl StateProofProvider for NoopProvider {
|
impl StateProofProvider for NoopProvider {
|
||||||
|
|||||||
@ -5,7 +5,8 @@ use alloy_primitives::{
|
|||||||
use reth_storage_errors::provider::ProviderResult;
|
use reth_storage_errors::provider::ProviderResult;
|
||||||
use reth_trie::{
|
use reth_trie::{
|
||||||
updates::{StorageTrieUpdates, TrieUpdates},
|
updates::{StorageTrieUpdates, TrieUpdates},
|
||||||
AccountProof, HashedPostState, HashedStorage, MultiProof, StorageProof, TrieInput,
|
AccountProof, HashedPostState, HashedStorage, MultiProof, StorageMultiProof, StorageProof,
|
||||||
|
TrieInput,
|
||||||
};
|
};
|
||||||
|
|
||||||
/// A type that can compute the state root of a given post state.
|
/// A type that can compute the state root of a given post state.
|
||||||
@ -56,6 +57,14 @@ pub trait StorageRootProvider: Send + Sync {
|
|||||||
slot: B256,
|
slot: B256,
|
||||||
hashed_storage: HashedStorage,
|
hashed_storage: HashedStorage,
|
||||||
) -> ProviderResult<StorageProof>;
|
) -> ProviderResult<StorageProof>;
|
||||||
|
|
||||||
|
/// Returns the storage multiproof for target slots.
|
||||||
|
fn storage_multiproof(
|
||||||
|
&self,
|
||||||
|
address: Address,
|
||||||
|
slots: &[B256],
|
||||||
|
hashed_storage: HashedStorage,
|
||||||
|
) -> ProviderResult<StorageMultiProof>;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// A type that can generate state proof on top of a given post state.
|
/// A type that can generate state proof on top of a given post state.
|
||||||
|
|||||||
@ -10,7 +10,7 @@ use reth_trie::{
|
|||||||
hashed_cursor::HashedPostStateCursorFactory,
|
hashed_cursor::HashedPostStateCursorFactory,
|
||||||
proof::{Proof, StorageProof},
|
proof::{Proof, StorageProof},
|
||||||
trie_cursor::InMemoryTrieCursorFactory,
|
trie_cursor::InMemoryTrieCursorFactory,
|
||||||
AccountProof, HashedPostStateSorted, HashedStorage, MultiProof, TrieInput,
|
AccountProof, HashedPostStateSorted, HashedStorage, MultiProof, StorageMultiProof, TrieInput,
|
||||||
};
|
};
|
||||||
|
|
||||||
/// Extends [`Proof`] with operations specific for working with a database transaction.
|
/// Extends [`Proof`] with operations specific for working with a database transaction.
|
||||||
@ -96,6 +96,14 @@ pub trait DatabaseStorageProof<'a, TX> {
|
|||||||
slot: B256,
|
slot: B256,
|
||||||
storage: HashedStorage,
|
storage: HashedStorage,
|
||||||
) -> Result<reth_trie::StorageProof, StateProofError>;
|
) -> 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>
|
impl<'a, TX: DbTx> DatabaseStorageProof<'a, TX>
|
||||||
@ -125,4 +133,26 @@ impl<'a, TX: DbTx> DatabaseStorageProof<'a, TX>
|
|||||||
.with_prefix_set_mut(prefix_set)
|
.with_prefix_set_mut(prefix_set)
|
||||||
.storage_proof(slot)
|
.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([(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)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user