Skip to content

Commit

Permalink
chore: move trace to extension trait (#818)
Browse files Browse the repository at this point in the history
  • Loading branch information
RexCloud authored Jun 3, 2024
1 parent bcbe735 commit eaf5355
Show file tree
Hide file tree
Showing 5 changed files with 122 additions and 65 deletions.
3 changes: 3 additions & 0 deletions crates/provider/src/ext/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,5 +11,8 @@ pub use engine::EngineApi;
mod debug;
pub use debug::DebugApi;

mod trace;
pub use trace::{TraceApi, TraceCallList};

mod txpool;
pub use txpool::TxPoolApi;
117 changes: 117 additions & 0 deletions crates/provider/src/ext/trace.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,117 @@
//! This module extends the Ethereum JSON-RPC provider with the Trace namespace's RPC methods.
use crate::{Provider, RpcWithBlock};
use alloy_eips::BlockNumberOrTag;
use alloy_network::Network;
use alloy_primitives::TxHash;
use alloy_rpc_types_trace::parity::{LocalizedTransactionTrace, TraceResults, TraceType};
use alloy_transport::{Transport, TransportResult};

/// List of trace calls for use with [`TraceApi::trace_call_many`]
pub type TraceCallList<'a, N> = &'a [(<N as Network>::TransactionRequest, Vec<TraceType>)];

/// Trace namespace rpc interface that gives access to several non-standard RPC methods.
#[cfg_attr(target_arch = "wasm32", async_trait::async_trait(?Send))]
#[cfg_attr(not(target_arch = "wasm32"), async_trait::async_trait)]
pub trait TraceApi<N, T>: Send + Sync
where
N: Network,
T: Transport + Clone,
{
/// Executes the given transaction and returns a number of possible traces.
///
/// # Note
///
/// Not all nodes support this call.
fn trace_call<'a, 'b>(
&self,
request: &'a N::TransactionRequest,
trace_type: &'b [TraceType],
) -> RpcWithBlock<T, (&'a N::TransactionRequest, &'b [TraceType]), TraceResults>;

/// Traces multiple transactions on top of the same block, i.e. transaction `n` will be executed
/// on top of the given block with all `n - 1` transaction applied first.
///
/// Allows tracing dependent transactions.
///
/// # Note
///
/// Not all nodes support this call.
fn trace_call_many<'a>(
&self,
request: TraceCallList<'a, N>,
) -> RpcWithBlock<T, TraceCallList<'a, N>, TraceResults>;

/// Parity trace transaction.
async fn trace_transaction(
&self,
hash: TxHash,
) -> TransportResult<Vec<LocalizedTransactionTrace>>;

/// Trace all transactions in the given block.
///
/// # Note
///
/// Not all nodes support this call.
async fn trace_block(
&self,
block: BlockNumberOrTag,
) -> TransportResult<Vec<LocalizedTransactionTrace>>;
}

#[cfg_attr(target_arch = "wasm32", async_trait::async_trait(?Send))]
#[cfg_attr(not(target_arch = "wasm32"), async_trait::async_trait)]
impl<N, T, P> TraceApi<N, T> for P
where
N: Network,
T: Transport + Clone,
P: Provider<T, N>,
{
fn trace_call<'a, 'b>(
&self,
request: &'a <N as Network>::TransactionRequest,
trace_type: &'b [TraceType],
) -> RpcWithBlock<T, (&'a <N as Network>::TransactionRequest, &'b [TraceType]), TraceResults>
{
RpcWithBlock::new(self.weak_client(), "trace_call", (request, trace_type))
}

fn trace_call_many<'a>(
&self,
request: TraceCallList<'a, N>,
) -> RpcWithBlock<T, TraceCallList<'a, N>, TraceResults> {
RpcWithBlock::new(self.weak_client(), "trace_callMany", request)
}

async fn trace_transaction(
&self,
hash: TxHash,
) -> TransportResult<Vec<LocalizedTransactionTrace>> {
self.client().request("trace_transaction", (hash,)).await
}

async fn trace_block(
&self,
block: BlockNumberOrTag,
) -> TransportResult<Vec<LocalizedTransactionTrace>> {
self.client().request("trace_block", (block,)).await
}
}

