mirror of
https://github.com/hl-archive-node/nanoreth.git
synced 2025-12-06 10:59:55 +00:00
feat: move StateRootProvider to StateProvider trait (#2392)
This commit is contained in:
@ -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,
|
||||
}
|
||||
|
||||
@ -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,
|
||||
|
||||
@ -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,
|
||||
|
||||
@ -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;
|
||||
|
||||
@ -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,
|
||||
|
||||
@ -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,
|
||||
|
||||
@ -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>> {
|
||||
|
||||
@ -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>> {
|
||||
|
||||
@ -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>>;
|
||||
}
|
||||
|
||||
@ -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();
|
||||
|
||||
@ -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)
|
||||
|
||||
@ -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>;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user