Skip to content

Commit 692c084

Browse files
refactor: move rate limit to rpc class
1 parent 588a3f0 commit 692c084

5 files changed

Lines changed: 49 additions & 37 deletions

File tree

packages/testing/src/execution_testing/cli/pytest_commands/plugins/execute/rpc/chain_builder_eth_rpc.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -205,11 +205,13 @@ def __init__(
205205
get_payload_wait_time: float,
206206
initial_forkchoice_update_retries: int = 5,
207207
transaction_wait_timeout: int = 60,
208+
max_transactions_per_batch: int | None = None,
208209
):
209210
"""Initialize the Ethereum RPC client for the hive simulator."""
210211
super().__init__(
211212
rpc_endpoint,
212213
transaction_wait_timeout=transaction_wait_timeout,
214+
max_transactions_per_batch=max_transactions_per_batch,
213215
)
214216
self.fork = fork
215217
self.engine_rpc = engine_rpc

packages/testing/src/execution_testing/cli/pytest_commands/plugins/execute/rpc/hive.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -383,6 +383,7 @@ def eth_rpc(
383383
session_fork: Fork,
384384
transactions_per_block: int,
385385
session_temp_folder: Path,
386+
max_transactions_per_batch: int | None,
386387
) -> EthRPC:
387388
"""Initialize ethereum RPC client for the execution client under test."""
388389
get_payload_wait_time = request.config.getoption("get_payload_wait_time")
@@ -395,4 +396,5 @@ def eth_rpc(
395396
session_temp_folder=session_temp_folder,
396397
get_payload_wait_time=get_payload_wait_time,
397398
transaction_wait_timeout=tx_wait_timeout,
399+
max_transactions_per_batch=max_transactions_per_batch,
398400
)

