mirror of
https://github.com/hl-archive-node/nanoreth.git
synced 2025-12-06 10:59:55 +00:00
Breaking changes (#5191)
Co-authored-by: Bjerg <onbjerg@users.noreply.github.com> Co-authored-by: Roman Krasiuk <rokrassyuk@gmail.com> Co-authored-by: joshieDo <ranriver@protonmail.com> Co-authored-by: joshieDo <93316087+joshieDo@users.noreply.github.com> Co-authored-by: Matthias Seitz <matthias.seitz@outlook.de> Co-authored-by: Oliver Nordbjerg <hi@notbjerg.me> Co-authored-by: Thomas Coratger <thomas.coratger@gmail.com>
This commit is contained in:
@ -17,7 +17,7 @@ ef-tests = []
|
||||
[dependencies]
|
||||
reth-primitives.workspace = true
|
||||
reth-db = { workspace = true, features = ["mdbx", "test-utils"] }
|
||||
reth-provider.workspace = true
|
||||
reth-provider = { workspace = true, features = ["test-utils"] }
|
||||
reth-stages.workspace = true
|
||||
reth-interfaces.workspace = true
|
||||
reth-revm.workspace = true
|
||||
@ -29,3 +29,4 @@ walkdir = "2.3.3"
|
||||
serde = "1.0.163"
|
||||
serde_json.workspace = true
|
||||
thiserror.workspace = true
|
||||
rayon.workspace = true
|
||||
|
||||
@ -5,10 +5,11 @@ use crate::{
|
||||
Case, Error, Suite,
|
||||
};
|
||||
use alloy_rlp::Decodable;
|
||||
use reth_db::test_utils::create_test_rw_db;
|
||||
use rayon::iter::{ParallelBridge, ParallelIterator};
|
||||
use reth_db::test_utils::{create_test_rw_db, create_test_static_files_dir};
|
||||
use reth_node_ethereum::EthEvmConfig;
|
||||
use reth_primitives::{BlockBody, SealedBlock};
|
||||
use reth_provider::{BlockWriter, HashingWriter, ProviderFactory};
|
||||
use reth_primitives::{BlockBody, SealedBlock, StaticFileSegment};
|
||||
use reth_provider::{providers::StaticFileWriter, HashingWriter, ProviderFactory};
|
||||
use reth_stages::{stages::ExecutionStage, ExecInput, Stage};
|
||||
use std::{collections::BTreeMap, fs, path::Path, sync::Arc};
|
||||
|
||||
@ -64,83 +65,107 @@ impl Case for BlockchainTestCase {
|
||||
}
|
||||
|
||||
// Iterate through test cases, filtering by the network type to exclude specific forks.
|
||||
for case in self.tests.values().filter(|case| {
|
||||
!matches!(
|
||||
case.network,
|
||||
ForkSpec::ByzantiumToConstantinopleAt5 |
|
||||
ForkSpec::Constantinople |
|
||||
ForkSpec::ConstantinopleFix |
|
||||
ForkSpec::MergeEOF |
|
||||
ForkSpec::MergeMeterInitCode |
|
||||
ForkSpec::MergePush0 |
|
||||
ForkSpec::Unknown
|
||||
)
|
||||
}) {
|
||||
// Create a new test database and initialize a provider for the test case.
|
||||
let db = create_test_rw_db();
|
||||
let provider = ProviderFactory::new(db.as_ref(), Arc::new(case.network.clone().into()))
|
||||
self.tests
|
||||
.values()
|
||||
.filter(|case| {
|
||||
!matches!(
|
||||
case.network,
|
||||
ForkSpec::ByzantiumToConstantinopleAt5 |
|
||||
ForkSpec::Constantinople |
|
||||
ForkSpec::ConstantinopleFix |
|
||||
ForkSpec::MergeEOF |
|
||||
ForkSpec::MergeMeterInitCode |
|
||||
ForkSpec::MergePush0 |
|
||||
ForkSpec::Unknown
|
||||
)
|
||||
})
|
||||
.par_bridge()
|
||||
.try_for_each(|case| {
|
||||
// Create a new test database and initialize a provider for the test case.
|
||||
let db = create_test_rw_db();
|
||||
let static_files_dir = create_test_static_files_dir();
|
||||
let provider = ProviderFactory::new(
|
||||
db.as_ref(),
|
||||
Arc::new(case.network.clone().into()),
|
||||
static_files_dir.clone(),
|
||||
)?
|
||||
.provider_rw()
|
||||
.unwrap();
|
||||
|
||||
// Insert initial test state into the provider.
|
||||
provider
|
||||
.insert_block(
|
||||
SealedBlock::new(
|
||||
case.genesis_block_header.clone().into(),
|
||||
BlockBody::default(),
|
||||
)
|
||||
.try_seal_with_senders()
|
||||
.unwrap(),
|
||||
None,
|
||||
)
|
||||
.map_err(|err| Error::RethError(err.into()))?;
|
||||
case.pre.write_to_db(provider.tx_ref())?;
|
||||
|
||||
// Decode and insert blocks, creating a chain of blocks for the test case.
|
||||
let last_block = case.blocks.iter().try_fold(None, |_, block| {
|
||||
let decoded = SealedBlock::decode(&mut block.rlp.as_ref())?;
|
||||
// Insert initial test state into the provider.
|
||||
provider
|
||||
.insert_block(decoded.clone().try_seal_with_senders().unwrap(), None)
|
||||
.insert_historical_block(
|
||||
SealedBlock::new(
|
||||
case.genesis_block_header.clone().into(),
|
||||
BlockBody::default(),
|
||||
)
|
||||
.try_seal_with_senders()
|
||||
.unwrap(),
|
||||
None,
|
||||
)
|
||||
.map_err(|err| Error::RethError(err.into()))?;
|
||||
Ok::<Option<SealedBlock>, Error>(Some(decoded))
|
||||
})?;
|
||||
case.pre.write_to_db(provider.tx_ref())?;
|
||||
|
||||
// Execute the execution stage using the EVM processor factory for the test case
|
||||
// network.
|
||||
let _ = ExecutionStage::new_with_factory(reth_revm::EvmProcessorFactory::new(
|
||||
Arc::new(case.network.clone().into()),
|
||||
EthEvmConfig::default(),
|
||||
))
|
||||
.execute(
|
||||
&provider,
|
||||
ExecInput { target: last_block.as_ref().map(|b| b.number), checkpoint: None },
|
||||
);
|
||||
|
||||
// Validate the post-state for the test case.
|
||||
match (&case.post_state, &case.post_state_hash) {
|
||||
(Some(state), None) => {
|
||||
// Validate accounts in the state against the provider's database.
|
||||
for (&address, account) in state.iter() {
|
||||
account.assert_db(address, provider.tx_ref())?;
|
||||
}
|
||||
}
|
||||
(None, Some(expected_state_root)) => {
|
||||
// Insert state hashes into the provider based on the expected state root.
|
||||
let last_block = last_block.unwrap_or_default();
|
||||
// Decode and insert blocks, creating a chain of blocks for the test case.
|
||||
let last_block = case.blocks.iter().try_fold(None, |_, block| {
|
||||
let decoded = SealedBlock::decode(&mut block.rlp.as_ref())?;
|
||||
provider
|
||||
.insert_hashes(
|
||||
0..=last_block.number,
|
||||
last_block.hash(),
|
||||
*expected_state_root,
|
||||
.insert_historical_block(
|
||||
decoded.clone().try_seal_with_senders().unwrap(),
|
||||
None,
|
||||
)
|
||||
.map_err(|err| Error::RethError(err.into()))?;
|
||||
}
|
||||
_ => return Err(Error::MissingPostState),
|
||||
}
|
||||
Ok::<Option<SealedBlock>, Error>(Some(decoded))
|
||||
})?;
|
||||
provider
|
||||
.static_file_provider()
|
||||
.latest_writer(StaticFileSegment::Headers)
|
||||
.unwrap()
|
||||
.commit()
|
||||
.unwrap();
|
||||
|
||||
// Drop the provider without committing to the database.
|
||||
drop(provider);
|
||||
}
|
||||
// Execute the execution stage using the EVM processor factory for the test case
|
||||
// network.
|
||||
let _ = ExecutionStage::new_with_factory(reth_revm::EvmProcessorFactory::new(
|
||||
Arc::new(case.network.clone().into()),
|
||||
EthEvmConfig::default(),
|
||||
))
|
||||
.execute(
|
||||
&provider,
|
||||
ExecInput { target: last_block.as_ref().map(|b| b.number), checkpoint: None },
|
||||
);
|
||||
|
||||
// Validate the post-state for the test case.
|
||||
match (&case.post_state, &case.post_state_hash) {
|
||||
(Some(state), None) => {
|
||||
// Validate accounts in the state against the provider's database.
|
||||
for (&address, account) in state.iter() {
|
||||
account.assert_db(address, provider.tx_ref())?;
|
||||
}
|
||||
}
|
||||
(None, Some(expected_state_root)) => {
|
||||
// Insert state hashes into the provider based on the expected state root.
|
||||
let last_block = last_block.unwrap_or_default();
|
||||
provider
|
||||
.insert_hashes(
|
||||
0..=last_block.number,
|
||||
last_block.hash(),
|
||||
*expected_state_root,
|
||||
)
|
||||
.map_err(|err| Error::RethError(err.into()))?;
|
||||
}
|
||||
_ => return Err(Error::MissingPostState),
|
||||
}
|
||||
|
||||
// Drop the provider without committing to the database.
|
||||
drop(provider);
|
||||
// TODO: replace with `tempdir` usage, so the temp directory is removed
|
||||
// automatically when the variable goes out of scope
|
||||
reth_primitives::fs::remove_dir_all(static_files_dir)
|
||||
.expect("Failed to remove static files directory");
|
||||
|
||||
Ok(())
|
||||
})?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
@ -161,7 +161,7 @@ impl State {
|
||||
bytecode_hash: code_hash,
|
||||
};
|
||||
tx.put::<tables::PlainAccountState>(address, reth_account)?;
|
||||
tx.put::<tables::HashedAccount>(hashed_address, reth_account)?;
|
||||
tx.put::<tables::HashedAccounts>(hashed_address, reth_account)?;
|
||||
if let Some(code_hash) = code_hash {
|
||||
tx.put::<tables::Bytecodes>(code_hash, Bytecode::new_raw(account.code.clone()))?;
|
||||
}
|
||||
@ -171,7 +171,7 @@ impl State {
|
||||
address,
|
||||
StorageEntry { key: storage_key, value: *v },
|
||||
)?;
|
||||
tx.put::<tables::HashedStorage>(
|
||||
tx.put::<tables::HashedStorages>(
|
||||
hashed_address,
|
||||
StorageEntry { key: keccak256(storage_key), value: *v },
|
||||
)
|
||||
|
||||
Reference in New Issue
Block a user