diff --git a/voltaire_bundler/cli_manager.py b/voltaire_bundler/cli_manager.py index 5396210..5516993 100644 --- a/voltaire_bundler/cli_manager.py +++ b/voltaire_bundler/cli_manager.py @@ -72,6 +72,8 @@ class InitData: logs_incremental_range: int logs_number_of_ranges: int health_check_interval: int + reputation_whitelist: list[str] + reputation_blacklist: list[str] def address(ep: str): @@ -460,6 +462,20 @@ def initialize_argument_parser() -> ArgumentParser: const=600, default=600, ) + + parser.add_argument( + "--reputation_whitelist", + help="Entities that will not be banned or throttled.", + type=str, + nargs="+", + ) + + parser.add_argument( + "--reputation_blacklist", + help="Entities that are always banned.", + type=str, + nargs="+", + ) return parser @@ -638,6 +654,8 @@ async def get_init_data(args: Namespace) -> InitData: args.logs_incremental_range, args.logs_number_of_ranges, args.health_check_interval, + args.reputation_whitelist, + args.reputation_blacklist ) if args.verbose: diff --git a/voltaire_bundler/execution_endpoint.py b/voltaire_bundler/execution_endpoint.py index 77686ec..c8c930c 100644 --- a/voltaire_bundler/execution_endpoint.py +++ b/voltaire_bundler/execution_endpoint.py @@ -67,6 +67,8 @@ def __init__( disable_v6: bool, logs_incremental_range: int, logs_number_of_ranges: int, + reputation_whitelist: list[str], + reputation_blacklist: list[str] ): super().__init__("bundler_endpoint") self.ethereum_node_url = ethereum_node_url @@ -95,6 +97,8 @@ def __init__( enforce_gas_price_tolerance, is_legacy_mode, ethereum_node_debug_trace_call_url, + reputation_whitelist, + reputation_blacklist ) if disable_v6: @@ -124,6 +128,8 @@ def __init__( enforce_gas_price_tolerance, is_legacy_mode, ethereum_node_debug_trace_call_url, + reputation_whitelist, + reputation_blacklist ) self.bundle_manager = BundlerManager( diff --git a/voltaire_bundler/main.py b/voltaire_bundler/main.py index 0d8d3ac..2da492f 100644 --- a/voltaire_bundler/main.py +++ b/voltaire_bundler/main.py @@ -73,6 +73,8 @@ async def main(cmd_args=sys.argv[1:], loop=None) -> None: init_data.disable_v6, init_data.logs_incremental_range, init_data.logs_number_of_ranges, + init_data.reputation_whitelist, + init_data.reputation_blacklist ) task_group.create_task(execution_endpoint.start_execution_endpoint()) diff --git a/voltaire_bundler/mempool/reputation_manager.py b/voltaire_bundler/mempool/reputation_manager.py index 2cf8bf6..0e5ee7d 100644 --- a/voltaire_bundler/mempool/reputation_manager.py +++ b/voltaire_bundler/mempool/reputation_manager.py @@ -25,10 +25,23 @@ class ReputationEntry: class ReputationManager: entities_reputation: dict[str, ReputationEntry] = {} - white_list: list = [] - black_list: list = [] + whitelist: list[str] = [] + blacklist: list[str] = [] - def __init__(self) -> None: + def __init__( + self, + reputation_whitelist: list[str], + reputation_blacklist: list[str] + ) -> None: + if reputation_whitelist is not None: + reputation_whitelist = list(map( + lambda entity: entity.lower(), reputation_whitelist)) + if reputation_blacklist is not None: + reputation_blacklist = list(map( + lambda entity: entity.lower(), reputation_blacklist)) + + self.whitelist = reputation_whitelist + self.blacklist = reputation_blacklist asyncio.ensure_future(self.execute_reputation_cron_job()) async def execute_reputation_cron_job(self) -> None: @@ -66,17 +79,29 @@ def update_included_status(self, entity: str, modifier: int = 1) -> None: self.entities_reputation[entity_address].ops_included += modifier def ban_entity(self, entity: str) -> None: - self.entities_reputation[entity.lower()] = ReputationEntry(10000, 0) + if self.is_whitelisted(entity): + logging.warning( + f"{entity} won't be banned because it is whitelisted.") + else: + self.entities_reputation[entity.lower()] = ReputationEntry(10000, 0) def is_whitelisted(self, entity: str) -> bool: - return entity.lower() in self.white_list + return entity.lower() in self.whitelist def is_blacklisted(self, entity: str) -> bool: - return entity.lower() in self.black_list + return entity.lower() in self.blacklist def get_status(self, entity: str) -> ReputationStatus: entity_address = entity.lower() - if entity_address not in self.entities_reputation: + if ( + self.is_blacklisted(entity) + ): + return ReputationStatus.BANNED + + if ( + entity_address not in self.entities_reputation or + self.is_whitelisted(entity) + ): return ReputationStatus.OK reputation_entry = self.entities_reputation[entity_address] diff --git a/voltaire_bundler/mempool/v6/mempool_manager_v6.py b/voltaire_bundler/mempool/v6/mempool_manager_v6.py index 1b65805..9a48f98 100644 --- a/voltaire_bundler/mempool/v6/mempool_manager_v6.py +++ b/voltaire_bundler/mempool/v6/mempool_manager_v6.py @@ -25,6 +25,8 @@ def __init__( enforce_gas_price_tolerance: int, is_legacy_mode: bool, ethereum_node_debug_trace_call_url: str, + reputation_whitelist: list[str], + reputation_blacklist: list[str] ): self.validation_manager = ValidationManagerV6( user_operation_handler, @@ -37,7 +39,8 @@ def __init__( ethereum_node_debug_trace_call_url, ) self.user_operation_handler = user_operation_handler - self.reputation_manager = ReputationManager() + self.reputation_manager = ReputationManager( + reputation_whitelist, reputation_blacklist) self.ethereum_node_url = ethereum_node_url self.bundler_address = bundler_address self.chain_id = chain_id diff --git a/voltaire_bundler/mempool/v7/mempool_manager_v7.py b/voltaire_bundler/mempool/v7/mempool_manager_v7.py index 3e89ef1..fc32490 100644 --- a/voltaire_bundler/mempool/v7/mempool_manager_v7.py +++ b/voltaire_bundler/mempool/v7/mempool_manager_v7.py @@ -25,6 +25,8 @@ def __init__( enforce_gas_price_tolerance: int, is_legacy_mode: bool, ethereum_node_debug_trace_call_url: str, + reputation_whitelist: list[str], + reputation_blacklist: list[str] ): self.validation_manager = ValidationManagerV7( user_operation_handler, @@ -37,7 +39,8 @@ def __init__( ethereum_node_debug_trace_call_url, ) self.user_operation_handler = user_operation_handler - self.reputation_manager = ReputationManager() + self.reputation_manager = ReputationManager( + reputation_whitelist, reputation_blacklist) self.ethereum_node_url = ethereum_node_url self.bundler_address = bundler_address self.chain_id = chain_id