packages/testing/src/execution_testing/cli/pytest_commands/plugins/execute/rpc/remote.py

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -149,11 +149,16 @@ def eth_rpc(
149149
session_fork: Fork,
150150
transactions_per_block: int,
151151
session_temp_folder: Path,
152+
max_transactions_per_batch: int | None,
152153
) -> EthRPC:
153154
"""Initialize ethereum RPC client for the execution client under test."""
154155
tx_wait_timeout = request.config.getoption("tx_wait_timeout")
155156
if engine_rpc is None:
156-
return EthRPC(rpc_endpoint, transaction_wait_timeout=tx_wait_timeout)
157+
return EthRPC(
158+
rpc_endpoint,
159+
transaction_wait_timeout=tx_wait_timeout,
160+
max_transactions_per_batch=max_transactions_per_batch,
161+
)
157162
get_payload_wait_time = request.config.getoption("get_payload_wait_time")
158163
return ChainBuilderEthRPC(
159164
rpc_endpoint=rpc_endpoint,
@@ -163,4 +168,5 @@ def eth_rpc(
163168
session_temp_folder=session_temp_folder,
164169
get_payload_wait_time=get_payload_wait_time,
165170
transaction_wait_timeout=tx_wait_timeout,
171+
max_transactions_per_batch=max_transactions_per_batch,
166172
)

packages/testing/src/execution_testing/execution/transaction_post.py

Lines changed: 3 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -23,9 +23,6 @@
2323

2424
logger = get_logger(__name__)
2525

26-
# Threshold above which RPC service may become unstable
27-
RPC_OVERLOAD_THRESHOLD = 1000
28-
2926

3027
class TransactionPost(BaseExecute):
3128
"""
@@ -41,8 +38,6 @@ class TransactionPost(BaseExecute):
4138
skip_gas_used_validation: bool = (
4239
False # Skip gas validation even if expected is set
4340
)
44-
# Transaction batching to avoid RPC overload
45-
max_transactions_per_batch: int = 750
4641

4742
format_name: ClassVar[str] = "transaction_post_test"
4843
description: ClassVar[str] = (
@@ -86,21 +81,6 @@ def execute(
8681
del fork
8782
del engine_rpc
8883

89-
# Check if CLI override for max_transactions_per_batch is provided
90-
cli_max_tx_per_batch = request.config.getoption(
91-
"max_tx_per_batch", None
92-
)
93-
if cli_max_tx_per_batch is not None:
94-
self.max_transactions_per_batch = cli_max_tx_per_batch
95-
96-
# Warn if max_transactions_per_batch exceeds safe threshold
97-
if self.max_transactions_per_batch > RPC_OVERLOAD_THRESHOLD:
98-
logger.warning(
99-
f"max_transactions_per_batch ({self.max_transactions_per_batch}) exceeds "
100-
f"the safe threshold ({RPC_OVERLOAD_THRESHOLD}). "
101-
"This may cause RPC service instability or failures."
102-
)
103-
10484
for block in self.blocks:
10585
for tx in block:
10686
if not isinstance(tx, NetworkWrappedTransaction):
@@ -152,18 +132,9 @@ def execute(
152132
f"Transaction rejected as expected: {exc_info.value}"
153133
)
154134
else:
155-
# Send transactions in batches to avoid RPC overload
156-
batch_size = self.max_transactions_per_batch
157-
for i in range(0, len(signed_txs), batch_size):
158-
batch = signed_txs[i : i + batch_size]
159-
logger.info(
160-
f"Sending transaction batch {i // batch_size + 1} "
161-
f"({len(batch)} transactions, "
162-
f"{i + 1}-{min(i + batch_size, len(signed_txs))} "
163-
f"of {len(signed_txs)})"
164-
)
165-
eth_rpc.send_wait_transactions(batch)
166-
all_tx_hashes.extend([tx.hash for tx in batch])
135+
# Send transactions (batching is handled by eth_rpc internally)
136+
eth_rpc.send_wait_transactions(signed_txs)
137+
all_tx_hashes.extend([tx.hash for tx in signed_txs])
167138

168139
# Perform gas validation if required for benchmarking
169140
# Ensures benchmark tests consume exactly the expected gas

packages/testing/src/execution_testing/rpc/rpc.py

Lines changed: 35 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -198,8 +198,12 @@ class EthRPC(BaseRPC):
198198
within EEST based hive simulators.
199199
"""
200200

201+
OVERLOAD_THRESHOLD: int = 1000
202+
DEFAULT_MAX_TRANSACTIONS_PER_BATCH: int = 750
203+
201204
transaction_wait_timeout: int = 60
202205
poll_interval: float = 1.0 # how often to poll for tx inclusion
206+
max_transactions_per_batch: int = DEFAULT_MAX_TRANSACTIONS_PER_BATCH
203207

204208
gas_information_stale_seconds: int
205209

@@ -214,6 +218,7 @@ def __init__(
214218
transaction_wait_timeout: int = 60,
215219
poll_interval: float | None = None,
216220
gas_information_stale_seconds: int = 12,
221+
max_transactions_per_batch: int | None = None,
217222
**kwargs: Any,
218223
) -> None:
219224
"""
@@ -251,6 +256,17 @@ def __init__(
251256
"blobBaseFee": 0.0,
252257
}
253258

259+
# Transaction batching configuration
260+
if max_transactions_per_batch is None:
261+
max_transactions_per_batch = self.DEFAULT_MAX_TRANSACTIONS_PER_BATCH
262+
self.max_transactions_per_batch = max_transactions_per_batch
263+
if max_transactions_per_batch > self.OVERLOAD_THRESHOLD:
264+
logger.warning(
265+
f"max_transactions_per_batch ({max_transactions_per_batch}) exceeds "
266+
f"the safe threshold ({self.OVERLOAD_THRESHOLD}). "
267+
"This may cause RPC service instability or failures."
268+
)
269+
254270
def config(self, timeout: int | None = None) -> EthConfigResponse | None:
255271
"""
256272
`eth_config`: Returns information about a fork configuration of the
@@ -581,10 +597,25 @@ def send_wait_transactions(
581597
) -> List[Any]:
582598
"""
583599
Send list of transactions and waits until all of them are included in a
584-
block.
585-
"""
586-
self.send_transactions(transactions)
587-
return self.wait_for_transactions(transactions)
600+
block. Transactions are sent in batches to avoid RPC overload.
601+
"""
602+
results: List[Any] = []
603+
batch_size = self.max_transactions_per_batch
604+
total_txs = len(transactions)
605+
606+
for i in range(0, total_txs, batch_size):
607+
batch = transactions[i : i + batch_size]
608+
if total_txs > batch_size:
609+
logger.info(
610+
f"Sending transaction batch {i // batch_size + 1} "
611+
f"({len(batch)} transactions, "
612+
f"{i + 1}-{min(i + batch_size, total_txs)} "
613+
f"of {total_txs})"
614+
)
615+
self.send_transactions(batch)
616+
results.extend(self.wait_for_transactions(batch))
617+
618+
return results
588619

589620

590621
class DebugRPC(EthRPC):

0 commit comments

Comments
 (0)