From 833787a91edc993508ae46448069ede0ad0d5212 Mon Sep 17 00:00:00 2001 From: Sean Matthew Date: Tue, 10 Oct 2023 15:34:34 -0400 Subject: [PATCH 01/22] only trace the block until the highest matching index in that block --- crates/rpc/rpc/src/trace.rs | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-) diff --git a/crates/rpc/rpc/src/trace.rs b/crates/rpc/rpc/src/trace.rs index 2beff9d6474d..d7e42afbeccc 100644 --- a/crates/rpc/rpc/src/trace.rs +++ b/crates/rpc/rpc/src/trace.rs @@ -276,29 +276,34 @@ where let mut target_blocks = Vec::new(); for block in blocks { let mut transaction_indices = HashSet::new(); + let mut highest_matching_index = 0; for (tx_idx, tx) in block.body.iter().enumerate() { let from = tx.recover_signer().ok_or(BlockError::InvalidSignature)?; let to = tx.to(); if matcher.matches(from, to) { - transaction_indices.insert(tx_idx as u64); + let idx = tx_idx as u64; + transaction_indices.insert(idx); + if idx > highest_matching_index { + highest_matching_index = idx; + } } } if !transaction_indices.is_empty() { - target_blocks.push((block.number, transaction_indices)); + target_blocks.push((block.number, transaction_indices, highest_matching_index)); } } - // TODO: this could be optimized to only trace the block until the highest matching index in - // that block - // trace all relevant blocks let mut block_traces = Vec::with_capacity(target_blocks.len()); - for (num, indices) in target_blocks { + for (num, indices, highest_idx) in target_blocks { let traces = self.trace_block_with( num.into(), TracingInspectorConfig::default_parity(), move |tx_info, inspector, res, _, _| { if let Some(idx) = tx_info.index { + if idx > highest_idx { + return Ok(None); + } if !indices.contains(&idx) { // only record traces for relevant transactions return Ok(None) From 9af97e003261e1d1cbecdca6ba194687a2f8f075 Mon Sep 17 00:00:00 2001 From: Sean Matthew Date: Wed, 11 Oct 2023 16:41:02 -0400 Subject: [PATCH 02/22] wip --- crates/rpc/rpc/src/trace.rs | 132 ++++++++++++++++++++++++++++++------ 1 file changed, 113 insertions(+), 19 deletions(-) diff --git a/crates/rpc/rpc/src/trace.rs b/crates/rpc/rpc/src/trace.rs index d7e42afbeccc..d9816c47fb5c 100644 --- a/crates/rpc/rpc/src/trace.rs +++ b/crates/rpc/rpc/src/trace.rs @@ -32,6 +32,11 @@ use revm_primitives::{db::DatabaseCommit, ExecutionResult, ResultAndState}; use std::{collections::HashSet, sync::Arc}; use tokio::sync::{AcquireError, OwnedSemaphorePermit}; +use reth_primitives::Block; +use reth_rpc_types::trace::filter::TraceFilterMatcher; + + + /// `trace` API implementation. /// /// This type provides the functionality for handling `trace` related requests. @@ -244,6 +249,33 @@ where } } + /// SME + fn find_relevant_blocks_to_trace( + blocks: Vec, + matcher: &TraceFilterMatcher, + ) -> EthResult, u64)>> { + + let mut target_blocks = Vec::new(); + for block in blocks { + let mut transaction_indices = HashSet::new(); + let mut highest_matching_index = 0; + for (tx_idx, tx) in block.body.iter().enumerate() { + let from = tx.recover_signer().ok_or(EthApiError::InvalidParams("Invalid signature".to_string()))?; + let to = tx.to(); + if matcher.matches(from, to) { + let idx = tx_idx as u64; + transaction_indices.insert(idx); + highest_matching_index = idx; + } + } + if !transaction_indices.is_empty() { + target_blocks.push((block.header.number, transaction_indices, highest_matching_index)); + } + } + + Ok(target_blocks) + } + /// Returns all transaction traces that match the given filter. /// /// This is similar to [Self::trace_block] but only returns traces for transactions that match @@ -273,25 +305,24 @@ where let blocks = self.provider().block_range(start..=end)?; // find relevant blocks to trace - let mut target_blocks = Vec::new(); - for block in blocks { - let mut transaction_indices = HashSet::new(); - let mut highest_matching_index = 0; - for (tx_idx, tx) in block.body.iter().enumerate() { - let from = tx.recover_signer().ok_or(BlockError::InvalidSignature)?; - let to = tx.to(); - if matcher.matches(from, to) { - let idx = tx_idx as u64; - transaction_indices.insert(idx); - if idx > highest_matching_index { - highest_matching_index = idx; - } - } - } - if !transaction_indices.is_empty() { - target_blocks.push((block.number, transaction_indices, highest_matching_index)); - } - } + let target_blocks = Self::find_relevant_blocks_to_trace(blocks, &matcher)?; + // let mut target_blocks = Vec::new(); + // for block in blocks { + // let mut transaction_indices = HashSet::new(); + // let mut highest_matching_index = 0; + // for (tx_idx, tx) in block.body.iter().enumerate() { + // let from = tx.recover_signer().ok_or(BlockError::InvalidSignature)?; + // let to = tx.to(); + // if matcher.matches(from, to) { + // let idx = tx_idx as u64; + // transaction_indices.insert(idx); + // highest_matching_index = idx; + // } + // } + // if !transaction_indices.is_empty() { + // target_blocks.push((block.number, transaction_indices, highest_matching_index)); + // } + // } // trace all relevant blocks let mut block_traces = Vec::with_capacity(target_blocks.len()); @@ -689,6 +720,69 @@ fn reward_trace(header: &SealedHeader, reward: RewardAction) -> LocalizedTransac mod tests { use super::*; + use reth_primitives::Header; + use reth_primitives::keccak256; + use reth_primitives::Signature; + use reth_primitives::TransactionSigned; + use reth_rpc_types::Transaction; + use reth_primitives::U64; + + fn mock_transaction() -> Transaction { + Transaction { + hash: B256::default(), // Assuming B256 has a default implementation + nonce: U64::default(), + block_hash: None, + block_number: None, + transaction_index: None, + from: Address::default(), // Assuming Address has a default implementation + to: None, + value: U256::default(), + gas_price: None, + gas: U256::default(), + max_fee_per_gas: None, + max_priority_fee_per_gas: None, + max_fee_per_blob_gas: None, + input: Bytes::default(), // Assuming Bytes has a default implementation + signature: None, + chain_id: None, + blob_versioned_hashes: vec![], + access_list: None, + transaction_type: None, + } + } + + fn mock_block() -> Block { + + let hash = keccak256("Hello World!"); + + + let signed_tx = TransactionSigned { + hash: hash, + signature: Signature::default(), + transaction: mock_transaction(), + }; + + Block { + header: Header::default(), + body: vec![signed_tx], // Use vec! to create a vector + ommers: vec![], + withdrawals: None, + } + } + + #[test] + fn exploration() { + println!("Hello World!"); + assert_eq!(2 + 2, 4); + + let block = mock_block(); + + + + + } + + #[test] fn test_parity_config() { let mut s = HashSet::new(); From 3b7c2fbb8374db20de51b14ce2332bf0994006fb Mon Sep 17 00:00:00 2001 From: Sean Matthew Date: Wed, 11 Oct 2023 19:21:33 -0400 Subject: [PATCH 03/22] update --- crates/rpc/rpc/src/trace.rs | 90 +++++-------------------------------- 1 file changed, 10 insertions(+), 80 deletions(-) diff --git a/crates/rpc/rpc/src/trace.rs b/crates/rpc/rpc/src/trace.rs index d9816c47fb5c..5ece991e4f4c 100644 --- a/crates/rpc/rpc/src/trace.rs +++ b/crates/rpc/rpc/src/trace.rs @@ -306,23 +306,6 @@ where // find relevant blocks to trace let target_blocks = Self::find_relevant_blocks_to_trace(blocks, &matcher)?; - // let mut target_blocks = Vec::new(); - // for block in blocks { - // let mut transaction_indices = HashSet::new(); - // let mut highest_matching_index = 0; - // for (tx_idx, tx) in block.body.iter().enumerate() { - // let from = tx.recover_signer().ok_or(BlockError::InvalidSignature)?; - // let to = tx.to(); - // if matcher.matches(from, to) { - // let idx = tx_idx as u64; - // transaction_indices.insert(idx); - // highest_matching_index = idx; - // } - // } - // if !transaction_indices.is_empty() { - // target_blocks.push((block.number, transaction_indices, highest_matching_index)); - // } - // } // trace all relevant blocks let mut block_traces = Vec::with_capacity(target_blocks.len()); @@ -346,6 +329,7 @@ where .into_localized_transaction_traces(tx_info); Ok(Some(traces)) }, + None, ); block_traces.push(traces); } @@ -396,6 +380,7 @@ where block_id: BlockId, config: TracingInspectorConfig, f: F, + highest_index: Option, ) -> EthResult>> where // This is the callback that's invoked for each transaction with @@ -437,6 +422,12 @@ where let mut transactions = transactions.into_iter().enumerate().peekable(); while let Some((idx, tx)) = transactions.next() { + // Check if current index exceeds the highest_index and break if it does + if let Some(highest) = highest_index { + if idx as u64 > highest { + break; + } + } let tx = tx.into_ecrecovered().ok_or(BlockError::InvalidSignature)?; let tx_info = TransactionInfo { hash: Some(tx.hash()), @@ -484,6 +475,7 @@ where .into_localized_transaction_traces(tx_info); Ok(traces) }, + None, ); let block = self.inner.eth_api.block_by_id(block_id); @@ -554,6 +546,7 @@ where }; Ok(trace) }, + None, ) .await } @@ -720,69 +713,6 @@ fn reward_trace(header: &SealedHeader, reward: RewardAction) -> LocalizedTransac mod tests { use super::*; - use reth_primitives::Header; - use reth_primitives::keccak256; - use reth_primitives::Signature; - use reth_primitives::TransactionSigned; - use reth_rpc_types::Transaction; - use reth_primitives::U64; - - fn mock_transaction() -> Transaction { - Transaction { - hash: B256::default(), // Assuming B256 has a default implementation - nonce: U64::default(), - block_hash: None, - block_number: None, - transaction_index: None, - from: Address::default(), // Assuming Address has a default implementation - to: None, - value: U256::default(), - gas_price: None, - gas: U256::default(), - max_fee_per_gas: None, - max_priority_fee_per_gas: None, - max_fee_per_blob_gas: None, - input: Bytes::default(), // Assuming Bytes has a default implementation - signature: None, - chain_id: None, - blob_versioned_hashes: vec![], - access_list: None, - transaction_type: None, - } - } - - fn mock_block() -> Block { - - let hash = keccak256("Hello World!"); - - - let signed_tx = TransactionSigned { - hash: hash, - signature: Signature::default(), - transaction: mock_transaction(), - }; - - Block { - header: Header::default(), - body: vec![signed_tx], // Use vec! to create a vector - ommers: vec![], - withdrawals: None, - } - } - - #[test] - fn exploration() { - println!("Hello World!"); - assert_eq!(2 + 2, 4); - - let block = mock_block(); - - - - - } - - #[test] fn test_parity_config() { let mut s = HashSet::new(); From b7fbe2dc5d3e8c462b6afc8f6b0a13e942b82d43 Mon Sep 17 00:00:00 2001 From: Sean Matthew Date: Wed, 11 Oct 2023 19:22:29 -0400 Subject: [PATCH 04/22] update --- crates/rpc/rpc/src/trace.rs | 4 ---- 1 file changed, 4 deletions(-) diff --git a/crates/rpc/rpc/src/trace.rs b/crates/rpc/rpc/src/trace.rs index 5ece991e4f4c..dc47334c5129 100644 --- a/crates/rpc/rpc/src/trace.rs +++ b/crates/rpc/rpc/src/trace.rs @@ -32,10 +32,6 @@ use revm_primitives::{db::DatabaseCommit, ExecutionResult, ResultAndState}; use std::{collections::HashSet, sync::Arc}; use tokio::sync::{AcquireError, OwnedSemaphorePermit}; -use reth_primitives::Block; -use reth_rpc_types::trace::filter::TraceFilterMatcher; - - /// `trace` API implementation. /// From c7c2c1971689b5ccd38430d60f57c026d2806aac Mon Sep 17 00:00:00 2001 From: Sean Matthew Date: Wed, 11 Oct 2023 19:23:13 -0400 Subject: [PATCH 05/22] update --- crates/rpc/rpc/src/trace.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/crates/rpc/rpc/src/trace.rs b/crates/rpc/rpc/src/trace.rs index dc47334c5129..f457a23e09da 100644 --- a/crates/rpc/rpc/src/trace.rs +++ b/crates/rpc/rpc/src/trace.rs @@ -245,7 +245,7 @@ where } } - /// SME + /// Returns all transaction traces that match the given filter. fn find_relevant_blocks_to_trace( blocks: Vec, matcher: &TraceFilterMatcher, From 6a7d680432a8a76eb35044835142671127908b49 Mon Sep 17 00:00:00 2001 From: Sean Matthew Date: Wed, 11 Oct 2023 19:24:30 -0400 Subject: [PATCH 06/22] update --- crates/rpc/rpc/src/trace.rs | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/crates/rpc/rpc/src/trace.rs b/crates/rpc/rpc/src/trace.rs index f457a23e09da..7efa843c7ee1 100644 --- a/crates/rpc/rpc/src/trace.rs +++ b/crates/rpc/rpc/src/trace.rs @@ -311,9 +311,6 @@ where TracingInspectorConfig::default_parity(), move |tx_info, inspector, res, _, _| { if let Some(idx) = tx_info.index { - if idx > highest_idx { - return Ok(None); - } if !indices.contains(&idx) { // only record traces for relevant transactions return Ok(None) @@ -325,7 +322,7 @@ where .into_localized_transaction_traces(tx_info); Ok(Some(traces)) }, - None, + highest_idx, ); block_traces.push(traces); } From 840405680088a42a47c24e383006a17e4dc16a0e Mon Sep 17 00:00:00 2001 From: Sean Matthew Date: Wed, 11 Oct 2023 20:47:49 -0400 Subject: [PATCH 07/22] update --- crates/rpc/rpc/src/trace.rs | 61 ++++++++++++++++++------------------- 1 file changed, 29 insertions(+), 32 deletions(-) diff --git a/crates/rpc/rpc/src/trace.rs b/crates/rpc/rpc/src/trace.rs index 7efa843c7ee1..46223a13220d 100644 --- a/crates/rpc/rpc/src/trace.rs +++ b/crates/rpc/rpc/src/trace.rs @@ -245,33 +245,6 @@ where } } - /// Returns all transaction traces that match the given filter. - fn find_relevant_blocks_to_trace( - blocks: Vec, - matcher: &TraceFilterMatcher, - ) -> EthResult, u64)>> { - - let mut target_blocks = Vec::new(); - for block in blocks { - let mut transaction_indices = HashSet::new(); - let mut highest_matching_index = 0; - for (tx_idx, tx) in block.body.iter().enumerate() { - let from = tx.recover_signer().ok_or(EthApiError::InvalidParams("Invalid signature".to_string()))?; - let to = tx.to(); - if matcher.matches(from, to) { - let idx = tx_idx as u64; - transaction_indices.insert(idx); - highest_matching_index = idx; - } - } - if !transaction_indices.is_empty() { - target_blocks.push((block.header.number, transaction_indices, highest_matching_index)); - } - } - - Ok(target_blocks) - } - /// Returns all transaction traces that match the given filter. /// /// This is similar to [Self::trace_block] but only returns traces for transactions that match @@ -301,12 +274,28 @@ where let blocks = self.provider().block_range(start..=end)?; // find relevant blocks to trace - let target_blocks = Self::find_relevant_blocks_to_trace(blocks, &matcher)?; + let mut target_blocks = Vec::new(); + for block in blocks { + let mut transaction_indices = HashSet::new(); + let mut highest_matching_index = 0; + for (tx_idx, tx) in block.body.iter().enumerate() { + let from = tx.recover_signer().ok_or(EthApiError::InvalidParams("Invalid signature".to_string()))?; + let to = tx.to(); + if matcher.matches(from, to) { + let idx = tx_idx as u64; + transaction_indices.insert(idx); + highest_matching_index = idx; + } + } + if !transaction_indices.is_empty() { + target_blocks.push((block.header.number, transaction_indices, highest_matching_index)); + } + } // trace all relevant blocks let mut block_traces = Vec::with_capacity(target_blocks.len()); for (num, indices, highest_idx) in target_blocks { - let traces = self.trace_block_with( + let traces = self.trace_block_until( num.into(), TracingInspectorConfig::default_parity(), move |tx_info, inspector, res, _, _| { @@ -322,7 +311,7 @@ where .into_localized_transaction_traces(tx_info); Ok(Some(traces)) }, - highest_idx, + Some(highest_idx), ); block_traces.push(traces); } @@ -373,6 +362,16 @@ where block_id: BlockId, config: TracingInspectorConfig, f: F, + ) -> EthResult>> + { + Self::trace_block_until(block_id, config, f, None).await + } + + async fn trace_block_until( + &self, + block_id: BlockId, + config: TracingInspectorConfig, + f: F, highest_index: Option, ) -> EthResult>> where @@ -468,7 +467,6 @@ where .into_localized_transaction_traces(tx_info); Ok(traces) }, - None, ); let block = self.inner.eth_api.block_by_id(block_id); @@ -539,7 +537,6 @@ where }; Ok(trace) }, - None, ) .await } From c5fcc5b6081850acebae085d3f9afd6aef7bf416 Mon Sep 17 00:00:00 2001 From: Sean Matthew Date: Wed, 11 Oct 2023 21:01:10 -0400 Subject: [PATCH 08/22] update --- crates/rpc/rpc/src/trace.rs | 32 +++++++++++++++++++------------- 1 file changed, 19 insertions(+), 13 deletions(-) diff --git a/crates/rpc/rpc/src/trace.rs b/crates/rpc/rpc/src/trace.rs index 46223a13220d..67aa54897667 100644 --- a/crates/rpc/rpc/src/trace.rs +++ b/crates/rpc/rpc/src/trace.rs @@ -279,7 +279,7 @@ where let mut transaction_indices = HashSet::new(); let mut highest_matching_index = 0; for (tx_idx, tx) in block.body.iter().enumerate() { - let from = tx.recover_signer().ok_or(EthApiError::InvalidParams("Invalid signature".to_string()))?; + let from = tx.recover_signer().ok_or(BlockError::InvalidSignature)?; let to = tx.to(); if matcher.matches(from, to) { let idx = tx_idx as u64; @@ -288,7 +288,7 @@ where } } if !transaction_indices.is_empty() { - target_blocks.push((block.header.number, transaction_indices, highest_matching_index)); + target_blocks.push((block.number, transaction_indices, highest_matching_index)); } } @@ -347,6 +347,17 @@ where .await } + type TransactionCallback<'a, R> = + Fn( + TransactionInfo, + TracingInspector, + ExecutionResult, + &'a revm_primitives::State, + &'a CacheDB>>, + ) -> EthResult + + Send + + 'static; + /// Executes all transactions of a block and returns a list of callback results invoked for each /// transaction in the block. /// @@ -363,8 +374,12 @@ where config: TracingInspectorConfig, f: F, ) -> EthResult>> + where + // This is the callback that's invoked for each transaction with + F: TransactionCallback<'a, R>, + R: Send + 'static, { - Self::trace_block_until(block_id, config, f, None).await + self.trace_block_until(block_id, config, f, None).await } async fn trace_block_until( @@ -375,16 +390,7 @@ where highest_index: Option, ) -> EthResult>> where - // This is the callback that's invoked for each transaction with - F: for<'a> Fn( - TransactionInfo, - TracingInspector, - ExecutionResult, - &'a revm_primitives::State, - &'a CacheDB>>, - ) -> EthResult - + Send - + 'static, + F: TransactionCallback<'a, R>, R: Send + 'static, { let ((cfg, block_env, _), block) = futures::try_join!( From 15b20b956eb29ef4cd8321b7ac98de116127e220 Mon Sep 17 00:00:00 2001 From: Sean Matthew Date: Wed, 11 Oct 2023 21:10:24 -0400 Subject: [PATCH 09/22] update --- crates/rpc/rpc/src/trace.rs | 50 ++++++++++++++++++++++++++----------- 1 file changed, 35 insertions(+), 15 deletions(-) diff --git a/crates/rpc/rpc/src/trace.rs b/crates/rpc/rpc/src/trace.rs index 67aa54897667..9f80ff5ca918 100644 --- a/crates/rpc/rpc/src/trace.rs +++ b/crates/rpc/rpc/src/trace.rs @@ -28,7 +28,7 @@ use reth_rpc_types::{ BlockError, BlockOverrides, CallRequest, Index, TransactionInfo, }; use revm::{db::CacheDB, primitives::Env}; -use revm_primitives::{db::DatabaseCommit, ExecutionResult, ResultAndState}; +use revm_primitives::{db::DatabaseCommit, ExecutionResult, ResultAndState, State}; use std::{collections::HashSet, sync::Arc}; use tokio::sync::{AcquireError, OwnedSemaphorePermit}; @@ -40,6 +40,34 @@ pub struct TraceApi { inner: Arc>, } +trait TransactionCallback +where + Self: for<'a> Fn( + TransactionInfo, + TracingInspector, + ExecutionResult, + &'a State, + &'a CacheDB>>, + ) -> EthResult + + Send + + 'static, +{ +} + +impl TransactionCallback for F +where + F: for<'a> Fn( + TransactionInfo, + TracingInspector, + ExecutionResult, + &'a State, + &'a CacheDB>>, + ) -> EthResult + + Send + + 'static, +{ +} + // === impl TraceApi === impl TraceApi { @@ -347,16 +375,8 @@ where .await } - type TransactionCallback<'a, R> = - Fn( - TransactionInfo, - TracingInspector, - ExecutionResult, - &'a revm_primitives::State, - &'a CacheDB>>, - ) -> EthResult - + Send - + 'static; + + /// Executes all transactions of a block and returns a list of callback results invoked for each /// transaction in the block. @@ -368,7 +388,7 @@ where /// 4. calls the callback with the transaction info, the execution result, the changed state /// _after_ the transaction [StateProviderDatabase] and the database that points to the state /// right _before_ the transaction. - async fn trace_block_with( + async fn trace_block_with<'a, F, R>( &self, block_id: BlockId, config: TracingInspectorConfig, @@ -376,13 +396,13 @@ where ) -> EthResult>> where // This is the callback that's invoked for each transaction with - F: TransactionCallback<'a, R>, + F: TransactionCallback, R: Send + 'static, { self.trace_block_until(block_id, config, f, None).await } - async fn trace_block_until( + async fn trace_block_until<'a, F, R>( &self, block_id: BlockId, config: TracingInspectorConfig, @@ -390,7 +410,7 @@ where highest_index: Option, ) -> EthResult>> where - F: TransactionCallback<'a, R>, + F: TransactionCallback, R: Send + 'static, { let ((cfg, block_env, _), block) = futures::try_join!( From f6eab16713304066cad6877821120781bbd80909 Mon Sep 17 00:00:00 2001 From: Sean Matthew Date: Wed, 11 Oct 2023 21:24:49 -0400 Subject: [PATCH 10/22] update --- crates/rpc/rpc/src/trace.rs | 1 - 1 file changed, 1 deletion(-) diff --git a/crates/rpc/rpc/src/trace.rs b/crates/rpc/rpc/src/trace.rs index 9f80ff5ca918..ff71fd704306 100644 --- a/crates/rpc/rpc/src/trace.rs +++ b/crates/rpc/rpc/src/trace.rs @@ -32,7 +32,6 @@ use revm_primitives::{db::DatabaseCommit, ExecutionResult, ResultAndState, State use std::{collections::HashSet, sync::Arc}; use tokio::sync::{AcquireError, OwnedSemaphorePermit}; - /// `trace` API implementation. /// /// This type provides the functionality for handling `trace` related requests. From 2f96b93d6d1e0d191fbfd5183d6be9dfef24f629 Mon Sep 17 00:00:00 2001 From: Sean Matthew Date: Thu, 12 Oct 2023 09:46:26 -0400 Subject: [PATCH 11/22] update --- crates/rpc/rpc/src/trace.rs | 27 +++++++++------------------ 1 file changed, 9 insertions(+), 18 deletions(-) diff --git a/crates/rpc/rpc/src/trace.rs b/crates/rpc/rpc/src/trace.rs index ff71fd704306..37b0a5bb047d 100644 --- a/crates/rpc/rpc/src/trace.rs +++ b/crates/rpc/rpc/src/trace.rs @@ -324,6 +324,7 @@ where for (num, indices, highest_idx) in target_blocks { let traces = self.trace_block_until( num.into(), + Some(highest_idx), TracingInspectorConfig::default_parity(), move |tx_info, inspector, res, _, _| { if let Some(idx) = tx_info.index { @@ -338,7 +339,6 @@ where .into_localized_transaction_traces(tx_info); Ok(Some(traces)) }, - Some(highest_idx), ); block_traces.push(traces); } @@ -398,15 +398,15 @@ where F: TransactionCallback, R: Send + 'static, { - self.trace_block_until(block_id, config, f, None).await + self.trace_block_until(block_id, None, config, f).await } async fn trace_block_until<'a, F, R>( &self, block_id: BlockId, + highest_index: Option, config: TracingInspectorConfig, f: F, - highest_index: Option, ) -> EthResult>> where F: TransactionCallback, @@ -436,15 +436,10 @@ where let mut results = Vec::with_capacity(transactions.len()); let mut db = CacheDB::new(StateProviderDatabase::new(state)); - let mut transactions = transactions.into_iter().enumerate().peekable(); + let max_transactions = highest_index.map_or(transactions.len(), |highest| highest as usize + 1); + let transactions = transactions.into_iter().take(max_transactions).enumerate(); - while let Some((idx, tx)) = transactions.next() { - // Check if current index exceeds the highest_index and break if it does - if let Some(highest) = highest_index { - if idx as u64 > highest { - break; - } - } + for (idx, tx) in transactions { let tx = tx.into_ecrecovered().ok_or(BlockError::InvalidSignature)?; let tx_info = TransactionInfo { hash: Some(tx.hash()), @@ -462,13 +457,9 @@ where let ResultAndState { result, state } = res; results.push(f(tx_info, inspector, result, &state, &db)?); - // need to apply the state changes of this transaction before executing the - // next transaction - if transactions.peek().is_some() { - // need to apply the state changes of this transaction before executing - // the next transaction - db.commit(state) - } + // need to apply the state changes of this transaction before executing + // the next transaction + db.commit(state) } Ok(results) From 472cb14a9a33be0278036541f7e02c23b1d9cc49 Mon Sep 17 00:00:00 2001 From: Sean Matthew Date: Thu, 12 Oct 2023 09:47:31 -0400 Subject: [PATCH 12/22] update --- crates/rpc/rpc/src/trace.rs | 3 --- 1 file changed, 3 deletions(-) diff --git a/crates/rpc/rpc/src/trace.rs b/crates/rpc/rpc/src/trace.rs index 37b0a5bb047d..ffbde7a38498 100644 --- a/crates/rpc/rpc/src/trace.rs +++ b/crates/rpc/rpc/src/trace.rs @@ -374,9 +374,6 @@ where .await } - - - /// Executes all transactions of a block and returns a list of callback results invoked for each /// transaction in the block. /// From 50817971480d14a1869f2a9cd25a66689c436286 Mon Sep 17 00:00:00 2001 From: Sean Matthew Date: Thu, 12 Oct 2023 09:59:18 -0400 Subject: [PATCH 13/22] update --- crates/rpc/rpc/src/trace.rs | 52 ++++++++++++++++++------------------- 1 file changed, 26 insertions(+), 26 deletions(-) diff --git a/crates/rpc/rpc/src/trace.rs b/crates/rpc/rpc/src/trace.rs index ffbde7a38498..d0b22e458ec7 100644 --- a/crates/rpc/rpc/src/trace.rs +++ b/crates/rpc/rpc/src/trace.rs @@ -39,31 +39,30 @@ pub struct TraceApi { inner: Arc>, } -trait TransactionCallback +trait TransactionCallback where Self: for<'a> Fn( - TransactionInfo, - TracingInspector, - ExecutionResult, - &'a State, - &'a CacheDB>>, - ) -> EthResult - + Send - + 'static, + TransactionInfo, + TracingInspector, + ExecutionResult, + &'a State, + &'a CacheDB>>, + ) -> EthResult + + Send + + 'static, { } -impl TransactionCallback for F -where +impl TransactionCallback for F where F: for<'a> Fn( - TransactionInfo, - TracingInspector, - ExecutionResult, - &'a State, - &'a CacheDB>>, - ) -> EthResult - + Send - + 'static, + TransactionInfo, + TracingInspector, + ExecutionResult, + &'a State, + &'a CacheDB>>, + ) -> EthResult + + Send + + 'static { } @@ -250,7 +249,7 @@ where ) -> EthResult> { if indices.len() != 1 { // The OG impl failed if it gets more than a single index - return Ok(None) + return Ok(None); } self.trace_get_index(hash, indices[0]).await } @@ -294,7 +293,7 @@ where if distance > 100 { return Err(EthApiError::InvalidParams( "Block range too large; currently limited to 100 blocks".to_string(), - )) + )); } // fetch all blocks in that range @@ -304,7 +303,7 @@ where let mut target_blocks = Vec::new(); for block in blocks { let mut transaction_indices = HashSet::new(); - let mut highest_matching_index = 0; + let mut highest_matching_index = 0; for (tx_idx, tx) in block.body.iter().enumerate() { let from = tx.recover_signer().ok_or(BlockError::InvalidSignature)?; let to = tx.to(); @@ -330,7 +329,7 @@ where if let Some(idx) = tx_info.index { if !indices.contains(&idx) { // only record traces for relevant transactions - return Ok(None) + return Ok(None); } } let traces = inspector @@ -433,7 +432,8 @@ where let mut results = Vec::with_capacity(transactions.len()); let mut db = CacheDB::new(StateProviderDatabase::new(state)); - let max_transactions = highest_index.map_or(transactions.len(), |highest| highest as usize + 1); + let max_transactions = + highest_index.map_or(transactions.len(), |highest| highest as usize + 1); let transactions = transactions.into_iter().take(max_transactions).enumerate(); for (idx, tx) in transactions { @@ -512,8 +512,8 @@ where author: block.header.beneficiary, reward_type: RewardType::Uncle, value: U256::from( - block_reward(base_block_reward, block.ommers.len()) - - base_block_reward, + block_reward(base_block_reward, block.ommers.len()) + - base_block_reward, ), }, )); From ee82515874bc1c8f388bbcf76b904411cd5d8b10 Mon Sep 17 00:00:00 2001 From: Sean Matthew Date: Thu, 12 Oct 2023 10:06:41 -0400 Subject: [PATCH 14/22] remove fmt --- crates/rpc/rpc/src/trace.rs | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/crates/rpc/rpc/src/trace.rs b/crates/rpc/rpc/src/trace.rs index d0b22e458ec7..c58c8e257719 100644 --- a/crates/rpc/rpc/src/trace.rs +++ b/crates/rpc/rpc/src/trace.rs @@ -249,7 +249,7 @@ where ) -> EthResult> { if indices.len() != 1 { // The OG impl failed if it gets more than a single index - return Ok(None); + return Ok(None) } self.trace_get_index(hash, indices[0]).await } @@ -293,7 +293,7 @@ where if distance > 100 { return Err(EthApiError::InvalidParams( "Block range too large; currently limited to 100 blocks".to_string(), - )); + )) } // fetch all blocks in that range @@ -329,7 +329,7 @@ where if let Some(idx) = tx_info.index { if !indices.contains(&idx) { // only record traces for relevant transactions - return Ok(None); + return Ok(None) } } let traces = inspector @@ -512,8 +512,8 @@ where author: block.header.beneficiary, reward_type: RewardType::Uncle, value: U256::from( - block_reward(base_block_reward, block.ommers.len()) - - base_block_reward, + block_reward(base_block_reward, block.ommers.len()) - + base_block_reward, ), }, )); From 5c05aa2e842e67bd413352ae007e4fd2edc18206 Mon Sep 17 00:00:00 2001 From: Sean Matthew Date: Thu, 12 Oct 2023 10:08:37 -0400 Subject: [PATCH 15/22] update --- crates/rpc/rpc/src/trace.rs | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/crates/rpc/rpc/src/trace.rs b/crates/rpc/rpc/src/trace.rs index c58c8e257719..28c1c3d9fe00 100644 --- a/crates/rpc/rpc/src/trace.rs +++ b/crates/rpc/rpc/src/trace.rs @@ -433,7 +433,7 @@ where let mut db = CacheDB::new(StateProviderDatabase::new(state)); let max_transactions = - highest_index.map_or(transactions.len(), |highest| highest as usize + 1); + highest_index.map_or(transactions.len(), |highest| highest as usize); let transactions = transactions.into_iter().take(max_transactions).enumerate(); for (idx, tx) in transactions { @@ -454,9 +454,13 @@ where let ResultAndState { result, state } = res; results.push(f(tx_info, inspector, result, &state, &db)?); - // need to apply the state changes of this transaction before executing - // the next transaction - db.commit(state) + // need to apply the state changes of this transaction before executing the +- // next transaction +- if transactions.peek().is_some() { + // need to apply the state changes of this transaction before executing + // the next transaction + db.commit(state) + } } Ok(results) From d2c94d2f2dde9480bad0017dcf487d556f177935 Mon Sep 17 00:00:00 2001 From: Sean Matthew Date: Thu, 12 Oct 2023 10:14:29 -0400 Subject: [PATCH 16/22] update --- crates/rpc/rpc/src/trace.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/crates/rpc/rpc/src/trace.rs b/crates/rpc/rpc/src/trace.rs index 28c1c3d9fe00..2280611273af 100644 --- a/crates/rpc/rpc/src/trace.rs +++ b/crates/rpc/rpc/src/trace.rs @@ -434,9 +434,9 @@ where let max_transactions = highest_index.map_or(transactions.len(), |highest| highest as usize); - let transactions = transactions.into_iter().take(max_transactions).enumerate(); + let mut transactions = transactions.into_iter().take(max_transactions).enumerate().peekable(); - for (idx, tx) in transactions { + while let Some((idx, tx)) = transactions.next() { let tx = tx.into_ecrecovered().ok_or(BlockError::InvalidSignature)?; let tx_info = TransactionInfo { hash: Some(tx.hash()), From 0e85a9ca327ab9f94a833e5eba358bf6b09e713f Mon Sep 17 00:00:00 2001 From: Sean Matthew Date: Thu, 12 Oct 2023 10:15:44 -0400 Subject: [PATCH 17/22] fix --- crates/rpc/rpc/src/trace.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/crates/rpc/rpc/src/trace.rs b/crates/rpc/rpc/src/trace.rs index 2280611273af..fa7ca27237bc 100644 --- a/crates/rpc/rpc/src/trace.rs +++ b/crates/rpc/rpc/src/trace.rs @@ -455,8 +455,8 @@ where results.push(f(tx_info, inspector, result, &state, &db)?); // need to apply the state changes of this transaction before executing the -- // next transaction -- if transactions.peek().is_some() { + // next transaction + if transactions.peek().is_some() { // need to apply the state changes of this transaction before executing // the next transaction db.commit(state) From 17e88aa8bc91fc9187f11a3e0dfd43b0eea5f8f6 Mon Sep 17 00:00:00 2001 From: Sean Matthew Date: Thu, 12 Oct 2023 12:20:04 -0400 Subject: [PATCH 18/22] fmt --- crates/rpc/rpc/src/trace.rs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/crates/rpc/rpc/src/trace.rs b/crates/rpc/rpc/src/trace.rs index fa7ca27237bc..83d5887125f1 100644 --- a/crates/rpc/rpc/src/trace.rs +++ b/crates/rpc/rpc/src/trace.rs @@ -434,7 +434,8 @@ where let max_transactions = highest_index.map_or(transactions.len(), |highest| highest as usize); - let mut transactions = transactions.into_iter().take(max_transactions).enumerate().peekable(); + let mut transactions = + transactions.into_iter().take(max_transactions).enumerate().peekable(); while let Some((idx, tx)) = transactions.next() { let tx = tx.into_ecrecovered().ok_or(BlockError::InvalidSignature)?; From d43b264c15bd9015e75461db50ebb45ac3fcffef Mon Sep 17 00:00:00 2001 From: Sean Matthew Date: Thu, 12 Oct 2023 12:21:42 -0400 Subject: [PATCH 19/22] update --- crates/rpc/rpc/src/trace.rs | 47 ++++++++++++++----------------------- 1 file changed, 18 insertions(+), 29 deletions(-) diff --git a/crates/rpc/rpc/src/trace.rs b/crates/rpc/rpc/src/trace.rs index 83d5887125f1..55eb2d8e8470 100644 --- a/crates/rpc/rpc/src/trace.rs +++ b/crates/rpc/rpc/src/trace.rs @@ -39,33 +39,6 @@ pub struct TraceApi { inner: Arc>, } -trait TransactionCallback -where - Self: for<'a> Fn( - TransactionInfo, - TracingInspector, - ExecutionResult, - &'a State, - &'a CacheDB>>, - ) -> EthResult - + Send - + 'static, -{ -} - -impl TransactionCallback for F where - F: for<'a> Fn( - TransactionInfo, - TracingInspector, - ExecutionResult, - &'a State, - &'a CacheDB>>, - ) -> EthResult - + Send - + 'static -{ -} - // === impl TraceApi === impl TraceApi { @@ -391,7 +364,15 @@ where ) -> EthResult>> where // This is the callback that's invoked for each transaction with - F: TransactionCallback, + F: for<'a> Fn( + TransactionInfo, + TracingInspector, + ExecutionResult, + &'a revm_primitives::State, + &'a CacheDB>>, + ) -> EthResult + + Send + + 'static, R: Send + 'static, { self.trace_block_until(block_id, None, config, f).await @@ -405,7 +386,15 @@ where f: F, ) -> EthResult>> where - F: TransactionCallback, + F: for<'a> Fn( + TransactionInfo, + TracingInspector, + ExecutionResult, + &'a revm_primitives::State, + &'a CacheDB>>, + ) -> EthResult + + Send + + 'static, R: Send + 'static, { let ((cfg, block_env, _), block) = futures::try_join!( From caf96fc8f9a0c6ca49fe98b26d8c23c771db9922 Mon Sep 17 00:00:00 2001 From: Sean Matthew Date: Thu, 12 Oct 2023 12:23:28 -0400 Subject: [PATCH 20/22] update --- crates/rpc/rpc/src/trace.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/crates/rpc/rpc/src/trace.rs b/crates/rpc/rpc/src/trace.rs index 55eb2d8e8470..123961f41880 100644 --- a/crates/rpc/rpc/src/trace.rs +++ b/crates/rpc/rpc/src/trace.rs @@ -368,7 +368,7 @@ where TransactionInfo, TracingInspector, ExecutionResult, - &'a revm_primitives::State, + &'a State, &'a CacheDB>>, ) -> EthResult + Send @@ -390,7 +390,7 @@ where TransactionInfo, TracingInspector, ExecutionResult, - &'a revm_primitives::State, + &'a State, &'a CacheDB>>, ) -> EthResult + Send From 5dd57123ea0dec2b2e63b251f002bc71a11733f1 Mon Sep 17 00:00:00 2001 From: Sean Matthew Date: Thu, 12 Oct 2023 12:25:12 -0400 Subject: [PATCH 21/22] update --- crates/rpc/rpc/src/trace.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/crates/rpc/rpc/src/trace.rs b/crates/rpc/rpc/src/trace.rs index 123961f41880..4e745f52f035 100644 --- a/crates/rpc/rpc/src/trace.rs +++ b/crates/rpc/rpc/src/trace.rs @@ -356,7 +356,7 @@ where /// 4. calls the callback with the transaction info, the execution result, the changed state /// _after_ the transaction [StateProviderDatabase] and the database that points to the state /// right _before_ the transaction. - async fn trace_block_with<'a, F, R>( + async fn trace_block_with( &self, block_id: BlockId, config: TracingInspectorConfig, @@ -378,7 +378,7 @@ where self.trace_block_until(block_id, None, config, f).await } - async fn trace_block_until<'a, F, R>( + async fn trace_block_until( &self, block_id: BlockId, highest_index: Option, From d50470bcb8a28d827bcc974ad9b9261a06f3823a Mon Sep 17 00:00:00 2001 From: Matthias Seitz Date: Thu, 12 Oct 2023 20:31:54 +0200 Subject: [PATCH 22/22] docs: some docs --- crates/rpc/rpc/src/trace.rs | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/crates/rpc/rpc/src/trace.rs b/crates/rpc/rpc/src/trace.rs index 4e745f52f035..9ed0d1894617 100644 --- a/crates/rpc/rpc/src/trace.rs +++ b/crates/rpc/rpc/src/trace.rs @@ -378,6 +378,11 @@ where self.trace_block_until(block_id, None, config, f).await } + /// Executes all transactions of a block. + /// + /// If a `highest_index` is given, this will only execute the first `highest_index` + /// transactions, in other words, it will stop executing transactions after the + /// `highest_index`th transaction. async fn trace_block_until( &self, block_id: BlockId,