diff --git a/crates/rpc/rpc-testing-util/src/trace.rs b/crates/rpc/rpc-testing-util/src/trace.rs index 69e51b398..ef1605b67 100644 --- a/crates/rpc/rpc-testing-util/src/trace.rs +++ b/crates/rpc/rpc-testing-util/src/trace.rs @@ -1,7 +1,8 @@ //! Helpers for testing trace calls. use futures::{Stream, StreamExt}; use jsonrpsee::core::Error as RpcError; -use reth_primitives::{BlockId, TxHash}; + +use reth_primitives::{BlockId, Bytes, TxHash}; use reth_rpc_api::clients::TraceApiClient; use reth_rpc_types::trace::parity::{LocalizedTransactionTrace, TraceResults, TraceType}; use std::{ @@ -9,6 +10,9 @@ use std::{ pin::Pin, task::{Context, Poll}, }; +/// A type alias that represents the result of a raw transaction trace stream. +type RawTransactionTraceResult<'a> = + Pin> + 'a>>; /// A result type for the `trace_block` method that also captures the requested block. pub type TraceBlockResult = Result<(Vec, BlockId), (RpcError, BlockId)>; /// Type alias representing the result of replaying a transaction. @@ -47,6 +51,34 @@ pub trait TraceApiExt { ) -> ReplayTransactionStream<'_> where I: IntoIterator; + + /// Returns a new stream that traces the provided raw transaction data. + fn trace_raw_transaction_stream( + &self, + data: Bytes, + trace_types: HashSet, + block_id: Option, + ) -> RawTransactionTraceStream<'_>; +} +/// A stream that traces the provided raw transaction data. + +#[must_use = "streams do nothing unless polled"] +pub struct RawTransactionTraceStream<'a> { + stream: RawTransactionTraceResult<'a>, +} + +impl<'a> Stream for RawTransactionTraceStream<'a> { + type Item = Result<(TraceResults, Bytes), (RpcError, Bytes)>; + + fn poll_next(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll> { + self.stream.as_mut().poll_next(cx) + } +} + +impl<'a> std::fmt::Debug for RawTransactionTraceStream<'a> { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + f.debug_struct("RawTransactionTraceStream").finish() + } } /// A stream that replays the transactions for the requested hashes. @@ -125,6 +157,20 @@ impl TraceApiExt for T { .buffered(10); ReplayTransactionStream { stream: Box::pin(stream) } } + fn trace_raw_transaction_stream( + &self, + data: Bytes, + trace_types: HashSet, + block_id: Option, + ) -> RawTransactionTraceStream<'_> { + let stream = futures::stream::once(async move { + match self.trace_raw_transaction(data.clone(), trace_types, block_id).await { + Ok(result) => Ok((result, data)), + Err(err) => Err((err, data)), + } + }); + RawTransactionTraceStream { stream: Box::pin(stream) } + } } /// A stream that yields the traces for the requested blocks.