Skip to content
This repository has been archived by the owner on Feb 6, 2025. It is now read-only.

Commit

Permalink
add bytecode execution
Browse files Browse the repository at this point in the history
  • Loading branch information
forcodedancing committed Apr 29, 2024
1 parent 58f5c96 commit f26252e
Show file tree
Hide file tree
Showing 11 changed files with 224 additions and 90 deletions.
10 changes: 5 additions & 5 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 2 additions & 2 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -358,7 +358,7 @@ test-fuzz = "5"


[patch.crates-io]
revm = { git = "https://github.com/bnb-chain/revm.git", rev = "76d842a", features = ["std", "secp256k1"], default-features = false }
revm-primitives = { git = "https://github.com/bnb-chain/revm.git", rev = "76d842a", features = ["std"], default-features = false }
revm = { git = "https://github.com/bnb-chain/revm.git", rev = "550b275", features = ["std", "secp256k1"], default-features = false }
revm-primitives = { git = "https://github.com/bnb-chain/revm.git", rev = "550b275", features = ["std"], default-features = false }
alloy-chains = { git = "https://github.com/bnb-chain/alloy-chains-rs.git", branch = "feat/v0.1.15-opbnb", feature = ["serde", "rlp", "arbitrary"] }
alloy-genesis = { git = "https://github.com/forcodedancing/alloy", branch = "feat/parlia-config" }
2 changes: 1 addition & 1 deletion bin/reth/src/commands/debug_cmd/build_block.rs
Original file line number Diff line number Diff line change
Expand Up @@ -308,7 +308,7 @@ impl Command {
let executor_factory = EvmProcessorFactory::new(self.chain.clone(), evm_config);
let mut executor = executor_factory.with_state(blockchain_db.latest()?);
executor
.execute_and_verify_receipt(&block_with_senders.clone().unseal(), U256::MAX)?;
.execute_and_verify_receipt(&block_with_senders.clone().unseal(), U256::MAX, 0)?;
let state = executor.take_output_state();
debug!(target: "reth::cli", ?state, "Executed block");

Expand Down
1 change: 1 addition & 0 deletions bin/reth/src/commands/debug_cmd/in_memory_merkle.rs
Original file line number Diff line number Diff line change
Expand Up @@ -177,6 +177,7 @@ impl Command {
.with_recovered_senders()
.ok_or(BlockValidationError::SenderRecoveryError)?,
merkle_block_td + block.difficulty,
0
)?;
let block_state = executor.take_output_state();

Expand Down
2 changes: 1 addition & 1 deletion crates/blockchain-tree/src/chain.rs
Original file line number Diff line number Diff line change
Expand Up @@ -202,7 +202,7 @@ impl AppendableChain {
let mut executor = externals.executor_factory.with_state(&provider);
let block_hash = block.hash();
let block = block.unseal();
executor.execute_and_verify_receipt(&block, U256::MAX)?;
executor.execute_and_verify_receipt(&block, U256::MAX, parent_block.timestamp)?;
let bundle_state = executor.take_output_state();

// check state root if the block extends the canonical chain __and__ if state root
Expand Down
4 changes: 2 additions & 2 deletions crates/primitives/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -47,8 +47,8 @@ pub mod transaction;
pub mod trie;
mod withdrawal;

#[cfg(feature = "bsc")]
mod system_contracts;
/// #[cfg(feature = "bsc")]
pub mod system_contracts;

pub use account::{Account, Bytecode};
#[cfg(any(test, feature = "arbitrary"))]
Expand Down
218 changes: 156 additions & 62 deletions crates/primitives/src/system_contracts/mod.rs

Large diffs are not rendered by default.

54 changes: 38 additions & 16 deletions crates/revm/src/processor.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,22 +7,25 @@ use crate::{
use reth_interfaces::executor::{BlockExecutionError, BlockValidationError};
use reth_node_api::ConfigureEvm;
use reth_primitives::{
Address, Block, BlockNumber, BlockWithSenders, Bloom, ChainSpec, GotExpected, Hardfork, Header,
PruneMode, PruneModes, PruneSegmentError, Receipt, ReceiptWithBloom, Receipts,
TransactionSigned, Withdrawals, B256, MINIMUM_PRUNING_DISTANCE, U256,
system_contracts, Address, Block, BlockNumber, BlockWithSenders, Bloom, ChainSpec, GotExpected,
Hardfork, Header, PruneMode, PruneModes, PruneSegmentError, Receipt, ReceiptWithBloom,
Receipts, TransactionSigned, Withdrawals, B256, MINIMUM_PRUNING_DISTANCE, U256,
};
use reth_provider::{
BlockExecutor, BlockExecutorStats, ProviderError, PrunableBlockExecutor, StateProvider,
};
use revm::{
db::{states::bundle_state::BundleRetention, EmptyDBTyped, StateDBBox},
inspector_handle_register,
interpreter::Host,
primitives::{CfgEnvWithHandlerCfg, ResultAndState},
interpreter::{instructions::system, Host},
primitives::{AccountInfo, CfgEnvWithHandlerCfg, ResultAndState},
Evm, State, StateBuilder,
};
use std::{sync::Arc, time::Instant};

#[cfg(feature = "bsc")]
use reth_primitives::system_contract;

#[cfg(feature = "optimism")]
use reth_primitives::revm::env::fill_op_tx_env;
#[cfg(not(feature = "optimism"))]
Expand Down Expand Up @@ -239,7 +242,6 @@ where
.increment_balances(balance_increments)
.map_err(|_| BlockValidationError::IncrementBalanceFailed)?;


Ok(())
}

Expand Down Expand Up @@ -306,7 +308,7 @@ where
gas: GotExpected { got: cumulative_gas_used, expected: block.gas_used },
gas_spent_by_tx: receipts.gas_spent_by_tx()?,
}
.into())
.into());
}
let time = Instant::now();
self.apply_post_execution_state_change(block, total_difficulty)?;
Expand All @@ -317,8 +319,8 @@ where
!self
.prune_modes
.account_history
.map_or(false, |mode| mode.should_prune(block.number, tip)) &&
!self
.map_or(false, |mode| mode.should_prune(block.number, tip))
&& !self
.prune_modes
.storage_history
.map_or(false, |mode| mode.should_prune(block.number, tip))
Expand Down Expand Up @@ -365,15 +367,15 @@ where
self.prune_modes.receipts.map_or(false, |mode| mode.should_prune(block_number, tip))
{
receipts.clear();
return Ok(())
return Ok(());
}

