Skip to content

Commit 1996f4e

Browse files
authored
Introduce HashedPostStateProvider (#45)
* feat: introduce StateCommitment in StateProviders * refactor: introduce StateCommimentProvider * feat: introduce HashedPostStateProvider * feat: HashedPostState from reverts * lint: revm/test-utils feature propogation * fix: add Send + Sync bound on introduced storage state api methods * fix: add merge files * fix lint * fix lint * fmt * address PR feedback
1 parent fbf8e9e commit 1996f4e

File tree

48 files changed

+322
-148
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

48 files changed

+322
-148
lines changed

Cargo.lock

Lines changed: 1 addition & 4 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

bin/reth/src/commands/debug_cmd/build_block.rs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -261,7 +261,8 @@ impl<C: ChainSpecParser<ChainSpec = ChainSpec>> Command<C> {
261261
let block_with_senders =
262262
SealedBlockWithSenders::<BlockTy<N>>::new(block.clone(), senders).unwrap();
263263

264-
let db = StateProviderDatabase::new(blockchain_db.latest()?);
264+
let state_provider = blockchain_db.latest()?;
265+
let db = StateProviderDatabase::new(&state_provider);
265266
let executor =
266267
EthExecutorProvider::ethereum(provider_factory.chain_spec()).executor(db);
267268

@@ -271,7 +272,7 @@ impl<C: ChainSpecParser<ChainSpec = ChainSpec>> Command<C> {
271272
ExecutionOutcome::from((block_execution_output, block.number));
272273
debug!(target: "reth::cli", ?execution_outcome, "Executed block");
273274

274-
let hashed_post_state = execution_outcome.hash_state_slow();
275+
let hashed_post_state = state_provider.hashed_post_state(execution_outcome.state());
275276
let (state_root, trie_updates) = StateRoot::overlay_root_with_updates(
276277
provider_factory.provider()?.tx_ref(),
277278
hashed_post_state.clone(),

bin/reth/src/commands/debug_cmd/in_memory_merkle.rs

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -24,8 +24,9 @@ use reth_node_ethereum::EthExecutorProvider;
2424
use reth_primitives::BlockExt;
2525
use reth_provider::{
2626
providers::ProviderNodeTypes, AccountExtReader, ChainSpecProvider, DatabaseProviderFactory,
27-
HashingWriter, HeaderProvider, LatestStateProviderRef, OriginalValuesKnown, ProviderFactory,
28-
StageCheckpointReader, StateWriter, StorageLocation, StorageReader,
27+
HashedPostStateProvider, HashingWriter, HeaderProvider, LatestStateProviderRef,
28+
OriginalValuesKnown, ProviderFactory, StageCheckpointReader, StateWriter, StorageLocation,
29+
StorageReader,
2930
};
3031
use reth_revm::database::StateProviderDatabase;
3132
use reth_stages::StageId;
@@ -142,7 +143,8 @@ impl<C: ChainSpecParser<ChainSpec = ChainSpec>> Command<C> {
142143
)
143144
.await?;
144145

145-
let db = StateProviderDatabase::new(LatestStateProviderRef::new(&provider));
146+
let state_provider = LatestStateProviderRef::new(&provider);
147+
let db = StateProviderDatabase::new(&state_provider);
146148

147149
let executor = EthExecutorProvider::ethereum(provider_factory.chain_spec()).executor(db);
148150

@@ -164,7 +166,7 @@ impl<C: ChainSpecParser<ChainSpec = ChainSpec>> Command<C> {
164166
// Unpacked `BundleState::state_root_slow` function
165167
let (in_memory_state_root, in_memory_updates) = StateRoot::overlay_root_with_updates(
166168
provider.tx_ref(),
167-
execution_outcome.hash_state_slow(),
169+
state_provider.hashed_post_state(execution_outcome.state()),
168170
)?;
169171

170172
if in_memory_state_root == block.state_root {

crates/blockchain-tree/src/blockchain_tree.rs

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -24,8 +24,8 @@ use reth_primitives::{
2424
use reth_provider::{
2525
BlockExecutionWriter, BlockNumReader, BlockWriter, CanonStateNotification,
2626
CanonStateNotificationSender, CanonStateNotifications, ChainSpecProvider, ChainSplit,
27-
ChainSplitTarget, DBProvider, DisplayBlocksChain, HeaderProvider, ProviderError,
28-
StaticFileProviderFactory, StorageLocation,
27+
ChainSplitTarget, DBProvider, DisplayBlocksChain, HashedPostStateProvider, HeaderProvider,
28+
ProviderError, StaticFileProviderFactory, StorageLocation,
2929
};
3030
use reth_stages_api::{MetricEvent, MetricEventsSender};
3131
use reth_storage_errors::provider::{ProviderResult, RootMismatch};
@@ -1215,7 +1215,7 @@ where
12151215
recorder: &mut MakeCanonicalDurationsRecorder,
12161216
) -> Result<(), CanonicalError> {
12171217
let (blocks, state, chain_trie_updates) = chain.into_inner();
1218-
let hashed_state = state.hash_state_slow();
1218+
let hashed_state = self.externals.provider_factory.hashed_post_state(state.state());
12191219
let prefix_sets = hashed_state.construct_prefix_sets().freeze();
12201220
let hashed_state_sorted = hashed_state.into_sorted();
12211221

@@ -1880,7 +1880,12 @@ mod tests {
18801880
);
18811881

18821882
let provider = tree.externals.provider_factory.provider().unwrap();
1883-
let prefix_sets = exec5.hash_state_slow().construct_prefix_sets().freeze();
1883+
let prefix_sets = tree
1884+
.externals
1885+
.provider_factory
1886+
.hashed_post_state(exec5.state())
1887+
.construct_prefix_sets()
1888+
.freeze();
18841889
let state_root =
18851890
StateRoot::from_tx(provider.tx_ref()).with_prefix_sets(prefix_sets).root().unwrap();
18861891
assert_eq!(state_root, block5.state_root);

crates/blockchain-tree/src/chain.rs

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -18,10 +18,10 @@ use reth_execution_types::{Chain, ExecutionOutcome};
1818
use reth_primitives::{GotExpected, SealedBlockWithSenders, SealedHeader};
1919
use reth_provider::{
2020
providers::{BundleStateProvider, ConsistentDbView, ProviderNodeTypes},
21-
DBProvider, FullExecutionDataProvider, ProviderError, StateRootProvider,
22-
TryIntoHistoricalStateProvider,
21+
DBProvider, FullExecutionDataProvider, HashedPostStateProvider, ProviderError,
22+
StateRootProvider, TryIntoHistoricalStateProvider,
2323
};
24-
use reth_trie::{updates::TrieUpdates, HashedPostState, TrieInput};
24+
use reth_trie::{updates::TrieUpdates, TrieInput};
2525
use reth_trie_parallel::root::ParallelStateRoot;
2626
use std::{
2727
collections::BTreeMap,
@@ -230,14 +230,13 @@ impl AppendableChain {
230230
execution_outcome.extend(initial_execution_outcome.clone());
231231
ParallelStateRoot::new(
232232
consistent_view,
233-
TrieInput::from_state(execution_outcome.hash_state_slow()),
233+
TrieInput::from_state(provider.hashed_post_state(execution_outcome.state())),
234234
)
235235
.incremental_root_with_updates()
236236
.map(|(root, updates)| (root, Some(updates)))
237237
.map_err(ProviderError::from)?
238238
} else {
239-
let hashed_state =
240-
HashedPostState::from_bundle_state(&initial_execution_outcome.state().state);
239+
let hashed_state = provider.hashed_post_state(initial_execution_outcome.state());
241240
let state_root = provider.state_root(hashed_state)?;
242241
(state_root, None)
243242
};

crates/chain-state/Cargo.toml

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ reth-trie.workspace = true
2626
alloy-eips.workspace = true
2727
alloy-primitives.workspace = true
2828
alloy-consensus.workspace = true
29+
revm.workspace = true
2930

3031
# async
3132
tokio = { workspace = true, default-features = false, features = ["sync", "macros"] }
@@ -44,25 +45,22 @@ pin-project.workspace = true
4445
alloy-signer = { workspace = true, optional = true }
4546
alloy-signer-local = { workspace = true, optional = true }
4647
rand = { workspace = true, optional = true }
47-
revm = { workspace = true, optional = true }
4848

4949
[dev-dependencies]
5050
reth-testing-utils.workspace = true
5151
alloy-signer.workspace = true
5252
alloy-signer-local.workspace = true
5353
alloy-consensus.workspace = true
5454
rand.workspace = true
55-
revm.workspace = true
5655

5756
[features]
5857
test-utils = [
5958
"alloy-signer",
6059
"alloy-signer-local",
6160
"rand",
62-
"revm",
6361
"reth-chainspec/test-utils",
6462
"reth-primitives/test-utils",
6563
"reth-primitives-traits/test-utils",
6664
"reth-trie/test-utils",
67-
"revm?/test-utils",
65+
"revm/test-utils",
6866
]

crates/chain-state/src/in_memory.rs

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -949,8 +949,8 @@ mod tests {
949949
use reth_errors::ProviderResult;
950950
use reth_primitives::{Account, Bytecode, EthPrimitives, Receipt};
951951
use reth_storage_api::{
952-
AccountReader, BlockHashReader, StateProofProvider, StateProvider, StateRootProvider,
953-
StorageRootProvider,
952+
AccountReader, BlockHashReader, HashedPostStateProvider, StateProofProvider, StateProvider,
953+
StateRootProvider, StorageRootProvider,
954954
};
955955
use reth_trie::{
956956
AccountProof, HashedStorage, MultiProof, StorageMultiProof, StorageProof, TrieInput,
@@ -1047,6 +1047,12 @@ mod tests {
10471047
}
10481048
}
10491049

1050+
impl HashedPostStateProvider for MockStateProvider {
1051+
fn hashed_post_state(&self, _bundle_state: &revm::db::BundleState) -> HashedPostState {
1052+
HashedPostState::default()
1053+
}
1054+
}
1055+
10501056
impl StorageRootProvider for MockStateProvider {
10511057
fn storage_root(
10521058
&self,

crates/chain-state/src/memory_overlay.rs

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,13 +8,14 @@ use alloy_primitives::{
88
use reth_errors::ProviderResult;
99
use reth_primitives::{Account, Bytecode, NodePrimitives};
1010
use reth_storage_api::{
11-
AccountReader, BlockHashReader, StateProofProvider, StateProvider, StateRootProvider,
12-
StorageRootProvider,
11+
AccountReader, BlockHashReader, HashedPostStateProvider, StateProofProvider, StateProvider,
12+
StateRootProvider, StorageRootProvider,
1313
};
1414
use reth_trie::{
1515
updates::TrieUpdates, AccountProof, HashedPostState, HashedStorage, MultiProof,
1616
StorageMultiProof, TrieInput,
1717
};
18+
use revm::db::BundleState;
1819
use std::sync::OnceLock;
1920

2021
/// A state provider that stores references to in-memory blocks along with their state as well as a
@@ -218,6 +219,12 @@ macro_rules! impl_state_provider {
218219
}
219220
}
220221

222+
impl $($tokens)* HashedPostStateProvider for $type {
223+
fn hashed_post_state(&self, bundle_state: &BundleState) -> HashedPostState {
224+
self.historical.hashed_post_state(bundle_state)
225+
}
226+
}
227+
221228
impl $($tokens)* StateProvider for $type {
222229
fn storage(
223230
&self,

crates/engine/invalid-block-hooks/src/witness.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ use reth_revm::{
1818
use reth_rpc_api::DebugApiClient;
1919
use reth_scroll_execution::FinalizeExecution;
2020
use reth_tracing::tracing::warn;
21-
use reth_trie::{updates::TrieUpdates, HashedPostState, HashedStorage};
21+
use reth_trie::{updates::TrieUpdates, HashedStorage};
2222
use serde::Serialize;
2323
use std::{collections::HashMap, fmt::Debug, fs::File, io::Write, path::PathBuf};
2424

@@ -127,7 +127,7 @@ where
127127
//
128128
// Note: We grab *all* accounts in the cache here, as the `BundleState` prunes
129129
// referenced accounts + storage slots.
130-
let mut hashed_state = HashedPostState::from_bundle_state(&bundle_state.state);
130+
let mut hashed_state = db.database.hashed_post_state(&bundle_state);
131131
for (address, account) in db.cache.accounts {
132132
let hashed_address = keccak256(address);
133133
#[cfg(feature = "scroll")]

crates/engine/tree/src/tree/mod.rs

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -41,8 +41,8 @@ use reth_primitives::{
4141
};
4242
use reth_provider::{
4343
providers::ConsistentDbView, BlockReader, DatabaseProviderFactory, ExecutionOutcome,
44-
ProviderError, StateProviderBox, StateProviderFactory, StateReader, StateRootProvider,
45-
TransactionVariant,
44+
HashedPostStateProvider, ProviderError, StateCommitmentProvider, StateProviderBox,
45+
StateProviderFactory, StateReader, StateRootProvider, TransactionVariant,
4646
};
4747
use reth_revm::database::StateProviderDatabase;
4848
use reth_stages_api::ControlFlow;
@@ -545,6 +545,8 @@ where
545545
+ BlockReader<Block = reth_primitives::Block>
546546
+ StateProviderFactory
547547
+ StateReader<Receipt = reth_primitives::Receipt>
548+
+ StateCommitmentProvider
549+
+ HashedPostStateProvider
548550
+ Clone
549551
+ 'static,
550552
<P as DatabaseProviderFactory>::Provider: BlockReader,
@@ -1561,7 +1563,7 @@ where
15611563
.provider
15621564
.get_state(block.number())?
15631565
.ok_or_else(|| ProviderError::StateForNumberNotFound(block.number()))?;
1564-
let hashed_state = execution_output.hash_state_slow();
1566+
let hashed_state = self.provider.hashed_post_state(execution_output.state());
15651567

15661568
Ok(Some(ExecutedBlock {
15671569
block: Arc::new(block),
@@ -2235,7 +2237,7 @@ where
22352237
return Err(err.into())
22362238
}
22372239

2238-
let hashed_state = HashedPostState::from_bundle_state(&output.state.state);
2240+
let hashed_state = self.provider.hashed_post_state(&output.state);
22392241

22402242
trace!(target: "engine::tree", block=?sealed_block.num_hash(), "Calculating block state root");
22412243
let root_time = Instant::now();

0 commit comments

Comments
 (0)