#[cfg(test)]
mod test {
use crate::ProviderBuilder;

use super::*;

fn init_tracing() {
let _ = tracing_subscriber::fmt::try_init();
}

#[tokio::test]
async fn test_trace_block() {
init_tracing();
let provider = ProviderBuilder::new().on_anvil();
let traces = provider.trace_block(BlockNumberOrTag::Latest).await.unwrap();
assert_eq!(traces.len(), 0);
}
}
3 changes: 1 addition & 2 deletions crates/provider/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -40,8 +40,7 @@ pub use heart::{PendingTransaction, PendingTransactionBuilder, PendingTransactio

mod provider;
pub use provider::{
EthCall, FilterPollerBuilder, Provider, RootProvider, RpcWithBlock, SendableTx, TraceCallList,
WalletProvider,
EthCall, FilterPollerBuilder, Provider, RootProvider, RpcWithBlock, SendableTx, WalletProvider,
};

pub mod utils;
Expand Down
2 changes: 1 addition & 1 deletion crates/provider/src/provider/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ mod sendable;
pub use sendable::SendableTx;

mod r#trait;
pub use r#trait::{FilterPollerBuilder, Provider, TraceCallList};
pub use r#trait::{FilterPollerBuilder, Provider};

mod wallet;
pub use wallet::WalletProvider;
Expand Down
62 changes: 0 additions & 62 deletions crates/provider/src/provider/trait.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,6 @@ use alloy_rpc_types::{
AccessListWithGasUsed, Block, BlockId, BlockNumberOrTag, EIP1186AccountProofResponse,
FeeHistory, Filter, FilterChanges, Log, SyncStatus,
};
use alloy_rpc_types_trace::parity::{LocalizedTransactionTrace, TraceResults, TraceType};
use alloy_transport::{BoxTransport, Transport, TransportErrorKind, TransportResult};
use serde_json::value::RawValue;
use std::borrow::Cow;
Expand All @@ -27,9 +26,6 @@ use std::borrow::Cow;
/// See [`PollerBuilder`] for more details.
pub type FilterPollerBuilder<T, R> = PollerBuilder<T, (U256,), Vec<R>>;

/// List of trace calls for use with [`Provider::trace_call_many`]
pub type TraceCallList<'a, N> = &'a [(<N as Network>::TransactionRequest, Vec<TraceType>)];

// todo: adjust docs
// todo: reorder
/// Provider is parameterized with a network and a transport. The default
Expand Down Expand Up @@ -789,56 +785,6 @@ pub trait Provider<T: Transport + Clone = BoxTransport, N: Network = Ethereum>:
RpcWithBlock::new(self.weak_client(), "eth_createAccessList", request)
}

/// Executes the given transaction and returns a number of possible traces.
///
/// # Note
///
/// Not all nodes support this call.
fn trace_call<'a, 'b>(
&self,
request: &'a N::TransactionRequest,
trace_type: &'b [TraceType],
) -> RpcWithBlock<T, (&'a N::TransactionRequest, &'b [TraceType]), TraceResults> {
RpcWithBlock::new(self.weak_client(), "trace_call", (request, trace_type))
}

/// Traces multiple transactions on top of the same block, i.e. transaction `n` will be executed
/// on top of the given block with all `n - 1` transaction applied first.
///
/// Allows tracing dependent transactions.
///
/// # Note
///
/// Not all nodes support this call.
fn trace_call_many<'a>(
&self,
request: TraceCallList<'a, N>,
) -> RpcWithBlock<T, TraceCallList<'a, N>, TraceResults> {
RpcWithBlock::new(self.weak_client(), "trace_callMany", request)
}

// todo: move to extension trait
/// Parity trace transaction.
async fn trace_transaction(
&self,
hash: TxHash,
) -> TransportResult<Vec<LocalizedTransactionTrace>> {
self.client().request("trace_transaction", (hash,)).await
}

// todo: move to extension trait
/// Trace all transactions in the given block.
///
/// # Note
///
/// Not all nodes support this call.
async fn trace_block(
&self,
block: BlockNumberOrTag,
) -> TransportResult<Vec<LocalizedTransactionTrace>> {
self.client().request("trace_block", (block,)).await
}

/* ------------------------------------------ anvil ----------------------------------------- */

/// Set the bytecode of a given account.
Expand Down Expand Up @@ -1305,14 +1251,6 @@ mod tests {
assert!(receipts.is_some());
}

#[tokio::test]
async fn gets_block_traces() {
init_tracing();
let provider = ProviderBuilder::new().on_anvil();
let traces = provider.trace_block(BlockNumberOrTag::Latest).await.unwrap();
assert_eq!(traces.len(), 0);
}

#[tokio::test]
async fn sends_raw_transaction() {
init_tracing();
Expand Down

0 comments on commit eaf5355

Please sign in to comment.