// All receipts from the last 128 blocks are required for blockchain tree, even with
// [`PruneSegment::ContractLogs`].
let prunable_receipts =
PruneMode::Distance(MINIMUM_PRUNING_DISTANCE).should_prune(block_number, tip);
if !prunable_receipts {
return Ok(())
return Ok(());
}

let contract_log_pruner = self.prune_modes.receipts_log_filter.group_by_block(tip, None)?;
Expand Down Expand Up @@ -422,6 +424,7 @@ where
&mut self,
block: &BlockWithSenders,
total_difficulty: U256,
parent_block_timestamp: u64,
) -> Result<(), BlockExecutionError> {
// execute block
let receipts = self.execute_inner(block, total_difficulty)?;
Expand All @@ -436,10 +439,25 @@ where
verify_receipt(block.header.receipts_root, block.header.logs_bloom, receipts.iter())
{
debug!(target: "evm", %error, ?receipts, "receipts verification failed");
return Err(error)
return Err(error);
};
self.stats.receipt_root_duration += time.elapsed();
}

match system_contracts::get_upgrade_system_contracts(
&self.chain_spec,
block.number,
parent_block_timestamp,
block.header.timestamp,
) {
Ok(contracts) => {
contracts.iter().for_each(|(k, v)| {
let account = AccountInfo { code: v.clone(), ..Default::default() };
self.db_mut().insert_account(*k, account);
});
}
Err(e) => return Err(BlockExecutionError::CanonicalCommit { inner: e.to_string() }),
};

self.save_receipts(receipts)
}
Expand All @@ -453,7 +471,7 @@ where

// perf: do not execute empty blocks
if block.body.is_empty() {
return Ok((Vec::new(), 0))
return Ok((Vec::new(), 0));
}

