sp1_cc_host_executor/
sketch_builder.rs

1use std::marker::PhantomData;
2
3use alloy_eips::BlockId;
4use alloy_provider::{network::AnyNetwork, Provider, RootProvider};
5use reth_primitives::EthPrimitives;
6use rsp_primitives::genesis::Genesis;
7use rsp_rpc_db::RpcDb;
8use sp1_cc_client_executor::io::Primitives;
9use url::Url;
10
11use crate::{
12    anchor_builder::{
13        AnchorBuilder, BeaconAnchorBuilder, ChainedBeaconAnchorBuilder, HeaderAnchorBuilder,
14    },
15    ConsensusBeaconAnchor, Eip4788BeaconAnchor, EvmSketch, HostError,
16};
17
18/// A builder for [`EvmSketch`].
19#[derive(Debug)]
20pub struct EvmSketchBuilder<P, PT, A> {
21    block: BlockId,
22    genesis: Genesis,
23    provider: P,
24    anchor_builder: A,
25    phantom: PhantomData<PT>,
26}
27
28impl<P, PT, A> EvmSketchBuilder<P, PT, A> {
29    /// Sets the block on which the contract will be called.
30    pub fn at_block<B: Into<BlockId>>(mut self, block: B) -> Self {
31        self.block = block.into();
32        self
33    }
34    /// Sets the chain on which the contract will be called.
35    pub fn with_genesis(mut self, genesis: Genesis) -> Self {
36        self.genesis = genesis;
37        self
38    }
39}
40
41impl<PT> EvmSketchBuilder<(), PT, ()> {
42    /// Sets the Ethereum HTTP RPC endpoint that will be used.
43    pub fn el_rpc_url(
44        self,
45        rpc_url: Url,
46    ) -> EvmSketchBuilder<RootProvider<AnyNetwork>, PT, HeaderAnchorBuilder<RootProvider<AnyNetwork>>>
47    {
48        let provider = RootProvider::new_http(rpc_url);
49        EvmSketchBuilder {
50            block: self.block,
51            genesis: self.genesis,
52            provider: provider.clone(),
53            anchor_builder: HeaderAnchorBuilder::new(provider),
54            phantom: PhantomData,
55        }
56    }
57}
58
59#[cfg(feature = "optimism")]
60impl<P, A> EvmSketchBuilder<P, EthPrimitives, A> {
61    /// Configures the [`EvmSketch`] for OP Stack.
62    ///
63    /// Note: the sketch must be configured with a OP stack genesis with [`with_genesis()`]. On the
64    /// client, the executor must be created with [`ClientExecutor::optimism()`].
65    ///
66    /// [`with_genesis()`]: EvmSketchBuilder::with_genesis
67    /// [`ClientExecutor::optimism()`]: sp1_cc_client_executor::ClientExecutor::optimism
68    pub fn optimism(self) -> EvmSketchBuilder<P, reth_optimism_primitives::OpPrimitives, A> {
69        EvmSketchBuilder {
70            block: self.block,
71            genesis: self.genesis,
72            provider: self.provider,
73            anchor_builder: self.anchor_builder,
74            phantom: PhantomData,
75        }
76    }
77
78    /// Configures the [`EvmSketch`] for OP Mainnet..
79    pub fn optimism_mainnet(
80        self,
81    ) -> EvmSketchBuilder<P, reth_optimism_primitives::OpPrimitives, A> {
82        EvmSketchBuilder {
83            block: self.block,
84            genesis: Genesis::OpMainnet,
85            provider: self.provider,
86            anchor_builder: self.anchor_builder,
87            phantom: PhantomData,
88        }
89    }
90}
91
92impl<P, PT> EvmSketchBuilder<P, PT, HeaderAnchorBuilder<P>>
93where
94    P: Provider<AnyNetwork>,
95{
96    /// Sets the Beacon HTTP RPC endpoint that will be used.
97    pub fn cl_rpc_url(
98        self,
99        rpc_url: Url,
100    ) -> EvmSketchBuilder<P, PT, BeaconAnchorBuilder<P, Eip4788BeaconAnchor>> {
101        EvmSketchBuilder {
102            block: self.block,
103            genesis: self.genesis,
104            provider: self.provider,
105            anchor_builder: BeaconAnchorBuilder::new(self.anchor_builder, rpc_url),
106            phantom: self.phantom,
107        }
108    }
109}
110
111impl<P, PT> EvmSketchBuilder<P, PT, BeaconAnchorBuilder<P, Eip4788BeaconAnchor>>
112where
113    P: Provider<AnyNetwork>,
114{
115    /// Sets the Beacon HTTP RPC endpoint that will be used.
116    pub fn at_reference_block<B: Into<BlockId>>(
117        self,
118        block_id: B,
119    ) -> EvmSketchBuilder<P, PT, ChainedBeaconAnchorBuilder<P>> {
120        EvmSketchBuilder {
121            block: self.block,
122            genesis: self.genesis,
123            provider: self.provider,
124            anchor_builder: ChainedBeaconAnchorBuilder::new(self.anchor_builder, block_id.into()),
125            phantom: self.phantom,
126        }
127    }
128
129    /// Configures the builder to generate an [`Anchor`] containing the slot number associated to
130    /// the beacon block root.
131    ///
132    /// This is useful for verification methods that have direct access to the state of the beacon
133    /// chain, such as systems using beacon light clients.
134    ///
135    /// [`Anchor`]: sp1_cc_client_executor::Anchor
136    pub fn consensus(
137        self,
138    ) -> EvmSketchBuilder<P, PT, BeaconAnchorBuilder<P, ConsensusBeaconAnchor>> {
139        EvmSketchBuilder {
140            block: self.block,
141            genesis: self.genesis,
142            provider: self.provider,
143            anchor_builder: self.anchor_builder.into_consensus(),
144            phantom: self.phantom,
145        }
146    }
147}
148
149impl<P, PT, A> EvmSketchBuilder<P, PT, A>
150where
151    P: Provider<AnyNetwork> + Clone,
152    PT: Primitives,
153    A: AnchorBuilder,
154{
155    /// Builds an [`EvmSketch`].
156    pub async fn build(self) -> Result<EvmSketch<P, PT>, HostError> {
157        let anchor = self.anchor_builder.build(self.block).await?;
158        let block_number = anchor.header().number;
159
160        let sketch = EvmSketch {
161            genesis: self.genesis,
162            anchor,
163            rpc_db: RpcDb::new(self.provider.clone(), block_number),
164            receipts: None,
165            provider: self.provider,
166            phantom: PhantomData,
167        };
168
169        Ok(sketch)
170    }
171}
172
173impl Default for EvmSketchBuilder<(), EthPrimitives, ()> {
174    fn default() -> Self {
175        Self {
176            block: BlockId::default(),
177            genesis: Genesis::Mainnet,
178            provider: (),
179            anchor_builder: (),
180            phantom: PhantomData,
181        }
182    }
183}