refactor: use DBProvider in HistoricalStateProvider (#12556)

This commit is contained in:
Arsenii Kulikov
2024-11-15 00:57:31 +04:00
committed by GitHub
parent 28a5b631d1
commit a534db8714
2 changed files with 96 additions and 162 deletions

View File

@ -178,11 +178,7 @@ impl<TX: DbTx + 'static, N: NodeTypes> DatabaseProvider<TX, N> {
let storage_history_prune_checkpoint =
self.get_prune_checkpoint(PruneSegment::StorageHistory)?;
let mut state_provider = HistoricalStateProviderRef::new(
&self.tx,
block_number,
self.static_file_provider.clone(),
);
let mut state_provider = HistoricalStateProviderRef::new(self, block_number);
// If we pruned account or storage history, we can't return state on every historical block.
// Instead, we should cap it at the latest prune checkpoint for corresponding prune segment.
@ -259,8 +255,7 @@ impl<TX: DbTx + 'static, N: NodeTypes> TryIntoHistoricalStateProvider for Databa
let storage_history_prune_checkpoint =
self.get_prune_checkpoint(PruneSegment::StorageHistory)?;
let mut state_provider =
HistoricalStateProvider::new(self.tx, block_number, self.static_file_provider);
let mut state_provider = HistoricalStateProvider::new(self, block_number);
// If we pruned account or storage history, we can't return state on every historical block.
// Instead, we should cap it at the latest prune checkpoint for corresponding prune segment.

View File

@ -1,6 +1,6 @@
use crate::{
providers::{state::macros::delegate_provider_impls, StaticFileProvider},
AccountReader, BlockHashReader, ProviderError, StateProvider, StateRootProvider,
providers::state::macros::delegate_provider_impls, AccountReader, BlockHashReader,
ProviderError, StateProvider, StateRootProvider,
};
use alloy_eips::merge::EPOCH_SLOTS;
use alloy_primitives::{
@ -14,8 +14,8 @@ use reth_db_api::{
table::Table,
transaction::DbTx,
};
use reth_primitives::{Account, Bytecode, StaticFileSegment};
use reth_storage_api::{StateProofProvider, StorageRootProvider};
use reth_primitives::{Account, Bytecode};
use reth_storage_api::{BlockNumReader, DBProvider, StateProofProvider, StorageRootProvider};
use reth_storage_errors::provider::ProviderResult;
use reth_trie::{
proof::{Proof, StorageProof},
@ -41,15 +41,13 @@ use std::fmt::Debug;
/// - [`tables::AccountChangeSets`]
/// - [`tables::StorageChangeSets`]
#[derive(Debug)]
pub struct HistoricalStateProviderRef<'b, TX: DbTx> {
/// Transaction
tx: &'b TX,
pub struct HistoricalStateProviderRef<'b, Provider> {
/// Database provider
provider: &'b Provider,
/// Block number is main index for the history state of accounts and storages.
block_number: BlockNumber,
/// Lowest blocks at which different parts of the state are available.
lowest_available_blocks: LowestAvailableBlocks,
/// Static File provider
static_file_provider: StaticFileProvider,
}
#[derive(Debug, Eq, PartialEq)]
@ -60,25 +58,20 @@ pub enum HistoryInfo {
MaybeInPlainState,
}
impl<'b, TX: DbTx> HistoricalStateProviderRef<'b, TX> {
impl<'b, Provider: DBProvider + BlockNumReader> HistoricalStateProviderRef<'b, Provider> {
/// Create new `StateProvider` for historical block number
pub fn new(
tx: &'b TX,
block_number: BlockNumber,
static_file_provider: StaticFileProvider,
) -> Self {
Self { tx, block_number, lowest_available_blocks: Default::default(), static_file_provider }
pub fn new(provider: &'b Provider, block_number: BlockNumber) -> Self {
Self { provider, block_number, lowest_available_blocks: Default::default() }
}
/// Create new `StateProvider` for historical block number and lowest block numbers at which
/// account & storage histories are available.
pub const fn new_with_lowest_available_blocks(
tx: &'b TX,
provider: &'b Provider,
block_number: BlockNumber,
lowest_available_blocks: LowestAvailableBlocks,
static_file_provider: StaticFileProvider,
) -> Self {
Self { tx, block_number, lowest_available_blocks, static_file_provider }
Self { provider, block_number, lowest_available_blocks }
}
/// Lookup an account in the `AccountsHistory` table
@ -117,15 +110,7 @@ impl<'b, TX: DbTx> HistoricalStateProviderRef<'b, TX> {
/// Checks and returns `true` if distance to historical block exceeds the provided limit.
fn check_distance_against_limit(&self, limit: u64) -> ProviderResult<bool> {
let tip = self
.tx
.cursor_read::<tables::CanonicalHeaders>()?
.last()?
.map(|(tip, _)| tip)
.or_else(|| {
self.static_file_provider.get_highest_static_file_block(StaticFileSegment::Headers)
})
.ok_or(ProviderError::BestBlockNotFound)?;
let tip = self.provider.last_block_number()?;
Ok(tip.saturating_sub(self.block_number) > limit)
}
@ -146,7 +131,7 @@ impl<'b, TX: DbTx> HistoricalStateProviderRef<'b, TX> {
);
}
Ok(HashedPostState::from_reverts(self.tx, self.block_number)?)
Ok(HashedPostState::from_reverts(self.tx(), self.block_number)?)
}
/// Retrieve revert hashed storage for this history provider and target address.
@ -163,7 +148,7 @@ impl<'b, TX: DbTx> HistoricalStateProviderRef<'b, TX> {
);
}
Ok(HashedStorage::from_reverts(self.tx, address, self.block_number)?)
Ok(HashedStorage::from_reverts(self.tx(), address, self.block_number)?)
}
fn history_info<T, K>(
@ -175,7 +160,7 @@ impl<'b, TX: DbTx> HistoricalStateProviderRef<'b, TX> {
where
T: Table<Key = K, Value = BlockNumberList>,
{
let mut cursor = self.tx.cursor_read::<T>()?;
let mut cursor = self.tx().cursor_read::<T>()?;
// Lookup the history chunk in the history index. If they key does not appear in the
// index, the first chunk for the next key will be returned so we filter out chunks that
@ -248,13 +233,21 @@ impl<'b, TX: DbTx> HistoricalStateProviderRef<'b, TX> {
}
}
impl<TX: DbTx> AccountReader for HistoricalStateProviderRef<'_, TX> {
impl<Provider: DBProvider + BlockNumReader> HistoricalStateProviderRef<'_, Provider> {
fn tx(&self) -> &Provider::Tx {
self.provider.tx_ref()
}
}
impl<Provider: DBProvider + BlockNumReader> AccountReader
for HistoricalStateProviderRef<'_, Provider>
{
/// Get basic account information.
fn basic_account(&self, address: Address) -> ProviderResult<Option<Account>> {
match self.account_history_lookup(address)? {
HistoryInfo::NotYetWritten => Ok(None),
HistoryInfo::InChangeset(changeset_block_number) => Ok(self
.tx
.tx()
.cursor_dup_read::<tables::AccountChangeSets>()?
.seek_by_key_subkey(changeset_block_number, address)?
.filter(|acc| acc.address == address)
@ -264,21 +257,18 @@ impl<TX: DbTx> AccountReader for HistoricalStateProviderRef<'_, TX> {
})?
.info),
HistoryInfo::InPlainState | HistoryInfo::MaybeInPlainState => {
Ok(self.tx.get::<tables::PlainAccountState>(address)?)
Ok(self.tx().get::<tables::PlainAccountState>(address)?)
}
}
}
}
impl<TX: DbTx> BlockHashReader for HistoricalStateProviderRef<'_, TX> {
impl<Provider: DBProvider + BlockNumReader + BlockHashReader> BlockHashReader
for HistoricalStateProviderRef<'_, Provider>
{
/// Get block hash by number.
fn block_hash(&self, number: u64) -> ProviderResult<Option<B256>> {
self.static_file_provider.get_with_static_file_or_database(
StaticFileSegment::Headers,
number,
|static_file| static_file.block_hash(number),
|| Ok(self.tx.get::<tables::CanonicalHeaders>(number)?),
)
self.provider.block_hash(number)
}
fn canonical_hashes_range(
@ -286,37 +276,23 @@ impl<TX: DbTx> BlockHashReader for HistoricalStateProviderRef<'_, TX> {
start: BlockNumber,
end: BlockNumber,
) -> ProviderResult<Vec<B256>> {
self.static_file_provider.get_range_with_static_file_or_database(
StaticFileSegment::Headers,
start..end,
|static_file, range, _| static_file.canonical_hashes_range(range.start, range.end),
|range, _| {
self.tx
.cursor_read::<tables::CanonicalHeaders>()
.map(|mut cursor| {
cursor
.walk_range(range)?
.map(|result| result.map(|(_, hash)| hash).map_err(Into::into))
.collect::<ProviderResult<Vec<_>>>()
})?
.map_err(Into::into)
},
|_| true,
)
self.provider.canonical_hashes_range(start, end)
}
}
impl<TX: DbTx> StateRootProvider for HistoricalStateProviderRef<'_, TX> {
impl<Provider: DBProvider + BlockNumReader> StateRootProvider
for HistoricalStateProviderRef<'_, Provider>
{
fn state_root(&self, hashed_state: HashedPostState) -> ProviderResult<B256> {
let mut revert_state = self.revert_state()?;
revert_state.extend(hashed_state);
StateRoot::overlay_root(self.tx, revert_state)
StateRoot::overlay_root(self.tx(), revert_state)
.map_err(|err| ProviderError::Database(err.into()))
}
fn state_root_from_nodes(&self, mut input: TrieInput) -> ProviderResult<B256> {
input.prepend(self.revert_state()?);
StateRoot::overlay_root_from_nodes(self.tx, input)
StateRoot::overlay_root_from_nodes(self.tx(), input)
.map_err(|err| ProviderError::Database(err.into()))
}
@ -326,7 +302,7 @@ impl<TX: DbTx> StateRootProvider for HistoricalStateProviderRef<'_, TX> {
) -> ProviderResult<(B256, TrieUpdates)> {
let mut revert_state = self.revert_state()?;
revert_state.extend(hashed_state);
StateRoot::overlay_root_with_updates(self.tx, revert_state)
StateRoot::overlay_root_with_updates(self.tx(), revert_state)
.map_err(|err| ProviderError::Database(err.into()))
}
@ -335,12 +311,14 @@ impl<TX: DbTx> StateRootProvider for HistoricalStateProviderRef<'_, TX> {
mut input: TrieInput,
) -> ProviderResult<(B256, TrieUpdates)> {
input.prepend(self.revert_state()?);
StateRoot::overlay_root_from_nodes_with_updates(self.tx, input)
StateRoot::overlay_root_from_nodes_with_updates(self.tx(), input)
.map_err(|err| ProviderError::Database(err.into()))
}
}
impl<TX: DbTx> StorageRootProvider for HistoricalStateProviderRef<'_, TX> {
impl<Provider: DBProvider + BlockNumReader> StorageRootProvider
for HistoricalStateProviderRef<'_, Provider>
{
fn storage_root(
&self,
address: Address,
@ -348,7 +326,7 @@ impl<TX: DbTx> StorageRootProvider for HistoricalStateProviderRef<'_, TX> {
) -> ProviderResult<B256> {
let mut revert_storage = self.revert_storage(address)?;
revert_storage.extend(&hashed_storage);
StorageRoot::overlay_root(self.tx, address, revert_storage)
StorageRoot::overlay_root(self.tx(), address, revert_storage)
.map_err(|err| ProviderError::Database(err.into()))
}
@ -360,12 +338,14 @@ impl<TX: DbTx> StorageRootProvider for HistoricalStateProviderRef<'_, TX> {
) -> ProviderResult<reth_trie::StorageProof> {
let mut revert_storage = self.revert_storage(address)?;
revert_storage.extend(&hashed_storage);
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)
}
}
impl<TX: DbTx> StateProofProvider for HistoricalStateProviderRef<'_, TX> {
impl<Provider: DBProvider + BlockNumReader> StateProofProvider
for HistoricalStateProviderRef<'_, Provider>
{
/// Get account and storage proofs.
fn proof(
&self,
@ -374,7 +354,7 @@ impl<TX: DbTx> StateProofProvider for HistoricalStateProviderRef<'_, TX> {
slots: &[B256],
) -> ProviderResult<AccountProof> {
input.prepend(self.revert_state()?);
Proof::overlay_account_proof(self.tx, input, address, slots)
Proof::overlay_account_proof(self.tx(), input, address, slots)
.map_err(Into::<ProviderError>::into)
}
@ -384,7 +364,7 @@ impl<TX: DbTx> StateProofProvider for HistoricalStateProviderRef<'_, TX> {
targets: HashMap<B256, HashSet<B256>>,
) -> ProviderResult<MultiProof> {
input.prepend(self.revert_state()?);
Proof::overlay_multiproof(self.tx, input, targets).map_err(Into::<ProviderError>::into)
Proof::overlay_multiproof(self.tx(), input, targets).map_err(Into::<ProviderError>::into)
}
fn witness(
@ -393,11 +373,13 @@ impl<TX: DbTx> StateProofProvider for HistoricalStateProviderRef<'_, TX> {
target: HashedPostState,
) -> ProviderResult<HashMap<B256, Bytes>> {
input.prepend(self.revert_state()?);
TrieWitness::overlay_witness(self.tx, input, target).map_err(Into::<ProviderError>::into)
TrieWitness::overlay_witness(self.tx(), input, target).map_err(Into::<ProviderError>::into)
}
}
impl<TX: DbTx> StateProvider for HistoricalStateProviderRef<'_, TX> {
impl<Provider: DBProvider + BlockNumReader + BlockHashReader> StateProvider
for HistoricalStateProviderRef<'_, Provider>
{
/// Get storage.
fn storage(
&self,
@ -407,7 +389,7 @@ impl<TX: DbTx> StateProvider for HistoricalStateProviderRef<'_, TX> {
match self.storage_history_lookup(address, storage_key)? {
HistoryInfo::NotYetWritten => Ok(None),
HistoryInfo::InChangeset(changeset_block_number) => Ok(Some(
self.tx
self.tx()
.cursor_dup_read::<tables::StorageChangeSets>()?
.seek_by_key_subkey((changeset_block_number, address).into(), storage_key)?
.filter(|entry| entry.key == storage_key)
@ -419,7 +401,7 @@ impl<TX: DbTx> StateProvider for HistoricalStateProviderRef<'_, TX> {
.value,
)),
HistoryInfo::InPlainState | HistoryInfo::MaybeInPlainState => Ok(self
.tx
.tx()
.cursor_dup_read::<tables::PlainStorageState>()?
.seek_by_key_subkey(address, storage_key)?
.filter(|entry| entry.key == storage_key)
@ -430,32 +412,26 @@ impl<TX: DbTx> StateProvider for HistoricalStateProviderRef<'_, TX> {
/// Get account code by its hash
fn bytecode_by_hash(&self, code_hash: B256) -> ProviderResult<Option<Bytecode>> {
self.tx.get::<tables::Bytecodes>(code_hash).map_err(Into::into)
self.tx().get::<tables::Bytecodes>(code_hash).map_err(Into::into)
}
}
/// State provider for a given block number.
/// For more detailed description, see [`HistoricalStateProviderRef`].
#[derive(Debug)]
pub struct HistoricalStateProvider<TX: DbTx> {
/// Database transaction
tx: TX,
pub struct HistoricalStateProvider<Provider> {
/// Database provider.
provider: Provider,
/// State at the block number is the main indexer of the state.
block_number: BlockNumber,
/// Lowest blocks at which different parts of the state are available.
lowest_available_blocks: LowestAvailableBlocks,
/// Static File provider
static_file_provider: StaticFileProvider,
}
impl<TX: DbTx> HistoricalStateProvider<TX> {
impl<Provider: DBProvider + BlockNumReader> HistoricalStateProvider<Provider> {
/// Create new `StateProvider` for historical block number
pub fn new(
tx: TX,
block_number: BlockNumber,
static_file_provider: StaticFileProvider,
) -> Self {
Self { tx, block_number, lowest_available_blocks: Default::default(), static_file_provider }
pub fn new(provider: Provider, block_number: BlockNumber) -> Self {
Self { provider, block_number, lowest_available_blocks: Default::default() }
}
/// Set the lowest block number at which the account history is available.
@ -478,18 +454,17 @@ impl<TX: DbTx> HistoricalStateProvider<TX> {
/// Returns a new provider that takes the `TX` as reference
#[inline(always)]
fn as_ref(&self) -> HistoricalStateProviderRef<'_, TX> {
const fn as_ref(&self) -> HistoricalStateProviderRef<'_, Provider> {
HistoricalStateProviderRef::new_with_lowest_available_blocks(
&self.tx,
&self.provider,
self.block_number,
self.lowest_available_blocks,
self.static_file_provider.clone(),
)
}
}
// Delegates all provider impls to [HistoricalStateProviderRef]
delegate_provider_impls!(HistoricalStateProvider<TX> where [TX: DbTx]);
delegate_provider_impls!(HistoricalStateProvider<Provider> where [Provider: DBProvider + BlockNumReader + BlockHashReader]);
/// Lowest blocks at which different parts of the state are available.
/// They may be [Some] if pruning is enabled.
@ -525,7 +500,6 @@ mod tests {
providers::state::historical::{HistoryInfo, LowestAvailableBlocks},
test_utils::create_test_provider_factory,
AccountReader, HistoricalStateProvider, HistoricalStateProviderRef, StateProvider,
StaticFileProviderFactory,
};
use alloy_primitives::{address, b256, Address, B256, U256};
use reth_db::{tables, BlockNumberList};
@ -534,6 +508,7 @@ mod tests {
transaction::{DbTx, DbTxMut},
};
use reth_primitives::{Account, StorageEntry};
use reth_storage_api::{BlockHashReader, BlockNumReader, DBProvider, DatabaseProviderFactory};
use reth_storage_errors::provider::ProviderError;
const ADDRESS: Address = address!("0000000000000000000000000000000000000001");
@ -542,7 +517,7 @@ mod tests {
const fn assert_state_provider<T: StateProvider>() {}
#[allow(dead_code)]
const fn assert_historical_state_provider<T: DbTx>() {
const fn assert_historical_state_provider<T: DBProvider + BlockNumReader + BlockHashReader>() {
assert_state_provider::<HistoricalStateProvider<T>>();
}
@ -550,7 +525,6 @@ mod tests {
fn history_provider_get_account() {
let factory = create_test_provider_factory();
let tx = factory.provider_rw().unwrap().into_tx();
let static_file_provider = factory.static_file_provider();
tx.put::<tables::AccountsHistory>(
ShardedKey { key: ADDRESS, highest_block_number: 7 },
@ -610,63 +584,46 @@ mod tests {
tx.put::<tables::PlainAccountState>(HIGHER_ADDRESS, higher_acc_plain).unwrap();
tx.commit().unwrap();
let tx = factory.provider().unwrap().into_tx();
let db = factory.provider().unwrap();
// run
assert_eq!(HistoricalStateProviderRef::new(&db, 1).basic_account(ADDRESS), Ok(None));
assert_eq!(
HistoricalStateProviderRef::new(&tx, 1, static_file_provider.clone())
.basic_account(ADDRESS),
Ok(None)
);
assert_eq!(
HistoricalStateProviderRef::new(&tx, 2, static_file_provider.clone())
.basic_account(ADDRESS),
HistoricalStateProviderRef::new(&db, 2).basic_account(ADDRESS),
Ok(Some(acc_at3))
);
assert_eq!(
HistoricalStateProviderRef::new(&tx, 3, static_file_provider.clone())
.basic_account(ADDRESS),
HistoricalStateProviderRef::new(&db, 3).basic_account(ADDRESS),
Ok(Some(acc_at3))
);
assert_eq!(
HistoricalStateProviderRef::new(&tx, 4, static_file_provider.clone())
.basic_account(ADDRESS),
HistoricalStateProviderRef::new(&db, 4).basic_account(ADDRESS),
Ok(Some(acc_at7))
);
assert_eq!(
HistoricalStateProviderRef::new(&tx, 7, static_file_provider.clone())
.basic_account(ADDRESS),
HistoricalStateProviderRef::new(&db, 7).basic_account(ADDRESS),
Ok(Some(acc_at7))
);
assert_eq!(
HistoricalStateProviderRef::new(&tx, 9, static_file_provider.clone())
.basic_account(ADDRESS),
HistoricalStateProviderRef::new(&db, 9).basic_account(ADDRESS),
Ok(Some(acc_at10))
);
assert_eq!(
HistoricalStateProviderRef::new(&tx, 10, static_file_provider.clone())
.basic_account(ADDRESS),
HistoricalStateProviderRef::new(&db, 10).basic_account(ADDRESS),
Ok(Some(acc_at10))
);
assert_eq!(
HistoricalStateProviderRef::new(&tx, 11, static_file_provider.clone())
.basic_account(ADDRESS),
HistoricalStateProviderRef::new(&db, 11).basic_account(ADDRESS),
Ok(Some(acc_at15))
);
assert_eq!(
HistoricalStateProviderRef::new(&tx, 16, static_file_provider.clone())
.basic_account(ADDRESS),
HistoricalStateProviderRef::new(&db, 16).basic_account(ADDRESS),
Ok(Some(acc_plain))
);
assert_eq!(HistoricalStateProviderRef::new(&db, 1).basic_account(HIGHER_ADDRESS), Ok(None));
assert_eq!(
HistoricalStateProviderRef::new(&tx, 1, static_file_provider.clone())
.basic_account(HIGHER_ADDRESS),
Ok(None)
);
assert_eq!(
HistoricalStateProviderRef::new(&tx, 1000, static_file_provider)
.basic_account(HIGHER_ADDRESS),
HistoricalStateProviderRef::new(&db, 1000).basic_account(HIGHER_ADDRESS),
Ok(Some(higher_acc_plain))
);
}
@ -675,7 +632,6 @@ mod tests {
fn history_provider_get_storage() {
let factory = create_test_provider_factory();
let tx = factory.provider_rw().unwrap().into_tx();
let static_file_provider = factory.static_file_provider();
tx.put::<tables::StoragesHistory>(
StorageShardedKey {
@ -722,57 +678,44 @@ mod tests {
tx.put::<tables::PlainStorageState>(HIGHER_ADDRESS, higher_entry_plain).unwrap();
tx.commit().unwrap();
let tx = factory.provider().unwrap().into_tx();
let db = factory.provider().unwrap();
// run
assert_eq!(HistoricalStateProviderRef::new(&db, 0).storage(ADDRESS, STORAGE), Ok(None));
assert_eq!(
HistoricalStateProviderRef::new(&tx, 0, static_file_provider.clone())
.storage(ADDRESS, STORAGE),
Ok(None)
);
assert_eq!(
HistoricalStateProviderRef::new(&tx, 3, static_file_provider.clone())
.storage(ADDRESS, STORAGE),
HistoricalStateProviderRef::new(&db, 3).storage(ADDRESS, STORAGE),
Ok(Some(U256::ZERO))
);
assert_eq!(
HistoricalStateProviderRef::new(&tx, 4, static_file_provider.clone())
.storage(ADDRESS, STORAGE),
HistoricalStateProviderRef::new(&db, 4).storage(ADDRESS, STORAGE),
Ok(Some(entry_at7.value))
);
assert_eq!(
HistoricalStateProviderRef::new(&tx, 7, static_file_provider.clone())
.storage(ADDRESS, STORAGE),
HistoricalStateProviderRef::new(&db, 7).storage(ADDRESS, STORAGE),
Ok(Some(entry_at7.value))
);
assert_eq!(
HistoricalStateProviderRef::new(&tx, 9, static_file_provider.clone())
.storage(ADDRESS, STORAGE),
HistoricalStateProviderRef::new(&db, 9).storage(ADDRESS, STORAGE),
Ok(Some(entry_at10.value))
);
assert_eq!(
HistoricalStateProviderRef::new(&tx, 10, static_file_provider.clone())
.storage(ADDRESS, STORAGE),
HistoricalStateProviderRef::new(&db, 10).storage(ADDRESS, STORAGE),
Ok(Some(entry_at10.value))
);
assert_eq!(
HistoricalStateProviderRef::new(&tx, 11, static_file_provider.clone())
.storage(ADDRESS, STORAGE),
HistoricalStateProviderRef::new(&db, 11).storage(ADDRESS, STORAGE),
Ok(Some(entry_at15.value))
);
assert_eq!(
HistoricalStateProviderRef::new(&tx, 16, static_file_provider.clone())
.storage(ADDRESS, STORAGE),
HistoricalStateProviderRef::new(&db, 16).storage(ADDRESS, STORAGE),
Ok(Some(entry_plain.value))
);
assert_eq!(
HistoricalStateProviderRef::new(&tx, 1, static_file_provider.clone())
.storage(HIGHER_ADDRESS, STORAGE),
HistoricalStateProviderRef::new(&db, 1).storage(HIGHER_ADDRESS, STORAGE),
Ok(None)
);
assert_eq!(
HistoricalStateProviderRef::new(&tx, 1000, static_file_provider)
.storage(HIGHER_ADDRESS, STORAGE),
HistoricalStateProviderRef::new(&db, 1000).storage(HIGHER_ADDRESS, STORAGE),
Ok(Some(higher_entry_plain.value))
);
}
@ -780,19 +723,17 @@ mod tests {
#[test]
fn history_provider_unavailable() {
let factory = create_test_provider_factory();
let tx = factory.provider_rw().unwrap().into_tx();
let static_file_provider = factory.static_file_provider();
let db = factory.database_provider_rw().unwrap();
// provider block_number < lowest available block number,
// i.e. state at provider block is pruned
let provider = HistoricalStateProviderRef::new_with_lowest_available_blocks(
&tx,
&db,
2,
LowestAvailableBlocks {
account_history_block_number: Some(3),
storage_history_block_number: Some(3),
},
static_file_provider.clone(),
);
assert_eq!(
provider.account_history_lookup(ADDRESS),
@ -806,13 +747,12 @@ mod tests {
// provider block_number == lowest available block number,
// i.e. state at provider block is available
let provider = HistoricalStateProviderRef::new_with_lowest_available_blocks(
&tx,
&db,
2,
LowestAvailableBlocks {
account_history_block_number: Some(2),
storage_history_block_number: Some(2),
},
static_file_provider.clone(),
);
assert_eq!(provider.account_history_lookup(ADDRESS), Ok(HistoryInfo::MaybeInPlainState));
assert_eq!(
@ -823,13 +763,12 @@ mod tests {
// provider block_number == lowest available block number,
// i.e. state at provider block is available
let provider = HistoricalStateProviderRef::new_with_lowest_available_blocks(
&tx,
&db,
2,
LowestAvailableBlocks {
account_history_block_number: Some(1),
storage_history_block_number: Some(1),
},
static_file_provider,
);
assert_eq!(provider.account_history_lookup(ADDRESS), Ok(HistoryInfo::MaybeInPlainState));
assert_eq!(