Skip to content

Commit 54a7490

Browse files
committed
refactors flashbots provider
1 parent aaa0de7 commit 54a7490

File tree

6 files changed

+224
-176
lines changed

6 files changed

+224
-176
lines changed

Makefile

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,3 @@ clippy:
4545

4646
test-flashbots:
4747
$(CARGO) test --test flashbots_provider_test -- --ignored
48-
49-
tx-submitter:
50-
$(CARGO) run --bin transaction-submitter

src/tasks/submit/flashbots/mod.rs

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,5 @@
11
//! Signet's Flashbots Block Submitter
22
3-
/// handles rollup block submission to the Flashbots network
4-
/// via the provider
5-
pub mod submitter;
6-
pub use submitter::FlashbotsSubmitter;
7-
83
/// implements a bundle provider API for building Flashbots
94
/// compatible MEV bundles
105
pub mod provider;
Lines changed: 46 additions & 113 deletions
Original file line numberDiff line numberDiff line change
@@ -1,143 +1,76 @@
11
//! A generic Flashbots bundle API wrapper.
2-
use alloy::network::{Ethereum, Network};
3-
use alloy::primitives::Address;
4-
use alloy::providers::{
5-
Provider, SendableTx,
6-
fillers::{FillerControlFlow, TxFiller},
2+
use crate::config::{BuilderConfig, HostProvider};
3+
use alloy::{
4+
primitives::BlockNumber,
5+
providers::Provider,
6+
rpc::types::mev::{EthBundleHash, MevSendBundle},
77
};
8-
use alloy::rpc::types::eth::TransactionRequest;
9-
use alloy::rpc::types::mev::{EthBundleHash, MevSendBundle, ProtocolVersion};
10-
use alloy_transport::TransportResult;
118
use eyre::Context as _;
12-
use std::ops::Deref;
13-
14-
use crate::tasks::block::sim::SimResult;
15-
use signet_types::SignedFill;
9+
use init4_bin_base::deps::tracing::debug;
10+
use serde_json::json;
11+
use signet_zenith::Zenith::ZenithInstance;
1612

1713
/// A wrapper over a `Provider` that adds Flashbots MEV bundle helpers.
18-
#[derive(Debug, Clone)]
19-
pub struct FlashbotsProvider<P> {
20-
inner: P,
14+
#[derive(Debug)]
15+
pub struct FlashbotsProvider {
2116
/// The base URL for the Flashbots API.
2217
pub relay_url: url::Url,
18+
/// Zenith instance for constructing Signet blocks.
19+
pub zenith: ZenithInstance<HostProvider>,
20+
/// Builder configuration for the task.
21+
pub config: BuilderConfig,
2322
}
2423

25-
impl<P: Provider<Ethereum>> FlashbotsProvider<P> {
24+
impl FlashbotsProvider {
2625
/// Wraps a provider with the URL and returns a new `FlashbotsProvider`.
27-
pub fn new(inner: P, relay_url: url::Url) -> Self {
28-
Self { inner, relay_url }
29-
}
30-
31-
/// Consume self and return the inner provider.
32-
pub fn into_inner(self) -> P {
33-
self.inner
34-
}
35-
36-
/// Borrow the inner provider.
37-
pub const fn inner(&self) -> &P {
38-
&self.inner
39-
}
40-
}
41-
42-
impl<P> Deref for FlashbotsProvider<P> {
43-
type Target = P;
44-
fn deref(&self) -> &Self::Target {
45-
&self.inner
46-
}
47-
}
48-
49-
impl<P> FlashbotsProvider<P>
50-
where
51-
P: Provider<Ethereum> + Clone + Send + Sync + 'static,
52-
{
53-
/// Convert a SignedFill to a TransactionRequest calling the Orders contract.
54-
///
55-
/// This prepares the calldata for RollupOrders::fillPermit2(outputs, permit2) and sets
56-
/// `to` to the given Orders contract address. The returned request is unsigned.
57-
pub fn fill_to_tx_request(fill: &SignedFill, orders_contract: Address) -> TransactionRequest {
58-
fill.to_fill_tx(orders_contract)
59-
}
60-
61-
/// Construct a new empty bundle template for the given block number.
62-
pub fn empty_bundle(&self, target_block: u64) -> MevSendBundle {
63-
MevSendBundle::new(target_block, Some(target_block), ProtocolVersion::V0_1, vec![])
64-
}
65-
66-
/// Prepares a bundle transaction from the simulation result.
67-
pub fn prepare_bundle(&self, sim_result: &SimResult, target_block: u64) -> MevSendBundle {
68-
let bundle_body = Vec::new();
69-
70-
// Populate the bundle body with the simulation result.
71-
72-
// TODO: Push host fills into the Flashbots bundle body.
73-
let _host_fills = sim_result.block.host_fills();
74-
// _host_fills.iter().map(|f| f.to_fill_tx(todo!()));
75-
76-
// TODO: Add the rollup block blob transaction to the Flashbots bundle body.
77-
// let blob_tx = ...;
78-
let _ = &sim_result; // keep param used until wired
79-
80-
// Create the bundle from the target block and bundle body
81-
MevSendBundle::new(target_block, Some(target_block), ProtocolVersion::V0_1, bundle_body)
26+
pub fn new(
27+
relay_url: url::Url,
28+
zenith: ZenithInstance<HostProvider>,
29+
config: &BuilderConfig,
30+
) -> Self {
31+
Self { relay_url, zenith, config: config.clone() }
8232
}
8333

8434
/// Submit the prepared Flashbots bundle to the relay via `mev_sendBundle`.
8535
pub async fn send_bundle(&self, bundle: MevSendBundle) -> eyre::Result<EthBundleHash> {
86-
// NOTE: The Flashbots relay expects a single parameter which is the bundle object.
36+
// NB: The Flashbots relay expects a single parameter which is the bundle object.
8737
// Alloy's `raw_request` accepts any serializable params; wrapping in a 1-tuple is fine.
8838
let hash: EthBundleHash = self
89-
.inner
39+
.zenith
40+
.provider()
9041
.raw_request("mev_sendBundle".into(), (bundle,))
9142
.await
92-
.wrap_err("flashbots mev_sendBundle RPC failed")?;
43+
.wrap_err("mev_sendBundle RPC failed")?;
44+
debug!(?hash, "mev_sendBundle response");
9345
Ok(hash)
9446
}
9547

9648
/// Simulate a bundle via `mev_simBundle`.
97-
pub async fn simulate_bundle(&self, bundle: &MevSendBundle) -> eyre::Result<()> {
98-
// We ignore the response (likely a JSON object with sim traces) for now and just ensure success.
99-
let _resp: serde_json::Value = self
100-
.inner
49+
pub async fn simulate_bundle(&self, bundle: MevSendBundle) -> eyre::Result<()> {
50+
let resp: serde_json::Value = self
51+
.zenith
52+
.provider()
10153
.raw_request("mev_simBundle".into(), (bundle.clone(),))
10254
.await
103-
.wrap_err("flashbots mev_simBundle RPC failed")?;
55+
.wrap_err("mev_simBundle RPC failed")?;
56+
debug!(?resp, "mev_simBundle response");
10457
Ok(())
10558
}
10659

107-
/// Check the status of a previously submitted bundle.
108-
pub async fn bundle_status(&self, _hash: EthBundleHash) -> eyre::Result<()> {
109-
eyre::bail!("FlashbotsProvider::bundle_status unimplemented")
110-
}
111-
}
112-
113-
impl<N, P> TxFiller<N> for FlashbotsProvider<P>
114-
where
115-
N: Network,
116-
P: TxFiller<N> + Provider<N> + Clone + Send + Sync + core::fmt::Debug + 'static,
117-
{
118-
type Fillable = <P as TxFiller<N>>::Fillable;
119-
120-
fn status(&self, tx: &N::TransactionRequest) -> FillerControlFlow {
121-
TxFiller::<N>::status(&self.inner, tx)
122-
}
123-
124-
fn fill_sync(&self, tx: &mut SendableTx<N>) {
125-
TxFiller::<N>::fill_sync(&self.inner, tx)
126-
}
127-
128-
fn prepare<Prov: Provider<N>>(
129-
&self,
130-
provider: &Prov,
131-
tx: &N::TransactionRequest,
132-
) -> impl core::future::Future<Output = TransportResult<Self::Fillable>> + Send {
133-
TxFiller::<N>::prepare(&self.inner, provider, tx)
134-
}
135-
136-
fn fill(
60+
/// Check that status of a bundle
61+
pub async fn bundle_status(
13762
&self,
138-
fillable: Self::Fillable,
139-
tx: SendableTx<N>,
140-
) -> impl core::future::Future<Output = TransportResult<SendableTx<N>>> + Send {
141-
TxFiller::<N>::fill(&self.inner, fillable, tx)
63+
_hash: EthBundleHash,
64+
block_number: BlockNumber,
65+
) -> eyre::Result<()> {
66+
let params = json!({ "bundleHash": _hash, "blockNumber": block_number });
67+
let resp: serde_json::Value = self
68+
.zenith
69+
.provider()
70+
.raw_request("flashbots_getBundleStatsV2".into(), (params,))
71+
.await
72+
.wrap_err("flashbots_getBundleStatsV2 RPC failed")?;
73+
debug!(?resp, "flashbots_getBundleStatsV2 response");
74+
Ok(())
14275
}
14376
}

0 commit comments

Comments
 (0)