refactor: add BlockWriter and BlockExecutionWriter (#3384)

This commit is contained in:
joshieDo
2023-06-27 10:02:17 +01:00
committed by GitHub
parent d3d44fd46f
commit 085a703d7c
16 changed files with 369 additions and 372 deletions

View File

@ -26,7 +26,7 @@ use reth_interfaces::{
use reth_network::NetworkHandle; use reth_network::NetworkHandle;
use reth_network_api::NetworkInfo; use reth_network_api::NetworkInfo;
use reth_primitives::{stage::StageId, BlockHashOrNumber, BlockNumber, ChainSpec, H256}; use reth_primitives::{stage::StageId, BlockHashOrNumber, BlockNumber, ChainSpec, H256};
use reth_provider::{ProviderFactory, StageCheckpointReader}; use reth_provider::{BlockExecutionWriter, ProviderFactory, StageCheckpointReader};
use reth_staged_sync::utils::init::{init_db, init_genesis}; use reth_staged_sync::utils::init::{init_db, init_genesis};
use reth_stages::{ use reth_stages::{
sets::DefaultStages, sets::DefaultStages,

View File

@ -13,7 +13,7 @@ use reth_db::{
transaction::DbTx, transaction::DbTx,
}; };
use reth_primitives::{BlockHashOrNumber, ChainSpec}; use reth_primitives::{BlockHashOrNumber, ChainSpec};
use reth_provider::ProviderFactory; use reth_provider::{BlockExecutionWriter, ProviderFactory};
use std::{ops::RangeInclusive, sync::Arc}; use std::{ops::RangeInclusive, sync::Arc};
/// `reth stage unwind` command /// `reth stage unwind` command

View File

@ -22,8 +22,9 @@ use reth_primitives::{
use reth_provider::{ use reth_provider::{
chain::{ChainSplit, SplitAt}, chain::{ChainSplit, SplitAt},
post_state::PostState, post_state::PostState,
BlockNumReader, CanonStateNotification, CanonStateNotificationSender, CanonStateNotifications, BlockExecutionWriter, BlockNumReader, BlockWriter, CanonStateNotification,
Chain, DatabaseProvider, DisplayBlocksChain, ExecutorFactory, HeaderProvider, CanonStateNotificationSender, CanonStateNotifications, Chain, DatabaseProvider,
DisplayBlocksChain, ExecutorFactory, HeaderProvider,
}; };
use std::{ use std::{
collections::{BTreeMap, HashMap}, collections::{BTreeMap, HashMap},
@ -1007,8 +1008,8 @@ impl<DB: Database, C: Consensus, EF: ExecutorFactory> BlockchainTree<DB, C, EF>
} }
/// Canonicalize the given chain and commit it to the database. /// Canonicalize the given chain and commit it to the database.
fn commit_canonical(&mut self, chain: Chain) -> Result<(), Error> { fn commit_canonical(&self, chain: Chain) -> Result<(), Error> {
let mut provider = DatabaseProvider::new_rw( let provider = DatabaseProvider::new_rw(
self.externals.db.tx_mut()?, self.externals.db.tx_mut()?,
self.externals.chain_spec.clone(), self.externals.chain_spec.clone(),
); );
@ -1093,9 +1094,9 @@ mod tests {
proofs::EMPTY_ROOT, stage::StageCheckpoint, ChainSpecBuilder, H256, MAINNET, proofs::EMPTY_ROOT, stage::StageCheckpoint, ChainSpecBuilder, H256, MAINNET,
}; };
use reth_provider::{ use reth_provider::{
insert_block,
post_state::PostState, post_state::PostState,
test_utils::{blocks::BlockChainTestData, TestExecutorFactory}, test_utils::{blocks::BlockChainTestData, TestExecutorFactory},
BlockWriter, ProviderFactory,
}; };
use std::{collections::HashSet, sync::Arc}; use std::{collections::HashSet, sync::Arc};
@ -1122,16 +1123,23 @@ mod tests {
genesis.header.header.number = 10; genesis.header.header.number = 10;
genesis.header.header.state_root = EMPTY_ROOT; genesis.header.header.state_root = EMPTY_ROOT;
let tx_mut = db.tx_mut().unwrap(); let factory = ProviderFactory::new(&db, MAINNET.clone());
let provider = factory.provider_rw().unwrap();
insert_block(&tx_mut, genesis, None).unwrap(); provider.insert_block(genesis, None).unwrap();
// insert first 10 blocks // insert first 10 blocks
for i in 0..10 { for i in 0..10 {
tx_mut.put::<tables::CanonicalHeaders>(i, H256([100 + i as u8; 32])).unwrap(); provider
.tx_ref()
.put::<tables::CanonicalHeaders>(i, H256([100 + i as u8; 32]))
.unwrap();
} }
tx_mut.put::<tables::SyncStage>("Finish".to_string(), StageCheckpoint::new(10)).unwrap(); provider
tx_mut.commit().unwrap(); .tx_ref()
.put::<tables::SyncStage>("Finish".to_string(), StageCheckpoint::new(10))
.unwrap();
provider.commit().unwrap();
} }
/// Test data structure that will check tree internals /// Test data structure that will check tree internals

View File

@ -1368,7 +1368,8 @@ mod tests {
use reth_payload_builder::test_utils::spawn_test_payload_service; use reth_payload_builder::test_utils::spawn_test_payload_service;
use reth_primitives::{stage::StageCheckpoint, ChainSpec, ChainSpecBuilder, H256, MAINNET}; use reth_primitives::{stage::StageCheckpoint, ChainSpec, ChainSpecBuilder, H256, MAINNET};
use reth_provider::{ use reth_provider::{
providers::BlockchainProvider, test_utils::TestExecutorFactory, ProviderFactory, providers::BlockchainProvider, test_utils::TestExecutorFactory, BlockWriter,
ProviderFactory,
}; };
use reth_stages::{test_utils::TestStages, ExecOutput, PipelineError, StageError}; use reth_stages::{test_utils::TestStages, ExecOutput, PipelineError, StageError};
use reth_tasks::TokioTaskExecutor; use reth_tasks::TokioTaskExecutor;
@ -1711,8 +1712,10 @@ mod tests {
mut blocks: impl Iterator<Item = &'a SealedBlock>, mut blocks: impl Iterator<Item = &'a SealedBlock>,
) { ) {
let factory = ProviderFactory::new(db, chain); let factory = ProviderFactory::new(db, chain);
let mut provider = factory.provider_rw().unwrap(); let provider = factory.provider_rw().unwrap();
blocks.try_for_each(|b| provider.insert_block(b.clone(), None)).expect("failed to insert"); blocks
.try_for_each(|b| provider.insert_block(b.clone(), None).map(|_| ()))
.expect("failed to insert");
provider.commit().unwrap(); provider.commit().unwrap();
} }

View File

@ -422,7 +422,7 @@ mod tests {
hex_literal::hex, keccak256, stage::StageUnitCheckpoint, Account, Bytecode, hex_literal::hex, keccak256, stage::StageUnitCheckpoint, Account, Bytecode,
ChainSpecBuilder, SealedBlock, StorageEntry, H160, H256, MAINNET, U256, ChainSpecBuilder, SealedBlock, StorageEntry, H160, H256, MAINNET, U256,
}; };
use reth_provider::{insert_canonical_block, AccountReader, ProviderFactory, ReceiptProvider}; use reth_provider::{AccountReader, BlockWriter, ProviderFactory, ReceiptProvider};
use reth_revm::Factory; use reth_revm::Factory;
use reth_rlp::Decodable; use reth_rlp::Decodable;
use std::sync::Arc; use std::sync::Arc;
@ -465,14 +465,14 @@ mod tests {
fn execution_checkpoint_precedes() { fn execution_checkpoint_precedes() {
let state_db = create_test_db::<WriteMap>(EnvKind::RW); let state_db = create_test_db::<WriteMap>(EnvKind::RW);
let factory = ProviderFactory::new(state_db.as_ref(), MAINNET.clone()); let factory = ProviderFactory::new(state_db.as_ref(), MAINNET.clone());
let mut provider = factory.provider_rw().unwrap(); let provider = factory.provider_rw().unwrap();
let mut genesis_rlp = hex!("f901faf901f5a00000000000000000000000000000000000000000000000000000000000000000a01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347942adc25665018aa1fe0e6bc666dac8fc2697ff9baa045571b40ae66ca7480791bbb2887286e4e4c4b1b298b191c889d6959023a32eda056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421b901000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000083020000808502540be400808000a00000000000000000000000000000000000000000000000000000000000000000880000000000000000c0c0").as_slice(); let mut genesis_rlp = hex!("f901faf901f5a00000000000000000000000000000000000000000000000000000000000000000a01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347942adc25665018aa1fe0e6bc666dac8fc2697ff9baa045571b40ae66ca7480791bbb2887286e4e4c4b1b298b191c889d6959023a32eda056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421b901000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000083020000808502540be400808000a00000000000000000000000000000000000000000000000000000000000000000880000000000000000c0c0").as_slice();
let genesis = SealedBlock::decode(&mut genesis_rlp).unwrap(); let genesis = SealedBlock::decode(&mut genesis_rlp).unwrap();
let mut block_rlp = hex!("f90262f901f9a075c371ba45999d87f4542326910a11af515897aebce5265d3f6acd1f1161f82fa01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347942adc25665018aa1fe0e6bc666dac8fc2697ff9baa098f2dcd87c8ae4083e7017a05456c14eea4b1db2032126e27b3b1563d57d7cc0a08151d548273f6683169524b66ca9fe338b9ce42bc3540046c828fd939ae23bcba03f4e5c2ec5b2170b711d97ee755c160457bb58d8daa338e835ec02ae6860bbabb901000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000083020000018502540be40082a8798203e800a00000000000000000000000000000000000000000000000000000000000000000880000000000000000f863f861800a8405f5e10094100000000000000000000000000000000000000080801ba07e09e26678ed4fac08a249ebe8ed680bf9051a5e14ad223e4b2b9d26e0208f37a05f6e3f188e3e6eab7d7d3b6568f5eac7d687b08d307d3154ccd8c87b4630509bc0").as_slice(); let mut block_rlp = hex!("f90262f901f9a075c371ba45999d87f4542326910a11af515897aebce5265d3f6acd1f1161f82fa01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347942adc25665018aa1fe0e6bc666dac8fc2697ff9baa098f2dcd87c8ae4083e7017a05456c14eea4b1db2032126e27b3b1563d57d7cc0a08151d548273f6683169524b66ca9fe338b9ce42bc3540046c828fd939ae23bcba03f4e5c2ec5b2170b711d97ee755c160457bb58d8daa338e835ec02ae6860bbabb901000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000083020000018502540be40082a8798203e800a00000000000000000000000000000000000000000000000000000000000000000880000000000000000f863f861800a8405f5e10094100000000000000000000000000000000000000080801ba07e09e26678ed4fac08a249ebe8ed680bf9051a5e14ad223e4b2b9d26e0208f37a05f6e3f188e3e6eab7d7d3b6568f5eac7d687b08d307d3154ccd8c87b4630509bc0").as_slice();
let block = SealedBlock::decode(&mut block_rlp).unwrap(); let block = SealedBlock::decode(&mut block_rlp).unwrap();
insert_canonical_block(provider.tx_mut(), genesis, None).unwrap(); provider.insert_block(genesis, None).unwrap();
insert_canonical_block(provider.tx_mut(), block.clone(), None).unwrap(); provider.insert_block(block.clone(), None).unwrap();
provider.commit().unwrap(); provider.commit().unwrap();
let previous_stage_checkpoint = ExecutionCheckpoint { let previous_stage_checkpoint = ExecutionCheckpoint {
@ -501,14 +501,14 @@ mod tests {
fn execution_checkpoint_recalculate_full_previous_some() { fn execution_checkpoint_recalculate_full_previous_some() {
let state_db = create_test_db::<WriteMap>(EnvKind::RW); let state_db = create_test_db::<WriteMap>(EnvKind::RW);
let factory = ProviderFactory::new(state_db.as_ref(), MAINNET.clone()); let factory = ProviderFactory::new(state_db.as_ref(), MAINNET.clone());
let mut provider = factory.provider_rw().unwrap(); let provider = factory.provider_rw().unwrap();
let mut genesis_rlp = hex!("f901faf901f5a00000000000000000000000000000000000000000000000000000000000000000a01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347942adc25665018aa1fe0e6bc666dac8fc2697ff9baa045571b40ae66ca7480791bbb2887286e4e4c4b1b298b191c889d6959023a32eda056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421b901000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000083020000808502540be400808000a00000000000000000000000000000000000000000000000000000000000000000880000000000000000c0c0").as_slice(); let mut genesis_rlp = hex!("f901faf901f5a00000000000000000000000000000000000000000000000000000000000000000a01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347942adc25665018aa1fe0e6bc666dac8fc2697ff9baa045571b40ae66ca7480791bbb2887286e4e4c4b1b298b191c889d6959023a32eda056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421b901000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000083020000808502540be400808000a00000000000000000000000000000000000000000000000000000000000000000880000000000000000c0c0").as_slice();
let genesis = SealedBlock::decode(&mut genesis_rlp).unwrap(); let genesis = SealedBlock::decode(&mut genesis_rlp).unwrap();
let mut block_rlp = hex!("f90262f901f9a075c371ba45999d87f4542326910a11af515897aebce5265d3f6acd1f1161f82fa01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347942adc25665018aa1fe0e6bc666dac8fc2697ff9baa098f2dcd87c8ae4083e7017a05456c14eea4b1db2032126e27b3b1563d57d7cc0a08151d548273f6683169524b66ca9fe338b9ce42bc3540046c828fd939ae23bcba03f4e5c2ec5b2170b711d97ee755c160457bb58d8daa338e835ec02ae6860bbabb901000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000083020000018502540be40082a8798203e800a00000000000000000000000000000000000000000000000000000000000000000880000000000000000f863f861800a8405f5e10094100000000000000000000000000000000000000080801ba07e09e26678ed4fac08a249ebe8ed680bf9051a5e14ad223e4b2b9d26e0208f37a05f6e3f188e3e6eab7d7d3b6568f5eac7d687b08d307d3154ccd8c87b4630509bc0").as_slice(); let mut block_rlp = hex!("f90262f901f9a075c371ba45999d87f4542326910a11af515897aebce5265d3f6acd1f1161f82fa01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347942adc25665018aa1fe0e6bc666dac8fc2697ff9baa098f2dcd87c8ae4083e7017a05456c14eea4b1db2032126e27b3b1563d57d7cc0a08151d548273f6683169524b66ca9fe338b9ce42bc3540046c828fd939ae23bcba03f4e5c2ec5b2170b711d97ee755c160457bb58d8daa338e835ec02ae6860bbabb901000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000083020000018502540be40082a8798203e800a00000000000000000000000000000000000000000000000000000000000000000880000000000000000f863f861800a8405f5e10094100000000000000000000000000000000000000080801ba07e09e26678ed4fac08a249ebe8ed680bf9051a5e14ad223e4b2b9d26e0208f37a05f6e3f188e3e6eab7d7d3b6568f5eac7d687b08d307d3154ccd8c87b4630509bc0").as_slice();
let block = SealedBlock::decode(&mut block_rlp).unwrap(); let block = SealedBlock::decode(&mut block_rlp).unwrap();
insert_canonical_block(provider.tx_mut(), genesis, None).unwrap(); provider.insert_block(genesis, None).unwrap();
insert_canonical_block(provider.tx_mut(), block.clone(), None).unwrap(); provider.insert_block(block.clone(), None).unwrap();
provider.commit().unwrap(); provider.commit().unwrap();
let previous_stage_checkpoint = ExecutionCheckpoint { let previous_stage_checkpoint = ExecutionCheckpoint {
@ -537,14 +537,14 @@ mod tests {
fn execution_checkpoint_recalculate_full_previous_none() { fn execution_checkpoint_recalculate_full_previous_none() {
let state_db = create_test_db::<WriteMap>(EnvKind::RW); let state_db = create_test_db::<WriteMap>(EnvKind::RW);
let factory = ProviderFactory::new(state_db.as_ref(), MAINNET.clone()); let factory = ProviderFactory::new(state_db.as_ref(), MAINNET.clone());
let mut provider = factory.provider_rw().unwrap(); let provider = factory.provider_rw().unwrap();
let mut genesis_rlp = hex!("f901faf901f5a00000000000000000000000000000000000000000000000000000000000000000a01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347942adc25665018aa1fe0e6bc666dac8fc2697ff9baa045571b40ae66ca7480791bbb2887286e4e4c4b1b298b191c889d6959023a32eda056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421b901000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000083020000808502540be400808000a00000000000000000000000000000000000000000000000000000000000000000880000000000000000c0c0").as_slice(); let mut genesis_rlp = hex!("f901faf901f5a00000000000000000000000000000000000000000000000000000000000000000a01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347942adc25665018aa1fe0e6bc666dac8fc2697ff9baa045571b40ae66ca7480791bbb2887286e4e4c4b1b298b191c889d6959023a32eda056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421b901000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000083020000808502540be400808000a00000000000000000000000000000000000000000000000000000000000000000880000000000000000c0c0").as_slice();
let genesis = SealedBlock::decode(&mut genesis_rlp).unwrap(); let genesis = SealedBlock::decode(&mut genesis_rlp).unwrap();
let mut block_rlp = hex!("f90262f901f9a075c371ba45999d87f4542326910a11af515897aebce5265d3f6acd1f1161f82fa01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347942adc25665018aa1fe0e6bc666dac8fc2697ff9baa098f2dcd87c8ae4083e7017a05456c14eea4b1db2032126e27b3b1563d57d7cc0a08151d548273f6683169524b66ca9fe338b9ce42bc3540046c828fd939ae23bcba03f4e5c2ec5b2170b711d97ee755c160457bb58d8daa338e835ec02ae6860bbabb901000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000083020000018502540be40082a8798203e800a00000000000000000000000000000000000000000000000000000000000000000880000000000000000f863f861800a8405f5e10094100000000000000000000000000000000000000080801ba07e09e26678ed4fac08a249ebe8ed680bf9051a5e14ad223e4b2b9d26e0208f37a05f6e3f188e3e6eab7d7d3b6568f5eac7d687b08d307d3154ccd8c87b4630509bc0").as_slice(); let mut block_rlp = hex!("f90262f901f9a075c371ba45999d87f4542326910a11af515897aebce5265d3f6acd1f1161f82fa01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347942adc25665018aa1fe0e6bc666dac8fc2697ff9baa098f2dcd87c8ae4083e7017a05456c14eea4b1db2032126e27b3b1563d57d7cc0a08151d548273f6683169524b66ca9fe338b9ce42bc3540046c828fd939ae23bcba03f4e5c2ec5b2170b711d97ee755c160457bb58d8daa338e835ec02ae6860bbabb901000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000083020000018502540be40082a8798203e800a00000000000000000000000000000000000000000000000000000000000000000880000000000000000f863f861800a8405f5e10094100000000000000000000000000000000000000080801ba07e09e26678ed4fac08a249ebe8ed680bf9051a5e14ad223e4b2b9d26e0208f37a05f6e3f188e3e6eab7d7d3b6568f5eac7d687b08d307d3154ccd8c87b4630509bc0").as_slice();
let block = SealedBlock::decode(&mut block_rlp).unwrap(); let block = SealedBlock::decode(&mut block_rlp).unwrap();
insert_canonical_block(provider.tx_mut(), genesis, None).unwrap(); provider.insert_block(genesis, None).unwrap();
insert_canonical_block(provider.tx_mut(), block.clone(), None).unwrap(); provider.insert_block(block.clone(), None).unwrap();
provider.commit().unwrap(); provider.commit().unwrap();
let previous_checkpoint = StageCheckpoint { block_number: 1, stage_checkpoint: None }; let previous_checkpoint = StageCheckpoint { block_number: 1, stage_checkpoint: None };
@ -567,7 +567,7 @@ mod tests {
// is merged as it has similar framework // is merged as it has similar framework
let state_db = create_test_db::<WriteMap>(EnvKind::RW); let state_db = create_test_db::<WriteMap>(EnvKind::RW);
let factory = ProviderFactory::new(state_db.as_ref(), MAINNET.clone()); let factory = ProviderFactory::new(state_db.as_ref(), MAINNET.clone());
let mut provider = factory.provider_rw().unwrap(); let provider = factory.provider_rw().unwrap();
let input = ExecInput { let input = ExecInput {
target: Some(1), target: Some(1),
/// The progress of this stage the last time it was executed. /// The progress of this stage the last time it was executed.
@ -577,13 +577,13 @@ mod tests {
let genesis = SealedBlock::decode(&mut genesis_rlp).unwrap(); let genesis = SealedBlock::decode(&mut genesis_rlp).unwrap();
let mut block_rlp = hex!("f90262f901f9a075c371ba45999d87f4542326910a11af515897aebce5265d3f6acd1f1161f82fa01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347942adc25665018aa1fe0e6bc666dac8fc2697ff9baa098f2dcd87c8ae4083e7017a05456c14eea4b1db2032126e27b3b1563d57d7cc0a08151d548273f6683169524b66ca9fe338b9ce42bc3540046c828fd939ae23bcba03f4e5c2ec5b2170b711d97ee755c160457bb58d8daa338e835ec02ae6860bbabb901000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000083020000018502540be40082a8798203e800a00000000000000000000000000000000000000000000000000000000000000000880000000000000000f863f861800a8405f5e10094100000000000000000000000000000000000000080801ba07e09e26678ed4fac08a249ebe8ed680bf9051a5e14ad223e4b2b9d26e0208f37a05f6e3f188e3e6eab7d7d3b6568f5eac7d687b08d307d3154ccd8c87b4630509bc0").as_slice(); let mut block_rlp = hex!("f90262f901f9a075c371ba45999d87f4542326910a11af515897aebce5265d3f6acd1f1161f82fa01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347942adc25665018aa1fe0e6bc666dac8fc2697ff9baa098f2dcd87c8ae4083e7017a05456c14eea4b1db2032126e27b3b1563d57d7cc0a08151d548273f6683169524b66ca9fe338b9ce42bc3540046c828fd939ae23bcba03f4e5c2ec5b2170b711d97ee755c160457bb58d8daa338e835ec02ae6860bbabb901000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000083020000018502540be40082a8798203e800a00000000000000000000000000000000000000000000000000000000000000000880000000000000000f863f861800a8405f5e10094100000000000000000000000000000000000000080801ba07e09e26678ed4fac08a249ebe8ed680bf9051a5e14ad223e4b2b9d26e0208f37a05f6e3f188e3e6eab7d7d3b6568f5eac7d687b08d307d3154ccd8c87b4630509bc0").as_slice();
let block = SealedBlock::decode(&mut block_rlp).unwrap(); let block = SealedBlock::decode(&mut block_rlp).unwrap();
insert_canonical_block(provider.tx_mut(), genesis, None).unwrap(); provider.insert_block(genesis, None).unwrap();
insert_canonical_block(provider.tx_mut(), block.clone(), None).unwrap(); provider.insert_block(block.clone(), None).unwrap();
provider.commit().unwrap(); provider.commit().unwrap();
// insert pre state // insert pre state
let mut provider = factory.provider_rw().unwrap(); let provider = factory.provider_rw().unwrap();
let db_tx = provider.tx_mut(); let db_tx = provider.tx_ref();
let acc1 = H160(hex!("1000000000000000000000000000000000000000")); let acc1 = H160(hex!("1000000000000000000000000000000000000000"));
let acc2 = H160(hex!("a94f5374fce5edbc8e2a8697c15331677e6ebf0b")); let acc2 = H160(hex!("a94f5374fce5edbc8e2a8697c15331677e6ebf0b"));
let code = hex!("5a465a905090036002900360015500"); let code = hex!("5a465a905090036002900360015500");
@ -676,7 +676,7 @@ mod tests {
let state_db = create_test_db::<WriteMap>(EnvKind::RW); let state_db = create_test_db::<WriteMap>(EnvKind::RW);
let factory = ProviderFactory::new(state_db.as_ref(), MAINNET.clone()); let factory = ProviderFactory::new(state_db.as_ref(), MAINNET.clone());
let mut provider = factory.provider_rw().unwrap(); let provider = factory.provider_rw().unwrap();
let input = ExecInput { let input = ExecInput {
target: Some(1), target: Some(1),
/// The progress of this stage the last time it was executed. /// The progress of this stage the last time it was executed.
@ -686,8 +686,8 @@ mod tests {
let genesis = SealedBlock::decode(&mut genesis_rlp).unwrap(); let genesis = SealedBlock::decode(&mut genesis_rlp).unwrap();
let mut block_rlp = hex!("f90262f901f9a075c371ba45999d87f4542326910a11af515897aebce5265d3f6acd1f1161f82fa01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347942adc25665018aa1fe0e6bc666dac8fc2697ff9baa098f2dcd87c8ae4083e7017a05456c14eea4b1db2032126e27b3b1563d57d7cc0a08151d548273f6683169524b66ca9fe338b9ce42bc3540046c828fd939ae23bcba03f4e5c2ec5b2170b711d97ee755c160457bb58d8daa338e835ec02ae6860bbabb901000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000083020000018502540be40082a8798203e800a00000000000000000000000000000000000000000000000000000000000000000880000000000000000f863f861800a8405f5e10094100000000000000000000000000000000000000080801ba07e09e26678ed4fac08a249ebe8ed680bf9051a5e14ad223e4b2b9d26e0208f37a05f6e3f188e3e6eab7d7d3b6568f5eac7d687b08d307d3154ccd8c87b4630509bc0").as_slice(); let mut block_rlp = hex!("f90262f901f9a075c371ba45999d87f4542326910a11af515897aebce5265d3f6acd1f1161f82fa01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347942adc25665018aa1fe0e6bc666dac8fc2697ff9baa098f2dcd87c8ae4083e7017a05456c14eea4b1db2032126e27b3b1563d57d7cc0a08151d548273f6683169524b66ca9fe338b9ce42bc3540046c828fd939ae23bcba03f4e5c2ec5b2170b711d97ee755c160457bb58d8daa338e835ec02ae6860bbabb901000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000083020000018502540be40082a8798203e800a00000000000000000000000000000000000000000000000000000000000000000880000000000000000f863f861800a8405f5e10094100000000000000000000000000000000000000080801ba07e09e26678ed4fac08a249ebe8ed680bf9051a5e14ad223e4b2b9d26e0208f37a05f6e3f188e3e6eab7d7d3b6568f5eac7d687b08d307d3154ccd8c87b4630509bc0").as_slice();
let block = SealedBlock::decode(&mut block_rlp).unwrap(); let block = SealedBlock::decode(&mut block_rlp).unwrap();
insert_canonical_block(provider.tx_mut(), genesis, None).unwrap(); provider.insert_block(genesis, None).unwrap();
insert_canonical_block(provider.tx_mut(), block.clone(), None).unwrap(); provider.insert_block(block.clone(), None).unwrap();
provider.commit().unwrap(); provider.commit().unwrap();
// variables // variables
@ -695,8 +695,8 @@ mod tests {
let balance = U256::from(0x3635c9adc5dea00000u128); let balance = U256::from(0x3635c9adc5dea00000u128);
let code_hash = keccak256(code); let code_hash = keccak256(code);
// pre state // pre state
let mut provider = factory.provider_rw().unwrap(); let provider = factory.provider_rw().unwrap();
let db_tx = provider.tx_mut(); let db_tx = provider.tx_ref();
let acc1 = H160(hex!("1000000000000000000000000000000000000000")); let acc1 = H160(hex!("1000000000000000000000000000000000000000"));
let acc1_info = Account { nonce: 0, balance: U256::ZERO, bytecode_hash: Some(code_hash) }; let acc1_info = Account { nonce: 0, balance: U256::ZERO, bytecode_hash: Some(code_hash) };
let acc2 = H160(hex!("a94f5374fce5edbc8e2a8697c15331677e6ebf0b")); let acc2 = H160(hex!("a94f5374fce5edbc8e2a8697c15331677e6ebf0b"));
@ -753,7 +753,7 @@ mod tests {
async fn test_selfdestruct() { async fn test_selfdestruct() {
let test_tx = TestTransaction::default(); let test_tx = TestTransaction::default();
let factory = ProviderFactory::new(test_tx.tx.as_ref(), MAINNET.clone()); let factory = ProviderFactory::new(test_tx.tx.as_ref(), MAINNET.clone());
let mut provider = factory.provider_rw().unwrap(); let provider = factory.provider_rw().unwrap();
let input = ExecInput { let input = ExecInput {
target: Some(1), target: Some(1),
/// The progress of this stage the last time it was executed. /// The progress of this stage the last time it was executed.
@ -763,8 +763,8 @@ mod tests {
let genesis = SealedBlock::decode(&mut genesis_rlp).unwrap(); let genesis = SealedBlock::decode(&mut genesis_rlp).unwrap();
let mut block_rlp = hex!("f9025ff901f7a0c86e8cc0310ae7c531c758678ddbfd16fc51c8cef8cec650b032de9869e8b94fa01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347942adc25665018aa1fe0e6bc666dac8fc2697ff9baa050554882fbbda2c2fd93fdc466db9946ea262a67f7a76cc169e714f105ab583da00967f09ef1dfed20c0eacfaa94d5cd4002eda3242ac47eae68972d07b106d192a0e3c8b47fbfc94667ef4cceb17e5cc21e3b1eebd442cebb27f07562b33836290db90100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008302000001830f42408238108203e800a00000000000000000000000000000000000000000000000000000000000000000880000000000000000f862f860800a83061a8094095e7baea6a6c7c4c2dfeb977efac326af552d8780801ba072ed817487b84ba367d15d2f039b5fc5f087d0a8882fbdf73e8cb49357e1ce30a0403d800545b8fc544f92ce8124e2255f8c3c6af93f28243a120585d4c4c6a2a3c0").as_slice(); let mut block_rlp = hex!("f9025ff901f7a0c86e8cc0310ae7c531c758678ddbfd16fc51c8cef8cec650b032de9869e8b94fa01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347942adc25665018aa1fe0e6bc666dac8fc2697ff9baa050554882fbbda2c2fd93fdc466db9946ea262a67f7a76cc169e714f105ab583da00967f09ef1dfed20c0eacfaa94d5cd4002eda3242ac47eae68972d07b106d192a0e3c8b47fbfc94667ef4cceb17e5cc21e3b1eebd442cebb27f07562b33836290db90100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008302000001830f42408238108203e800a00000000000000000000000000000000000000000000000000000000000000000880000000000000000f862f860800a83061a8094095e7baea6a6c7c4c2dfeb977efac326af552d8780801ba072ed817487b84ba367d15d2f039b5fc5f087d0a8882fbdf73e8cb49357e1ce30a0403d800545b8fc544f92ce8124e2255f8c3c6af93f28243a120585d4c4c6a2a3c0").as_slice();
let block = SealedBlock::decode(&mut block_rlp).unwrap(); let block = SealedBlock::decode(&mut block_rlp).unwrap();
insert_canonical_block(provider.tx_mut(), genesis, None).unwrap(); provider.insert_block(genesis, None).unwrap();
insert_canonical_block(provider.tx_mut(), block.clone(), None).unwrap(); provider.insert_block(block.clone(), None).unwrap();
provider.commit().unwrap(); provider.commit().unwrap();
// variables // variables

View File

@ -88,14 +88,14 @@ impl AccountHashingStage {
generators::{random_block_range, random_eoa_account_range}, generators::{random_block_range, random_eoa_account_range},
}; };
use reth_primitives::{Account, H256, U256}; use reth_primitives::{Account, H256, U256};
use reth_provider::insert_canonical_block; use reth_provider::BlockWriter;
let mut rng = generators::rng(); let mut rng = generators::rng();
let blocks = random_block_range(&mut rng, opts.blocks.clone(), H256::zero(), opts.txs); let blocks = random_block_range(&mut rng, opts.blocks.clone(), H256::zero(), opts.txs);
for block in blocks { for block in blocks {
insert_canonical_block(provider.tx_ref(), block, None).unwrap(); provider.insert_block(block, None).unwrap();
} }
let mut accounts = random_eoa_account_range(&mut rng, opts.accounts); let mut accounts = random_eoa_account_range(&mut rng, opts.accounts);
{ {

View File

@ -76,10 +76,10 @@ impl TestTransaction {
/// Invoke a callback with transaction committing it afterwards /// Invoke a callback with transaction committing it afterwards
pub fn commit<F>(&self, f: F) -> Result<(), DbError> pub fn commit<F>(&self, f: F) -> Result<(), DbError>
where where
F: FnOnce(&mut Tx<'_, RW, WriteMap>) -> Result<(), DbError>, F: FnOnce(&Tx<'_, RW, WriteMap>) -> Result<(), DbError>,
{ {
let mut tx = self.inner_rw(); let mut tx = self.inner_rw();
f(tx.tx_mut())?; f(tx.tx_ref())?;
tx.commit().expect("failed to commit"); tx.commit().expect("failed to commit");
Ok(()) Ok(())
} }
@ -200,7 +200,7 @@ impl TestTransaction {
} }
/// Inserts a single [SealedHeader] into the corresponding tables of the headers stage. /// Inserts a single [SealedHeader] into the corresponding tables of the headers stage.
fn insert_header(tx: &mut Tx<'_, RW, WriteMap>, header: &SealedHeader) -> Result<(), DbError> { fn insert_header(tx: &Tx<'_, RW, WriteMap>, header: &SealedHeader) -> Result<(), DbError> {
tx.put::<tables::CanonicalHeaders>(header.number, header.hash())?; tx.put::<tables::CanonicalHeaders>(header.number, header.hash())?;
tx.put::<tables::HeaderNumbers>(header.hash(), header.number)?; tx.put::<tables::HeaderNumbers>(header.hash(), header.number)?;
tx.put::<tables::Headers>(header.number, header.clone().unseal()) tx.put::<tables::Headers>(header.number, header.clone().unseal())

View File

@ -21,14 +21,14 @@
/// Various provider traits. /// Various provider traits.
mod traits; mod traits;
pub use traits::{ pub use traits::{
AccountExtReader, AccountReader, BlockExecutor, BlockHashReader, BlockIdReader, BlockNumReader, AccountExtReader, AccountReader, BlockExecutionWriter, BlockExecutor, BlockHashReader,
BlockReader, BlockReaderIdExt, BlockSource, BlockchainTreePendingStateProvider, BlockIdReader, BlockNumReader, BlockReader, BlockReaderIdExt, BlockSource, BlockWriter,
CanonChainTracker, CanonStateNotification, CanonStateNotificationSender, BlockchainTreePendingStateProvider, CanonChainTracker, CanonStateNotification,
CanonStateNotifications, CanonStateSubscriptions, EvmEnvProvider, ExecutorFactory, CanonStateNotificationSender, CanonStateNotifications, CanonStateSubscriptions, EvmEnvProvider,
HashingWriter, HeaderProvider, HistoryWriter, PostStateDataProvider, ReceiptProvider, ExecutorFactory, HashingWriter, HeaderProvider, HistoryWriter, PostStateDataProvider,
ReceiptProviderIdExt, StageCheckpointReader, StageCheckpointWriter, StateProvider, ReceiptProvider, ReceiptProviderIdExt, StageCheckpointReader, StageCheckpointWriter,
StateProviderBox, StateProviderFactory, StateRootProvider, StorageReader, TransactionsProvider, StateProvider, StateProviderBox, StateProviderFactory, StateRootProvider, StorageReader,
WithdrawalsProvider, TransactionsProvider, WithdrawalsProvider,
}; };
/// Provider trait implementations. /// Provider trait implementations.
@ -42,10 +42,6 @@ pub use providers::{
pub mod post_state; pub mod post_state;
pub use post_state::PostState; pub use post_state::PostState;
/// Common database utilities.
mod utils;
pub use utils::{insert_block, insert_canonical_block};
#[cfg(any(test, feature = "test-utils"))] #[cfg(any(test, feature = "test-utils"))]
/// Common test helpers for mocking the Provider. /// Common test helpers for mocking the Provider.
pub mod test_utils; pub mod test_utils;

View File

@ -1,10 +1,9 @@
use crate::{ use crate::{
insert_canonical_block,
post_state::StorageChangeset, post_state::StorageChangeset,
traits::{AccountExtReader, BlockSource, ReceiptProvider, StageCheckpointWriter}, traits::{AccountExtReader, BlockSource, ReceiptProvider, StageCheckpointWriter},
AccountReader, BlockHashReader, BlockNumReader, BlockReader, EvmEnvProvider, HashingWriter, AccountReader, BlockExecutionWriter, BlockHashReader, BlockNumReader, BlockReader, BlockWriter,
HeaderProvider, HistoryWriter, PostState, ProviderError, StageCheckpointReader, StorageReader, EvmEnvProvider, HashingWriter, HeaderProvider, HistoryWriter, PostState, ProviderError,
TransactionsProvider, WithdrawalsProvider, StageCheckpointReader, StorageReader, TransactionsProvider, WithdrawalsProvider,
}; };
use itertools::{izip, Itertools}; use itertools::{izip, Itertools};
use reth_db::{ use reth_db::{
@ -13,7 +12,7 @@ use reth_db::{
database::{Database, DatabaseGAT}, database::{Database, DatabaseGAT},
models::{ models::{
sharded_key, storage_sharded_key::StorageShardedKey, AccountBeforeTx, BlockNumberAddress, sharded_key, storage_sharded_key::StorageShardedKey, AccountBeforeTx, BlockNumberAddress,
ShardedKey, StoredBlockBodyIndices, ShardedKey, StoredBlockBodyIndices, StoredBlockOmmers, StoredBlockWithdrawals,
}, },
table::Table, table::Table,
tables, tables,
@ -190,24 +189,6 @@ impl<'this, TX: DbTxMut<'this> + DbTx<'this>> DatabaseProvider<'this, TX> {
// TODO(joshie) TEMPORARY should be moved to trait providers // TODO(joshie) TEMPORARY should be moved to trait providers
/// Get range of blocks and its execution result
pub fn get_block_and_execution_range(
&self,
chain_spec: &ChainSpec,
range: RangeInclusive<BlockNumber>,
) -> Result<Vec<(SealedBlockWithSenders, PostState)>> {
self.get_take_block_and_execution_range::<false>(chain_spec, range)
}
/// Take range of blocks and its execution result
pub fn take_block_and_execution_range(
&self,
chain_spec: &ChainSpec,
range: RangeInclusive<BlockNumber>,
) -> Result<Vec<(SealedBlockWithSenders, PostState)>> {
self.get_take_block_and_execution_range::<true>(chain_spec, range)
}
/// Traverse over changesets and plain state and recreate the [`PostState`]s for the given range /// Traverse over changesets and plain state and recreate the [`PostState`]s for the given range
/// of blocks. /// of blocks.
/// ///
@ -389,72 +370,6 @@ impl<'this, TX: DbTxMut<'this> + DbTx<'this>> DatabaseProvider<'this, TX> {
Ok(block_states.into_values().collect()) Ok(block_states.into_values().collect())
} }
/// Return range of blocks and its execution result
pub fn get_take_block_and_execution_range<const TAKE: bool>(
&self,
chain_spec: &ChainSpec,
range: RangeInclusive<BlockNumber>,
) -> Result<Vec<(SealedBlockWithSenders, PostState)>> {
if TAKE {
let storage_range = BlockNumberAddress::range(range.clone());
self.unwind_account_hashing(range.clone())?;
self.unwind_account_history_indices(range.clone())?;
self.unwind_storage_hashing(storage_range.clone())?;
self.unwind_storage_history_indices(storage_range)?;
// merkle tree
let (new_state_root, trie_updates) =
StateRoot::incremental_root_with_updates(&self.tx, range.clone())
.map_err(Into::<reth_db::DatabaseError>::into)?;
let parent_number = range.start().saturating_sub(1);
let parent_state_root = self
.header_by_number(parent_number)?
.ok_or_else(|| ProviderError::HeaderNotFound(parent_number.into()))?
.state_root;
// state root should be always correct as we are reverting state.
// but for sake of double verification we will check it again.
if new_state_root != parent_state_root {
let parent_hash = self
.block_hash(parent_number)?
.ok_or_else(|| ProviderError::HeaderNotFound(parent_number.into()))?;
return Err(ProviderError::UnwindStateRootMismatch {
got: new_state_root,
expected: parent_state_root,
block_number: parent_number,
block_hash: parent_hash,
}
.into())
}
trie_updates.flush(&self.tx)?;
}
// get blocks
let blocks = self.get_take_block_range::<TAKE>(chain_spec, range.clone())?;
let unwind_to = blocks.first().map(|b| b.number.saturating_sub(1));
// get execution res
let execution_res = self.get_take_block_execution_result_range::<TAKE>(range.clone())?;
// combine them
let blocks_with_exec_result: Vec<_> =
blocks.into_iter().zip(execution_res.into_iter()).collect();
// remove block bodies it is needed for both get block range and get block execution results
// that is why it is deleted afterwards.
if TAKE {
// rm block bodies
self.get_or_take::<tables::BlockBodyIndices, TAKE>(range)?;
// Update pipeline progress
if let Some(fork_number) = unwind_to {
self.update_pipeline_stages(fork_number, true)?;
}
}
// return them
Ok(blocks_with_exec_result)
}
/// Return list of entries from table /// Return list of entries from table
/// ///
/// If TAKE is true, opened cursor would be write and it would delete all values from db. /// If TAKE is true, opened cursor would be write and it would delete all values from db.
@ -770,56 +685,6 @@ impl<'this, TX: DbTxMut<'this> + DbTx<'this>> DatabaseProvider<'this, TX> {
} }
Ok(()) Ok(())
} }
/// Append blocks and insert its post state.
/// This will insert block data to all related tables and will update pipeline progress.
pub fn append_blocks_with_post_state(
&mut self,
blocks: Vec<SealedBlockWithSenders>,
state: PostState,
) -> Result<()> {
if blocks.is_empty() {
return Ok(())
}
let new_tip = blocks.last().unwrap();
let new_tip_number = new_tip.number;
let first_number = blocks.first().unwrap().number;
let last = blocks.last().unwrap();
let last_block_number = last.number;
let last_block_hash = last.hash();
let expected_state_root = last.state_root;
// Insert the blocks
for block in blocks {
let (block, senders) = block.into_components();
insert_canonical_block(self.tx_mut(), block, Some(senders))?;
}
// Write state and changesets to the database.
// Must be written after blocks because of the receipt lookup.
state.write_to_db(self.tx_mut())?;
self.insert_hashes(first_number..=last_block_number, last_block_hash, expected_state_root)?;
self.calculate_history_indices(first_number..=last_block_number)?;
// Update pipeline progress
self.update_pipeline_stages(new_tip_number, false)?;
Ok(())
}
/// Insert full block and make it canonical.
pub fn insert_block(
&mut self,
block: SealedBlock,
senders: Option<Vec<Address>>,
) -> Result<()> {
insert_canonical_block(self.tx_mut(), block, senders)?;
Ok(())
}
} }
impl<'this, TX: DbTx<'this>> AccountReader for DatabaseProvider<'this, TX> { impl<'this, TX: DbTx<'this>> AccountReader for DatabaseProvider<'this, TX> {
@ -1745,3 +1610,192 @@ impl<'this, TX: DbTxMut<'this> + DbTx<'this>> HistoryWriter for DatabaseProvider
Ok(changesets) Ok(changesets)
} }
} }
impl<'this, TX: DbTxMut<'this> + DbTx<'this>> BlockExecutionWriter for DatabaseProvider<'this, TX> {
fn get_or_take_block_and_execution_range<const TAKE: bool>(
&self,
chain_spec: &ChainSpec,
range: RangeInclusive<BlockNumber>,
) -> Result<Vec<(SealedBlockWithSenders, PostState)>> {
if TAKE {
let storage_range = BlockNumberAddress::range(range.clone());
self.unwind_account_hashing(range.clone())?;
self.unwind_account_history_indices(range.clone())?;
self.unwind_storage_hashing(storage_range.clone())?;
self.unwind_storage_history_indices(storage_range)?;
// merkle tree
let (new_state_root, trie_updates) =
StateRoot::incremental_root_with_updates(&self.tx, range.clone())
.map_err(Into::<reth_db::DatabaseError>::into)?;
let parent_number = range.start().saturating_sub(1);
let parent_state_root = self
.header_by_number(parent_number)?
.ok_or_else(|| ProviderError::HeaderNotFound(parent_number.into()))?
.state_root;
// state root should be always correct as we are reverting state.
// but for sake of double verification we will check it again.
if new_state_root != parent_state_root {
let parent_hash = self
.block_hash(parent_number)?
.ok_or_else(|| ProviderError::HeaderNotFound(parent_number.into()))?;
return Err(ProviderError::UnwindStateRootMismatch {
got: new_state_root,
expected: parent_state_root,
block_number: parent_number,
block_hash: parent_hash,
}
.into())
}
trie_updates.flush(&self.tx)?;
}
// get blocks
let blocks = self.get_take_block_range::<TAKE>(chain_spec, range.clone())?;
let unwind_to = blocks.first().map(|b| b.number.saturating_sub(1));
// get execution res
let execution_res = self.get_take_block_execution_result_range::<TAKE>(range.clone())?;
// combine them
let blocks_with_exec_result: Vec<_> =
blocks.into_iter().zip(execution_res.into_iter()).collect();
// remove block bodies it is needed for both get block range and get block execution results
// that is why it is deleted afterwards.
if TAKE {
// rm block bodies
self.get_or_take::<tables::BlockBodyIndices, TAKE>(range)?;
// Update pipeline progress
if let Some(fork_number) = unwind_to {
self.update_pipeline_stages(fork_number, true)?;
}
}
// return them
Ok(blocks_with_exec_result)
}
}
impl<'this, TX: DbTxMut<'this> + DbTx<'this>> BlockWriter for DatabaseProvider<'this, TX> {
fn insert_block(
&self,
block: SealedBlock,
senders: Option<Vec<Address>>,
) -> Result<StoredBlockBodyIndices> {
let block_number = block.number;
self.tx.put::<tables::CanonicalHeaders>(block.number, block.hash())?;
// Put header with canonical hashes.
self.tx.put::<tables::Headers>(block.number, block.header.as_ref().clone())?;
self.tx.put::<tables::HeaderNumbers>(block.hash(), block.number)?;
// total difficulty
let ttd = if block.number == 0 {
block.difficulty
} else {
let parent_block_number = block.number - 1;
let parent_ttd =
self.tx.get::<tables::HeaderTD>(parent_block_number)?.unwrap_or_default();
parent_ttd.0 + block.difficulty
};
self.tx.put::<tables::HeaderTD>(block.number, ttd.into())?;
// insert body ommers data
if !block.ommers.is_empty() {
self.tx.put::<tables::BlockOmmers>(
block.number,
StoredBlockOmmers { ommers: block.ommers },
)?;
}
let mut next_tx_num = self
.tx
.cursor_read::<tables::Transactions>()?
.last()?
.map(|(n, _)| n + 1)
.unwrap_or_default();
let first_tx_num = next_tx_num;
let tx_count = block.body.len() as u64;
let senders_len = senders.as_ref().map(|s| s.len());
let tx_iter = if Some(block.body.len()) == senders_len {
block.body.into_iter().zip(senders.unwrap().into_iter()).collect::<Vec<(_, _)>>()
} else {
block
.body
.into_iter()
.map(|tx| {
let signer = tx.recover_signer();
(tx, signer.unwrap_or_default())
})
.collect::<Vec<(_, _)>>()
};
for (transaction, sender) in tx_iter {
let hash = transaction.hash();
self.tx.put::<tables::TxSenders>(next_tx_num, sender)?;
self.tx.put::<tables::Transactions>(next_tx_num, transaction.into())?;
self.tx.put::<tables::TxHashNumber>(hash, next_tx_num)?;
next_tx_num += 1;
}
if let Some(withdrawals) = block.withdrawals {
if !withdrawals.is_empty() {
self.tx.put::<tables::BlockWithdrawals>(
block_number,
StoredBlockWithdrawals { withdrawals },
)?;
}
}
let block_indices = StoredBlockBodyIndices { first_tx_num, tx_count };
self.tx.put::<tables::BlockBodyIndices>(block_number, block_indices.clone())?;
if !block_indices.is_empty() {
self.tx.put::<tables::TransactionBlock>(block_indices.last_tx_num(), block_number)?;
}
Ok(block_indices)
}
fn append_blocks_with_post_state(
&self,
blocks: Vec<SealedBlockWithSenders>,
state: PostState,
) -> Result<()> {
if blocks.is_empty() {
return Ok(())
}
let new_tip = blocks.last().unwrap();
let new_tip_number = new_tip.number;
let first_number = blocks.first().unwrap().number;
let last = blocks.last().unwrap();
let last_block_number = last.number;
let last_block_hash = last.hash();
let expected_state_root = last.state_root;
// Insert the blocks
for block in blocks {
let (block, senders) = block.into_components();
self.insert_block(block, Some(senders))?;
}
// Write state and changesets to the database.
// Must be written after blocks because of the receipt lookup.
state.write_to_db(self.tx_ref())?;
self.insert_hashes(first_number..=last_block_number, last_block_hash, expected_state_root)?;
self.calculate_history_indices(first_number..=last_block_number)?;
// Update pipeline progress
self.update_pipeline_stages(new_tip_number, false)?;
Ok(())
}
}

View File

@ -1,13 +1,15 @@
use crate::{ use crate::{
BlockIdReader, BlockNumReader, HeaderProvider, ReceiptProvider, ReceiptProviderIdExt, BlockIdReader, BlockNumReader, HeaderProvider, PostState, ReceiptProvider,
TransactionsProvider, WithdrawalsProvider, ReceiptProviderIdExt, TransactionsProvider, WithdrawalsProvider,
}; };
use auto_impl::auto_impl;
use reth_db::models::StoredBlockBodyIndices; use reth_db::models::StoredBlockBodyIndices;
use reth_interfaces::Result; use reth_interfaces::Result;
use reth_primitives::{ use reth_primitives::{
Block, BlockHashOrNumber, BlockId, BlockNumber, BlockNumberOrTag, BlockWithSenders, Header, Address, Block, BlockHashOrNumber, BlockId, BlockNumber, BlockNumberOrTag, BlockWithSenders,
Receipt, SealedBlock, SealedHeader, H256, ChainSpec, Header, Receipt, SealedBlock, SealedBlockWithSenders, SealedHeader, H256,
}; };
use std::ops::RangeInclusive;
/// A helper enum that represents the origin of the requested block. /// A helper enum that represents the origin of the requested block.
/// ///
@ -198,3 +200,55 @@ pub trait BlockReaderIdExt: BlockReader + BlockIdReader + ReceiptProviderIdExt {
/// Returns `None` if block is not found. /// Returns `None` if block is not found.
fn ommers_by_id(&self, id: BlockId) -> Result<Option<Vec<Header>>>; fn ommers_by_id(&self, id: BlockId) -> Result<Option<Vec<Header>>>;
} }
/// BlockExecution Writer
#[auto_impl(&, Arc, Box)]
pub trait BlockExecutionWriter: BlockWriter + BlockReader + Send + Sync {
/// Get range of blocks and its execution result
fn get_block_and_execution_range(
&self,
chain_spec: &ChainSpec,
range: RangeInclusive<BlockNumber>,
) -> Result<Vec<(SealedBlockWithSenders, PostState)>> {
self.get_or_take_block_and_execution_range::<false>(chain_spec, range)
}
/// Take range of blocks and its execution result
fn take_block_and_execution_range(
&self,
chain_spec: &ChainSpec,
range: RangeInclusive<BlockNumber>,
) -> Result<Vec<(SealedBlockWithSenders, PostState)>> {
self.get_or_take_block_and_execution_range::<true>(chain_spec, range)
}
/// Return range of blocks and its execution result
fn get_or_take_block_and_execution_range<const TAKE: bool>(
&self,
chain_spec: &ChainSpec,
range: RangeInclusive<BlockNumber>,
) -> Result<Vec<(SealedBlockWithSenders, PostState)>>;
}
/// Block Writer
#[auto_impl(&, Arc, Box)]
pub trait BlockWriter: Send + Sync {
/// Insert full block and make it canonical. Parent tx num and transition id is taken from
/// parent block in database.
///
/// Return [StoredBlockBodyIndices] that contains indices of the first and last transactions and
/// transition in the block.
fn insert_block(
&self,
block: SealedBlock,
senders: Option<Vec<Address>>,
) -> Result<StoredBlockBodyIndices>;
/// Append blocks and insert its post state.
/// This will insert block data to all related tables and will update pipeline progress.
fn append_blocks_with_post_state(
&self,
blocks: Vec<SealedBlockWithSenders>,
state: PostState,
) -> Result<()>;
}

View File

@ -7,7 +7,7 @@ mod storage;
pub use storage::StorageReader; pub use storage::StorageReader;
mod block; mod block;
pub use block::{BlockReader, BlockReaderIdExt, BlockSource}; pub use block::{BlockExecutionWriter, BlockReader, BlockReaderIdExt, BlockSource, BlockWriter};
mod block_hash; mod block_hash;
pub use block_hash::BlockHashReader; pub use block_hash::BlockHashReader;

View File

@ -5,9 +5,7 @@ use std::fmt::Debug;
#[cfg(test)] #[cfg(test)]
mod test { mod test {
use crate::{ use crate::{test_utils::blocks::*, ProviderFactory, TransactionsProvider};
insert_canonical_block, test_utils::blocks::*, ProviderFactory, TransactionsProvider,
};
use reth_db::{ use reth_db::{
mdbx::test_utils::create_test_rw_db, mdbx::test_utils::create_test_rw_db,
models::{storage_sharded_key::StorageShardedKey, ShardedKey}, models::{storage_sharded_key::StorageShardedKey, ShardedKey},
@ -40,7 +38,7 @@ mod test {
let storage1_shard_key = let storage1_shard_key =
StorageShardedKey::new(H160([0x60; 20]), U256::from(5).into(), u64::MAX); StorageShardedKey::new(H160([0x60; 20]), U256::from(5).into(), u64::MAX);
insert_canonical_block(provider.tx_ref(), data.genesis.clone(), None).unwrap(); provider.insert_block(data.genesis.clone(), None).unwrap();
assert_genesis_block(&provider, data.genesis); assert_genesis_block(&provider, data.genesis);
@ -153,7 +151,7 @@ mod test {
let (block1, exec_res1) = data.blocks[0].clone(); let (block1, exec_res1) = data.blocks[0].clone();
let (block2, exec_res2) = data.blocks[1].clone(); let (block2, exec_res2) = data.blocks[1].clone();
insert_canonical_block(provider.tx_mut(), data.genesis.clone(), None).unwrap(); provider.insert_block(data.genesis.clone(), None).unwrap();
assert_genesis_block(&provider, data.genesis); assert_genesis_block(&provider, data.genesis);

View File

@ -1,103 +0,0 @@
use reth_db::{
cursor::DbCursorRO,
models::{StoredBlockBodyIndices, StoredBlockOmmers, StoredBlockWithdrawals},
tables,
transaction::{DbTx, DbTxMut},
DatabaseError,
};
use reth_primitives::{Address, SealedBlock};
/// Insert block data into corresponding tables. Used mainly for testing & internal tooling.
///
///
/// Check parent dependency in [tables::HeaderNumbers] and in [tables::BlockBodyIndices] tables.
/// Inserts header data to [tables::CanonicalHeaders], [tables::Headers], [tables::HeaderNumbers].
/// and transactions data to [tables::TxSenders], [tables::Transactions], [tables::TxHashNumber].
/// and transition/transaction meta data to [tables::BlockBodyIndices]
/// and block data to [tables::BlockOmmers] and [tables::BlockWithdrawals].
///
/// Return [StoredBlockBodyIndices] that contains indices of the first and last transactions and
/// transition in the block.
pub fn insert_block<'a, TX: DbTxMut<'a> + DbTx<'a>>(
tx: &TX,
block: SealedBlock,
senders: Option<Vec<Address>>,
) -> Result<StoredBlockBodyIndices, DatabaseError> {
let block_number = block.number;
tx.put::<tables::CanonicalHeaders>(block.number, block.hash())?;
// Put header with canonical hashes.
tx.put::<tables::Headers>(block.number, block.header.as_ref().clone())?;
tx.put::<tables::HeaderNumbers>(block.hash(), block.number)?;
// total difficulty
let ttd = if block.number == 0 {
block.difficulty
} else {
let parent_block_number = block.number - 1;
let parent_ttd = tx.get::<tables::HeaderTD>(parent_block_number)?.unwrap_or_default();
parent_ttd.0 + block.difficulty
};
tx.put::<tables::HeaderTD>(block.number, ttd.into())?;
// insert body ommers data
if !block.ommers.is_empty() {
tx.put::<tables::BlockOmmers>(block.number, StoredBlockOmmers { ommers: block.ommers })?;
}
let mut next_tx_num =
tx.cursor_read::<tables::Transactions>()?.last()?.map(|(n, _)| n + 1).unwrap_or_default();
let first_tx_num = next_tx_num;
let tx_count = block.body.len() as u64;
let senders_len = senders.as_ref().map(|s| s.len());
let tx_iter = if Some(block.body.len()) == senders_len {
block.body.into_iter().zip(senders.unwrap().into_iter()).collect::<Vec<(_, _)>>()
} else {
block
.body
.into_iter()
.map(|tx| {
let signer = tx.recover_signer();
(tx, signer.unwrap_or_default())
})
.collect::<Vec<(_, _)>>()
};
for (transaction, sender) in tx_iter {
let hash = transaction.hash();
tx.put::<tables::TxSenders>(next_tx_num, sender)?;
tx.put::<tables::Transactions>(next_tx_num, transaction.into())?;
tx.put::<tables::TxHashNumber>(hash, next_tx_num)?;
next_tx_num += 1;
}
if let Some(withdrawals) = block.withdrawals {
if !withdrawals.is_empty() {
tx.put::<tables::BlockWithdrawals>(
block_number,
StoredBlockWithdrawals { withdrawals },
)?;
}
}
let block_indices = StoredBlockBodyIndices { first_tx_num, tx_count };
tx.put::<tables::BlockBodyIndices>(block_number, block_indices.clone())?;
if !block_indices.is_empty() {
tx.put::<tables::TransactionBlock>(block_indices.last_tx_num(), block_number)?;
}
Ok(block_indices)
}
/// Inserts canonical block in blockchain. Parent tx num and transition id is taken from
/// parent block in database.
pub fn insert_canonical_block<'a, TX: DbTxMut<'a> + DbTx<'a>>(
tx: &TX,
block: SealedBlock,
senders: Option<Vec<Address>>,
) -> Result<StoredBlockBodyIndices, DatabaseError> {
insert_block(tx, block, senders)
}

View File

@ -529,7 +529,7 @@ mod tests {
use std::{collections::BTreeMap, ops::Mul, str::FromStr}; use std::{collections::BTreeMap, ops::Mul, str::FromStr};
fn insert_account<'a, TX: DbTxMut<'a>>( fn insert_account<'a, TX: DbTxMut<'a>>(
tx: &mut TX, tx: &TX,
address: Address, address: Address,
account: Account, account: Account,
storage: &BTreeMap<H256, U256>, storage: &BTreeMap<H256, U256>,
@ -540,7 +540,7 @@ mod tests {
} }
fn insert_storage<'a, TX: DbTxMut<'a>>( fn insert_storage<'a, TX: DbTxMut<'a>>(
tx: &mut TX, tx: &TX,
hashed_address: H256, hashed_address: H256,
storage: &BTreeMap<H256, U256>, storage: &BTreeMap<H256, U256>,
) { ) {
@ -556,7 +556,7 @@ mod tests {
fn incremental_vs_full_root(inputs: &[&str], modified: &str) { fn incremental_vs_full_root(inputs: &[&str], modified: &str) {
let db = create_test_rw_db(); let db = create_test_rw_db();
let factory = ProviderFactory::new(db.as_ref(), MAINNET.clone()); let factory = ProviderFactory::new(db.as_ref(), MAINNET.clone());
let mut tx = factory.provider_rw().unwrap(); let tx = factory.provider_rw().unwrap();
let hashed_address = H256::from_low_u64_be(1); let hashed_address = H256::from_low_u64_be(1);
let mut hashed_storage_cursor = let mut hashed_storage_cursor =
@ -592,7 +592,7 @@ mod tests {
// 3. Calculate the incremental root // 3. Calculate the incremental root
let mut storage_changes = PrefixSet::default(); let mut storage_changes = PrefixSet::default();
storage_changes.insert(Nibbles::unpack(modified_key)); storage_changes.insert(Nibbles::unpack(modified_key));
let loader = StorageRoot::new_hashed(tx.tx_mut(), hashed_address) let loader = StorageRoot::new_hashed(tx.tx_ref(), hashed_address)
.with_changed_prefixes(storage_changes); .with_changed_prefixes(storage_changes);
let incremental_root = loader.root().unwrap(); let incremental_root = loader.root().unwrap();
@ -633,8 +633,8 @@ mod tests {
} }
tx.commit().unwrap(); tx.commit().unwrap();
let mut tx = factory.provider_rw().unwrap(); let tx = factory.provider_rw().unwrap();
let got = StorageRoot::new(tx.tx_mut(), address).root().unwrap(); let got = StorageRoot::new(tx.tx_ref(), address).root().unwrap();
let expected = storage_root(storage.into_iter()); let expected = storage_root(storage.into_iter());
assert_eq!(expected, got); assert_eq!(expected, got);
}); });
@ -681,7 +681,7 @@ mod tests {
fn test_empty_storage_root() { fn test_empty_storage_root() {
let db = create_test_rw_db(); let db = create_test_rw_db();
let factory = ProviderFactory::new(db.as_ref(), MAINNET.clone()); let factory = ProviderFactory::new(db.as_ref(), MAINNET.clone());
let mut tx = factory.provider_rw().unwrap(); let tx = factory.provider_rw().unwrap();
let address = Address::random(); let address = Address::random();
let code = "el buen fla"; let code = "el buen fla";
@ -690,11 +690,11 @@ mod tests {
balance: U256::from(414241124u32), balance: U256::from(414241124u32),
bytecode_hash: Some(keccak256(code)), bytecode_hash: Some(keccak256(code)),
}; };
insert_account(tx.tx_mut(), address, account, &Default::default()); insert_account(tx.tx_ref(), address, account, &Default::default());
tx.commit().unwrap(); tx.commit().unwrap();
let mut tx = factory.provider_rw().unwrap(); let tx = factory.provider_rw().unwrap();
let got = StorageRoot::new(tx.tx_mut(), address).root().unwrap(); let got = StorageRoot::new(tx.tx_ref(), address).root().unwrap();
assert_eq!(got, EMPTY_ROOT); assert_eq!(got, EMPTY_ROOT);
} }
@ -703,7 +703,7 @@ mod tests {
fn test_storage_root() { fn test_storage_root() {
let db = create_test_rw_db(); let db = create_test_rw_db();
let factory = ProviderFactory::new(db.as_ref(), MAINNET.clone()); let factory = ProviderFactory::new(db.as_ref(), MAINNET.clone());
let mut tx = factory.provider_rw().unwrap(); let tx = factory.provider_rw().unwrap();
let address = Address::random(); let address = Address::random();
let storage = BTreeMap::from([ let storage = BTreeMap::from([
@ -718,11 +718,11 @@ mod tests {
bytecode_hash: Some(keccak256(code)), bytecode_hash: Some(keccak256(code)),
}; };
insert_account(tx.tx_mut(), address, account, &storage); insert_account(tx.tx_ref(), address, account, &storage);
tx.commit().unwrap(); tx.commit().unwrap();
let mut tx = factory.provider_rw().unwrap(); let tx = factory.provider_rw().unwrap();
let got = StorageRoot::new(tx.tx_mut(), address).root().unwrap(); let got = StorageRoot::new(tx.tx_ref(), address).root().unwrap();
assert_eq!(storage_root(storage.into_iter()), got); assert_eq!(storage_root(storage.into_iter()), got);
} }
@ -747,13 +747,13 @@ mod tests {
let db = create_test_rw_db(); let db = create_test_rw_db();
let factory = ProviderFactory::new(db.as_ref(), MAINNET.clone()); let factory = ProviderFactory::new(db.as_ref(), MAINNET.clone());
let mut tx = factory.provider_rw().unwrap(); let tx = factory.provider_rw().unwrap();
for (address, (account, storage)) in &state { for (address, (account, storage)) in &state {
insert_account(tx.tx_mut(), *address, *account, storage) insert_account(tx.tx_ref(), *address, *account, storage)
} }
tx.commit().unwrap(); tx.commit().unwrap();
let mut tx = factory.provider_rw().unwrap(); let tx = factory.provider_rw().unwrap();
let expected = state_root(state.into_iter()); let expected = state_root(state.into_iter());
@ -763,7 +763,7 @@ mod tests {
let mut intermediate_state: Option<Box<IntermediateStateRootState>> = None; let mut intermediate_state: Option<Box<IntermediateStateRootState>> = None;
while got.is_none() { while got.is_none() {
let calculator = StateRoot::new(tx.tx_mut()) let calculator = StateRoot::new(tx.tx_ref())
.with_threshold(threshold) .with_threshold(threshold)
.with_intermediate_state(intermediate_state.take().map(|state| *state)); .with_intermediate_state(intermediate_state.take().map(|state| *state));
match calculator.root_with_progress().unwrap() { match calculator.root_with_progress().unwrap() {
@ -786,16 +786,16 @@ mod tests {
fn test_state_root_with_state(state: State) { fn test_state_root_with_state(state: State) {
let db = create_test_rw_db(); let db = create_test_rw_db();
let factory = ProviderFactory::new(db.as_ref(), MAINNET.clone()); let factory = ProviderFactory::new(db.as_ref(), MAINNET.clone());
let mut tx = factory.provider_rw().unwrap(); let tx = factory.provider_rw().unwrap();
for (address, (account, storage)) in &state { for (address, (account, storage)) in &state {
insert_account(tx.tx_mut(), *address, *account, storage) insert_account(tx.tx_ref(), *address, *account, storage)
} }
tx.commit().unwrap(); tx.commit().unwrap();
let expected = state_root(state.into_iter()); let expected = state_root(state.into_iter());
let mut tx = factory.provider_rw().unwrap(); let tx = factory.provider_rw().unwrap();
let got = StateRoot::new(tx.tx_mut()).root().unwrap(); let got = StateRoot::new(tx.tx_ref()).root().unwrap();
assert_eq!(expected, got); assert_eq!(expected, got);
} }
@ -836,9 +836,9 @@ mod tests {
hashed_storage_cursor.upsert(key3, StorageEntry { key: hashed_slot, value }).unwrap(); hashed_storage_cursor.upsert(key3, StorageEntry { key: hashed_slot, value }).unwrap();
} }
tx.commit().unwrap(); tx.commit().unwrap();
let mut tx = factory.provider_rw().unwrap(); let tx = factory.provider_rw().unwrap();
let account3_storage_root = StorageRoot::new(tx.tx_mut(), address3).root().unwrap(); let account3_storage_root = StorageRoot::new(tx.tx_ref(), address3).root().unwrap();
let expected_root = storage_root_prehashed(storage.into_iter()); let expected_root = storage_root_prehashed(storage.into_iter());
assert_eq!(expected_root, account3_storage_root); assert_eq!(expected_root, account3_storage_root);
} }
@ -858,7 +858,7 @@ mod tests {
let db = create_test_rw_db(); let db = create_test_rw_db();
let factory = ProviderFactory::new(db.as_ref(), MAINNET.clone()); let factory = ProviderFactory::new(db.as_ref(), MAINNET.clone());
let mut tx = factory.provider_rw().unwrap(); let tx = factory.provider_rw().unwrap();
let mut hashed_account_cursor = let mut hashed_account_cursor =
tx.tx_ref().cursor_write::<tables::HashedAccount>().unwrap(); tx.tx_ref().cursor_write::<tables::HashedAccount>().unwrap();
@ -906,7 +906,7 @@ mod tests {
} }
hashed_storage_cursor.upsert(key3, StorageEntry { key: hashed_slot, value }).unwrap(); hashed_storage_cursor.upsert(key3, StorageEntry { key: hashed_slot, value }).unwrap();
} }
let account3_storage_root = StorageRoot::new(tx.tx_mut(), address3).root().unwrap(); let account3_storage_root = StorageRoot::new(tx.tx_ref(), address3).root().unwrap();
hash_builder.add_leaf( hash_builder.add_leaf(
Nibbles::unpack(key3), Nibbles::unpack(key3),
&encode_account(account3, Some(account3_storage_root)), &encode_account(account3, Some(account3_storage_root)),
@ -1105,7 +1105,7 @@ mod tests {
drop(tx); drop(tx);
} }
let mut tx = factory.provider_rw().unwrap(); let tx = factory.provider_rw().unwrap();
{ {
let mut hashed_account_cursor = let mut hashed_account_cursor =
tx.tx_ref().cursor_write::<tables::HashedAccount>().unwrap(); tx.tx_ref().cursor_write::<tables::HashedAccount>().unwrap();
@ -1129,7 +1129,7 @@ mod tests {
(key6, encode_account(account6, None)), (key6, encode_account(account6, None)),
]); ]);
let (root, trie_updates) = StateRoot::new(tx.tx_mut()) let (root, trie_updates) = StateRoot::new(tx.tx_ref())
.with_changed_account_prefixes(account_prefix_set) .with_changed_account_prefixes(account_prefix_set)
.root_with_updates() .root_with_updates()
.unwrap(); .unwrap();
@ -1165,11 +1165,11 @@ mod tests {
fn account_trie_around_extension_node() { fn account_trie_around_extension_node() {
let db = create_test_rw_db(); let db = create_test_rw_db();
let factory = ProviderFactory::new(db.as_ref(), MAINNET.clone()); let factory = ProviderFactory::new(db.as_ref(), MAINNET.clone());
let mut tx = factory.provider_rw().unwrap(); let tx = factory.provider_rw().unwrap();
let expected = extension_node_trie(&mut tx); let expected = extension_node_trie(&tx);
let (got, updates) = StateRoot::new(tx.tx_mut()).root_with_updates().unwrap(); let (got, updates) = StateRoot::new(tx.tx_ref()).root_with_updates().unwrap();
assert_eq!(expected, got); assert_eq!(expected, got);
// Check account trie // Check account trie
@ -1191,13 +1191,13 @@ mod tests {
fn account_trie_around_extension_node_with_dbtrie() { fn account_trie_around_extension_node_with_dbtrie() {
let db = create_test_rw_db(); let db = create_test_rw_db();
let factory = ProviderFactory::new(db.as_ref(), MAINNET.clone()); let factory = ProviderFactory::new(db.as_ref(), MAINNET.clone());
let mut tx = factory.provider_rw().unwrap(); let tx = factory.provider_rw().unwrap();
let expected = extension_node_trie(&mut tx); let expected = extension_node_trie(&tx);
let (got, updates) = StateRoot::new(tx.tx_mut()).root_with_updates().unwrap(); let (got, updates) = StateRoot::new(tx.tx_ref()).root_with_updates().unwrap();
assert_eq!(expected, got); assert_eq!(expected, got);
updates.flush(tx.tx_mut()).unwrap(); updates.flush(tx.tx_ref()).unwrap();
// read the account updates from the db // read the account updates from the db
let mut accounts_trie = tx.tx_ref().cursor_read::<tables::AccountsTrie>().unwrap(); let mut accounts_trie = tx.tx_ref().cursor_read::<tables::AccountsTrie>().unwrap();
@ -1219,7 +1219,7 @@ mod tests {
let db = create_test_rw_db(); let db = create_test_rw_db();
let factory = ProviderFactory::new(db.as_ref(), MAINNET.clone()); let factory = ProviderFactory::new(db.as_ref(), MAINNET.clone());
let mut tx = factory.provider_rw().unwrap(); let tx = factory.provider_rw().unwrap();
let mut hashed_account_cursor = tx.tx_ref().cursor_write::<tables::HashedAccount>().unwrap(); let mut hashed_account_cursor = tx.tx_ref().cursor_write::<tables::HashedAccount>().unwrap();
let mut state = BTreeMap::default(); let mut state = BTreeMap::default();
@ -1233,7 +1233,7 @@ mod tests {
} }
} }
let (state_root, trie_updates) = StateRoot::new(tx.tx_mut()) let (state_root, trie_updates) = StateRoot::new(tx.tx_ref())
.with_changed_account_prefixes(changes) .with_changed_account_prefixes(changes)
.root_with_updates() .root_with_updates()
.unwrap(); .unwrap();
@ -1243,7 +1243,7 @@ mod tests {
state.clone().into_iter().map(|(key, balance)| (key, (Account { balance, ..Default::default() }, std::iter::empty()))) state.clone().into_iter().map(|(key, balance)| (key, (Account { balance, ..Default::default() }, std::iter::empty())))
); );
assert_eq!(expected_root, state_root); assert_eq!(expected_root, state_root);
trie_updates.flush(tx.tx_mut()).unwrap(); trie_updates.flush(tx.tx_ref()).unwrap();
} }
}); });
} }
@ -1253,14 +1253,13 @@ mod tests {
fn storage_trie_around_extension_node() { fn storage_trie_around_extension_node() {
let db = create_test_rw_db(); let db = create_test_rw_db();
let factory = ProviderFactory::new(db.as_ref(), MAINNET.clone()); let factory = ProviderFactory::new(db.as_ref(), MAINNET.clone());
let mut tx = factory.provider_rw().unwrap(); let tx = factory.provider_rw().unwrap();
let hashed_address = H256::random(); let hashed_address = H256::random();
let (expected_root, expected_updates) = let (expected_root, expected_updates) = extension_node_storage_trie(&tx, hashed_address);
extension_node_storage_trie(&mut tx, hashed_address);
let (got, _, updates) = let (got, _, updates) =
StorageRoot::new_hashed(tx.tx_mut(), hashed_address).root_with_updates().unwrap(); StorageRoot::new_hashed(tx.tx_ref(), hashed_address).root_with_updates().unwrap();
assert_eq!(expected_root, got); assert_eq!(expected_root, got);
// Check account trie // Check account trie
@ -1279,7 +1278,7 @@ mod tests {
} }
fn extension_node_storage_trie( fn extension_node_storage_trie(
tx: &mut DatabaseProviderRW<'_, &Env<WriteMap>>, tx: &DatabaseProviderRW<'_, &Env<WriteMap>>,
hashed_address: H256, hashed_address: H256,
) -> (H256, HashMap<Nibbles, BranchNodeCompact>) { ) -> (H256, HashMap<Nibbles, BranchNodeCompact>) {
let value = U256::from(1); let value = U256::from(1);
@ -1305,7 +1304,7 @@ mod tests {
(root, updates) (root, updates)
} }
fn extension_node_trie(tx: &mut DatabaseProviderRW<'_, &Env<WriteMap>>) -> H256 { fn extension_node_trie(tx: &DatabaseProviderRW<'_, &Env<WriteMap>>) -> H256 {
let a = let a =
Account { nonce: 0, balance: U256::from(1u64), bytecode_hash: Some(H256::random()) }; Account { nonce: 0, balance: U256::from(1u64), bytecode_hash: Some(H256::random()) };
let val = encode_account(a, None); let val = encode_account(a, None);

View File

@ -6,7 +6,8 @@ use crate::{
}; };
use reth_db::mdbx::test_utils::create_test_rw_db; use reth_db::mdbx::test_utils::create_test_rw_db;
use reth_primitives::{BlockBody, SealedBlock}; use reth_primitives::{BlockBody, SealedBlock};
use reth_provider::ProviderFactory; use reth_provider::{BlockWriter, ProviderFactory};
use reth_rlp::Decodable;
use reth_stages::{stages::ExecutionStage, ExecInput, Stage}; use reth_stages::{stages::ExecutionStage, ExecInput, Stage};
use std::{collections::BTreeMap, ffi::OsStr, fs, path::Path, sync::Arc}; use std::{collections::BTreeMap, ffi::OsStr, fs, path::Path, sync::Arc};
@ -79,8 +80,7 @@ impl Case for BlockchainTestCase {
let mut provider = factory.provider_rw().unwrap(); let mut provider = factory.provider_rw().unwrap();
// Insert test state // Insert test state
reth_provider::insert_canonical_block( provider.insert_block(
provider.tx_ref(),
SealedBlock::new(case.genesis_block_header.clone().into(), BlockBody::default()), SealedBlock::new(case.genesis_block_header.clone().into(), BlockBody::default()),
None, None,
)?; )?;
@ -88,7 +88,9 @@ impl Case for BlockchainTestCase {
let mut last_block = None; let mut last_block = None;
for block in case.blocks.iter() { for block in case.blocks.iter() {
last_block = Some(block.write_to_db(provider.tx_ref())?); let decoded = SealedBlock::decode(&mut block.rlp.as_ref())?;
last_block = Some(decoded.number);
provider.insert_block(decoded, None)?;
} }
// Call execution stage // Call execution stage

View File

@ -7,11 +7,10 @@ use reth_db::{
transaction::{DbTx, DbTxMut}, transaction::{DbTx, DbTxMut},
}; };
use reth_primitives::{ use reth_primitives::{
keccak256, Account as RethAccount, Address, BigEndianHash, BlockNumber, Bloom, Bytecode, Bytes, keccak256, Account as RethAccount, Address, BigEndianHash, Bloom, Bytecode, Bytes, ChainSpec,
ChainSpec, ChainSpecBuilder, Header as RethHeader, JsonU256, SealedBlock, SealedHeader, ChainSpecBuilder, Header as RethHeader, JsonU256, SealedHeader, StorageEntry, Withdrawal, H160,
StorageEntry, Withdrawal, H160, H256, H64, U256, H256, H64, U256,
}; };
use reth_rlp::Decodable;
use serde::{self, Deserialize}; use serde::{self, Deserialize};
use std::{collections::BTreeMap, ops::Deref}; use std::{collections::BTreeMap, ops::Deref};
@ -138,19 +137,6 @@ pub struct Block {
pub withdrawals: Option<Vec<Withdrawal>>, pub withdrawals: Option<Vec<Withdrawal>>,
} }
impl Block {
/// Write the block to the database.
pub fn write_to_db<'a, Tx>(&self, tx: &'a Tx) -> Result<BlockNumber, Error>
where
Tx: DbTx<'a> + DbTxMut<'a>,
{
let decoded = SealedBlock::decode(&mut self.rlp.as_ref())?;
let block_number = decoded.number;
reth_provider::insert_canonical_block(tx, decoded, None)?;
Ok(block_number)
}
}
/// Transaction sequence in block /// Transaction sequence in block
#[derive(Debug, PartialEq, Eq, Deserialize)] #[derive(Debug, PartialEq, Eq, Deserialize)]
#[serde(deny_unknown_fields)] #[serde(deny_unknown_fields)]