Skip to content

Commit eab5984

Browse files
committed
refactor(tests): Use with_all_typed_transactions for block rlp limit test
1 parent c4f4fee commit eab5984

File tree

1 file changed

+56
-63
lines changed

1 file changed

+56
-63
lines changed

tests/osaka/eip7934_block_rlp_limit/test_max_block_rlp_size.py

Lines changed: 56 additions & 63 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88

99
import pytest
1010

11-
from ethereum_test_base_types import AccessList, Address, HexNumber, ZeroPaddedHexNumber
11+
from ethereum_test_base_types import Address, HexNumber, ZeroPaddedHexNumber
1212
from ethereum_test_fixtures.blockchain import (
1313
FixtureBlockBase,
1414
FixtureHeader,
@@ -23,7 +23,7 @@
2323
Transaction,
2424
)
2525
from ethereum_test_tools import Opcodes as Op
26-
from ethereum_test_types import EOA, AuthorizationTuple, Environment, add_kzg_version
26+
from ethereum_test_types import EOA, Environment
2727

2828
from .spec import Spec, ref_spec_7934
2929

@@ -103,45 +103,13 @@ def get_block_rlp_size(transactions: List[Transaction], gas_used: int) -> int:
103103
return len(test_block.with_rlp(txs=transactions).rlp)
104104

105105

