diff --git a/crates/rbuilder/src/backtest/backtest_build_block.rs b/crates/rbuilder/src/backtest/backtest_build_block.rs
index 5d0953bb..c5775dfb 100644
--- a/crates/rbuilder/src/backtest/backtest_build_block.rs
+++ b/crates/rbuilder/src/backtest/backtest_build_block.rs
@@ -107,7 +107,7 @@ where
provider_factory.clone(),
chain_spec.clone(),
cli.block_building_time_ms,
- config.base_config().blocklist()?,
+ config.base_config().blocklist_file_path.clone(),
&config.base_config().sbundle_mergeable_signers(),
config.base_config().coinbase_signer()?,
)?;
diff --git a/crates/rbuilder/src/backtest/backtest_build_range.rs b/crates/rbuilder/src/backtest/backtest_build_range.rs
index da96d7f3..16b32eed 100644
--- a/crates/rbuilder/src/backtest/backtest_build_range.rs
+++ b/crates/rbuilder/src/backtest/backtest_build_range.rs
@@ -133,7 +133,7 @@ where
None
};
- let blocklist = config.base_config().blocklist()?;
+ let blocklist = config.base_config().blocklist_file_path.clone();
let mut read_blocks = spawn_block_fetcher(
historical_data_storage,
diff --git a/crates/rbuilder/src/backtest/execute.rs b/crates/rbuilder/src/backtest/execute.rs
index 053d8bb5..1971ac92 100644
--- a/crates/rbuilder/src/backtest/execute.rs
+++ b/crates/rbuilder/src/backtest/execute.rs
@@ -1,5 +1,6 @@
use crate::{
backtest::BlockData,
+ blocklist::BlockList,
building::{
builders::BacktestSimulateBlockInput, multi_share_bundle_merger::MultiShareBundleMerger,
sim::simulate_all_orders_with_sim_tree, BlockBuildingContext, BundleErr, OrderErr,
@@ -9,7 +10,6 @@ use crate::{
primitives::{OrderId, SimulatedOrder},
utils::{clean_extradata, Signer},
};
-use ahash::HashSet;
use alloy_primitives::{Address, U256};
use reth::revm::cached::CachedReads;
use reth_chainspec::ChainSpec;
@@ -61,7 +61,7 @@ pub fn backtest_prepare_ctx_for_block
(
provider: P,
chain_spec: Arc,
build_block_lag_ms: i64,
- blocklist: HashSet,
+ blocklist: BlockList,
sbundle_mergeabe_signers: &[Address],
builder_signer: Signer,
) -> eyre::Result
@@ -114,7 +114,7 @@ pub fn backtest_simulate_block(
build_block_lag_ms: i64,
builders_names: Vec,
config: &ConfigType,
- blocklist: HashSet,
+ blocklist: BlockList,
sbundle_mergeabe_signers: &[Address],
) -> eyre::Result
where
diff --git a/crates/rbuilder/src/backtest/redistribute/mod.rs b/crates/rbuilder/src/backtest/redistribute/mod.rs
index 1d26a940..514ca994 100644
--- a/crates/rbuilder/src/backtest/redistribute/mod.rs
+++ b/crates/rbuilder/src/backtest/redistribute/mod.rs
@@ -1009,7 +1009,7 @@ where
built_block_lag_ms,
base_config.backtest_builders.clone(),
config,
- base_config.blocklist()?,
+ base_config.blocklist_file_path.clone(),
&base_config.sbundle_mergeable_signers(),
)?
.builder_outputs
diff --git a/crates/rbuilder/src/backtest/restore_landed_orders/resim_landed_block.rs b/crates/rbuilder/src/backtest/restore_landed_orders/resim_landed_block.rs
index 5f570f9b..9933d25e 100644
--- a/crates/rbuilder/src/backtest/restore_landed_orders/resim_landed_block.rs
+++ b/crates/rbuilder/src/backtest/restore_landed_orders/resim_landed_block.rs
@@ -5,7 +5,7 @@ use crate::{
},
utils::{extract_onchain_block_txs, find_suggested_fee_recipient, signed_uint_delta},
};
-use ahash::{HashMap, HashSet};
+use ahash::HashMap;
use alloy_primitives::{TxHash, B256, I256};
use eyre::Context;
use reth_chainspec::ChainSpec;
@@ -46,7 +46,7 @@ where
onchain_block,
chain_spec,
None,
- HashSet::default(),
+ Default::default(),
coinbase,
suggested_fee_recipient,
None,
diff --git a/crates/rbuilder/src/blocklist/mod.rs b/crates/rbuilder/src/blocklist/mod.rs
new file mode 100644
index 00000000..bcbf4361
--- /dev/null
+++ b/crates/rbuilder/src/blocklist/mod.rs
@@ -0,0 +1,147 @@
+use ahash::{HashSet, HashSetExt};
+use alloy_primitives::Address;
+use serde::{Deserialize, Deserializer};
+use std::fs::read_to_string;
+use std::path::PathBuf;
+
+#[derive(Debug, Clone, PartialEq, Eq, Default)]
+pub struct BlockList {
+ list: HashSet,
+}
+
+impl BlockList {
+ fn new() -> Self {
+ Self {
+ list: HashSet::new(),
+ }
+ }
+
+ fn from_file(path: PathBuf) -> eyre::Result {
+ let blocklist_file = read_to_string(path)?;
+ let blocklist: Vec = serde_json::from_str(&blocklist_file)?;
+
+ Ok(Self {
+ list: blocklist.into_iter().collect(),
+ })
+ }
+
+ pub fn len(&self) -> usize {
+ self.list.len()
+ }
+
+ pub fn contains(&self, address: &Address) -> bool {
+ self.list.contains(address)
+ }
+
+ #[cfg(test)]
+ fn add(&mut self, address: Address) {
+ self.list.insert(address);
+ }
+}
+
+impl From for BlockList {
+ fn from(path: PathBuf) -> Self {
+ Self::from_file(path).unwrap_or_else(|_| Self::new())
+ }
+}
+
+impl From> for BlockList {
+ fn from(addresses: Vec) -> Self {
+ Self {
+ list: addresses.into_iter().collect(),
+ }
+ }
+}
+
+impl<'de> Deserialize<'de> for BlockList {
+ fn deserialize(deserializer: D) -> Result
+ where
+ D: Deserializer<'de>,
+ {
+ let path: Option = Option::deserialize(deserializer)?;
+
+ match path {
+ Some(path) => BlockList::from_file(path).map_err(serde::de::Error::custom),
+ None => Ok(BlockList::new()),
+ }
+ }
+}
+
+#[cfg(test)]
+mod test {
+ use super::*;
+ use alloy_primitives::{address, Address};
+ use serde::Deserialize;
+
+ #[test]
+ fn test_read_blocklist_from_file() {
+ let block_list = BlockList::from_file(
+ PathBuf::from(env!("CARGO_MANIFEST_DIR")).join("src/blocklist/testdata/blocklist.txt"),
+ )
+ .unwrap();
+
+ let addr0 = address!("14dC79964da2C08b23698B3D3cc7Ca32193d9955");
+ assert_eq!(block_list.contains(&addr0), true);
+
+ let addr1 = address!("f39Fd6e51aad88F6F4ce6aB8827279cffFb92266");
+ assert_eq!(block_list.contains(&addr1), true);
+
+ let addr2 = address!("a0Ee7A142d267C1f36714E4a8F75612F20a79720");
+ assert_eq!(block_list.contains(&addr2), false);
+ }
+
+ #[test]
+ fn test_blocklist() {
+ let mut blocklist = BlockList::new();
+ let addr0 = Address::random();
+
+ blocklist.add(addr0);
+ assert_eq!(blocklist.len(), 1);
+ assert_eq!(blocklist.contains(&addr0), true);
+
+ // you cannot add twice the same value
+ blocklist.add(addr0);
+ assert_eq!(blocklist.len(), 1);
+
+ let addr1 = Address::random();
+ assert_eq!(blocklist.contains(&addr1), false);
+
+ blocklist.add(addr1);
+ assert_eq!(blocklist.len(), 2);
+ assert_eq!(blocklist.contains(&addr1), true);
+ }
+
+ #[derive(Deserialize)]
+ struct Config {
+ block_list: BlockList,
+ }
+
+ #[test]
+ fn test_deserialize_config() {
+ let config_str = r#"
+ block_list = "src/blocklist/testdata/blocklist.txt"
+ "#;
+ let config: Config = toml::from_str(config_str).unwrap();
+ assert_eq!(config.block_list.len(), 3);
+
+ let addr1 = address!("f39Fd6e51aad88F6F4ce6aB8827279cffFb92266");
+ assert_eq!(config.block_list.contains(&addr1), true);
+
+ let empty_config_str = r#""#;
+ let config: Config = toml::from_str(empty_config_str).unwrap();
+ assert_eq!(config.block_list.len(), 0);
+ }
+
+ #[test]
+ fn test_from_vec() {
+ let addr0 = address!("14dC79964da2C08b23698B3D3cc7Ca32193d9955");
+ let addr1 = address!("f39Fd6e51aad88F6F4ce6aB8827279cffFb92266");
+
+ let addresses = vec![addr0, addr1];
+ let blocklist = BlockList::from(addresses);
+
+ assert_eq!(blocklist.len(), 2);
+ assert_eq!(blocklist.contains(&addr0), true);
+ assert_eq!(blocklist.contains(&addr1), true);
+ }
+}
diff --git a/crates/rbuilder/src/blocklist/testdata/blocklist.txt b/crates/rbuilder/src/blocklist/testdata/blocklist.txt
new file mode 100644
index 00000000..5d1884d3
--- /dev/null
+++ b/crates/rbuilder/src/blocklist/testdata/blocklist.txt
@@ -0,0 +1,5 @@
+[
+ "0x14dC79964da2C08b23698B3D3cc7Ca32193d9955",
+ "0x3C44CdDdB6a900fa2b585dd299e03d12FA4293BC",
+ "f39Fd6e51aad88F6F4ce6aB8827279cffFb92266"
+]
\ No newline at end of file
diff --git a/crates/rbuilder/src/building/built_block_trace.rs b/crates/rbuilder/src/building/built_block_trace.rs
index 2a2b809d..b5af5439 100644
--- a/crates/rbuilder/src/building/built_block_trace.rs
+++ b/crates/rbuilder/src/building/built_block_trace.rs
@@ -1,7 +1,8 @@
use super::{BundleErr, ExecutionError, ExecutionResult, OrderErr};
+use crate::blocklist::BlockList;
use crate::primitives::{Order, OrderId, OrderReplacementKey};
use ahash::{HashMap, HashSet};
-use alloy_primitives::{Address, TxHash, U256};
+use alloy_primitives::{TxHash, U256};
use std::{collections::hash_map, time::Duration};
use time::OffsetDateTime;
@@ -91,7 +92,7 @@ impl BuiltBlockTrace {
pub fn verify_bundle_consistency(
&self,
- blocklist: &HashSet,
+ blocklist: &BlockList,
) -> Result<(), BuiltBlockTraceError> {
let mut replacement_data_count: HashSet<_> = HashSet::default();
let mut bundle_txs_scratchpad = HashMap::default();
diff --git a/crates/rbuilder/src/building/mod.rs b/crates/rbuilder/src/building/mod.rs
index 7f59bf0e..855432e6 100644
--- a/crates/rbuilder/src/building/mod.rs
+++ b/crates/rbuilder/src/building/mod.rs
@@ -18,11 +18,11 @@ use reth_primitives::BlockBody;
use reth_provider::{BlockReader, DatabaseProviderFactory, StateProviderFactory};
use crate::{
+ blocklist::BlockList,
primitives::{Order, OrderId, SimValue, SimulatedOrder, TransactionSignedEcRecoveredWithBlobs},
roothash::{calculate_state_root, RootHashConfig, RootHashError},
utils::{a2r_withdrawal, calc_gas_limit, timestamp_as_u64, Signer},
};
-use ahash::HashSet;
use alloy_eips::{
calc_excess_blob_gas, eip4844::BlobTransactionSidecar, eip4895::Withdrawals, eip7685::Requests,
merge::BEACON_NONCE,
@@ -78,7 +78,7 @@ pub struct BlockBuildingContext {
/// None: coinbase = attributes.suggested_fee_recipient. No payoffs allowed.
/// Some(signer): coinbase = signer.
pub builder_signer: Option,
- pub blocklist: HashSet,
+ pub blocklist: BlockList,
pub extra_data: Vec,
/// Excess blob gas calculated from the parent block header
pub excess_blob_gas: Option,
@@ -96,7 +96,7 @@ impl BlockBuildingContext {
parent: &Header,
signer: Signer,
chain_spec: Arc,
- blocklist: HashSet,
+ blocklist: BlockList,
prefer_gas_limit: Option,
extra_data: Vec,
spec_id: Option,
@@ -173,7 +173,7 @@ impl BlockBuildingContext {
onchain_block: alloy_rpc_types::Block,
chain_spec: Arc,
spec_id: Option,
- blocklist: HashSet,
+ blocklist: BlockList,
coinbase: Address,
suggested_fee_recipient: Address,
builder_signer: Option,
diff --git a/crates/rbuilder/src/building/testing/bundle_tests/mod.rs b/crates/rbuilder/src/building/testing/bundle_tests/mod.rs
index 6a3bef50..b1babd22 100644
--- a/crates/rbuilder/src/building/testing/bundle_tests/mod.rs
+++ b/crates/rbuilder/src/building/testing/bundle_tests/mod.rs
@@ -2,10 +2,10 @@ pub mod setup;
use alloy_primitives::{Address, B256, U256};
use itertools::Itertools;
-use std::collections::HashSet;
use uuid::Uuid;
use crate::{
+ blocklist::BlockList,
building::{testing::bundle_tests::setup::NonceValue, BuiltBlockTrace, BundleErr, OrderErr},
primitives::{
Bundle, BundleReplacementData, BundleReplacementKey, Order, OrderId, Refund, RefundConfig,
@@ -462,7 +462,7 @@ fn test_mev_share_failed_refunds() -> eyre::Result<()> {
fn test_bundle_consistency_check() -> eyre::Result<()> {
let mut test_setup = TestSetup::gen_test_setup(BlockArgs::default().number(11))?;
- let blocklist = HashSet::default();
+ let blocklist = BlockList::default();
// check revertible tx detection
{
let mut built_block_trace = BuiltBlockTrace::new();
@@ -522,9 +522,7 @@ fn test_bundle_consistency_check() -> eyre::Result<()> {
// check commit of blocklisted tx from
{
- let blocklist = vec![test_setup.named_address(NamedAddr::User(0))?]
- .into_iter()
- .collect();
+ let blocklist = BlockList::from(vec![test_setup.named_address(NamedAddr::User(0))?]);
let mut built_block_trace = BuiltBlockTrace::new();
test_setup.begin_bundle_order(11);
@@ -540,9 +538,7 @@ fn test_bundle_consistency_check() -> eyre::Result<()> {
// check commit of blocklisted tx to
{
- let blocklist = vec![test_setup.named_address(NamedAddr::User(1))?]
- .into_iter()
- .collect();
+ let blocklist = BlockList::from(vec![test_setup.named_address(NamedAddr::User(1))?]);
let mut built_block_trace = BuiltBlockTrace::new();
test_setup.begin_bundle_order(11);
diff --git a/crates/rbuilder/src/building/testing/test_chain_state.rs b/crates/rbuilder/src/building/testing/test_chain_state.rs
index 507ca25d..9e5c4cf8 100644
--- a/crates/rbuilder/src/building/testing/test_chain_state.rs
+++ b/crates/rbuilder/src/building/testing/test_chain_state.rs
@@ -1,4 +1,3 @@
-use ahash::HashSet;
use alloy_consensus::{Header, TxEip1559};
use alloy_primitives::{
keccak256, utils::parse_ether, Address, BlockHash, Bytes, TxKind as TransactionKind, B256, B64,
@@ -17,7 +16,7 @@ use reth_provider::test_utils::{create_test_provider_factory, MockNodeTypesWithD
use revm_primitives::SpecId;
use std::sync::Arc;
-use crate::{building::BlockBuildingContext, utils::Signer};
+use crate::{blocklist::BlockList, building::BlockBuildingContext, utils::Signer};
#[derive(Debug, Clone, Copy)]
pub enum NamedAddr {
@@ -233,7 +232,7 @@ struct TestBlockContextBuilder {
parent_gas_used: u64,
parent_hash: BlockHash,
chain_spec: Arc,
- blocklist: HashSet,
+ blocklist: BlockList,
prefer_gas_limit: Option,
use_suggested_fee_recipient_as_coinbase: bool,
}
@@ -260,7 +259,7 @@ impl TestBlockContextBuilder {
parent_gas_used: 15_000_000,
parent_hash,
chain_spec,
- blocklist: vec![blocklisted].into_iter().collect(),
+ blocklist: BlockList::from(vec![blocklisted]),
prefer_gas_limit: None,
use_suggested_fee_recipient_as_coinbase: block_args
.use_suggested_fee_recipient_as_coinbase,
diff --git a/crates/rbuilder/src/lib.rs b/crates/rbuilder/src/lib.rs
index 7572d559..0d7aca1e 100644
--- a/crates/rbuilder/src/lib.rs
+++ b/crates/rbuilder/src/lib.rs
@@ -1,5 +1,6 @@
pub mod backtest;
pub mod beacon_api_client;
+pub mod blocklist;
pub mod building;
pub mod integration;
pub mod live_builder;
diff --git a/crates/rbuilder/src/live_builder/base_config.rs b/crates/rbuilder/src/live_builder/base_config.rs
index 21a3b8e8..d9d72514 100644
--- a/crates/rbuilder/src/live_builder/base_config.rs
+++ b/crates/rbuilder/src/live_builder/base_config.rs
@@ -1,13 +1,13 @@
//! Config should always be deserializable, default values should be used
//!
use crate::{
+ blocklist::BlockList,
building::builders::UnfinishedBlockBuildingSinkFactory,
live_builder::{order_input::OrderInputConfig, LiveBuilder},
roothash::RootHashConfig,
telemetry::{setup_reloadable_tracing_subscriber, LoggerConfig},
utils::{http_provider, BoxedProvider, ProviderFactoryReopener, Signer},
};
-use ahash::HashSet;
use alloy_primitives::{Address, B256};
use eyre::{eyre, Context};
use jsonrpsee::RpcModule;
@@ -76,7 +76,7 @@ pub struct BaseConfig {
pub reth_db_path: Option,
pub reth_static_files_path: Option,
- pub blocklist_file_path: Option,
+ pub blocklist_file_path: BlockList,
pub extra_data: String,
/// mev-share bundles coming from this address are treated in a special way(see [`ShareBundleMerger`])
@@ -223,7 +223,7 @@ impl BaseConfig {
coinbase_signer: self.coinbase_signer()?,
extra_data: self.extra_data()?,
- blocklist: self.blocklist()?,
+ blocklist: self.blocklist_file_path.clone(),
global_cancellation: cancellation_token,
@@ -308,6 +308,7 @@ impl BaseConfig {
Ok(extra_data)
}
+<<<<<<< Updated upstream
pub fn blocklist(&self) -> eyre::Result> {
if let Some(path) = &self.blocklist_file_path {
let blocklist_file = read_to_string(path).context("blocklist file")?;
@@ -328,6 +329,8 @@ impl BaseConfig {
}
}
+=======
+>>>>>>> Stashed changes
pub fn eth_rpc_provider(&self) -> eyre::Result {
Ok(http_provider(self.backtest_fetch_eth_rpc_url.parse()?))
}
@@ -449,7 +452,7 @@ impl Default for BaseConfig {
reth_datadir: Some(DEFAULT_RETH_DB_PATH.parse().unwrap()),
reth_db_path: None,
reth_static_files_path: None,
- blocklist_file_path: None,
+ blocklist_file_path: Default::default(),
extra_data: "extra_data_change_me".to_string(),
root_hash_use_sparse_trie: false,
root_hash_compare_sparse_trie: false,
diff --git a/crates/rbuilder/src/live_builder/config.rs b/crates/rbuilder/src/live_builder/config.rs
index bf17e5c0..e76b20f8 100644
--- a/crates/rbuilder/src/live_builder/config.rs
+++ b/crates/rbuilder/src/live_builder/config.rs
@@ -327,7 +327,7 @@ impl LiveBuilderConfig for Config {
let payload_event = MevBoostSlotDataGenerator::new(
self.l1_config.beacon_clients()?,
relays,
- self.base_config.blocklist()?,
+ self.base_config.blocklist_file_path.clone(),
cancellation_token.clone(),
);
let live_builder = self
diff --git a/crates/rbuilder/src/live_builder/mod.rs b/crates/rbuilder/src/live_builder/mod.rs
index ff6ede4e..24b07946 100644
--- a/crates/rbuilder/src/live_builder/mod.rs
+++ b/crates/rbuilder/src/live_builder/mod.rs
@@ -9,6 +9,7 @@ pub mod simulation;
pub mod watchdog;
use crate::{
+ blocklist::BlockList,
building::{
builders::{BlockBuildingAlgorithm, UnfinishedBlockBuildingSinkFactory},
BlockBuildingContext,
@@ -23,7 +24,6 @@ use crate::{
error_storage::spawn_error_storage_writer, provider_head_state::ProviderHeadState, Signer,
},
};
-use ahash::HashSet;
use alloy_consensus::Header;
use alloy_primitives::{Address, B256};
use building::BlockBuildingPool;
@@ -102,7 +102,7 @@ where
pub coinbase_signer: Signer,
pub extra_data: Vec,
- pub blocklist: HashSet,
+ pub blocklist: BlockList,
pub global_cancellation: CancellationToken,
diff --git a/crates/rbuilder/src/live_builder/payload_events/mod.rs b/crates/rbuilder/src/live_builder/payload_events/mod.rs
index d1285f08..afcbbd4a 100644
--- a/crates/rbuilder/src/live_builder/payload_events/mod.rs
+++ b/crates/rbuilder/src/live_builder/payload_events/mod.rs
@@ -7,6 +7,7 @@ pub mod relay_epoch_cache;
use crate::{
beacon_api_client::Client,
+ blocklist::BlockList,
live_builder::{
payload_events::{
payload_source::PayloadSourceMuxer,
@@ -16,7 +17,6 @@ use crate::{
},
primitives::mev_boost::{MevBoostRelay, MevBoostRelayID},
};
-use ahash::HashSet;
use alloy_eips::merge::SLOT_DURATION;
use alloy_primitives::{utils::format_ether, Address, B256, U256};
use alloy_rpc_types_beacon::events::PayloadAttributesEvent;
@@ -81,7 +81,7 @@ impl MevBoostSlotData {
pub struct MevBoostSlotDataGenerator {
cls: Vec,
relays: Vec,
- blocklist: HashSet,
+ blocklist: BlockList,
global_cancellation: CancellationToken,
}
@@ -90,7 +90,7 @@ impl MevBoostSlotDataGenerator {
pub fn new(
cls: Vec,
relays: Vec,
- blocklist: HashSet,
+ blocklist: BlockList,
global_cancellation: CancellationToken,
) -> Self {
Self {
@@ -192,7 +192,7 @@ impl SlotSource for MevBoostSlotDataGenerator {
fn check_slot_data_for_blocklist(
data: &MevBoostSlotData,
- blocklist: &HashSet,
+ blocklist: &BlockList,
) -> eyre::Result<()> {
if blocklist.contains(&data.fee_recipient()) {
return Err(eyre::eyre!(