refactor: Execution Stage owns Executor (#1568)

Co-authored-by: Roman Krasiuk <rokrassyuk@gmail.com>
Co-authored-by: Oliver Nordbjerg <hi@notbjerg.me>
This commit is contained in:
Georgios Konstantopoulos
2023-02-28 16:55:51 -07:00
committed by GitHub
parent 71bc1451af
commit 4285186dbd
12 changed files with 181 additions and 147 deletions

View File

@ -27,6 +27,7 @@ use reth_staged_sync::{
use reth_stages::{
prelude::*,
stages::{ExecutionStage, SenderRecoveryStage, TotalDifficultyStage},
DefaultDB,
};
use std::sync::Arc;
use tracing::{debug, info};
@ -156,9 +157,11 @@ impl ImportCommand {
.set(SenderRecoveryStage {
commit_threshold: config.stages.sender_recovery.commit_threshold,
})
.set(ExecutionStage {
chain_spec: self.chain.clone(),
commit_threshold: config.stages.execution.commit_threshold,
.set({
let mut stage: ExecutionStage<'_, DefaultDB<'_>> =
ExecutionStage::from(self.chain.clone());
stage.commit_threshold = config.stages.execution.commit_threshold;
stage
}),
)
.with_max_block(0)

View File

@ -7,8 +7,9 @@ use eyre::Result;
use reth_db::{
cursor::DbCursorRO, database::Database, table::TableImporter, tables, transaction::DbTx,
};
use reth_primitives::MAINNET;
use reth_provider::Transaction;
use reth_stages::{stages::ExecutionStage, Stage, StageId, UnwindInput};
use reth_stages::{stages::ExecutionStage, DefaultDB, Stage, StageId, UnwindInput};
use std::ops::DerefMut;
use tracing::info;
@ -96,7 +97,7 @@ async fn unwind_and_copy<DB: Database>(
output_db: &reth_db::mdbx::Env<reth_db::mdbx::WriteMap>,
) -> eyre::Result<()> {
let mut unwind_tx = Transaction::new(db_tool.db)?;
let mut exec_stage = ExecutionStage::default();
let mut exec_stage: ExecutionStage<'_, DefaultDB<'_>> = ExecutionStage::from(MAINNET.clone());
exec_stage
.unwind(
@ -125,7 +126,7 @@ async fn dry_run(
info!(target: "reth::cli", "Executing stage. [dry-run]");
let mut tx = Transaction::new(&output_db)?;
let mut exec_stage = ExecutionStage::default();
let mut exec_stage: ExecutionStage<'_, DefaultDB<'_>> = ExecutionStage::from(MAINNET.clone());
exec_stage
.execute(

View File

@ -50,6 +50,7 @@ use reth_staged_sync::{
use reth_stages::{
prelude::*,
stages::{ExecutionStage, SenderRecoveryStage, TotalDifficultyStage, FINISH},
DefaultDB,
};
use reth_tasks::TaskExecutor;
use std::{net::SocketAddr, path::PathBuf, sync::Arc};
@ -448,9 +449,11 @@ impl Command {
.set(SenderRecoveryStage {
commit_threshold: stage_conf.sender_recovery.commit_threshold,
})
.set(ExecutionStage {
chain_spec: self.chain.clone(),
commit_threshold: stage_conf.execution.commit_threshold,
.set({
let mut stage: ExecutionStage<'_, DefaultDB<'_>> =
ExecutionStage::from(self.chain.clone());
stage.commit_threshold = stage_conf.execution.commit_threshold;
stage
}),
)
.build();

View File

@ -17,7 +17,7 @@ use reth_staged_sync::{
};
use reth_stages::{
stages::{BodyStage, ExecutionStage, SenderRecoveryStage},
ExecInput, Stage, StageId, UnwindInput,
DefaultDB, ExecInput, Stage, StageId, UnwindInput,
};
use std::{net::SocketAddr, sync::Arc};
use tracing::*;
@ -171,8 +171,8 @@ impl Command {
stage.execute(&mut tx, input).await?;
}
StageEnum::Execution => {
let mut stage =
ExecutionStage { chain_spec: self.chain.clone(), commit_threshold: num_blocks };
let mut stage = ExecutionStage::<DefaultDB<'_>>::from(self.chain.clone());
stage.commit_threshold = num_blocks;
if !self.skip_unwind {
stage.unwind(&mut tx, unwind).await?;
}

View File

@ -15,7 +15,7 @@ use reth_primitives::{
};
use reth_provider::Transaction;
use reth_rlp::Decodable;
use reth_stages::{stages::ExecutionStage, ExecInput, Stage, StageId};
use reth_stages::{stages::ExecutionStage, DefaultDB, ExecInput, Stage, StageId};
use std::{
collections::HashMap,
ffi::OsStr,
@ -193,7 +193,7 @@ pub async fn run_test(path: PathBuf) -> eyre::Result<TestOutcome> {
// Initialize the execution stage
// Hardcode the chain_id to Ethereum 1.
let mut stage = ExecutionStage::new(chain_spec, 1000);
let mut stage = ExecutionStage::<DefaultDB<'_>>::from(chain_spec);
// Call execution stage
let input = ExecInput {

View File

@ -21,26 +21,47 @@ use revm::{
primitives::{Account as RevmAccount, AccountInfo, Bytecode, ResultAndState},
EVM,
};
use std::collections::{BTreeMap, HashMap};
use std::{
collections::{BTreeMap, HashMap},
sync::Arc,
};
/// Main block executor
pub struct Executor<'a, DB>
where
DB: StateProvider,
{
chain_spec: &'a ChainSpec,
/// The configured chain-spec
pub chain_spec: Arc<ChainSpec>,
evm: EVM<&'a mut SubState<DB>>,
stack: InspectorStack,
}
impl<'a, DB> From<ChainSpec> for Executor<'a, DB>
where
DB: StateProvider,
{
/// Instantiates a new executor from the chainspec. Must call
/// `with_db` to set the database before executing.
fn from(chain_spec: ChainSpec) -> Self {
let evm = EVM::new();
Executor {
chain_spec: Arc::new(chain_spec),
evm,
stack: InspectorStack::new(InspectorStackConfig::default()),
}
}
}
impl<'a, DB> Executor<'a, DB>
where
DB: StateProvider,
{
/// Creates a new executor from the given chain spec and database.
pub fn new(chain_spec: &'a ChainSpec, db: &'a mut SubState<DB>) -> Self {
pub fn new(chain_spec: Arc<ChainSpec>, db: &'a mut SubState<DB>) -> Self {
let mut evm = EVM::new();
evm.database(db);
Executor { chain_spec, evm, stack: InspectorStack::new(InspectorStackConfig::default()) }
}
@ -50,10 +71,21 @@ where
self
}
fn db(&mut self) -> &mut SubState<DB> {
/// Gives a reference to the database
pub fn db(&mut self) -> &mut SubState<DB> {
self.evm.db().expect("db to not be moved")
}
/// Overrides the database
pub fn with_db<OtherDB: StateProvider>(
&self,
db: &'a mut SubState<OtherDB>,
) -> Executor<'a, OtherDB> {
let mut evm = EVM::new();
evm.database(db);
Executor { chain_spec: self.chain_spec.clone(), evm, stack: self.stack.clone() }
}
fn recover_senders(
&self,
body: &[TransactionSigned],
@ -75,7 +107,7 @@ where
fill_cfg_and_block_env(
&mut self.evm.env.cfg,
&mut self.evm.env.block,
self.chain_spec,
&self.chain_spec,
header,
total_difficulty,
);
@ -341,6 +373,30 @@ where
}
}
/// Execute and verify block
pub fn execute_and_verify_receipt(
&mut self,
block: &Block,
total_difficulty: U256,
senders: Option<Vec<Address>>,
) -> Result<ExecutionResult, Error> {
let execution_result = self.execute(block, total_difficulty, senders)?;
let receipts_iter =
execution_result.tx_changesets.iter().map(|changeset| &changeset.receipt);
if self.chain_spec.fork(Hardfork::Byzantium).active_at_block(block.header.number) {
verify_receipt(block.header.receipts_root, block.header.logs_bloom, receipts_iter)?;
}
// TODO Before Byzantium, receipts contained state root that would mean that expensive
// operation as hashing that is needed for state root got calculated in every
// transaction This was replaced with is_success flag.
// See more about EIP here: https://eips.ethereum.org/EIPS/eip-658
Ok(execution_result)
}
/// Runs a single transaction in the configured environment and proceeds
/// to return the result and state diff (without applying it).
///
@ -464,30 +520,6 @@ where
}
}
/// Execute and verify block
pub fn execute_and_verify_receipt<DB: StateProvider>(
block: &Block,
total_difficulty: U256,
senders: Option<Vec<Address>>,
chain_spec: &ChainSpec,
db: &mut SubState<DB>,
) -> Result<ExecutionResult, Error> {
let execution_result = execute(block, total_difficulty, senders, chain_spec, db)?;
let receipts_iter = execution_result.tx_changesets.iter().map(|changeset| &changeset.receipt);
if chain_spec.fork(Hardfork::Byzantium).active_at_block(block.header.number) {
verify_receipt(block.header.receipts_root, block.header.logs_bloom, receipts_iter)?;
}
// TODO Before Byzantium, receipts contained state root that would mean that expensive operation
// as hashing that is needed for state root got calculated in every transaction
// This was replaced with is_success flag.
// See more about EIP here: https://eips.ethereum.org/EIPS/eip-658
Ok(execution_result)
}
/// Verify receipts
pub fn verify_receipt<'a>(
expected_receipts_root: H256,
@ -511,22 +543,6 @@ pub fn verify_receipt<'a>(
Ok(())
}
/// Verify block. Execute all transaction and compare results.
/// Returns ChangeSet on transaction granularity.
/// NOTE: If block reward is still active (Before Paris/Merge) we would return
/// additional TransactionStatechangeset for account that receives the reward.
pub fn execute<DB: StateProvider>(
block: &Block,
total_difficulty: U256,
senders: Option<Vec<Address>>,
chain_spec: &ChainSpec,
db: &mut SubState<DB>,
) -> Result<ExecutionResult, Error> {
let mut executor = Executor::new(chain_spec, db)
.with_stack(InspectorStack::new(InspectorStackConfig::default()));
executor.execute(block, total_difficulty, senders)
}
#[cfg(test)]
mod tests {
use super::*;
@ -640,13 +656,13 @@ mod tests {
);
// spec at berlin fork
let chain_spec = ChainSpecBuilder::mainnet().berlin_activated().build();
let chain_spec = Arc::new(ChainSpecBuilder::mainnet().berlin_activated().build());
let mut db = SubState::new(State::new(db));
// execute chain and verify receipts
let out =
execute_and_verify_receipt(&block, U256::ZERO, None, &chain_spec, &mut db).unwrap();
let mut executor = Executor::new(chain_spec, &mut db);
let out = executor.execute_and_verify_receipt(&block, U256::ZERO, None).unwrap();
assert_eq!(out.tx_changesets.len(), 1, "Should executed one transaction");
@ -765,21 +781,23 @@ mod tests {
beneficiary_balance += i;
}
let chain_spec = ChainSpecBuilder::from(&*MAINNET)
.homestead_activated()
.with_fork(Hardfork::Dao, ForkCondition::Block(1))
.build();
let chain_spec = Arc::new(
ChainSpecBuilder::from(&*MAINNET)
.homestead_activated()
.with_fork(Hardfork::Dao, ForkCondition::Block(1))
.build(),
);
let mut db = SubState::new(State::new(db));
// execute chain and verify receipts
let out = execute_and_verify_receipt(
&Block { header, body: vec![], ommers: vec![], withdrawals: None },
U256::ZERO,
None,
&chain_spec,
&mut db,
)
.unwrap();
let mut executor = Executor::new(chain_spec, &mut db);
let out = executor
.execute_and_verify_receipt(
&Block { header, body: vec![], ommers: vec![], withdrawals: None },
U256::ZERO,
None,
)
.unwrap();
assert_eq!(out.tx_changesets.len(), 0, "No tx");
// Check if cache is set
@ -858,13 +876,13 @@ mod tests {
);
// spec at berlin fork
let chain_spec = ChainSpecBuilder::mainnet().berlin_activated().build();
let chain_spec = Arc::new(ChainSpecBuilder::mainnet().berlin_activated().build());
let mut db = SubState::new(State::new(db));
// execute chain and verify receipts
let out =
execute_and_verify_receipt(&block, U256::ZERO, None, &chain_spec, &mut db).unwrap();
let mut executor = Executor::new(chain_spec, &mut db);
let out = executor.execute_and_verify_receipt(&block, U256::ZERO, None).unwrap();
assert_eq!(out.tx_changesets.len(), 1, "Should executed one transaction");
@ -907,17 +925,17 @@ mod tests {
Address::from_str("c94f5374fce5edbc8e2a8697c15331677e6ebf0b").unwrap();
// spec at shanghai fork
let chain_spec = ChainSpecBuilder::mainnet().shanghai_activated().build();
let chain_spec = Arc::new(ChainSpecBuilder::mainnet().shanghai_activated().build());
let mut db = SubState::new(State::new(StateProviderTest::default()));
// execute chain and verify receipts
let out =
execute_and_verify_receipt(&block, U256::ZERO, None, &chain_spec, &mut db).unwrap();
let mut executor = Executor::new(chain_spec, &mut db);
let out = executor.execute_and_verify_receipt(&block, U256::ZERO, None).unwrap();
assert_eq!(out.tx_changesets.len(), 0, "No tx");
let withdrawal_sum = withdrawals.iter().fold(U256::ZERO, |sum, w| sum + w.amount_wei());
let beneficiary_account = db.accounts.get(&withdrawal_beneficiary).unwrap();
let beneficiary_account = executor.db().accounts.get(&withdrawal_beneficiary).unwrap();
assert_eq!(beneficiary_account.info.balance, withdrawal_sum);
assert_eq!(beneficiary_account.info.nonce, 0);
assert_eq!(beneficiary_account.account_state, AccountState::StorageCleared);
@ -931,8 +949,7 @@ mod tests {
);
// Execute same block again
let out =
execute_and_verify_receipt(&block, U256::ZERO, None, &chain_spec, &mut db).unwrap();
let out = executor.execute_and_verify_receipt(&block, U256::ZERO, None).unwrap();
assert_eq!(out.tx_changesets.len(), 0, "No tx");
assert_eq!(out.block_changesets.len(), 1);

View File

@ -10,7 +10,7 @@ use revm::{
/// - Block: Hook on block execution
/// - BlockWithIndex: Hook on block execution transaction index
/// - Transaction: Hook on a specific transaction hash
#[derive(Default)]
#[derive(Default, Clone)]
pub enum Hook {
#[default]
/// No hook.
@ -23,7 +23,7 @@ pub enum Hook {
All,
}
#[derive(Default)]
#[derive(Default, Clone)]
/// An inspector that calls multiple inspectors in sequence.
///
/// If a call to an inspector returns a value other than [InstructionResult::Continue] (or

View File

@ -12,3 +12,6 @@ pub mod database;
/// reexport for convenience
pub use reth_revm_primitives::*;
/// Re-export everything
pub use revm;

View File

@ -1,6 +1,5 @@
use crate::{message::EngineApiMessageVersion, EngineApiError, EngineApiMessage, EngineApiResult};
use futures::StreamExt;
use reth_executor::executor;
use reth_interfaces::consensus::ForkchoiceState;
use reth_primitives::{
proofs::{self, EMPTY_LIST_HASH},
@ -17,6 +16,7 @@ use reth_rpc_types::engine::{
use std::{
future::Future,
pin::Pin,
sync::Arc,
task::{ready, Context, Poll},
};
use tokio::sync::{mpsc, oneshot, watch};
@ -37,7 +37,7 @@ const MAX_PAYLOAD_BODIES_LIMIT: u64 = 1024;
pub struct EngineApi<Client> {
client: Client,
/// Consensus configuration
chain_spec: ChainSpec,
chain_spec: Arc<ChainSpec>,
message_rx: UnboundedReceiverStream<EngineApiMessage>,
forkchoice_state_tx: watch::Sender<ForkchoiceState>,
// TODO: Placeholder for storing future blocks. Make cache bounded. Use lru
@ -57,7 +57,7 @@ impl<Client: HeaderProvider + BlockProvider + StateProviderFactory + EvmEnvProvi
) -> Self {
Self {
client,
chain_spec,
chain_spec: Arc::new(chain_spec),
message_rx: UnboundedReceiverStream::new(message_rx),
forkchoice_state_tx,
}
@ -304,13 +304,10 @@ impl<Client: HeaderProvider + BlockProvider + StateProviderFactory + EvmEnvProvi
let state_provider = self.client.latest()?;
let total_difficulty = parent_td + block.header.difficulty;
match executor::execute_and_verify_receipt(
&block.unseal(),
total_difficulty,
None,
&self.chain_spec,
&mut SubState::new(State::new(&state_provider)),
) {
let mut db = SubState::new(State::new(&state_provider));
let mut executor = reth_executor::executor::Executor::new(self.chain_spec.clone(), &mut db);
match executor.execute_and_verify_receipt(&block.unseal(), total_difficulty, None) {
Ok(_) => Ok(PayloadStatus::new(PayloadStatusEnum::Valid, block_hash)),
Err(err) => Ok(PayloadStatus::new(
PayloadStatusEnum::Invalid { validation_error: err.to_string() },
@ -443,7 +440,7 @@ mod tests {
};
fn setup_engine_api() -> (EngineApiTestHandle, EngineApi<Arc<MockEthProvider>>) {
let chain_spec = MAINNET.clone();
let chain_spec = Arc::new(MAINNET.clone());
let client = Arc::new(MockEthProvider::default());
let (msg_tx, msg_rx) = unbounded_channel();
let (forkchoice_state_tx, forkchoice_state_rx) = watch::channel(ForkchoiceState::default());
@ -458,7 +455,7 @@ mod tests {
}
struct EngineApiTestHandle {
chain_spec: ChainSpec,
chain_spec: Arc<ChainSpec>,
client: Arc<MockEthProvider>,
msg_tx: UnboundedSender<EngineApiMessage>,
forkchoice_state_rx: WatchReceiver<ForkchoiceState>,

View File

@ -56,6 +56,11 @@ mod stage;
mod trie;
mod util;
/// The real database type we use in Reth using MDBX.
pub type DefaultDB<'a> = LatestStateProviderRef<'a, 'a, Tx<'a, RW, WriteMap>>;
use reth_db::mdbx::{tx::Tx, WriteMap, RW};
use reth_provider::LatestStateProviderRef;
#[allow(missing_docs)]
#[cfg(any(test, feature = "test-utils"))]
pub mod test_utils;

View File

@ -170,7 +170,7 @@ impl<DB: Database> StageSet<DB> for ExecutionStages {
fn builder(self) -> StageSetBuilder<DB> {
StageSetBuilder::default()
.add_stage(SenderRecoveryStage::default())
.add_stage(ExecutionStage { chain_spec: self.chain_spec, ..Default::default() })
.add_stage(ExecutionStage::<crate::DefaultDB<'_>>::from(self.chain_spec))
}
}

View File

@ -1,6 +1,6 @@
use crate::{
exec_or_return, ExecAction, ExecInput, ExecOutput, Stage, StageError, StageId, UnwindInput,
UnwindOutput,
exec_or_return, DefaultDB, ExecAction, ExecInput, ExecOutput, Stage, StageError, StageId,
UnwindInput, UnwindOutput,
};
use reth_db::{
cursor::{DbCursorRO, DbCursorRW, DbDupCursorRO},
@ -9,12 +9,11 @@ use reth_db::{
tables,
transaction::{DbTx, DbTxMut},
};
use reth_executor::execution_result::AccountChangeSet;
use reth_executor::{execution_result::AccountChangeSet, executor::Executor};
use reth_interfaces::provider::ProviderError;
use reth_primitives::{Address, Block, ChainSpec, Hardfork, StorageEntry, H256, MAINNET, U256};
use reth_provider::{LatestStateProviderRef, Transaction};
use reth_primitives::{Address, Block, ChainSpec, Hardfork, StorageEntry, H256, U256};
use reth_provider::{LatestStateProviderRef, StateProvider, Transaction};
use reth_revm::database::{State, SubState};
use std::fmt::Debug;
use tracing::*;
/// The [`StageId`] of the execution stage.
@ -48,24 +47,35 @@ pub const EXECUTION: StageId = StageId("Execution");
/// - [tables::AccountHistory] to remove change set and apply old values to
/// - [tables::PlainAccountState] [tables::StorageHistory] to remove change set and apply old values
/// to [tables::PlainStorageState]
#[derive(Debug)]
pub struct ExecutionStage {
/// Executor configuration.
pub chain_spec: ChainSpec,
// false positive, we cannot derive it if !DB: Debug.
#[allow(missing_debug_implementations)]
pub struct ExecutionStage<'a, DB = DefaultDB<'a>>
where
DB: StateProvider,
{
/// The stage's internal executor
pub executor: Executor<'a, DB>,
/// Commit threshold
pub commit_threshold: u64,
}
impl Default for ExecutionStage {
fn default() -> Self {
Self { chain_spec: MAINNET.clone(), commit_threshold: 1_000 }
impl<'a, DB: StateProvider> From<Executor<'a, DB>> for ExecutionStage<'a, DB> {
fn from(executor: Executor<'a, DB>) -> Self {
Self { executor, commit_threshold: 1_000 }
}
}
impl ExecutionStage {
impl<'a, DB: StateProvider> From<ChainSpec> for ExecutionStage<'a, DB> {
fn from(chain_spec: ChainSpec) -> Self {
let executor = Executor::from(chain_spec);
Self::from(executor)
}
}
impl<'a, S: StateProvider> ExecutionStage<'a, S> {
/// Execute the stage.
pub fn execute_inner<DB: Database>(
&self,
&mut self,
tx: &mut Transaction<'_, DB>,
input: ExecInput,
) -> Result<ExecOutput, StageError> {
@ -87,7 +97,6 @@ impl ExecutionStage {
let mut tx_cursor = tx.cursor_read::<tables::Transactions>()?;
// Skip sender recovery and load signer from database.
let mut tx_sender = tx.cursor_read::<tables::TxSenders>()?;
// Get block headers and bodies
let block_batch = headers_cursor
.walk_range(start_block..=end_block)?
@ -106,6 +115,7 @@ impl ExecutionStage {
.collect::<Result<Vec<_>, _>>()?;
// Create state provider with cached state
let mut state_provider = SubState::new(State::new(LatestStateProviderRef::new(&**tx)));
// Fetch transactions, execute them and generate results
@ -143,14 +153,15 @@ impl ExecutionStage {
trace!(target: "sync::stages::execution", number = block_number, txs = transactions.len(), "Executing block");
let changeset = reth_executor::executor::execute_and_verify_receipt(
&Block { header, body: transactions, ommers, withdrawals },
td,
Some(signers),
&self.chain_spec,
&mut state_provider,
)
.map_err(|error| StageError::ExecutionError { block: block_number, error })?;
// Configure the executor to use the current state.
let mut executor = self.executor.with_db(&mut state_provider);
let changeset = executor
.execute_and_verify_receipt(
&Block { header, body: transactions, ommers, withdrawals },
td,
Some(signers),
)
.map_err(|error| StageError::ExecutionError { block: block_number, error })?;
block_change_patches.push((changeset, block_number));
}
@ -160,8 +171,11 @@ impl ExecutionStage {
// apply changes to plain database.
for (results, block_number) in block_change_patches.into_iter() {
let spurious_dragon_active =
self.chain_spec.fork(Hardfork::SpuriousDragon).active_at_block(block_number);
let spurious_dragon_active = self
.executor
.chain_spec
.fork(Hardfork::SpuriousDragon)
.active_at_block(block_number);
// insert state change set
for result in results.tx_changesets.into_iter() {
for (address, account_change_set) in result.changeset.into_iter() {
@ -266,15 +280,15 @@ impl ExecutionStage {
}
}
impl ExecutionStage {
impl<'a, DB: StateProvider> ExecutionStage<'a, DB> {
/// Create new execution stage with specified config.
pub fn new(chain_spec: ChainSpec, commit_threshold: u64) -> Self {
Self { chain_spec, commit_threshold }
pub fn new(executor: Executor<'a, DB>, commit_threshold: u64) -> Self {
Self { executor, commit_threshold }
}
}
#[async_trait::async_trait]
impl<DB: Database> Stage<DB> for ExecutionStage {
impl<State: StateProvider, DB: Database> Stage<DB> for ExecutionStage<'_, State> {
/// Return the id of the stage
fn id(&self) -> StageId {
EXECUTION
@ -392,20 +406,18 @@ impl<DB: Database> Stage<DB> for ExecutionStage {
#[cfg(test)]
mod tests {
use std::ops::{Deref, DerefMut};
use crate::test_utils::{TestTransaction, PREV_STAGE_ID};
use super::*;
use crate::test_utils::{TestTransaction, PREV_STAGE_ID};
use reth_db::{
mdbx::{test_utils::create_test_db, EnvKind, WriteMap},
models::AccountBeforeTx,
};
use reth_primitives::{
hex_literal::hex, keccak256, Account, ChainSpecBuilder, SealedBlock, H160, U256,
hex_literal::hex, keccak256, Account, ChainSpecBuilder, SealedBlock, H160, MAINNET, U256,
};
use reth_provider::insert_canonical_block;
use reth_rlp::Decodable;
use std::ops::{Deref, DerefMut};
#[tokio::test]
async fn sanity_execution_of_block() {
@ -448,11 +460,8 @@ mod tests {
db_tx.put::<tables::Bytecodes>(code_hash, code.to_vec()).unwrap();
tx.commit().unwrap();
// execute
let mut execution_stage = ExecutionStage {
chain_spec: ChainSpecBuilder::mainnet().berlin_activated().build(),
..Default::default()
};
let chain_spec = ChainSpecBuilder::mainnet().berlin_activated().build();
let mut execution_stage = ExecutionStage::<DefaultDB<'_>>::from(chain_spec);
let output = execution_stage.execute(&mut tx, input).await.unwrap();
tx.commit().unwrap();
assert_eq!(output, ExecOutput { stage_progress: 1, done: true });
@ -536,14 +545,12 @@ mod tests {
tx.commit().unwrap();
// execute
let mut execution_stage = ExecutionStage {
chain_spec: ChainSpecBuilder::mainnet().berlin_activated().build(),
..Default::default()
};
let chain_spec = ChainSpecBuilder::mainnet().berlin_activated().build();
let mut execution_stage = ExecutionStage::<DefaultDB<'_>>::from(chain_spec);
let _ = execution_stage.execute(&mut tx, input).await.unwrap();
tx.commit().unwrap();
let o = ExecutionStage::default()
let o = ExecutionStage::<DefaultDB<'_>>::from(MAINNET.clone())
.unwind(&mut tx, UnwindInput { stage_progress: 1, unwind_to: 0, bad_block: None })
.await
.unwrap();
@ -624,10 +631,8 @@ mod tests {
tx.commit().unwrap();
// execute
let mut execution_stage = ExecutionStage {
chain_spec: ChainSpecBuilder::mainnet().berlin_activated().build(),
..Default::default()
};
let chain_spec = ChainSpecBuilder::mainnet().berlin_activated().build();
let mut execution_stage = ExecutionStage::<DefaultDB<'_>>::from(chain_spec);
let _ = execution_stage.execute(&mut tx, input).await.unwrap();
tx.commit().unwrap();