Skip to content

Commit

Permalink
add bytecode execution
Browse files Browse the repository at this point in the history
  • Loading branch information
forcodedancing committed May 7, 2024
1 parent 15767f7 commit 1c73436
Show file tree
Hide file tree
Showing 10 changed files with 225 additions and 78 deletions.
4 changes: 2 additions & 2 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -390,7 +390,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 @@ -311,7 +311,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 @@ -206,7 +206,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 @@ -48,8 +48,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.

41 changes: 32 additions & 9 deletions crates/revm/src/processor.rs
Original file line number Diff line number Diff line change
@@ -1,16 +1,20 @@
#[cfg(not(feature = "optimism"))]
use revm::DatabaseCommit;
use reth_primitives::system_contracts;
use revm::{
db::StateDBBox,
inspector_handle_register,
interpreter::Host,
primitives::{CfgEnvWithHandlerCfg, ResultAndState},
interpreter::{instructions::system, Host},
primitives::{AccountInfo, CfgEnvWithHandlerCfg, ResultAndState},
Evm, State,
};
use std::{sync::Arc, time::Instant};
#[cfg(not(feature = "optimism"))]
use tracing::{debug, trace};

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

use reth_evm::ConfigureEvm;
use reth_interfaces::executor::{BlockExecutionError, BlockValidationError};
#[cfg(feature = "optimism")]
Expand Down Expand Up @@ -204,7 +208,6 @@ where
.increment_balances(balance_increments)
.map_err(|_| BlockValidationError::IncrementBalanceFailed)?;


Ok(())
}

Expand Down Expand Up @@ -271,7 +274,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 Down Expand Up @@ -302,6 +305,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 @@ -316,11 +320,26 @@ 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.batch_record.save_receipts(receipts)?;
Ok(())
}
Expand All @@ -334,7 +353,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 @@ -349,7 +368,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 @@ -446,14 +465,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 @@ -527,6 +546,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 @@ -623,6 +643,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 @@ -679,6 +700,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 @@ -724,6 +746,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
29 changes: 28 additions & 1 deletion crates/stages/src/stages/execution.rs
Original file line number Diff line number Diff line change
Expand Up @@ -191,6 +191,30 @@ 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;
}

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;
}


let mut blocks = Vec::new();
for block_number in start_block..=max_block {
// Fetch the block
Expand All @@ -214,7 +238,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 Down Expand Up @@ -244,6 +268,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 @@ -17,6 +17,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 @@ -30,6 +30,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 1c73436

Please sign in to comment.