mirror of
https://github.com/paradigmxyz/reth.git
synced 2026-01-26 23:58:46 -05:00
test(provider): ChangeSetReader of BlockchainProvider2 (#10415)
This commit is contained in:
@@ -1489,28 +1489,46 @@ where
|
||||
mod tests {
|
||||
use std::sync::Arc;
|
||||
|
||||
use itertools::Itertools;
|
||||
use rand::Rng;
|
||||
use reth_chain_state::{ExecutedBlock, NewCanonicalChain};
|
||||
use reth_chainspec::ChainSpecProvider;
|
||||
use reth_db::{test_utils::TempDatabase, DatabaseEnv};
|
||||
use reth_db::{models::AccountBeforeTx, test_utils::TempDatabase, DatabaseEnv};
|
||||
use reth_execution_types::ExecutionOutcome;
|
||||
use reth_primitives::{
|
||||
BlockHashOrNumber, BlockNumberOrTag, Header, Receipt, SealedBlock, StaticFileSegment, B256,
|
||||
};
|
||||
use reth_storage_api::{
|
||||
BlockHashReader, BlockNumReader, BlockReader, BlockReaderIdExt, BlockSource,
|
||||
HeaderProvider, ReceiptProviderIdExt,
|
||||
ChangeSetReader, HeaderProvider, ReceiptProviderIdExt,
|
||||
};
|
||||
use reth_testing_utils::generators::{self, random_block, random_block_range, random_receipt};
|
||||
use reth_testing_utils::generators::{
|
||||
self, random_block, random_block_range, random_changeset_range, random_eoa_accounts,
|
||||
random_receipt,
|
||||
};
|
||||
use revm::db::BundleState;
|
||||
|
||||
use crate::{
|
||||
providers::BlockchainProvider2, test_utils::create_test_provider_factory,
|
||||
providers::BlockchainProvider2, test_utils::create_test_provider_factory, BlockWriter,
|
||||
CanonChainTracker, StaticFileWriter,
|
||||
};
|
||||
|
||||
const TEST_BLOCKS_COUNT: usize = 5;
|
||||
|
||||
fn random_blocks(
|
||||
rng: &mut impl Rng,
|
||||
database_blocks: usize,
|
||||
in_memory_blocks: usize,
|
||||
) -> (Vec<SealedBlock>, Vec<SealedBlock>) {
|
||||
let block_range = (database_blocks + in_memory_blocks - 1) as u64;
|
||||
let blocks = random_block_range(rng, 0..=block_range, B256::ZERO, 0..1);
|
||||
let (database_blocks, in_memory_blocks) = blocks.split_at(database_blocks);
|
||||
(database_blocks.to_vec(), in_memory_blocks.to_vec())
|
||||
}
|
||||
|
||||
#[allow(clippy::type_complexity)]
|
||||
fn provider_with_random_blocks(
|
||||
rng: &mut impl Rng,
|
||||
database_blocks: usize,
|
||||
in_memory_blocks: usize,
|
||||
) -> eyre::Result<(
|
||||
@@ -1519,22 +1537,20 @@ mod tests {
|
||||
Vec<SealedBlock>,
|
||||
Vec<Vec<Receipt>>,
|
||||
)> {
|
||||
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 receipts: Vec<Vec<_>> = blocks
|
||||
let (database_blocks, in_memory_blocks) =
|
||||
random_blocks(rng, database_blocks, in_memory_blocks);
|
||||
let receipts: Vec<Vec<_>> = database_blocks
|
||||
.iter()
|
||||
.chain(in_memory_blocks.iter())
|
||||
.map(|block| block.body.iter())
|
||||
.map(|tx| tx.map(|tx| random_receipt(&mut rng, tx, Some(2))).collect())
|
||||
.map(|tx| tx.map(|tx| random_receipt(rng, tx, Some(2))).collect())
|
||||
.collect();
|
||||
|
||||
let factory = create_test_provider_factory();
|
||||
let provider_rw = factory.provider_rw()?;
|
||||
|
||||
let mut blocks_iter = blocks.clone().into_iter();
|
||||
|
||||
// Insert blocks and receipts into the database
|
||||
for block in (0..database_blocks).map_while(|_| blocks_iter.next()) {
|
||||
for block in &database_blocks {
|
||||
provider_rw.insert_historical_block(
|
||||
block.clone().seal_with_senders().expect("failed to seal block with senders"),
|
||||
)?;
|
||||
@@ -1553,7 +1569,8 @@ mod tests {
|
||||
|
||||
// Insert the rest of the blocks and receipts into the in-memory state
|
||||
let chain = NewCanonicalChain::Commit {
|
||||
new: blocks_iter
|
||||
new: in_memory_blocks
|
||||
.iter()
|
||||
.map(|block| {
|
||||
let senders = block.senders().expect("failed to recover senders");
|
||||
let block_receipts = receipts.get(block.number as usize).unwrap().clone();
|
||||
@@ -1561,7 +1578,7 @@ mod tests {
|
||||
ExecutionOutcome { receipts: block_receipts.into(), ..Default::default() };
|
||||
|
||||
ExecutedBlock::new(
|
||||
Arc::new(block),
|
||||
Arc::new(block.clone()),
|
||||
Arc::new(senders),
|
||||
execution_outcome.into(),
|
||||
Default::default(),
|
||||
@@ -1573,17 +1590,17 @@ mod tests {
|
||||
provider.canonical_in_memory_state.update_chain(chain);
|
||||
|
||||
// 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();
|
||||
let blocks = database_blocks.iter().chain(in_memory_blocks.iter()).collect::<Vec<_>>();
|
||||
let block_count = blocks.len();
|
||||
let canonical_block = blocks.get(block_count - 1).unwrap();
|
||||
let safe_block = blocks.get(block_count - 2).unwrap();
|
||||
let finalized_block = blocks.get(block_count - 3).unwrap();
|
||||
|
||||
// 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);
|
||||
provider.set_canonical_head(canonical_block.header.clone());
|
||||
provider.set_safe(safe_block.header.clone());
|
||||
provider.set_finalized(finalized_block.header.clone());
|
||||
|
||||
let (database_blocks, in_memory_blocks) = blocks.split_at(database_blocks);
|
||||
Ok((provider, database_blocks.to_vec(), in_memory_blocks.to_vec(), receipts))
|
||||
}
|
||||
|
||||
@@ -1751,8 +1768,9 @@ mod tests {
|
||||
|
||||
#[test]
|
||||
fn test_block_reader_pending_block() -> eyre::Result<()> {
|
||||
let mut rng = generators::rng();
|
||||
let (provider, _, _, _) =
|
||||
provider_with_random_blocks(TEST_BLOCKS_COUNT, TEST_BLOCKS_COUNT).unwrap();
|
||||
provider_with_random_blocks(&mut rng, TEST_BLOCKS_COUNT, TEST_BLOCKS_COUNT).unwrap();
|
||||
|
||||
// Generate a random block
|
||||
let mut rng = generators::rng();
|
||||
@@ -1851,8 +1869,9 @@ mod tests {
|
||||
|
||||
#[test]
|
||||
fn test_block_hash_reader() -> eyre::Result<()> {
|
||||
let mut rng = generators::rng();
|
||||
let (provider, database_blocks, in_memory_blocks, _) =
|
||||
provider_with_random_blocks(TEST_BLOCKS_COUNT, TEST_BLOCKS_COUNT)?;
|
||||
provider_with_random_blocks(&mut rng, TEST_BLOCKS_COUNT, TEST_BLOCKS_COUNT)?;
|
||||
|
||||
let database_block = database_blocks.first().unwrap().clone();
|
||||
let in_memory_block = in_memory_blocks.last().unwrap().clone();
|
||||
@@ -1874,8 +1893,9 @@ 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();
|
||||
provider_with_random_blocks(&mut rng, 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();
|
||||
@@ -1938,8 +1958,9 @@ mod tests {
|
||||
|
||||
#[test]
|
||||
fn test_block_num_reader() -> 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();
|
||||
provider_with_random_blocks(&mut rng, 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);
|
||||
@@ -1954,8 +1975,9 @@ mod tests {
|
||||
|
||||
#[test]
|
||||
fn test_block_reader_id_ext_block_by_id() {
|
||||
let mut rng = generators::rng();
|
||||
let (provider, database_blocks, in_memory_blocks, _) =
|
||||
provider_with_random_blocks(TEST_BLOCKS_COUNT, TEST_BLOCKS_COUNT).unwrap();
|
||||
provider_with_random_blocks(&mut rng, 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();
|
||||
@@ -1982,8 +2004,9 @@ mod tests {
|
||||
|
||||
#[test]
|
||||
fn test_block_reader_id_ext_header_by_number_or_tag() {
|
||||
let mut rng = generators::rng();
|
||||
let (provider, database_blocks, in_memory_blocks, _) =
|
||||
provider_with_random_blocks(TEST_BLOCKS_COUNT, TEST_BLOCKS_COUNT).unwrap();
|
||||
provider_with_random_blocks(&mut rng, TEST_BLOCKS_COUNT, TEST_BLOCKS_COUNT).unwrap();
|
||||
|
||||
let database_block = database_blocks.first().unwrap().clone();
|
||||
|
||||
@@ -2032,8 +2055,9 @@ mod tests {
|
||||
|
||||
#[test]
|
||||
fn test_block_reader_id_ext_header_by_id() {
|
||||
let mut rng = generators::rng();
|
||||
let (provider, database_blocks, in_memory_blocks, _) =
|
||||
provider_with_random_blocks(TEST_BLOCKS_COUNT, TEST_BLOCKS_COUNT).unwrap();
|
||||
provider_with_random_blocks(&mut rng, 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();
|
||||
@@ -2083,8 +2107,9 @@ mod tests {
|
||||
|
||||
#[test]
|
||||
fn test_block_reader_id_ext_ommers_by_id() {
|
||||
let mut rng = generators::rng();
|
||||
let (provider, database_blocks, in_memory_blocks, _) =
|
||||
provider_with_random_blocks(TEST_BLOCKS_COUNT, TEST_BLOCKS_COUNT).unwrap();
|
||||
provider_with_random_blocks(&mut rng, 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();
|
||||
@@ -2116,8 +2141,9 @@ mod tests {
|
||||
|
||||
#[test]
|
||||
fn test_receipt_provider_id_ext_receipts_by_block_id() -> eyre::Result<()> {
|
||||
let mut rng = generators::rng();
|
||||
let (provider, database_blocks, in_memory_blocks, receipts) =
|
||||
provider_with_random_blocks(TEST_BLOCKS_COUNT, TEST_BLOCKS_COUNT)?;
|
||||
provider_with_random_blocks(&mut rng, TEST_BLOCKS_COUNT, TEST_BLOCKS_COUNT)?;
|
||||
|
||||
let database_block = database_blocks.first().unwrap().clone();
|
||||
let in_memory_block = in_memory_blocks.last().unwrap().clone();
|
||||
@@ -2151,8 +2177,9 @@ mod tests {
|
||||
|
||||
#[test]
|
||||
fn test_receipt_provider_id_ext_receipts_by_block_number_or_tag() -> eyre::Result<()> {
|
||||
let mut rng = generators::rng();
|
||||
let (provider, database_blocks, in_memory_blocks, receipts) =
|
||||
provider_with_random_blocks(TEST_BLOCKS_COUNT, TEST_BLOCKS_COUNT)?;
|
||||
provider_with_random_blocks(&mut rng, TEST_BLOCKS_COUNT, TEST_BLOCKS_COUNT)?;
|
||||
|
||||
let database_block = database_blocks.first().unwrap().clone();
|
||||
|
||||
@@ -2180,4 +2207,117 @@ mod tests {
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_changeset_reader() -> eyre::Result<()> {
|
||||
let mut rng = generators::rng();
|
||||
let (database_blocks, in_memory_blocks) = random_blocks(&mut rng, TEST_BLOCKS_COUNT, 1);
|
||||
let first_database_block = database_blocks.first().map(|block| block.number).unwrap();
|
||||
let last_database_block = database_blocks.last().map(|block| block.number).unwrap();
|
||||
let first_in_memory_block = in_memory_blocks.first().map(|block| block.number).unwrap();
|
||||
|
||||
let accounts = random_eoa_accounts(&mut rng, 2);
|
||||
|
||||
let (database_changesets, database_state) = random_changeset_range(
|
||||
&mut rng,
|
||||
&database_blocks,
|
||||
accounts.into_iter().map(|(address, account)| (address, (account, Vec::new()))),
|
||||
0..0,
|
||||
0..0,
|
||||
);
|
||||
let (in_memory_changesets, in_memory_state) = random_changeset_range(
|
||||
&mut rng,
|
||||
&in_memory_blocks,
|
||||
database_state
|
||||
.iter()
|
||||
.map(|(address, (account, storage))| (*address, (*account, storage.clone()))),
|
||||
0..0,
|
||||
0..0,
|
||||
);
|
||||
|
||||
let factory = create_test_provider_factory();
|
||||
|
||||
let provider_rw = factory.provider_rw()?;
|
||||
provider_rw.append_blocks_with_state(
|
||||
database_blocks
|
||||
.into_iter()
|
||||
.map(|b| b.seal_with_senders().expect("failed to seal block with senders"))
|
||||
.collect(),
|
||||
ExecutionOutcome {
|
||||
bundle: BundleState::new(
|
||||
database_state.into_iter().map(|(address, (account, _))| {
|
||||
(address, None, Some(account.into()), Default::default())
|
||||
}),
|
||||
database_changesets
|
||||
.iter()
|
||||
.map(|block_changesets| {
|
||||
block_changesets.iter().map(|(address, account, _)| {
|
||||
(*address, Some(Some((*account).into())), [])
|
||||
})
|
||||
})
|
||||
.collect::<Vec<_>>(),
|
||||
Vec::new(),
|
||||
),
|
||||
first_block: first_database_block,
|
||||
..Default::default()
|
||||
},
|
||||
Default::default(),
|
||||
Default::default(),
|
||||
)?;
|
||||
provider_rw.commit()?;
|
||||
|
||||
let provider = BlockchainProvider2::new(factory)?;
|
||||
|
||||
let in_memory_changesets = in_memory_changesets.into_iter().next().unwrap();
|
||||
let chain = NewCanonicalChain::Commit {
|
||||
new: vec![in_memory_blocks
|
||||
.first()
|
||||
.map(|block| {
|
||||
let senders = block.senders().expect("failed to recover senders");
|
||||
ExecutedBlock::new(
|
||||
Arc::new(block.clone()),
|
||||
Arc::new(senders),
|
||||
Arc::new(ExecutionOutcome {
|
||||
bundle: BundleState::new(
|
||||
in_memory_state.into_iter().map(|(address, (account, _))| {
|
||||
(address, None, Some(account.into()), Default::default())
|
||||
}),
|
||||
[in_memory_changesets.iter().map(|(address, account, _)| {
|
||||
(*address, Some(Some((*account).into())), Vec::new())
|
||||
})],
|
||||
[],
|
||||
),
|
||||
first_block: first_in_memory_block,
|
||||
..Default::default()
|
||||
}),
|
||||
Default::default(),
|
||||
Default::default(),
|
||||
)
|
||||
})
|
||||
.unwrap()],
|
||||
};
|
||||
provider.canonical_in_memory_state.update_chain(chain);
|
||||
|
||||
assert_eq!(
|
||||
provider.account_block_changeset(last_database_block).unwrap(),
|
||||
database_changesets
|
||||
.into_iter()
|
||||
.last()
|
||||
.unwrap()
|
||||
.into_iter()
|
||||
.sorted_by_key(|(address, _, _)| *address)
|
||||
.map(|(address, account, _)| AccountBeforeTx { address, info: Some(account) })
|
||||
.collect::<Vec<_>>()
|
||||
);
|
||||
assert_eq!(
|
||||
provider.account_block_changeset(first_in_memory_block).unwrap(),
|
||||
in_memory_changesets
|
||||
.into_iter()
|
||||
.sorted_by_key(|(address, _, _)| *address)
|
||||
.map(|(address, account, _)| AccountBeforeTx { address, info: Some(account) })
|
||||
.collect::<Vec<_>>()
|
||||
);
|
||||
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user