feat: move StateRootProvider to StateProvider trait (#2392)

This commit is contained in:
Matthias Seitz
2023-04-25 19:52:46 +02:00
committed by GitHub
parent ccdaa74e41
commit 420a65a206
12 changed files with 77 additions and 47 deletions

View File

@ -91,4 +91,6 @@ pub enum ProviderError {
/// Thrown when we failed to lookup a block for the pending state
#[error("Unknown block hash: {0:}")]
UnknownBlockHash(H256),
#[error("Unable to compute state root on top of historical block")]
StateRootNotAvailableForHistoricalBlock,
}

View File

@ -600,7 +600,9 @@ mod tests {
constants::ETH_TO_WEI, hex_literal::hex, keccak256, Account, Address, BlockNumber,
Bytecode, Bytes, ChainSpecBuilder, ForkCondition, StorageKey, H256, MAINNET, U256,
};
use reth_provider::{post_state::Storage, AccountProvider, BlockHashProvider, StateProvider};
use reth_provider::{
post_state::Storage, AccountProvider, BlockHashProvider, StateProvider, StateRootProvider,
};
use reth_rlp::Decodable;
use std::{collections::HashMap, str::FromStr};
@ -655,6 +657,12 @@ mod tests {
}
}
impl StateRootProvider for StateProviderTest {
fn state_root(&self, _post_state: PostState) -> reth_interfaces::Result<H256> {
todo!()
}
}
impl StateProvider for StateProviderTest {
fn storage(
&self,

View File

@ -1174,13 +1174,10 @@ mod tests {
#[test]
fn post_state_state_root() {
let mut state: BTreeMap<Address, (Account, BTreeMap<H256, U256>)> = (0..10)
.into_iter()
.map(|key| {
let account = Account { nonce: 1, balance: U256::from(key), bytecode_hash: None };
let storage = (0..10)
.into_iter()
.map(|key| (H256::from_low_u64_be(key), U256::from(key)))
.collect();
let storage =
(0..10).map(|key| (H256::from_low_u64_be(key), U256::from(key))).collect();
(Address::from_low_u64_be(key), (account, storage))
})
.collect();
@ -1190,7 +1187,7 @@ mod tests {
// insert initial state to the database
db.update(|tx| {
for (address, (account, storage)) in state.iter() {
let hashed_address = keccak256(&address);
let hashed_address = keccak256(address);
tx.put::<tables::HashedAccount>(hashed_address, *account).unwrap();
for (slot, value) in storage {
tx.put::<tables::HashedStorage>(
@ -1240,7 +1237,7 @@ mod tests {
let slot_2 = U256::from(2);
let slot_2_key = H256(slot_2.to_be_bytes());
let address_2_slot_2_old_value =
state.get(&address_2).unwrap().1.get(&slot_2_key).unwrap().clone();
*state.get(&address_2).unwrap().1.get(&slot_2_key).unwrap();
let address_2_slot_2_new_value = U256::from(100);
state.get_mut(&address_2).unwrap().1.insert(slot_2_key, address_2_slot_2_new_value);
post_state.change_storage(
@ -1261,8 +1258,7 @@ mod tests {
// change balance of account 3
let address_3 = Address::from_low_u64_be(3);
let address_3_account_old = state.get(&address_3).unwrap().0;
let address_3_account_new =
Account { balance: U256::from(24), ..address_3_account_old.clone() };
let address_3_account_new = Account { balance: U256::from(24), ..address_3_account_old };
state.get_mut(&address_3).unwrap().0.balance = address_3_account_new.balance;
post_state.change_account(
block_number,
@ -1283,7 +1279,7 @@ mod tests {
// change nonce of account 4
let address_4 = Address::from_low_u64_be(4);
let address_4_account_old = state.get(&address_4).unwrap().0;
let address_4_account_new = Account { nonce: 128, ..address_4_account_old.clone() };
let address_4_account_new = Account { nonce: 128, ..address_4_account_old };
state.get_mut(&address_4).unwrap().0.nonce = address_4_account_new.nonce;
post_state.change_account(
block_number,

View File

@ -1,11 +1,11 @@
use crate::{
providers::state::{historical::HistoricalStateProvider, latest::LatestStateProvider},
traits::ReceiptProvider,
BlockHashProvider, BlockIdProvider, BlockProvider, EvmEnvProvider, HeaderProvider, PostState,
ProviderError, StateProviderBox, StateRootProvider, TransactionsProvider, WithdrawalsProvider,
BlockHashProvider, BlockIdProvider, BlockProvider, EvmEnvProvider, HeaderProvider,
ProviderError, StateProviderBox, TransactionsProvider, WithdrawalsProvider,
};
use reth_db::{cursor::DbCursorRO, database::Database, tables, transaction::DbTx};
use reth_interfaces::{Error, Result};
use reth_interfaces::Result;
use reth_primitives::{
Block, BlockHash, BlockId, BlockNumber, ChainInfo, ChainSpec, Hardfork, Head, Header, Receipt,
TransactionMeta, TransactionSigned, TxHash, TxNumber, Withdrawal, H256, U256,
@ -440,16 +440,6 @@ impl<DB: Database> EvmEnvProvider for ShareableDatabase<DB> {
}
}
impl<DB> StateRootProvider for ShareableDatabase<DB>
where
DB: Database,
{
fn state_root(&self, post_state: &PostState) -> Result<H256> {
let tx = self.db.tx()?;
post_state.state_root_slow(&tx).map_err(|err| Error::Database(err.into()))
}
}
#[cfg(test)]
mod tests {
use super::ShareableDatabase;

View File

@ -1,8 +1,8 @@
use crate::{
BlockHashProvider, BlockIdProvider, BlockProvider, BlockchainTreePendingStateProvider,
CanonStateNotifications, CanonStateSubscriptions, EvmEnvProvider, HeaderProvider, PostState,
CanonStateNotifications, CanonStateSubscriptions, EvmEnvProvider, HeaderProvider,
PostStateDataProvider, ReceiptProvider, StateProviderBox, StateProviderFactory,
StateRootProvider, TransactionsProvider, WithdrawalsProvider,
TransactionsProvider, WithdrawalsProvider,
};
use reth_db::database::Database;
use reth_interfaces::{
@ -290,16 +290,6 @@ where
}
}
impl<DB, Tree> StateRootProvider for BlockchainProvider<DB, Tree>
where
DB: Database,
Tree: Send + Sync,
{
fn state_root(&self, post_state: &PostState) -> Result<H256> {
self.database.state_root(post_state)
}
}
impl<DB, Tree> BlockchainTreeEngine for BlockchainProvider<DB, Tree>
where
DB: Send + Sync,

View File

@ -1,4 +1,7 @@
use crate::{AccountProvider, BlockHashProvider, PostStateDataProvider, StateProvider};
use crate::{
AccountProvider, BlockHashProvider, PostState, PostStateDataProvider, StateProvider,
StateRootProvider,
};
use reth_interfaces::{provider::ProviderError, Result};
use reth_primitives::{Account, Address, BlockNumber, Bytecode, Bytes, H256, U256};
@ -48,6 +51,16 @@ impl<SP: StateProvider, PSDP: PostStateDataProvider> AccountProvider
}
}
impl<SP: StateProvider, PSDP: PostStateDataProvider> StateRootProvider
for PostStateProvider<SP, PSDP>
{
fn state_root(&self, post_state: PostState) -> Result<H256> {
let mut state = self.post_state_data_provider.state().clone();
state.extend(post_state);
self.state_provider.state_root(state)
}
}
impl<SP: StateProvider, PSDP: PostStateDataProvider> StateProvider for PostStateProvider<SP, PSDP> {
fn storage(
&self,

View File

@ -1,6 +1,6 @@
use crate::{
providers::state::macros::delegate_provider_impls, AccountProvider, BlockHashProvider,
ProviderError, StateProvider,
PostState, ProviderError, StateProvider, StateRootProvider,
};
use reth_db::{
cursor::{DbCursorRO, DbDupCursorRO},
@ -92,6 +92,12 @@ impl<'a, 'b, TX: DbTx<'a>> BlockHashProvider for HistoricalStateProviderRef<'a,
}
}
impl<'a, 'b, TX: DbTx<'a>> StateRootProvider for HistoricalStateProviderRef<'a, 'b, TX> {
fn state_root(&self, _post_state: PostState) -> Result<H256> {
Err(ProviderError::StateRootNotAvailableForHistoricalBlock.into())
}
}
impl<'a, 'b, TX: DbTx<'a>> StateProvider for HistoricalStateProviderRef<'a, 'b, TX> {
/// Get storage.
fn storage(&self, address: Address, storage_key: StorageKey) -> Result<Option<StorageValue>> {

View File

@ -1,6 +1,6 @@
use crate::{
providers::state::macros::delegate_provider_impls, AccountProvider, BlockHashProvider,
StateProvider,
PostState, StateProvider, StateRootProvider,
};
use reth_db::{
cursor::{DbCursorRO, DbDupCursorRO},
@ -55,6 +55,14 @@ impl<'a, 'b, TX: DbTx<'a>> BlockHashProvider for LatestStateProviderRef<'a, 'b,
}
}
impl<'a, 'b, TX: DbTx<'a>> StateRootProvider for LatestStateProviderRef<'a, 'b, TX> {
fn state_root(&self, post_state: PostState) -> Result<H256> {
post_state
.state_root_slow(self.db)
.map_err(|err| reth_interfaces::Error::Database(err.into()))
}
}
impl<'a, 'b, TX: DbTx<'a>> StateProvider for LatestStateProviderRef<'a, 'b, TX> {
/// Get storage.
fn storage(&self, account: Address, storage_key: StorageKey) -> Result<Option<StorageValue>> {

View File

@ -30,6 +30,9 @@ macro_rules! delegate_provider_impls {
($target:ty $(where [$($generics:tt)*])?) => {
$crate::providers::state::macros::delegate_impls_to_as_ref!(
for $target =>
StateRootProvider $(where [$($generics)*])? {
fn state_root(&self, state: crate::PostState) -> reth_interfaces::Result<reth_primitives::H256>;
}
AccountProvider $(where [$($generics)*])? {
fn basic_account(&self, address: reth_primitives::Address) -> reth_interfaces::Result<Option<reth_primitives::Account>>;
}

View File

@ -1,7 +1,7 @@
use crate::{
traits::ReceiptProvider, AccountProvider, BlockHashProvider, BlockIdProvider, BlockProvider,
EvmEnvProvider, HeaderProvider, PostStateDataProvider, StateProvider, StateProviderBox,
StateProviderFactory, TransactionsProvider,
EvmEnvProvider, HeaderProvider, PostState, PostStateDataProvider, StateProvider,
StateProviderBox, StateProviderFactory, StateRootProvider, TransactionsProvider,
};
use parking_lot::Mutex;
use reth_interfaces::Result;
@ -267,6 +267,12 @@ impl AccountProvider for MockEthProvider {
}
}
impl StateRootProvider for MockEthProvider {
fn state_root(&self, _post_state: PostState) -> Result<H256> {
todo!()
}
}
impl StateProvider for MockEthProvider {
fn storage(&self, account: Address, storage_key: StorageKey) -> Result<Option<StorageValue>> {
let lock = self.accounts.lock();

View File

@ -1,7 +1,7 @@
use crate::{
traits::ReceiptProvider, AccountProvider, BlockHashProvider, BlockIdProvider, BlockProvider,
EvmEnvProvider, HeaderProvider, StateProvider, StateProviderBox, StateProviderFactory,
TransactionsProvider,
EvmEnvProvider, HeaderProvider, PostState, StateProvider, StateProviderBox,
StateProviderFactory, StateRootProvider, TransactionsProvider,
};
use reth_interfaces::Result;
use reth_primitives::{
@ -126,6 +126,12 @@ impl AccountProvider for NoopProvider {
}
}
impl StateRootProvider for NoopProvider {
fn state_root(&self, _post_state: PostState) -> Result<H256> {
todo!()
}
}
impl StateProvider for NoopProvider {
fn storage(&self, _account: Address, _storage_key: StorageKey) -> Result<Option<StorageValue>> {
Ok(None)

View File

@ -12,7 +12,9 @@ pub type StateProviderBox<'a> = Box<dyn StateProvider + 'a>;
/// An abstraction for a type that provides state data.
#[auto_impl(&, Arc, Box)]
pub trait StateProvider: BlockHashProvider + AccountProvider + Send + Sync {
pub trait StateProvider:
BlockHashProvider + AccountProvider + StateRootProvider + Send + Sync
{
/// Get storage of given account.
fn storage(&self, account: Address, storage_key: StorageKey) -> Result<Option<StorageValue>>;
@ -154,8 +156,8 @@ pub trait PostStateDataProvider: Send + Sync {
}
/// A type that can compute the state root of a given post state.
#[auto_impl[Box,&]]
#[auto_impl[Box,&, Arc]]
pub trait StateRootProvider: Send + Sync {
/// Returns the state root of the given block.
fn state_root(&self, post_state: &PostState) -> Result<H256>;
/// Returns the state root of the PostState on top of the current state.
fn state_root(&self, post_state: PostState) -> Result<H256>;
}