fix: make ChainState provider work for Box<dyn StateProvider> (#1755)

This commit is contained in:
Matthias Seitz
2023-03-15 01:58:14 +01:00
committed by GitHub
parent 46c96a1466
commit 4725c4d776
3 changed files with 23 additions and 24 deletions

View File

@@ -348,7 +348,7 @@ mod tests {
let mut block1 = block.clone();
let mut block2 = block.clone();
let mut block3 = block.clone();
let mut block4 = block.clone();
let mut block4 = block;
block1.block.header.hash = block1_hash;
block2.block.header.hash = block2_hash;
@@ -360,13 +360,13 @@ mod tests {
let mut chain1 = Chain {
substate: Default::default(),
changesets: vec![],
blocks: BTreeMap::from([(1, block1.clone()), (2, block2.clone())]),
blocks: BTreeMap::from([(1, block1), (2, block2)]),
};
let chain2 = Chain {
substate: Default::default(),
changesets: vec![],
blocks: BTreeMap::from([(3, block3.clone()), (4, block4.clone())]),
blocks: BTreeMap::from([(3, block3), (4, block4)]),
};
assert_eq!(chain1.append_chain(chain2.clone()), Ok(()));
@@ -418,7 +418,7 @@ mod tests {
// split in two
assert_eq!(
chain.clone().split(SplitAt::Hash(block1_hash)),
ChainSplit::Split { canonical: chain_split1.clone(), pending: chain_split2.clone() }
ChainSplit::Split { canonical: chain_split1, pending: chain_split2 }
);
// split at unknown block hash
@@ -433,9 +433,6 @@ mod tests {
ChainSplit::NoSplitCanonical(chain.clone())
);
// split at lower number
assert_eq!(
chain.clone().split(SplitAt::Number(0)),
ChainSplit::NoSplitPending(chain.clone())
);
assert_eq!(chain.clone().split(SplitAt::Number(0)), ChainSplit::NoSplitPending(chain));
}
}

View File

@@ -11,8 +11,8 @@ use reth_db::{cursor::DbCursorRO, database::Database, tables, transaction::DbTx}
use reth_interfaces::{consensus::Consensus, executor::Error as ExecError, Error};
use reth_primitives::{BlockHash, BlockNumber, ChainSpec, SealedBlock, SealedBlockWithSenders};
use reth_provider::{
ExecutorFactory, HeaderProvider, ShareableDatabase, StateProvider, StateProviderFactory,
Transaction,
providers::ChainState, ExecutorFactory, HeaderProvider, ShareableDatabase,
StateProviderFactory, Transaction,
};
use std::{
collections::{BTreeMap, HashMap},
@@ -177,9 +177,9 @@ impl<DB: Database, C: Consensus, EF: ExecutorFactory> BlockchainTree<DB, C, EF>
let db = self.externals.sharable_db();
let provider = if canonical_fork.hash == canonical_tip_hash {
Box::new(db.latest()?) as Box<dyn StateProvider>
ChainState::boxed(db.latest()?)
} else {
Box::new(db.history_by_block_number(canonical_fork.number)?) as Box<dyn StateProvider>
ChainState::boxed(db.history_by_block_number(canonical_fork.number)?)
};
// append the block if it is continuing the chain.
@@ -226,9 +226,9 @@ impl<DB: Database, C: Consensus, EF: ExecutorFactory> BlockchainTree<DB, C, EF>
.ok_or(ExecError::CanonicalChain { block_hash: block.parent_hash })?;
let provider = if block.parent_hash == canonical_tip {
Box::new(db.latest()?) as Box<dyn StateProvider>
ChainState::boxed(db.latest()?)
} else {
Box::new(db.history_by_block_number(block.number - 1)?) as Box<dyn StateProvider>
ChainState::boxed(db.history_by_block_number(block.number - 1)?)
};
let parent_header = parent_header.seal(block.parent_hash);
@@ -554,8 +554,6 @@ impl<DB: Database, C: Consensus, EF: ExecutorFactory> BlockchainTree<DB, C, EF>
#[cfg(test)]
mod tests {
use std::collections::HashSet;
use super::*;
use parking_lot::Mutex;
use reth_db::{
@@ -566,8 +564,9 @@ mod tests {
use reth_primitives::{hex_literal::hex, proofs::EMPTY_ROOT, ChainSpecBuilder, H256, MAINNET};
use reth_provider::{
execution_result::ExecutionResult, insert_block, test_utils::blocks::BlockChainTestData,
BlockExecutor,
BlockExecutor, StateProvider,
};
use std::collections::HashSet;
struct TestFactory {
exec_result: Arc<Mutex<Vec<ExecutionResult>>>,
@@ -644,7 +643,7 @@ mod tests {
genesis.header.header.state_root = EMPTY_ROOT;
let tx_mut = externals.0.tx_mut().unwrap();
insert_block(&tx_mut, genesis.clone(), None, false, Some((0, 0))).unwrap();
insert_block(&tx_mut, genesis, None, false, Some((0, 0))).unwrap();
// insert first 10 blocks
for i in 0..10 {
@@ -710,7 +709,7 @@ mod tests {
H256(hex!("90101a13dd059fa5cca99ed93d1dc23657f63626c5b8f993a2ccbdf7446b64f8"));
// test pops execution results from vector, so order is from last to first.ß
let externals = externals(vec![exec2.clone(), exec1.clone(), exec2.clone(), exec1.clone()]);
let externals = externals(vec![exec2.clone(), exec1.clone(), exec2, exec1]);
// last finalized block would be number 9.
setup(data.genesis, &externals);

View File

@@ -2,7 +2,6 @@ use crate::{
providers::state::macros::delegate_provider_impls, AccountProvider, BlockHashProvider,
StateProvider,
};
use std::marker::PhantomData;
/// A type that can access the state at a specific access point (block number or tag)
///
@@ -16,16 +15,20 @@ use std::marker::PhantomData;
///
/// Note: The lifetime of this type is limited by the type that created it.
pub struct ChainState<'a> {
inner: Box<dyn StateProvider>,
_phantom: PhantomData<&'a ()>,
inner: Box<dyn StateProvider + 'a>,
}
// == impl ChainState ===
impl<'a> ChainState<'a> {
/// Wraps the given [StateProvider]
pub fn new(inner: Box<dyn StateProvider>) -> Self {
Self { inner, _phantom: Default::default() }
pub fn boxed<S: StateProvider + 'a>(inner: S) -> Self {
Self::new(Box::new(inner))
}
/// Wraps the given [StateProvider]
pub fn new(inner: Box<dyn StateProvider + 'a>) -> Self {
Self { inner }
}
/// Returns a new provider that takes the `TX` as reference