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

Add blocklist struct #325

Open
wants to merge 6 commits into
base: develop
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 4 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 0 additions & 2 deletions config-live-example.toml
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,6 @@ jsonrpc_server_ip = "0.0.0.0"
el_node_ipc_path = "/tmp/reth.ipc"
extra_data = "⚡🤖"

blocklist_file_path = "./blocklist.json"

dry_run = true
dry_run_validation_url = "http://localhost:8545"

Expand Down
2 changes: 1 addition & 1 deletion crates/rbuilder/src/backtest/backtest_build_block.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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()?,
)?;
Expand Down
2 changes: 1 addition & 1 deletion crates/rbuilder/src/backtest/backtest_build_range.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down
6 changes: 3 additions & 3 deletions crates/rbuilder/src/backtest/execute.rs
Original file line number Diff line number Diff line change
@@ -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,
Expand All @@ -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;
Expand Down Expand Up @@ -61,7 +61,7 @@ pub fn backtest_prepare_ctx_for_block<P>(
provider: P,
chain_spec: Arc<ChainSpec>,
build_block_lag_ms: i64,
blocklist: HashSet<Address>,
blocklist: BlockList,
sbundle_mergeabe_signers: &[Address],
builder_signer: Signer,
) -> eyre::Result<BacktestBlockInput>
Expand Down Expand Up @@ -114,7 +114,7 @@ pub fn backtest_simulate_block<P, DB, ConfigType>(
build_block_lag_ms: i64,
builders_names: Vec<String>,
config: &ConfigType,
blocklist: HashSet<Address>,
blocklist: BlockList,
sbundle_mergeabe_signers: &[Address],
) -> eyre::Result<BlockBacktestValue>
where
Expand Down
2 changes: 1 addition & 1 deletion crates/rbuilder/src/backtest/redistribute/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -46,7 +46,7 @@ where
onchain_block,
chain_spec,
None,
HashSet::default(),
Default::default(),
coinbase,
suggested_fee_recipient,
None,
Expand Down
148 changes: 148 additions & 0 deletions crates/rbuilder/src/blocklist/mod.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,148 @@
use ahash::{HashSet, HashSetExt};
use alloy_primitives::Address;
use serde::{Deserialize, Deserializer};
use std::fs::read_to_string;
use std::path::PathBuf;

#[allow(clippy::len_without_is_empty)]
#[derive(Debug, Clone, PartialEq, Eq, Default)]
pub struct BlockList {
list: HashSet<Address>,
}

impl BlockList {
fn new() -> Self {
Self {
list: HashSet::new(),
}
}

fn from_file(path: PathBuf) -> eyre::Result<Self> {
let blocklist_file = read_to_string(path)?;
let blocklist: Vec<Address> = 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)
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Might want to impl

impl Deref for BlockList {
    type Target = HashSet<Address>;

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

instead of the inner methods individually

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Added Deref but not sure what changes I have to make to the len and contains functions.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You can remove them now :)


#[cfg(test)]
fn add(&mut self, address: Address) {
self.list.insert(address);
}
}

impl From<PathBuf> for BlockList {
fn from(path: PathBuf) -> Self {
Self::from_file(path).unwrap_or_else(|_| Self::new())
}
Copy link
Contributor

@liamaharon liamaharon Jan 2, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would expect this type of method to return an error if the path doesn't exist instead of an empty list.

Suggested change
fn from(path: PathBuf) -> Self {
Self::from_file(path).unwrap_or_else(|_| Self::new())
}
fn try_from(path: PathBuf) -> Result<Self, ...> {
Self::from_file(path).unwrap_or_else(|_| Self::new())
}

}

impl From<Vec<Address>> for BlockList {
fn from(addresses: Vec<Address>) -> Self {
Self {
list: addresses.into_iter().collect(),
}
}
}

impl<'de> Deserialize<'de> for BlockList {
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where
D: Deserializer<'de>,
{
let path: Option<PathBuf> = 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);
}
}
5 changes: 5 additions & 0 deletions crates/rbuilder/src/blocklist/testdata/blocklist.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
[
"0x14dC79964da2C08b23698B3D3cc7Ca32193d9955",
"0x3C44CdDdB6a900fa2b585dd299e03d12FA4293BC",
"f39Fd6e51aad88F6F4ce6aB8827279cffFb92266"
]
5 changes: 3 additions & 2 deletions crates/rbuilder/src/building/built_block_trace.rs
Original file line number Diff line number Diff line change
@@ -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;

Expand Down Expand Up @@ -91,7 +92,7 @@ impl BuiltBlockTrace {

pub fn verify_bundle_consistency(
&self,
blocklist: &HashSet<Address>,
blocklist: &BlockList,
) -> Result<(), BuiltBlockTraceError> {
let mut replacement_data_count: HashSet<_> = HashSet::default();
let mut bundle_txs_scratchpad = HashMap::default();
Expand Down
8 changes: 4 additions & 4 deletions crates/rbuilder/src/building/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down Expand Up @@ -78,7 +78,7 @@ pub struct BlockBuildingContext {
/// None: coinbase = attributes.suggested_fee_recipient. No payoffs allowed.
/// Some(signer): coinbase = signer.
pub builder_signer: Option<Signer>,
pub blocklist: HashSet<Address>,
pub blocklist: BlockList,
pub extra_data: Vec<u8>,
/// Excess blob gas calculated from the parent block header
pub excess_blob_gas: Option<u64>,
Expand All @@ -96,7 +96,7 @@ impl BlockBuildingContext {
parent: &Header,
signer: Signer,
chain_spec: Arc<ChainSpec>,
blocklist: HashSet<Address>,
blocklist: BlockList,
prefer_gas_limit: Option<u64>,
extra_data: Vec<u8>,
spec_id: Option<SpecId>,
Expand Down Expand Up @@ -173,7 +173,7 @@ impl BlockBuildingContext {
onchain_block: alloy_rpc_types::Block,
chain_spec: Arc<ChainSpec>,
spec_id: Option<SpecId>,
blocklist: HashSet<Address>,
blocklist: BlockList,
coinbase: Address,
suggested_fee_recipient: Address,
builder_signer: Option<Signer>,
Expand Down
12 changes: 4 additions & 8 deletions crates/rbuilder/src/building/testing/bundle_tests/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down Expand Up @@ -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();
Expand Down Expand Up @@ -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);
Expand All @@ -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);
Expand Down
7 changes: 3 additions & 4 deletions crates/rbuilder/src/building/testing/test_chain_state.rs
Original file line number Diff line number Diff line change
@@ -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,
Expand All @@ -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 {
Expand Down Expand Up @@ -233,7 +232,7 @@ struct TestBlockContextBuilder {
parent_gas_used: u64,
parent_hash: BlockHash,
chain_spec: Arc<ChainSpec>,
blocklist: HashSet<Address>,
blocklist: BlockList,
prefer_gas_limit: Option<u64>,
use_suggested_fee_recipient_as_coinbase: bool,
}
Expand All @@ -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,
Expand Down
1 change: 1 addition & 0 deletions crates/rbuilder/src/lib.rs
Original file line number Diff line number Diff line change
@@ -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;
Expand Down
Loading
Loading