let mut cumulative_gas_used = 0;
Expand All @@ -468,7 +486,7 @@ where
transaction_gas_limit: transaction.gas_limit(),
block_available_gas,
}
.into())
.into());
}
// Execute transaction.
let ResultAndState { result, state } = self.transact(transaction, *sender)?;
Expand Down Expand Up @@ -566,14 +584,14 @@ pub fn compare_receipts_root_and_logs_bloom(
return Err(BlockValidationError::ReceiptRootDiff(
GotExpected { got: calculated_receipts_root, expected: expected_receipts_root }.into(),
)
.into())
.into());
}

if calculated_logs_bloom != expected_logs_bloom {
return Err(BlockValidationError::BloomLogDiff(
GotExpected { got: calculated_logs_bloom, expected: expected_logs_bloom }.into(),
)
.into())
.into());
}

Ok(())
Expand Down Expand Up @@ -647,6 +665,7 @@ mod tests {
senders: vec![],
},
U256::ZERO,
0,
)
.expect_err(
"Executing cancun block without parent beacon block root field should fail",
Expand Down Expand Up @@ -743,6 +762,7 @@ mod tests {
senders: vec![],
},
U256::ZERO,
0,
)
.expect(
"Executing a block with no transactions while cancun is active should not fail",
Expand Down Expand Up @@ -799,6 +819,7 @@ mod tests {
senders: vec![],
},
U256::ZERO,
0,
)
.expect(
"Executing a block with no transactions while cancun is active should not fail",
Expand Down Expand Up @@ -844,6 +865,7 @@ mod tests {
senders: vec![],
},
U256::ZERO,
0,
)
.expect_err(
"Executing genesis cancun block with non-zero parent beacon block root field should fail",
Expand Down
17 changes: 16 additions & 1 deletion crates/stages/src/stages/execution.rs
Original file line number Diff line number Diff line change
Expand Up @@ -155,6 +155,18 @@ impl<EF: ExecutorFactory> ExecutionStage<EF> {
let mut cumulative_gas = 0;
let batch_start = Instant::now();

let mut parent_block_timestamp = 0u64;

// get parent block timestamp for execution
if start_block > 0 {
let parent_block_number = start_block - 1 as u64;
let parent_header = match static_file_provider.header_by_number(parent_block_number) {
Ok(Some(header)) => header,
_ => return Err(StageError::DatabaseIntegrity(ProviderError::HeaderNotFound(parent_block_number.into()))),
};
parent_block_timestamp = parent_header.timestamp;
}

for block_number in start_block..=max_block {
// Fetch the block
let fetch_block_start = Instant::now();
Expand All @@ -177,7 +189,7 @@ impl<EF: ExecutorFactory> ExecutionStage<EF> {

// Execute the block
let execute_start = Instant::now();
executor.execute_and_verify_receipt(&block, td).map_err(|error| StageError::Block {
executor.execute_and_verify_receipt(&block, td, parent_block_timestamp).map_err(|error| StageError::Block {
block: Box::new(block.header.clone().seal_slow()),
error: BlockErrorKind::Execution(error),
})?;
Expand All @@ -203,6 +215,9 @@ impl<EF: ExecutorFactory> ExecutionStage<EF> {
) {
break
}

// Update parent block timestamp for next block
parent_block_timestamp = block.header.timestamp;
}
let time = Instant::now();
let state = executor.take_output_state();
Expand Down
1 change: 1 addition & 0 deletions crates/storage/provider/src/test_utils/executor.rs
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ impl BlockExecutor for TestExecutor {
&mut self,
_block: &BlockWithSenders,
_total_difficulty: U256,
_parent_block_timestamper: u64,
) -> Result<(), BlockExecutionError> {
if self.0.is_none() {
return Err(BlockExecutionError::UnavailableForTest)
Expand Down
1 change: 1 addition & 0 deletions crates/storage/provider/src/traits/executor.rs
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ pub trait BlockExecutor {
&mut self,
block: &BlockWithSenders,
total_difficulty: U256,
parent_block_timestamp: u64,
) -> Result<(), Self::Error>;

/// Runs the provided transactions and commits their state to the run-time database.
Expand Down

0 comments on commit f26252e

Please sign in to comment.