Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: Add a TraceRpc helper type #1086

Open
wants to merge 3 commits into
base: main
Choose a base branch
from

Conversation

moricho
Copy link
Contributor

@moricho moricho commented Jul 21, 2024

Motivation

Closes: #820
This allows users to set trace types for trace rpc calls using the builder pattern as with RpcWithBlock.

Solution

Adds TraceRpcWithBlock, allowing users to configure TraceType for trace RPC calls using the builder pattern. This includes RpcWithBlock as a member and implements Deref, enabling the setting of block kind arguments as with RpcWithBlock.

On the RpcWithBlock side, a trace_types field is added, which is enabled when the trace-api feature is on. The trace_types is passed by TraceRpcWithBlock and merged into the request parameters when calling RpcWithBlockFut::poll_preparing.

Proposed API

#[derive(Debug, Clone)]
pub struct TraceRpcWithBlock<T, Params, Resp, Output = Resp, Map = fn(Resp) -> Output>
where
    T: Transport + Clone,
    Params: RpcParam,
    Resp: RpcReturn,
    Map: Fn(Resp) -> Output,
{
    inner: RpcWithBlock<T, Params, Resp, Output, Map>,
    trace_types: HashSet<TraceType>,
}

impl<T, Params, Resp, Output, Map> TraceRpcWithBlock<T, Params, Resp, Output, Map>
where
    T: Transport + Clone,
    Params: RpcParam,
    Resp: RpcReturn,
    Map: Fn(Resp) -> Output + 'static,
{
    /// Set the trace type.
    pub fn trace_type(mut self, trace_type: TraceType) -> Self {
        self.trace_types.insert(trace_type);
        self
    }

    /// Set the trace types.
    pub fn trace_types<I: IntoIterator<Item = TraceType>>(mut self, trace_types: I) -> Self {
        self.trace_types.extend(trace_types);
        self
    }

    /// Set the trace type to "trace".
    pub fn trace(self) -> Self {
        self.trace_type(TraceType::Trace)
    }

    /// Set the trace type to "vmTrace".
    pub fn vm_trace(self) -> Self {
        self.trace_type(TraceType::VmTrace)
    }

    /// Set the trace type to "stateDiff".
    pub fn state_diff(self) -> Self {
        self.trace_type(TraceType::StateDiff)
    }
}

impl<T, Params, Resp, Output, Map> Deref for TraceRpcWithBlock<T, Params, Resp, Output, Map>
where
    T: Transport + Clone,
    Params: RpcParam,
    Resp: RpcReturn,
    Map: Fn(Resp) -> Output,
{
    type Target = RpcWithBlock<T, Params, Resp, Output, Map>;

    fn deref(&self) -> &Self::Target {
        &self.inner
    }
}

Usage

let provider = ProviderBuilder::new().on_anvil();
let traces = provider
    .trace_replay_block_transactions(BlockNumberOrTag::Latest)
    .trace()
    .await
    .unwrap();
let provider = ProviderBuilder::new().on_anvil();
let tx_reqs = vec![];
let trace_types = vec![TraceType::Trace, TraceType::VmTrace];
let traces = provider
    .trace_call_many(tx_reqs)
    .trace_types(trace_types)
    .await
    .unwrap();

PR Checklist

  • Added Tests
  • Added Documentation
  • Breaking changes

@moricho
Copy link
Contributor Author

moricho commented Jul 21, 2024

@mattsse I implemented TraceRpcWithBlock as shown in this PR, but there might be a better way or something I missed. Please give me any feedback you have on the API design 🙏

@moricho
Copy link
Contributor Author

moricho commented Jul 25, 2024

@mattsse could you please take a look?

@yash-atreya
Copy link
Member

Hey @moricho thank you for your contribution and sorry for the delayed response.

This is indeed helpful. We would want TraceRpcWithBlock integrated with ProviderCall, so that the trait can be overridden to fetch from arbitrary data sources.

Please take a look at how RpcWithBlock leverages ProviderCall under the hood here: https://github.com/alloy-rs/alloy/blob/main/crates/provider/src/provider/with_block.rs.

Let me know if you need more pointers.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Add a TraceRpc helper type for configuring the trace kind argument
2 participants