Skip to content

Commit dad6d74

Browse files
authored
Introduce StateRootProviderExt and integrate StateRootProvider* with StateCommitment (#48)
* feat: introduce StateCommitment in StateProviders * refactor: introduce StateCommimentProvider * feat: introduce HashedPostStateProvider * feat: HashedPostState from reverts * feat: introduce HashedStorageProvider * lint: revm/test-utils feature propogation * fix: add Send + Sync bound on introduced storage state api methods * feat: introduce KeyHasherProvider * feat: introduce StateRootProviderExt and integrate it (and StateRootProvider) with StateCommitment * fix: add merge files * fix lint * fix lint * fmt * add KeyHasher generic to DatabaseHashedStorage::from_reverts trait * add merge files * add merge files * fix: propagate feature * fix: merge conflicts * reduce diff with upstream * remove clone requirement in blockchain_tree state root calculation
1 parent 59a1ccd commit dad6d74

File tree

31 files changed

+291
-152
lines changed

31 files changed

+291
-152
lines changed

Cargo.lock

Lines changed: 0 additions & 3 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

bin/reth/Cargo.toml

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -54,8 +54,6 @@ reth-payload-primitives.workspace = true
5454
reth-payload-validator.workspace = true
5555
reth-basic-payload-builder.workspace = true
5656
reth-static-file.workspace = true
57-
reth-trie = { workspace = true, features = ["metrics"] }
58-
reth-trie-db = { workspace = true, features = ["metrics"] }
5957
reth-node-api.workspace = true
6058
reth-node-core.workspace = true
6159
reth-ethereum-payload-builder.workspace = true

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

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -43,8 +43,6 @@ use reth_transaction_pool::{
4343
blobstore::InMemoryBlobStore, BlobStore, EthPooledTransaction, PoolConfig, TransactionOrigin,
4444
TransactionPool, TransactionValidationTaskExecutor,
4545
};
46-
use reth_trie::StateRoot;
47-
use reth_trie_db::DatabaseStateRoot;
4846
use std::{path::PathBuf, str::FromStr, sync::Arc};
4947
use tracing::*;
5048

@@ -273,10 +271,8 @@ impl<C: ChainSpecParser<ChainSpec = ChainSpec>> Command<C> {
273271
debug!(target: "reth::cli", ?execution_outcome, "Executed block");
274272

275273
let hashed_post_state = state_provider.hashed_post_state(execution_outcome.state());
276-
let (state_root, trie_updates) = StateRoot::overlay_root_with_updates(
277-
provider_factory.provider()?.tx_ref(),
278-
hashed_post_state.clone(),
279-
)?;
274+
let (state_root, trie_updates) =
275+
state_provider.state_root_from_state_with_updates(hashed_post_state.clone())?;
280276

281277
if state_root != block_with_senders.state_root {
282278
eyre::bail!(

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

Lines changed: 8 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -25,14 +25,12 @@ use reth_primitives::BlockExt;
2525
use reth_provider::{
2626
providers::ProviderNodeTypes, AccountExtReader, ChainSpecProvider, DatabaseProviderFactory,
2727
HashedPostStateProvider, HashingWriter, HeaderProvider, LatestStateProviderRef,
28-
OriginalValuesKnown, ProviderFactory, StageCheckpointReader, StateWriter, StorageLocation,
29-
StorageReader,
28+
OriginalValuesKnown, ProviderFactory, StageCheckpointReader, StateRootProvider,
29+
StateRootProviderExt, StateWriter, StorageLocation, StorageReader,
3030
};
3131
use reth_revm::database::StateProviderDatabase;
3232
use reth_stages::StageId;
3333
use reth_tasks::TaskExecutor;
34-
use reth_trie::StateRoot;
35-
use reth_trie_db::DatabaseStateRoot;
3634
use std::{path::PathBuf, sync::Arc};
3735
use tracing::*;
3836

@@ -164,10 +162,10 @@ impl<C: ChainSpecParser<ChainSpec = ChainSpec>> Command<C> {
164162
let execution_outcome = ExecutionOutcome::from((block_execution_output, block.number));
165163

166164
// Unpacked `BundleState::state_root_slow` function
167-
let (in_memory_state_root, in_memory_updates) = StateRoot::overlay_root_with_updates(
168-
provider.tx_ref(),
169-
state_provider.hashed_post_state(execution_outcome.state()),
170-
)?;
165+
let (in_memory_state_root, in_memory_updates) = state_provider
166+
.state_root_from_state_with_updates(
167+
state_provider.hashed_post_state(execution_outcome.state()),
168+
)?;
171169

172170
if in_memory_state_root == block.state_root {
173171
info!(target: "reth::cli", state_root = ?in_memory_state_root, "Computed in-memory state root matches");
@@ -195,10 +193,8 @@ impl<C: ChainSpecParser<ChainSpec = ChainSpec>> Command<C> {
195193
let accounts = provider_rw.basic_accounts(account_lists)?;
196194
provider_rw.insert_account_for_hashing(accounts)?;
197195

198-
let (state_root, incremental_trie_updates) = StateRoot::incremental_root_with_updates(
199-
provider_rw.tx_ref(),
200-
block.number..=block.number,
201-
)?;
196+
let (state_root, incremental_trie_updates) =
197+
state_provider.incremental_state_root_with_updates(block.number..=block.number)?;
202198
if state_root != block.state_root {
203199
eyre::bail!(
204200
"Computed incremental state root mismatch. Expected: {:?}. Got: {:?}",

crates/blockchain-tree/Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,6 @@ reth-provider.workspace = true
2424
reth-execution-types.workspace = true
2525
reth-stages-api.workspace = true
2626
reth-trie = { workspace = true, features = ["metrics"] }
27-
reth-trie-db = { workspace = true, features = ["metrics"] }
2827
reth-trie-parallel.workspace = true
2928
reth-network.workspace = true
3029
reth-consensus.workspace = true
@@ -58,6 +57,7 @@ reth-provider = { workspace = true, features = ["test-utils"] }
5857
reth-evm = { workspace = true, features = ["test-utils"] }
5958
reth-consensus = { workspace = true, features = ["test-utils"] }
6059
reth-testing-utils.workspace = true
60+
reth-trie-db = { workspace = true, features = ["test-utils"] }
6161
reth-revm.workspace = true
6262
reth-evm-ethereum.workspace = true
6363
reth-execution-types.workspace = true

crates/blockchain-tree/src/blockchain_tree.rs

Lines changed: 9 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -25,12 +25,11 @@ use reth_provider::{
2525
BlockExecutionWriter, BlockNumReader, BlockWriter, CanonStateNotification,
2626
CanonStateNotificationSender, CanonStateNotifications, ChainSpecProvider, ChainSplit,
2727
ChainSplitTarget, DBProvider, DisplayBlocksChain, HashedPostStateProvider, HeaderProvider,
28-
ProviderError, StaticFileProviderFactory, StorageLocation,
28+
LatestStateProviderRef, ProviderError, StateRootProviderExt, StaticFileProviderFactory,
29+
StorageLocation,
2930
};
3031
use reth_stages_api::{MetricEvent, MetricEventsSender};
3132
use reth_storage_errors::provider::{ProviderResult, RootMismatch};
32-
use reth_trie::{hashed_cursor::HashedPostStateCursorFactory, StateRoot};
33-
use reth_trie_db::{DatabaseHashedCursorFactory, DatabaseStateRoot};
3433
use std::{
3534
collections::{btree_map::Entry, BTreeMap, HashSet},
3635
sync::Arc,
@@ -1216,17 +1215,15 @@ where
12161215
) -> Result<(), CanonicalError> {
12171216
let (blocks, state, chain_trie_updates) = chain.into_inner();
12181217
let hashed_state = self.externals.provider_factory.hashed_post_state(state.state());
1219-
let prefix_sets = hashed_state.construct_prefix_sets().freeze();
1220-
let hashed_state_sorted = hashed_state.into_sorted();
12211218

12221219
// Compute state root or retrieve cached trie updates before opening write transaction.
12231220
let block_hash_numbers =
12241221
blocks.iter().map(|(number, b)| (number, b.hash())).collect::<Vec<_>>();
1225-
let trie_updates = match chain_trie_updates {
1222+
let (trie_updates, hashed_state_sorted) = match chain_trie_updates {
12261223
Some(updates) => {
12271224
debug!(target: "blockchain_tree", blocks = ?block_hash_numbers, "Using cached trie updates");
12281225
self.metrics.trie_updates_insert_cached.increment(1);
1229-
updates
1226+
(updates, hashed_state.into_sorted())
12301227
}
12311228
None => {
12321229
debug!(target: "blockchain_tree", blocks = ?block_hash_numbers, "Recomputing state root for insert");
@@ -1237,14 +1234,9 @@ where
12371234
// State root calculation can take a while, and we're sure no write transaction
12381235
// will be open in parallel. See https://github.com/paradigmxyz/reth/issues/6168.
12391236
.disable_long_read_transaction_safety();
1240-
let (state_root, trie_updates) = StateRoot::from_tx(provider.tx_ref())
1241-
.with_hashed_cursor_factory(HashedPostStateCursorFactory::new(
1242-
DatabaseHashedCursorFactory::new(provider.tx_ref()),
1243-
&hashed_state_sorted,
1244-
))
1245-
.with_prefix_sets(prefix_sets)
1246-
.root_with_updates()
1247-
.map_err(Into::<BlockValidationError>::into)?;
1237+
let (state_root, trie_updates, hashed_state_sorted) =
1238+
LatestStateProviderRef::new(&provider)
1239+
.state_root_from_state_with_updates_and_sorted_state(hashed_state)?;
12481240
let tip = blocks.tip();
12491241
if state_root != tip.state_root {
12501242
return Err(ProviderError::StateRootMismatch(Box::new(RootMismatch {
@@ -1255,7 +1247,7 @@ where
12551247
.into())
12561248
}
12571249
self.metrics.trie_updates_insert_recomputed.increment(1);
1258-
trie_updates
1250+
(trie_updates, hashed_state_sorted)
12591251
}
12601252
};
12611253
recorder.record_relative(MakeCanonicalAction::RetrieveStateTrieUpdates);
@@ -1402,6 +1394,7 @@ mod tests {
14021394
};
14031395
use reth_stages_api::StageCheckpoint;
14041396
use reth_trie::{root::state_root_unhashed, StateRoot};
1397+
use reth_trie_db::DatabaseStateRoot;
14051398
use revm::AccountInfo;
14061399
use std::collections::HashMap;
14071400

crates/blockchain-tree/src/chain.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -237,7 +237,7 @@ impl AppendableChain {
237237
.map_err(ProviderError::from)?
238238
} else {
239239
let hashed_state = provider.hashed_post_state(initial_execution_outcome.state());
240-
let state_root = provider.state_root(hashed_state)?;
240+
let state_root = provider.state_root_from_state(hashed_state)?;
241241
(state_root, None)
242242
};
243243
if block.state_root != state_root {

crates/chain-state/src/in_memory.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1027,15 +1027,15 @@ mod tests {
10271027
}
10281028

10291029
impl StateRootProvider for MockStateProvider {
1030-
fn state_root(&self, _hashed_state: HashedPostState) -> ProviderResult<B256> {
1030+
fn state_root_from_state(&self, _hashed_state: HashedPostState) -> ProviderResult<B256> {
10311031
Ok(B256::random())
10321032
}
10331033

10341034
fn state_root_from_nodes(&self, _input: TrieInput) -> ProviderResult<B256> {
10351035
Ok(B256::random())
10361036
}
10371037

1038-
fn state_root_with_updates(
1038+
fn state_root_from_state_with_updates(
10391039
&self,
10401040
_hashed_state: HashedPostState,
10411041
) -> ProviderResult<(B256, TrieUpdates)> {

crates/chain-state/src/memory_overlay.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -119,7 +119,7 @@ macro_rules! impl_state_provider {
119119
}
120120

121121
impl $($tokens)* StateRootProvider for $type {
122-
fn state_root(&self, state: HashedPostState) -> ProviderResult<B256> {
122+
fn state_root_from_state(&self, state: HashedPostState) -> ProviderResult<B256> {
123123
self.state_root_from_nodes(TrieInput::from_state(state))
124124
}
125125

@@ -129,7 +129,7 @@ macro_rules! impl_state_provider {
129129
self.historical.state_root_from_nodes(input)
130130
}
131131

132-
fn state_root_with_updates(
132+
fn state_root_from_state_with_updates(
133133
&self,
134134
state: HashedPostState,
135135
) -> ProviderResult<(B256, TrieUpdates)> {

crates/cli/commands/Cargo.toml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -45,8 +45,7 @@ reth-stages.workspace = true
4545
reth-stages-types = { workspace = true, optional = true }
4646
reth-static-file-types = { workspace = true, features = ["clap"] }
4747
reth-static-file.workspace = true
48-
reth-trie = { workspace = true, features = ["metrics"] }
49-
reth-trie-db = { workspace = true, features = ["metrics"] }
48+
reth-trie = { workspace = true, optional = true }
5049
reth-trie-common = { workspace = true, optional = true }
5150

5251
# ethereum
@@ -113,6 +112,7 @@ arbitrary = [
113112
"reth-codecs?/arbitrary",
114113
"reth-prune-types?/arbitrary",
115114
"reth-stages-types?/arbitrary",
115+
"reth-trie",
116116
"reth-trie-common?/arbitrary",
117117
"alloy-consensus/arbitrary",
118118
]

0 commit comments

Comments
 (0)