From 1c4056947dfd24cb87f7f145a5398058e2ecb6a4 Mon Sep 17 00:00:00 2001 From: Renato Dinhani Date: Mon, 12 Aug 2024 16:00:38 -0300 Subject: [PATCH] perf: do not depend on entire block --- src/eth/executor/evm_input.rs | 7 +++---- src/eth/executor/executor.rs | 27 ++++++++++++++++----------- src/eth/primitives/execution.rs | 5 ++--- 3 files changed, 21 insertions(+), 18 deletions(-) diff --git a/src/eth/executor/evm_input.rs b/src/eth/executor/evm_input.rs index 9b60598bc..3478984ca 100644 --- a/src/eth/executor/evm_input.rs +++ b/src/eth/executor/evm_input.rs @@ -6,7 +6,6 @@ use crate::eth::primitives::BlockNumber; use crate::eth::primitives::Bytes; use crate::eth::primitives::CallInput; use crate::eth::primitives::ChainId; -use crate::eth::primitives::ExternalBlock; use crate::eth::primitives::ExternalReceipt; use crate::eth::primitives::ExternalTransaction; use crate::eth::primitives::Gas; @@ -132,7 +131,7 @@ impl EvmInput { /// Creates a transaction that was executed in an external blockchain and imported to Stratus. /// /// Successful external transactions executes with max gas and zero gas price to ensure we will have the same execution result. - pub fn from_external(tx: &ExternalTransaction, receipt: &ExternalReceipt, block: &ExternalBlock) -> anyhow::Result { + pub fn from_external(tx: &ExternalTransaction, receipt: &ExternalReceipt, block_number: BlockNumber, block_timestamp: UnixTime) -> anyhow::Result { Ok(Self { from: tx.0.from.into(), to: tx.0.to.map_into(), @@ -142,8 +141,8 @@ impl EvmInput { gas_limit: if_else!(receipt.is_success(), Gas::MAX, tx.0.gas.try_into()?), gas_price: if_else!(receipt.is_success(), Wei::ZERO, tx.0.gas_price.map_into().unwrap_or(Wei::ZERO)), point_in_time: StoragePointInTime::Pending, - block_number: block.number(), - block_timestamp: block.timestamp(), + block_number, + block_timestamp, chain_id: match tx.0.chain_id { Some(chain_id) => Some(chain_id.try_into()?), None => None, diff --git a/src/eth/executor/executor.rs b/src/eth/executor/executor.rs index 78a943fce..8f4876869 100644 --- a/src/eth/executor/executor.rs +++ b/src/eth/executor/executor.rs @@ -16,6 +16,7 @@ use crate::eth::executor::EvmInput; use crate::eth::executor::ExecutorConfig; use crate::eth::miner::Miner; use crate::eth::primitives::BlockFilter; +use crate::eth::primitives::BlockNumber; use crate::eth::primitives::CallInput; use crate::eth::primitives::EvmExecution; use crate::eth::primitives::EvmExecutionMetrics; @@ -27,6 +28,7 @@ use crate::eth::primitives::ExternalTransactionExecution; use crate::eth::primitives::StratusError; use crate::eth::primitives::TransactionExecution; use crate::eth::primitives::TransactionInput; +use crate::eth::primitives::UnixTime; use crate::eth::storage::StoragePointInTime; use crate::eth::storage::StratusStorage; use crate::ext::spawn_thread; @@ -231,10 +233,11 @@ impl Executor { let _span = info_span!("executor::external_block", block_number = %block.number()).entered(); tracing::info!(block_number = %block.number(), "reexecuting external block"); - // track pending block number - let storage = &self.storage; - storage.set_pending_external_block(block.clone())?; - storage.set_pending_block_number(block.number())?; + // track pending block + let block_number = block.number(); + let block_timpestamp = block.timestamp(); + self.storage.set_pending_external_block(block.clone())?; + self.storage.set_pending_block_number(block_number)?; // determine how to execute each transaction for tx in &block.transactions { @@ -242,7 +245,8 @@ impl Executor { self.execute_external_transaction( tx, receipt, - block, + block_number, + block_timpestamp, #[cfg(feature = "metrics")] &mut block_metrics, )?; @@ -267,7 +271,8 @@ impl Executor { &self, tx: &ExternalTransaction, receipt: &ExternalReceipt, - block: &ExternalBlock, + block_number: BlockNumber, + block_timestamp: UnixTime, #[cfg(feature = "metrics")] block_metrics: &mut EvmExecutionMetrics, ) -> anyhow::Result<()> { // track @@ -275,7 +280,7 @@ impl Executor { let start = metrics::now(); #[cfg(feature = "tracing")] let _span = info_span!("executor::external_transaction", tx_hash = %tx.hash).entered(); - tracing::info!(block_number = %block.number(), tx_hash = %tx.hash(), "reexecuting external transaction"); + tracing::info!(%block_number, tx_hash = %tx.hash(), "reexecuting external transaction"); // when transaction externally failed, create fake transaction instead of reexecuting let tx_execution = match receipt.is_success() { @@ -283,7 +288,7 @@ impl Executor { // successful external transaction, re-execute locally true => { // re-execute transaction - let evm_input = EvmInput::from_external(tx, receipt, block)?; + let evm_input = EvmInput::from_external(tx, receipt, block_number, block_timestamp)?; let evm_execution = self.evms.execute(evm_input.clone(), EvmRoute::External); // handle re-execution result @@ -292,7 +297,7 @@ impl Executor { Err(e) => { let json_tx = to_json_string(&tx); let json_receipt = to_json_string(&receipt); - tracing::error!(reason = ?e, block_number = %block.number(), tx_hash = %tx.hash(), %json_tx, %json_receipt, "failed to reexecute external transaction"); + tracing::error!(reason = ?e, %block_number, tx_hash = %tx.hash(), %json_tx, %json_receipt, "failed to reexecute external transaction"); return Err(e.into()); } }; @@ -305,7 +310,7 @@ impl Executor { let json_tx = to_json_string(&tx); let json_receipt = to_json_string(&receipt); let json_execution_logs = to_json_string(&evm_execution.execution.logs); - tracing::error!(reason = %"mismatch reexecuting transaction", block_number = %block.number(), tx_hash = %tx.hash(), %json_tx, %json_receipt, %json_execution_logs, "failed to reexecute external transaction"); + tracing::error!(reason = %"mismatch reexecuting transaction", %block_number, tx_hash = %tx.hash(), %json_tx, %json_receipt, %json_execution_logs, "failed to reexecute external transaction"); return Err(e); }; @@ -315,7 +320,7 @@ impl Executor { // failed external transaction, re-cretea from receipt without re-executing false => { let sender = self.storage.read_account(&receipt.from.into(), &StoragePointInTime::Pending)?; - let execution = EvmExecution::from_failed_external_transaction(sender, receipt, block)?; + let execution = EvmExecution::from_failed_external_transaction(sender, receipt, block_timestamp)?; let evm_result = EvmExecutionResult { execution, metrics: EvmExecutionMetrics::default(), diff --git a/src/eth/primitives/execution.rs b/src/eth/primitives/execution.rs index bd7de64cd..9bcd9df93 100644 --- a/src/eth/primitives/execution.rs +++ b/src/eth/primitives/execution.rs @@ -10,7 +10,6 @@ use crate::eth::primitives::Address; use crate::eth::primitives::Bytes; use crate::eth::primitives::ExecutionAccountChanges; use crate::eth::primitives::ExecutionResult; -use crate::eth::primitives::ExternalBlock; use crate::eth::primitives::ExternalReceipt; use crate::eth::primitives::Gas; use crate::eth::primitives::Log; @@ -51,7 +50,7 @@ pub struct EvmExecution { impl EvmExecution { /// Creates an execution from an external transaction that failed. - pub fn from_failed_external_transaction(sender: Account, receipt: &ExternalReceipt, block: &ExternalBlock) -> anyhow::Result { + pub fn from_failed_external_transaction(sender: Account, receipt: &ExternalReceipt, block_timestamp: UnixTime) -> anyhow::Result { if receipt.is_success() { return log_and_err!("cannot create failed execution for successful transaction"); } @@ -66,7 +65,7 @@ impl EvmExecution { // crete execution and apply costs let mut execution = Self { - block_timestamp: block.timestamp(), + block_timestamp, receipt_applied: false, result: ExecutionResult::new_reverted(), // assume it reverted output: Bytes::default(), // we cannot really know without performing an eth_call to the external system