106-
def create_typed_transaction(tx_type: int) -> Transaction:
107-
"""Create a transaction for the given transaction type."""
108-
if tx_type == 0:
109-
return Transaction(type=tx_type, gas_price=10**9)
110-
else:
111-
access_list = [
112-
AccessList(address=0x1234, storage_keys=[0, 1]),
113-
AccessList(address=0x5678, storage_keys=[2, 3]),
114-
]
115-
tx = Transaction(type=tx_type, access_list=access_list)
116-
if tx_type == 1:
117-
tx.gas_price = HexNumber(10**9)
118-
if tx_type >= 2:
119-
tx.max_fee_per_gas = HexNumber(10**9)
120-
tx.max_priority_fee_per_gas = HexNumber(10**9)
121-
if tx_type == 3:
122-
tx.max_fee_per_blob_gas = HexNumber(10**9)
123-
tx.blob_versioned_hashes = add_kzg_version(
124-
[1],
125-
Spec.BLOB_COMMITMENT_VERSION_KZG,
126-
)
127-
elif tx_type == 4:
128-
tx.authorization_list = [
129-
AuthorizationTuple(
130-
address=Address(0x1234), nonce=0, signer=EOA("0x" + "11" * 20, key=123)
131-
)
132-
]
133-
elif tx_type >= 5:
134-
raise NotImplementedError(f"Update test to support new transaction type {tx_type}")
135-
return tx
136-
137-
138106
def exact_size_transactions(
139107
sender: EOA,
140108
block_size_limit: int,
141109
fork: Fork,
142110
pre: Optional[Alloc],
143-
tx_type: Optional[int] = None,
144111
emit_logs: bool = False,
112+
specific_transaction_to_include: Optional[Transaction] = None,
145113
) -> Tuple[List[Transaction], int]:
146114
"""
147115
Generate transactions that fill a block to exactly the RLP size limit.
@@ -153,9 +121,9 @@ def exact_size_transactions(
153121
sender: The sender account
154122
block_size_limit: The target block RLP size limit
155123
fork: The fork to generate transactions for
156-
tx_type: Optional transaction type to include
157-
emit_logs: If True, transactions will call a contract that emits logs
158124
pre: Required if emit_logs is True, used to deploy the log contract
125+
emit_logs: If True, transactions will call a contract that emits logs
126+
specific_transaction_to_include: If provided, this transaction will be included
159127
160128
"""
161129
log_contract = None
@@ -183,9 +151,19 @@ def exact_size_transactions(
183151
log_contract_code += Op.LOG4
184152
log_contract = pre.deploy_contract(log_contract_code)
185153

186-
stubbed_transactions, gas_used = _exact_size_transactions_calculation(
187-
block_size_limit, fork, tx_type, emit_logs_contract=log_contract
188-
)
154+
if not specific_transaction_to_include:
155+
# use cached version when possible for performance
156+
stubbed_transactions, gas_used = _exact_size_transactions_cached(
157+
block_size_limit, fork, emit_logs_contract=log_contract
158+
)
159+
else:
160+
# Direct calculation, no cache, since `Transaction` is not hashable
161+
stubbed_transactions, gas_used = _exact_size_transactions_impl(
162+
block_size_limit,
163+
fork,
164+
specific_transaction_to_include=specific_transaction_to_include,
165+
)
166+
189167
test_transactions = []
190168
for tx in stubbed_transactions:
191169
# Create a new transaction with the correct sender, preserving all other fields
@@ -199,16 +177,28 @@ def exact_size_transactions(
199177

200178

201179
@lru_cache(maxsize=128)
202-
def _exact_size_transactions_calculation(
180+
def _exact_size_transactions_cached(
203181
block_size_limit: int,
204182
fork: Fork,
205-
tx_type: Optional[int] = None,
206183
emit_logs_contract: Optional[Address] = None,
207184
) -> Tuple[List[Transaction], int]:
208185
"""
209186
Generate transactions that fill a block to exactly the RLP size limit. Abstracted
210187
with hashable arguments for caching block calculations.
211188
"""
189+
return _exact_size_transactions_impl(block_size_limit, fork, None, emit_logs_contract)
190+
191+
192+
def _exact_size_transactions_impl(
193+
block_size_limit: int,
194+
fork: Fork,
195+
specific_transaction_to_include: Optional[Transaction] = None,
196+
emit_logs_contract: Optional[Address] = None,
197+
) -> Tuple[List[Transaction], int]:
198+
"""
199+
Calculate the exact size of transactions to be included. Shared by both cached and
200+
non-cached paths.
201+
"""
212202
transactions = []
213203
sender = EOA("0x" + "00" * 20, key=123)
214204
nonce = 0
@@ -223,7 +213,9 @@ def _exact_size_transactions_calculation(
223213
# block with 16 transactions + large calldata remains safely below the limit
224214
# add 15 generic transactions to fill the block and one typed transaction
225215
# if tx_type is specified, otherwise just add 16 generic transactions
226-
not_all_generic_txs = any(kwarg is not None for kwarg in {tx_type, emit_logs_contract})
216+
not_all_generic_txs = any(
217+
kwarg is not None for kwarg in [specific_transaction_to_include, emit_logs_contract]
218+
)
227219

228220
generic_tx_num = 15 if not_all_generic_txs else 16
229221
for _ in range(generic_tx_num):
@@ -239,24 +231,23 @@ def _exact_size_transactions_calculation(
239231
total_gas_used += gas_limit_large
240232
nonce += 1
241233

242-
# append a typed transaction to fill the block if tx_type is specified
234+
# append a typed transaction to fill the block
243235
if not_all_generic_txs:
244-
if tx_type is not None:
245-
last_tx = create_typed_transaction(tx_type)
246-
last_tx.sender = sender
247-
last_tx.nonce = HexNumber(nonce)
248-
last_tx.data = Bytes(b"\x00" * 200_000)
249-
last_tx.gas_limit = HexNumber(
236+
if specific_transaction_to_include is not None:
237+
tx_dict = specific_transaction_to_include.model_dump(exclude_unset=True)
238+
data = Bytes(b"\x00" * 200_000)
239+
gas_limit = HexNumber(
250240
calculator(
251-
calldata=last_tx.data,
252-
access_list=last_tx.access_list if hasattr(last_tx, "access_list") else None,
253-
authorization_list_or_count=(
254-
last_tx.authorization_list
255-
if hasattr(last_tx, "authorization_list")
256-
else None
257-
),
241+
calldata=data,
242+
access_list=specific_transaction_to_include.access_list,
243+
authorization_list_or_count=len(tx_dict.get("authorization_list", [])),
258244
)
259245
)
246+
tx_dict["sender"] = sender
247+
tx_dict["nonce"] = nonce
248+
tx_dict["data"] = data
249+
tx_dict["gas_limit"] = gas_limit
250+
last_tx = Transaction(**tx_dict)
260251
elif emit_logs_contract is not None:
261252
last_tx = Transaction(
262253
sender=sender,
@@ -266,6 +257,10 @@ def _exact_size_transactions_calculation(
266257
gas_limit=calculator(calldata=b""),
267258
to=emit_logs_contract,
268259
)
260+
else:
261+
raise ValueError(
262+
"Either specific_transaction_to_include or emit_logs_contract must be provided."
263+
)
269264

270265
transactions.append(last_tx)
271266
nonce += 1
@@ -400,7 +395,6 @@ def test_block_at_rlp_size_limit_boundary(
400395
block_size_limit,
401396
fork,
402397
pre,
403-
tx_type=None,
404398
)
405399
block_rlp_size = get_block_rlp_size(transactions, gas_used=gas_used)
406400
assert block_rlp_size == block_size_limit, (
@@ -430,24 +424,24 @@ def test_block_at_rlp_size_limit_boundary(
430424
)
431425

432426

433-
@pytest.mark.with_all_tx_types
434-
def test_block_rlp_size_at_limit_with_all_tx_types(
427+
@pytest.mark.with_all_typed_transactions
428+
def test_block_rlp_size_at_limit_with_all_typed_transactions(
435429
blockchain_test: BlockchainTestFiller,
436430
pre: Alloc,
437431
post: Alloc,
438432
fork: Fork,
439433
sender: EOA,
440434
block_size_limit: int,
441435
env: Environment,
442-
tx_type: int,
436+
typed_transaction: Transaction,
443437
) -> None:
444438
"""Test the block RLP size limit with all transaction types."""
445439
transactions, gas_used = exact_size_transactions(
446440
sender,
447441
block_size_limit,
448442
fork,
449443
pre,
450-
tx_type=tx_type,
444+
specific_transaction_to_include=typed_transaction,
451445
)
452446
block_rlp_size = get_block_rlp_size(transactions, gas_used=gas_used)
453447
assert block_rlp_size == block_size_limit, (
@@ -483,7 +477,6 @@ def test_block_at_rlp_limit_with_logs(
483477
block_size_limit,
484478
fork,
485479
pre,
486-
tx_type=None,
487480
emit_logs=True,
488481
)
489482

0 commit comments

Comments
 (0)