mirror of
https://github.com/hl-archive-node/nanoreth.git
synced 2025-12-06 19:09:54 +00:00
test: BlockReaderIdExt implementation for BlockchainProvider2 (#10376)
This commit is contained in:
@ -858,7 +858,7 @@ where
|
||||
transactions.push(block_state.block().block().body.clone());
|
||||
last_in_memory_block = Some(number);
|
||||
} else {
|
||||
break;
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
@ -1491,26 +1491,37 @@ mod tests {
|
||||
use std::sync::Arc;
|
||||
|
||||
use reth_chain_state::{ExecutedBlock, NewCanonicalChain};
|
||||
use reth_primitives::B256;
|
||||
use reth_storage_api::{BlockHashReader, BlockNumReader, HeaderProvider};
|
||||
use reth_db::{test_utils::TempDatabase, DatabaseEnv};
|
||||
use reth_primitives::{BlockNumberOrTag, SealedBlock, B256};
|
||||
use reth_storage_api::{BlockHashReader, BlockNumReader, BlockReaderIdExt, HeaderProvider};
|
||||
use reth_testing_utils::generators::{self, random_block_range};
|
||||
|
||||
use crate::{providers::BlockchainProvider2, test_utils::create_test_provider_factory};
|
||||
use crate::{
|
||||
providers::BlockchainProvider2, test_utils::create_test_provider_factory, CanonChainTracker,
|
||||
};
|
||||
|
||||
#[test]
|
||||
fn test_block_hash_reader() -> eyre::Result<()> {
|
||||
const TEST_BLOCKS_COUNT: usize = 5;
|
||||
|
||||
#[allow(clippy::type_complexity)]
|
||||
fn provider_with_random_blocks(
|
||||
database_blocks: usize,
|
||||
in_memory_blocks: usize,
|
||||
) -> eyre::Result<(
|
||||
BlockchainProvider2<Arc<TempDatabase<DatabaseEnv>>>,
|
||||
Vec<SealedBlock>,
|
||||
Vec<SealedBlock>,
|
||||
)> {
|
||||
let mut rng = generators::rng();
|
||||
let block_range = (database_blocks + in_memory_blocks - 1) as u64;
|
||||
let blocks = random_block_range(&mut rng, 0..=block_range, B256::ZERO, 0..1);
|
||||
|
||||
let factory = create_test_provider_factory();
|
||||
|
||||
// Generate 10 random blocks
|
||||
let blocks = random_block_range(&mut rng, 0..=10, B256::ZERO, 0..1);
|
||||
let provider_rw = factory.provider_rw()?;
|
||||
|
||||
let mut blocks_iter = blocks.clone().into_iter();
|
||||
|
||||
// Insert first 5 blocks into the database
|
||||
let provider_rw = factory.provider_rw()?;
|
||||
for block in (0..5).map_while(|_| blocks_iter.next()) {
|
||||
// Insert data blocks into the database
|
||||
for block in (0..database_blocks).map_while(|_| blocks_iter.next()) {
|
||||
provider_rw.insert_historical_block(
|
||||
block.seal_with_senders().expect("failed to seal block with senders"),
|
||||
)?;
|
||||
@ -1536,15 +1547,39 @@ mod tests {
|
||||
};
|
||||
provider.canonical_in_memory_state.update_chain(chain);
|
||||
|
||||
let database_block = blocks.first().unwrap().clone();
|
||||
let in_memory_block = blocks.last().unwrap().clone();
|
||||
// Get canonical, safe, and finalized blocks
|
||||
let block_count = database_blocks + in_memory_blocks;
|
||||
let canonical_block = blocks.get(block_count - 1).unwrap().clone();
|
||||
let safe_block = blocks.get(block_count - 2).unwrap().clone();
|
||||
let finalized_block = blocks.get(block_count - 3).unwrap().clone();
|
||||
|
||||
// Set the canonical head, safe, and finalized blocks
|
||||
provider.set_canonical_head(canonical_block.header);
|
||||
provider.set_safe(safe_block.header);
|
||||
provider.set_finalized(finalized_block.header);
|
||||
|
||||
let (database_blocks, in_memory_blocks) = blocks.split_at(database_blocks);
|
||||
Ok((provider, database_blocks.to_vec(), in_memory_blocks.to_vec()))
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_block_hash_reader() -> eyre::Result<()> {
|
||||
let (provider, database_blocks, in_memory_blocks) =
|
||||
provider_with_random_blocks(TEST_BLOCKS_COUNT, TEST_BLOCKS_COUNT)?;
|
||||
|
||||
let database_block = database_blocks.first().unwrap().clone();
|
||||
let in_memory_block = in_memory_blocks.last().unwrap().clone();
|
||||
|
||||
assert_eq!(provider.block_hash(database_block.number)?, Some(database_block.hash()));
|
||||
assert_eq!(provider.block_hash(in_memory_block.number)?, Some(in_memory_block.hash()));
|
||||
|
||||
assert_eq!(
|
||||
provider.canonical_hashes_range(0, 10)?,
|
||||
blocks.iter().map(|block| block.hash()).collect::<Vec<_>>()
|
||||
[database_blocks, in_memory_blocks]
|
||||
.concat()
|
||||
.iter()
|
||||
.map(|block| block.hash())
|
||||
.collect::<Vec<_>>()
|
||||
);
|
||||
|
||||
Ok(())
|
||||
@ -1552,45 +1587,12 @@ mod tests {
|
||||
|
||||
#[test]
|
||||
fn test_header_provider() -> eyre::Result<()> {
|
||||
let mut rng = generators::rng();
|
||||
let (provider, database_blocks, in_memory_blocks) =
|
||||
provider_with_random_blocks(TEST_BLOCKS_COUNT, TEST_BLOCKS_COUNT).unwrap();
|
||||
|
||||
let factory = create_test_provider_factory();
|
||||
|
||||
// Generate 10 random blocks
|
||||
let blocks = random_block_range(&mut rng, 0..=10, B256::ZERO, 0..1);
|
||||
|
||||
let mut blocks_iter = blocks.clone().into_iter();
|
||||
|
||||
// Insert first 5 blocks into the database
|
||||
let provider_rw = factory.provider_rw()?;
|
||||
for block in (0..5).map_while(|_| blocks_iter.next()) {
|
||||
provider_rw.insert_historical_block(
|
||||
block.seal_with_senders().expect("failed to seal block with senders"),
|
||||
)?;
|
||||
}
|
||||
provider_rw.commit()?;
|
||||
|
||||
let provider = BlockchainProvider2::new(factory)?;
|
||||
|
||||
// Insert the rest of the blocks into the in-memory state
|
||||
let chain = NewCanonicalChain::Commit {
|
||||
new: blocks_iter
|
||||
.map(|block| {
|
||||
let senders = block.senders().expect("failed to recover senders");
|
||||
ExecutedBlock::new(
|
||||
Arc::new(block),
|
||||
Arc::new(senders),
|
||||
Default::default(),
|
||||
Default::default(),
|
||||
Default::default(),
|
||||
)
|
||||
})
|
||||
.collect(),
|
||||
};
|
||||
provider.canonical_in_memory_state.update_chain(chain);
|
||||
|
||||
let database_block = blocks.first().unwrap().clone();
|
||||
let in_memory_block = blocks.last().unwrap().clone();
|
||||
let database_block = database_blocks.first().unwrap().clone();
|
||||
let in_memory_block = in_memory_blocks.last().unwrap().clone();
|
||||
let blocks = [database_blocks, in_memory_blocks].concat();
|
||||
|
||||
assert_eq!(provider.header(&database_block.hash())?, Some(database_block.header().clone()));
|
||||
assert_eq!(
|
||||
@ -1649,57 +1651,179 @@ mod tests {
|
||||
|
||||
#[test]
|
||||
fn test_block_num_reader() -> eyre::Result<()> {
|
||||
let mut rng = generators::rng();
|
||||
|
||||
let factory = create_test_provider_factory();
|
||||
|
||||
// Generate 10 random blocks
|
||||
let blocks = random_block_range(&mut rng, 0..=10, B256::ZERO, 0..1);
|
||||
let database_blocks = blocks[0..5].to_vec();
|
||||
let in_memory_blocks = blocks[5..].to_vec();
|
||||
|
||||
let mut blocks_iter = blocks.into_iter();
|
||||
|
||||
// Insert first 5 blocks into the database
|
||||
let provider_rw = factory.provider_rw()?;
|
||||
for block in (0..5).map_while(|_| blocks_iter.next()) {
|
||||
provider_rw.insert_historical_block(
|
||||
block.seal_with_senders().expect("failed to seal block with senders"),
|
||||
)?;
|
||||
}
|
||||
provider_rw.commit()?;
|
||||
|
||||
let provider = BlockchainProvider2::new(factory)?;
|
||||
|
||||
// Insert the rest of the blocks into the in-memory state
|
||||
let chain = NewCanonicalChain::Commit {
|
||||
new: blocks_iter
|
||||
.map(|block| {
|
||||
let senders = block.senders().expect("failed to recover senders");
|
||||
ExecutedBlock::new(
|
||||
Arc::new(block),
|
||||
Arc::new(senders),
|
||||
Default::default(),
|
||||
Default::default(),
|
||||
Default::default(),
|
||||
)
|
||||
})
|
||||
.collect(),
|
||||
};
|
||||
provider.canonical_in_memory_state.update_chain(chain);
|
||||
provider
|
||||
.canonical_in_memory_state
|
||||
.set_canonical_head(in_memory_blocks.last().unwrap().clone().header);
|
||||
|
||||
let database_block = database_blocks.first().unwrap().clone();
|
||||
let in_memory_block = in_memory_blocks.last().unwrap().clone();
|
||||
let (provider, database_blocks, in_memory_blocks) =
|
||||
provider_with_random_blocks(TEST_BLOCKS_COUNT, TEST_BLOCKS_COUNT).unwrap();
|
||||
|
||||
assert_eq!(provider.best_block_number()?, in_memory_blocks.last().unwrap().number);
|
||||
assert_eq!(provider.last_block_number()?, database_blocks.last().unwrap().number);
|
||||
|
||||
let database_block = database_blocks.first().unwrap().clone();
|
||||
let in_memory_block = in_memory_blocks.first().unwrap().clone();
|
||||
assert_eq!(provider.block_number(database_block.hash())?, Some(database_block.number));
|
||||
assert_eq!(provider.block_number(in_memory_block.hash())?, Some(in_memory_block.number));
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_block_reader_id_ext_block_by_id() {
|
||||
let (provider, database_blocks, in_memory_blocks) =
|
||||
provider_with_random_blocks(TEST_BLOCKS_COUNT, TEST_BLOCKS_COUNT).unwrap();
|
||||
|
||||
let database_block = database_blocks.first().unwrap().clone();
|
||||
let in_memory_block = in_memory_blocks.last().unwrap().clone();
|
||||
|
||||
let block_number = database_block.number;
|
||||
let block_hash = database_block.header.hash();
|
||||
assert_eq!(
|
||||
provider.block_by_id(block_number.into()).unwrap(),
|
||||
Some(database_block.clone().unseal())
|
||||
);
|
||||
assert_eq!(provider.block_by_id(block_hash.into()).unwrap(), Some(database_block.unseal()));
|
||||
|
||||
let block_number = in_memory_block.number;
|
||||
let block_hash = in_memory_block.header.hash();
|
||||
assert_eq!(
|
||||
provider.block_by_id(block_number.into()).unwrap(),
|
||||
Some(in_memory_block.clone().unseal())
|
||||
);
|
||||
assert_eq!(
|
||||
provider.block_by_id(block_hash.into()).unwrap(),
|
||||
Some(in_memory_block.unseal())
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_block_reader_id_ext_header_by_number_or_tag() {
|
||||
let (provider, database_blocks, in_memory_blocks) =
|
||||
provider_with_random_blocks(TEST_BLOCKS_COUNT, TEST_BLOCKS_COUNT).unwrap();
|
||||
|
||||
let database_block = database_blocks.first().unwrap().clone();
|
||||
|
||||
let in_memory_block_count = in_memory_blocks.len();
|
||||
let canonical_block = in_memory_blocks.get(in_memory_block_count - 1).unwrap().clone();
|
||||
let safe_block = in_memory_blocks.get(in_memory_block_count - 2).unwrap().clone();
|
||||
let finalized_block = in_memory_blocks.get(in_memory_block_count - 3).unwrap().clone();
|
||||
|
||||
let block_number = database_block.number;
|
||||
assert_eq!(
|
||||
provider.header_by_number_or_tag(block_number.into()).unwrap(),
|
||||
Some(database_block.header.clone().unseal())
|
||||
);
|
||||
assert_eq!(
|
||||
provider.sealed_header_by_number_or_tag(block_number.into()).unwrap(),
|
||||
Some(database_block.header)
|
||||
);
|
||||
|
||||
assert_eq!(
|
||||
provider.header_by_number_or_tag(BlockNumberOrTag::Latest).unwrap(),
|
||||
Some(canonical_block.header.clone().unseal())
|
||||
);
|
||||
assert_eq!(
|
||||
provider.sealed_header_by_number_or_tag(BlockNumberOrTag::Latest).unwrap(),
|
||||
Some(canonical_block.header)
|
||||
);
|
||||
|
||||
assert_eq!(
|
||||
provider.header_by_number_or_tag(BlockNumberOrTag::Safe).unwrap(),
|
||||
Some(safe_block.header.clone().unseal())
|
||||
);
|
||||
assert_eq!(
|
||||
provider.sealed_header_by_number_or_tag(BlockNumberOrTag::Safe).unwrap(),
|
||||
Some(safe_block.header)
|
||||
);
|
||||
|
||||
assert_eq!(
|
||||
provider.header_by_number_or_tag(BlockNumberOrTag::Finalized).unwrap(),
|
||||
Some(finalized_block.header.clone().unseal())
|
||||
);
|
||||
assert_eq!(
|
||||
provider.sealed_header_by_number_or_tag(BlockNumberOrTag::Finalized).unwrap(),
|
||||
Some(finalized_block.header)
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_block_reader_id_ext_header_by_id() {
|
||||
let (provider, database_blocks, in_memory_blocks) =
|
||||
provider_with_random_blocks(TEST_BLOCKS_COUNT, TEST_BLOCKS_COUNT).unwrap();
|
||||
|
||||
let database_block = database_blocks.first().unwrap().clone();
|
||||
let in_memory_block = in_memory_blocks.last().unwrap().clone();
|
||||
|
||||
let block_number = database_block.number;
|
||||
let block_hash = database_block.header.hash();
|
||||
|
||||
assert_eq!(
|
||||
provider.header_by_id(block_number.into()).unwrap(),
|
||||
Some(database_block.header.clone().unseal())
|
||||
);
|
||||
assert_eq!(
|
||||
provider.sealed_header_by_id(block_number.into()).unwrap(),
|
||||
Some(database_block.header.clone())
|
||||
);
|
||||
|
||||
assert_eq!(
|
||||
provider.header_by_id(block_hash.into()).unwrap(),
|
||||
Some(database_block.header.clone().unseal())
|
||||
);
|
||||
assert_eq!(
|
||||
provider.sealed_header_by_id(block_hash.into()).unwrap(),
|
||||
Some(database_block.header)
|
||||
);
|
||||
|
||||
let block_number = in_memory_block.number;
|
||||
let block_hash = in_memory_block.header.hash();
|
||||
|
||||
assert_eq!(
|
||||
provider.header_by_id(block_number.into()).unwrap(),
|
||||
Some(in_memory_block.header.clone().unseal())
|
||||
);
|
||||
assert_eq!(
|
||||
provider.sealed_header_by_id(block_number.into()).unwrap(),
|
||||
Some(in_memory_block.header.clone())
|
||||
);
|
||||
|
||||
assert_eq!(
|
||||
provider.header_by_id(block_hash.into()).unwrap(),
|
||||
Some(in_memory_block.header.clone().unseal())
|
||||
);
|
||||
assert_eq!(
|
||||
provider.sealed_header_by_id(block_hash.into()).unwrap(),
|
||||
Some(in_memory_block.header)
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_block_reader_id_ext_ommers_by_id() {
|
||||
let (provider, database_blocks, in_memory_blocks) =
|
||||
provider_with_random_blocks(TEST_BLOCKS_COUNT, TEST_BLOCKS_COUNT).unwrap();
|
||||
|
||||
let database_block = database_blocks.first().unwrap().clone();
|
||||
let in_memory_block = in_memory_blocks.last().unwrap().clone();
|
||||
|
||||
let block_number = database_block.number;
|
||||
let block_hash = database_block.header.hash();
|
||||
|
||||
assert_eq!(
|
||||
provider.ommers_by_id(block_number.into()).unwrap().unwrap_or_default(),
|
||||
database_block.ommers
|
||||
);
|
||||
assert_eq!(
|
||||
provider.ommers_by_id(block_hash.into()).unwrap().unwrap_or_default(),
|
||||
database_block.ommers
|
||||
);
|
||||
|
||||
let block_number = in_memory_block.number;
|
||||
let block_hash = in_memory_block.header.hash();
|
||||
|
||||
assert_eq!(
|
||||
provider.ommers_by_id(block_number.into()).unwrap().unwrap_or_default(),
|
||||
in_memory_block.ommers
|
||||
);
|
||||
assert_eq!(
|
||||
provider.ommers_by_id(block_hash.into()).unwrap().unwrap_or_default(),
|
||||
in_memory_block.ommers
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@ -2002,6 +2002,10 @@ impl<TX: DbTx> BlockReader for DatabaseProvider<TX> {
|
||||
Ok(None)
|
||||
}
|
||||
|
||||
/// Returns the ommers for the block with matching id from the database.
|
||||
///
|
||||
/// If the block is not found, this returns `None`.
|
||||
/// If the block exists, but doesn't contain ommers, this returns `None`.
|
||||
fn ommers(&self, id: BlockHashOrNumber) -> ProviderResult<Option<Vec<Header>>> {
|
||||
if let Some(number) = self.convert_hash_or_number(id)? {
|
||||
// If the Paris (Merge) hardfork block is known and block is after it, return empty
|
||||
|
||||
Reference in New Issue
Block a user