Skip to content

Commit b648bfb

Browse files
committed
cleanup
1 parent aef9b98 commit b648bfb

File tree

3 files changed

+101
-37
lines changed

3 files changed

+101
-37
lines changed

src/tasks/submit/flashbots/provider.rs

Lines changed: 19 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,15 @@
11
//! A generic Flashbots bundle API wrapper.
2-
use std::io::Read;
3-
42
use crate::config::BuilderConfig;
53
use alloy::{
6-
primitives::{BlockNumber, keccak256, ruint::aliases::B256},
7-
rpc::types::mev::{EthBundleHash, MevSendBundle},
4+
primitives::{BlockNumber, keccak256},
5+
rpc::types::mev::{EthBundleHash, MevSendBundle, SimBundleResponse},
86
signers::Signer,
97
};
10-
use axum::body;
118
use eyre::Context as _;
12-
9+
use init4_bin_base::utils::signer::LocalOrAws;
1310
use reqwest::header::CONTENT_TYPE;
1411
use serde_json::json;
1512

16-
use init4_bin_base::utils::signer::LocalOrAws;
17-
1813
/// A wrapper over a `Provider` that adds Flashbots MEV bundle helpers.
1914
#[derive(Debug)]
2015
pub struct Flashbots {
@@ -50,7 +45,10 @@ impl Flashbots {
5045
/// Simulate a bundle via `mev_simBundle`.
5146
pub async fn simulate_bundle(&self, bundle: MevSendBundle) -> eyre::Result<()> {
5247
let params = serde_json::to_value(bundle)?;
53-
let _ = self.raw_call("mev_simBundle", params).await?;
48+
let v = self.raw_call("mev_simBundle", params).await?;
49+
let resp: SimBundleResponse =
50+
serde_json::from_value(v.get("result").cloned().unwrap_or(serde_json::Value::Null))?;
51+
dbg!("successfully simulated bundle", &resp);
5452
Ok(())
5553
}
5654

@@ -79,13 +77,7 @@ impl Flashbots {
7977
let body = json!({"jsonrpc":"2.0","id":1,"method":method,"params":params});
8078
let body_bz = serde_json::to_vec(&body)?;
8179

82-
let payload = format!("0x{:x}", keccak256(body_bz.clone()));
83-
let signature = self.signer.sign_message(payload.as_ref()).await?;
84-
dbg!(signature.to_string());
85-
86-
let address = self.signer.address();
87-
let value = format!("{}:{}", address, signature);
88-
dbg!(value.clone());
80+
let value = self.compute_signature(&body_bz).await?;
8981

9082
let client = reqwest::Client::new();
9183
let resp = client
@@ -95,6 +87,7 @@ impl Flashbots {
9587
.body(body_bz)
9688
.send()
9789
.await?;
90+
9891
let text = resp.text().await?;
9992
let v: serde_json::Value =
10093
serde_json::from_str(&text).wrap_err("failed to parse flashbots JSON")?;
@@ -103,7 +96,14 @@ impl Flashbots {
10396
}
10497
Ok(v)
10598
}
106-
}
10799

108-
// Raw Flashbots JSON-RPC call with header signing via reqwest.
109-
impl Flashbots {}
100+
/// Builds an EIP-191 signature for the given body bytes.
101+
async fn compute_signature(&self, body_bz: &Vec<u8>) -> Result<String, eyre::Error> {
102+
let payload = format!("0x{:x}", keccak256(body_bz.clone()));
103+
let signature = self.signer.sign_message(payload.as_ref()).await?;
104+
dbg!(signature.to_string());
105+
let address = self.signer.address();
106+
let value = format!("{}:{}", address, signature);
107+
Ok(value)
108+
}
109+
}

src/test_utils.rs

Lines changed: 55 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,10 @@
11
//! Test utilities for testing builder tasks
22
use crate::config::BuilderConfig;
33
use alloy::{
4-
consensus::{SignableTransaction, TxEip1559, TxEnvelope}, primitives::{Address, TxKind, B256, U256}, rpc::client::BuiltInConnectionString, signers::{local::PrivateKeySigner, SignerSync}
4+
consensus::{SignableTransaction, TxEip1559, TxEnvelope},
5+
primitives::{Address, B256, TxKind, U256},
6+
rpc::client::BuiltInConnectionString,
7+
signers::{SignerSync, local::PrivateKeySigner},
58
};
69
use eyre::Result;
710
use init4_bin_base::{
@@ -11,13 +14,56 @@ use init4_bin_base::{
1114
perms::OAuthConfig,
1215
utils::{calc::SlotCalculator, provider::ProviderConfig},
1316
};
17+
use std::env;
1418
use std::str::FromStr;
1519
use trevm::revm::{context::BlockEnv, context_interface::block::BlobExcessGasAndPrice};
1620

21+
/// Sets up a sepolia Flashbots-compatible builder config with test values
22+
pub fn setup_sepolia_config() -> Result<BuilderConfig> {
23+
let config = BuilderConfig {
24+
host_chain_id: 11155111, // Sepolia chain ID
25+
ru_chain_id: signet_constants::pecorino::RU_CHAIN_ID,
26+
host_rpc: "https://ethereum-sepolia-rpc.publicnode.com"
27+
.parse::<BuiltInConnectionString>()
28+
.map(ProviderConfig::new)
29+
.unwrap(),
30+
ru_rpc: "ws://rpc.pecorino.signet.sh"
31+
.parse::<BuiltInConnectionString>()
32+
.unwrap()
33+
.try_into()
34+
.unwrap(),
35+
tx_broadcast_urls: vec!["http://localhost:9000".into()],
36+
flashbots_endpoint: Some("https://relay-sepolia.flashbots.net:443".parse().unwrap()), // NB: Flashbots API default
37+
zenith_address: Address::default(),
38+
quincey_url: "http://localhost:8080".into(),
39+
sequencer_key: None,
40+
builder_key: env::var("SEPOLIA_ETH_PRIV_KEY").expect("SEPOLIA_ETH_PRIV_KEY must be set"),
41+
builder_port: 8080,
42+
builder_rewards_address: Address::default(),
43+
rollup_block_gas_limit: 3_000_000_000,
44+
tx_pool_url: "http://localhost:9000/".parse().unwrap(),
45+
oauth: OAuthConfig {
46+
oauth_client_id: "some_client_id".into(),
47+
oauth_client_secret: "some_client_secret".into(),
48+
oauth_authenticate_url: "http://localhost:8080".parse().unwrap(),
49+
oauth_token_url: "http://localhost:8080".parse().unwrap(),
50+
oauth_token_refresh_interval: 300, // 5 minutes
51+
},
52+
builder_helper_address: Address::default(),
53+
concurrency_limit: None, // NB: Defaults to available parallelism
54+
slot_calculator: SlotCalculator::new(
55+
1740681556, // pecorino start timestamp as sane default
56+
0, 1,
57+
),
58+
};
59+
Ok(config)
60+
}
61+
1762
/// Sets up a block builder with test values
1863
pub fn setup_test_config() -> Result<BuilderConfig> {
1964
let config = BuilderConfig {
20-
host_chain_id: signet_constants::pecorino::HOST_CHAIN_ID,
65+
// host_chain_id: signet_constants::pecorino::HOST_CHAIN_ID,
66+
host_chain_id: 11155111, // Sepolia chain ID
2167
ru_chain_id: signet_constants::pecorino::RU_CHAIN_ID,
2268
host_rpc: "ws://host-rpc.pecorino.signet.sh"
2369
.parse::<BuiltInConnectionString>()
@@ -30,12 +76,14 @@ pub fn setup_test_config() -> Result<BuilderConfig> {
3076
.unwrap(),
3177
tx_broadcast_urls: vec!["http://localhost:9000".into()],
3278
flashbots_endpoint: Some("https://relay-sepolia.flashbots.net:443".parse().unwrap()), // NB: Flashbots API default
33-
// flashbots_endpoint: Some("https://relay.flashbots.net:443".parse().unwrap()), // NB: Flashbots API default
3479
zenith_address: Address::default(),
3580
quincey_url: "http://localhost:8080".into(),
36-
builder_port: 8080,
3781
sequencer_key: None,
38-
builder_key: PrivateKeySigner::random().to_bytes().to_string(),
82+
builder_key: env::var("SEPOLIA_ETH_PRIV_KEY").unwrap_or_else(|_| {
83+
dbg!("USING RANDOM BUILDER KEY, set SEPOLIA_ETH_PRIV_KEY to override");
84+
PrivateKeySigner::random().to_bytes().to_string()
85+
}),
86+
builder_port: 8080,
3987
builder_rewards_address: Address::default(),
4088
rollup_block_gas_limit: 3_000_000_000,
4189
tx_pool_url: "http://localhost:9000/".parse().unwrap(),
@@ -64,9 +112,9 @@ pub fn new_signed_tx(
64112
mpfpg: u128,
65113
) -> Result<TxEnvelope> {
66114
let tx = TxEip1559 {
67-
chain_id: signet_constants::pecorino::RU_CHAIN_ID,
115+
chain_id: 11155111,
68116
nonce,
69-
max_fee_per_gas: 50_000,
117+
max_fee_per_gas: 10_000_000,
70118
max_priority_fee_per_gas: mpfpg,
71119
to: TxKind::Call(Address::from_str("0x0000000000000000000000000000000000000000").unwrap()),
72120
value,

tests/flashbots_provider_test.rs

Lines changed: 27 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,33 +1,49 @@
1-
//! Integration tests for the FlashbotsProvider.
2-
//! These tests require the `FLASHBOTS_ENDPOINT` env var to be set.
3-
41
use alloy::{
2+
consensus::Transaction,
53
eips::Encodable2718,
64
primitives::U256,
5+
providers::Provider,
76
rpc::types::mev::{BundleItem, MevSendBundle, ProtocolVersion},
87
signers::local::PrivateKeySigner,
98
};
10-
use builder::tasks::submit::flashbots::Flashbots;
11-
use builder::test_utils::{new_signed_tx, setup_logging, setup_test_config};
9+
use builder::{
10+
tasks::submit::flashbots::Flashbots,
11+
test_utils::{new_signed_tx, setup_sepolia_config, setup_logging},
12+
};
13+
use std::str::FromStr;
1214

1315
#[tokio::test]
1416
#[ignore = "integration test"]
15-
async fn simulate_valid_bundle() {
17+
async fn test_simulate_valid_bundle_sepolia() {
1618
setup_logging();
1719

1820
let flashbots = get_test_provider().await;
1921

20-
let wallet = PrivateKeySigner::random();
21-
let tx = new_signed_tx(&wallet, 0, U256::from(1u64), 51_000).unwrap();
22+
let signer = flashbots.config.builder_key.clone();
23+
let signer = PrivateKeySigner::from_str(&signer).unwrap();
24+
dbg!("using builder key", signer.address());
25+
26+
let tx = new_signed_tx(&signer, 0, U256::from(1u64), 51_000).unwrap();
2227
let tx_bytes = tx.encoded_2718().into();
2328

24-
let bundle_body = vec![BundleItem::Tx { tx: tx_bytes, can_revert: false }];
25-
let bundle = MevSendBundle::new(0, Some(0), ProtocolVersion::V0_1, bundle_body);
29+
let host_provider = flashbots.config.connect_host_provider().await.unwrap();
30+
let latest_block = host_provider
31+
.get_block_by_number(alloy::eips::BlockNumberOrTag::Latest)
32+
.await
33+
.unwrap()
34+
.unwrap()
35+
.number();
36+
dbg!("latest block number", latest_block);
37+
dbg!(tx.chain_id());
38+
39+
let bundle_body = vec![BundleItem::Tx { tx: tx_bytes, can_revert: true }];
40+
dbg!("submitting bundle with 1 tx", &bundle_body);
41+
let bundle = MevSendBundle::new(latest_block, Some(0), ProtocolVersion::V0_1, bundle_body);
2642

2743
let _ = flashbots.simulate_bundle(bundle).await.expect("failed to simulate bundle");
2844
}
2945

3046
async fn get_test_provider() -> Flashbots {
31-
let config = setup_test_config().unwrap();
47+
let config = setup_sepolia_config().unwrap();
3248
Flashbots::new(&config.clone()).await
3349
}

0 commit comments

Comments
 (0)